コード例 #1
0
ファイル: transformers_visual.py プロジェクト: gak/Vintageous
    def run(self, edit, mode, current_iteration, total_iterations):
        def f(view, s):
            delta = 1
            if mode == MODE_VISUAL:
                delta = 1 if utils.is_region_reversed(view, s) else 2

            text_before_caret = view.substr(sublime.Region(view.line(s.b).a, s.b - delta))
            first_char_is_space = view.substr(s.b - delta).isspace() if (view.line(s.b).a == s.b - delta) else False

            if mode == MODE_NORMAL:
                if text_before_caret.isspace() or first_char_is_space:
                    pt = utils.previous_non_white_space_char(self.view, s.b - 1, white_space='\t ')
                    if view.line(pt).empty():
                        return sublime.Region(s.a , pt + 1)
                    elif view.word(pt).size() == 1:
                        return sublime.Region(pt + 1, pt + 1)

                    return sublime.Region(pt, pt)

                # At BOL.
                # XXX: Use a general function instead of spelling out the computation.
                elif view.line(s.b).a == s.b and not view.line(s.b - 1).empty():
                    return sublime.Region(s.b - 1, s.b - 1)

            elif mode == MODE_VISUAL:
                if utils.is_region_reversed(view, s):

                    if text_before_caret.isspace() or first_char_is_space:
                        pt = utils.previous_non_white_space_char(self.view, s.b - delta, white_space='\t ')
                        # PREVIOUSLINE empty; don't go past it.
                        if view.line(pt).empty():
                            return sublime.Region(s.a , pt + 1)
                        return sublime.Region(s.a, pt)

                    elif utils.is_at_bol(view, s) and not view.line(s.b - 1).empty():
                        # Single-character words are a special case; we don't want to skip over
                        # them.
                        if view.word(s.b - 1).size() > 1:
                            return sublime.Region(s.a, s.b - 1)

                else:
                    # Non-reversed region. Note that .b here is at NEXTCHAR, not CURRENTCHAR.
                    if text_before_caret.isspace() or first_char_is_space:
                        pt = utils.previous_non_white_space_char(self.view, s.b - delta, white_space='\t ')
                        if view.line(pt).empty():
                            return sublime.Region(s.a , pt + 1)
                        # XXX: I don't think this branch is necessary.
                        # On new WORD; make sure motion doesn't skip it.
                        elif view.substr(pt) not in ('\t \n'):
                            return sublime.Region(s.a, pt + 1)

                        return sublime.Region(s.a, pt)

                    # At WORDBEGIN or at any non-ALPHANUMERICCHAR.
                    elif (view.word(s.b - 1).a == s.b - 1) or not view.substr(s.b - 1).isalnum():
                        return sublime.Region(s.a, s.b - 1)

            return s

        regions_transformer(self.view, f)
コード例 #2
0
ファイル: motion_cmds.py プロジェクト: Web5design/Vintageous
    def run(self, edit, extend=False, character=None, mode=None, count=1):
        def f(view, s):
            line_text = view.substr(sublime.Region(view.line(s.b).a, s.b))
            offset = 0
            a, b = view.line(s.b).a, s.b
            final_offset = -1

            try:
                for i in range(count):
                    line_text = view.substr(sublime.Region(a, b))
                    match_in_line = line_text.rindex(character)

                    final_offset = match_in_line

                    b = view.line(s.a).a + final_offset
            except ValueError:
                pass

            if final_offset > -1:
                pt = view.line(s.b).a + final_offset

                state = VintageState(view)
                if state.mode == MODE_VISUAL or mode == _MODE_INTERNAL_NORMAL:
                    return sublime.Region(s.a, pt)

                return sublime.Region(pt, pt)

            return s

        regions_transformer(self.view, f)
コード例 #3
0
    def run(self, edit, mode=None, extend=False, count=None):
        def f(view, s):
            if mode == MODE_NORMAL:
                pt = self.col_to_pt(pt=s.b, nr=count)
                return sublime.Region(pt, pt)

            elif mode == MODE_VISUAL:
                pt = self.col_to_pt(pt=s.b - 1, nr=count)
                if s.a < s.b:
                    if pt < s.a:
                        return sublime.Region(s.a + 1, pt)
                    else:
                        return sublime.Region(s.a, pt + 1)
                else:
                    if pt > s.a:
                        return sublime.Region(s.a - 1, pt + 1)
                    else:
                        return sublime.Region(s.a, pt)

            elif mode == _MODE_INTERNAL_NORMAL:
                pt = self.col_to_pt(pt=s.b, nr=count)
                if s.a < s.b:
                    return sublime.Region(s.a, pt)
                else:
                    return sublime.Region(s.a + 1, pt)

            return s

        regions_transformer(self.view, f)
コード例 #4
0
ファイル: motion_cmds.py プロジェクト: Web5design/Vintageous
    def run(self, edit, count=None, extend=False, mode=None):
        def f(view, s):
            if mode == MODE_NORMAL:
                return sublime.Region(target, target)
            elif mode == _MODE_INTERNAL_NORMAL:
                if s.b >= target:
                    return sublime.Region(s.a + 1, target)
                return sublime.Region(s.a, target)
            elif mode == MODE_VISUAL:
                if s.b >= target:
                    new_target = utils.next_non_white_space_char(view, target)
                    return sublime.Region(s.a + 1, new_target)
                new_target = utils.next_non_white_space_char(view, target)
                return sublime.Region(s.a, new_target + 1)
            else:
                return s

        r = self.view.visible_region()
        row_a, _ = self.view.rowcol(r.a)
        row_b, _ = self.view.rowcol(r.b)
        row = ((row_a + row_b) / 2)

        target = self.view.text_point(row, 0)

        regions_transformer(self.view, f)
        self.view.show(target)
