<commit_before>"""This module encapsulates communication with sublime settings

Attributes:
    log (logging.Logger): logger
"""
import sublime
import logging
import re

import os.path as path

from .tools import PKG_NAME

log = logging.getLogger(__name__)
log.debug(" reloading module")


class Settings:

    """class that encapsulates sublime settings

    Attributes:
        clang_binary (string): name of clang binary to be used
        complete_all (bool): flag to trigger autocompletion on every keystroke
        errors_on_save (bool): if true, show errors on save
        include_dirs (string[]): array of directories with headers
        include_file_folder (bool): if true, current location -> 'include_dirs'
        include_parent_folder (bool): if true, parent -> 'include_dirs'
        search_clang_complete (bool): if true search for '.clang_complete'
                                        file up the tree
        std_flag (string): flag of the c++ std library, e.g. -std=c++11
        subl_settings (sublime.settings): link to sublime text settings dict
        triggers (string[]): triggers that trigger autocompletion
        use_libclang (TYPE): Description
        verbose (bool): verbose flag
    """

    subl_settings = None

    verbose = None
    include_file_folder = None
    include_parent_folder = None
    complete_all = None
    triggers = None
    include_dirs = None
    clang_binary = None
    std_flag = None
    search_clang_complete = None
    errors_on_save = None
    use_libclang = None

    def __init__(self):
        """Initialize the class.
        """
        self.load_settings()
        if not self.is_valid():
            log.critical(" Could not load settings!")
            log.critical(" NO AUTOCOMPLETE WILL BE AVAILABLE")
            return

    def on_settings_changed(self):
        """When user changes settings, trigger this.
        """
        self.load_settings()
        log.info(" settings changed and reloaded")

    def load_settings(self):
        """Load settings from sublime dictionary to internal variables
        """
        self.subl_settings = sublime.load_settings(
            PKG_NAME + ".sublime-settings")
        self.verbose = self.subl_settings.get("verbose")
        self.complete_all = self.subl_settings.get("autocomplete_all")
        self.include_parent_folder = self.subl_settings.get(
            "include_file_parent_folder")
        self.include_file_folder = self.subl_settings.get(
            "include_file_folder")
        self.triggers = self.subl_settings.get("triggers")
        self.include_dirs = self.subl_settings.get("include_dirs")
        self.clang_binary = self.subl_settings.get("clang_binary")
        self.errors_on_save = self.subl_settings.get("errors_on_save")
        self.std_flag = self.subl_settings.get("std_flag")
        self.use_libclang = self.subl_settings.get("use_libclang")
        self.search_clang_complete = self.subl_settings.get(
            "search_clang_complete_file")
        self.project_specific_settings = self.subl_settings.get(
            "use_project_specific_settings")

        self.subl_settings.clear_on_change(PKG_NAME)
        self.subl_settings.add_on_change(PKG_NAME, self.on_settings_changed)

        self.project_base_name = ""
        self.project_base_folder = ""
        variables = sublime.active_window().extract_variables()
        if 'folder' in variables:
            self.project_base_folder = variables['folder']
        if 'project_base_name' in variables:
            self.project_base_name = variables['project_base_name']

        if self.std_flag is None:
            self.std_flag = "-std=c++11"
            log.debug(" set std_flag to default: %s", self.std_flag)

    def get_project_clang_flags(self):
        """Get clang flags for the current project 

        Returns:
            list(str): flags for clang, None if no project found
        """
        try:
            project_data = sublime.active_window().project_data()
            log.debug(" project data: %s", project_data)
            project_settings = project_data["settings"]
            log.debug(" project settings: %s", project_settings)
            project_flags = project_settings["clang_flags"]
            log.debug(" project_flags: %s", project_flags)
            for flag in project_flags:
                if flag.startswith('-I'):
                    path_to_add = flag[2:].rstrip()
                    if path.isabs(path_to_add):
                        flag = '-I "{}"'.format(path.normpath(path_to_add))
                    else:
                        flag = '-I "{}"'.format(
                            path.join(self.project_base_folder, path_to_add))
                elif flag.startswith('-std'):<commit_msg>remove trailing space<commit_after>"""This module encapsulates communication with sublime settings

Attributes:
    log (logging.Logger): logger
"""
import sublime
import logging
import re

