示例#1
0
    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()
示例#2
0
    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()
示例#3
0
    def run(self, edit, **vi_cmd_data):
        self.debug("Data in ViRunCommand:", vi_cmd_data)

        try:
            if vi_cmd_data["restore_original_carets"]:
                self.save_caret_pos()

            # If we're about to jump, we need to remember the current position so we can jump back
            # here. XXX creates_jump_at_current_position might be redundant.
            if vi_cmd_data["creates_jump_at_current_position"] or vi_cmd_data["is_jump"]:
                self.add_to_jump_list(vi_cmd_data)

            # XXX: Fix this. When should we run the motion exactly?
            if vi_cmd_data["action"]:
                # If no motion is present, we know we just have to run the action (like ctrl+w, v).
                if (vi_cmd_data["motion"]) or (
                    vi_cmd_data["motion_required"] and not view.has_non_empty_selection_region()
                ):
                    self.do_whole_motion(vi_cmd_data)

                # The motion didn't change the selections: abort action if so required.
                # TODO: What to do with .post_action() and .restore_original_carets_if_needed() in this event?
                if (
                    vi_cmd_data["mode"] == _MODE_INTERNAL_NORMAL
                    and all([v.empty() for v in self.view.sel()])
                    and vi_cmd_data["cancel_action_if_motion_fails"]
                ):
                    return

                self.do_action(vi_cmd_data)
            else:
                self.do_whole_motion(vi_cmd_data)

        finally:
            # XXX: post_action should be run only if do_action succeeds (?).
            self.do_post_action(vi_cmd_data)

            if vi_cmd_data["must_update_xpos"]:
                state = VintageState(self.view)
                state.update_xpos()

            self.do_modify_selections(vi_cmd_data)
            self.restore_original_carets_if_needed(vi_cmd_data)

            if vi_cmd_data["scroll_into_view"]:
                if vi_cmd_data["scroll_command"]:
                    self.view.run_command(*vi_cmd_data["scroll_command"])
                else:
                    # TODO: If moving by lines, scroll the minimum amount to display the new sels.
                    self.view.show(self.view.sel()[0])

            # We cannot run (maybe_)mark_undo_groups_for_gluing/glue_marked_undo_groups commands
            # within a command meant to be subsumed in the group to be glued. It won't work. So
            # let's save the data we need to transtion to the next mode, which will be taken care
            # of later by VintageState.reset().
            # XXX: This code can probably be moved to VintageState.run().
            state = VintageState(self.view)
            state.next_mode = vi_cmd_data["next_mode"]
            state.next_mode_command = vi_cmd_data["follow_up_mode"]
示例#4
0
    def run(self):
        state = VintageState(self.view)
        for i in range(state.count):
            self.view.run_command('redo')

        state.update_xpos()
        # Ensure that we wipe the count, if any.
        state.reset()
        self.view.run_command('vi_enter_normal_mode')
示例#5
0
    def run(self):
        state = VintageState(self.view)
        for i in range(state.count):
            self.view.run_command('redo')

        state.update_xpos()
        # Ensure that we wipe the count, if any.
        state.reset()
        self.view.run_command('vi_enter_normal_mode')
