Jon, first of all thanks for the great product, and for providing the Vintage mode and python API.
I was personally missing a couple of VI bindings in insert mode so I implemented the ones I need most (and were easy to implement):
-
CTRL+W for left word delete
-
CTRL+H for left character delete
-
CTRL+U for undo of current line
-
CTRL+R for pasting
-
CTRL+O for one-command-mode
If any one is interested here are the keybindings:
{ "keys": "ctrl+w"], "command": "set_action_motion", "args": {
"action": "vi_delete",
"motion": "move",
"motion_args": {"by": "stops", "word_begin": true, "punct_begin": true, "empty_line": true, "forward": false, "extend": true }},
"motion_inclusive": true,
"context":
{ "key": "setting.command_mode", "operand": false },
{ "key": "setting.is_widget", "operand": false },
{ "key": "setting.vintage_ctrl_keys" }
]
},
{ "keys": "ctrl+h"], "command": "left_delete",
"context":
{ "key": "setting.command_mode", "operand": false },
{ "key": "setting.is_widget", "operand": false },
{ "key": "setting.vintage_ctrl_keys" }
]
},
{ "keys": "ctrl+u"], "command": "run_macro_file", "args": {
"file": "Packages/User/Insert Undo.sublime-macro"},
"context":
{ "key": "setting.command_mode", "operand": false },
{ "key": "setting.is_widget", "operand": false },
{ "key": "setting.vintage_ctrl_keys" }
]
},
{ "keys": "ctrl+r"], "command": "vi_paste_left",
"context":
{ "key": "setting.command_mode", "operand": false },
{ "key": "setting.is_widget", "operand": false },
{ "key": "setting.vintage_ctrl_keys" }
]
},
{ "keys": "ctrl+o"], "command": "temp_command_mode",
"context":
{ "key": "setting.command_mode", "operand": false },
{ "key": "setting.is_widget", "operand": false },
{ "key": "setting.vintage_ctrl_keys" }
]
}
Insert Undo.sublime-macro:
{"command": "exit_insert_mode"},
{"command": "undo"}
]
temp_command_mode.py:
from threading import Timer
import sublime, sublime_plugin
times = 0
class TempCommandModeCommand(sublime_plugin.TextCommand):
def run(self, edit):
self.view.run_command('exit_insert_mode')
global times # FIXME: is global a good idea?
times = 0
def check_history():
global times
last_command = self.view.command_history(0)
if times < 500 and last_command[0] == 'temp_command_mode':
sublime.set_timeout(check_history, 100)
elif last_command[0] == 'vi_eval':
# print 'entered command %s' % (last_command)
try:
if last_command[1]'motion_args']'forward'] == False:
self.view.run_command('enter_insert_mode')
else:
self.view.run_command('enter_insert_mode', {"insert_command": "move", "insert_args": {"by": "characters", "forward": True}})
except:
self.view.run_command('enter_insert_mode', {"insert_command": "move", "insert_args": {"by": "characters", "forward": True}})
times += 1
sublime.set_timeout(check_history, 100)
This is my first attempt at scripting ST2 so there’s undoubtedly room for improvement, any suggestions are welcome.
The temp command is particularly nasty since I use a timeout to avoid having to register an expensive ‘on_selection_changed’ listener, if there’s a better way please let me know.
Finally, I’ve been working on a couple of other commands such as CTRL+O from command mode to go to the previous location, and a way to visualize the characters you’re ‘Finding’ (with f or F) in a line. If any other Vintage lovers are interested I can clean these up and publish them here.