Permalink
Browse files

Add GNU readline-like keybindings to input widget (including history)

fixes #4
  • Loading branch information...
1 parent 9059bfe commit bfabb07dbdfb2f467a75042a4bedf5914f687b2d @misfo committed Mar 3, 2012
Showing with 76 additions and 2 deletions.
  1. +31 −0 Default.sublime-keymap
  2. +7 −2 shell_turtlestein.py
  3. +38 −0 sublime_readline.py
View
@@ -0,0 +1,31 @@
+[
+ // GNU readline-like keybindings for the input widget
+ {"keys": ["up"], "command": "readline_history_change",
+ "args": {"movement": "move", "movement_args": {"by": "lines", "forward": false}},
+ "context": [{"key": "setting.readline_input_widget"}]
+ },
+ {"keys": ["down"], "command": "readline_history_change",
+ "args": {"movement": "move", "movement_args": {"by": "lines", "forward": true}},
+ "context": [{"key": "setting.readline_input_widget"}]
+ },
+ {"keys": ["shift+up"], "command": "readline_history_change",
+ "args": {"movement": "move", "movement_args": {"by": "lines", "forward": false}},
+ "context": [{"key": "setting.readline_input_widget"}]
+ },
+ {"keys": ["shift+down"], "command": "readline_history_change",
+ "args": {"movement": "move", "movement_args": {"by": "lines", "forward": true}},
+ "context": [{"key": "setting.readline_input_widget"}]
+ },
+ {"keys": ["ctrl+a"], "command": "move_to",
+ "args": {"to": "bol"},
+ "context": [{"key": "setting.readline_input_widget"}]
+ },
+ {"keys": ["ctrl+e"], "command": "move_to",
+ "args": {"to": "eol"},
+ "context": [{"key": "setting.readline_input_widget"}]
+ },
+ {"keys": ["ctrl+u"], "command": "run_macro_file",
+ "args": {"file": "Packages/Default/Delete to Hard BOL.sublime-macro"},
+ "context": [{"key": "setting.readline_input_widget"}]
+ }
+]
View
@@ -1,6 +1,7 @@
import os.path, re, subprocess
import sublime, sublime_plugin
from functools import partial
+from sublime_readline import show_input_panel_with_readline
def cwd_for_window(window):
"""
@@ -71,10 +72,14 @@ class ShellPromptCommand(sublime_plugin.WindowCommand):
Prompt the user for a shell command to run the the window's directory
"""
def run(self):
+ if not hasattr(self, 'cmd_history'):
+ self.cmd_history = []
cwd = cwd_for_window(self.window)
on_done = partial(exec_cmd, self.window, cwd)
- view = self.window.show_input_panel(abbreviate_user(cwd) + " $", "",
- on_done, None, None)
+ view = show_input_panel_with_readline(self.window,
+ abbreviate_user(cwd) + " $",
+ self.cmd_history,
+ on_done, None, None)
for (setting, value) in settings().get('input_widget').iteritems():
view.settings().set(setting, value)
View
@@ -0,0 +1,38 @@
+# Adds some GNU readline-like features to an input widget
+
+import sublime_plugin
+from functools import partial
+
+active_input_row = -1
+
+def callback_with_history(callback, cmd_history, input_text):
+ if callback:
+ cmd = input_text.split("\n")[active_input_row]
+ if cmd in cmd_history:
+ cmd_history.remove(cmd)
+ cmd_history.append(cmd)
+ return callback(cmd)
+
+def show_input_panel_with_readline(window, caption, cmd_history,
+ on_done, on_change, on_cancel):
+ global active_input_row
+ active_input_row = -1
+ view = window.show_input_panel(caption, u"\n".join(cmd_history) + u"\n",
+ partial(callback_with_history, on_done, cmd_history),
+ on_change, on_cancel)
+ view.settings().set('readline_input_widget', True)
+ view.show(view.size())
+ return view
+
+class ReadlineHistoryChange(sublime_plugin.TextCommand):
+ def run_(self, args):
+ # Override default run_ so that an edit isn't created.
+ if 'event' in args:
+ del args['event']
+ return self.run(**args)
+
+ def run(self, movement, movement_args):
+ self.view.run_command(movement, movement_args)
+ self.view.run_command("move_to", {"to": "eol", "extend": False})
+ global active_input_row
+ active_input_row, _ = self.view.rowcol(self.view.sel()[0].b)

0 comments on commit bfabb07

Please sign in to comment.