<commit_before># Class for configuring StatusBarExtended

from fman import ApplicationCommand, \
 show_prompt, show_alert, show_status_message, load_json, save_json, \
 PLATFORM, DATA_DIRECTORY
from fman.fs import exists, delete, move_to_trash
from fman.url import as_human_readable as as_path, as_url, join, splitscheme, basename, dirname

class SingletonConfig(object):
    def __new__(cls):
        """Create the global config singleton object or return the existing one."""
        if not hasattr(cls, 'instance'):
            cls.instance = super(SingletonConfig, cls).__new__(cls)
            cls.instance.__initialized = False
        return cls.instance

    def __init__(self): # set the defaults only once
        if(self.__initialized): return
        self.__initialized = True
        self.setDefault()

    @classmethod
    def setDefault(cls): # set the defaults in a dictionary
        cls.Default                 = dict()
        cls.Default['Enabled']      = True    # enable plugin
        cls.Default['SizeDivisor']  = 1024.0    # binary file sizes
        cls.Default['MaxGlob']      = 5000      # skip large folders with as many items; 0=∞
        cls.Default['SymbolPane']   = ['◧','◨'] # Left/Right
        cls.Default['SymbolHiddenF']= ['◻','◼'] # Show/Hide hidden files
        cls.Default['HideDotfile']  = False     # hide non-hidden dotfiles on Windows
        cls.Default['Justify']      = {       # right-justification parameter
                    'folder'        : 5 ,
                    'file'          : 5 ,
                    'size'          : 7 }
        cls.msgTimeout = 5 # timeout in seconds for show_status_message

    @classmethod
    def loadConfig(cls):
        """Check StatusBarExtended.json for consistency/completeness, restore defaults on fail"""
        msg_t = cls.msgTimeout
        if hasattr(cls, 'locked_update'):
            show_status_message("StatusBarExtended: waiting for the config files to be updated, try again later...")
            return None, 'UpdateInProgress'
        cls.locked_update = True # ensure globally unique 'loadConfig' run so that e.g. we don't ask a user multiple times to delete corrupted configs

        cfgCurrent = load_json('StatusBarExtended.json') # within one fman session, it is guaranteed that multiple calls to load_json(...) with the same JSON name always return the same object, so save {} when deleting the files to force reload
        if type(cfgCurrent) not in (type(dict()), type(None)):
            # delete config files, fman's save_json can't replace types
            config_files       = ['StatusBarExtended.json']
            config_files.append(  'StatusBarExtended ('+PLATFORM+').json')
            user_settings_url  = join(as_url(DATA_DIRECTORY),'Plugins','User','Settings')
            user_input_allow   = ''
            prompt_msg_full    = ''
            corrupt_config     = []
            for f in config_files:
                f_url  = join(user_settings_url,f)
                f_path = as_path(f_url)

                if not exists(f_url):
                    continue
<commit_msg>:recycle: make dictionary ordered<commit_after># Class for configuring StatusBarExtended

from fman import ApplicationCommand, \
 show_prompt, show_alert, show_status_message, load_json, save_json, \
 PLATFORM, DATA_DIRECTORY
from fman.fs import exists, delete, move_to_trash
from fman.url import as_human_readable as as_path, as_url, join, splitscheme, basename, dirname
from collections import OrderedDict as odict

class SingletonConfig(object):
    def __new__(cls):
        """Create the global config singleton object or return the existing one."""
        if not hasattr(cls, 'instance'):
            cls.instance = super(SingletonConfig, cls).__new__(cls)
            cls.instance.__initialized = False
        return cls.instance

    def __init__(self): # set the defaults only once
        if(self.__initialized): return
        self.__initialized = True
        self.setDefault()

    @classmethod
    def setDefault(cls): # set the defaults in a dictionary
        cls.Default                 = odict()
        cls.Default['Enabled']      = True    # enable plugin
        cls.Default['SizeDivisor']  = 1024.0    # binary file sizes
        cls.Default['MaxGlob']      = 5000      # skip large folders with as many items; 0=∞
        cls.Default['SymbolPane']   = ['◧','◨'] # Left/Right
        cls.Default['SymbolHiddenF']= ['◻','◼'] # Show/Hide hidden files
        cls.Default['HideDotfile']  = False     # hide non-hidden dotfiles on Windows
        cls.Default['Justify']      = odict({   # right-justification parameter
                    'folder'        : 5 ,
                    'file'          : 5 ,
                    'size'          : 7 })
        cls.msgTimeout = 5 # timeout in seconds for show_status_message

    @classmethod
    def loadConfig(cls):
        """Check StatusBarExtended.json for consistency/completeness, restore defaults on fail"""
        msg_t = cls.msgTimeout
        if hasattr(cls, 'locked_update'):
            show_status_message("StatusBarExtended: waiting for the config files to be updated, try again later...")
            return None, 'UpdateInProgress'
        cls.locked_update = True # ensure globally unique 'loadConfig' run so that e.g. we don't ask a user multiple times to delete corrupted configs

        cfgCurrent = load_json('StatusBarExtended.json') # within one fman session, it is guaranteed that multiple calls to load_json(...) with the same JSON name always return the same object, so save {} when deleting the files to force reload
        if type(cfgCurrent) not in (type(dict()), type(None)):
            # delete config files, fman's save_json can't replace types
            config_files       = ['StatusBarExtended.json']
            config_files.append(  'StatusBarExtended ('+PLATFORM+').json')
            user_settings_url  = join(as_url(DATA_DIRECTORY),'Plugins','User','Settings')
            user_input_allow   = ''
            prompt_msg_full    = ''
            corrupt_config     = []
            for f in config_files:
                f_url  = join(user_settings_url,f)
                f_path = as_path(f_url)

                if not exists(f_url):
                    continue

{'fraction_non_alphanumeric': 0.09338645418326694, 'fraction_numerical': 0.004462151394422311, 'mean_word_length': 2.418300653594771, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2960791', 'n_tokens_mistral': 1739, 'n_tokens_neox': 1660, 'n_words': 516}