Beispiel #1
0
def load_config(cfg_path, find_config_files, config_loader, loader_callback=None):
	'''Load configuration file and setup watches

	Watches are only set up if loader_callback is not None.

	:param str cfg_path:
		Path for configuration file that should be loaded.
	:param function find_config_files:
		Function that finds configuration file. Check out the description of 
		the return value of ``generate_config_finder`` function.
	:param ConfigLoader config_loader:
		Configuration file loader class instance.
	:param function loader_callback:
		Function that will be called by config_loader when change to 
		configuration file is detected.

	:return: Configuration file contents.
	'''
	found_files = find_config_files(cfg_path, config_loader, loader_callback)
	ret = None
	for path in found_files:
		if loader_callback:
			config_loader.register(loader_callback, path)
		if ret is None:
			ret = config_loader.load(path)
		else:
			mergedicts(ret, config_loader.load(path))
	return ret
Beispiel #2
0
def load_config(cfg_path,
                find_config_files,
                config_loader,
                loader_callback=None):
    '''Load configuration file and setup watches

	Watches are only set up if loader_callback is not None.

	:param str cfg_path:
		Path for configuration file that should be loaded.
	:param function find_config_files:
		Function that finds configuration file. Check out the description of 
		the return value of ``generate_config_finder`` function.
	:param ConfigLoader config_loader:
		Configuration file loader class instance.
	:param function loader_callback:
		Function that will be called by config_loader when change to 
		configuration file is detected.

	:return: Configuration file contents.
	'''
    found_files = find_config_files(cfg_path, config_loader, loader_callback)
    ret = None
    for path in found_files:
        if loader_callback:
            config_loader.register(loader_callback, path)
        if ret is None:
            ret = config_loader.load(path)
        else:
            mergedicts(ret, config_loader.load(path))
    return ret
Beispiel #3
0
	def load_theme_config(self, name):
		r = super(PDBPowerline, self).load_theme_config(name)
		theme_overrides = os.environ.get('POWERLINE_THEME_OVERRIDES')
		if theme_overrides:
			theme_overrides_dict = mergeargs(parse_override_var(theme_overrides))
			if name in theme_overrides_dict:
				mergedicts(r, theme_overrides_dict[name])
		return r
Beispiel #4
0
 def load_theme_config(self, name):
     r = super(PDBPowerline, self).load_theme_config(name)
     theme_overrides = os.environ.get('POWERLINE_THEME_OVERRIDES')
     if theme_overrides:
         theme_overrides_dict = mergeargs(
             parse_override_var(theme_overrides))
         if name in theme_overrides_dict:
             mergedicts(r, theme_overrides_dict[name])
     return r
Beispiel #5
0
def _override_from(config, override_varname, key=None):
	try:
		overrides = vim_getvar(override_varname)
	except KeyError:
		return config
	if key is not None:
		try:
			overrides = overrides[key]
		except KeyError:
			return config
	mergedicts(config, overrides)
	return config
Beispiel #6
0
	def test_mergedicts(self):
		d = {}
		mergedicts(d, {'abc': {'def': 'ghi'}})
		self.assertEqual(d, {'abc': {'def': 'ghi'}})
		mergedicts(d, {'abc': {'def': {'ghi': 'jkl'}}})
		self.assertEqual(d, {'abc': {'def': {'ghi': 'jkl'}}})
		mergedicts(d, {})
		self.assertEqual(d, {'abc': {'def': {'ghi': 'jkl'}}})
		mergedicts(d, {'abc': {'mno': 'pqr'}})
		self.assertEqual(d, {'abc': {'def': {'ghi': 'jkl'}, 'mno': 'pqr'}})
		mergedicts(d, {'abc': {'def': REMOVE_THIS_KEY}})
		self.assertEqual(d, {'abc': {'mno': 'pqr'}})
