예제 #1
0
	def should_not_validate_after_closing_bracket(self, vh):
		vh.set_line('require ("require("../package").subPackage');
		vh.move_cursor(0, 35)

		print(get_context(vh.view))
		result = get_context(vh.view).get("valid_needle")

		self.assert_equal(result, False)
예제 #2
0
    def should_not_validate_after_closing_bracket(self, vh):
        vh.set_line('require ("require("../package").subPackage')
        vh.move_cursor(0, 35)

        print(get_context(vh.view))
        result = get_context(vh.view).get("valid_needle")

        self.assert_equal(result, False)
예제 #3
0
    def should_return_style_in_quotes(self, vh):
        vh.set_line('"background": prefix(test)')
        vh.move_cursor(0, 23)

        result = get_context(vh.view).get("style")

        self.assert_equal(result, 'background')
예제 #4
0
    def should_return_prefix_before_colon(self, viewHelper):
        viewHelper.set_line('prefix:file')
        viewHelper.move_cursor(0, 10)

        result = get_context(viewHelper.view).get("prefix")

        self.assert_equal(result, 'prefix')
예제 #5
0
    def should_return_word_as_needle(self, viewHelper):
        viewHelper.set_line('result = path')
        viewHelper.move_cursor(0, 12)

        needle = get_context(viewHelper.view).get("needle")

        self.assert_equal(needle, 'path')
예제 #6
0
    def should_return_tagName(self, vh):
        vh.set_line('<div id')
        vh.move_cursor(0, 10)

        result = get_context(vh.view).get("tagName")

        self.assert_equal(result, 'div')
예제 #7
0
    def on_post_insert_completion(view, post_remove):
        start_expression = FuzzyFilePath.start_expression
        expression = Context.get_context(view)

        # diff of previous needle and inserted needle
        diff = get_diff(post_remove, expression["needle"])
        # cleanup string
        final_path = re.sub("^" + diff["start"], "", expression["needle"])
        # do not replace current word
        if diff["end"] != start_expression["word"]:
            final_path = re.sub(diff["end"] + "$", "", final_path)

        # remove path query completely
        final_path = Completion.get_final_path(final_path)
        log("post cleanup path:'", expression.get("needle"), "' ~~> '",
            final_path, "'")

        # replace current query with final path
        view.run_command(
            "ffp_replace_region", {
                "a": expression["region"].a,
                "b": expression["region"].b,
                "string": final_path,
                "move_cursor": True
            })
예제 #8
0
def update_inserted_filepath(view, post_remove):
    """ post completion: adjusts inserted filepath """
    expression = Context.get_context(view)
    # diff of previous needle and inserted needle
    diff = get_diff(post_remove, expression["needle"])
    # cleanup string
    result = re.sub("^" + diff["start"], "", expression["needle"])
    # do not replace current word
    if diff["end"] != start_expression["word"]:
        result = re.sub(diff["end"] + "$", "", result)

    # remove path query completely
    result = apply_post_replacements(result, state.get("base_directory"),
                                     state.get("replace_on_insert"))
    log("post cleanup path:'", expression.get("needle"), "' ~~> '", result,
        "'")

    # replace current query with final path
    view.run_command(
        "ffp_replace_region", {
            "a": expression["region"].a,
            "b": expression["region"].b,
            "string": result,
            "move_cursor": True
        })
예제 #9
0
	def should_return_word_as_needle(self, viewHelper):
		viewHelper.set_line('result = path')
		viewHelper.move_cursor(0, 12)

		needle = get_context(viewHelper.view).get("needle")

		self.assert_equal(needle, 'path')
