コード例 #1
0
    def replace_word(self, view, edit, value):
        '''
        Replaces the current word with the provided string in each selection

        For the definition of word, see get_current_word()

        :param view:
            the current view

        :param edit:
            the current edit

        :param value:
            the string to replace the current word with
        '''
        new_regions = []
        for sel in view.sel():
            if sel.empty():
                word_region = self.get_current_word(view, sel.end())
                start_point = word_region.begin()
                end_point = word_region.end()
            else:
                word_region = self.get_current_word(view, sel)
                start_point = word_region.begin()
                end_point = word_region.end()

            view.replace(edit, getRegion(start_point, end_point), value)

            if sel.empty():
                start_point = end_point = start_point + len(value)
            else:
                end_point = start_point + len(value)
            new_regions.append(getRegion(start_point, end_point))

        self.update_selections(view, new_regions)
コード例 #2
0
    def get_fancy_prefix(self, view, location):
        '''
        Gets the prefix for the command assuming it takes a form like:
            \cite_prefix
            \ref_prefix

        These are also supported:
            \cite_prefix{
            \ref_prefix{

        The prefix is defined by everything *after* the underscore

        :param view:
            the current view

        :param location:
            either a point or a sublime.Region that defines the caret position
            or current selection
        '''
        if isinstance(location, sublime.Region):
            start = location.begin()
        else:
            start = location

        start_line = view.line(start)
        # inverse prefix so we search from the right-hand side
        line_prefix = view.substr(getRegion(start_line.begin(), start))[::-1]

        m = self.FANCY_PREFIX_RX.match(line_prefix)
        if not m:
            return getRegion(start, start)

        return getRegion(start - len(m.group(0)), start - m.start())
コード例 #3
0
    def get_common_prefix(self, view, locations):
        '''
        gets the common prefix (if any) from a list of locations

        :param view:
            the current view

        :param locations:
            either a list of points or a list of sublime.Regions
        '''
        if type(locations[0]) is int or type(locations[0]) is long:
            locations = [getRegion(l, l) for l in locations]

        old_prefix = None
        for location in locations:
            if location.empty():
                word_region = getRegion(
                    self.get_current_word(view, location).begin(),
                    location.b
                )
                prefix = view.substr(word_region)
            else:
                prefix = view.substr(location)

            if old_prefix is None:
                old_prefix = prefix
            elif old_prefix != prefix:
                prefix = ''
                break

        return prefix
コード例 #4
0
    def get_common_prefix(self, view, locations):
        '''
        gets the common prefix (if any) from a list of locations

        :param view:
            the current view

        :param locations:
            either a list of points or a list of sublime.Regions
        '''
        if type(locations[0]) is int or type(locations[0]) is long:
            locations = [getRegion(l, l) for l in locations]

        old_prefix = None
        for location in locations:
            if location.empty():
                word_region = getRegion(
                    self.get_current_word(view, location).begin(), location.b)
                prefix = view.substr(word_region)
            else:
                prefix = view.substr(location)

            if old_prefix is None:
                old_prefix = prefix
            elif old_prefix != prefix:
                prefix = ''
                break

        return prefix
コード例 #5
0
    def tuples_to_regions(self, tuples):
        '''
        Converts a list of 2-tuples to a list of corresponding regions

        This is the opposite of regions_to_tuples and is intended to
        deserialize regions serialized using that method

        :param tuples:
            an iterable of two-element tuples to convert to sublime.Regions
        '''
        if type(tuples) == tuple:
            return [getRegion(tuples[0], tuples[1])]

        return [getRegion(start, end) for start, end in tuples]
コード例 #6
0
    def on_query_context(self, view, key, operator, operand, match_all):
        '''
        supports query_context for all completion types
        key is "lt_fill_all_{name}" where name is the short name of the
        completion type, e.g. "lt_fill_all_cite", etc.
        '''
        # quick exit conditions
        for sel in view.sel():
            point = sel.b
            if (
                view.score_selector(point, "text.tex.latex") == 0 or
                view.score_selector(point, "comment") > 0
            ):
                return None

        # load the plugins
        if self.SUPPORTED_KEYS is None:
            self.SUPPORTED_KEYS = dict(
                ("lt_fill_all_{0}".format(name), name)
                for name in self.get_completion_types()
            )

        try:
            key, insert_char = key.split('.')
        except:
            insert_char = ''

        # not handled here
        if key not in self.SUPPORTED_KEYS:
            return None
        # unsupported bracket
        elif insert_char and insert_char not in self.SUPPORTED_INSERT_CHARS:
            return False
        # unsupported operators
        elif operator not in [sublime.OP_EQUAL, sublime.OP_NOT_EQUAL]:
            return False

        insert_char = self.SUPPORTED_INSERT_CHARS.get(insert_char, '')

        completion_type = self.get_completion_type(
            self.SUPPORTED_KEYS.get(key)
        )

        if not(completion_type and completion_type.is_enabled()):
            return False

        lines = [
            insert_char + view.substr(
                getRegion(view.line(sel).begin(), sel.b)
            )[::-1]
            for sel in view.sel()
        ]

        func = all if match_all else any
        result = func((
            completion_type.matches_line(line)
            for line in lines
        ))

        return result if operator == sublime.OP_EQUAL else not result
コード例 #7
0
ファイル: latex_fill_all.py プロジェクト: wolfv/LaTeXTools
    def on_query_context(self, view, key, operator, operand, match_all):
        '''
        supports query_context for all completion types
        key is "lt_fill_all_{name}" where name is the short name of the
        completion type, e.g. "lt_fill_all_cite", etc.
        '''
        # quick exit conditions
        for sel in view.sel():
            point = sel.b
            if (
                view.score_selector(point, "text.tex.latex") == 0 or
                view.score_selector(point, "comment") > 0
            ):
                return None

        # load the plugins
        if self.SUPPORTED_KEYS is None:
            self.SUPPORTED_KEYS = dict(
                ("lt_fill_all_{0}".format(name), name)
                for name in self.get_completion_types()
            )

        try:
            key, insert_char = key.split('.')
        except:
            insert_char = ''

        # not handled here
        if key not in self.SUPPORTED_KEYS:
            return None
        # unsupported bracket
        elif insert_char and insert_char not in self.SUPPORTED_INSERT_CHARS:
            return False
        # unsupported operators
        elif operator not in [sublime.OP_EQUAL, sublime.OP_NOT_EQUAL]:
            return False

        insert_char = self.SUPPORTED_INSERT_CHARS.get(insert_char, '')

        completion_type = self.get_completion_type(
            self.SUPPORTED_KEYS.get(key)
        )

        if not(completion_type and completion_type.is_enabled()):
            return False

        lines = [
            insert_char + view.substr(
                getRegion(view.line(sel).begin(), sel.b)
            )[::-1]
            for sel in view.sel()
        ]

        func = all if match_all else any
        result = func((
            completion_type.matches_line(line)
            for line in lines
        ))

        return result if operator == sublime.OP_EQUAL else not result
