Skip to content

Commit

Permalink
Config: Update widget shortcuts on the fly after resetting all shortcuts
Browse files Browse the repository at this point in the history
Also, add inline typing for several attributes of ConfigurationManager
and remove associated comments.
  • Loading branch information
ccordoba12 committed Nov 25, 2024
1 parent bba018e commit b8d84e8
Showing 1 changed file with 40 additions and 11 deletions.
51 changes: 40 additions & 11 deletions spyder/config/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from spyder.config.main import CONF_VERSION, DEFAULTS, NAME_MAP
from spyder.config.types import ConfigurationKey, ConfigurationObserver
from spyder.config.user import UserConfig, MultiUserConfig, NoDefault, cp
from spyder.plugins.shortcuts.utils import SHORTCUTS_FOR_WIDGETS_DATA
from spyder.utils.programs import check_version


Expand Down Expand Up @@ -100,24 +101,25 @@ def __init__(self, parent=None, active_project_callback=None,
# This dict maps from a configuration key (str/tuple) to a set
# of objects that should be notified on changes to the corresponding
# subscription key per section. The observer objects must be hashable.
#
# type: Dict[ConfigurationKey, Dict[str, Set[ConfigurationObserver]]]
self._observers = {}
self._observers: Dict[
ConfigurationKey, Dict[str, Set[ConfigurationObserver]]
] = {}

# Set of suscription keys per observer object
# This dict maps from a observer object to the set of configuration
# keys that the object is subscribed to per section.
#
# type: Dict[ConfigurationObserver, Dict[str, Set[ConfigurationKey]]]
self._observer_map_keys = weakref.WeakKeyDictionary()
self._observer_map_keys: Dict[
ConfigurationObserver, Dict[str, Set[ConfigurationKey]]
] = weakref.WeakKeyDictionary()

# List of options with disabled notifications.
# This holds a list of (section, option) options that won't be notified
# to observers. It can be used to temporarily disable notifications for
# some options.
#
# type: List[Tuple(str, ConfigurationKey)]
self._disabled_options = []
self._disabled_options: List[Tuple(str, ConfigurationKey)] = []

# Mapping for shortcuts that need to be notified
self._shortcuts_to_notify: Dict[(str, str), Optional[str]] = {}

# Setup
self.remove_deprecated_config_locations()
Expand Down Expand Up @@ -361,8 +363,11 @@ def notify_observers(
if option == '__section':
self._notify_section(section)
else:
value = self.get(section, option, secure=secure)
self._notify_option(section, option, value)
if section == "shortcuts":
self._notify_shortcut(option)
else:
value = self.get(section, option, secure=secure)
self._notify_option(section, option, value)

def _notify_option(self, section: str, option: ConfigurationKey,
value: Any):
Expand Down Expand Up @@ -392,6 +397,27 @@ def _notify_section(self, section: str):
section_values = dict(self.items(section) or [])
self._notify_option(section, '__section', section_values)

def _notify_shortcut(self, option: str):
# We need this mapping for two reasons:
# 1. We don't need to notify changes for all shortcuts, only for
# widget shortcuts, which are the ones with associated observers
# (see SpyderShortcutsMixin.register_shortcut_for_widget).
# 2. Besides context and name, we need the plugin_name to correctly get
# the shortcut value to notify. That's not saved in our config
# system, but it is in SHORTCUTS_FOR_WIDGETS_DATA.
if not self._shortcuts_to_notify:
# Populate mapping only once
self._shortcuts_to_notify = {
(data.context, data.name): data.plugin_name
for data in SHORTCUTS_FOR_WIDGETS_DATA
}

context, name = option.split("/")
if (context, name) in self._shortcuts_to_notify:
plugin_name = self._shortcuts_to_notify[(context, name)]
value = self.get_shortcut(context, name, plugin_name)
self._notify_option("shortcuts", option, value)

def notify_section_all_observers(self, section: str):
"""Notify all the observers subscribed to any option of a section."""
option_observers = self._observers[section]
Expand Down Expand Up @@ -734,6 +760,9 @@ def reset_shortcuts(self):
# TODO: check if the section exists?
plugin_config.reset_to_defaults(section='shortcuts')

# This necessary to notify the observers of widget shortcuts
self.notify_section_all_observers(section="shortcuts")


try:
CONF = ConfigurationManager()
Expand Down

0 comments on commit b8d84e8

Please sign in to comment.