[
  {
    "path": ".gitignore",
    "content": "# Sublime Text files\nace-jump.sublime-project\nace-jump.sublime-workspace\n\n# To do\n*.TODO\n"
  },
  {
    "path": "AceJump.sublime-settings",
    "content": "{\n    // Characters to be used as labels in order they'll appear\n    \"labels\": \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\",\n\n    // Syntax highlighting scope for the labels\n    \"labels_scope\": \"invalid\",\n\n    // Toggles case sensitive search in word and character modes.\n    \"search_case_sensitivity\": true,\n\n    // Saves all the files aceJump tried to parse.\n    // This setting will reset any linter warnings you might see during jump\n    // By saving all effected files\n    \"save_files_after_jump\": false,\n\n    // If turned on, character mode will jump after a character \n    // it it's the last character on a line.\n    \"jump_behind_last_characters\": false,\n\n    // View settings that should be respected when switching the syntax\n    // highlighting mode. In case a plugin you use adds a new\n    // setting to a view, you probably want to add it to this list.\n    \"view_settings\": [\n        \"auto_indent\",\n        \"tab_size\",\n        \"translate_tabs_to_spaces\",\n        \"use_tab_stops\",\n        \"trim_automatic_white_space\",\n        \"detect_indentation\",\n        \"draw_white_space\",\n        \"trim_trailing_white_space_on_save\",\n        \"always_show_minimap_viewport\",\n        \"color_scheme\",\n        \"font_face\",\n        \"font_options\",\n        \"gutter\",\n        \"rulers\",\n        \"draw_minimap_border\",\n        \"highlight_line\",\n        \"line_padding_top\",\n        \"line_padding_bottom\",\n        \"scroll_past_end\",\n        \"line_numbers\",\n        \"word_wrap\",\n        \"wrap_width\",\n        \"indent_subsequent_lines\",\n        \"draw_centered\",\n        \"match_brackets\",\n        \"match_brackets_content\",\n        \"match_brackets_square\",\n        \"match_brackets_braces\",\n        \"match_brackets_angle\",\n    ]\n}\n"
  },
  {
    "path": "AceJump.tmLanguage",
    "content": "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n    <key>name</key>\n    <string>AceJump</string>\n    <key>hidden</key>\n    <true/>\n    <key>patterns</key>\n    <array>\n        <dict>\n            <key>match</key>\n            <string>(.*)</string>\n            <key>name</key>\n            <string>text.ace_jump</string>\n        </dict>\n    </array>\n    <key>scopeName</key>\n    <string>comment</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Default (Linux).sublime-keymap",
    "content": "[\n    {\n        \"keys\": [\"ctrl+shift+;\"],\n        \"command\": \"ace_jump_word\"\n    },\n    {\n        \"keys\": [\"ctrl+shift+'\"],\n        \"command\": \"ace_jump_char\"\n    },\n    {\n        \"keys\": [\"ctrl+shift+.\"],\n        \"command\": \"ace_jump_line\"\n    },\n    {\n        \"keys\": [\"ctrl+shift+,\"],\n        \"command\": \"ace_jump_within_line\"\n    },\n    {\n        \"keys\": [\"alt+;\"],\n        \"command\": \"ace_jump_select\"\n    },\n    {\n        \"keys\": [\"alt+'\"],\n        \"command\": \"ace_jump_add_cursor\"\n    },\n    {\n        \"keys\": [\"alt+.\"],\n        \"command\": \"ace_jump_after\"\n    }\n]\n"
  },
  {
    "path": "Default (OSX).sublime-keymap",
    "content": "[\n    {\n        \"keys\": [\"super+shift+;\"],\n        \"command\": \"ace_jump_word\"\n    },\n    {\n        \"keys\": [\"super+shift+'\"],\n        \"command\": \"ace_jump_char\"\n    },\n    {\n        \"keys\": [\"super+shift+.\"],\n        \"command\": \"ace_jump_line\"\n    },\n    {\n        \"keys\": [\"super+shift+,\"],\n        \"command\": \"ace_jump_within_line\"\n    },\n    {\n        \"keys\": [\"ctrl+;\"],\n        \"command\": \"ace_jump_select\"\n    },\n    {\n        \"keys\": [\"ctrl+'\"],\n        \"command\": \"ace_jump_add_cursor\"\n    },\n    {\n        \"keys\": [\"ctrl+.\"],\n        \"command\": \"ace_jump_after\"\n    }\n]\n"
  },
  {
    "path": "Default (Windows).sublime-keymap",
    "content": "[\n    {\n        \"keys\": [\"ctrl+shift+;\"],\n        \"command\": \"ace_jump_word\"\n    },\n    {\n        \"keys\": [\"ctrl+shift+'\"],\n        \"command\": \"ace_jump_char\"\n    },\n    {\n        \"keys\": [\"ctrl+shift+.\"],\n        \"command\": \"ace_jump_line\"\n    },\n    {\n        \"keys\": [\"ctrl+shift+,\"],\n        \"command\": \"ace_jump_within_line\"\n    },\n    {\n        \"keys\": [\"alt+;\"],\n        \"command\": \"ace_jump_select\"\n    },\n    {\n        \"keys\": [\"alt+'\"],\n        \"command\": \"ace_jump_add_cursor\"\n    },\n    {\n        \"keys\": [\"alt+.\"],\n        \"command\": \"ace_jump_after\"\n    }\n]\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 Kuba Birecki\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
  },
  {
    "path": "Main.sublime-menu",
    "content": "[\n    {\n        \"id\": \"preferences\",\n        \"children\": [\n            {\n                \"id\": \"package-settings\",\n                \"children\": [\n                    {\n                        \"caption\": \"AceJump\",\n                        \"children\": [\n                            {\n                                \"caption\": \"README\",\n                                \"command\": \"open_file\",\n                                \"args\": {\n                                    \"file\": \"${packages}/AceJump/README.md\"\n                                }\n                            },\n                            {\n                                \"caption\": \"-\"\n                            },\n                            {\n                                \"caption\": \"Settings - Default\",\n                                \"command\": \"open_file\",\n                                \"args\": {\n                                    \"file\": \"${packages}/AceJump/AceJump.sublime-settings\"\n                                }\n                            },\n                            {\n                                \"caption\": \"Settings - User\",\n                                \"command\": \"open_file\",\n                                \"args\": {\n                                    \"file\": \"${packages}/User/AceJump.sublime-settings\"\n                                }\n                            },\n                            {\n                                \"caption\": \"-\"\n                            },\n                            {\n                                \"caption\": \"Key Bindings - Default\",\n                                \"command\": \"open_file\",\n                                \"args\": {\n                                    \"file\": \"${packages}/AceJump/Default (OSX).sublime-keymap\",\n                                    \"platform\": \"OSX\"\n                                }\n                            },\n                            {\n                                \"caption\": \"Key Bindings - Default\",\n                                \"command\": \"open_file\",\n                                \"args\": {\n                                    \"file\": \"${packages}/AceJump/Default (Linux).sublime-keymap\",\n                                    \"platform\": \"Linux\"\n                                }\n                            },\n                            {\n                                \"caption\": \"Key Bindings - Default\",\n                                \"command\": \"open_file\",\n                                \"args\": {\n                                    \"file\": \"${packages}/AceJump/Default (Windows).sublime-keymap\",\n                                    \"platform\": \"Windows\"\n                                }\n                            },\n                            {\n                                \"caption\": \"Key Bindings - User\",\n                                \"command\": \"open_file\",\n                                \"args\": {\n                                    \"file\": \"${packages}/User/Default (OSX).sublime-keymap\",\n                                    \"platform\": \"OSX\"\n                                }\n                            },\n                            {\n                                \"caption\": \"Key Bindings - User\",\n                                \"command\": \"open_file\",\n                                \"args\": {\n                                    \"file\": \"${packages}/User/Default (Linux).sublime-keymap\",\n                                    \"platform\": \"Linux\"\n                                }\n                            },\n                            {\n                                \"caption\": \"Key Bindings - User\",\n                                \"command\": \"open_file\",\n                                \"args\": {\n                                    \"file\": \"${packages}/User/Default (Windows).sublime-keymap\",\n                                    \"platform\": \"Windows\"\n                                }\n                            },\n                            {\n                                \"caption\": \"-\"\n                            }\n                        ]\n                    }\n                ]\n            }\n        ]\n    }\n]\n"
  },
  {
    "path": "README.md",
    "content": "# AceJump\n\nA plugin for Sublime Text 3 heavily inspired by AceJump for emacs.\n\nAceJump allows you to move the cursor to any character to any place currently on screen.\nTo clarify, you can jump between characters in all visible portions of currently open documents in any panes.\nLike it's emacs counterpart, AceJump for sublime features word (on the image below), character and line modes which make jumping even easier.\n\n![AceJump](https://cloud.githubusercontent.com/assets/8056203/10858871/92069504-7f58-11e5-8593-e373121fd917.gif)\n\nAfter selecting a mode, you type in a character (except in line mode, where you don't have to type in anything) and appropriate labels are displayed. Then all you need to do is press the key from the label and voila!\n\n## Installation\n\n### PackageControl\n\nYou can install AceJump from [PackageControl](http://wbond.net/sublime_packages/package_control) by following the steps below:\n\n- Open up the command palette and select ```Package Control: Install Package```\n- Wait for the packages index to load and select ```AceJump```\n\n### Manual installation\n\nYou can install AceJump manually using git by running the following command within sublime packages directory (Preferences > Browse Packages):\n\n```\n$ git clone git@github.com:ice9js/ace-jump-sublime.git AceJump/\n```\n\nOr you can just copy the contents of this repository into ```Packages/AceJump```.\n\n## Usage\n\n### Word mode\n\nGoes to a word starting with the given character. This mode works only with alphanumeric characters. If you're interested in jumping to a special character, use character mode instead.\n\n- ```Ctrl/Super + Shift + ;```\n- ```<head character>```\n- ```<label>```\n\nNo need to press enter after selecting a label!\n\n![Word mode](https://cloud.githubusercontent.com/assets/8056203/10858875/921aa814-7f58-11e5-99ec-9d17fc22f313.gif)\n\n### Character mode\n\nGoes to an occurence of the given character.\n\n- ```Ctrl/Super + Shift + '```\n- ```<character>```\n- ```<label>```\n\n![Character mode](https://cloud.githubusercontent.com/assets/8056203/10858870/92021b8c-7f58-11e5-916f-8ebc2d1d5eb4.gif)\n\n### Line mode\n\nLabels all non-empty lines and lets you jump to one of them.\n\n- ```Ctrl/Super + Shift + .```\n- ```<label>```\n\n![Line mode](https://cloud.githubusercontent.com/assets/8056203/10858872/9207c596-7f58-11e5-9353-2d57783ca2cc.gif)\n\n### Within Line mode\n\nLabels all words within the line where current cursor locate and lets you jump to one of them.\n\n- ```Ctrl/Super + Shift + ,```\n- ```<label>```\n\n### Select mode\n\nAfter triggering select mode, the next jump will select everything inbetween the current cursor position and the selected label.\nWhen select mode is triggered, the next jump is limited to the current file.\n\n- ```Alt+;``` (```Ctrl+;``` for OS X)\n- perform a jump using word, character or line mode\n\n![Select mode](https://cloud.githubusercontent.com/assets/8056203/10858874/921207a4-7f58-11e5-936a-6e56ec80d486.gif)\n\n### Multiple cursors mode\n\nAfter triggering multiple cursors mode, the next jump will add a new cursor to the view instead of moving the existing one.\nAgain, when this mode is triggered, only jumps in the same file are available.\n\n- ```Alt+'``` (```Ctrl+'``` for OS X)\n\n![Multiple cursors mode](https://cloud.githubusercontent.com/assets/8056203/10858873/9207ee86-7f58-11e5-9251-e74bd64dbfed.gif)\n\n### Jump-after mode\n\nIn this mode, the cursor will jump behind the targeted instance. Unfortunetely,\nthis mode cannot be paired with select or multiple cursors mode yet.\n\n- ```Alt+.``` (```Ctrl+.``` for OS X)\n\n![Jump-after mode](https://cloud.githubusercontent.com/assets/8056203/10858868/91fb4b22-7f58-11e5-8bdf-b489c6bb7ee2.gif)\n\n### Batching\n\nIn case there are more places to jump to than labels available, labels will be batched and you can cycle through them by simply pressing enter.\n\n![Batching](https://cloud.githubusercontent.com/assets/8056203/10858869/92006792-7f58-11e5-9ece-6b94d1016147.gif)\n\n## Customization\n\nIn order to access AceJump settings, go to ```Preferences > Package Settings > AceJump > Settings - User```.\n\n### Key bindings\n\nGo to ```Preferences > Package Settings > AceJump > Key Bindings - User```.\nYou can then override the bindings for any of the following commands:\n\n- ```ace_jump_word```\n- ```ace_jump_char```\n- ```ace_jump_line```\n- ```ace_jump_within_line```\n- ```ace_jump_select```\n- ```ace_jump_add_cursor```\n- ```ace_jump_after```\n\nThe commands accept an optional Boolean `current_buffer_only` argument. When present and set to `true`, AceJump only performs on the currently edited buffer.\n\n### Labels\n\nYou can override the ```labels``` setting to provide your own set of labels to be used by AceJump.\n\n### Highlighting\n\nYou can also set the syntsx scope that's used for highlighting by overriding ```labels_scope```. The default scope is ```invalid```.\n\n### Case sensitivity\n\nAce jump is case sensitive by default. Case sensitivity can be toggled on and off by altering the ```search_case_sensitivity``` setting.\n\n### Jumping behind the last character in a line\n\nBy setting ```jump_behind_last_characters``` to ```true```, AceJump will jump behind a character if it's the last character on a line, without the need to trigger jump after mode. This only works in character mode and is switched off by default.\n\n### Known issues\n\nIt has been reported that the _Select mode_, _Multi cursors mode_ and _Jump after_ mode might not work using the specified keybinding.  \nAs a workaround for that follow these steps:\n\n- Start a regular search, e.g. word search (default keybinding: Ctrl+Shift+;).\n- **Before** entering any character, activate the advanced mode (e.g. for _Select mode_ use Alt+;).\n- Now enter the character to lookup.\n- Use the label to go to the corresponding location.\n"
  },
  {
    "path": "ace_jump.py",
    "content": "import sublime, sublime_plugin\nimport re, itertools\n\nlast_index = 0\nhints = []\nsearch_regex = r''\n\nnext_search = False\n\n# MODES\n# 0: default (jumps in front of the selection)\n# 1: select\n# 2: add-cursor\n# 3: jump-after\nmode = 0\n\nace_jump_active = False\n\ndef get_active_views(window, current_buffer_only):\n    \"\"\"Returns all currently visible views\"\"\"\n\n    views = []\n    if current_buffer_only:\n        views.append(window.active_view())\n    else:\n        for group in range(window.num_groups()):\n            views.append(window.active_view_in_group(group))\n    return views\n\ndef set_views_setting(views, setting, values):\n    \"\"\"Sets the values for the setting in all given views\"\"\"\n\n    for i in range(len(views)):\n        views[i].settings().set(setting, values[i])\n\ndef set_views_settings(views, settings, values):\n    \"\"\"Sets the values for all settings in all given views\"\"\"\n\n    for i in range(len(settings)):\n        set_views_setting(views, settings[i], values[i])\n\ndef get_views_setting(views, setting):\n    \"\"\"Returns the setting value for all given views\"\"\"\n\n    settings = []\n    for view in views:\n        settings.append(view.settings().get(setting))\n    return settings\n\ndef get_views_settings(views, settings):\n    \"\"\"Gets the settings for every given view\"\"\"\n\n    values = []\n    for setting in settings:\n        values.append(get_views_setting(views, setting))\n    return values\n\ndef set_views_syntax(views, syntax):\n    \"\"\"Sets the syntax highlighting for all given views\"\"\"\n\n    for i in range(len(views)):\n        views[i].set_syntax_file(syntax[i])\n\ndef set_views_sel(views, selections):\n    \"\"\"Sets the selections for all given views\"\"\"\n\n    for i in range(len(views)):\n        for sel in selections[i]:\n            views[i].sel().add(sel)\n\ndef get_views_sel(views):\n    \"\"\"Returns the current selection for each from the given views\"\"\"\n\n    selections = []\n    for view in views:\n        selections.append(view.sel())\n    return selections\n\nclass AceJumpCommand(sublime_plugin.WindowCommand):\n    \"\"\"Base command class for AceJump plugin\"\"\"\n\n    def run(self, current_buffer_only = False):\n        global ace_jump_active\n        ace_jump_active = True\n\n        self.char = \"\"\n        self.target = \"\"\n        self.views = []\n        self.changed_views = []\n        self.breakpoints = []\n\n        self.all_views = get_active_views(self.window, current_buffer_only)\n        self.syntax = get_views_setting(self.all_views, \"syntax\")\n        self.sel = get_views_sel(self.all_views)\n\n        settings = sublime.load_settings(\"AceJump.sublime-settings\")\n        self.highlight = settings.get(\"labels_scope\", \"invalid\")\n        self.labels = settings.get(\n            \"labels\",\n            \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n        )\n        self.case_sensitivity = settings.get(\"search_case_sensitivity\", True)\n        self.jump_behind_last = settings.get(\"jump_behind_last_characters\", False)\n        self.save_files_after_jump = settings.get(\"save_files_after_jump\", False)\n\n        self.view_settings = settings.get(\"view_settings\", [])\n        self.view_values = get_views_settings(\n            self.all_views,\n            self.view_settings\n        )\n\n        self.show_prompt(self.prompt(), self.init_value())\n\n    def is_enabled(self):\n        global ace_jump_active\n        return not ace_jump_active\n\n    def show_prompt(self, title, value):\n        \"\"\"Shows a prompt with the given title and value in the window\"\"\"\n\n        self.window.show_input_panel(\n            title, value,\n            self.next_batch, self.on_input, self.submit\n        )\n\n    def next_batch(self, command):\n        \"\"\"Displays the next batch of labels after pressing return\"\"\"\n\n        self.remove_labels()\n        self.show_prompt(self.prompt(), self.char)\n\n    def on_input(self, command):\n        \"\"\"Fires the necessary actions for the current input\"\"\"\n\n        if len(command) == 1:\n            self.char = command\n            if self.char == \"<\" or self.char == \">\":\n                # re.escape escapes these 2 characters but it isn't needed for view.find()\n                self.add_labels(self.regex().format(self.char))\n            else:\n                self.add_labels(self.regex().format(re.escape(self.char)))\n            return\n\n        if len(command) == 2:\n            self.target = command[1]\n\n        self.window.run_command(\"hide_panel\", {\"cancel\": True})\n\n    def submit(self):\n        \"\"\"Handles the behavior after closing the prompt\"\"\"\n        global next_search, mode, ace_jump_active\n        next_search = False\n\n        self.remove_labels()\n        set_views_sel(self.all_views, self.sel)\n        set_views_syntax(self.all_views, self.syntax)\n\n        if self.valid_target(self.target):\n            self.jump(self.labels.find(self.target))\n\n        mode = 0\n        ace_jump_active = False\n\n        \"\"\"Saves changed views after jump is complete\"\"\"\n        if self.save_files_after_jump:\n          for view in self.changed_views:\n            if not view.is_read_only() and not view.is_dirty():\n              view.run_command(\"save\")\n\n    def add_labels(self, regex):\n        \"\"\"Adds labels to characters matching the regex\"\"\"\n\n        global last_index, hints\n\n        last_index = 0\n        hints = []\n\n        self.views = self.views_to_label()\n        self.region_type = self.get_region_type()\n        self.changed_views = []\n        self.breakpoints = []\n        changed_buffers = []\n\n        for view in self.views[:]:\n            if view.buffer_id() in changed_buffers:\n                break\n\n            view.run_command(\"add_ace_jump_labels\", {\n                \"regex\": regex,\n                \"region_type\": self.region_type,\n                \"labels\": self.labels,\n                \"highlight\": self.highlight,\n                \"case_sensitive\": self.case_sensitivity\n            })\n            self.breakpoints.append(last_index)\n            self.changed_views.append(view)\n            changed_buffers.append(view.buffer_id())\n\n            if next_search:\n                break\n\n            self.views.remove(view)\n\n        set_views_syntax(self.all_views, list(itertools.repeat(\n            \"Packages/AceJump/AceJump.tmLanguage\",\n            len(self.all_views)\n        )))\n\n        set_views_settings(\n            self.all_views,\n            self.view_settings,\n            self.view_values\n        )\n\n    def remove_labels(self):\n        \"\"\"Removes all previously added labels\"\"\"\n\n        last_breakpoint = 0\n        for breakpoint in self.breakpoints:\n            if breakpoint != last_breakpoint:\n                view = self.changed_views[self.view_for_index(breakpoint - 1)]\n                view.run_command(\"remove_ace_jump_labels\")\n                last_breakpoint = breakpoint\n\n    def jump(self, index):\n        \"\"\"Performs the jump action\"\"\"\n\n        region = hints[index].begin()\n        view = self.changed_views[self.view_for_index(index)]\n\n        self.window.focus_view(view)\n        view.run_command(\"perform_ace_jump\", {\"target\": region})\n        self.after_jump(view)\n\n    def views_to_label(self):\n        \"\"\"Returns the views that still have to be labeled\"\"\"\n\n        if mode != 0:\n            return [self.window.active_view()]\n\n        return self.all_views[:] if len(self.views) == 0 else self.views\n\n    def view_for_index(self, index):\n        \"\"\"Returns a view index for the given label index\"\"\"\n\n        for breakpoint in self.breakpoints:\n            if index < breakpoint:\n                return self.breakpoints.index(breakpoint)\n\n    def valid_target(self, target):\n        \"\"\"Check if jump target is valid\"\"\"\n\n        index = self.labels.find(target)\n\n        return target != \"\" and index >= 0 and index < last_index;\n\n    def get_region_type(self):\n        \"\"\"Return region type for labeling\"\"\"\n\n        return \"visible_region\"\n\nclass AceJumpWordCommand(AceJumpCommand):\n    \"\"\"Specialized command for word-mode\"\"\"\n\n    def prompt(self):\n        return \"Head char\"\n\n    def init_value(self):\n        return \"\"\n\n    def regex(self):\n        return r'\\b{}'\n\n    def after_jump(self, view):\n        global mode\n\n        if mode == 3:\n            view.run_command(\"move\", {\"by\": \"word_ends\", \"forward\": True})\n            mode = 0\n\nclass AceJumpCharCommand(AceJumpCommand):\n    \"\"\"Specialized command for char-mode\"\"\"\n\n    def prompt(self):\n        return \"Char\"\n\n    def init_value(self):\n        return \"\"\n\n    def regex(self):\n        return r'{}'\n\n    def after_jump(self, view):\n        global mode\n\n        if mode == 3:\n            view.run_command(\"move\", {\"by\": \"characters\", \"forward\": True})\n            mode = 0\n\n    def jump(self, index):\n        global mode\n\n        view = self.changed_views[self.view_for_index(index)]\n        if self.jump_behind_last and \"\\n\" in view.substr(hints[index].end()):\n            mode = 3\n\n        return AceJumpCommand.jump(self, index)\n\nclass AceJumpLineCommand(AceJumpCommand):\n    \"\"\"Specialized command for line-mode\"\"\"\n\n    def prompt(self):\n        return \"\"\n\n    def init_value(self):\n        return \" \"\n\n    def regex(self):\n        return r'(.*)[^\\s](.*)\\n'\n\n    def after_jump(self, view):\n        global mode\n\n        if mode == 3:\n            view.run_command(\"move\", {\"by\": \"lines\", \"forward\": True})\n            view.run_command(\"move\", {\"by\": \"characters\", \"forward\": False})\n            mode = 0\n\nclass AceJumpWithinLineCommand(AceJumpCommand):\n    \"\"\"Specialized command for within-line-mode\"\"\"\n\n    def prompt(self):\n        return \"\"\n\n    def init_value(self):\n        return \" \"\n\n    def regex(self):\n        return r'\\b\\w'\n\n    def after_jump(self, view):\n        global mode\n\n        if mode == 3:\n            view.run_command(\"move\", {\"by\": \"word_ends\", \"forward\": True})\n            mode = 0\n\n    def get_region_type(self):\n\n        return \"current_line\"\n\nclass AceJumpSelectCommand(sublime_plugin.WindowCommand):\n    \"\"\"Command for turning on select mode\"\"\"\n\n    def run(self):\n        global mode\n\n        mode = 0 if mode == 1 else 1\n\nclass AceJumpAddCursorCommand(sublime_plugin.WindowCommand):\n    \"\"\"Command for turning on multiple cursor mode\"\"\"\n\n    def run(self):\n        global mode\n\n        mode = 0 if mode == 2 else 2\n\nclass AceJumpAfterCommand(sublime_plugin.WindowCommand):\n    \"\"\"Modifier-command which lets you jump behind a character, word or line\"\"\"\n\n    def run(self):\n        global mode\n\n        mode = 0 if mode == 3 else 3\n\nclass AddAceJumpLabelsCommand(sublime_plugin.TextCommand):\n    \"\"\"Command for adding labels to the views\"\"\"\n\n    def run(self, edit, regex, region_type, labels, highlight, case_sensitive):\n        global hints\n\n        characters = self.find(regex, region_type, len(labels), case_sensitive)\n        self.add_labels(edit, characters, labels)\n        self.view.add_regions(\"ace_jump_hints\", characters, highlight)\n\n        hints = hints + characters\n\n    def find(self, regex, region_type, max_labels, case_sensitive):\n        \"\"\"Returns a list with all occurences matching the regex\"\"\"\n\n        global next_search, last_index\n\n        chars = []\n\n        region = self.get_target_region(region_type)\n        next_search = next_search if next_search else region.begin()\n        last_search = region.end()\n\n        while (next_search < last_search and last_index < max_labels):\n            word = self.view.find(regex, next_search, 0 if case_sensitive else sublime.IGNORECASE)\n\n            if not word or word.end() > last_search:\n                break\n\n            last_index += 1\n            next_search = word.end()\n            chars.append(sublime.Region(word.begin(), word.begin() + 1))\n\n        if last_index < max_labels:\n            next_search = False\n\n        return chars\n\n    def add_labels(self, edit, regions, labels):\n        \"\"\"Replaces the given regions with labels\"\"\"\n\n        for i in range(len(regions)):\n            self.view.replace(\n                edit, regions[i], labels[last_index + i - len(regions)]\n            )\n\n    def get_target_region(self, region_type):\n\n        return {\n            'visible_region': lambda view : view.visible_region(),\n            'current_line': lambda view : view.line(view.sel()[0]),\n        }.get(region_type)(self.view)\n\nclass RemoveAceJumpLabelsCommand(sublime_plugin.TextCommand):\n    \"\"\"Command for removing labels from the views\"\"\"\n\n    def run(self, edit):\n        self.view.erase_regions(\"ace_jump_hints\")\n        self.view.end_edit(edit)\n        self.view.run_command(\"undo\")\n\nclass PerformAceJumpCommand(sublime_plugin.TextCommand):\n    \"\"\"Command performing the jump\"\"\"\n\n    def run(self, edit, target):\n        global mode\n        if mode == 0 or mode == 3:\n            self.view.sel().clear()\n\n        self.view.sel().add(self.target_region(target))\n        self.view.show(target)\n\n    def target_region(self, target):\n        if mode == 1:\n            for cursor in self.view.sel():\n                return sublime.Region(cursor.begin(), target)\n\n        return sublime.Region(target)\n"
  }
]