33from collections .abc import Container
44from datetime import datetime
55from pathlib import Path
6- from typing import Optional
6+ from typing import Callable , Optional
77
88from talon import Context , Module , actions , app , fs
99
3232"""
3333
3434
35+ GetType = Callable [[str , str ], str ]
36+
37+
3538def init_csv_and_watch_changes (
3639 filename : str ,
3740 default_values : dict [str , dict [str , str ]],
@@ -42,6 +45,7 @@ def init_csv_and_watch_changes(
4245 ctx : Context = Context (),
4346 no_update_file : bool = False ,
4447 pluralize_lists : list [str ] = [],
48+ get_type : Optional [GetType ] = None ,
4549):
4650 """
4751 Initialize a cursorless settings csv, creating it if necessary, and watch
@@ -106,6 +110,7 @@ def on_watch(path, flags):
106110 default_list_name ,
107111 pluralize_lists ,
108112 output_file_path ,
113+ get_type ,
109114 ctx ,
110115 )
111116
@@ -128,6 +133,7 @@ def on_watch(path, flags):
128133 default_list_name ,
129134 pluralize_lists ,
130135 output_file_path ,
136+ get_type ,
131137 ctx ,
132138 )
133139 else :
@@ -141,6 +147,7 @@ def on_watch(path, flags):
141147 default_list_name ,
142148 pluralize_lists ,
143149 output_file_path ,
150+ get_type ,
144151 ctx ,
145152 )
146153
@@ -188,6 +195,7 @@ def update_dicts(
188195 default_list_name : Optional [str ],
189196 pluralize_lists : list [str ],
190197 output_file_path : Path ,
198+ get_type : Optional [GetType ],
191199 ctx : Context ,
192200):
193201 # Create map with all default values
@@ -214,29 +222,24 @@ def update_dicts(
214222
215223 # Convert result map back to result list
216224 results = {res ["list" ]: {} for res in results_map .values ()}
217- output_file_dict = {}
225+ output_file_entries = []
218226 for obj in results_map .values ():
219227 value = obj ["value" ]
220228 key = obj ["key" ]
221- if not is_removed (key ):
222- for k in key .split ("|" ):
223- if value == "pasteFromClipboard" and k .endswith (" to" ):
224- # FIXME: This is a hack to work around the fact that the
225- # spoken form of the `pasteFromClipboard` action used to be
226- # "paste to", but now the spoken form is just "paste" and
227- # the "to" is part of the positional target. Users who had
228- # cursorless before this change would have "paste to" as
229- # their spoken form and so would need to say "paste to to".
230- k = k [:- 3 ]
231- results [obj ["list" ]][k .strip ()] = value
232- output_file_dict [value ] = k .strip ()
229+ spoken_forms = list (get_spoken_forms (value , key ))
230+ for spoken_form in spoken_forms :
231+ results [obj ["list" ]][spoken_form ] = value
232+ if get_type is not None and (entry_type := get_type (obj ["list" ], value )):
233+ output_file_entries .append (
234+ {"type" : entry_type , "id" : value , "spokenForms" : spoken_forms }
235+ )
233236
234237 # Assign result to talon context list
235238 assign_lists_to_context (ctx , results , pluralize_lists )
236239
237240 with open (output_file_path , "w" ) as out :
238241 try :
239- out .write (json .dumps (output_file_dict ))
242+ out .write (json .dumps ({ "version" : 0 , "entries" : output_file_entries } ))
240243 except Exception :
241244 error_message = f"Error writing spoken form json { output_file_path } "
242245 print (error_message )
@@ -256,6 +259,21 @@ def assign_lists_to_context(
256259 ctx .lists [list_plural_name ] = {pluralize (k ): v for k , v in dict .items ()}
257260
258261
262+ def get_spoken_forms (id : str , spoken_form : str ):
263+ if not is_removed (spoken_form ):
264+ for k in spoken_form .split ("|" ):
265+ if id == "pasteFromClipboard" and k .endswith (" to" ):
266+ # FIXME: This is a hack to work around the fact that the
267+ # spoken form of the `pasteFromClipboard` action used to be
268+ # "paste to", but now the spoken form is just "paste" and
269+ # the "to" is part of the positional target. Users who had
270+ # cursorless before this change would have "paste to" as
271+ # their spoken form and so would need to say "paste to to".
272+ k = k [:- 3 ]
273+
274+ yield k .strip ()
275+
276+
259277def update_file (
260278 path : Path ,
261279 headers : list [str ],
0 commit comments