コード例 #8
0
    def insert_at_end(self, view, edit, value):
        '''
        Inserts a string at the end of every current selection

        :param view:
            the current view

        :param edit:
            the current edit

        :param value:
            the string to insert
        '''
        if value:
            new_regions = []
            cmd_mode = view.settings().get('command_mode', False)
            for sel in view.sel():
                # Workaround for Issue 1329 (based on @dhelonious)
                if (cmd_mode
                        and view.substr(sel.end() + 1).strip() in ('', '\x00')
                        and not view.substr(sel.end())
                        in '.|,|;|?|!|\'|"|(|)|[|]|{|}'.split('|')):
                    view.insert(edit, sel.end() + 1, value)
                else:
                    view.insert(edit, sel.end(), value)
                if sel.empty():
                    new_start = new_end = sel.end() + len(value)
                else:
                    new_start = sel.begin()
                    new_end = sel.end() + len(value)

                new_regions.append(getRegion(new_start, new_end))
            self.update_selections(view, new_regions)
コード例 #9
0
    def insert_at_end(self, view, edit, value):
        '''
        Inserts a string at the end of every current selection

        :param view:
            the current view

        :param edit:
            the current edit

        :param value:
            the string to insert
        '''
        if value:
            new_regions = []
            for sel in view.sel():
                view.insert(edit, sel.end(), value)
                if sel.empty():
                    new_start = new_end = sel.end() + len(value)
                else:
                    new_start = sel.begin()
                    new_end = sel.end() + len(value)

                new_regions.append(getRegion(new_start, new_end))
            self.update_selections(view, new_regions)
コード例 #10
0
    def get_common_fancy_prefix(self, view, locations):
        '''
        get the common fancy prefix (if any) from a list of locations

        see get_fancy_prefix for the definition of a fancy prefix

        :param view:
            the current view

        :param locations:
            either a list of points or a list of sublime.Regions
        '''
        remove_regions = []
        old_prefix = None
        new_prefix = ''

        for location in locations:
            prefix_region = self.get_fancy_prefix(view, location)
            if prefix_region.empty():
                continue

            new_prefix = view.substr(
                getRegion(prefix_region.begin() + 1, prefix_region.end()))

            remove_regions.append(prefix_region)

            if old_prefix is None:
                old_prefix = new_prefix
            elif old_prefix != new_prefix:
                # dummy value that is not None and will never match the
                # prefix
                old_prefix = True
                new_prefix = ''

        return new_prefix, remove_regions
コード例 #11
0
    def insert_at_end(self, view, edit, value):
        '''
        Inserts a string at the end of every current selection

        :param view:
            the current view

        :param edit:
            the current edit

        :param value:
            the string to insert
        '''
        cmd_mode = view.settings().get('command_mode', False)
        if value:
            new_regions = []
            for sel in view.sel():
                if cmd_mode and view.substr(sel.end() + 1) == '\n':
                    view.insert(edit, sel.end() + 1, value)
                else:
                    view.insert(edit, sel.end(), value)
                if sel.empty():
                    new_start = new_end = sel.end() + len(value)
                else:
                    new_start = sel.begin()
                    new_end = sel.end() + len(value)

                new_regions.append(getRegion(new_start, new_end))
            self.update_selections(view, new_regions)
コード例 #12
0
    def insert_at_end(self, view, edit, value):
        '''
        Inserts a string at the end of every current selection

        :param view:
            the current view

        :param edit:
            the current edit

        :param value:
            the string to insert
        '''
        if value:
            new_regions = []
            for sel in view.sel():
                view.insert(edit, sel.end(), value)
                if sel.empty():
                    new_start = new_end = sel.end() + len(value)
                else:
                    new_start = sel.begin()
                    new_end = sel.end() + len(value)

                new_regions.append(getRegion(new_start, new_end))
            self.update_selections(view, new_regions)
コード例 #13
0
    def tuples_to_regions(self, tuples):
        '''
        Converts a list of 2-tuples to a list of corresponding regions

        This is the opposite of regions_to_tuples and is intended to
        deserialize regions serialized using that method

        :param tuples:
            an iterable of two-element tuples to convert to sublime.Regions
        '''
        if type(tuples) == tuple:
            return [getRegion(tuples[0], tuples[1])]

        return [
            getRegion(start, end)
            for start, end in tuples
        ]
コード例 #14
0
    def replace_word(self, view, edit, value):
        '''
        Replaces the current word with the provided string in each selection

        For the definition of word, see get_current_word()

        :param view:
            the current view

        :param edit:
            the current edit

        :param value:
            the string to replace the current word with
        '''
        new_regions = []
        for sel in view.sel():
            if sel.empty():
                word_region = self.get_current_word(view, sel.end())
                start_point = word_region.begin()
                end_point = word_region.end()
            else:
                word_region = self.get_current_word(view, sel)
                start_point = word_region.begin()
                end_point = word_region.end()

            view.replace(
                edit, getRegion(start_point, end_point),
                value
            )

            if sel.empty:
                start_point = end_point = start_point + len(value)
            else:
                end_point = start_point + len(value)
            new_regions.append(getRegion(start_point, end_point))

        self.update_selections(view, new_regions)
コード例 #15
0
    def get_current_word(self, view, location):
        '''
        Gets the region containing the current word which contains the caret
        or the given selection.

        The current word is defined between the nearest non-word characters to
        the left and to the right of the current selected location.

        Non-word characters are defined by the WORD_SEPARATOR_RX.

        :param view:
            the current view

        :param location:
            either a point or a sublime.Region that defines the caret position
            or current selection
        '''
        if isinstance(location, sublime.Region):
            start, end = location.begin(), location.end()
        else:
            start = end = location

        start_line = view.line(start)
        end_line = view.line(end)
        # inverse prefix so we search from the right-hand side
        line_prefix = view.substr(getRegion(start_line.begin(), start))[::-1]
        line_suffix = view.substr(getRegion(end, end_line.end()))

        # prefix is the characters before caret
        m = self.WORD_SEPARATOR_RX.search(line_prefix)
        prefix = m.group(1) if m else ''

        m = self.WORD_SEPARATOR_RX.search(line_suffix)
        suffix = m.group(1) if m else ''

        return getRegion(
            start - len(prefix), end + len(suffix)
        )
コード例 #16
0
    def get_current_word(self, view, location):
        '''
        Gets the region containing the current word which contains the caret
        or the given selection.

        The current word is defined between the nearest non-word characters to
        the left and to the right of the current selected location.

        Non-word characters are defined by the WORD_SEPARATOR_RX.

        :param view:
            the current view

        :param location:
            either a point or a sublime.Region that defines the caret position
            or current selection
        '''
        if isinstance(location, sublime.Region):
            start, end = location.begin(), location.end()
        else:
            start = end = location

        start_line = view.line(start)
        end_line = view.line(end)
        # inverse prefix so we search from the right-hand side
        line_prefix = view.substr(getRegion(start_line.begin(), start))[::-1]
        line_suffix = view.substr(getRegion(end, end_line.end()))

        # prefix is the characters before caret
        m = self.WORD_SEPARATOR_RX.search(line_prefix)
        prefix = m.group(1) if m else ''

        m = self.WORD_SEPARATOR_RX.search(line_suffix)
        suffix = m.group(1) if m else ''

        return getRegion(
            start - len(prefix), end + len(suffix)
        )
コード例 #17
0
    def get_fancy_prefix(self, view, location):
        '''
        Gets the prefix for the command assuming it takes a form like:
            \cite_prefix
            \ref_prefix

        These are also supported:
            \cite_prefix{
            \ref_prefix{

        The prefix is defined by everything *after* the underscore

        :param view:
            the current view

        :param location:
            either a point or a sublime.Region that defines the caret position
            or current selection
        '''
        if isinstance(location, sublime.Region):
            start = location.begin()
        else:
            start = location

        start_line = view.line(start)
        # inverse prefix so we search from the right-hand side
        line_prefix = view.substr(getRegion(start_line.begin(), start))[::-1]

        m = self.FANCY_PREFIX_RX.match(line_prefix)
        if not m:
            return getRegion(start, start)

        return getRegion(
            start - len(m.group(0)),
            start - m.start()
        )
