Skip to content
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

Avoid updating CSV on error reading VSCode settings #137

Merged
merged 3 commits into from
Dec 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 8 additions & 2 deletions src/csv_overrides.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def init_csv_and_watch_changes(
default_list_name: Optional[str] = None,
headers: list[str] = [SPOKEN_FORM_HEADER, CURSORLESS_IDENTIFIER_HEADER],
ctx: Context = Context(),
no_update_file: bool = False,
):
"""
Initialize a cursorless settings csv, creating it if necessary, and watch
Expand All @@ -49,6 +50,8 @@ def init_csv_and_watch_changes(
allow_unknown_values bool: If unknown values appear, just put them in the list
default_list_name Optional[str]: If unknown values are allowed, put any
unknown values in this list
no_update_file Optional[bool]: Set this to `TRUE` to indicate that we should
not update the csv. This is used generally in case there was an issue coming up with the default set of values so we don't want to persist those to disk
"""
if extra_ignored_values is None:
extra_ignored_values = []
Expand Down Expand Up @@ -85,6 +88,7 @@ def on_watch(path, flags):
super_default_values,
extra_ignored_values,
allow_unknown_values,
no_update_file,
)
update_dicts(
default_values,
Expand All @@ -95,7 +99,8 @@ def on_watch(path, flags):
ctx,
)
else:
create_file(file_path, headers, super_default_values)
if not no_update_file:
create_file(file_path, headers, super_default_values)
update_dicts(
default_values,
super_default_values,
Expand Down Expand Up @@ -165,6 +170,7 @@ def update_file(
default_values: dict,
extra_ignored_values: list[str],
allow_unknown_values: bool,
no_update_file: bool,
):
current_values, has_errors = read_file(
path,
Expand All @@ -181,7 +187,7 @@ def update_file(
missing[key] = value

if missing:
if has_errors:
if has_errors or no_update_file:
print(
"NOTICE: New cursorless features detected, but refusing to update "
"csv due to errors. Please fix csv errors above and restart talon"
Expand Down
39 changes: 26 additions & 13 deletions src/marks/mark.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from talon import Module, actions, app, Context, fs, cron
from ..csv_overrides import init_csv_and_watch_changes
from .lines_number import DEFAULT_DIRECTIONS
from .vscode_settings import vscode_get_setting_with_fallback

mod = Module()
ctx = Context()
Expand Down Expand Up @@ -145,23 +144,33 @@ def cursorless_mark(m) -> str:
def setup_hat_styles_csv():
global unsubscribe_hat_styles

(
color_enablement_settings,
is_color_error,
) = actions.user.vscode_get_setting_with_fallback(
"cursorless.hatEnablement.colors",
default_value={},
fallback_value=FALLBACK_COLOR_ENABLEMENT,
fallback_message="Error finding color enablement; falling back to full enablement",
)

(
shape_enablement_settings,
is_shape_error,
) = actions.user.vscode_get_setting_with_fallback(
"cursorless.hatEnablement.shapes",
default_value={},
fallback_value=FALLBACK_SHAPE_ENABLEMENT,
fallback_message="Error finding shape enablement; falling back to full enablement",
)

color_enablement = {
**DEFAULT_COLOR_ENABLEMENT,
**vscode_get_setting_with_fallback(
"cursorless.hatEnablement.colors",
default_value={},
fallback_value=FALLBACK_COLOR_ENABLEMENT,
fallback_message="Error finding color enablement; falling back to full enablement",
),
**color_enablement_settings,
}
shape_enablement = {
**DEFAULT_SHAPE_ENABLEMENT,
**vscode_get_setting_with_fallback(
"cursorless.hatEnablement.shapes",
default_value={},
fallback_value=FALLBACK_SHAPE_ENABLEMENT,
fallback_message="Error finding shape enablement; falling back to full enablement",
),
**shape_enablement_settings,
}

active_hat_colors = {
Expand All @@ -185,8 +194,12 @@ def setup_hat_styles_csv():
"hat_shape": active_hat_shapes,
},
[*hat_colors.values(), *hat_shapes.values()],
no_update_file=is_shape_error or is_color_error,
)

if is_shape_error or is_color_error:
app.notify("Error reading vscode settings. Restart talon; see log")


fast_reload_job = None
slow_reload_job = None
Expand Down
49 changes: 24 additions & 25 deletions src/marks/vscode_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,30 @@ def vscode_get_setting(key: str, default_value: Any = None):
else:
return settings[key]

def vscode_get_setting_with_fallback(
key: str,
default_value: Any,
fallback_value: Any,
fallback_message: str,
) -> tuple[Any, bool]:
"""Returns a vscode setting with a fallback in case there's an error

Args:
key (str): The key of the setting to look up
default_value (Any): The default value to return if the setting is not defined
fallback_value (Any): The value to return if there is an error looking up the setting
fallback_message (str): The message to show to the user if we end up having to use the fallback

Returns:
tuple[Any, bool]: The value of the setting or the default or fall back, along with boolean which is true if there was an error
"""
try:
return actions.user.vscode_get_setting(key, default_value), False
except Exception as e:
print(fallback_message)
traceback.print_exc()
return fallback_value, True


def pick_path(paths: list[Path]):
existing_paths = [path for path in paths if path.exists()]
Expand Down Expand Up @@ -79,28 +103,3 @@ def vscode_settings_path() -> Path:
Path(f"{os.environ['APPDATA']}/VSCodium/User/settings.json"),
]
)


def vscode_get_setting_with_fallback(
key: str,
default_value: Any,
fallback_value: Any,
fallback_message: str,
):
"""Returns a vscode setting with a fallback in case there's an error

Args:
key (str): The key of the setting to look up
default_value (Any): The default value to return if the setting is not defined
fallback_value (Any): The value to return if there is an error looking up the setting
fallback_message (str): The message to show to the user if we end up having to use the fallback

Returns:
Any: The value of the setting or the default or fall back
"""
try:
return actions.user.vscode_get_setting(key, default_value)
except Exception as e:
print(fallback_message)
traceback.print_exc()
return fallback_value