Beispiel #7
0
 def test_mergedicts(self):
     d = {}
     mergedicts(d, {'abc': {'def': 'ghi'}})
     self.assertEqual(d, {'abc': {'def': 'ghi'}})
     mergedicts(d, {'abc': {'def': {'ghi': 'jkl'}}})
     self.assertEqual(d, {'abc': {'def': {'ghi': 'jkl'}}})
     mergedicts(d, {})
     self.assertEqual(d, {'abc': {'def': {'ghi': 'jkl'}}})
     mergedicts(d, {'abc': {'mno': 'pqr'}})
     self.assertEqual(d, {'abc': {'def': {'ghi': 'jkl'}, 'mno': 'pqr'}})
     mergedicts(d, {'abc': {'def': REMOVE_THIS_KEY}})
     self.assertEqual(d, {'abc': {'mno': 'pqr'}})
Beispiel #8
0
    def add_local_theme(self, key, config):
        '''Add local themes at runtime (during vim session).

		:param str key:
			Matcher name (in format ``{matcher_module}.{module_attribute}`` or 
			``{module_attribute}`` if ``{matcher_module}`` is 
			``powerline.matchers.vim``). Function pointed by 
			``{module_attribute}`` should be hashable and accept a dictionary 
			with information about current buffer and return boolean value 
			indicating whether current window matched conditions. See also 
			:ref:`local_themes key description <config-ext-local_themes>`.

		:param dict config:
			:ref:`Theme <config-themes>` dictionary.

		:return:
			``True`` if theme was added successfully and ``False`` if theme with 
			the same matcher already exists.
		'''
        self.update_renderer()
        matcher = self.get_matcher(key)
        theme_config = {}
        for cfg_path in self.theme_levels:
            try:
                lvl_config = self.load_config(cfg_path, 'theme')
            except IOError:
                pass
            else:
                mergedicts(theme_config, lvl_config)
        mergedicts(theme_config, config)
        try:
            self.renderer.add_local_theme(matcher, {'config': theme_config})
        except KeyError:
            return False
        else:
            # Hack for local themes support: when reloading modules it is not
            # guaranteed that .add_local_theme will be called once again, so
            # this function arguments will be saved here for calling from
            # .do_setup().
            self.setup_kwargs.setdefault('_local_themes', []).append(
                (key, config))
            return True
Beispiel #9
0
    def _load_hierarhical_config(self, cfg_type, levels, ignore_levels):
        '''Load and merge multiple configuration files

		:param str cfg_type:
			Type of the loaded configuration files (e.g. ``colorscheme``, 
			``theme``).
		:param list levels:
			Configuration names resembling levels in hierarchy, sorted by 
			priority. Configuration file names with higher priority should go 
			last.
		:param set ignore_levels:
			If only files listed in this variable are present then configuration 
			file is considered not loaded: at least one file on the level not 
			listed in this variable must be present.
		'''
        config = {}
        loaded = 0
        exceptions = []
        for i, cfg_path in enumerate(levels):
            try:
                lvl_config = self.load_config(cfg_path, cfg_type)
            except IOError as e:
                if sys.version_info < (3, ):
                    tb = sys.exc_info()[2]
                    exceptions.append((e, tb))
                else:
                    exceptions.append(e)
            else:
                if i not in ignore_levels:
                    loaded += 1
                mergedicts(config, lvl_config)
        if not loaded:
            for exception in exceptions:
                if type(exception) is tuple:
                    e = exception[0]
                else:
                    e = exception
                self.exception('Failed to load %s: {0}' % cfg_type,
                               e,
                               exception=exception)
            raise e
        return config
Beispiel #10
0
	def add_local_theme(self, key, config):
		'''Add local themes at runtime (during vim session).

		:param str key:
			Matcher name (in format ``{matcher_module}.{module_attribute}`` or 
			``{module_attribute}`` if ``{matcher_module}`` is 
			``powerline.matchers.vim``). Function pointed by 
			``{module_attribute}`` should be hashable and accept a dictionary 
			with information about current buffer and return boolean value 
			indicating whether current window matched conditions. See also 
			:ref:`local_themes key description <config-ext-local_themes>`.

		:param dict config:
			:ref:`Theme <config-themes>` dictionary.

		:return:
			``True`` if theme was added successfully and ``False`` if theme with 
			the same matcher already exists.
		'''
		self.update_renderer()
		matcher = self.get_matcher(key)
		theme_config = {}
		for cfg_path in self.theme_levels:
			try:
				lvl_config = self.load_config(cfg_path, 'theme')
			except IOError:
				pass
			else:
				mergedicts(theme_config, lvl_config)
		mergedicts(theme_config, config)
		try:
			self.renderer.add_local_theme(matcher, {'config': theme_config})
		except KeyError:
			return False
		else:
			# Hack for local themes support: when reloading modules it is not 
			# guaranteed that .add_local_theme will be called once again, so 
			# this function arguments will be saved here for calling from 
			# .do_setup().
			self.setup_kwargs.setdefault('_local_themes', []).append((key, config))
			return True