コード例 #18
0
    def get_common_fancy_prefix(self, view, locations):
        '''
        get the common fancy prefix (if any) from a list of locations

        see get_fancy_prefix for the definition of a fancy prefix

        :param view:
            the current view

        :param locations:
            either a list of points or a list of sublime.Regions
        '''
        remove_regions = []
        old_prefix = None
        new_prefix = ''

        for location in locations:
            prefix_region = self.get_fancy_prefix(view, location)
            if prefix_region.empty():
                continue

            new_prefix = view.substr(
                getRegion(
                    prefix_region.begin() + 1, prefix_region.end()
                )
            )

            remove_regions.append(prefix_region)

            if old_prefix is None:
                old_prefix = new_prefix
            elif old_prefix != new_prefix:
                # dummy value that is not None and will never match the
                # prefix
                old_prefix = True
                new_prefix = ''

        return new_prefix, remove_regions
コード例 #19
0
    def complete_auto_match(self, view, edit, insert_char):
        '''
        Completes brackets if auto_match is enabled; also implements the
        "smart_bracket_auto_trigger" logic, which tries to complete the nearest
        open bracket intelligently.

        :param view:
            the current view

        :param edit:
            the current edit

        :param insert_char:
            the character to try to automatch
        '''
        if sublime.load_settings('Preferences.sublime-settings').get(
                'auto_match_enabled', True):
            # simple case: we have an insert char, insert closing char,
            # if its defined
            if insert_char:
                self.insert_at_end(view, edit,
                                   self.get_match_char(insert_char))

                # if the insert_char is a bracket, move cursor to middle of
                # bracket and return
                if insert_char in self.MATCH_CHARS:
                    new_regions = []
                    for sel in view.sel():
                        if not sel.empty():
                            new_regions.append(sel)
                        else:
                            new_point = sel.end() - 1
                            new_regions.append(getRegion(new_point, new_point))

                    self.update_selections(view, new_regions)
                    return
            elif get_setting('smart_bracket_auto_trigger', True):
                # more complex: if we do not have an insert_char, try to close
                # the nearest bracket that occurs before each selection
                new_regions = []

                for sel in view.sel():
                    word_region = self.get_current_word(view, sel)
                    close_bracket = self.get_closing_bracket(view, word_region)
                    # we should close the bracket
                    if close_bracket:
                        # insert the closing bracket
                        view.insert(edit, word_region.end(), close_bracket)

                        if sel.empty():
                            if word_region.empty():
                                new_regions.append(
                                    getRegion(word_region.end(),
                                              word_region.end()))
                            else:
                                new_point = word_region.end() + len(
                                    close_bracket)
                                new_regions.append(
                                    getRegion(new_point, new_point))
                        else:
                            new_regions.append(
                                getRegion(
                                    sel.begin(),
                                    word_region.end() + len(close_bracket)))
                    else:
                        new_regions.append(sel)

                self.update_selections(view, new_regions)
コード例 #20
0
ファイル: latex_fill_all.py プロジェクト: wolfv/LaTeXTools
    def complete_auto_match(self, view, edit, insert_char):
        '''
        Completes brackets if auto_match is enabled; also implements the
        "smart_bracket_auto_trigger" logic, which tries to complete the nearest
        open bracket intelligently.

        :param view:
            the current view

        :param edit:
            the current edit

        :param insert_char:
            the character to try to automatch
        '''
        if sublime.load_settings('Preferences.sublime-settings').get(
            'auto_match_enabled', True
        ):
            # simple case: we have an insert char, insert closing char,
            # if its defined
            if insert_char:
                self.insert_at_end(
                    view, edit, self.get_match_char(insert_char)
                )

                # if the insert_char is a bracket, move cursor to middle of
                # bracket and return
                if insert_char in self.MATCH_CHARS:
                    new_regions = []
                    for sel in view.sel():
                        if not sel.empty():
                            new_regions.append(sel)
                        else:
                            new_point = sel.end() - 1
                            new_regions.append(getRegion(new_point, new_point))

                    self.update_selections(view, new_regions)
                    return

        if (
            insert_char and insert_char not in self.MATCH_CHARS and
            get_setting('smart_bracket_auto_trigger', True)
        ):
            # more complex: if we do not have an insert_char, try to close the
            # nearest bracket that occurs before each selection
            new_regions = []

            for sel in view.sel():
                word_region = self.get_current_word(view, sel)
                close_bracket = self.get_closing_bracket(view, word_region)
                # we should close the bracket
                if close_bracket:
                    # move to the position after any words separated by a comma
                    while True:
                        suffix_region = getRegion(
                            word_region.end() + 1,
                            view.line(word_region.end()).end()
                        )

                        suffix = view.substr(suffix_region)

                        # count words separated by commas as part of the
                        # argument to the current command
                        m = re.search(r',', suffix)
                        if not m:
                            break

                        word_region = self.get_current_word(
                            view,
                            word_region.end() + len(m.group(0))
                        )

                    # insert the closing bracket
                    view.insert(edit, word_region.end(), close_bracket)

                    if sel.empty():
                        if word_region.empty():
                            new_regions.append(
                                getRegion(word_region.end(), word_region.end())
                            )
                        else:
                            new_point = word_region.end() + len(close_bracket)
                            new_regions.append(
                                getRegion(new_point, new_point)
                            )
                    else:
                        new_regions.append(
                            getRegion(
                                sel.begin(),
                                word_region.end() + len(close_bracket)
                            )
                        )
                else:
                    new_regions.append(sel)

            self.update_selections(view, new_regions)