예제 #10
0
    def run(self, edit):
        context = Context.get_context(self.view)
        current_scope = self.view.scope_name(Selection.get_position(self.view))
        trigger = resolve_trigger(self.view, Query)
        print("FOUND TRIGGER", trigger)

        self.content = "<h4>FuzzyFilepath - context evaluation</h4>"
        self.add("filepath valid", context.get("valid_needle"))
        self.add("context valid", context.get("is_valid"))
        self.content += "<br>"
        self.add("path", context.get("needle"))
        self.add("prefix", context.get("prefix"))
        self.add("property", context.get("style"))
        self.add("tag", context.get("tagName"))
        self.add("word", context.get("word"))
        self.content += "<br>"
        self.add("scope", current_scope)
        self.content += "<br>"
        self.content += "<h5>Trigger</h5>"
        if trigger is False:
            self.content += "no trigger could be found matching the given context"
        else:
            for key in trigger:
                self.add(key, trigger.get(key))

        self.show()
예제 #11
0
    def should_return_line_as_needle(self, viewHelper):
        viewHelper.set_line('../line/as/path')
        viewHelper.move_cursor(0, 12)

        needle = get_context(viewHelper.view).get("needle")

        self.assert_equal(needle, '../line/as/path')
예제 #12
0
	def should_return_tagName(self, vh):
		vh.set_line('<div id')
		vh.move_cursor(0, 10)

		result = get_context(vh.view).get("tagName")

		self.assert_equal(result, 'div')
예제 #13
0
	def should_return_style_in_quotes(self, vh):
		vh.set_line('"background": prefix(test)')
		vh.move_cursor(0, 23)

		result = get_context(vh.view).get("style")

		self.assert_equal(result, 'background')
예제 #14
0
	def should_return_line_as_needle(self, viewHelper):
		viewHelper.set_line('../line/as/path')
		viewHelper.move_cursor(0, 12)

		needle = get_context(viewHelper.view).get("needle")

		self.assert_equal(needle, '../line/as/path')
예제 #15
0
	def should_return_prefix_before_colon(self, viewHelper):
		viewHelper.set_line('prefix:file')
		viewHelper.move_cursor(0, 10)

		result = get_context(viewHelper.view).get("prefix")

		self.assert_equal(result, 'prefix')
예제 #16
0
    def should_return_style_in_tag(self, vh):
        vh.set_line('<h1 style=\"\'background\': prefix(\'test\')\"')
        vh.move_cursor(0, 36)

        result = get_context(vh.view)

        self.assert_equal(result.get("tagName"), 'h1')
        self.assert_equal(result.get("style"), 'background')
예제 #17
0
    def should_identify_hbs_partials(self, viewHelper):
        viewHelper.set_line('{{> src/to/folder/file.hbs}}')
        viewHelper.move_cursor(0, 10)

        context = get_context(viewHelper.view)

        self.assert_equal(context.get("needle"), 'src/to/folder/file.hbs')
        self.assert_equal(context.get("region").a, 4)
예제 #18
0
	def should_return_style_in_tag(self, vh):
		vh.set_line('<h1 style=\"\'background\': prefix(\'test\')\"')
		vh.move_cursor(0, 36)

		result = get_context(vh.view)

		self.assert_equal(result.get("tagName"), 'h1')
		self.assert_equal(result.get("style"), 'background')
예제 #19
0
 def start_tracking(self, view, command_name=None):
     self.track_insert["active"] = True
     self.track_insert["start_line"] = Selection.get_line(view)
     """
         - sublime inserts completions by replacing the current word
         - this results in wrong path insertions if the query contains word_separators like slashes
         - thus the path until current word has to be removed after insertion
         - ... and possibly afterwards
     """
     context = Context.get_context(view)
     needle = context.get("needle")
     word = re.escape(Selection.get_word(view))
     self.post_remove = re.sub(word + "$", "", needle)
     verbose(ID, "start tracking", self.post_remove)