Beispiel #11
0
	def _load_hierarhical_config(self, cfg_type, levels, ignore_levels):
		'''Load and merge multiple configuration files

		:param str cfg_type:
			Type of the loaded configuration files (e.g. ``colorscheme``, 
			``theme``).
		:param list levels:
			Configuration names resembling levels in hierarchy, sorted by 
			priority. Configuration file names with higher priority should go 
			last.
		:param set ignore_levels:
			If only files listed in this variable are present then configuration 
			file is considered not loaded: at least one file on the level not 
			listed in this variable must be present.
		'''
		config = {}
		loaded = 0
		exceptions = []
		for i, cfg_path in enumerate(levels):
			try:
				lvl_config = self.load_config(cfg_path, cfg_type)
			except IOError as e:
				if sys.version_info < (3,):
					tb = sys.exc_info()[2]
					exceptions.append((e, tb))
				else:
					exceptions.append(e)
			else:
				if i not in ignore_levels:
					loaded += 1
				mergedicts(config, lvl_config)
		if not loaded:
			for exception in exceptions:
				if type(exception) is tuple:
					e = exception[0]
				else:
					e = exception
				self.exception('Failed to load %s: {0}' % cfg_type, e, exception=exception)
			raise e
		return config
Beispiel #12
0
 def load_theme_config(self, name):
     r = super(ShellPowerline, self).load_theme_config(name)
     if self.args.theme_override and name in self.args.theme_override:
         mergedicts(r, self.args.theme_override[name])
     return r
Beispiel #13
0
 def load_theme_config(self, name):
     r = super(IPythonPowerline, self).load_theme_config(name)
     if name in self.theme_overrides:
         mergedicts(r, self.theme_overrides[name])
     return r
Beispiel #14
0
 def load_main_config(self):
     r = super(IPythonPowerline, self).load_main_config()
     if self.config_overrides:
         mergedicts(r, self.config_overrides)
     return r