示例#6
0
class Test_update_xpos(unittest.TestCase):
    def setUp(self):
        TestsState.view.settings().erase('vintage')
        TestsState.view.window().settings().erase('vintage')
        TestsState.view.settings().erase('is_widget')
        self.state = VintageState(TestsState.view)

    def tearDown(self):
        self.state.view.sel().clear()
        self.state.view.sel().add(sublime.Region(0, 0))

    def testCanSetXposInNormalMode(self):
        self.state.mode = MODE_NORMAL
        self.state.view.sel().clear()
        pt = self.state.view.text_point(2, 10)
        self.state.view.sel().add(sublime.Region(pt, pt))
        self.state.update_xpos()
        self.assertEqual(self.state.xpos, 10)

    def testCanSetXposInVisualMode(self):
        self.state.mode = MODE_VISUAL
        self.state.view.sel().clear()
        pt = self.state.view.text_point(2, 10)
        self.state.view.sel().add(sublime.Region(pt - 5, pt))
        self.state.update_xpos()
        self.assertEqual(self.state.xpos, 9)

    def testCanSetXposInVisualModeWithReversedRegion(self):
        self.state.mode = MODE_VISUAL
        self.state.view.sel().clear()
        pt = self.state.view.text_point(2, 10)
        self.state.view.sel().add(sublime.Region(pt, pt - 5))
        self.state.update_xpos()
        self.assertEqual(self.state.xpos, 5)

    def testCanSetXposToDefaultValue(self):
        self.state.mode = MODE_VISUAL_LINE
        self.state.view.sel().clear()
        pt = self.state.view.text_point(2, 10)
        self.state.view.sel().add(sublime.Region(pt, pt - 5))
        self.state.update_xpos()
        self.assertEqual(self.state.xpos, 0)
示例#7
0
    def run(self, edit, **vi_cmd_data):
        self.debug("Data in ViRunCommand:", vi_cmd_data)

        state = VintageState(self.view)

        try:
            # Always save carets just in case.
            self.save_caret_pos()

            # If we're about to jump, we need to remember the current position so we can jump back
            # here. XXX creates_jump_at_current_position might be redundant.
            # TODO: Extract method.
            if vi_cmd_data['creates_jump_at_current_position'] or vi_cmd_data['is_jump']:
                self.add_to_jump_list(vi_cmd_data)

            sels_before_motion = list(self.view.sel())

            # XXX: Fix this. When should we run the motion exactly?
            if vi_cmd_data['action']:
                # If no motion is present, we know we just have to run the action (like ctrl+w, v).
                if ((vi_cmd_data['motion']) or
                    (vi_cmd_data['motion_required'] and
                     not view.has_non_empty_selection_region())):
                        self.do_whole_motion(vi_cmd_data)

                        # The motion didn't change the selections: abort action if so required.
                        # TODO: What to do with .post_action() and .restore_original_carets_if_needed() in this event?
                        if (vi_cmd_data['mode'] in (_MODE_INTERNAL_NORMAL, MODE_VISUAL) and
                            any([(old == new) for (old, new) in zip(sels_before_motion, list(self.view.sel()))]) and
                            vi_cmd_data['cancel_action_if_motion_fails']):
                                # TODO: There should be a method that lets us do this without modifying vi_cmd_data.
                                vi_cmd_data['restore_original_carets'] = True
                                # FIXME: This is redundant: we call the same method in 'finally' clause.
                                self.restore_original_carets_if_needed(vi_cmd_data)
                                utils.blink()
                                state.cancel_macro = True
                                return

                self.reorient_begin_to_end(vi_cmd_data)
                self.do_action(vi_cmd_data)
            else:
                self.do_whole_motion(vi_cmd_data)
                if (vi_cmd_data['mode'] == MODE_NORMAL and
                    any([(old == new) for (old, new) in zip(sels_before_motion, list(self.view.sel()))])):
                        state.cancel_macro = True
                        utils.blink()

        finally:
            # XXX: post_action should be run only if do_action succeeds (?).
            self.do_post_action(vi_cmd_data)

            # TODO: Extract method.
            if vi_cmd_data['must_update_xpos']:
                state = VintageState(self.view)
                state.update_xpos()

            self.do_modify_selections(vi_cmd_data)
            self.restore_original_carets_if_needed(vi_cmd_data)

            # TODO: Extract method.
            if vi_cmd_data['scroll_into_view']:
                if vi_cmd_data['scroll_command']:
                    self.view.run_command(*vi_cmd_data['scroll_command'])
                else:
                    # TODO: If moving by lines, scroll the minimum amount to display the new sels.
                    self.view.show(self.view.sel()[0])

            # We cannot run (maybe_)mark_undo_groups_for_gluing/glue_marked_undo_groups commands
            # within a command meant to be subsumed in the group to be glued. It won't work. So
            # let's save the data we need to transtion to the next mode, which will be taken care
            # of later by VintageState.reset().
            # XXX: This code can probably be moved to VintageState.run().
            # TODO: Extract method.
            state = VintageState(self.view)
            state.next_mode = vi_cmd_data['next_mode']
            state.next_mode_command = vi_cmd_data['follow_up_mode']