コード例 #21
0
    def get_closing_bracket(self, view, sel):
        '''
        Determines if the nearest bracket that occurs before the given
        selection is closed. If the bracket should be closed, returns the
        closing bracket to use.

        Note that this will not work if the arguments to the command span
        multiple lines, but we generally don't support that anyway.

        :param view:
            the current view

        :param sel:
            a sublime.Region indicating the selected area
        '''
        # candidates stores matched bracket-pairs so that we only have
        # to find all matches once per bracket type
        # if the view has changed, we reset the candidates
        candidates = None

        if not hasattr(self, 'last_view') or self.last_view != view.id():
            self.last_view = view.id()
            self.use_full_scan = get_setting(
                'smart_bracket_scan_full_document', False)
            candidates = self.candidates = {}

        if not self.use_full_scan:
            # always clear the candidates when not using a full scan
            candidates = {}
            # when not using a full scan, get the number of lines to
            # look-behind
            try:
                look_around = int(get_setting('smart_bracket_look_around', 5))
            except ValueError:
                look_around = 5

        if candidates is None:
            try:
                candidates = self.candidates
            except:
                candidates = self.candidates = {}

        # first, find the nearest bracket
        if type(sel) is sublime.Region:
            start, end = sel.begin(), sel.end()
        else:
            start = end = sel

        if self.use_full_scan:
            prefix = view.substr(getRegion(0, start))
            prefix_start = 0
            suffix_end = view.size()
        else:
            prefix_lines = view.lines(getRegion(0, start))
            if len(prefix_lines) >= look_around:
                prefix_start = prefix_lines[-look_around].begin()
            else:
                prefix_start = prefix_lines[0].begin()

            suffix_lines = view.lines(getRegion(end, view.size()))
            if len(suffix_lines) >= look_around:
                suffix_end = suffix_lines[look_around - 1].end()
            else:
                suffix_end = suffix_lines[-1].end()

            prefix = view.substr(getRegion(prefix_start, start))

        open_bracket, last_index = None, -1
        for char in self.MATCH_CHARS:
            index = prefix.rfind(char)
            if index > last_index:
                open_bracket, last_index = char, index

        if last_index == -1:
            # can't determine bracket to match
            return None

        close_bracket = self.MATCH_CHARS[open_bracket]
        open_brackets = []
        # this is used to throw-away as many matches as possible
        # so subsequent requests don't need to consider every match
        closed_brackets = []

        if open_bracket not in candidates:
            # find all open / close brackets in the current buffer,
            # removing all comments
            candidates[open_bracket] = results = []

            start = prefix_start
            re_str = re.escape(open_bracket) + '|' + re.escape(close_bracket)
            while True:
                if start >= suffix_end:
                    break

                c = view.find(re_str, start)
                if c is None or c.begin() == -1:
                    break

                if c.end() > suffix_end:
                    break

                if view.score_selector(c.begin(), 'comment') != 0:
                    start = c.end()
                    continue

                results.append(c)

                start = c.end()

        for candidate in candidates[open_bracket]:
            if view.substr(candidate) == open_bracket:
                if len(open_brackets) == 0 and candidate.begin() > end:
                    break

                open_brackets.append(candidate)
            else:
                try:
                    removed = open_brackets.pop()
                    if candidate.end() < start:
                        closed_brackets.append(removed)
                        closed_brackets.append(candidate)
                except IndexError:
                    # unbalanced close before open
                    if candidate.end() > end:
                        break

        if len(closed_brackets) > 0:
            candidates[open_bracket] = [
                c for c in candidates[open_bracket] if c not in closed_brackets
            ]

        # if we have an open bracket left, then the current bracket needs to
        # be closed
        return close_bracket if len(open_brackets) > 0 else None
コード例 #22
0
    def run(
        self, edit, completion_type=None, insert_char="", overwrite=False,
        force=False
    ):
        view = self.view

        for sel in view.sel():
            point = sel.b
            if not view.score_selector(point, "text.tex.latex"):
                self.complete_brackets(view, edit, insert_char)
                return

        # if completion_type is a simple string, try to load it
        if isinstance(completion_type, strbase):
            completion_type = self.get_completion_type(completion_type)
            if completion_type is None:
                if not force:
                    self.complete_brackets(view, edit, insert_char)
                return
        elif force:
            print('Cannot set `force` if completion type is not specified')
            return

        if force:
            insert_char = ''
            overwrite = False

        # tracks any regions to be removed
        remove_regions = []
        prefix = ''

        # handle the _ prefix, if necessary
        if (
            not isinstance(completion_type, FillAllHelper) or
            hasattr(completion_type, 'matches_fancy_prefix')
        ):
            fancy_prefix, remove_regions = self.get_common_fancy_prefix(
                view, view.sel()
            )

        # if we found a _ prefix, we use the raw line, so \ref_eq
        fancy_prefixed_line = None
        if remove_regions:
            fancy_prefixed_line = view.substr(
                getRegion(view.line(point).begin(), point)
            )[::-1]

        # normal line calculation
        line = (view.substr(
            getRegion(view.line(point).begin(), point)
        ) + insert_char)[::-1]

        # handle a list of completion types
        if type(completion_type) is list:
            for name in completion_type:
                try:
                    ct = self.get_completion_type(name)
                    if (
                        fancy_prefixed_line is not None and
                        hasattr(ct, 'matches_fancy_prefix')
                    ):
                        if ct.matches_fancy_prefix(fancy_prefixed_line):
                            completion_type = ct
                            prefix = fancy_prefix
                            break
                        elif ct.matches_line(line):
                            completion_type = ct
                            remove_regions = []
                            break
                    elif ct.matches_line(line):
                        completion_type = ct
                        remove_regions = []
                        break
                except:
                    pass

            if type(completion_type) is list:
                message = "No valid completions found"
                print(message)
                sublime.status_message(message)
                self.complete_brackets(view, edit, insert_char)
                return
        # unknown completion type
        elif (
            completion_type is None or
            not isinstance(completion_type, FillAllHelper)
        ):
            for name in self.get_completion_types():
                ct = self.get_completion_type(name)
                if ct is None:
                    continue

                if (
                    fancy_prefixed_line is not None and
                    hasattr(ct, 'matches_fancy_prefix')
                ):
                    if ct.matches_fancy_prefix(fancy_prefixed_line):
                        completion_type = ct
                        prefix = fancy_prefix
                        break
                    elif ct.matches_line(line):
                        completion_type = ct
                        remove_regions = []
                        break
                elif ct.matches_line(line):
                    completion_type = ct
                    remove_regions = []
                    break

            if (
                completion_type is None or
                isinstance(completion_type, strbase)
            ):
                message = \
                    'Cannot determine completion type for current selection'
                print(message)
                sublime.status_message(message)

                self.complete_brackets(view, edit, insert_char)
                return
        # assume only a single completion type to use
        else:
            # if force is set, we do no matching
            if not force:
                if (
                    fancy_prefixed_line is not None and
                    hasattr(completion_type, 'matches_fancy_prefix')
                ):
                    if completion_type.matches_fancy_prefix(
                        fancy_prefixed_line
                    ):
                        prefix = fancy_prefix
                    elif completion_type.matches_line(line):
                        remove_regions = []
                elif completion_type.matches_line(line):
                    remove_regions = []

        # we only check if the completion type is enabled if we're also
        # inserting a comma or bracket; otherwise, it must've been a keypress
        if insert_char and not completion_type.is_enabled():
            self.complete_brackets(view, edit, insert_char)
            return

        # we are not adding a bracket or comma, we do not have a fancy prefix
        # and the overwrite and force options were not set, so calculate the
        # prefix as the previous word
        if insert_char == '' and not prefix and not overwrite and not force:
            prefix = self.get_common_prefix(view, view.sel())

        # reset the _ completions if we are not using them
        if (
            insert_char and
            "fancy_prefix" in locals() and
            prefix != fancy_prefix
        ):
            remove_regions = []
            prefix = ''

        try:
            completions = completion_type.get_completions(
                view, prefix, line[::-1]
            )
        except:
            self.complete_brackets(
                view, edit, insert_char, remove_regions=remove_regions
            )
            reraise(*sys.exc_info())

        if completions is None:
            self.complete_brackets(
                view, edit, insert_char, remove_regions=remove_regions
            )
            return
        elif type(completions) is tuple:
            formatted_completions, completions = completions
        else:
            formatted_completions = completions

        if len(completions) == 0:
            self.complete_brackets(
                view, edit, insert_char, remove_regions=remove_regions
            )
        elif len(completions) == 1:
            # if there is only one completion and it already matches the
            # current text
            if force:
                view.insert(edit, completions[0])
                return
            else:
                if completions[0] == prefix:
                    return

                if insert_char:
                    insert_text = (
                        insert_char + completions[0]
                        if completions[0] else insert_char
                    )
                    self.insert_at_end(view, edit, insert_text)
                elif completions[0]:
                    self.replace_word(view, edit, completions[0])

                self.complete_auto_match(view, edit, insert_char)
                self.remove_regions(view, edit, remove_regions)
            self.clear_bracket_cache()
        else:
            def on_done(i):
                if i < 0:
                    view.run_command(
                        'latex_tools_fill_all_complete_bracket',
                        {
                            'insert_char': insert_char,
                            'remove_regions':
                                self.regions_to_tuples(remove_regions)
                        }
                    )
                    return

                if force:
                    view.run_command(
                        'insert',
                        {
                            'characters': completions[i]
                        }
                    )
                else:
                    view.run_command(
                        'latex_tools_replace_word',
                        {
                            'insert_char': insert_char,
                            'replacement': completions[i],
                            'remove_regions':
                                self.regions_to_tuples(remove_regions)
                        }
                    )

            view.window().show_quick_panel(formatted_completions, on_done)
            self.clear_bracket_cache()