Beispiel #15
0
	def create_renderer(self, load_main=False, load_colors=False, load_colorscheme=False, load_theme=False):
		'''(Re)create renderer object. Can be used after Powerline object was 
		successfully initialized. If any of the below parameters except 
		``load_main`` is True renderer object will be recreated.

		:param bool load_main:
			Determines whether main configuration file (:file:`config.json`) 
			should be loaded. If appropriate configuration changes implies 
			``load_colorscheme`` and ``load_theme`` and recreation of renderer 
			object. Won’t trigger recreation if only unrelated configuration 
			changed.
		:param bool load_colors:
			Determines whether colors configuration from :file:`colors.json` 
			should be (re)loaded.
		:param bool load_colorscheme:
			Determines whether colorscheme configuration should be (re)loaded.
		:param bool load_theme:
			Determines whether theme configuration should be reloaded.
		'''
		common_config_differs = False
		ext_config_differs = False
		if load_main:
			self._purge_configs('main')
			config = self.load_main_config()
			self.common_config = finish_common_config(self.get_encoding(), config['common'])
			if self.common_config != self.prev_common_config:
				common_config_differs = True

				load_theme = (load_theme
					or not self.prev_common_config
					or self.prev_common_config['default_top_theme'] != self.common_config['default_top_theme'])

				self.prev_common_config = self.common_config

				self.import_paths = self.common_config['paths']

				if not self.logger:
					self.logger = self.create_logger()

				if not self.pl:
					self.pl = PowerlineLogger(self.use_daemon_threads, self.logger, self.ext)
					self.config_loader.pl = self.pl

				if not self.run_once:
					self.config_loader.set_watcher(self.common_config['watcher'])

				self.get_module_attr = gen_module_attr_getter(self.pl, self.import_paths, self.imported_modules)

				mergedicts(self.renderer_options, dict(
					pl=self.pl,
					term_truecolor=self.common_config['term_truecolor'],
					term_escape_style=self.common_config['term_escape_style'],
					ambiwidth=self.common_config['ambiwidth'],
					tmux_escape=self.common_config['additional_escapes'] == 'tmux',
					screen_escape=self.common_config['additional_escapes'] == 'screen',
					theme_kwargs={
						'ext': self.ext,
						'common_config': self.common_config,
						'run_once': self.run_once,
						'shutdown_event': self.shutdown_event,
						'get_module_attr': self.get_module_attr,
					},
				))

				if not self.run_once and self.common_config['reload_config']:
					interval = self.common_config['interval']
					self.config_loader.set_interval(interval)
					self.run_loader_update = (interval is None)
					if interval is not None and not self.config_loader.is_alive():
						self.config_loader.start()

			self.ext_config = config['ext'][self.ext]

			top_theme = (
				self.ext_config.get('top_theme')
				or self.common_config['default_top_theme']
			)
			self.theme_levels = (
				os.path.join('themes', top_theme),
				os.path.join('themes', self.ext, '__main__'),
			)
			self.renderer_options['theme_kwargs']['top_theme'] = top_theme

			if self.ext_config != self.prev_ext_config:
				ext_config_differs = True
				if (
					not self.prev_ext_config
					or self.ext_config.get('components') != self.prev_ext_config.get('components')
				):
					self.setup_components(self.ext_config.get('components'))
				if (
					not self.prev_ext_config
					or self.ext_config.get('local_themes') != self.prev_ext_config.get('local_themes')
				):
					self.renderer_options['local_themes'] = self.get_local_themes(self.ext_config.get('local_themes'))
				load_colorscheme = (
					load_colorscheme
					or not self.prev_ext_config
					or self.prev_ext_config['colorscheme'] != self.ext_config['colorscheme']
				)
				load_theme = (
					load_theme
					or not self.prev_ext_config
					or self.prev_ext_config['theme'] != self.ext_config['theme']
				)
				self.prev_ext_config = self.ext_config

		create_renderer = load_colors or load_colorscheme or load_theme or common_config_differs or ext_config_differs

		if load_colors:
			self._purge_configs('colors')
			self.colors_config = self.load_colors_config()

		if load_colorscheme or load_colors:
			self._purge_configs('colorscheme')
			if load_colorscheme:
				self.colorscheme_config = self.load_colorscheme_config(self.ext_config['colorscheme'])
			self.renderer_options['theme_kwargs']['colorscheme'] = (
				Colorscheme(self.colorscheme_config, self.colors_config))

		if load_theme:
			self._purge_configs('theme')
			self.renderer_options['theme_config'] = self.load_theme_config(self.ext_config.get('theme', 'default'))

		if create_renderer:
			Renderer = self.get_module_attr(self.renderer_module, 'renderer')
			if not Renderer:
				if hasattr(self, 'renderer'):
					return
				else:
					raise ImportError('Failed to obtain renderer')

			# Renderer updates configuration file via segments’ .startup thus it 
			# should be locked to prevent state when configuration was updated, 
			# but .render still uses old renderer.
			try:
				renderer = Renderer(**self.renderer_options)
			except Exception as e:
				self.exception('Failed to construct renderer object: {0}', str(e))
				if not hasattr(self, 'renderer'):
					raise
			else:
				self.renderer = renderer
Beispiel #16
0
	def load_main_config(self):
		r = super(PDBPowerline, self).load_main_config()
		config_overrides = os.environ.get('POWERLINE_CONFIG_OVERRIDES')
		if config_overrides:
			mergedicts(r, mergeargs(parse_override_var(config_overrides)))
		return r
