Sublime Forum

How to make plugin work better with Vintage?

#1

I stumbled my way through the API documentation to write a hacky plugin to move to the previous/next blank line. I know that there is a built-in command for this, but that only works for truly blank lines, whereas mine also works for “visually” blank lines that have only whitespace on them and jumps by contiguous block. Here is the plugin:

[code]import sublime, sublime_plugin, bisect

class MoveToBlankLineCommand(sublime_plugin.TextCommand):
def run(self, edit, line):
view = self.view
blank_line_pattern = “^\s*\n|^\s*$”

    #NOTE: view.rowcol rows are 0-indexed, while ST commands assume 1-indexed line numbers.
    chars_before_cursor = view.sel()[0].begin()
    current_line_number = view.rowcol(chars_before_cursor)[0] + 1
    blank_lines_in_file = view.find_all(blank_line_pattern) #(num. of chars to first char, "" last char)
    blank_line_numbers  = [view.rowcol(line.begin())[0] + 1 for line in blank_lines_in_file] 
    
    direction = args["direction"]
    get_index = bisect.bisect_left if direction == "up" else bisect.bisect_right #current line might be blank...
    
    current_line_index_in_blanks = get_index(blank_line_numbers, current_line_number)
    
    somewhere_to_go = (direction == "up" and current_line_index_in_blanks > 0) or \
                      (direction == "down" and current_line_index_in_blanks <= len(blank_line_numbers) - 1)
    
    if somewhere_to_go:
        target_line_number = blank_line_numbers[current_line_index_in_blanks - 1] if direction == "up" else \
                             blank_line_numbers[current_line_index_in_blanks] 
        
        for digit in str(target_line_number):
            view.run_command("push_repeat_digit", {"digit": digit})
            
        view.run_command("set_motion", {"linewise": "true", 
                                        "motion": "vi_goto_line", 
                                        "motion_args": {"ending": "eof", 
                                                        "explicit_repeat": "true", 
                                                        "extend": "true", 
                                                        "repeat": 1}
                                       })[/code]

Anyhow, one problem I have is that I want to use this to indent blocks of code using “>” in vintage command mode followed by the motion command. This works fine once, but when I hit “.” to repeat the command it repeats the motion instead of the indent. Is there a relatively straightforward way to make it repeat the indent?

0 Likes