コード例 #5
0
ファイル: motion_cmds.py プロジェクト: Web5design/Vintageous
    def run(self, edit, mode=None, count=1, extend=False):
        def f(view, s):

            pattern = r'\b{0}\b'.format(query)
            flags = sublime.IGNORECASE

            if mode == _MODE_INTERNAL_NORMAL:
                match = view.find(pattern, view.word(s.end()).end(), flags)
            else:
                match = view.find(pattern, view.word(s).end(), flags)

            if match:
                if mode == _MODE_INTERNAL_NORMAL:
                    return sublime.Region(s.a, match.begin())
                elif state.mode == MODE_VISUAL:
                    return sublime.Region(s.a, match.begin())
                elif state.mode == MODE_NORMAL:
                    return sublime.Region(match.begin(), match.begin())
            return s

        state = VintageState(self.view)
        # TODO: make sure we swallow any leading white space.
        query = self.view.substr(self.view.word(self.view.sel()[0].end()))
        if query:
            state.last_buffer_search = query

        regions_transformer(self.view, f)
コード例 #6
0
ファイル: actions.py プロジェクト: ahnan4arch/Vintageous
    def run(self):
        # We define our own transformer here because we want to handle undo as a special case.
        # TODO: I don't know if it needs to be an special case in reality.
        def f(view, s):
            # Compensates the move issued below.
            if s.a < s.b :
                return sublime.Region(s.a + 1, s.a + 1)
            else:
                return sublime.Region(s.a, s.a)

        state = VintageState(self.view)
        for i in range(state.count):
            self.view.run_command('undo')

        if self.view.has_non_empty_selection_region():
            regions_transformer(self.view, f)
            # !! HACK !! /////////////////////////////////////////////////////////
            # This is a hack to work around an issue in Sublime Text:
            # When undoing in normal mode, Sublime Text seems to prime a move by chars
            # forward that has never been requested by the user or Vintageous.
            # As far as I can tell, Vintageous isn't at fault here, but it seems weird
            # to think that Sublime Text is wrong.
            self.view.run_command('move', {'by': 'characters', 'forward': False})
            # ////////////////////////////////////////////////////////////////////

        state.update_xpos()
        # Ensure that we wipe the count, if any.
        state.reset()
コード例 #7
0
ファイル: actions.py プロジェクト: ahnan4arch/Vintageous
    def run(self, edit, mode=None, character=None, extend=False):
        def f(view, s):
            if mode == MODE_VISUAL:
                if s.a <= s.b:
                    if address.b < s.b:
                        return sublime.Region(s.a + 1, address.b)
                    else:
                        return sublime.Region(s.a, address.b)
                else:
                    return sublime.Region(s.a + 1, address.b)
            elif mode == MODE_NORMAL:
                return address
            elif mode == _MODE_INTERNAL_NORMAL:
                return sublime.Region(s.a, address.b)

            return s

        state = VintageState(self.view)
        address = state.marks.get_as_encoded_address(character)

        if address is None:
            return

        if isinstance(address, str):
            if not address.startswith('<command'):
                self.view.window().open_file(address, sublime.ENCODED_POSITION)
            else:
                # We get a command in this form: <command _vi_double_quote>
                self.view.run_command(address.split(' ')[1][:-1])
            return

        # This is a motion in a composite command.
        regions_transformer(self.view, f)
コード例 #8
0
ファイル: actions.py プロジェクト: ahnan4arch/Vintageous
    def run(self, edit, mode=None):
        def f(view, s):
            if mode == _MODE_INTERNAL_NORMAL:
                full_current_line = view.full_line(s.b)
                target = full_current_line.b - 1
                full_next_line = view.full_line(full_current_line.b)
                two_lines = sublime.Region(full_current_line.a, full_next_line.b)

                # Text without \n.
                first_line_text = view.substr(view.line(full_current_line.a))
                next_line_text = view.substr(full_next_line)

                if len(next_line_text) > 1:
                    next_line_text = next_line_text.lstrip()

                sep = ''
                if first_line_text and not first_line_text.endswith(' '):
                    sep = ' '

                view.replace(edit, two_lines, first_line_text + sep + next_line_text)

                if first_line_text:
                    return sublime.Region(target, target)
                return s
            else:
                return s

        regions_transformer(self.view, f)
コード例 #9
0
    def run(self, edit, mode=None):
        def f(view, s):
            if mode == _MODE_INTERNAL_NORMAL:
                if view.line(s).empty():
                    return s
            elif mode == MODE_VISUAL:
                if view.line(s.b - 1).empty() and s.size() == 1:
                    return s

            state = VintageState(self.view)
            autoindent = state.settings.vi['autoindent']

            if mode == _MODE_INTERNAL_NORMAL:
                if not autoindent:
                    return self.view.line(s)
                else:
                    pt = utils.next_non_white_space_char(view, self.view.line(s).a)
                    return sublime.Region(pt, self.view.line(s).b)
            elif mode == MODE_VISUAL:
                if not autoindent:
                    return self.view.line(sublime.Region(s.a, s.b - 1))
                else:
                    pt = utils.next_non_white_space_char(view, self.view.line(s.a).a)
                    return sublime.Region(pt, self.view.line(s.b - 1).b)

        regions_transformer(self.view, f)
コード例 #10
0
ファイル: motion_cmds.py プロジェクト: Web5design/Vintageous
    def run(self, edit, count=None, extend=False, mode=None):
        def f(view, s):
            if mode == MODE_NORMAL:
                return sublime.Region(target, target)
            elif mode == _MODE_INTERNAL_NORMAL:
                if s.b >= target:
                    return sublime.Region(s.a + 1, target)
                return sublime.Region(s.a, target)
            elif mode == MODE_VISUAL:
                if s.b >= target:
                    new_target = utils.next_non_white_space_char(view, target)
                    return sublime.Region(s.a + 1, new_target)
                new_target = utils.next_non_white_space_char(view, target)
                return sublime.Region(s.a, new_target + 1)
            else:
                return s

        r = self.view.visible_region()
        row, _ = self.view.rowcol(r.b)
        row -= count + 1

        # XXXX: Subtract 1 so that Sublime Text won't attempt to scroll the line into view, which
        # would be quite annoying.
        target = self.view.text_point(row - 1, 0)

        regions_transformer(self.view, f)
        self.view.show(target)