示例#8
0
    def run(self, edit, **vi_cmd_data):
        self.debug("Data in ViRunCommand:", vi_cmd_data)

        state = VintageState(self.view)

        try:
            # Always save carets just in case.
            self.save_caret_pos()

            # If we're about to jump, we need to remember the current position so we can jump back
            # here. XXX creates_jump_at_current_position might be redundant.
            # TODO: Extract method.
            if vi_cmd_data['creates_jump_at_current_position'] or vi_cmd_data[
                    'is_jump']:
                self.add_to_jump_list(vi_cmd_data)

            sels_before_motion = list(self.view.sel())

            # XXX: Fix this. When should we run the motion exactly?
            if vi_cmd_data['action']:
                # If no motion is present, we know we just have to run the action (like ctrl+w, v).
                if ((vi_cmd_data['motion'])
                        or (vi_cmd_data['motion_required']
                            and not view.has_non_empty_selection_region())):
                    self.do_whole_motion(vi_cmd_data)

                    # The motion didn't change the selections: abort action if so required.
                    # TODO: What to do with .post_action() and .restore_original_carets_if_needed() in this event?
                    if (vi_cmd_data['mode']
                            in (_MODE_INTERNAL_NORMAL, MODE_VISUAL)
                            and any([(old == new) for (old, new) in zip(
                                sels_before_motion, list(self.view.sel()))])
                            and vi_cmd_data['cancel_action_if_motion_fails']):
                        # TODO: There should be a method that lets us do this without modifying vi_cmd_data.
                        vi_cmd_data['restore_original_carets'] = True
                        # FIXME: This is redundant: we call the same method in 'finally' clause.
                        self.restore_original_carets_if_needed(vi_cmd_data)
                        utils.blink()
                        state.cancel_macro = True
                        return

                self.do_action(vi_cmd_data)
            else:
                self.do_whole_motion(vi_cmd_data)
                if (vi_cmd_data['mode'] == MODE_NORMAL
                        and any([(old == new) for (old, new) in zip(
                            sels_before_motion, list(self.view.sel()))])):
                    state.cancel_macro = True
                    utils.blink()

        finally:
            # XXX: post_action should be run only if do_action succeeds (?).
            self.do_post_action(vi_cmd_data)

            # TODO: Extract method.
            if vi_cmd_data['must_update_xpos']:
                state = VintageState(self.view)
                state.update_xpos()

            self.do_modify_selections(vi_cmd_data)
            self.restore_original_carets_if_needed(vi_cmd_data)

            # TODO: Extract method.
            if vi_cmd_data['scroll_into_view']:
                if vi_cmd_data['scroll_command']:
                    self.view.run_command(*vi_cmd_data['scroll_command'])
                else:
                    # TODO: If moving by lines, scroll the minimum amount to display the new sels.
                    self.view.show(self.view.sel()[0])

            # We cannot run (maybe_)mark_undo_groups_for_gluing/glue_marked_undo_groups commands
            # within a command meant to be subsumed in the group to be glued. It won't work. So
            # let's save the data we need to transtion to the next mode, which will be taken care
            # of later by VintageState.reset().
            # XXX: This code can probably be moved to VintageState.run().
            # TODO: Extract method.
            state = VintageState(self.view)
            state.next_mode = vi_cmd_data['next_mode']
            state.next_mode_command = vi_cmd_data['follow_up_mode']