From 04cf66ff12508cb57fd4445ffcc79870edd900e4 Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Tue, 30 Jul 2024 10:48:17 -0600 Subject: [PATCH 01/29] Start on three column CSV handling code --- core/modes/language_modes.py | 2 ++ core/user_settings.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/core/modes/language_modes.py b/core/modes/language_modes.py index 936c147b12..af3ca59c8b 100644 --- a/core/modes/language_modes.py +++ b/core/modes/language_modes.py @@ -1,5 +1,7 @@ from talon import Context, Module, actions +from ..user_settings import get_list_from_three_column_csv + # Maps language mode names to the extensions that activate them. Only put things # here which have a supported language mode; that's why there are so many # commented out entries. TODO: make this a csv file? diff --git a/core/user_settings.py b/core/user_settings.py index 2630f2c518..76e7e2d3be 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -75,3 +75,35 @@ def append_to_csv(filename: str, rows: dict[str, str]): writer.writerow([]) for key, value in rows.items(): writer.writerow([key] if key == value else [value, key]) + + +def get_list_from_three_column_csv( + filename: str, headers: tuple[str, str, str], default: dict[str, str] = {} +): + """Retrieves a list from a CSV of the form name,values,spoken_forms""" + path = _compute_csv_path(filename) + if not path.is_file(): + _create_three_columns_csv_from_default(path, headers, default) + + rows = _obtain_rows_from_csv(path) + + talon_list = _convert_rows_to_key_value_pairs(rows) + return talon_list + +def _create_three_columns_csv_from_default(path, headers, default): + pass + +def _obtain_rows_from_csv(path): + with resource.open(str(path), "r") as f: + rows = list(csv.reader(f)) + return rows + +def _convert_rows_to_key_value_pairs(rows): + key_value_pairs = {} + spoken_forms = {} + + +def _compute_csv_path(filename: str): + path = SETTINGS_DIR / filename + assert filename.endswith(".csv") + return path \ No newline at end of file From 7bad13a6fec5b06ab93fd55592187a0818a2eaf8 Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Tue, 30 Jul 2024 11:15:06 -0600 Subject: [PATCH 02/29] Draft parsing the file --- core/modes/language_modes.py | 2 +- core/user_settings.py | 44 +++++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/core/modes/language_modes.py b/core/modes/language_modes.py index af3ca59c8b..d5feda8ddc 100644 --- a/core/modes/language_modes.py +++ b/core/modes/language_modes.py @@ -1,6 +1,6 @@ from talon import Context, Module, actions -from ..user_settings import get_list_from_three_column_csv +from ..user_settings import get_key_value_pairs_and_spoken_forms_from_three_column_csv # Maps language mode names to the extensions that activate them. Only put things # here which have a supported language mode; that's why there are so many diff --git a/core/user_settings.py b/core/user_settings.py index 76e7e2d3be..d4dddb45aa 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -77,7 +77,7 @@ def append_to_csv(filename: str, rows: dict[str, str]): writer.writerow([key] if key == value else [value, key]) -def get_list_from_three_column_csv( +def get_key_value_pairs_and_spoken_forms_from_three_column_csv( filename: str, headers: tuple[str, str, str], default: dict[str, str] = {} ): """Retrieves a list from a CSV of the form name,values,spoken_forms""" @@ -87,7 +87,7 @@ def get_list_from_three_column_csv( rows = _obtain_rows_from_csv(path) - talon_list = _convert_rows_to_key_value_pairs(rows) + talon_list = _convert_rows_from_file_with_headers_to_key_value_pairs_and_spoken_forms(rows, filename, headers) return talon_list def _create_three_columns_csv_from_default(path, headers, default): @@ -98,10 +98,48 @@ def _obtain_rows_from_csv(path): rows = list(csv.reader(f)) return rows -def _convert_rows_to_key_value_pairs(rows): +def _convert_rows_from_file_with_headers_to_key_value_pairs_and_spoken_forms(rows, filename, headers): key_value_pairs = {} spoken_forms = {} + if len(rows) >= 2: + _complain_if_invalid_headers_found_in_file(rows, filename, headers) + for row in rows[1:]: + if len(row) == 0: + # Windows newlines are sometimes read as empty rows. :champagne: + continue + elif len(row) == 1: + print(f"{filename}: Ignoring row with only one value: {row}.") + continue + elif len(row) == 2: + name, values_text = row + new_spoken_forms_text = "" + else: + if len(row) > 3: + print( + f'"{filename}": More than three values in row: {row}.' + + " Ignoring the extras." + ) + name, values_text, new_spoken_forms_text = row[:3] + name = name.strip() + values = _get_intermediate_values_from_column(values_text) + key_value_pairs[name] = values + if new_spoken_forms_text: + spoken_forms[name] = _get_spoken_forms_from_column(new_spoken_forms_text) + return key_value_pairs, spoken_forms + +def _get_intermediate_values_from_column(values_text): + pass + +def _get_spoken_forms_from_column(spoken_forms_text): + pass +def _complain_if_invalid_headers_found_in_file(rows, expected_headers, filename): + actual_headers = rows[0] + if not actual_headers == list(expected_headers): + print( + f'"{filename}": Malformed headers - {actual_headers}.' + + f" Should be {list(expected_headers)}. Ignoring row." + ) def _compute_csv_path(filename: str): path = SETTINGS_DIR / filename From 2817402dda03ae3603479716b48d0c32ceb0dd00 Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Tue, 30 Jul 2024 11:27:14 -0600 Subject: [PATCH 03/29] Add parsing intermediate value parsing --- core/user_settings.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/core/user_settings.py b/core/user_settings.py index d4dddb45aa..6b95da81fb 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -128,10 +128,15 @@ def _convert_rows_from_file_with_headers_to_key_value_pairs_and_spoken_forms(row return key_value_pairs, spoken_forms def _get_intermediate_values_from_column(values_text): - pass + reader = csv.reader([values_text], delimiter=";") + values = next(reader) + return values def _get_spoken_forms_from_column(spoken_forms_text): - pass + reader = csv.reader([spoken_forms_text], delimiter=";") + spoken_forms = next(reader) + spoken_forms = [spoken_form.strip() for spoken_form in spoken_forms] + return spoken_forms def _complain_if_invalid_headers_found_in_file(rows, expected_headers, filename): actual_headers = rows[0] From ea9e81fad2360f691dbf470e9535d8af922fe597 Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Wed, 31 Jul 2024 10:08:07 -0600 Subject: [PATCH 04/29] Draft unification function --- core/user_settings.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/core/user_settings.py b/core/user_settings.py index 6b95da81fb..5c89b23fde 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -149,4 +149,15 @@ def _complain_if_invalid_headers_found_in_file(rows, expected_headers, filename) def _compute_csv_path(filename: str): path = SETTINGS_DIR / filename assert filename.endswith(".csv") - return path \ No newline at end of file + return path + +def compute_unified_dictionary_from_key_value_pairs_and_spoken_forms( + key_value_pairs, + spoken_forms + ): + result = { + name: key + for key in key_value_pairs + for name in spoken_forms.get(key, [key]) + } + return result \ No newline at end of file From be4aa56d0b6f7b3d93fbe036598b9400a0ac0064 Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Wed, 31 Jul 2024 10:13:35 -0600 Subject: [PATCH 05/29] Improve naming --- core/user_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/user_settings.py b/core/user_settings.py index 5c89b23fde..32cacf2396 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -151,7 +151,7 @@ def _compute_csv_path(filename: str): assert filename.endswith(".csv") return path -def compute_unified_dictionary_from_key_value_pairs_and_spoken_forms( +def compute_spoken_form_to_key_dictionary( key_value_pairs, spoken_forms ): From 7fa6e0be3c6917444a8060b61fc7fde0eafa18dc Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Wed, 31 Jul 2024 14:43:07 -0600 Subject: [PATCH 06/29] Finish drafting file handling --- core/user_settings.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/core/user_settings.py b/core/user_settings.py index 32cacf2396..6ccb2fe590 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -1,5 +1,6 @@ import csv import os +import io from pathlib import Path from talon import resource @@ -91,7 +92,26 @@ def get_key_value_pairs_and_spoken_forms_from_three_column_csv( return talon_list def _create_three_columns_csv_from_default(path, headers, default): - pass + with open(path, "w", encoding="utf-8", newline="") as file: + writer = csv.writer(file) + writer.writerow(headers) + for row_tuple in default.: + row = _compute_row_for_three_column_csv(row_tuple) + writer.writerow(row) + +def _compute_row_for_three_column_csv(input_tuple): + name, values, spoken_forms = input_tuple + values_text = _compute_values_packed_into_column(values) + spoken_forms_text = _compute_values_packed_into_column(spoken_forms) + row = [name, values_text, spoken_forms_text] + return row + +def _compute_values_packed_into_column(values): + output = io.StringIO() + writer = csv.writer(output, delimiter=";") + writer.writerow(values) + result = output.getvalue().strip() + return result def _obtain_rows_from_csv(path): with resource.open(str(path), "r") as f: From d005db00e1ce885c4348c01cb2f7e855a29d655d Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Wed, 31 Jul 2024 14:45:13 -0600 Subject: [PATCH 07/29] Fix syntax --- core/user_settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/user_settings.py b/core/user_settings.py index 6ccb2fe590..5237873f64 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -79,7 +79,7 @@ def append_to_csv(filename: str, rows: dict[str, str]): def get_key_value_pairs_and_spoken_forms_from_three_column_csv( - filename: str, headers: tuple[str, str, str], default: dict[str, str] = {} + filename: str, headers: tuple[str, str, str], default: list[str, tuple[str], tuple[str]] ): """Retrieves a list from a CSV of the form name,values,spoken_forms""" path = _compute_csv_path(filename) @@ -95,7 +95,7 @@ def _create_three_columns_csv_from_default(path, headers, default): with open(path, "w", encoding="utf-8", newline="") as file: writer = csv.writer(file) writer.writerow(headers) - for row_tuple in default.: + for row_tuple in default: row = _compute_row_for_three_column_csv(row_tuple) writer.writerow(row) From e4fd3f0271c66ac8e3caf8428ee04160f082e7c5 Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Wed, 31 Jul 2024 15:27:36 -0600 Subject: [PATCH 08/29] Make some minor fixes --- core/user_settings.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/core/user_settings.py b/core/user_settings.py index 5237873f64..4fd25316ae 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -122,7 +122,7 @@ def _convert_rows_from_file_with_headers_to_key_value_pairs_and_spoken_forms(row key_value_pairs = {} spoken_forms = {} if len(rows) >= 2: - _complain_if_invalid_headers_found_in_file(rows, filename, headers) + _complain_if_invalid_headers_found_in_file(rows, headers, filename) for row in rows[1:]: if len(row) == 0: # Windows newlines are sometimes read as empty rows. :champagne: @@ -175,9 +175,15 @@ def compute_spoken_form_to_key_dictionary( key_value_pairs, spoken_forms ): - result = { - name: key - for key in key_value_pairs - for name in spoken_forms.get(key, [key]) - } - return result \ No newline at end of file + if spoken_forms: + result = { + name: key + for key in key_value_pairs + for name in spoken_forms.get(key, [key]) + } + else: + result = { + key: key + for key in key_value_pairs + } + return result From f4306553594ffac82c3ea70874cdc354da3d01f6 Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Wed, 31 Jul 2024 15:44:43 -0600 Subject: [PATCH 09/29] Stop using deprecated function --- core/user_settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/user_settings.py b/core/user_settings.py index 4fd25316ae..f0dc64b61c 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -1,4 +1,4 @@ -import csv +Uimport csv import os import io from pathlib import Path @@ -114,7 +114,7 @@ def _compute_values_packed_into_column(values): return result def _obtain_rows_from_csv(path): - with resource.open(str(path), "r") as f: + with open(str(path), "r") as f: rows = list(csv.reader(f)) return rows From 70c2eab5cbfd4a2af3ba834287f283399a1ce9bc Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Wed, 31 Jul 2024 16:06:27 -0600 Subject: [PATCH 10/29] Handle different tuple sizes --- core/user_settings.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/core/user_settings.py b/core/user_settings.py index f0dc64b61c..507d173a27 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -100,10 +100,16 @@ def _create_three_columns_csv_from_default(path, headers, default): writer.writerow(row) def _compute_row_for_three_column_csv(input_tuple): - name, values, spoken_forms = input_tuple + if len(input_tuple) == 3: + name, values, spoken_forms = input_tuple + else: + name, values = input_tuple + spoken_forms = None values_text = _compute_values_packed_into_column(values) - spoken_forms_text = _compute_values_packed_into_column(spoken_forms) - row = [name, values_text, spoken_forms_text] + row = [name, values_text] + if spoken_forms: + spoken_forms_text = _compute_values_packed_into_column(spoken_forms) + row.append(spoken_forms_text) return row def _compute_values_packed_into_column(values): From 3f1fd5e3956bb6e3c1c0a49560782bdc091266af Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Wed, 31 Jul 2024 16:06:56 -0600 Subject: [PATCH 11/29] Remove accidental character --- core/user_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/user_settings.py b/core/user_settings.py index 507d173a27..d1bac10092 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -1,4 +1,4 @@ -Uimport csv +import csv import os import io from pathlib import Path From b7e8b9e742822d01d5d101070a325ffe47f4a336 Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Wed, 31 Jul 2024 16:10:32 -0600 Subject: [PATCH 12/29] Make name less confusing --- core/user_settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/user_settings.py b/core/user_settings.py index d1bac10092..bcc07f5ffe 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -88,8 +88,8 @@ def get_key_value_pairs_and_spoken_forms_from_three_column_csv( rows = _obtain_rows_from_csv(path) - talon_list = _convert_rows_from_file_with_headers_to_key_value_pairs_and_spoken_forms(rows, filename, headers) - return talon_list + result = _convert_rows_from_file_with_headers_to_key_value_pairs_and_spoken_forms(rows, filename, headers) + return result def _create_three_columns_csv_from_default(path, headers, default): with open(path, "w", encoding="utf-8", newline="") as file: From 9ebff4cdc6921f17f5967aebcadfa829b1d7d669 Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Wed, 31 Jul 2024 17:38:40 -0600 Subject: [PATCH 13/29] Watch file --- core/modes/language_modes.py | 10 ++++++++-- core/user_settings.py | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/core/modes/language_modes.py b/core/modes/language_modes.py index d5feda8ddc..2ca92305f6 100644 --- a/core/modes/language_modes.py +++ b/core/modes/language_modes.py @@ -1,6 +1,12 @@ -from talon import Context, Module, actions +from talon import Context, Module, actions, resource + +from ..user_settings import get_key_value_pairs_and_spoken_forms_from_three_column_csv, compute_csv_path + +settings_filepath = compute_csv_path("language_modes.csv") +@resource.watch(settings_filepath) +def load_language_modes(path: str): + pass -from ..user_settings import get_key_value_pairs_and_spoken_forms_from_three_column_csv # Maps language mode names to the extensions that activate them. Only put things # here which have a supported language mode; that's why there are so many diff --git a/core/user_settings.py b/core/user_settings.py index bcc07f5ffe..28573088d1 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -82,7 +82,7 @@ def get_key_value_pairs_and_spoken_forms_from_three_column_csv( filename: str, headers: tuple[str, str, str], default: list[str, tuple[str], tuple[str]] ): """Retrieves a list from a CSV of the form name,values,spoken_forms""" - path = _compute_csv_path(filename) + path = compute_csv_path(filename) if not path.is_file(): _create_three_columns_csv_from_default(path, headers, default) @@ -172,7 +172,7 @@ def _complain_if_invalid_headers_found_in_file(rows, expected_headers, filename) + f" Should be {list(expected_headers)}. Ignoring row." ) -def _compute_csv_path(filename: str): +def compute_csv_path(filename: str): path = SETTINGS_DIR / filename assert filename.endswith(".csv") return path From f37298d14cdd86946191f89a56db906b1b6388d0 Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Thu, 1 Aug 2024 15:34:39 -0600 Subject: [PATCH 14/29] Draft refactoring of language modes --- core/modes/language_modes.py | 153 +++++++++++++++++------------------ core/user_settings.py | 2 +- 2 files changed, 74 insertions(+), 81 deletions(-) diff --git a/core/modes/language_modes.py b/core/modes/language_modes.py index 2ca92305f6..974054aa19 100644 --- a/core/modes/language_modes.py +++ b/core/modes/language_modes.py @@ -1,73 +1,6 @@ from talon import Context, Module, actions, resource -from ..user_settings import get_key_value_pairs_and_spoken_forms_from_three_column_csv, compute_csv_path - -settings_filepath = compute_csv_path("language_modes.csv") -@resource.watch(settings_filepath) -def load_language_modes(path: str): - pass - - -# Maps language mode names to the extensions that activate them. Only put things -# here which have a supported language mode; that's why there are so many -# commented out entries. TODO: make this a csv file? -language_extensions = { - # 'assembly': 'asm s', - # 'bash': 'bashbook sh', - "batch": "bat", - "c": "c h", - # 'cmake': 'cmake', - # "cplusplus": "cpp hpp", - "csharp": "cs", - "css": "css", - # 'elisp': 'el', - # 'elm': 'elm', - "gdb": "gdb", - "go": "go", - "java": "java", - "javascript": "js", - "javascriptreact": "jsx", - # "json": "json", - "kotlin": "kt", - "lua": "lua", - "markdown": "md", - # 'perl': 'pl', - "php": "php", - # 'powershell': 'ps1', - "python": "py", - "protobuf": "proto", - "r": "r", - # 'racket': 'rkt', - "ruby": "rb", - "rust": "rs", - "scala": "scala", - "scss": "scss", - # 'snippets': 'snippets', - "sql": "sql", - "stata": "do ado", - "talon": "talon", - "talonlist": "talon-list", - "terraform": "tf", - "tex": "tex", - "typescript": "ts", - "typescriptreact": "tsx", - # 'vba': 'vba', - "vimscript": "vim vimrc", - # html doesn't actually have a language mode, but we do have snippets. - "html": "html", -} - -# Override speakable forms for language modes. If not present, a language mode's -# name is used directly. -language_name_overrides = { - "cplusplus": ["see plus plus"], - "csharp": ["see sharp"], - "css": ["c s s"], - "gdb": ["g d b"], - "go": ["go", "go lang", "go language"], - "r": ["are language"], - "tex": ["tech", "lay tech", "latex"], -} +from ..user_settings import get_key_value_pairs_and_spoken_forms_from_three_column_csv, compute_csv_path, compute_spoken_form_to_key_dictionary mod = Module() @@ -82,20 +15,80 @@ def load_language_modes(path: str): mod.tag("code_language_forced", "This tag is active when a language mode is forced") mod.list("language_mode", desc="Name of a programming language mode.") -ctx.lists["self.language_mode"] = { - name: language - for language in language_extensions - for name in language_name_overrides.get(language, [language]) -} - # Maps extension to languages. -extension_lang_map = { - "." + ext: language - for language, extensions in language_extensions.items() - for ext in extensions.split() -} +extension_lang_map = None -language_ids = set(language_extensions.keys()) +language_ids = None +language_extensions = None + +settings_filepath = compute_csv_path("language_modes.csv") +@resource.watch(settings_filepath) +def load_language_modes(path: str): + # Maps language mode names to the extensions that activate them. Only put things + # here which have a supported language mode; that's why there are so many + # commented out entries. TODO: make this a csv file? + default_csv_contents = [ + #['assembly', ('asm', 's'),], + #['bash', ('bashbook', 'sh'),], + ["batch", ("bat"),], + ["c", ("c", "h"),], + #['cmake', ('cmake'),], + #["cplusplus", ("cpp hpp"), ("see plus plus")], + ["csharp", ("cs"), ("see sharp")], + ["css", ("css"), ("c s s")], + #['elisp', ('el'),], + #['elm', ('elm'),], + ["gdb", ("gdb"), ("g d b")], + ["go", ("go"), ("go", "go lang", "go language")], + ["java", ("java"),], + ["javascript", ("js"),], + ["javascriptreact", ("jsx"),], + #["json", ("json"),], + ["kotlin", ("kt"),], + ["lua", ("lua"),], + ["markdown", ("md"),], + #['perl', ('pl'),], + ["php", ("php"),], + #['powershell', ('ps1'),], + ["python", ("py"),], + ["protobuf", ("proto"),], + ["r", ("r"), ("are language")], + #['racket', ('rkt'),], + ["ruby", ("rb"),], + ["rust", ("rs"),], + ["scala", ("scala"),], + ["scss", ("scss"),], + #['snippets', ('snippets'),], + ["sql", ("sql"),], + ["stata", ("do", "ado"),], + ["talon", ("talon"),], + ["talonlist", ("talon-list"),], + ["terraform", ("tf"),], + ["tex", ("tex"), ("tech", "lay tech", "latex")], + ["typescript", ("ts"),], + ["typescriptreact", ("tsx"),], + #['vba', ('vba'),], + ["vimscript", ("vim", "vimrc"),], + #htm doesn't actually have a language moded, but we do have snippets. + ["html", ("html"),], + ] + + global language_extensions + language_extensions, language_spoken_forms = get_key_value_pairs_and_spoken_forms_from_three_column_csv( + path, + ["language", "extensions", "spoken_forms"], + default_csv_contents, + ) + ctx.lists["self.language_mode"] = compute_spoken_form_to_key_dictionary(language_extensions, language_spoken_forms) + global extension_lang_map + extension_lang_map = { + "." + ext: language + for language, extensions in language_extensions.items() + for ext in extensions + } + global language_ids + language_ids = set(language_extensions.keys()) +load_language_modes(settings_filepath) forced_language = "" diff --git a/core/user_settings.py b/core/user_settings.py index 28573088d1..3d31f0f9d6 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -79,7 +79,7 @@ def append_to_csv(filename: str, rows: dict[str, str]): def get_key_value_pairs_and_spoken_forms_from_three_column_csv( - filename: str, headers: tuple[str, str, str], default: list[str, tuple[str], tuple[str]] + filename: str, headers: tuple[str, str, str], default: list[list[str, tuple[str], tuple[str]]] ): """Retrieves a list from a CSV of the form name,values,spoken_forms""" path = compute_csv_path(filename) From 76a9df6bff08a99eddf63f8402c8557b6d0b999d Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Fri, 2 Aug 2024 17:22:02 -0600 Subject: [PATCH 15/29] Correctly use name, fix single item tuples --- core/modes/language_modes.py | 75 ++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/core/modes/language_modes.py b/core/modes/language_modes.py index 974054aa19..099a1fd6a4 100644 --- a/core/modes/language_modes.py +++ b/core/modes/language_modes.py @@ -21,7 +21,8 @@ language_ids = None language_extensions = None -settings_filepath = compute_csv_path("language_modes.csv") +SETTINGS_FILENAME = "language_modes.csv" +settings_filepath = compute_csv_path(SETTINGS_FILENAME) @resource.watch(settings_filepath) def load_language_modes(path: str): # Maps language mode names to the extensions that activate them. Only put things @@ -30,52 +31,52 @@ def load_language_modes(path: str): default_csv_contents = [ #['assembly', ('asm', 's'),], #['bash', ('bashbook', 'sh'),], - ["batch", ("bat"),], + ["batch", ("bat",),], ["c", ("c", "h"),], - #['cmake', ('cmake'),], - #["cplusplus", ("cpp hpp"), ("see plus plus")], - ["csharp", ("cs"), ("see sharp")], - ["css", ("css"), ("c s s")], + #['cmake', ('cmake',),], + #["cplusplus", ("cpp hpp",), ("see plus plus",)], + ["csharp", ("cs",), ("see sharp",)], + ["css", ("css",), ("c s s",)], #['elisp', ('el'),], #['elm', ('elm'),], - ["gdb", ("gdb"), ("g d b")], - ["go", ("go"), ("go", "go lang", "go language")], - ["java", ("java"),], - ["javascript", ("js"),], - ["javascriptreact", ("jsx"),], - #["json", ("json"),], - ["kotlin", ("kt"),], - ["lua", ("lua"),], - ["markdown", ("md"),], - #['perl', ('pl'),], - ["php", ("php"),], - #['powershell', ('ps1'),], - ["python", ("py"),], - ["protobuf", ("proto"),], - ["r", ("r"), ("are language")], - #['racket', ('rkt'),], - ["ruby", ("rb"),], - ["rust", ("rs"),], - ["scala", ("scala"),], - ["scss", ("scss"),], - #['snippets', ('snippets'),], - ["sql", ("sql"),], + ["gdb", ("gdb",), ("g d b",)], + ["go", ("go",), ("go", "go lang", "go language")], + ["java", ("java",),], + ["javascript", ("js",),], + ["javascriptreact", ("jsx",),], + #["json", ("json",),], + ["kotlin", ("kt",),], + ["lua", ("lua",),], + ["markdown", ("md",),], + #['perl', ('pl',),], + ["php", ("php",),], + #['powershell', ('ps1',),], + ["python", ("py",),], + ["protobuf", ("proto",),], + ["r", ("r"), ("are language",)], + #['racket', ('rkt,'),], + ["ruby", ("rb",),], + ["rust", ("rs",),], + ["scala", ("scala",),], + ["scss", ("scss",),], + #['snippets', ('snippets',),], + ["sql", ("sql",),], ["stata", ("do", "ado"),], - ["talon", ("talon"),], - ["talonlist", ("talon-list"),], - ["terraform", ("tf"),], - ["tex", ("tex"), ("tech", "lay tech", "latex")], - ["typescript", ("ts"),], - ["typescriptreact", ("tsx"),], - #['vba', ('vba'),], + ["talon", ("talon",),], + ["talonlist", ("talon-list",),], + ["terraform", ("tf",),], + ["tex", ("tex",), ("tech", "lay tech", "latex")], + ["typescript", ("ts",),], + ["typescriptreact", ("tsx",),], + #['vba', ('vba',),], ["vimscript", ("vim", "vimrc"),], #htm doesn't actually have a language moded, but we do have snippets. - ["html", ("html"),], + ["html", ("html",),], ] global language_extensions language_extensions, language_spoken_forms = get_key_value_pairs_and_spoken_forms_from_three_column_csv( - path, + SETTINGS_FILENAME, ["language", "extensions", "spoken_forms"], default_csv_contents, ) From a8d0a96c982fb1a819bab5e0c5dcf2c3e729b53f Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Fri, 2 Aug 2024 17:34:00 -0600 Subject: [PATCH 16/29] Make sure file exists before loading as a resource --- core/modes/language_modes.py | 24 ++++++++++++++---------- core/user_settings.py | 13 ++++++++++--- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/core/modes/language_modes.py b/core/modes/language_modes.py index 099a1fd6a4..3b3768eaf3 100644 --- a/core/modes/language_modes.py +++ b/core/modes/language_modes.py @@ -1,6 +1,7 @@ from talon import Context, Module, actions, resource -from ..user_settings import get_key_value_pairs_and_spoken_forms_from_three_column_csv, compute_csv_path, compute_spoken_form_to_key_dictionary +from ..user_settings import get_key_value_pairs_and_spoken_forms_from_three_column_csv, compute_csv_path, compute_spoken_form_to_key_dictionary, \ + create_three_columns_csv_from_default_if_nonexistent mod = Module() @@ -23,9 +24,11 @@ SETTINGS_FILENAME = "language_modes.csv" settings_filepath = compute_csv_path(SETTINGS_FILENAME) -@resource.watch(settings_filepath) -def load_language_modes(path: str): - # Maps language mode names to the extensions that activate them. Only put things + +LANGUAGE_HEADERS = ["language", "extensions", "spoken_forms"] + +def make_sure_settings_file_exists(): + # Maps language mode names to the extensions that activate them and language spoken forms. Only put things # here which have a supported language mode; that's why there are so many # commented out entries. TODO: make this a csv file? default_csv_contents = [ @@ -39,9 +42,6 @@ def load_language_modes(path: str): ["css", ("css",), ("c s s",)], #['elisp', ('el'),], #['elm', ('elm'),], - ["gdb", ("gdb",), ("g d b",)], - ["go", ("go",), ("go", "go lang", "go language")], - ["java", ("java",),], ["javascript", ("js",),], ["javascriptreact", ("jsx",),], #["json", ("json",),], @@ -73,12 +73,16 @@ def load_language_modes(path: str): #htm doesn't actually have a language moded, but we do have snippets. ["html", ("html",),], ] - + create_three_columns_csv_from_default_if_nonexistent(SETTINGS_FILENAME, LANGUAGE_HEADERS, default_csv_contents) +make_sure_settings_file_exists() + +@resource.watch(settings_filepath) +def load_language_modes(path: str): + make_sure_settings_file_exists() global language_extensions language_extensions, language_spoken_forms = get_key_value_pairs_and_spoken_forms_from_three_column_csv( SETTINGS_FILENAME, - ["language", "extensions", "spoken_forms"], - default_csv_contents, + LANGUAGE_HEADERS, ) ctx.lists["self.language_mode"] = compute_spoken_form_to_key_dictionary(language_extensions, language_spoken_forms) global extension_lang_map diff --git a/core/user_settings.py b/core/user_settings.py index 3d31f0f9d6..507b5c7ba8 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -79,18 +79,25 @@ def append_to_csv(filename: str, rows: dict[str, str]): def get_key_value_pairs_and_spoken_forms_from_three_column_csv( - filename: str, headers: tuple[str, str, str], default: list[list[str, tuple[str], tuple[str]]] + filename: str, headers: tuple[str, str, str] ): """Retrieves a list from a CSV of the form name,values,spoken_forms""" path = compute_csv_path(filename) - if not path.is_file(): - _create_three_columns_csv_from_default(path, headers, default) rows = _obtain_rows_from_csv(path) result = _convert_rows_from_file_with_headers_to_key_value_pairs_and_spoken_forms(rows, filename, headers) return result +def create_three_columns_csv_from_default_if_nonexistent( + filename: str, + headers: tuple[str, str, str], + default: list[list[str, tuple[str], tuple[str]]] +): + path = compute_csv_path(filename) + if not path.is_file(): + _create_three_columns_csv_from_default(path, headers, default) + def _create_three_columns_csv_from_default(path, headers, default): with open(path, "w", encoding="utf-8", newline="") as file: writer = csv.writer(file) From e2d4c917efdc8298b2898c8bf29c1b280626aaec Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 3 Aug 2024 16:11:01 +0000 Subject: [PATCH 17/29] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- core/modes/language_modes.py | 173 ++++++++++++++++++++++++++--------- core/user_settings.py | 53 ++++++----- 2 files changed, 161 insertions(+), 65 deletions(-) diff --git a/core/modes/language_modes.py b/core/modes/language_modes.py index 3b3768eaf3..8d0587110e 100644 --- a/core/modes/language_modes.py +++ b/core/modes/language_modes.py @@ -1,7 +1,11 @@ from talon import Context, Module, actions, resource -from ..user_settings import get_key_value_pairs_and_spoken_forms_from_three_column_csv, compute_csv_path, compute_spoken_form_to_key_dictionary, \ - create_three_columns_csv_from_default_if_nonexistent +from ..user_settings import ( + compute_csv_path, + compute_spoken_form_to_key_dictionary, + create_three_columns_csv_from_default_if_nonexistent, + get_key_value_pairs_and_spoken_forms_from_three_column_csv, +) mod = Module() @@ -27,64 +31,143 @@ LANGUAGE_HEADERS = ["language", "extensions", "spoken_forms"] + def make_sure_settings_file_exists(): # Maps language mode names to the extensions that activate them and language spoken forms. Only put things # here which have a supported language mode; that's why there are so many # commented out entries. TODO: make this a csv file? default_csv_contents = [ - #['assembly', ('asm', 's'),], - #['bash', ('bashbook', 'sh'),], - ["batch", ("bat",),], - ["c", ("c", "h"),], - #['cmake', ('cmake',),], - #["cplusplus", ("cpp hpp",), ("see plus plus",)], + # ['assembly', ('asm', 's'),], + # ['bash', ('bashbook', 'sh'),], + [ + "batch", + ("bat",), + ], + [ + "c", + ("c", "h"), + ], + # ['cmake', ('cmake',),], + # ["cplusplus", ("cpp hpp",), ("see plus plus",)], ["csharp", ("cs",), ("see sharp",)], ["css", ("css",), ("c s s",)], - #['elisp', ('el'),], - #['elm', ('elm'),], - ["javascript", ("js",),], - ["javascriptreact", ("jsx",),], - #["json", ("json",),], - ["kotlin", ("kt",),], - ["lua", ("lua",),], - ["markdown", ("md",),], - #['perl', ('pl',),], - ["php", ("php",),], - #['powershell', ('ps1',),], - ["python", ("py",),], - ["protobuf", ("proto",),], + # ['elisp', ('el'),], + # ['elm', ('elm'),], + [ + "javascript", + ("js",), + ], + [ + "javascriptreact", + ("jsx",), + ], + # ["json", ("json",),], + [ + "kotlin", + ("kt",), + ], + [ + "lua", + ("lua",), + ], + [ + "markdown", + ("md",), + ], + # ['perl', ('pl',),], + [ + "php", + ("php",), + ], + # ['powershell', ('ps1',),], + [ + "python", + ("py",), + ], + [ + "protobuf", + ("proto",), + ], ["r", ("r"), ("are language",)], - #['racket', ('rkt,'),], - ["ruby", ("rb",),], - ["rust", ("rs",),], - ["scala", ("scala",),], - ["scss", ("scss",),], - #['snippets', ('snippets',),], - ["sql", ("sql",),], - ["stata", ("do", "ado"),], - ["talon", ("talon",),], - ["talonlist", ("talon-list",),], - ["terraform", ("tf",),], + # ['racket', ('rkt,'),], + [ + "ruby", + ("rb",), + ], + [ + "rust", + ("rs",), + ], + [ + "scala", + ("scala",), + ], + [ + "scss", + ("scss",), + ], + # ['snippets', ('snippets',),], + [ + "sql", + ("sql",), + ], + [ + "stata", + ("do", "ado"), + ], + [ + "talon", + ("talon",), + ], + [ + "talonlist", + ("talon-list",), + ], + [ + "terraform", + ("tf",), + ], ["tex", ("tex",), ("tech", "lay tech", "latex")], - ["typescript", ("ts",),], - ["typescriptreact", ("tsx",),], - #['vba', ('vba',),], - ["vimscript", ("vim", "vimrc"),], - #htm doesn't actually have a language moded, but we do have snippets. - ["html", ("html",),], + [ + "typescript", + ("ts",), + ], + [ + "typescriptreact", + ("tsx",), + ], + # ['vba', ('vba',),], + [ + "vimscript", + ("vim", "vimrc"), + ], + # htm doesn't actually have a language moded, but we do have snippets. + [ + "html", + ("html",), + ], ] - create_three_columns_csv_from_default_if_nonexistent(SETTINGS_FILENAME, LANGUAGE_HEADERS, default_csv_contents) + create_three_columns_csv_from_default_if_nonexistent( + SETTINGS_FILENAME, LANGUAGE_HEADERS, default_csv_contents + ) + + make_sure_settings_file_exists() + @resource.watch(settings_filepath) def load_language_modes(path: str): - make_sure_settings_file_exists() + make_sure_settings_file_exists() global language_extensions - language_extensions, language_spoken_forms = get_key_value_pairs_and_spoken_forms_from_three_column_csv( - SETTINGS_FILENAME, - LANGUAGE_HEADERS, + language_extensions, language_spoken_forms = ( + get_key_value_pairs_and_spoken_forms_from_three_column_csv( + SETTINGS_FILENAME, + LANGUAGE_HEADERS, + ) + ) + ctx.lists["self.language_mode"] = compute_spoken_form_to_key_dictionary( + language_extensions, language_spoken_forms ) - ctx.lists["self.language_mode"] = compute_spoken_form_to_key_dictionary(language_extensions, language_spoken_forms) global extension_lang_map extension_lang_map = { "." + ext: language @@ -93,6 +176,8 @@ def load_language_modes(path: str): } global language_ids language_ids = set(language_extensions.keys()) + + load_language_modes(settings_filepath) forced_language = "" diff --git a/core/user_settings.py b/core/user_settings.py index 507b5c7ba8..028905aeb7 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -1,6 +1,6 @@ import csv -import os import io +import os from pathlib import Path from talon import resource @@ -79,25 +79,29 @@ def append_to_csv(filename: str, rows: dict[str, str]): def get_key_value_pairs_and_spoken_forms_from_three_column_csv( - filename: str, headers: tuple[str, str, str] + filename: str, headers: tuple[str, str, str] ): """Retrieves a list from a CSV of the form name,values,spoken_forms""" - path = compute_csv_path(filename) - + path = compute_csv_path(filename) + rows = _obtain_rows_from_csv(path) - - result = _convert_rows_from_file_with_headers_to_key_value_pairs_and_spoken_forms(rows, filename, headers) + + result = _convert_rows_from_file_with_headers_to_key_value_pairs_and_spoken_forms( + rows, filename, headers + ) return result + def create_three_columns_csv_from_default_if_nonexistent( filename: str, headers: tuple[str, str, str], - default: list[list[str, tuple[str], tuple[str]]] + default: list[list[str, tuple[str], tuple[str]]], ): path = compute_csv_path(filename) if not path.is_file(): _create_three_columns_csv_from_default(path, headers, default) + def _create_three_columns_csv_from_default(path, headers, default): with open(path, "w", encoding="utf-8", newline="") as file: writer = csv.writer(file) @@ -106,6 +110,7 @@ def _create_three_columns_csv_from_default(path, headers, default): row = _compute_row_for_three_column_csv(row_tuple) writer.writerow(row) + def _compute_row_for_three_column_csv(input_tuple): if len(input_tuple) == 3: name, values, spoken_forms = input_tuple @@ -119,6 +124,7 @@ def _compute_row_for_three_column_csv(input_tuple): row.append(spoken_forms_text) return row + def _compute_values_packed_into_column(values): output = io.StringIO() writer = csv.writer(output, delimiter=";") @@ -126,12 +132,16 @@ def _compute_values_packed_into_column(values): result = output.getvalue().strip() return result + def _obtain_rows_from_csv(path): with open(str(path), "r") as f: rows = list(csv.reader(f)) return rows -def _convert_rows_from_file_with_headers_to_key_value_pairs_and_spoken_forms(rows, filename, headers): + +def _convert_rows_from_file_with_headers_to_key_value_pairs_and_spoken_forms( + rows, filename, headers +): key_value_pairs = {} spoken_forms = {} if len(rows) >= 2: @@ -149,28 +159,33 @@ def _convert_rows_from_file_with_headers_to_key_value_pairs_and_spoken_forms(row else: if len(row) > 3: print( - f'"{filename}": More than three values in row: {row}.' - + " Ignoring the extras." - ) + f'"{filename}": More than three values in row: {row}.' + + " Ignoring the extras." + ) name, values_text, new_spoken_forms_text = row[:3] name = name.strip() values = _get_intermediate_values_from_column(values_text) key_value_pairs[name] = values if new_spoken_forms_text: - spoken_forms[name] = _get_spoken_forms_from_column(new_spoken_forms_text) + spoken_forms[name] = _get_spoken_forms_from_column( + new_spoken_forms_text + ) return key_value_pairs, spoken_forms - + + def _get_intermediate_values_from_column(values_text): reader = csv.reader([values_text], delimiter=";") values = next(reader) return values + def _get_spoken_forms_from_column(spoken_forms_text): reader = csv.reader([spoken_forms_text], delimiter=";") spoken_forms = next(reader) spoken_forms = [spoken_form.strip() for spoken_form in spoken_forms] return spoken_forms + def _complain_if_invalid_headers_found_in_file(rows, expected_headers, filename): actual_headers = rows[0] if not actual_headers == list(expected_headers): @@ -179,15 +194,14 @@ def _complain_if_invalid_headers_found_in_file(rows, expected_headers, filename) + f" Should be {list(expected_headers)}. Ignoring row." ) + def compute_csv_path(filename: str): path = SETTINGS_DIR / filename assert filename.endswith(".csv") return path -def compute_spoken_form_to_key_dictionary( - key_value_pairs, - spoken_forms - ): + +def compute_spoken_form_to_key_dictionary(key_value_pairs, spoken_forms): if spoken_forms: result = { name: key @@ -195,8 +209,5 @@ def compute_spoken_form_to_key_dictionary( for name in spoken_forms.get(key, [key]) } else: - result = { - key: key - for key in key_value_pairs - } + result = {key: key for key in key_value_pairs} return result From c98009a7e190e62c42f8b520ff6d9b07ce5f5d69 Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Sun, 4 Aug 2024 18:35:59 -0600 Subject: [PATCH 18/29] Add missing defaults --- core/modes/language_modes.py | 144 ++++++++++------------------------- 1 file changed, 39 insertions(+), 105 deletions(-) diff --git a/core/modes/language_modes.py b/core/modes/language_modes.py index 8d0587110e..434c4b6a71 100644 --- a/core/modes/language_modes.py +++ b/core/modes/language_modes.py @@ -37,115 +37,49 @@ def make_sure_settings_file_exists(): # here which have a supported language mode; that's why there are so many # commented out entries. TODO: make this a csv file? default_csv_contents = [ - # ['assembly', ('asm', 's'),], - # ['bash', ('bashbook', 'sh'),], - [ - "batch", - ("bat",), - ], - [ - "c", - ("c", "h"), - ], - # ['cmake', ('cmake',),], - # ["cplusplus", ("cpp hpp",), ("see plus plus",)], + #['assembly', ('asm', 's'),], + #['bash', ('bashbook', 'sh'),], + ["batch", ("bat",),], + ["c", ("c", "h"),], + #['cmake', ('cmake',),], + #["cplusplus", ("cpp hpp",), ("see plus plus",)], ["csharp", ("cs",), ("see sharp",)], ["css", ("css",), ("c s s",)], - # ['elisp', ('el'),], - # ['elm', ('elm'),], - [ - "javascript", - ("js",), - ], - [ - "javascriptreact", - ("jsx",), - ], - # ["json", ("json",),], - [ - "kotlin", - ("kt",), - ], - [ - "lua", - ("lua",), - ], - [ - "markdown", - ("md",), - ], - # ['perl', ('pl',),], - [ - "php", - ("php",), - ], - # ['powershell', ('ps1',),], - [ - "python", - ("py",), - ], - [ - "protobuf", - ("proto",), - ], + #['elisp', ('el'),], + #['elm', ('elm'),], + ["gdb", ("gdb",), ("g d b",)], + ["go", ("go",), ("go", "go lang", "go language")], + ["java", ("java",)], + ["javascript", ("js",)], + ["javascriptreact", ("jsx",)], + #["json", ("json",),], + ["kotlin", ("kt",),], + ["lua", ("lua",),], + ["markdown", ("md",),], + #['perl', ('pl',),], + ["php", ("php",),], + #['powershell', ('ps1',),], + ["python", ("py",),], + ["protobuf", ("proto",),], ["r", ("r"), ("are language",)], - # ['racket', ('rkt,'),], - [ - "ruby", - ("rb",), - ], - [ - "rust", - ("rs",), - ], - [ - "scala", - ("scala",), - ], - [ - "scss", - ("scss",), - ], - # ['snippets', ('snippets',),], - [ - "sql", - ("sql",), - ], - [ - "stata", - ("do", "ado"), - ], - [ - "talon", - ("talon",), - ], - [ - "talonlist", - ("talon-list",), - ], - [ - "terraform", - ("tf",), - ], + #['racket', ('rkt,'),], + ["ruby", ("rb",),], + ["rust", ("rs",),], + ["scala", ("scala",),], + ["scss", ("scss",),], + #['snippets', ('snippets',),], + ["sql", ("sql",),], + ["stata", ("do", "ado"),], + ["talon", ("talon",),], + ["talonlist", ("talon-list",),], + ["terraform", ("tf",),], ["tex", ("tex",), ("tech", "lay tech", "latex")], - [ - "typescript", - ("ts",), - ], - [ - "typescriptreact", - ("tsx",), - ], - # ['vba', ('vba',),], - [ - "vimscript", - ("vim", "vimrc"), - ], - # htm doesn't actually have a language moded, but we do have snippets. - [ - "html", - ("html",), - ], + ["typescript", ("ts",),], + ["typescriptreact", ("tsx",),], + #['vba', ('vba',),], + ["vimscript", ("vim", "vimrc"),], + #htm doesn't actually have a language moded, but we do have snippets. + ["html", ("html",),], ] create_three_columns_csv_from_default_if_nonexistent( SETTINGS_FILENAME, LANGUAGE_HEADERS, default_csv_contents From 88f816c3fee46b31e75e56e4f655dbb230949add Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 00:36:18 +0000 Subject: [PATCH 19/29] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- core/modes/language_modes.py | 131 ++++++++++++++++++++++++++--------- 1 file changed, 97 insertions(+), 34 deletions(-) diff --git a/core/modes/language_modes.py b/core/modes/language_modes.py index 434c4b6a71..958d6b8a17 100644 --- a/core/modes/language_modes.py +++ b/core/modes/language_modes.py @@ -37,49 +37,112 @@ def make_sure_settings_file_exists(): # here which have a supported language mode; that's why there are so many # commented out entries. TODO: make this a csv file? default_csv_contents = [ - #['assembly', ('asm', 's'),], - #['bash', ('bashbook', 'sh'),], - ["batch", ("bat",),], - ["c", ("c", "h"),], - #['cmake', ('cmake',),], - #["cplusplus", ("cpp hpp",), ("see plus plus",)], + # ['assembly', ('asm', 's'),], + # ['bash', ('bashbook', 'sh'),], + [ + "batch", + ("bat",), + ], + [ + "c", + ("c", "h"), + ], + # ['cmake', ('cmake',),], + # ["cplusplus", ("cpp hpp",), ("see plus plus",)], ["csharp", ("cs",), ("see sharp",)], ["css", ("css",), ("c s s",)], - #['elisp', ('el'),], - #['elm', ('elm'),], + # ['elisp', ('el'),], + # ['elm', ('elm'),], ["gdb", ("gdb",), ("g d b",)], ["go", ("go",), ("go", "go lang", "go language")], ["java", ("java",)], ["javascript", ("js",)], ["javascriptreact", ("jsx",)], - #["json", ("json",),], - ["kotlin", ("kt",),], - ["lua", ("lua",),], - ["markdown", ("md",),], - #['perl', ('pl',),], - ["php", ("php",),], - #['powershell', ('ps1',),], - ["python", ("py",),], - ["protobuf", ("proto",),], + # ["json", ("json",),], + [ + "kotlin", + ("kt",), + ], + [ + "lua", + ("lua",), + ], + [ + "markdown", + ("md",), + ], + # ['perl', ('pl',),], + [ + "php", + ("php",), + ], + # ['powershell', ('ps1',),], + [ + "python", + ("py",), + ], + [ + "protobuf", + ("proto",), + ], ["r", ("r"), ("are language",)], - #['racket', ('rkt,'),], - ["ruby", ("rb",),], - ["rust", ("rs",),], - ["scala", ("scala",),], - ["scss", ("scss",),], - #['snippets', ('snippets',),], - ["sql", ("sql",),], - ["stata", ("do", "ado"),], - ["talon", ("talon",),], - ["talonlist", ("talon-list",),], - ["terraform", ("tf",),], + # ['racket', ('rkt,'),], + [ + "ruby", + ("rb",), + ], + [ + "rust", + ("rs",), + ], + [ + "scala", + ("scala",), + ], + [ + "scss", + ("scss",), + ], + # ['snippets', ('snippets',),], + [ + "sql", + ("sql",), + ], + [ + "stata", + ("do", "ado"), + ], + [ + "talon", + ("talon",), + ], + [ + "talonlist", + ("talon-list",), + ], + [ + "terraform", + ("tf",), + ], ["tex", ("tex",), ("tech", "lay tech", "latex")], - ["typescript", ("ts",),], - ["typescriptreact", ("tsx",),], - #['vba', ('vba',),], - ["vimscript", ("vim", "vimrc"),], - #htm doesn't actually have a language moded, but we do have snippets. - ["html", ("html",),], + [ + "typescript", + ("ts",), + ], + [ + "typescriptreact", + ("tsx",), + ], + # ['vba', ('vba',),], + [ + "vimscript", + ("vim", "vimrc"), + ], + # htm doesn't actually have a language moded, but we do have snippets. + [ + "html", + ("html",), + ], ] create_three_columns_csv_from_default_if_nonexistent( SETTINGS_FILENAME, LANGUAGE_HEADERS, default_csv_contents From d81ebd5ad08da3b26787a78280156f9a053442e7 Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Sun, 4 Aug 2024 18:40:43 -0600 Subject: [PATCH 20/29] Properly handle new lines --- core/user_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/user_settings.py b/core/user_settings.py index 028905aeb7..0bb2b57864 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -134,7 +134,7 @@ def _compute_values_packed_into_column(values): def _obtain_rows_from_csv(path): - with open(str(path), "r") as f: + with open(str(path), "r", newline='') as f: rows = list(csv.reader(f)) return rows From 79a9cac7c0e791aa5545f5001df0cac2acd87037 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 00:41:00 +0000 Subject: [PATCH 21/29] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- core/user_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/user_settings.py b/core/user_settings.py index 0bb2b57864..7a397e8f31 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -134,7 +134,7 @@ def _compute_values_packed_into_column(values): def _obtain_rows_from_csv(path): - with open(str(path), "r", newline='') as f: + with open(str(path), "r", newline="") as f: rows = list(csv.reader(f)) return rows From 10bd11b72093f63ed512a5f0b46559a9fdd2111a Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Sun, 4 Aug 2024 18:47:14 -0600 Subject: [PATCH 22/29] Strip text for values --- core/user_settings.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/core/user_settings.py b/core/user_settings.py index 7a397e8f31..93874a8ccb 100644 --- a/core/user_settings.py +++ b/core/user_settings.py @@ -167,7 +167,7 @@ def _convert_rows_from_file_with_headers_to_key_value_pairs_and_spoken_forms( values = _get_intermediate_values_from_column(values_text) key_value_pairs[name] = values if new_spoken_forms_text: - spoken_forms[name] = _get_spoken_forms_from_column( + spoken_forms[name] = _get_intermediate_values_from_column( new_spoken_forms_text ) return key_value_pairs, spoken_forms @@ -176,16 +176,10 @@ def _convert_rows_from_file_with_headers_to_key_value_pairs_and_spoken_forms( def _get_intermediate_values_from_column(values_text): reader = csv.reader([values_text], delimiter=";") values = next(reader) + values = [value.strip() for value in values] return values -def _get_spoken_forms_from_column(spoken_forms_text): - reader = csv.reader([spoken_forms_text], delimiter=";") - spoken_forms = next(reader) - spoken_forms = [spoken_form.strip() for spoken_form in spoken_forms] - return spoken_forms - - def _complain_if_invalid_headers_found_in_file(rows, expected_headers, filename): actual_headers = rows[0] if not actual_headers == list(expected_headers): From 000fb4071f6bed6009c7548de034eace269630ab Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Sat, 10 Aug 2024 11:41:12 -0600 Subject: [PATCH 23/29] Theoretically address issues brought up in community meeting --- CHANGELOG.md | 1 + core/edit_text_file.py | 1 + core/modes/language_modes.py | 10 ++++------ 3 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..f849f11573 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1 @@ +August 10 2024: The language modes (that keep track of programming language names, corresponding extensions, and spoken forms) have been migrated to a CSV file. If you have made changes directly to the language_modes.py file to customize that information, you can migrate your changes by letting the new community code run to generate the CSV file and then editing it. \ No newline at end of file diff --git a/core/edit_text_file.py b/core/edit_text_file.py index f246baf763..befd359ec4 100644 --- a/core/edit_text_file.py +++ b/core/edit_text_file.py @@ -24,6 +24,7 @@ "unix utilities": "unix_utilities.csv", "websites": "websites.csv", "words to replace": "words_to_replace.csv", + "language modes": "language_modes.csv", }.items() } _csvs["homophones"] = os.path.join(REPO_DIR, "core", "homophones", "homophones.csv") diff --git a/core/modes/language_modes.py b/core/modes/language_modes.py index 958d6b8a17..4ca23857c0 100644 --- a/core/modes/language_modes.py +++ b/core/modes/language_modes.py @@ -34,8 +34,8 @@ def make_sure_settings_file_exists(): # Maps language mode names to the extensions that activate them and language spoken forms. Only put things - # here which have a supported language mode; that's why there are so many - # commented out entries. TODO: make this a csv file? + # here which have a supported language mode or snippets; that's why there are so many + # commented out entries. default_csv_contents = [ # ['assembly', ('asm', 's'),], # ['bash', ('bashbook', 'sh'),], @@ -138,7 +138,7 @@ def make_sure_settings_file_exists(): "vimscript", ("vim", "vimrc"), ], - # htm doesn't actually have a language moded, but we do have snippets. + # html doesn't actually have a language mode, but we do have snippets. [ "html", ("html",), @@ -155,7 +155,7 @@ def make_sure_settings_file_exists(): @resource.watch(settings_filepath) def load_language_modes(path: str): make_sure_settings_file_exists() - global language_extensions + global language_extensions, extension_lang_map, language_ids language_extensions, language_spoken_forms = ( get_key_value_pairs_and_spoken_forms_from_three_column_csv( SETTINGS_FILENAME, @@ -165,13 +165,11 @@ def load_language_modes(path: str): ctx.lists["self.language_mode"] = compute_spoken_form_to_key_dictionary( language_extensions, language_spoken_forms ) - global extension_lang_map extension_lang_map = { "." + ext: language for language, extensions in language_extensions.items() for ext in extensions } - global language_ids language_ids = set(language_extensions.keys()) From e46d3ebef683b9f64743800bc57fb4e9cb7d4e38 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 10 Aug 2024 17:41:27 +0000 Subject: [PATCH 24/29] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f849f11573..b9ec5165c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1 +1 @@ -August 10 2024: The language modes (that keep track of programming language names, corresponding extensions, and spoken forms) have been migrated to a CSV file. If you have made changes directly to the language_modes.py file to customize that information, you can migrate your changes by letting the new community code run to generate the CSV file and then editing it. \ No newline at end of file +August 10 2024: The language modes (that keep track of programming language names, corresponding extensions, and spoken forms) have been migrated to a CSV file. If you have made changes directly to the language_modes.py file to customize that information, you can migrate your changes by letting the new community code run to generate the CSV file and then editing it. From fc201b89730c825fbdd815de023e7793e902f2dd Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Sat, 10 Aug 2024 11:50:05 -0600 Subject: [PATCH 25/29] Document more of the change --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9ec5165c0..1dad209ed5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1 +1 @@ -August 10 2024: The language modes (that keep track of programming language names, corresponding extensions, and spoken forms) have been migrated to a CSV file. If you have made changes directly to the language_modes.py file to customize that information, you can migrate your changes by letting the new community code run to generate the CSV file and then editing it. +August 10 2024: The language modes (that keep track of programming language names, corresponding extensions, and spoken forms) have been migrated to a CSV file. If you have made changes directly to the language_modes.py file to customize that information, you can migrate your changes by letting the new community code run to generate the CSV file and then editing it. Items within the same column can be separated by semicolons if you want to have multiple spoken forms or file extensions associated with the same language. From 42753929819d54ae608c4932353eca346477a1f8 Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Sat, 10 Aug 2024 11:52:57 -0600 Subject: [PATCH 26/29] Declare globals first --- core/modes/language_modes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modes/language_modes.py b/core/modes/language_modes.py index 4ca23857c0..559b22b65e 100644 --- a/core/modes/language_modes.py +++ b/core/modes/language_modes.py @@ -154,8 +154,8 @@ def make_sure_settings_file_exists(): @resource.watch(settings_filepath) def load_language_modes(path: str): - make_sure_settings_file_exists() global language_extensions, extension_lang_map, language_ids + make_sure_settings_file_exists() language_extensions, language_spoken_forms = ( get_key_value_pairs_and_spoken_forms_from_three_column_csv( SETTINGS_FILENAME, From 94c16a790c168ae342561981337b502ffab62621 Mon Sep 17 00:00:00 2001 From: Nicholas Riley Date: Sat, 10 Aug 2024 15:11:42 -0400 Subject: [PATCH 27/29] Update edit_text_file.py This list is alphabetized. --- core/edit_text_file.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/edit_text_file.py b/core/edit_text_file.py index befd359ec4..e5cb92ca42 100644 --- a/core/edit_text_file.py +++ b/core/edit_text_file.py @@ -19,12 +19,12 @@ "alphabet": "alphabet.csv", "directories": "directories.csv", "file extensions": "file_extensions.csv", + "language modes": "language_modes.csv", "search engines": "search_engines.csv", "system paths": "system_paths.csv", "unix utilities": "unix_utilities.csv", "websites": "websites.csv", "words to replace": "words_to_replace.csv", - "language modes": "language_modes.csv", }.items() } _csvs["homophones"] = os.path.join(REPO_DIR, "core", "homophones", "homophones.csv") From cb26c9912a1d48f042c31a4790f4d8dacdb0dcec Mon Sep 17 00:00:00 2001 From: Fire Chicken Date: Sun, 11 Aug 2024 15:52:56 -0600 Subject: [PATCH 28/29] Add callback --- core/modes/language_modes.py | 9 +++++++++ core/snippets/snippets.py | 31 ++++++++++++++++++++----------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/core/modes/language_modes.py b/core/modes/language_modes.py index 559b22b65e..defec3f94f 100644 --- a/core/modes/language_modes.py +++ b/core/modes/language_modes.py @@ -1,4 +1,5 @@ from talon import Context, Module, actions, resource +from typing import Callable from ..user_settings import ( compute_csv_path, @@ -31,6 +32,7 @@ LANGUAGE_HEADERS = ["language", "extensions", "spoken_forms"] +language_mode_update_callbacks = {} def make_sure_settings_file_exists(): # Maps language mode names to the extensions that activate them and language spoken forms. Only put things @@ -172,6 +174,9 @@ def load_language_modes(path: str): } language_ids = set(language_extensions.keys()) + for callback in language_mode_update_callbacks.values(): + callback() + load_language_modes(settings_filepath) @@ -208,3 +213,7 @@ def code_clear_language_mode(): global forced_language forced_language = "" ctx.tags = [] + + def register_language_mode_on_update_callback(name: str, callback: Callable[[], None]): + """Registers a callback to be called when the language mode csv is updated""" + language_mode_update_callbacks[name] = callback \ No newline at end of file diff --git a/core/snippets/snippets.py b/core/snippets/snippets.py index e04f10ebfa..1dfab8f90a 100644 --- a/core/snippets/snippets.py +++ b/core/snippets/snippets.py @@ -23,18 +23,23 @@ desc="Directory (relative to Talon user) containing additional snippets", ) -context_map = { - # `_` represents the global context, ie snippets available regardless of language - "_": Context(), -} -snippets_map = {} - -# Create a context for each defined language -for lang in language_ids: - ctx = Context() - ctx.matches = f"code.language: {lang}" - context_map[lang] = ctx +context_map = None + +def create_context_map(): + global context_map + context_map = { + # `_` represents the global context, ie snippets available regardless of language + "_": Context(), + } + + # Create a context for each defined language + for lang in language_ids: + ctx = Context() + ctx.matches = f"code.language: {lang}" + context_map[lang] = ctx +create_context_map() +snippets_map = {} def get_setting_dir(): setting_dir = settings.get("user.snippets_dir") @@ -198,6 +203,9 @@ def create_lists( return snippets_map, insertions, insertions_phrase, wrappers +def on_language_modes_update(): + create_context_map() + update_snippets() def on_ready(): fs.watch(str(SNIPPETS_DIR), lambda _1, _2: update_snippets()) @@ -206,6 +214,7 @@ def on_ready(): fs.watch(str(get_setting_dir()), lambda _1, _2: update_snippets()) update_snippets() + actions.user.register_language_mode_on_update_callback("snippets", on_language_modes_update) app.register("ready", on_ready) From 3d55c2ce186fcd7b90d5b45c024f7f68c7c6fac4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 11 Aug 2024 21:53:12 +0000 Subject: [PATCH 29/29] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- core/modes/language_modes.py | 10 +++++++--- core/snippets/snippets.py | 10 +++++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/core/modes/language_modes.py b/core/modes/language_modes.py index defec3f94f..75fc00a513 100644 --- a/core/modes/language_modes.py +++ b/core/modes/language_modes.py @@ -1,6 +1,7 @@ -from talon import Context, Module, actions, resource from typing import Callable +from talon import Context, Module, actions, resource + from ..user_settings import ( compute_csv_path, compute_spoken_form_to_key_dictionary, @@ -34,6 +35,7 @@ language_mode_update_callbacks = {} + def make_sure_settings_file_exists(): # Maps language mode names to the extensions that activate them and language spoken forms. Only put things # here which have a supported language mode or snippets; that's why there are so many @@ -214,6 +216,8 @@ def code_clear_language_mode(): forced_language = "" ctx.tags = [] - def register_language_mode_on_update_callback(name: str, callback: Callable[[], None]): + def register_language_mode_on_update_callback( + name: str, callback: Callable[[], None] + ): """Registers a callback to be called when the language mode csv is updated""" - language_mode_update_callbacks[name] = callback \ No newline at end of file + language_mode_update_callbacks[name] = callback diff --git a/core/snippets/snippets.py b/core/snippets/snippets.py index 1dfab8f90a..5624f92a8a 100644 --- a/core/snippets/snippets.py +++ b/core/snippets/snippets.py @@ -25,6 +25,7 @@ context_map = None + def create_context_map(): global context_map context_map = { @@ -37,10 +38,13 @@ def create_context_map(): ctx = Context() ctx.matches = f"code.language: {lang}" context_map[lang] = ctx + + create_context_map() snippets_map = {} + def get_setting_dir(): setting_dir = settings.get("user.snippets_dir") if not setting_dir: @@ -203,10 +207,12 @@ def create_lists( return snippets_map, insertions, insertions_phrase, wrappers + def on_language_modes_update(): create_context_map() update_snippets() + def on_ready(): fs.watch(str(SNIPPETS_DIR), lambda _1, _2: update_snippets()) @@ -214,7 +220,9 @@ def on_ready(): fs.watch(str(get_setting_dir()), lambda _1, _2: update_snippets()) update_snippets() - actions.user.register_language_mode_on_update_callback("snippets", on_language_modes_update) + actions.user.register_language_mode_on_update_callback( + "snippets", on_language_modes_update + ) app.register("ready", on_ready)