コード例 #11
0
    def run(self, edit):
        def f(view, s):
            a = view.line(s.a).a
            b = view.line(s.b - 1).b
            return sublime.Region(a, b + 1)

        regions_transformer(self.view, f)
コード例 #12
0
    def run(self, edit, **kwargs):
        def f(view, s):
            # Consider 2d$. This command should delete two lines and this class helps with that.
            # In some cases, though, we can't possibly know whether .b is at SOMELINE HARDEOL
            # or at SOMELINE HARDBOL. For example, if .b is at CURRENTLINE HARDEOL and NEXTLINE is
            # shorter, 2d$ may cause the caret to land at NEXTLINE HARDEOL, which is the same
            # point as HARDBOL two lines down. In such case, we don't need to extend .b to
            # HARDEOL, but with the available data to this function, we can't know that.
            #
            # For now, we'll consider the example above as an exception and let Vintageous do the
            # wrong thing. It's more important that the command mentioned above works well when
            # the caret is in the middle of a line or at HARDBOL.
            state = VintageState(view)

            if state.mode == MODE_VISUAL:
                if s.a < s.b and not view.line(s.b - 1).empty():
                    hard_eol = self.view.full_line(s.b - 1).b
                    return sublime.Region(s.a, hard_eol)

            elif state.mode == MODE_NORMAL:
                pass

            return s

        regions_transformer(self.view, f)
コード例 #13
0
ファイル: motion_cmds.py プロジェクト: structAnkit/Vintageous
    def run(self, edit, mode=None, extend=False, exact_word=True):
        def f(view, s):

            if exact_word:
                pattern = r'\b{0}\b'.format(query)
            else:
                pattern = query

            flags = sublime.IGNORECASE

            if mode == _MODE_INTERNAL_NORMAL:
                match = reverse_search(view, pattern, 0, current_sel.a, flags)
            else:
                match = reverse_search(view, pattern, 0, current_sel.a, flags)

            if match:
                if mode == _MODE_INTERNAL_NORMAL:
                    return sublime.Region(s.b, match.begin())
                elif state.mode == MODE_VISUAL:
                    return sublime.Region(s.b, match.begin())
                elif state.mode == MODE_NORMAL:
                    return sublime.Region(match.begin(), match.begin())
            return s

        state = VintageState(self.view)
        # TODO: make sure we swallow any leading white space.
        query = self.view.substr(self.view.word(self.view.sel()[0].end()))
        if query:
            state.last_buffer_search = query

        current_sel = self.view.sel()[0]

        regions_transformer(self.view, f)
コード例 #14
0
    def run(self, edit, count=None, extend=False, mode=None):
        def f(view, s):
            if mode == _MODE_INTERNAL_NORMAL:
                x_limit = max(view.line(s.b).a, s.b - count)
                return sublime.Region(s.a, x_limit)

            elif mode == MODE_VISUAL:
                if s.a < s.b:
                    x_limit = max(view.line(s.b - 1).a + 1, s.b - count)
                    if view.line(s.a) == view.line(s.b - 1) and count >= s.size():
                        x_limit = max(view.line(s.b - 1).a, s.b - count - 1)
                        return sublime.Region(s.a + 1, x_limit)
                    return sublime.Region(s.a, x_limit)

                if s.a > s.b:
                    x_limit = max(view.line(s.b).a, s.b - count)
                    return sublime.Region(s.a, x_limit)

            elif mode == MODE_NORMAL:
                x_limit = max(view.line(s.b).a, s.b - count)
                return sublime.Region(x_limit, x_limit)

            # XXX: We should never reach this.
            return s

        regions_transformer(self.view, f)
コード例 #15
0
ファイル: motion_cmds.py プロジェクト: structAnkit/Vintageous
    def run(self, edit, mode=None, extend=False):
        def f(view, s):
            # TODO: must skip empty paragraphs.
            start = utils.previous_non_white_space_char(view, s.b - 1, white_space='\n \t')
            par_as_region = view.expand_by_class(start, sublime.CLASS_EMPTY_LINE)

            if mode == MODE_NORMAL:
                return sublime.Region(par_as_region.a, par_as_region.a)

            elif mode == MODE_VISUAL:
                return sublime.Region(s.a + 1, par_as_region.a)

            elif mode == _MODE_INTERNAL_NORMAL:
                return sublime.Region(s.a, par_as_region.a)

            elif mode == MODE_VISUAL_LINE:
                if s.a <= s.b:
                    if par_as_region.a < s.a:
                        return sublime.Region(view.full_line(s.a).b, par_as_region.a)
                    return sublime.Region(s.a, par_as_region.a + 1)
                else:
                    return sublime.Region(s.a, par_as_region.a)

            return s

        regions_transformer(self.view, f)
コード例 #16
0
ファイル: motion_cmds.py プロジェクト: structAnkit/Vintageous
    def run(self, edit, mode=None, extend=False):
        def f(view, s):
            # TODO: must skip empty paragraphs.
            start = utils.next_non_white_space_char(view, s.b, white_space='\n \t')
            par_as_region = view.expand_by_class(start, sublime.CLASS_EMPTY_LINE)

            if mode == MODE_NORMAL:
                return sublime.Region(min(par_as_region.b, view.size() - 1),
                                      min(par_as_region.b, view.size() - 1))

            elif mode == MODE_VISUAL:
                return sublime.Region(s.a, par_as_region.b + 1)

            elif mode == _MODE_INTERNAL_NORMAL:
                return sublime.Region(s.a, par_as_region.b - 1)

            elif mode == MODE_VISUAL_LINE:
                if s.a <= s.b:
                    return sublime.Region(s.a, par_as_region.b + 1)
                else:
                    if par_as_region.b > s.a:
                        return sublime.Region(view.line(s.a - 1).a, par_as_region.b + 1)
                    return sublime.Region(s.a, par_as_region.b)

            return s

        regions_transformer(self.view, f)
