Sublime Forum

Change sublime default settings only effect in plugin scope

#1

Hi Folks,
I am working on a sublime Event_listener auto complete plugin, specifically add auto complete in on_query_completions function. And I need to change word_separator under default setting


Basically the goal is to remove dot as a word separator while I am typing words, but soon before the on_query_completion ends, change back word_separator to original value, so that users will not be impact when the auto completion will not trigger.
Some pseudo code

class EventListener(sublime_plugin.EventListener):
    def on_query_completions(self, view, prefix, locations):

        # find table as a pattern IN
        def is_alias(view, cursor, all_tables):
            # load setting for word sep, uncheck space then bring it back
            # find preceding 3 word
            a = view.lines(cursor)[0].a
            b = view.lines(cursor)[0].b
            if a > b:
                a, b = b, a
            current_line_str = view.substr(sublime.Region(a, b))
            current_line_lst = current_line_str.split(" ")
            intersection = list(set(current_line_lst) & set(all_tables))
            if len(intersection) == 0:
                return
            else:
                for tbl in intersection:
                    idx = current_line_lst.index(tbl)
                    if current_line_lst[idx + 1] == "as" and idx + 2 < len(
                        current_line_lst
                    ):
                        alias = current_line_lst[idx + 2]
                        alias_dict = {alias: tbl}
                        current_aliases = write_to_alias(alias_dict)
                        # final.update(alias_dict)
            print("Line start {}, end {}, string is {}".format(a, b, current_line_str))


        '''
        CHECK HERE !!!
        word_separator set to /\\()\"'-:,;<>~!@#$%^&*|+=[]{}`~?
        '''
        settings = sublime.load_settings("Preferences.sublime-settings")
        settings.set("word_separator", "/\\()\"'-:,;<>~!@#$%^&*|+=[]{}`~?")
        sublime.save_settings("Preferences.sublime-settings")

        customCompletion_Files = sublime.find_resources("EDW_SQL.custom-completions")
        file = customCompletion_Files[0]
        jsonString = sublime.load_resource(file)
        jsonValues = sublime.decode_value(jsonString)

        # this will check if autocompletion will effect in what kind of file
        fileExtensions = jsonValues["fileExtensions"]
        completionSeparator = jsonValues["separator"]
        jsonCompletions = jsonValues["completions"]
        all_tables = [
            "{}.{}".format(db, tbl_key)
            for db, tbl in jsonCompletions.items()
            for tbl_key, cols in tbl.items()
        ]
        enable = jsonValues["enable"]
        # alias = jsonValues["alias"]

        if enable is not True:
            return

        if len(fileExtensions) == 0:
            fileExtension_Verification_Enabled = False
        else:
            fileExtension_Verification_Enabled = True

        syntax = view.settings().get("syntax")
        syntax = syntax.split("/")[1].lower()

        fileExtension_Match_Found = False
        for extension in fileExtensions:
            if extension.lower() == syntax:
                fileExtension_Match_Found = True


        if (
            fileExtension_Verification_Enabled == True
            and fileExtension_Match_Found == False
        ):
            return []

        input_cursor_word = []
        for cursor in view.sel():
            alias_dict = is_alias(view, cursor, all_tables)
            input_cursor_word.append(view.substr(view.word(cursor)))

        print("current cursor word", input_cursor_word)

        #  Populate Completions  #
        completions = []
        preload = False
        for word in input_cursor_word:
            ct = word.count(completionSeparator)
            if ct == 0:
                for db in jsonCompletions:
                    txt_show = db + f"\tdatabase"
                    completions.append((txt_show, db))
            if ct == 1:
                db, temp = word.split(completionSeparator)
                if db in jsonCompletions:
                    tbl_lst = list(jsonCompletions[db].keys())
                    print(tbl_lst)
                    for tbl in tbl_lst:
                        txt = db + completionSeparator + tbl
                        txt_show = txt + "\ttable"
                        completions.append((txt_show, txt))

            if ct == 2:
                db, tbl, temp = word.split(completionSeparator)
                if db in jsonCompletions:
                    tbl_lst = list(jsonCompletions[db].keys())
                    if tbl in tbl_lst:
                        print(db, tbl, "here")
                        cols = jsonCompletions[db][tbl]
                        for col in cols:
                            txt = (
                                db
                                + completionSeparator
                                + tbl
                                + completionSeparator
                                + col
                            )
                            dtype = type_mapping[cols[col]]
                            txt_show = txt + f"\t{dtype}"
                            txt_auto_complete = (
                                f"SELECT a.{col}$0 FROM {db}.{tbl} as a ;"
                            )
                            preload = True
                            completions.append((txt_show, txt_auto_complete))



        '''
        CHECK HERE !!!
        word_separator change to ./\\()\"'-:,.;<>~!@#$%^&*|+=[]{}`~?
        '''

        settings = sublime.load_settings("Preferences.sublime-settings")
        settings.set("word_separator", "./\\()\"'-:,.;<>~!@#$%^&*|+=[]{}`~?")
        sublime.save_settings("Preferences.sublime-settings")


        return (completions, sublime.INHIBIT_WORD_COMPLETIONS)

So if y’all focus on the CHECK HERE, basically I want to change the setting while I am run this autocompletion and then change it back when I end run the completion . It won’t work as expected. It will only work if I save word_separator without dot in preference setting under user folder.

How can I achieve the same thing here?

0 Likes

#2

In auto-completion plugin should IMHO never mess with user settings this way, especially calling sublime.save_settings() each time is horrible.

0 Likes

#3

Hey sorry for the late reply.
I know this is definitely a horrible practice, but I just can’t think of other way to achieve similar result:
overwrite sublime’s default setting within the scope of plugin and return to the original value afterward. Even though event listener on_query_completion will trigger everytime user type something…

0 Likes

#4

It’s unclear from your code sample but are you saying that somehow view.set_settings() to alter the setting in a non destructive way only in the view that the event is running inside of doesn’t work?

0 Likes