예제 #20
0
def resolve_trigger(view, query):
    global start_expression

    # parse current context, may contain 'is_valid: False'
    start_expression = Context.get_context(view)
    if start_expression["error"] and not query.by_command():
        verbose(ID, "abort - not a valid context")
        return False

    current_scope = Selection.get_scope(view)
    trigger = find_trigger(current_scope, start_expression, query.by_command())

    # currently trigger is required in Query.build
    if trigger is False:
        verbose(ID, "abort - no trigger found")
        return False

    return trigger
    def run(self, edit):
    	print("show context")
    	context = Context.get_context(self.view)
    	current_scope = self.view.scope_name(Selection.get_position(self.view))

    	self.content = "<h4>FuzzyFilepath - context evaluation</h4>"
    	self.add("filepath valid", context.get("valid_needle"))
    	self.add("context valid", context.get("is_valid"))
    	self.content += "<br>"
    	self.add("path", context.get("needle"))
    	self.add("prefix", context.get("prefix"))
    	self.add("property", context.get("style"))
    	self.add("tag", context.get("tagName"))
    	self.add("word", context.get("word"))
    	self.content += "<br>"
    	self.add("scope", current_scope)

    	self.show()
예제 #22
0
    def run(self, edit):
        print("show context")
        context = Context.get_context(self.view)
        current_scope = self.view.scope_name(Selection.get_position(self.view))

        self.content = "<h4>FuzzyFilepath - context evaluation</h4>"
        self.add("filepath valid", context.get("valid_needle"))
        self.add("context valid", context.get("is_valid"))
        self.content += "<br>"
        self.add("path", context.get("needle"))
        self.add("prefix", context.get("prefix"))
        self.add("property", context.get("style"))
        self.add("tag", context.get("tagName"))
        self.add("word", context.get("word"))
        self.content += "<br>"
        self.add("scope", current_scope)

        self.show()
예제 #23
0
    def run(self, edit):
        current_directory = os.path.dirname(self.view.file_name())
        context = Context.get_context(self.view)
        if context.get("valid") is False:
            return log(ID, "abort, no valid path given:", context.get("needle"))

        path = context.get("needle")
        project_folder = state.get_project_directory()

        if not (path and project_folder):
            return log(ID, "path or project invalid", path, project_folder)

        is_relative = Path.is_relative(path)
        if is_relative:
            path = Path.get_absolute_path(current_directory, path)
            path = re.sub(project_folder, "", path)


        path = re.sub("^[\\\\/\.]", "", path)
        realpath = path
        # cleanup string, in case there are special characters for a path
        # e.g. webpack uses ~, which is not part of path
        path = re.sub("[^A-Za-z0-9 \-_\\\\/.%?#]*", "", path)
        files = state.find_file(path)

        if len(files) == 0:
            # it may be an uncached file, try to open it by using the real path
            if self.filepath_exists(os.path.join(project_folder, realpath)):
                return self.open_file(project_folder, realpath)
            return log(ID, "failed finding file", path, "it is not within the cache and not a realpath")

        if len(files) == 1:
            self.open_file(project_folder, files[0])
        else:
            # if javascript, search for index.js
            current_scope = self.view.scope_name(Selection.get_position(self.view))
            if re.search("\.js ", current_scope):
                for file in files:
                    if "index.js" in file:
                        return self.open_file(project_folder, file)

            self.files = files
            self.project_folder = project_folder
            self.view.show_popup_menu(files, self.select_file)
예제 #24
0
    def run(self, edit):
        current_directory = os.path.dirname(self.view.file_name())
        context = Context.get_context(self.view)
        if context.get("valid") is False:
            return log(ID, "abort, no valid path given:",
                       context.get("needle"))

        path = context.get("needle")
        project_folder = state.get_project_directory()

        if not (path and project_folder):
            return log(ID, "path or project invalid", path, project_folder)

        is_relative = Path.is_relative(path)
        if is_relative:
            path = Path.get_absolute_path(current_directory, path)
            path = re.sub(project_folder, "", path)

        path = re.sub("^[\\\\/\.]", "", path)
        files = state.find_file(path)

        if len(files) == 0:
            return log(ID, "failed finding file", path)

        if len(files) == 1:
            self.open_file(project_folder, files[0])
        else:
            # if javascript, search for index.js
            current_scope = self.view.scope_name(
                Selection.get_position(self.view))
            if re.search("\.js ", current_scope):
                for file in files:
                    if "index.js" in file:
                        return self.open_file(project_folder, file)

            self.files = files
            self.project_folder = project_folder
            self.view.show_popup_menu(files, self.select_file)
