aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples/data/uzbl/plugins/keycmd.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/data/uzbl/plugins/keycmd.py')
-rw-r--r--examples/data/uzbl/plugins/keycmd.py213
1 files changed, 98 insertions, 115 deletions
diff --git a/examples/data/uzbl/plugins/keycmd.py b/examples/data/uzbl/plugins/keycmd.py
index 3dd6f37..79a96e4 100644
--- a/examples/data/uzbl/plugins/keycmd.py
+++ b/examples/data/uzbl/plugins/keycmd.py
@@ -57,12 +57,22 @@ class Keylet(object):
self._to_string = None
self.modcmd = False
- self.wasmod = False
+
+ def mod_held(self):
+ ''' returns true if any modkey is held. '''
+ return any([len(x) != 1 for x in self.held])
+
+ def key_cmd(self):
+ ''' get the keycmd-part of the keylet. '''
+ return self.cmd
+
+ def mod_cmd(self):
+ ''' get the modcmd-part of the keylet. '''
+ return ''.join(['<%s>' % key for key in self.held])
def __repr__(self):
return '<Keycmd(%r)>' % self.to_string()
-
def to_string(self):
'''Return a string representation of the keys held and pressed that
have been recorded.'''
@@ -70,15 +80,8 @@ class Keylet(object):
if self._to_string is not None:
# Return cached keycmd string.
return self._to_string
-
- if not self.held:
- self._to_string = self.cmd
-
- else:
- self._to_string = ''.join(['<%s>' % key for key in self.held])
- if self.cmd:
- self._to_string += self.cmd
-
+
+ self._to_string = self.mod_cmd() + self.key_cmd()
return self._to_string
@@ -135,10 +138,7 @@ def clear_keycmd(uzbl):
k.cursor = 0
k._to_string = None
- if k.modcmd:
- k.wasmod = True
-
- k.modcmd = False
+ k.modcmd = k.mod_held()
config = uzbl.get_config()
if 'keycmd' not in config or config['keycmd'] != '':
config['keycmd'] = ''
@@ -146,13 +146,14 @@ def clear_keycmd(uzbl):
uzbl.event('KEYCMD_CLEAR')
-def update_event(uzbl, k):
+def update_event(uzbl, k, execute=True):
'''Raise keycmd & modcmd update events.'''
config = uzbl.get_config()
if k.modcmd:
keycmd = k.to_string()
- uzbl.event('MODCMD_UPDATE', k)
+ if execute:
+ uzbl.event('MODCMD_UPDATE', k)
if keycmd != k.to_string():
return
@@ -165,7 +166,8 @@ def update_event(uzbl, k):
return
keycmd = k.cmd
- uzbl.event('KEYCMD_UPDATE', k)
+ if execute:
+ uzbl.event('KEYCMD_UPDATE', k)
if keycmd != k.cmd:
return
@@ -187,19 +189,10 @@ def key_press(uzbl, key):
'''Handle KEY_PRESS events. Things done by this function include:
1. Ignore all shift key presses (shift can be detected by capital chars)
- 2. Re-enable modcmd var if the user presses another key with at least one
- modkey still held from the previous modcmd (I.e. <Ctrl>+t, clear &
- <Ctrl>+o without having to re-press <Ctrl>)
3. In non-modcmd mode:
- a. BackSpace deletes the character before the cursor position.
- b. Delete deletes the character at the cursor position.
- c. End moves the cursor to the end of the keycmd.
- d. Home moves the cursor to the beginning of the keycmd.
- e. Return raises a KEYCMD_EXEC event then clears the keycmd.
- f. Escape clears the keycmd.
- 4. If keycmd and held keys are both empty/null and a modkey was pressed
- set modcmd mode.
- 5. If in modcmd mode only mod keys are added to the held keys list.
+ a. append char to keycmd
+ 4. If not in modcmd mode and a modkey was pressed set modcmd mode.
+ 5. If in modcmd mode the pressed key is added to the held keys list.
6. Keycmd is updated and events raised if anything is changed.'''
if key.startswith('Shift_'):
@@ -210,82 +203,17 @@ def key_press(uzbl, key):
k = get_keylet(uzbl)
cmdmod = False
- if k.held and k.wasmod:
- k.modcmd = True
- k.wasmod = False
- cmdmod = True
- if k.cmd and key == 'Space':
+ if k.cmd and not k.modcmd and key == 'Space':
k.cmd = "%s %s" % (k.cmd[:k.cursor], k.cmd[k.cursor:])
k.cursor += 1
cmdmod = True
- elif not k.modcmd and k.cmd and key in ['BackSpace', 'Delete']:
- if key == 'BackSpace' and k.cursor > 0:
- k.cursor -= 1
- k.cmd = k.cmd[:k.cursor] + k.cmd[k.cursor+1:]
-
- elif key == 'Delete':
- cmd = k.cmd
- k.cmd = k.cmd[:k.cursor] + k.cmd[k.cursor+1:]
- if k.cmd != cmd:
- cmdmod = True
-
- if not k.cmd:
- clear_keycmd(uzbl)
-
- elif key == 'BackSpace':
- cmdmod = True
-
- elif not k.modcmd and key == 'Return':
- if k.cmd:
- uzbl.event('KEYCMD_EXEC', k)
-
- clear_keycmd(uzbl)
-
- elif not k.modcmd and key == 'Escape':
- clear_keycmd(uzbl)
-
- elif not k.modcmd and k.cmd and key == 'Left':
- if k.cursor > 0:
- k.cursor -= 1
- cmdmod = True
-
- elif not k.modcmd and k.cmd and key == 'Right':
- if k.cursor < len(k.cmd):
- k.cursor += 1
- cmdmod = True
-
- elif not k.modcmd and k.cmd and key == 'End':
- if k.cursor != len(k.cmd):
- k.cursor = len(k.cmd)
- cmdmod = True
-
- elif not k.modcmd and k.cmd and key == 'Home':
- if k.cursor:
- k.cursor = 0
- cmdmod = True
-
- elif not k.held and not k.cmd and len(key) > 1:
+ elif len(key) > 1:
k.modcmd = True
- k.held.append(key)
- cmdmod = True
-
- elif k.modcmd:
cmdmod = True
- if len(key) > 1:
- if key == 'Shift-Tab' and 'Tab' in k.held:
- k.held.remove('Tab')
-
- if key not in k.held:
- k.held.append(key)
- k.held.sort()
- else:
- k.cmd = "%s%s%s" % (k.cmd[:k.cursor], key, k.cmd[k.cursor:])
- k.cursor += 1
-
- else:
+ elif not k.modcmd:
config = uzbl.get_config()
if 'keycmd_events' not in config or config['keycmd_events'] == '1':
if len(key) == 1:
@@ -298,6 +226,15 @@ def key_press(uzbl, key):
k.cmd = ''
k.cursor = 0
+ if k.modcmd:
+ if key == 'Shift-Tab' and 'Tab' in k.held:
+ k.held.remove('Tab')
+
+ if key not in k.held:
+ k.held.append(key)
+ k.held.sort()
+ cmdmod = True
+
if cmdmod:
update_event(uzbl, k)
@@ -306,10 +243,8 @@ def key_release(uzbl, key):
'''Respond to KEY_RELEASE event. Things done by this function include:
1. Remove the key from the keylet held list.
- 2. If the key removed was a mod key and it was in a mod-command then
- raise a MODCMD_EXEC event then clear the keycmd.
- 3. Stop trying to restore mod-command status with wasmod if both the
- keycmd and held list are empty/null.
+ 2. If in a mod-command then raise a MODCMD_EXEC.
+ 3. Check if any modkey is held, if so set modcmd mode.
4. Update the keycmd uzbl variable if anything changed.'''
if len(key) > 1:
@@ -325,15 +260,12 @@ def key_release(uzbl, key):
key = 'Meta'
if key in k.held:
+ cmdmod = True
+ k.held.remove(key)
+ k.modcmd = k.mod_held()
if k.modcmd:
uzbl.event('MODCMD_EXEC', k)
- k.held.remove(key)
- clear_keycmd(uzbl)
-
- if not k.held and not k.cmd and k.wasmod:
- k.wasmod = False
-
if cmdmod:
update_event(uzbl, k)
@@ -342,22 +274,70 @@ def set_keycmd(uzbl, keycmd):
'''Allow setting of the keycmd externally.'''
k = get_keylet(uzbl)
- k.wasmod = k.modcmd = False
+ k.modcmd = False
k._to_string = None
k.cmd = keycmd
k.cursor = len(keycmd)
- update_event(uzbl, k)
+
+ update_event(uzbl, k, False)
+
+
+def keycmd_strip_word(uzbl, sep):
+ ''' Removes the last word from the keycmd, similar to readline ^W '''
+ sep = sep or ' '
+ k = get_keylet(uzbl)
+ if not k.cmd:
+ return
+
+ cmd = k.cmd[:k.cursor]
+ tail = len(k.cmd) - k.cursor
+
+ if sep in cmd:
+ tmp = cmd.rstrip(sep).rsplit(sep, 1)
+ else:
+ tmp = ('',)
+
+ k.cmd = tmp[0] + (sep if len(tmp) == 2 else '') + k.cmd[k.cursor:]
+ k.cursor = len(tmp[0]) + (len(tmp) - 1)
+
+ assert len(k.cmd) - k.cursor == tail, "tail size changed (%s) (%s - %s)" % (tail, len(k.cmd), k.cursor)
+
+ update_event(uzbl, k, False)
+
+
+def keycmd_backspace(uzbl, _foo):
+ ''' Removes the last char of the keycmd '''
+ k = get_keylet(uzbl)
+ if not k.cmd:
+ return
+
+ k.cmd = k.cmd[:k.cursor-1] + k.cmd[k.cursor:]
+ k.cursor -= 1
+
+ update_event(uzbl, k, False)
+
+
+def keycmd_exec_current(uzbl, _foo):
+ ''' Raise a KEYCMD_EXEC with the current keylet and then clear the keycmd '''
+ k = get_keylet(uzbl)
+ uzbl.event('KEYCMD_EXEC', k)
+ clear_keycmd(uzbl)
def set_cursor_pos(uzbl, index):
'''Allow setting of the cursor position externally. Supports negative
- indexing.'''
+ indexing and relative stepping with '+' and '-'.'''
- cursor = int(index.strip())
k = get_keylet(uzbl)
- if cursor < 0:
- cursor = len(k.cmd) + cursor
+ if index == '-':
+ cursor = k.cursor - 1
+ elif index == '+':
+ cursor = k.cursor + 1
+ else:
+ cursor = int(index.strip())
+ if cursor < 0:
+ cursor = len(k.cmd) + cursor + 1
if cursor < 0:
cursor = 0
@@ -366,7 +346,7 @@ def set_cursor_pos(uzbl, index):
cursor = len(k.cmd)
k.cursor = cursor
- update_event(uzbl, k)
+ update_event(uzbl, k, False)
def init(uzbl):
@@ -377,6 +357,9 @@ def init(uzbl):
'KEY_PRESS': key_press,
'KEY_RELEASE': key_release,
'SET_KEYCMD': set_keycmd,
+ 'KEYCMD_STRIP_WORD': keycmd_strip_word,
+ 'KEYCMD_BACKSPACE': keycmd_backspace,
+ 'KEYCMD_EXEC_CURRENT': keycmd_exec_current,
'SET_CURSOR_POS': set_cursor_pos}
uzbl.connect_dict(connects)