コード例 #17
0
ファイル: actions.py プロジェクト: bahtou/sublConfig
    def run(self, edit):
        def f(view, s):
            return sublime.Region(s.b, view.line(s.b).a)

        regions_transformer(self.view, f)

        self.view.run_command('left_delete')
コード例 #18
0
    def run(self, edit, mode=None, count=None):
        def f(view, s):
            if mode == MODE_NORMAL:
                if view.line(s.b).empty():
                    return s

                x_limit = min(view.line(s.b).b - 1, s.b + count, view.size())
                return sublime.Region(x_limit, x_limit)

            if mode == _MODE_INTERNAL_NORMAL:
                x_limit = min(view.line(s.b).b, s.b + count)
                x_limit = max(0, x_limit)
                return sublime.Region(s.a, x_limit)

            if mode in (MODE_VISUAL, MODE_VISUAL_BLOCK):
                if s.a < s.b:
                    x_limit = min(view.full_line(s.b - 1).b, s.b + count)
                    return sublime.Region(s.a, x_limit)

                if s.a > s.b:
                    x_limit = min(view.full_line(s.b).b - 1, s.b + count)
                    if view.substr(s.b) == '\n':
                        return s

                    if view.line(s.a) == view.line(s.b) and count >= s.size():
                        x_limit = min(view.full_line(s.b).b, s.b + count + 1)
                        return sublime.Region(s.a - 1, x_limit)

                    return sublime.Region(s.a, x_limit)

            return s

        regions_transformer(self.view, f)
コード例 #19
0
    def run(self, edit, search_string, mode=None, count=1, extend=False):
        def f(view, s):
            if mode == MODE_VISUAL:
                return sublime.Region(s.a, match.a + 1)

            elif mode == _MODE_INTERNAL_NORMAL:
                return sublime.Region(s.a, match.a)

            elif mode == MODE_NORMAL:
                return sublime.Region(match.a, match.a)

            return s

        # This happens when we attempt to repeat the search and there's no search term stored yet.
        if search_string is None:
            return

        # We want to start searching right after the current selection.
        current_sel = self.view.sel()[0]
        start = current_sel.b if not current_sel.empty() else current_sel.b + 1
        wrapped_end = self.view.size()

        # TODO: What should we do here? Case-sensitive or case-insensitive search? Configurable?
        # Search wrapping around the end of the buffer.
        match = find_wrapping(self.view, search_string, start, wrapped_end, flags=0, times=count)
        if not match:
            return

        regions_transformer(self.view, f)
        self.hilite(search_string)
コード例 #20
0
    def run(self, edit):
        def f(view, s):
            line = view.line(s.b)
            pt = utils.next_non_white_space_char(view, line.a)
            return sublime.Region(pt, pt)

        regions_transformer(self.view, f)
コード例 #21
0
    def run(self, edit, search_string, mode=None, count=1, extend=False):
        def f(view, s):
            # FIXME: Readjust carets if we searched for '\n'.
            if mode == MODE_VISUAL:
                return sublime.Region(s.end(), found.a)

            elif mode == _MODE_INTERNAL_NORMAL:
                return sublime.Region(s.end(), found.a)

            elif mode == MODE_NORMAL:
                return sublime.Region(found.a, found.a)

            return s

        # This happens when we attempt to repeat the search and there's no search term stored yet.
        if search_string is None:
            return

        # FIXME: What should we do here? Case-sensitive or case-insensitive search? Configurable?
        found = reverse_find_wrapping(
            self.view, term=search_string, start=0, end=self.view.sel()[0].b, flags=0, times=count
        )

        if not found:
            print("Vintageous: Pattern not found.")
            return

        regions_transformer(self.view, f)
        self.hilite(search_string)
コード例 #22
0
    def run(self, edit, forward=True, mode=None):
        def f(view, s):
            if mode != MODE_VISUAL_LINE:
                if s.end() - s.begin() == 1:
                    if forward:
                        if s.b < s.a:
                            return sublime.Region(s.b, s.a)
                        else:
                            return s
                    else:
                        if s.b > s.a:
                            return sublime.Region(s.b, s.a)
                        else:
                            return s
                else:
                    return s

            else:
                if forward:
                    if self.view.full_line(s.b).a == s.b and self.view.full_line(s.b).b == s.a:
                        return sublime.Region(s.b, s.a)
                    else:
                        return s
                elif self.view.full_line(s.b - 1).a == s.a and self.view.full_line(s.b - 1).b == s.b:
                    r = sublime.Region(self.view.full_line(s.a).b, s.a)
                    return r
                else:
                    return s

        regions_transformer(self.view, f)
コード例 #23
0
ファイル: motion_cmds.py プロジェクト: structAnkit/Vintageous
    def run(self, edit, mode=None, extend=False, globally=False):

        def f(view, s):
            if mode == MODE_NORMAL:
                return sublime.Region(location, location)

            elif mode == MODE_VISUAL:
                return sublime.Region(s.a + 1, location)

            elif mode == _MODE_INTERNAL_NORMAL:
                return sublime.Region(s.a, location)

            return s

        current_sel = self.view.sel()[0]
        self.view.sel().clear()
        self.view.sel().add(current_sel)

        location = self.find_symbol(current_sel, globally=globally)
        if not location:
            return

        if globally:
            # Global symbol; simply open the file; not a motion.
            # TODO: Perhaps must be a motion if the target file happens to be the current one?
            self.view.window().open_file(location[0] + ':' + ':'.join([str(x) for x in location[2]]), sublime.ENCODED_POSITION)
            return

        # Local symbol; select.
        location = self.view.text_point(*location)
        regions_transformer(self.view, f)