Beispiel #17
0
    def create_renderer(self,
                        load_main=False,
                        load_colors=False,
                        load_colorscheme=False,
                        load_theme=False):
        '''(Re)create renderer object. Can be used after Powerline object was 
		successfully initialized. If any of the below parameters except 
		``load_main`` is True renderer object will be recreated.

		:param bool load_main:
			Determines whether main configuration file (:file:`config.json`) 
			should be loaded. If appropriate configuration changes implies 
			``load_colorscheme`` and ``load_theme`` and recreation of renderer 
			object. Won’t trigger recreation if only unrelated configuration 
			changed.
		:param bool load_colors:
			Determines whether colors configuration from :file:`colors.json` 
			should be (re)loaded.
		:param bool load_colorscheme:
			Determines whether colorscheme configuration should be (re)loaded.
		:param bool load_theme:
			Determines whether theme configuration should be reloaded.
		'''
        common_config_differs = False
        ext_config_differs = False
        if load_main:
            self._purge_configs('main')
            config = self.load_main_config()
            self.common_config = finish_common_config(self.get_encoding(),
                                                      config['common'])
            if self.common_config != self.prev_common_config:
                common_config_differs = True

                load_theme = (load_theme or not self.prev_common_config
                              or self.prev_common_config['default_top_theme']
                              != self.common_config['default_top_theme'])

                log_keys_differ = (not self.prev_common_config
                                   or (_get_log_keys(self.prev_common_config)
                                       != _get_log_keys(self.common_config)))

                self.prev_common_config = self.common_config

                if log_keys_differ:
                    if self.had_logger:
                        self.pl = PowerlineLogger(self.use_daemon_threads,
                                                  self.logger, self.ext)
                        self.get_module_attr = gen_module_attr_getter(
                            self.pl, self.common_config['paths'],
                            self.imported_modules)
                    else:
                        self.logger, self.pl, self.get_module_attr = self.create_logger(
                        )
                    self.config_loader.pl = self.pl

                if not self.run_once:
                    self.config_loader.set_watcher(
                        self.common_config['watcher'])

                mergedicts(
                    self.renderer_options,
                    dict(
                        pl=self.pl,
                        term_truecolor=self.common_config['term_truecolor'],
                        term_escape_style=self.
                        common_config['term_escape_style'],
                        ambiwidth=self.common_config['ambiwidth'],
                        tmux_escape=self.common_config['additional_escapes'] ==
                        'tmux',
                        screen_escape=self.common_config['additional_escapes']
                        == 'screen',
                        theme_kwargs={
                            'ext': self.ext,
                            'common_config': self.common_config,
                            'run_once': self.run_once,
                            'shutdown_event': self.shutdown_event,
                            'get_module_attr': self.get_module_attr,
                        },
                    ))

                if not self.run_once and self.common_config['reload_config']:
                    interval = self.common_config['interval']
                    self.config_loader.set_interval(interval)
                    self.run_loader_update = (interval is None)
                    if interval is not None and not self.config_loader.is_alive(
                    ):
                        self.config_loader.start()

            self.ext_config = config['ext'][self.ext]

            top_theme = (self.ext_config.get('top_theme')
                         or self.common_config['default_top_theme'])
            self.theme_levels = (
                os.path.join('themes', top_theme),
                os.path.join('themes', self.ext, '__main__'),
            )
            self.renderer_options['theme_kwargs']['top_theme'] = top_theme

            if self.ext_config != self.prev_ext_config:
                ext_config_differs = True
                if (not self.prev_ext_config
                        or self.ext_config.get('components') !=
                        self.prev_ext_config.get('components')):
                    self.setup_components(self.ext_config.get('components'))
                if (not self.prev_ext_config
                        or self.ext_config.get('local_themes') !=
                        self.prev_ext_config.get('local_themes')):
                    self.renderer_options[
                        'local_themes'] = self.get_local_themes(
                            self.ext_config.get('local_themes'))
                self.update_interval = self.ext_config.get(
                    'update_interval', 2)
                load_colorscheme = (load_colorscheme
                                    or not self.prev_ext_config
                                    or self.prev_ext_config['colorscheme'] !=
                                    self.ext_config['colorscheme'])
                load_theme = (load_theme or not self.prev_ext_config
                              or self.prev_ext_config['theme'] !=
                              self.ext_config['theme'])
                self.prev_ext_config = self.ext_config

        create_renderer = load_colors or load_colorscheme or load_theme or common_config_differs or ext_config_differs

        if load_colors:
            self._purge_configs('colors')
            self.colors_config = self.load_colors_config()

        if load_colorscheme or load_colors:
            self._purge_configs('colorscheme')
            if load_colorscheme:
                self.colorscheme_config = self.load_colorscheme_config(
                    self.ext_config['colorscheme'])
            self.renderer_options['theme_kwargs']['colorscheme'] = (
                Colorscheme(self.colorscheme_config, self.colors_config))

        if load_theme:
            self._purge_configs('theme')
            self.renderer_options['theme_config'] = self.load_theme_config(
                self.ext_config.get('theme', 'default'))

        if create_renderer:
            Renderer = self.get_module_attr(self.renderer_module, 'renderer')
            if not Renderer:
                if hasattr(self, 'renderer'):
                    return
                else:
                    raise ImportError('Failed to obtain renderer')

            # Renderer updates configuration file via segments’ .startup thus it
            # should be locked to prevent state when configuration was updated,
            # but .render still uses old renderer.
            try:
                renderer = Renderer(**self.renderer_options)
            except Exception as e:
                self.exception('Failed to construct renderer object: {0}',
                               str(e))
                if not hasattr(self, 'renderer'):
                    raise
            else:
                self.renderer = renderer