コード例 #23
0
    def on_query_completions(self, view, prefix, locations):
        for location in locations:
            if not view.score_selector(location, "text.tex.latex"):
                return

        completion_types = self.get_completion_types()

        orig_prefix = prefix

        # tracks any regions to be removed
        fancy_prefix, remove_regions = self.get_common_fancy_prefix(
            view, locations
        )
        # although a prefix is passed in, our redefinition of "word" boundaries
        # mean we should recalculate this
        prefix = self.get_common_prefix(view, locations)

        fancy_prefixed_line = None
        if remove_regions:
            if remove_regions:
                fancy_prefixed_line = view.substr(
                    getRegion(view.line(locations[0]).begin(), locations[0])
                )[::-1]

        line = view.substr(
            getRegion(view.line(locations[0]).begin(), locations[0])
        )[::-1]

        completion_type = None
        for name in completion_types:
            ct = self.get_completion_type(name)
            if (
                fancy_prefixed_line is not None and
                hasattr(ct, 'matches_fancy_prefix')
            ):
                if ct.matches_fancy_prefix(fancy_prefixed_line):
                    line = fancy_prefixed_line
                    prefix = fancy_prefix
                    completion_type = ct
                    break
                elif ct.matches_line(line):
                    completion_type = ct
                    remove_regions = []
                    break
            elif ct.matches_line(line):
                completion_type = ct
                # reset fancy prefix
                remove_regions = []
                break

        if completion_type is None:
            self.clear_bracket_cache()
            return []
        elif not self.score_selector(
                view, completion_type.get_supported_scope_selector()):
            self.clear_bracket_cache()
            return []
        # completions could be unpredictable if we've changed the prefix
        elif orig_prefix and not prefix:
            self.clear_bracket_cache()
            return []

        try:
            completions = completion_type.get_auto_completions(
                view, prefix, line[::-1]
            )
        except:
            traceback.print_exc()
            self.clear_bracket_cache()
            return []

        if len(completions) == 0:
            self.clear_bracket_cache()
            return []
        elif type(completions) is tuple and len(completions) == 2:
            completions, insert_char = completions
            if len(completions) == 0:
                self.clear_bracket_cache()
                return []
        else:
            # this assumes that all regions have a similar current word
            # not ideal, but reasonably safe see:
            # http://docs.sublimetext.info/en/latest/extensibility/completions.html#completions-with-multiple-cursors
            insert_char = view.substr(
                self.get_current_word(view, locations[0])
            )

        # we found a _<prefix> entry, so clear it and remove the prefix
        # and close the brackets
        if remove_regions:
            view.run_command(
                'latex_tools_fill_all_complete_bracket',
                {
                    'insert_char': insert_char,
                    'remove_regions': self.regions_to_tuples(remove_regions)
                }
            )

        if type(completions[0]) is tuple:
            show, completions = zip(*completions)
        else:
            show = completions[:]

        # we did not find a fancy prefix, so append the closing bracket,
        # if needed, to the completions
        if not remove_regions:
            closing_bracket = None
            for sel in view.sel():
                new_bracket = self.get_closing_bracket(view, sel)
                if closing_bracket is None:
                    closing_bracket = new_bracket
                elif new_bracket != closing_bracket:
                    closing_bracket = None
                    break

            if closing_bracket:
                completions = [
                    c + closing_bracket
                    for c in completions
                ]

        self.clear_bracket_cache()

        return (
            zip(show, completions),
            sublime.INHIBIT_WORD_COMPLETIONS |
            sublime.INHIBIT_EXPLICIT_COMPLETIONS
        )
コード例 #24
0
    def get_closing_bracket(self, view, sel):
        '''
        Determines if the nearest bracket that occurs before the given
        selection is closed. If the bracket should be closed, returns the
        closing bracket to use.

        Note that this will not work if the arguments to the command span
        multiple lines, but we generally don't support that anyway.

        :param view:
            the current view

        :param sel:
            a sublime.Region indicating the selected area
        '''
        # candidates stores matched bracket-pairs so that we only have
        # to find all matches once per bracket type
        # if the view has changed, we reset the candidates
        candidates = None

        if not hasattr(self, 'last_view') or self.last_view != view.id():
            self.last_view = view.id()
            self.use_full_scan = get_setting(
                'smart_bracket_scan_full_document', False)
            candidates = self.candidates = {}

        if not self.use_full_scan:
            # always clear the candidates when not using a full scan
            candidates = {}
            # when not using a full scan, get the number of lines to
            # look-behind
            try:
                look_around = int(get_setting('smart_bracket_look_around', 5))
            except ValueError:
                look_around = 5

        if candidates is None:
            try:
                candidates = self.candidates
            except:
                candidates = self.candidates = {}

        # first, find the nearest bracket
        if type(sel) is sublime.Region:
            start, end = sel.begin(), sel.end()
        else:
            start = end = sel

        if self.use_full_scan:
            prefix = view.substr(getRegion(0, start))
            prefix_start = 0
            suffix_end = view.size()
        else:
            prefix_lines = view.lines(getRegion(0, start))
            if len(prefix_lines) >= look_around:
                prefix_start = prefix_lines[-look_around].begin()
            else:
                prefix_start = prefix_lines[0].begin()

            suffix_lines = view.lines(getRegion(end, view.size()))
            if len(suffix_lines) >= look_around:
                suffix_end = suffix_lines[look_around - 1].end()
            else:
                suffix_end = suffix_lines[-1].end()

            prefix = view.substr(getRegion(prefix_start, start))

        open_bracket, last_index = None, -1
        for char in self.MATCH_CHARS:
            index = prefix.rfind(char)
            if index > last_index:
                open_bracket, last_index = char, index

        if last_index == -1:
            # can't determine bracket to match
            return None

        close_bracket = self.MATCH_CHARS[open_bracket]
        open_brackets = []
        # this is used to throw-away as many matches as possible
        # so subsequent requests don't need to consider every match
        closed_brackets = []

        if open_bracket not in candidates:
            # find all open / close brackets in the current buffer,
            # removing all comments
            candidates[open_bracket] = results = []

            start = prefix_start
            re_str = re.escape(open_bracket) + '|' + re.escape(close_bracket)
            while True:
                if start >= suffix_end:
                    break

                c = view.find(re_str, start)
                if c is None or c.begin() == -1:
                    break

                if c.end() > suffix_end:
                    break

                if view.score_selector(c.begin(), 'comment') != 0:
                    start = c.end()
                    continue

                results.append(c)

                start = c.end()

        for candidate in candidates[open_bracket]:
            if view.substr(candidate) == open_bracket:
                if len(open_brackets) == 0 and candidate.begin() > end:
                    break

                open_brackets.append(candidate)
            else:
                try:
                    removed = open_brackets.pop()
                    if candidate.end() < start:
                        closed_brackets.append(removed)
                        closed_brackets.append(candidate)
                except IndexError:
                    # unbalanced close before open
                    if candidate.end() > end:
                        break

        if len(closed_brackets) > 0:
            candidates[open_bracket] = [
                c for c in candidates[open_bracket]
                if c not in closed_brackets
            ]

        # if we have an open bracket left, then the current bracket needs to
        # be closed
        return close_bracket if len(open_brackets) > 0 else None