예제 #25
0
    def on_post_insert_completion(view, post_remove):
        start_expression = FuzzyFilePath.start_expression
        expression = Context.get_context(view)

        # diff of previous needle and inserted needle
        diff = get_diff(post_remove, expression["needle"])
        # cleanup string
        final_path = re.sub("^" + diff["start"], "", expression["needle"])
        # do not replace current word
        if diff["end"] != start_expression["word"]:
            final_path = re.sub(diff["end"] + "$", "", final_path)

        # remove path query completely
        final_path = Completion.get_final_path(final_path)
        log("post cleanup path:'", expression.get("needle"), "' ~~> '", final_path, "'")

        # replace current query with final path
        view.run_command("ffp_replace_region", {
            "a": expression["region"].a,
            "b": expression["region"].b,
            "string": final_path,
            "move_cursor": True
        })
예제 #26
0
    def run(self, edit):
        current_directory = os.path.dirname(self.view.file_name())

        context = Context.get_context(self.view)
        if context.get("valid") is False:
            return log(ID, "abort, no valid path given:", context.get("needle"))

        path = context.get("needle")
        project = ProjectManager.get_current_project()

        if not (path and project):
            return log(ID, "path or project invalid", path, project)

        is_relative = Path.is_relative(path)
        if is_relative:
            path = Path.get_absolute_path(current_directory, path)
            path = re.sub(project.get_directory(), "", path)

        path = re.sub("^[\\\\/\.]", "", path)
        files = project.find_file(path)

        if len(files) == 0:
            return log(ID, "failed finding file", path)

        if len(files) == 1:
            self.open_file(project.get_directory(), files[0])
        else:
            # if javascript, search for index.js
            current_scope = self.view.scope_name(Selection.get_position(self.view))
            if re.search("\.js ", current_scope):
                for file in files:
                    if "index.js" in file:
                        return self.open_file(project.get_directory(), file)

            self.files = files
            self.project_folder = project.get_directory()
            self.view.show_popup_menu(files, self.select_file)
예제 #27
0
    def on_query_completions(view, project_folder, current_folder):
        global Context, Selection

        current_scope = Selection.get_scope(view)

        if not Query.by_command():
            triggers = get_matching_autotriggers(current_scope,
                                                 config["TRIGGER"])
        else:
            triggers = config["TRIGGER"]

        if not bool(triggers):
            verbose(ID,
                    "abort query, no valid scope-regex for current context")
            return False

        # parse current context, may contain 'is_valid: False'
        expression = Context.get_context(view)
        if expression["error"] and not Query.by_command():
            verbose(ID, "abort not a valid context")
            return False

        # check if there is a trigger for the current expression
        trigger = Context.find_trigger(expression, current_scope, triggers)
        # verbose("trigger", trigger)

        # expression | trigger  | force | ACTION            | CURRENT
        # -----------|----------|-------|-------------------|--------
        # invalid    | False    | False | abort             | abort
        # invalid    | False    | True  | query needle      | abort
        # invalid    | True     | False | query             |
        # invalid    | True     | True  | query +override   |
        # valid      | False    | False | abort             | abort
        # valid      | False    | True  | query needle      | abort
        # valid      | True     | False | query             |
        # valid      | True     | True  | query +override   |

        # currently trigger is required in Query.build
        if trigger is False:
            verbose(ID, "abort completion, no trigger found")
            return False

        if not expression["valid_needle"]:
            word = Selection.get_word(view)
            expression["needle"] = re.sub("[^\.A-Za-z0-9\-\_$]", "", word)
            verbose(
                ID,
                "changed invalid needle to {0}".format(expression["needle"]))
        else:
            verbose(ID, "context evaluation {0}".format(expression))

        if Query.build(expression.get("needle"), trigger, current_folder,
                       project_folder) is False:
            # query is valid, but may not be triggered: not forced, no auto-options
            verbose(ID, "abort valid query: auto trigger disabled")
            return False

        verbose(
            ID,
            ".───────────────────────────────────────────────────────────────")
        verbose(ID, "| scope settings: {0}".format(trigger))
        verbose(ID, "| search needle: '{0}'".format(Query.needle))
        verbose(ID, "| in base path: '{0}'".format(Query.base_path))

        FuzzyFilePath.start_expression = expression
        completions = ProjectManager.search_completions(
            Query.needle, project_folder, Query.extensions, Query.base_path)

        if completions and len(completions[0]) > 0:
            Completion.start(Query.replace_on_insert)
            view.run_command('_enter_insert_mode')  # vintageous
            log("| => {0} completions found".format(len(completions)))
        else:
            sublime.status_message("FFP no filepaths found for '" +
                                   Query.needle + "'")
            Completion.stop()
            log("| => no valid files found for needle: {0}".format(
                Query.needle))

        log("")

        Query.reset()
        return completions