コード例 #24
0
    def run(self, edit, mode=None):
        def f(view, s):
            if mode == _MODE_INTERNAL_NORMAL:
                current_line = view.line(s.b)
                return sublime.Region(current_line.a, current_line.a)
            return s

        regions_transformer(self.view, f)
コード例 #25
0
    def run(self, edit, **kwargs):
        def f(view, s):
            if (s.a < s.b and self.view.full_line(s.b - 1).b == s.b):
                    return sublime.Region(s.a, s.b - 1)
            else:
                return s

        regions_transformer(self.view, f)
コード例 #26
0
    def run(self, edit, **kwargs):
        def f(view, s):
            if is_at_eol(self.view, s) and not self.view.line(s.b).empty():
                return back_one_char(s)
            else:
                return s

        regions_transformer(self.view, f)
コード例 #27
0
    def run(self, edit):
        def f(view, s):
            if not s.empty():
                return sublime.Region(s.begin(), s.begin())
            else:
                return s

        regions_transformer(self.view, f)
コード例 #28
0
    def run(self, edit, **kwargs):
        def f(view, s):
            if is_at_eol(self.view, s) and not self.view.line(s.b).empty():
                s = back_one_char(s)
            # s = next_non_white_space_char(self.view, s.b)
            return s

        regions_transformer(self.view, f)
コード例 #29
0
    def run(self, edit):
        def f(view, s):
            if not is_on_empty_line(self.view, s) and is_at_eol(self.view, s):
                return back_one_char(s)
            else:
                return s

        regions_transformer(self.view, f)
コード例 #30
0
    def run(self, edit, **kwargs):
        def f(view, s):
            if view.size() > 0 and is_at_eol(self.view, s):
                return forward_one_char(s)
            else:
                return s

        regions_transformer(self.view, f)
コード例 #31
0
    def run(self, edit):
        def f(view, s):
            if s.size() > 0:
                if view.full_line(s.b - 1).b == s.b:
                    return self.view.full_line(sublime.Region(s.a, s.b - 1))
                else:
                    return self.view.full_line(s)
            else:
                return self.view.full_line(s)

        regions_transformer(self.view, f)
コード例 #32
0
    def run(self, edit):
        def f(view, s):
            if not s.empty():
                if s.a < s.b:
                    return sublime.Region(s.b - 1, s.b - 1)
                else:
                    return sublime.Region(s.b, s.b)
            else:
                return s

        regions_transformer(self.view, f)
コード例 #33
0
ファイル: motion_cmds.py プロジェクト: typopl/Vintageous
    def run(self, edit, extend=False, percent=None, mode=None):
        if percent == None:

            def move_to_bracket(view, s):
                def find_bracket_location(pt):
                    bracket, brackets, bracket_pt = self.find_a_bracket(pt)
                    if not bracket:
                        return

                    if bracket == brackets[0]:
                        return self.find_balanced_closing_bracket(
                            bracket_pt + 1, brackets)
                    else:
                        return self.find_balanced_opening_bracket(
                            bracket_pt, brackets)

                if mode == MODE_VISUAL:
                    # TODO: Improve handling of s.a < s.b and s.a > s.b cases.
                    a = find_bracket_location(s.b - 1)
                    if a is not None:
                        a = a + 1 if a > s.b else a
                        if a == s.a:
                            a += 1
                        return sublime.Region(s.a, a)

                elif mode == MODE_NORMAL:
                    a = find_bracket_location(s.b)
                    if a is not None:
                        return sublime.Region(a, a)

                # TODO: According to Vim we must swallow brackets in this case.
                elif mode == _MODE_INTERNAL_NORMAL:
                    a = find_bracket_location(s.b)
                    if a is not None:
                        return sublime.Region(s.a, a)

                return s

            regions_transformer(self.view, move_to_bracket)

            return

        row = self.view.rowcol(self.view.size())[0] * (percent / 100)

        def f(view, s):
            pt = view.text_point(row, 0)
            return sublime.Region(pt, pt)

        regions_transformer(self.view, f)

        # FIXME: Bringing the selections into view will be undesirable in many cases. Maybe we
        # should have an optional .scroll_selections_into_view() step during command execution.
        self.view.show(self.view.sel()[0])
コード例 #34
0
    def run(self, edit, mode=None):
        def f(view, s):
            if mode == _MODE_INTERNAL_NORMAL:
                if view.line(s).empty():
                    return s
            elif mode == MODE_VISUAL:
                if view.line(s.b - 1).empty():
                    return s

            return sublime.Region(s.a, self.view.line(s).b)

        regions_transformer(self.view, f)
コード例 #35
0
    def run(self, edit, mode=None):
        def f(view, s):
            if mode == _MODE_INTERNAL_NORMAL:
                if view.substr(s.b) != '\n':
                    return sublime.Region(s.a, view.line(s.b).b)
            elif mode == MODE_VISUAL:
                if view.substr(s.b) != '\n':
                    return sublime.Region(s.a, view.line(s.b).b)

            return s

        regions_transformer(self.view, f)
コード例 #36
0
ファイル: action_cmds.py プロジェクト: typopl/Vintageous
    def run(self, edit, mode=None):
        def f(view, s):
            if mode == _MODE_INTERNAL_NORMAL:
                line = view.line(s.b)
                if view.substr(line).isupper():
                    view.replace(edit, line, view.substr(line).lower())
                else:
                    view.replace(edit, line, view.substr(line).upper())
                return line
            return s

        regions_transformer(self.view, f)
コード例 #37
0
ファイル: actions.py プロジェクト: DylanBruzenak/Vintageous
    def run(self, edit, character=None, mode=None):
        def f(view, s):
            next_row = view.rowcol(s.b - 1)[0] + 1
            pt = view.text_point(next_row, 0)
            return sublime.Region(pt, pt)

        if mode == _MODE_INTERNAL_NORMAL:
            for s in self.view.sel():
                self.view.replace(edit, s, character * s.size())

        if character == '\n':
            regions_transformer(self.view, f)