コード例 #25
0
    def get_closing_bracket(self, view, sel):
        '''
        Determines if the nearest bracket that occurs before the given
        selection is closed. If the bracket should be closed, returns the
        closing bracket to use.

        Note that this will not work if the arguments to the command span
        multiple lines, but we generally don't support that anyway.

        :param view:
            the current view

        :param sel:
            a sublime.Region indicating the selected area
        '''
        # candidates stores matched bracket-pairs so that we only have
        # to find all matches once per bracket type
        # if the view has changed, we reset the candidates
        candidates = None
        if hasattr(self, 'last_view') and self.last_view != view.id():
            self.last_view = view.id()
            candidates = self.candidates = {}

        if candidates is None:
            try:
                candidates = self.candidates
            except:
                candidates = self.candidates = {}

        # first, find the nearest bracket
        if type(sel) is sublime.Region:
            start, end = sel.begin(), sel.end()
        else:
            start = end = sel

        prefix = view.substr(getRegion(0, start))

        open_bracket, last_index = None, -1
        for char in self.MATCH_CHARS:
            index = prefix.rfind(char)
            if index > last_index:
                open_bracket, last_index = char, index

        if last_index == -1:
            # can't determine bracket to match
            return None

        close_bracket = self.MATCH_CHARS[open_bracket]
        open_brackets = []
        # this is used to throw-away as many matches as possible
        # so subsequent requests don't need to consider every match
        closed_brackets = []

        if open_bracket not in candidates:
            # find all open / close brackets in the current buffer,
            # removing all comments
            candidates[open_bracket] = [
                c for c in view.find_all(
                    re.escape(open_bracket) + '|' + re.escape(close_bracket))
                if view.score_selector(c.begin(), 'comment') == 0
            ]

        for candidate in candidates[open_bracket]:
            if view.substr(candidate) == open_bracket:
                if candidate.begin() > end:
                    break

                open_brackets.append(candidate)
            else:
                try:
                    removed = open_brackets.pop()
                    if candidate.end() < start:
                        closed_brackets.append(removed)
                        closed_brackets.append(candidate)
                except IndexError:
                    # unbalanced close before open
                    if candidate.end() > end:
                        break

        if len(closed_brackets) > 0:
            candidates[open_bracket] = [
                c for c in candidates[open_bracket] if c not in closed_brackets
            ]

        # if we have an open bracket left, then the current bracket needs to
        # be closed
        return close_bracket if len(open_brackets) > 0 else None
コード例 #26
0
    def on_query_completions(self, view, prefix, locations):
        if not is_cwl_available():
            return []

        point = locations[0]
        if not view.score_selector(point, "text.tex.latex"):
            return []

        point_before = point - len(prefix)
        char_before = view.substr(getRegion(point_before - 1, point_before))
        is_prefixed = char_before == "\\"

        line = view.substr(getRegion(view.line(point).begin(), point))
        line = line[::-1]
        is_env = bool(BEGIN_END_BEFORE_REGEX.match(line))

        # default completion level is "prefixed"
        completion_level = get_setting("command_completion", "prefixed")

        do_complete = {
            "never": False,
            "prefixed": is_prefixed or is_env,
            "always": True
        }.get(completion_level, is_prefixed or is_env)

        if not do_complete:
            return []

        # do not autocomplete if the leading backslash is escaped
        if ESCAPE_REGEX.match(line):
            # if there the autocompletion has been opened with the \ trigger
            # (no prefix) and the user has not enabled auto completion for the
            # scope, then hide the auto complete popup
            selector = view.settings().get("auto_complete_selector")
            if not prefix and not view.score_selector(point, selector):
                view.run_command("hide_auto_complete")
            return []

        # Do not do completions in actions
        if (latex_input_completions.TEX_INPUT_FILE_REGEX
                not in ENV_DONOT_AUTO_COM):
            ENV_DONOT_AUTO_COM.append(
                latex_input_completions.TEX_INPUT_FILE_REGEX)

        for rex in ENV_DONOT_AUTO_COM:
            if match(rex, line) is not None:
                return []

        # load the completions for the document
        if is_env:
            completions = CWL_COMPLETIONS.get_completions(env=True) + \
                get_own_env_completion(view)
        else:
            completions = CWL_COMPLETIONS.get_completions() + \
                get_own_command_completion(view)

        # autocompleting with slash already on line
        # this is necessary to work around a short-coming in ST where having a
        # keyed entry appears to interfere with it recognising that there is a
        # \ already on the line
        #
        # NB this may not work if there are other punctuation marks in the
        # completion
        if is_prefixed:
            completions = [(c[0], c[1][1:]) if c[1].startswith("\\") else c
                           for c in completions]

        return (completions, sublime.INHIBIT_WORD_COMPLETIONS
                | sublime.INHIBIT_EXPLICIT_COMPLETIONS)
コード例 #27
0
    def on_query_completions(self, view, prefix, locations):
        for location in locations:
            if not view.score_selector(location, "text.tex.latex"):
                return

        completion_types = self.get_completion_types()

        orig_prefix = prefix

        # tracks any regions to be removed
        fancy_prefix, remove_regions = self.get_common_fancy_prefix(
            view, locations)
        # although a prefix is passed in, our redefinition of "word" boundaries
        # mean we should recalculate this
        prefix = self.get_common_prefix(view, locations)

        fancy_prefixed_line = None
        if remove_regions:
            if remove_regions:
                fancy_prefixed_line = view.substr(
                    getRegion(view.line(locations[0]).begin(),
                              locations[0]))[::-1]

        line = view.substr(
            getRegion(view.line(locations[0]).begin(), locations[0]))[::-1]

        completion_type = None
        for name in completion_types:
            ct = self.get_completion_type(name)
            if (fancy_prefixed_line is not None
                    and hasattr(ct, 'matches_fancy_prefix')):
                if ct.matches_fancy_prefix(fancy_prefixed_line):
                    line = fancy_prefixed_line
                    prefix = fancy_prefix
                    completion_type = ct
                    break
                elif ct.matches_line(line):
                    completion_type = ct
                    remove_regions = []
                    break
            elif ct.matches_line(line):
                completion_type = ct
                # reset fancy prefix
                remove_regions = []
                break

        if completion_type is None:
            self.clear_bracket_cache()
            return []
        elif not self.score_selector(
                view, completion_type.get_supported_scope_selector()):
            self.clear_bracket_cache()
            return []
        # completions could be unpredictable if we've changed the prefix
        elif orig_prefix and not prefix:
            self.clear_bracket_cache()
            return []

        try:
            completions = completion_type.get_auto_completions(
                view, prefix, line[::-1])
        except:
            traceback.print_exc()
            self.clear_bracket_cache()
            return []

        if len(completions) == 0:
            self.clear_bracket_cache()
            return []
        elif type(completions) is tuple and len(completions) == 2:
            completions, insert_char = completions
            if len(completions) == 0:
                self.clear_bracket_cache()
                return []
        else:
            # this assumes that all regions have a similar current word
            # not ideal, but reasonably safe see:
            # http://docs.sublimetext.info/en/latest/extensibility/completions.html#completions-with-multiple-cursors
            insert_char = view.substr(self.get_current_word(
                view, locations[0]))

        # we found a _<prefix> entry, so clear it and remove the prefix
        # and close the brackets
        if remove_regions:
            view.run_command(
                'latex_tools_fill_all_complete_bracket', {
                    'insert_char': insert_char,
                    'remove_regions': self.regions_to_tuples(remove_regions)
                })

        if type(completions[0]) is tuple:
            show, completions = zip(*completions)
        else:
            show = completions[:]

        # we did not find a fancy prefix, so append the closing bracket,
        # if needed, to the completions
        if not remove_regions:
            closing_bracket = None
            for sel in view.sel():
                new_bracket = self.get_closing_bracket(view, sel)
                if closing_bracket is None:
                    closing_bracket = new_bracket
                elif new_bracket != closing_bracket:
                    closing_bracket = None
                    break

            if closing_bracket:
                completions = [c + closing_bracket for c in completions]

        self.clear_bracket_cache()

        return (zip(show, completions), sublime.INHIBIT_WORD_COMPLETIONS
                | sublime.INHIBIT_EXPLICIT_COMPLETIONS)