import os.path as path

from .tools import PKG_NAME

log = logging.getLogger(__name__)
log.debug(" reloading module")


class Settings:

    """class that encapsulates sublime settings

    Attributes:
        clang_binary (string): name of clang binary to be used
        complete_all (bool): flag to trigger autocompletion on every keystroke
        errors_on_save (bool): if true, show errors on save
        include_dirs (string[]): array of directories with headers
        include_file_folder (bool): if true, current location -> 'include_dirs'
        include_parent_folder (bool): if true, parent -> 'include_dirs'
        search_clang_complete (bool): if true search for '.clang_complete'
                                        file up the tree
        std_flag (string): flag of the c++ std library, e.g. -std=c++11
        subl_settings (sublime.settings): link to sublime text settings dict
        triggers (string[]): triggers that trigger autocompletion
        use_libclang (TYPE): Description
        verbose (bool): verbose flag
    """

    subl_settings = None

    verbose = None
    include_file_folder = None
    include_parent_folder = None
    complete_all = None
    triggers = None
    include_dirs = None
    clang_binary = None
    std_flag = None
    search_clang_complete = None
    errors_on_save = None
    use_libclang = None

    def __init__(self):
        """Initialize the class.
        """
        self.load_settings()
        if not self.is_valid():
            log.critical(" Could not load settings!")
            log.critical(" NO AUTOCOMPLETE WILL BE AVAILABLE")
            return

    def on_settings_changed(self):
        """When user changes settings, trigger this.
        """
        self.load_settings()
        log.info(" settings changed and reloaded")

    def load_settings(self):
        """Load settings from sublime dictionary to internal variables
        """
        self.subl_settings = sublime.load_settings(
            PKG_NAME + ".sublime-settings")
        self.verbose = self.subl_settings.get("verbose")
        self.complete_all = self.subl_settings.get("autocomplete_all")
        self.include_parent_folder = self.subl_settings.get(
            "include_file_parent_folder")
        self.include_file_folder = self.subl_settings.get(
            "include_file_folder")
        self.triggers = self.subl_settings.get("triggers")
        self.include_dirs = self.subl_settings.get("include_dirs")
        self.clang_binary = self.subl_settings.get("clang_binary")
        self.errors_on_save = self.subl_settings.get("errors_on_save")
        self.std_flag = self.subl_settings.get("std_flag")
        self.use_libclang = self.subl_settings.get("use_libclang")
        self.search_clang_complete = self.subl_settings.get(
            "search_clang_complete_file")
        self.project_specific_settings = self.subl_settings.get(
            "use_project_specific_settings")

        self.subl_settings.clear_on_change(PKG_NAME)
        self.subl_settings.add_on_change(PKG_NAME, self.on_settings_changed)

        self.project_base_name = ""
        self.project_base_folder = ""
        variables = sublime.active_window().extract_variables()
        if 'folder' in variables:
            self.project_base_folder = variables['folder']
        if 'project_base_name' in variables:
            self.project_base_name = variables['project_base_name']

        if self.std_flag is None:
            self.std_flag = "-std=c++11"
            log.debug(" set std_flag to default: %s", self.std_flag)

    def get_project_clang_flags(self):
        """Get clang flags for the current project

        Returns:
            list(str): flags for clang, None if no project found
        """
        try:
            project_data = sublime.active_window().project_data()
            log.debug(" project data: %s", project_data)
            project_settings = project_data["settings"]
            log.debug(" project settings: %s", project_settings)
            project_flags = project_settings["clang_flags"]
            log.debug(" project_flags: %s", project_flags)
            for flag in project_flags:
                if flag.startswith('-I'):
                    path_to_add = flag[2:].rstrip()
                    if path.isabs(path_to_add):
                        flag = '-I "{}"'.format(path.normpath(path_to_add))
                    else:
                        flag = '-I "{}"'.format(
                            path.join(self.project_base_folder, path_to_add))
                elif flag.startswith('-std'):
{'fraction_non_alphanumeric': 0.09349124829682423, 'fraction_numerical': 0.0010481081647626036, 'mean_word_length': 2.442279942279942, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7359172', 'n_tokens_mistral': 2750, 'n_tokens_neox': 2662, 'n_words': 641}