コード例 #38
0
ファイル: actions.py プロジェクト: escherpf/Vintageous
    def run(self, edit, mode=None):
        def f(view, s):
            # We've made a selection with _vi_big_s_motion just before this.
            if mode == _MODE_INTERNAL_NORMAL:
                pt = utils.next_non_white_space_char(view,
                                                     s.a,
                                                     white_space=' \t')
                view.erase(edit, sublime.Region(pt, view.line(s.b).b))
                return sublime.Region(pt, pt)
            return s

        regions_transformer(self.view, f)
コード例 #39
0
    def run(self, edit, count=None, mode=None):
        def f(view, s):
            if mode == _MODE_INTERNAL_NORMAL:
                x_limit = max(view.line(s.b).a, s.b - count)
                return sublime.Region(s.a, x_limit)

            # TODO: Split handling of the two modes for clarity.
            elif mode in (MODE_VISUAL, MODE_VISUAL_BLOCK):

                if s.a < s.b:
                    if mode == MODE_VISUAL_BLOCK and self.view.rowcol(
                            s.b - 1)[1] == baseline:
                        return s

                    x_limit = max(view.line(s.b - 1).a + 1, s.b - count)
                    if view.line(
                            s.a) == view.line(s.b - 1) and count >= s.size():
                        x_limit = max(view.line(s.b - 1).a, s.b - count - 1)
                        return sublime.Region(s.a + 1, x_limit)
                    return sublime.Region(s.a, x_limit)

                if s.a > s.b:
                    x_limit = max(view.line(s.b).a, s.b - count)
                    return sublime.Region(s.a, x_limit)

            elif mode == MODE_NORMAL:
                x_limit = max(view.line(s.b).a, s.b - count)
                return sublime.Region(x_limit, x_limit)

            # XXX: We should never reach this.
            return s

        # For jagged selections (on the rhs), only those sticking out need to move leftwards.
        # Example ([] denotes the selection):
        #
        #   10 foo bar foo [bar]
        #   11 foo bar foo [bar foo bar]
        #   12 foo bar foo [bar foo]
        #
        #  Only lines 11 and 12 should move when we press h.
        baseline = 0
        if mode == MODE_VISUAL_BLOCK:
            sel = self.view.sel()[0]
            if sel.a < sel.b:
                min_ = min(
                    self.view.rowcol(r.b - 1)[1] for r in self.view.sel())
                if any(
                        self.view.rowcol(r.b - 1)[1] != min_
                        for r in self.view.sel()):
                    baseline = min_

        regions_transformer(self.view, f)
コード例 #40
0
    def run(self,
            edit,
            mode=None,
            current_iteration=None,
            total_iterations=None):
        def f(view, s):
            if mode == _MODE_INTERNAL_NORMAL:
                if view.substr(s.b) == '\n':
                    return sublime.Region(s.b + 1, s.b + 1)

            return s

        regions_transformer(self.view, f)
コード例 #41
0
    def run(self,
            edit,
            mode=None,
            current_iteration=None,
            total_iterations=None):
        def f(view, s):
            if view.substr(s.b - 1) == '\n':
                # FIXME: Actually, we should go back to the first \n; we may have run over
                # multiple ones.
                return sublime.Region(s.a, s.b - 1)
            return s

        regions_transformer(self.view, f)
コード例 #42
0
    def run(self, edit, mode=None):
        def f(view, s):
            if mode == MODE_VISUAL:
                if s.a < s.b:
                    a = view.line(s.a).a
                    b = view.full_line(s.b - 1).b
                else:
                    a = view.full_line(s.a - 1).b
                    b = view.full_line(s.b).a
                return sublime.Region(a, b)
            return s

        regions_transformer(self.view, f)
コード例 #43
0
ファイル: test_constants.py プロジェクト: typopl/Vintageous
    def testCanTransformRegions(self):
        TestsState.view.sel().clear()
        TestsState.view.sel().add(sublime.Region(0, 100))
        TestsState.view.sel().add(sublime.Region(200, 300))
        TestsState.view.sel().add(sublime.Region(400, 500))

        transf = lambda view, x: sublime.Region(x.a, x.b - (x.size() - 1))
        regions_transformer(TestsState.view, transf)

        regions = list(TestsState.view.sel())

        for r in regions:
            self.assertEqual(r.size(), 1)
コード例 #44
0
    def run(self, edit):
        def f(view, s):
            if s.a < s.b:
                # going forward
                if utils.is_at_hard_eol(self.view, s) and \
                   not utils.visual_is_on_empty_line_forward(self.view, s):
                    return utils.back_end_one_char(s)
                else:
                    return s
            else:
                # Moving down by lines.
                return s

        regions_transformer(self.view, f)
コード例 #45
0
    def run(self, edit):
        def f(view, s):
            # TODO: This will confuse users, but otherwise they will be even more confused, because
            # the caret will disappear until they press h, l, etc.
            # Alternatively, we could abort the mode change?
            if view.size() == 0:
                return s

            if s.empty():
                return sublime.Region(s.a, s.b + 1)
            else:
                return s

        regions_transformer(self.view, f)
コード例 #46
0
    def run(self, edit, mode=None):
        def f(view, s):
            if mode == MODE_VISUAL:
                line = view.line(s.b - 1)
                pt = utils.next_non_white_space_char(view, line.a)
                return sublime.Region(s.a, pt + 1)
            elif mode != MODE_VISUAL_LINE:
                line = view.line(s.b)
                pt = utils.next_non_white_space_char(view, line.a)
                return sublime.Region(pt, pt)

            return s

        regions_transformer(self.view, f)