コード例 #28
0
    def run(self,
            edit,
            completion_type=None,
            insert_char="",
            overwrite=False,
            force=False):
        view = self.view

        for sel in view.sel():
            point = sel.b
            if not view.score_selector(point, "text.tex.latex"):
                self.complete_brackets(view, edit, insert_char)
                return

        # if completion_type is a simple string, try to load it
        if isinstance(completion_type, strbase):
            completion_type = self.get_completion_type(completion_type)
            if completion_type is None:
                if not force:
                    self.complete_brackets(view, edit, insert_char)
                return
        elif force:
            print('Cannot set `force` if completion type is not specified')
            return

        if force:
            insert_char = ''
            overwrite = False

        # tracks any regions to be removed
        remove_regions = []
        prefix = ''

        # handle the _ prefix, if necessary
        if (not isinstance(completion_type, FillAllHelper)
                or hasattr(completion_type, 'matches_fancy_prefix')):
            fancy_prefix, remove_regions = self.get_common_fancy_prefix(
                view, view.sel())

        # if we found a _ prefix, we use the raw line, so \ref_eq
        fancy_prefixed_line = None
        if remove_regions:
            fancy_prefixed_line = view.substr(
                getRegion(view.line(point).begin(), point))[::-1]

        # normal line calculation
        line = (view.substr(getRegion(view.line(point).begin(), point)) +
                insert_char)[::-1]

        # handle a list of completion types
        if type(completion_type) is list:
            for name in completion_type:
                try:
                    ct = self.get_completion_type(name)
                    if (fancy_prefixed_line is not None
                            and hasattr(ct, 'matches_fancy_prefix')):
                        if ct.matches_fancy_prefix(fancy_prefixed_line):
                            completion_type = ct
                            prefix = fancy_prefix
                            break
                        elif ct.matches_line(line):
                            completion_type = ct
                            remove_regions = []
                            break
                    elif ct.matches_line(line):
                        completion_type = ct
                        remove_regions = []
                        break
                except:
                    pass

            if type(completion_type) is list:
                message = "No valid completions found"
                print(message)
                sublime.status_message(message)
                self.complete_brackets(view, edit, insert_char)
                return
        # unknown completion type
        elif (completion_type is None
              or not isinstance(completion_type, FillAllHelper)):
            for name in self.get_completion_types():
                ct = self.get_completion_type(name)
                if ct is None:
                    continue

                if (fancy_prefixed_line is not None
                        and hasattr(ct, 'matches_fancy_prefix')):
                    if ct.matches_fancy_prefix(fancy_prefixed_line):
                        completion_type = ct
                        prefix = fancy_prefix
                        break
                    elif ct.matches_line(line):
                        completion_type = ct
                        remove_regions = []
                        break
                elif ct.matches_line(line):
                    completion_type = ct
                    remove_regions = []
                    break

            if (completion_type is None
                    or isinstance(completion_type, strbase)):
                message = \
                    'Cannot determine completion type for current selection'
                print(message)
                sublime.status_message(message)

                self.complete_brackets(view, edit, insert_char)
                return
        # assume only a single completion type to use
        else:
            # if force is set, we do no matching
            if not force:
                if (fancy_prefixed_line is not None
                        and hasattr(completion_type, 'matches_fancy_prefix')):
                    if completion_type.matches_fancy_prefix(
                            fancy_prefixed_line):
                        prefix = fancy_prefix
                    elif completion_type.matches_line(line):
                        remove_regions = []
                elif completion_type.matches_line(line):
                    remove_regions = []

        # we only check if the completion type is enabled if we're also
        # inserting a comma or bracket; otherwise, it must've been a keypress
        if insert_char and not completion_type.is_enabled():
            self.complete_brackets(view, edit, insert_char)
            return

        # we are not adding a bracket or comma, we do not have a fancy prefix
        # and the overwrite and force options were not set, so calculate the
        # prefix as the previous word
        if insert_char == '' and not prefix and not overwrite and not force:
            prefix = self.get_common_prefix(view, view.sel())

        # reset the _ completions if we are not using them
        if (insert_char and "fancy_prefix" in locals()
                and prefix != fancy_prefix):
            remove_regions = []
            prefix = ''

        try:
            completions = completion_type.get_completions(
                view, prefix, line[::-1])
        except:
            self.complete_brackets(view,
                                   edit,
                                   insert_char,
                                   remove_regions=remove_regions)
            reraise(*sys.exc_info())

        if completions is None:
            self.complete_brackets(view,
                                   edit,
                                   insert_char,
                                   remove_regions=remove_regions)
            return
        elif type(completions) is tuple:
            formatted_completions, completions = completions
        else:
            formatted_completions = completions

        if len(completions) == 0:
            self.complete_brackets(view,
                                   edit,
                                   insert_char,
                                   remove_regions=remove_regions)
        elif len(completions) == 1:
            # if there is only one completion and it already matches the
            # current text
            if force:
                view.insert(edit, completions[0])
                return
            else:
                if completions[0] == prefix:
                    return

                if insert_char:
                    insert_text = (insert_char + completions[0]
                                   if completions[0] else insert_char)
                    self.insert_at_end(view, edit, insert_text)
                elif completions[0]:
                    self.replace_word(view, edit, completions[0])

                self.complete_auto_match(view, edit, insert_char)
                self.remove_regions(view, edit, remove_regions)
            self.clear_bracket_cache()
        else:

            def on_done(i):
                if i < 0:
                    view.run_command(
                        'latex_tools_fill_all_complete_bracket', {
                            'insert_char':
                            insert_char,
                            'remove_regions':
                            self.regions_to_tuples(remove_regions)
                        })
                    return

                if force:
                    view.run_command('insert', {'characters': completions[i]})
                else:
                    view.run_command(
                        'latex_tools_replace_word', {
                            'insert_char':
                            insert_char,
                            'replacement':
                            completions[i],
                            'remove_regions':
                            self.regions_to_tuples(remove_regions)
                        })

            view.window().show_quick_panel(formatted_completions, on_done)
            self.clear_bracket_cache()
