Allow combining multiple independent actions into a single shortcut

Fixes #128
This commit is contained in:
Kovid Goyal 2017-10-20 12:31:36 +05:30
parent e8a1ada5bf
commit efc8b898f8
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 45 additions and 15 deletions

View File

@ -29,3 +29,5 @@ version 0.4.0 [future]
- The block cursor in now fully opaque but renders the character under it in
the background color, for enhanced visibility.
- Allow combining multiple independent actions into a single shortcut

View File

@ -168,11 +168,15 @@ class Boss:
def dispatch_special_key(self, key, scancode, action, mods):
# Handles shortcuts, return True if the key was consumed
action = get_shortcut(self.opts.keymap, mods, key, scancode)
if action is not None:
f = getattr(self, action.func, None)
key_action = get_shortcut(self.opts.keymap, mods, key, scancode)
self.current_key_press_info = key, scancode, action, mods
return self.dispatch_action(key_action)
def dispatch_action(self, key_action):
if key_action is not None:
f = getattr(self, key_action.func, None)
if f is not None:
passthrough = f(*action.args)
passthrough = f(*key_action.args)
if passthrough is not True:
return True
tab = self.active_tab
@ -181,12 +185,13 @@ class Boss:
window = self.active_window
if window is None:
return False
if action is not None:
f = getattr(tab, action.func, getattr(window, action.func, None))
if key_action is not None:
f = getattr(tab, key_action.func, getattr(window, key_action.func, None))
if f is not None:
passthrough = f(*action.args)
passthrough = f(*key_action.args)
if passthrough is not True:
return True
key, scancode, action, mods = self.current_key_press_info
data = get_sent_data(
self.opts.send_text_map, key, scancode, mods, window, action
)
@ -195,6 +200,10 @@ class Boss:
return True
return False
def combine(self, *actions):
for key_action in actions:
self.dispatch_action(key_action)
def on_focus(self, window, focused):
self.window_is_focused = focused
w = self.active_window

View File

@ -98,12 +98,15 @@ KeyAction = namedtuple('KeyAction', 'func args')
def parse_key_action(action):
parts = action.split(' ', 1)
func = parts[0]
if len(parts) == 1:
return KeyAction(parts[0], ())
safe_print(
'Invalid shortcut action: {}. Ignoring.'.format(action),
file=sys.stderr
)
return KeyAction(func, ())
rest = parts[1]
if func == 'combine':
sep, rest = rest.split(' ', 1)
parts = re.split(r'\s*' + re.escape(sep) + r'\s*', rest)
args = tuple(map(parse_key_action, parts))
return KeyAction(func, args)
def parse_key(val, keymap):
@ -118,7 +121,14 @@ def parse_key(val, keymap):
file=sys.stderr
)
return
try:
paction = parse_key_action(action)
except Exception:
safe_print(
'Invalid shortcut action: {}. Ignoring.'.format(action),
file=sys.stderr
)
else:
if paction is not None:
keymap[(mods, key)] = paction

View File

@ -198,11 +198,20 @@ color14 #14ffff
color7 #dddddd
color15 #ffffff
# Key mapping
# For a list of key names, see: http://www.glfw.org/docs/latest/group__keys.html
# For a list of modifier names, see: http://www.glfw.org/docs/latest/group__mods.html
#
# You can use the special action no_op to unmap a keyboard shortcut that is
# assigned in the default configuration.
#
# You can combine multiple actions to be triggered by a single shortcut, using the
# syntax below:
# map key combine <separator> action1 <separator> action2 <separator> action3 ...
# For example:
map ctrl+shift+e combine : new_window : next_layout
# this will create a new window and switch to the next available layout
# Clipboard
map ctrl+shift+v paste_from_clipboard