コード例 #47
0
ファイル: motion_cmds.py プロジェクト: typopl/Vintageous
    def run(self, edit, extend=False, line=None):
        line = line if line > 0 else 1
        dest = self.view.text_point(line - 1, 0)

        def f(view, s):
            if not extend:
                return sublime.Region(dest, dest)
            else:
                return sublime.Region(s.a, dest)

        regions_transformer(self.view, f)

        # FIXME: Bringing the selections into view will be undesirable in many cases. Maybe we
        # should have an optional .scroll_selections_into_view() step during command execution.
        self.view.show(self.view.sel()[0])
コード例 #48
0
    def run(self, edit, xpos=-1):
        def f(view, s):
            row, col = view.rowcol(s.b)
            # We assume every time we need to adjust xpos it's because the old one is smaller.
            if (s.a >= s.b) and col < xpos:
                limit = view.line(s.b).size()
                new_col = min(xpos + 1, limit)

                return sublime.Region(s.a, view.text_point(row, new_col))
            return s

        if xpos < 0:
            return

        regions_transformer(self.view, f)
コード例 #49
0
    def run(self, edit, mode=None):
        def f(view, s):
            if mode == MODE_NORMAL:
                line = view.line(s.b)
                return sublime.Region(line.a, line.a)
            elif mode == _MODE_INTERNAL_NORMAL:
                return sublime.Region(view.line(s.b).a, view.full_line(s.b).b)
            elif mode == MODE_VISUAL:
                # TODO: This is sloppy. We're reorienting the caret here. We need to use the
                #       existing mechanism for that or imrpove it (using a normal hook as for
                #       other cases.)
                return sublime.Region(s.end(), s.begin())
            return s

        regions_transformer(self.view, f)
コード例 #50
0
ファイル: motion_cmds.py プロジェクト: typopl/Vintageous
    def run(self, edit, mode=None, extend=False):
        def f(view, s):
            if mode == MODE_NORMAL:
                pass

            elif mode == MODE_VISUAL:
                if s.a > s.b:
                    return sublime.Region(s.a, s.b - 1)

            elif mode == _MODE_INTERNAL_NORMAL:
                pass

            return s

        regions_transformer(self.view, f)
コード例 #51
0
ファイル: motion_cmds.py プロジェクト: typopl/Vintageous
    def run(self, edit, extend=False, character=None, mode=None, count=1):
        def f(view, s):
            eol = view.line(s.b).end()
            if not s.empty():
                eol = view.line(s.b - 1).end()

            match = s
            offset = 1 if count > 1 else 0
            for i in range(count):

                # Define search range as 'rest of the line to the right'.
                if state.mode != MODE_VISUAL:
                    search_range = sublime.Region(
                        min(match.b + 1 + offset, eol), eol)
                else:
                    search_range = sublime.Region(min(match.b + offset, eol),
                                                  eol)

                match = find_in_range(view, character, search_range.a,
                                      search_range.b, sublime.LITERAL)

                # Count too high or simply no match; break.
                if match is None:
                    match = s
                    break

            if state.mode == MODE_VISUAL or mode == _MODE_INTERNAL_NORMAL:
                if match == s:
                    # FIXME: It won't blink because the current light can't be highlighted right
                    # now (we are in command mode and there is a selection on the screen. Perhaps
                    # we can make the gutter blink instead.)
                    utils.blink()
                    return s
                return sublime.Region(s.a, match.b - 1)

            if match == s:
                utils.blink()
                return s
            return sublime.Region(match.a - 1, match.a - 1)

        # TODO: Give feedback to the user that the search failed?
        if character is None:
            return
        else:
            state = VintageState(self.view)
            state.last_character_search = character

        regions_transformer(self.view, f)
コード例 #52
0
    def run(self, edit, mode=None):
        def f(view, s):
            if s.a < s.b:
                # TODO: Wait until regions can compare themselves neatly.
                if (self.view.line(s.b).a == self.view.line(s.b - 1).a and
                        self.view.line(s.b).b == self.view.line(s.b - 1).b):
                    return sublime.Region(s.a, self.view.full_line(s.b).b)
                else:
                    return s
            else:
                if self.view.line(s.b).a != s.b:
                    r = sublime.Region(s.a, self.view.full_line(s.b).a)
                    return r
                else:
                    return s

        regions_transformer(self.view, f)
コード例 #53
0
    def run(self,
            edit,
            current_iteration=None,
            total_iterations=None,
            mode=None):
        def f(view, s):
            is_last_iteration = (current_iteration == total_iterations - 1)

            if mode == _MODE_INTERNAL_NORMAL:
                # If we're at BOL one LINE down; move to NEXTWORD WORDEND inclusive.
                if utils.is_at_bol(self.view, s):
                    next = utils.next_non_white_space_char(self.view,
                                                           s.b,
                                                           white_space='\t \n')
                    next = self.view.word(next)
                    return sublime.Region(s.a, next.b)
                else:
                    return s

            elif mode == MODE_NORMAL:
                # If we're at BOL one LINE down; move to NEXTWORD WORDEND exclusive.
                if utils.is_at_bol(self.view, s):
                    next = utils.next_non_white_space_char(self.view,
                                                           s.b,
                                                           white_space='\t \n')
                    next = self.view.word(next)
                    return sublime.Region(next.b - 1, next.b - 1)
                # Last motion; ensure caret ends up at a WORDEND exclusive. The native 'move'
                # command will have left us on the next character.
                elif is_last_iteration:
                    return sublime.Region(s.a - 1, s.b - 1)
                else:
                    return s

            elif mode == MODE_VISUAL:
                # If we're at BOL one LINE down, move to NEXTWORD WORDEND inclusive.
                if utils.is_at_bol(self.view, s):
                    next = utils.next_non_white_space_char(self.view,
                                                           s.b,
                                                           white_space='\t \n')
                    next = self.view.word(next)
                    return sublime.Region(s.a, next.b)
                else:
                    return s

        regions_transformer(self.view, f)
