From e038a90f7722a3294bf99298daece25954697dfa Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Sat, 23 Nov 2024 17:43:32 +0100 Subject: [PATCH 01/13] Added delimiter pairs --- core/edit/delimiter_pair.py | 32 ++++++++++++++++ core/edit/delimiter_pair.talon-list | 11 ++++++ core/edit/edit.talon | 4 +- core/edit/edit_command_actions.py | 57 +++++++++++++++++++++++++---- 4 files changed, 96 insertions(+), 8 deletions(-) create mode 100644 core/edit/delimiter_pair.py create mode 100644 core/edit/delimiter_pair.talon-list diff --git a/core/edit/delimiter_pair.py b/core/edit/delimiter_pair.py new file mode 100644 index 0000000000..88e86886d4 --- /dev/null +++ b/core/edit/delimiter_pair.py @@ -0,0 +1,32 @@ +from talon import Module, actions + +mod = Module() + +mod.list("delimiter_pair", "List of matching pair delimiters") + + +@mod.capture(rule="{user.delimiter_pair}") +def delimiter_pair(m) -> list[str]: + pair = m.delimiter_pair.split() + assert len(pair) == 2 + open = pair[0] if pair[0] != "space" else " " + close = pair[1] if pair[1] != "space" else " " + return [open, close] + + +@mod.action_class +class Actions: + def delimiter_pair_insert(pair: list[str]): + """Insert a delimiter pair leaving the cursor in the middle""" + left, right = pair + actions.insert(f"{left}{right}") + for _ in right: + actions.edit.left() + + def delimiter_pair_wrap_selection(pair: list[str]): + """Wrap selection with delimiter pair """ + left, right = pair + selected = actions.edit.selected_text() + actions.insert(f"{left}{selected}{right}") + for _ in right: + actions.edit.left() diff --git a/core/edit/delimiter_pair.talon-list b/core/edit/delimiter_pair.talon-list new file mode 100644 index 0000000000..1ed6d57a4f --- /dev/null +++ b/core/edit/delimiter_pair.talon-list @@ -0,0 +1,11 @@ +list: user.delimiter_pair +- + +round: ( ) +index: [ ] +diamond: < > +curly: { } +twin: "' '" +quad: '" "' +skis: ` ` +padding: space space diff --git a/core/edit/edit.talon b/core/edit/edit.talon index bfb3131f3f..cfb30f1b3f 100644 --- a/core/edit/edit.talon +++ b/core/edit/edit.talon @@ -125,12 +125,14 @@ new line above: edit.line_insert_up() new line below | slap: edit.line_insert_down() # Insert padding with optional symbols -(pad | padding): user.insert_between(" ", " ") (pad | padding) +: insert(" ") user.insert_many(symbol_key_list) insert(" ") +# Insert delimiter pairs +: user.delimiter_pair_insert(delimiter_pair) + # Undo/redo undo that: edit.undo() redo that: edit.redo() diff --git a/core/edit/edit_command_actions.py b/core/edit/edit_command_actions.py index 9239ea5a0f..d3bf658f88 100644 --- a/core/edit/edit_command_actions.py +++ b/core/edit/edit_command_actions.py @@ -1,36 +1,75 @@ from dataclasses import dataclass -from typing import Callable +from typing import Callable, Union from talon import Module, actions @dataclass -class EditAction: +class EditSimpleAction: type: str + def __str__(self): + return self.type + @dataclass -class EditInsertAction(EditAction): +class EditInsertAction: type = "insert" text: str + def __str__(self): + return self.type + @dataclass -class EditFormatAction(EditAction): +class EditWrapAction: + type = "wrapWithDelimiterPair" + pair: list[str] + + def __str__(self): + return self.type + + +@dataclass +class EditFormatAction: type = "applyFormatter" formatters: str + def __str__(self): + return self.type + + +EditAction = Union[ + EditSimpleAction, + EditInsertAction, + EditWrapAction, + EditFormatAction, +] mod = Module() mod.list("edit_action", desc="Actions for the edit command") @mod.capture(rule="{user.edit_action}") -def edit_simple_action(m) -> EditAction: - return EditAction(m.edit_action) +def edit_simple_action(m) -> EditSimpleAction: + return EditSimpleAction(m.edit_action) + + +@mod.capture(rule=" wrap") +def edit_wrap_action(m) -> EditWrapAction: + return EditWrapAction(m.delimiter_pair) -@mod.capture(rule="") +@mod.capture(rule=" (format | form)") +def edit_format_action(m) -> EditFormatAction: + return EditFormatAction(m.formatters) + + +@mod.capture( + rule="" + " | " + " | " +) def edit_action(m) -> EditAction: return m[0] @@ -62,6 +101,10 @@ def run_action_callback(action: EditAction): assert isinstance(action, EditInsertAction) actions.insert(action.text) + case "wrapWithDelimiterPair": + assert isinstance(action, EditWrapAction) + return lambda: actions.user.delimiter_pair_wrap_selection(action.pair) + case "applyFormatter": assert isinstance(action, EditFormatAction) actions.user.formatters_reformat_selection(action.formatters) From 06f6ff26709a3bae9ac6efcc688d1d183f9f65f6 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Sat, 23 Nov 2024 17:47:57 +0100 Subject: [PATCH 02/13] Clean up --- core/edit/edit_command_actions.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/core/edit/edit_command_actions.py b/core/edit/edit_command_actions.py index d3bf658f88..26a743e6ba 100644 --- a/core/edit/edit_command_actions.py +++ b/core/edit/edit_command_actions.py @@ -60,16 +60,7 @@ def edit_wrap_action(m) -> EditWrapAction: return EditWrapAction(m.delimiter_pair) -@mod.capture(rule=" (format | form)") -def edit_format_action(m) -> EditFormatAction: - return EditFormatAction(m.formatters) - - -@mod.capture( - rule="" - " | " - " | " -) +@mod.capture(rule=" | ") def edit_action(m) -> EditAction: return m[0] From 39da7b1c0e1fa627038f4f76e609aff335afb3a9 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Sat, 23 Nov 2024 19:03:51 +0100 Subject: [PATCH 03/13] Use insert between --- core/edit/delimiter_pair.py | 10 ++-------- core/edit/insert_between.py | 4 ++-- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/core/edit/delimiter_pair.py b/core/edit/delimiter_pair.py index 88e86886d4..130b7a36c5 100644 --- a/core/edit/delimiter_pair.py +++ b/core/edit/delimiter_pair.py @@ -18,15 +18,9 @@ def delimiter_pair(m) -> list[str]: class Actions: def delimiter_pair_insert(pair: list[str]): """Insert a delimiter pair leaving the cursor in the middle""" - left, right = pair - actions.insert(f"{left}{right}") - for _ in right: - actions.edit.left() + actions.user.insert_between(pair[0], pair[1]) def delimiter_pair_wrap_selection(pair: list[str]): """Wrap selection with delimiter pair """ - left, right = pair selected = actions.edit.selected_text() - actions.insert(f"{left}{selected}{right}") - for _ in right: - actions.edit.left() + actions.user.insert_between(pair[0], pair[1], selected) diff --git a/core/edit/insert_between.py b/core/edit/insert_between.py index ba957cde74..332f32fa39 100644 --- a/core/edit/insert_between.py +++ b/core/edit/insert_between.py @@ -5,9 +5,9 @@ @mod.action_class class module_actions: - def insert_between(before: str, after: str): + def insert_between(before: str, after: str, middle=""): """Insert `before + after`, leaving cursor between `before` and `after`. Not entirely reliable if `after` contains newlines.""" - actions.insert(before + after) + actions.insert(f"{before}{middle}{after}") for _ in after: actions.edit.left() From 6cc287028a637da95257f766025a49e0609e5fd5 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Sun, 24 Nov 2024 06:18:24 +0100 Subject: [PATCH 04/13] Update list --- core/edit/delimiter_pair.talon-list | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/edit/delimiter_pair.talon-list b/core/edit/delimiter_pair.talon-list index 1ed6d57a4f..ba08ca26a5 100644 --- a/core/edit/delimiter_pair.talon-list +++ b/core/edit/delimiter_pair.talon-list @@ -1,11 +1,14 @@ list: user.delimiter_pair - +# SPOKEN_FORM: LEFT_DELIMITER RIGHT_DELIMITER. Example: "round: ( )" +# Special case for whitespace "space". Example: "pad: space space" + round: ( ) -index: [ ] +box: [ ] diamond: < > curly: { } twin: "' '" quad: '" "' skis: ` ` -padding: space space +pad: space space From 3e1cd46c25e84566057cada13a8b2c8734afd2d7 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Sun, 24 Nov 2024 06:20:30 +0100 Subject: [PATCH 05/13] Update core/edit/delimiter_pair.py Co-authored-by: Phil Cohen --- core/edit/delimiter_pair.py | 1 + 1 file changed, 1 insertion(+) diff --git a/core/edit/delimiter_pair.py b/core/edit/delimiter_pair.py index 130b7a36c5..7b3795eb4e 100644 --- a/core/edit/delimiter_pair.py +++ b/core/edit/delimiter_pair.py @@ -9,6 +9,7 @@ def delimiter_pair(m) -> list[str]: pair = m.delimiter_pair.split() assert len(pair) == 2 + # "space" requires a special written form because Talon lists are whitespace insensitive open = pair[0] if pair[0] != "space" else " " close = pair[1] if pair[1] != "space" else " " return [open, close] From f4570efd889e2631f3dabe6ac0a2a93b6ab6b314 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Sun, 24 Nov 2024 06:21:43 +0100 Subject: [PATCH 06/13] Added wrapper command --- core/edit/edit.talon | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/edit/edit.talon b/core/edit/edit.talon index cfb30f1b3f..f26c88937d 100644 --- a/core/edit/edit.talon +++ b/core/edit/edit.talon @@ -125,6 +125,7 @@ new line above: edit.line_insert_up() new line below | slap: edit.line_insert_down() # Insert padding with optional symbols +(padding): user.insert_between(" ", " ") (pad | padding) +: insert(" ") user.insert_many(symbol_key_list) @@ -133,6 +134,9 @@ new line below | slap: edit.line_insert_down() # Insert delimiter pairs : user.delimiter_pair_insert(delimiter_pair) +# Wrap selection with delimiter pairs + that: user.delimiter_pair_wrap_selection(delimiter_pair) + # Undo/redo undo that: edit.undo() redo that: edit.redo() From 3c1b43185c76525f9e3fe2eb251b81db38052fd5 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Sun, 24 Nov 2024 06:22:55 +0100 Subject: [PATCH 07/13] Added comment --- core/edit/edit_command_actions.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/edit/edit_command_actions.py b/core/edit/edit_command_actions.py index 26a743e6ba..3a0f9f3faa 100644 --- a/core/edit/edit_command_actions.py +++ b/core/edit/edit_command_actions.py @@ -4,6 +4,8 @@ from talon import Module, actions +# "simple" actions are actions that don't require any arguments. Only a type. +# select, copy, delete, etc. @dataclass class EditSimpleAction: type: str From 9fc28aa7eb6fe12821860c03b13912a4aa95516f Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Sun, 24 Nov 2024 06:45:53 +0100 Subject: [PATCH 08/13] Deprecated symbol commands --- BREAKING_CHANGES.txt | 2 + core/edit/delimiter_pair.talon-list | 6 ++ plugin/symbols/symbols.talon | 37 +---------- plugin/symbols/symbols_deprecated.talon | 83 +++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 36 deletions(-) create mode 100644 plugin/symbols/symbols_deprecated.talon diff --git a/BREAKING_CHANGES.txt b/BREAKING_CHANGES.txt index ba6219fd1e..5cd41b12c2 100644 --- a/BREAKING_CHANGES.txt +++ b/BREAKING_CHANGES.txt @@ -7,6 +7,8 @@ and when the change was applied given the delay between changes being submitted and the time they were reviewed and merged. --- +* 2024-11-24 Deprecated a bunch of symbol commands to insert delimited pairs + ("", '', []) in favor of the new `delimiter_pair` Talon list file. * 2024-09-07 Removed `get_list_from_csv` from `user_settings.py`. Please use the new `track_csv_list` decorator, which leverages Talon's `talon.watch` API for robustness on Talon launch. diff --git a/core/edit/delimiter_pair.talon-list b/core/edit/delimiter_pair.talon-list index ba08ca26a5..fa078aa345 100644 --- a/core/edit/delimiter_pair.talon-list +++ b/core/edit/delimiter_pair.talon-list @@ -11,4 +11,10 @@ curly: { } twin: "' '" quad: '" "' skis: ` ` +percentages: % % pad: space space + +escaped quad: '\\" \\"' +escaped twin: "\\' \\'" +escaped round: \( \) +escaped box: \[ \] \ No newline at end of file diff --git a/plugin/symbols/symbols.talon b/plugin/symbols/symbols.talon index 251407cc6b..048989cf10 100644 --- a/plugin/symbols/symbols.talon +++ b/plugin/symbols/symbols.talon @@ -1,44 +1,9 @@ new line: "\n" double dash: "--" triple quote: "'''" -(triple grave | triple back tick | gravy): insert("```") +triple grave | triple back tick | gravy: "```" (dot dot | dotdot): ".." ellipsis: "..." (comma and | spamma): ", " arrow: "->" dub arrow: "=>" -empty dub string: user.insert_between('"', '"') -empty escaped (dub string | dub quotes): user.insert_between('\\"', '\\"') -empty string: user.insert_between("'", "'") -empty escaped string: user.insert_between("\\'", "\\'") -(inside parens | args): user.insert_between("(", ")") -inside (squares | brackets | square brackets | list): user.insert_between("[", "]") -inside (braces | curly brackets): user.insert_between("{", "}") -inside percent: user.insert_between("%", "%") -inside (quotes | string): user.insert_between("'", "'") -inside (double quotes | dub quotes): user.insert_between('"', '"') -inside (graves | back ticks): user.insert_between("`", "`") -angle that: - text = edit.selected_text() - user.paste("<{text}>") -(square | bracket | square bracket) that: - text = edit.selected_text() - user.paste("[{text}]") -(brace | curly bracket) that: - text = edit.selected_text() - user.paste("{{{text}}}") -(parens | args) that: - text = edit.selected_text() - user.paste("({text})") -percent that: - text = edit.selected_text() - user.paste("%{text}%") -quote that: - text = edit.selected_text() - user.paste("'{text}'") -(double quote | dub quote) that: - text = edit.selected_text() - user.paste('"{text}"') -(grave | back tick) that: - text = edit.selected_text() - user.paste("`{text}`") diff --git a/plugin/symbols/symbols_deprecated.talon b/plugin/symbols/symbols_deprecated.talon new file mode 100644 index 0000000000..ea2a3c8587 --- /dev/null +++ b/plugin/symbols/symbols_deprecated.talon @@ -0,0 +1,83 @@ +empty dub string: + user.deprecate_command("2024-11-24", "empty dub string", "quad") + user.insert_between('"', '"') + +empty escaped (dub string | dub quotes): + user.deprecate_command("2024-11-24", "empty escaped (dub string | dub quotes)", "escaped quad") + user.insert_between('\\"', '\\"') + +empty string: + user.deprecate_command("2024-11-24", "empty string", "twin") + user.insert_between("'", "'") + +empty escaped string: + user.deprecate_command("2024-11-24", "empty escaped string", "escaped twin") + user.insert_between("\\'", "\\'") + +inside (parens | args): + user.deprecate_command("2024-11-24", "inside (parens | args)", "round") + user.insert_between("(", ")") + +inside (squares | brackets | square brackets | list): + user.deprecate_command("2024-11-24", "inside (squares | brackets | square brackets | list)", "box") + user.insert_between("[", "]") + +inside (braces | curly brackets): + user.deprecate_command("2024-11-24", "inside (braces | curly brackets)", "curly") + user.insert_between("{", "}") + +inside percent: + user.deprecate_command("2024-11-24", "inside percent", "percentages") + user.insert_between("%", "%") + +inside (quotes | string): + user.deprecate_command("2024-11-24", "inside (quotes | string)", "twin") + user.insert_between("'", "'") + +inside (double quotes | dub quotes): + user.deprecate_command("2024-11-24", "inside (double quotes | dub quotes)", "quad") + user.insert_between('"', '"') + +inside (graves | back ticks): + user.deprecate_command("2024-11-24", "inside (graves | back ticks)", "skis") + user.insert_between("`", "`") + +angle that: + user.deprecate_command("2024-11-24", "angle that", "diamond that") + text = edit.selected_text() + user.paste("<{text}>") + +(square | bracket | square bracket) that: + user.deprecate_command("2024-11-24", "(square | bracket | square bracket) that", "box that") + text = edit.selected_text() + user.paste("[{text}]") + +(brace | curly bracket) that: + user.deprecate_command("2024-11-24", "(brace | curly bracket) that", "curly that") + text = edit.selected_text() + user.paste("{{{text}}}") + +(parens | args) that: + user.deprecate_command("2024-11-24", "(parens | args) that", "round that") + text = edit.selected_text() + user.paste("({text})") + +percent that: + user.deprecate_command("2024-11-24", "percent that", "percentages that") + text = edit.selected_text() + user.paste("%{text}%") + +quote that: + user.deprecate_command("2024-11-24", "quote that", "twin that") + text = edit.selected_text() + user.paste("'{text}'") + +(double quote | dub quote) that: + user.deprecate_command("2024-11-24", "(double quote | dub quote) that", "quad that") + text = edit.selected_text() + user.paste('"{text}"') + +(grave | back tick) that: + user.deprecate_command("2024-11-24", "(grave | back tick) that", "skis that") + text = edit.selected_text() + user.paste("`{text}`") From 400fe48f40b4bae62d60554975fec9085f977402 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 24 Nov 2024 05:46:14 +0000 Subject: [PATCH 09/13] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- core/edit/delimiter_pair.talon-list | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/edit/delimiter_pair.talon-list b/core/edit/delimiter_pair.talon-list index fa078aa345..51aecaa6fa 100644 --- a/core/edit/delimiter_pair.talon-list +++ b/core/edit/delimiter_pair.talon-list @@ -17,4 +17,4 @@ pad: space space escaped quad: '\\" \\"' escaped twin: "\\' \\'" escaped round: \( \) -escaped box: \[ \] \ No newline at end of file +escaped box: \[ \] From 032842962f5f992e10a06b2b297c944d821f90cc Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Sun, 24 Nov 2024 07:49:00 +0100 Subject: [PATCH 10/13] Update core/edit/insert_between.py Co-authored-by: Jeff Knaus --- core/edit/insert_between.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/edit/insert_between.py b/core/edit/insert_between.py index 01dffb6b7e..5d35a1fa1d 100644 --- a/core/edit/insert_between.py +++ b/core/edit/insert_between.py @@ -5,7 +5,7 @@ @mod.action_class class module_actions: - def insert_between(before: str, after: str, middle=""): + def insert_between(before: str, after: str, middle: str=""): """Insert `before + after`, leaving cursor between `before` and `after`. Not entirely reliable if `after` contains newlines.""" actions.insert(f"{before}{middle}{after}") for _ in after: From 1618c16ffd1b23bff5853988fecef8a1c14df545 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 24 Nov 2024 06:49:13 +0000 Subject: [PATCH 11/13] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- core/edit/insert_between.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/edit/insert_between.py b/core/edit/insert_between.py index 5d35a1fa1d..2440546eac 100644 --- a/core/edit/insert_between.py +++ b/core/edit/insert_between.py @@ -5,7 +5,7 @@ @mod.action_class class module_actions: - def insert_between(before: str, after: str, middle: str=""): + def insert_between(before: str, after: str, middle: str = ""): """Insert `before + after`, leaving cursor between `before` and `after`. Not entirely reliable if `after` contains newlines.""" actions.insert(f"{before}{middle}{after}") for _ in after: From 210425820fecebafd4d85ad5dae107572eb5316e Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Sun, 24 Nov 2024 07:52:21 +0100 Subject: [PATCH 12/13] Moved to symbols file --- core/edit/edit.talon | 6 ------ plugin/symbols/symbols.talon | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/edit/edit.talon b/core/edit/edit.talon index f26c88937d..99e7f22f0f 100644 --- a/core/edit/edit.talon +++ b/core/edit/edit.talon @@ -131,12 +131,6 @@ new line below | slap: edit.line_insert_down() user.insert_many(symbol_key_list) insert(" ") -# Insert delimiter pairs -: user.delimiter_pair_insert(delimiter_pair) - -# Wrap selection with delimiter pairs - that: user.delimiter_pair_wrap_selection(delimiter_pair) - # Undo/redo undo that: edit.undo() redo that: edit.redo() diff --git a/plugin/symbols/symbols.talon b/plugin/symbols/symbols.talon index 048989cf10..5e8ecdbea9 100644 --- a/plugin/symbols/symbols.talon +++ b/plugin/symbols/symbols.talon @@ -7,3 +7,9 @@ ellipsis: "..." (comma and | spamma): ", " arrow: "->" dub arrow: "=>" + +# Insert delimiter pairs +: user.delimiter_pair_insert(delimiter_pair) + +# Wrap selection with delimiter pairs + that: user.delimiter_pair_wrap_selection(delimiter_pair) \ No newline at end of file From 42fcead6e0ac81367d02a134452fc73051b545b1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 24 Nov 2024 06:52:47 +0000 Subject: [PATCH 13/13] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- plugin/symbols/symbols.talon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/symbols/symbols.talon b/plugin/symbols/symbols.talon index 5e8ecdbea9..a44fc5a3db 100644 --- a/plugin/symbols/symbols.talon +++ b/plugin/symbols/symbols.talon @@ -12,4 +12,4 @@ dub arrow: "=>" : user.delimiter_pair_insert(delimiter_pair) # Wrap selection with delimiter pairs - that: user.delimiter_pair_wrap_selection(delimiter_pair) \ No newline at end of file + that: user.delimiter_pair_wrap_selection(delimiter_pair)