Beispiel #18
0
 def load_main_config(self):
     r = super(PDBPowerline, self).load_main_config()
     config_overrides = os.environ.get('POWERLINE_CONFIG_OVERRIDES')
     if config_overrides:
         mergedicts(r, mergeargs(parse_override_var(config_overrides)))
     return r
Beispiel #19
0
	def load_theme_config(self, name):
		r = super(IPythonPowerline, self).load_theme_config(name)
		if name in self.theme_overrides:
			mergedicts(r, self.theme_overrides[name])
		return r
Beispiel #20
0
	def load_main_config(self):
		r = super(ShellPowerline, self).load_main_config()
		if self.args.config_override:
			mergedicts(r, self.args.config_override)
		return r
Beispiel #21
0
	def load_theme_config(self, name):
		r = super(ShellPowerline, self).load_theme_config(name)
		if self.args.theme_override and name in self.args.theme_override:
			mergedicts(r, self.args.theme_override[name])
		return r
Beispiel #22
0
 def load_main_config(self):
     r = super(ShellPowerline, self).load_main_config()
     if self.args.config_override:
         mergedicts(r, self.args.config_override)
     return r
Beispiel #23
0
	def load_main_config(self):
		r = super(IPythonPowerline, self).load_main_config()
		if self.config_overrides:
			mergedicts(r, self.config_overrides)
		return r