コード例 #54
0
ファイル: motion_cmds.py プロジェクト: typopl/Vintageous
    def run(self, edit, mode=None, extend=False):
        def f(view, s):
            # TODO: must skip empty paragraphs.
            sen = self.find_previous_sentence_end(s)

            if mode == MODE_NORMAL:
                return sublime.Region(sen.a, sen.a)

            elif mode == MODE_VISUAL:
                return sublime.Region(s.a + 1, sen.a + 1)

            elif mode == _MODE_INTERNAL_NORMAL:
                return sublime.Region(s.a, sen.a + 1)

            return s

        regions_transformer(self.view, f)
コード例 #55
0
ファイル: motion_cmds.py プロジェクト: typopl/Vintageous
    def run(self, edit, mode=None, extend=False):
        def f(view, s):
            if mode == MODE_NORMAL:
                pt = self.first_non_white_space_char(s.b)
                pt = min((pt, self.view.line(pt).b))
                return sublime.Region(pt, pt)

            elif mode == MODE_VISUAL:
                pt = self.first_non_white_space_char(s.b)
                return sublime.Region(s.a, pt)

            elif mode == _MODE_INTERNAL_NORMAL:
                # Same as dj, dk delete two entire lines, here we do a similar thing.
                return sublime.Region(s.a, self.view.line(s.b).a)

            return s

        regions_transformer(self.view, f)
コード例 #56
0
    def run(self, edit, mode=None, extend=False):
        def f(view, s):
            if mode == _MODE_INTERNAL_NORMAL:
                if s.a <= s.b:
                    if view.substr(s.b) != '\n':
                        end = view.word(s.b).b
                        end = utils.next_non_white_space_char(
                            view, end, white_space='\t ')
                        if end == s.b:
                            end = view.expand_by_class(
                                s.b, sublime.CLASS_PUNCTUATION_END).b
                        return sublime.Region(s.a, end)

                    elif view.line(s.b).empty():
                        return sublime.Region(s.a, s.b + 1)
            return s

        regions_transformer(self.view, f)
コード例 #57
0
ファイル: motion_cmds.py プロジェクト: typopl/Vintageous
    def run(self, edit, mode=None, extend=False):
        def f(view, s):
            # TODO: must skip empty paragraphs.
            sen = self.find_next_sentence_end(s)

            if mode == MODE_NORMAL:
                target = min(sen.b, view.size() - 1)
                return sublime.Region(target, target)

            elif mode == MODE_VISUAL:
                # TODO: Must encompass new line char too?
                return sublime.Region(s.a, sen.b)

            elif mode == _MODE_INTERNAL_NORMAL:
                return sublime.Region(s.a, sen.b)

            return s

        regions_transformer(self.view, f)
コード例 #58
0
ファイル: motion_cmds.py プロジェクト: typopl/Vintageous
    def run(self, edit, mode=None, extend=False, exact_word=True):
        def f(view, s):

            if exact_word:
                pattern = r'\b{0}\b'.format(query)
            else:
                pattern = query

            flags = sublime.IGNORECASE

            if mode == _MODE_INTERNAL_NORMAL:
                match = reverse_find_wrapping(view,
                                              term=pattern,
                                              start=0,
                                              end=current_sel.a,
                                              flags=0,
                                              times=1)
            else:
                match = reverse_find_wrapping(view,
                                              term=pattern,
                                              start=0,
                                              end=current_sel.a,
                                              flags=0,
                                              times=1)

            if match:
                if mode == _MODE_INTERNAL_NORMAL:
                    return sublime.Region(s.b, match.begin())
                elif state.mode == MODE_VISUAL:
                    return sublime.Region(s.b, match.begin())
                elif state.mode == MODE_NORMAL:
                    return sublime.Region(match.begin(), match.begin())
            return s

        state = VintageState(self.view)
        # TODO: make sure we swallow any leading white space.
        query = self.view.substr(self.view.word(self.view.sel()[0].end()))
        if query:
            state.last_buffer_search = query

        current_sel = self.view.sel()[0]

        regions_transformer(self.view, f)
コード例 #59
0
ファイル: motion_cmds.py プロジェクト: typopl/Vintageous
    def run(self, edit, extend=False, character=None, mode=None, count=1):
        def f(view, s):
            # TODO: Refactor this mess.
            line_text = view.substr(sublime.Region(view.line(s.b).a, s.b))
            offset = 0
            a, b = view.line(s.b).a, s.b
            final_offset = -1

            try:
                for i in range(count):
                    line_text = view.substr(sublime.Region(a, b))
                    match_in_line = line_text.rindex(character)

                    final_offset = match_in_line

                    b = view.line(s.a).a + final_offset
            except ValueError:
                pass

            if final_offset > -1:
                pt = view.line(s.b).a + final_offset

                state = VintageState(view)
                if state.mode == MODE_VISUAL or mode == _MODE_INTERNAL_NORMAL:
                    if sublime.Region(s.b, pt) == s:
                        utils.blink()
                        return s
                    return sublime.Region(s.a, pt)

                if pt == s.b:
                    utils.blink()
                    return s
                return sublime.Region(pt, pt)

            return s

        if character is None:
            return
        else:
            state = VintageState(self.view)
            state.last_character_search = character

        regions_transformer(self.view, f)
コード例 #60
0
ファイル: motion_cmds.py プロジェクト: typopl/Vintageous
    def run(self, edit, mode=None, extend=False, count=None):
        def f(view, s):
            if mode == MODE_NORMAL:
                return previous

            elif mode == MODE_VISUAL:
                return sublime.Region(s.a, previous.b)

            elif mode == _MODE_INTERNAL_NORMAL:
                return sublime.Region(s.a, previous.b)

            elif mode == MODE_VISUAL_LINE:
                return sublime.Region(s.a, self.view.full_line(previous.b).b)

            return s

        previous, scroll_amount = self.prev_half_page(count)
        regions_transformer(self.view, f)
        self.view.run_command('scroll_lines', {'amount': scroll_amount})