コード例 #29
0
    def complete_auto_match(self, view, edit, insert_char):
        '''
        Completes brackets if auto_match is enabled; also implements the
        "smart_bracket_auto_trigger" logic, which tries to complete the nearest
        open bracket intelligently.

        :param view:
            the current view

        :param edit:
            the current edit

        :param insert_char:
            the character to try to automatch
        '''
        if sublime.load_settings('Preferences.sublime-settings').get(
            'auto_match_enabled', True
        ):
            # simple case: we have an insert char, insert closing char,
            # if its defined
            if insert_char:
                self.insert_at_end(
                    view, edit, self.get_match_char(insert_char)
                )

                # if the insert_char is a bracket, move cursor to middle of
                # bracket and return
                if insert_char in self.MATCH_CHARS:
                    new_regions = []
                    for sel in view.sel():
                        if not sel.empty():
                            new_regions.append(sel)
                        else:
                            new_point = sel.end() - 1
                            new_regions.append(getRegion(new_point, new_point))

                    self.update_selections(view, new_regions)
                    return
            elif get_setting('smart_bracket_auto_trigger', True):
                # more complex: if we do not have an insert_char, try to close
                # the nearest bracket that occurs before each selection
                new_regions = []

                for sel in view.sel():
                    word_region = self.get_current_word(view, sel)
                    close_bracket = self.get_closing_bracket(view, word_region)
                    # we should close the bracket
                    if close_bracket:
                        # insert the closing bracket
                        view.insert(edit, word_region.end(), close_bracket)

                        if sel.empty():
                            if word_region.empty():
                                new_regions.append(
                                    getRegion(
                                        word_region.end(), word_region.end()
                                    )
                                )
                            else:
                                new_point = word_region.end() + \
                                    len(close_bracket)
                                new_regions.append(
                                    getRegion(new_point, new_point)
                                )
                        else:
                            new_regions.append(
                                getRegion(
                                    sel.begin(),
                                    word_region.end() + len(close_bracket)
                                )
                            )
                    else:
                        new_regions.append(sel)

                self.update_selections(view, new_regions)
コード例 #30
0
    def get_closing_bracket(self, view, sel):
        '''
        Determines if the nearest bracket that occurs before the given
        selection is closed. If the bracket should be closed, returns the
        closing bracket to use.

        Note that this will not work if the arguments to the command span
        multiple lines, but we generally don't support that anyway.

        :param view:
            the current view

        :param sel:
            a sublime.Region indicating the selected area
        '''
        # candidates stores matched bracket-pairs so that we only have
        # to find all matches once per bracket type
        # if the view has changed, we reset the candidates
        candidates = None
        if not hasattr(self, 'last_view') or self.last_view != view.id():
            self.last_view = view.id()
            candidates = self.candidates = {}

        if candidates is None:
            try:
                candidates = self.candidates
            except:
                candidates = self.candidates = {}

        # first, find the nearest bracket
        if type(sel) is sublime.Region:
            start, end = sel.begin(), sel.end()
        else:
            start = end = sel

        prefix = view.substr(getRegion(0, start))

        open_bracket, last_index = None, -1
        for char in self.MATCH_CHARS:
            index = prefix.rfind(char)
            if index > last_index:
                open_bracket, last_index = char, index

        if last_index == -1:
            # can't determine bracket to match
            return None

        close_bracket = self.MATCH_CHARS[open_bracket]
        open_brackets = []
        # this is used to throw-away as many matches as possible
        # so subsequent requests don't need to consider every match
        closed_brackets = []

        if open_bracket not in candidates:
            # find all open / close brackets in the current buffer,
            # removing all comments
            candidates[open_bracket] = [
                c for c in view.find_all(
                    re.escape(open_bracket) + '|' +
                    re.escape(close_bracket)
                )
                if view.score_selector(c.begin(), 'comment') == 0
            ]

        for candidate in candidates[open_bracket]:
            if view.substr(candidate) == open_bracket:
                if candidate.begin() > end:
                    break

                open_brackets.append(candidate)
            else:
                try:
                    removed = open_brackets.pop()
                    if candidate.end() < start:
                        closed_brackets.append(removed)
                        closed_brackets.append(candidate)
                except IndexError:
                    # unbalanced close before open
                    if candidate.end() > end:
                        break

        if len(closed_brackets) > 0:
            candidates[open_bracket] = [
                c for c in candidates[open_bracket]
                if c not in closed_brackets
            ]

        # if we have an open bracket left, then the current bracket needs to
        # be closed
        return close_bracket if len(open_brackets) > 0 else None
コード例 #31
0
    def on_query_completions(self, view, prefix, locations):
        if not is_cwl_available():
            return []

        point = locations[0]
        if not view.score_selector(point, "text.tex.latex"):
            return []

        point_before = point - len(prefix)
        char_before = view.substr(getRegion(point_before - 1, point_before))
        is_prefixed = char_before == "\\"

        line = view.substr(getRegion(view.line(point).begin(), point))
        line = line[::-1]
        is_env = bool(BEGIN_END_BEFORE_REGEX.match(line))

        # default completion level is "prefixed"
        completion_level = get_setting(
            "command_completion", "prefixed"
        )

        do_complete = {
            "never": False,
            "prefixed": is_prefixed or is_env,
            "always": True
        }.get(completion_level, is_prefixed or is_env)

        if not do_complete:
            return []

        # do not autocomplete if the leading backslash is escaped
        if ESCAPE_REGEX.match(line):
            # if there the autocompletion has been opened with the \ trigger
            # (no prefix) and the user has not enabled auto completion for the
            # scope, then hide the auto complete popup
            selector = view.settings().get("auto_complete_selector")
            if not prefix and not view.score_selector(point, selector):
                view.run_command("hide_auto_complete")
            return []

        # Do not do completions in actions
        if (
            latex_input_completions.TEX_INPUT_FILE_REGEX not in
            ENV_DONOT_AUTO_COM
        ):
            ENV_DONOT_AUTO_COM.append(
                latex_input_completions.TEX_INPUT_FILE_REGEX)

        for rex in ENV_DONOT_AUTO_COM:
            if match(rex, line) is not None:
                return []

        # load the completions for the document
        if is_env:
            completions = CWL_COMPLETIONS.get_completions(env=True) + \
                get_own_env_completion(view)
        else:
            completions = CWL_COMPLETIONS.get_completions() + \
                get_own_command_completion(view)

        # autocompleting with slash already on line
        # this is necessary to work around a short-coming in ST where having a
        # keyed entry appears to interfere with it recognising that there is a
        # \ already on the line
        #
        # NB this may not work if there are other punctuation marks in the
        # completion
        if is_prefixed:
            completions = [
                (c[0], c[1][1:]) if c[1].startswith("\\") else c
                for c in completions
            ]

        return (
            completions,
            sublime.INHIBIT_WORD_COMPLETIONS |
            sublime.INHIBIT_EXPLICIT_COMPLETIONS
        )
コード例 #32
0
# -*- encoding: utf-8-*-
from getRegion import getRegion

# 经度
lon = 116.65
# w纬度
lat = 40.13

#s省份、城市、乡镇
pro, city, xiangzhen = getRegion(lon, lat)
print pro, city, xiangzhen