예제 #28
0
    def on_query_completions(view, project_folder, current_folder):
        global Context, Selection

        current_scope = Selection.get_scope(view)

        if not Query.by_command():
            triggers = get_matching_autotriggers(current_scope, config["TRIGGER"])
        else:
            triggers = config["TRIGGER"]

        if not bool(triggers):
            verbose(ID, "abort query, no valid scope-regex for current context")
            return False

        # parse current context, may contain 'is_valid: False'
        expression = Context.get_context(view)
        if expression["error"] and not Query.by_command():
            verbose(ID, "abort not a valid context")
            return False

        # check if there is a trigger for the current expression
        trigger = Context.find_trigger(expression, current_scope, triggers)
        # verbose("trigger", trigger)

        # expression | trigger  | force | ACTION            | CURRENT
        # -----------|----------|-------|-------------------|--------
        # invalid    | False    | False | abort             | abort
        # invalid    | False    | True  | query needle      | abort
        # invalid    | True     | False | query             |
        # invalid    | True     | True  | query +override   |
        # valid      | False    | False | abort             | abort
        # valid      | False    | True  | query needle      | abort
        # valid      | True     | False | query             |
        # valid      | True     | True  | query +override   |

        # currently trigger is required in Query.build
        if trigger is False:
            verbose(ID, "abort completion, no trigger found")
            return False

        if not expression["valid_needle"]:
            word = Selection.get_word(view)
            expression["needle"] = re.sub("[^\.A-Za-z0-9\-\_$]", "", word)
            verbose(ID, "changed invalid needle to {0}".format(expression["needle"]))
        else:
            verbose(ID, "context evaluation {0}".format(expression))

        if Query.build(expression.get("needle"), trigger, current_folder, project_folder) is False:
            # query is valid, but may not be triggered: not forced, no auto-options
            verbose(ID, "abort valid query: auto trigger disabled")
            return False

        verbose(ID, ".───────────────────────────────────────────────────────────────")
        verbose(ID, "| scope settings: {0}".format(trigger))
        verbose(ID, "| search needle: '{0}'".format(Query.needle))
        verbose(ID, "| in base path: '{0}'".format(Query.base_path))

        FuzzyFilePath.start_expression = expression
        completions = ProjectManager.search_completions(Query.needle, project_folder, Query.extensions, Query.base_path)

        if completions and len(completions[0]) > 0:
            Completion.start(Query.replace_on_insert)
            view.run_command('_enter_insert_mode') # vintageous
            log("| => {0} completions found".format(len(completions)))
        else:
            sublime.status_message("FFP no filepaths found for '" + Query.needle + "'")
            Completion.stop()
            log("| => no valid files found for needle: {0}".format(Query.needle))

        log("")

        Query.reset()
        return completions