Beispiel #24
0
    def create_renderer(self, load_main=False, load_colors=False, load_colorscheme=False, load_theme=False):
        """(Re)create renderer object. Can be used after Powerline object was 
		successfully initialized. If any of the below parameters except 
		``load_main`` is True renderer object will be recreated.

		:param bool load_main:
			Determines whether main configuration file (:file:`config.json`) 
			should be loaded. If appropriate configuration changes implies 
			``load_colorscheme`` and ``load_theme`` and recreation of renderer 
			object. Won’t trigger recreation if only unrelated configuration 
			changed.
		:param bool load_colors:
			Determines whether colors configuration from :file:`colors.json` 
			should be (re)loaded.
		:param bool load_colorscheme:
			Determines whether colorscheme configuration should be (re)loaded.
		:param bool load_theme:
			Determines whether theme configuration should be reloaded.
		"""
        common_config_differs = False
        ext_config_differs = False
        if load_main:
            self._purge_configs("main")
            config = self.load_main_config()
            self.common_config = finish_common_config(self.get_encoding(), config["common"])
            if self.common_config != self.prev_common_config:
                common_config_differs = True

                load_theme = (
                    load_theme
                    or not self.prev_common_config
                    or self.prev_common_config["default_top_theme"] != self.common_config["default_top_theme"]
                )

                log_keys_differ = not self.prev_common_config or (
                    _get_log_keys(self.prev_common_config) != _get_log_keys(self.common_config)
                )

                self.prev_common_config = self.common_config

                if log_keys_differ:
                    if self.had_logger:
                        self.pl = PowerlineLogger(self.use_daemon_threads, self.logger, self.ext)
                        self.get_module_attr = gen_module_attr_getter(
                            self.pl, self.common_config["paths"], self.imported_modules
                        )
                    else:
                        self.logger, self.pl, self.get_module_attr = self.create_logger()
                    self.config_loader.pl = self.pl

                if not self.run_once:
                    self.config_loader.set_watcher(self.common_config["watcher"])

                mergedicts(
                    self.renderer_options,
                    dict(
                        pl=self.pl,
                        term_truecolor=self.common_config["term_truecolor"],
                        term_escape_style=self.common_config["term_escape_style"],
                        ambiwidth=self.common_config["ambiwidth"],
                        tmux_escape=self.common_config["additional_escapes"] == "tmux",
                        screen_escape=self.common_config["additional_escapes"] == "screen",
                        theme_kwargs={
                            "ext": self.ext,
                            "common_config": self.common_config,
                            "run_once": self.run_once,
                            "shutdown_event": self.shutdown_event,
                            "get_module_attr": self.get_module_attr,
                        },
                    ),
                )

                if not self.run_once and self.common_config["reload_config"]:
                    interval = self.common_config["interval"]
                    self.config_loader.set_interval(interval)
                    self.run_loader_update = interval is None
                    if interval is not None and not self.config_loader.is_alive():
                        self.config_loader.start()

            self.ext_config = config["ext"][self.ext]

            top_theme = self.ext_config.get("top_theme") or self.common_config["default_top_theme"]
            self.theme_levels = (os.path.join("themes", top_theme), os.path.join("themes", self.ext, "__main__"))
            self.renderer_options["theme_kwargs"]["top_theme"] = top_theme

            if self.ext_config != self.prev_ext_config:
                ext_config_differs = True
                if not self.prev_ext_config or self.ext_config.get("components") != self.prev_ext_config.get(
                    "components"
                ):
                    self.setup_components(self.ext_config.get("components"))
                if not self.prev_ext_config or self.ext_config.get("local_themes") != self.prev_ext_config.get(
                    "local_themes"
                ):
                    self.renderer_options["local_themes"] = self.get_local_themes(self.ext_config.get("local_themes"))
                load_colorscheme = (
                    load_colorscheme
                    or not self.prev_ext_config
                    or self.prev_ext_config["colorscheme"] != self.ext_config["colorscheme"]
                )
                load_theme = (
                    load_theme or not self.prev_ext_config or self.prev_ext_config["theme"] != self.ext_config["theme"]
                )
                self.prev_ext_config = self.ext_config

        create_renderer = load_colors or load_colorscheme or load_theme or common_config_differs or ext_config_differs

        if load_colors:
            self._purge_configs("colors")
            self.colors_config = self.load_colors_config()

        if load_colorscheme or load_colors:
            self._purge_configs("colorscheme")
            if load_colorscheme:
                self.colorscheme_config = self.load_colorscheme_config(self.ext_config["colorscheme"])
            self.renderer_options["theme_kwargs"]["colorscheme"] = Colorscheme(
                self.colorscheme_config, self.colors_config
            )

        if load_theme:
            self._purge_configs("theme")
            self.renderer_options["theme_config"] = self.load_theme_config(self.ext_config.get("theme", "default"))

        if create_renderer:
            Renderer = self.get_module_attr(self.renderer_module, "renderer")
            if not Renderer:
                if hasattr(self, "renderer"):
                    return
                else:
                    raise ImportError("Failed to obtain renderer")

                    # Renderer updates configuration file via segments’ .startup thus it
                    # should be locked to prevent state when configuration was updated,
                    # but .render still uses old renderer.
            try:
                renderer = Renderer(**self.renderer_options)
            except Exception as e:
                self.exception("Failed to construct renderer object: {0}", str(e))
                if not hasattr(self, "renderer"):
                    raise
            else:
                self.renderer = renderer