Skip to content

Instantly share code, notes, and snippets.

@sahutd
Created June 13, 2014 14:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sahutd/0a471db8138383fd73b2 to your computer and use it in GitHub Desktop.
Save sahutd/0a471db8138383fd73b2 to your computer and use it in GitHub Desktop.
from itertools import permutations
from tkinter import Tk
from _tkinter import TclError
from idlelib.keybindingDialog import is_keyseq_valid
modifiers = ['Shift', 'Control', 'Alt', 'Meta']
alpha_uppercase_key = ['Key-A']
alpha_lowercase_key = ['Key-a']
alpha_uppercase = ['A']
alpha_lowercase = ['a']
direction = ['Up']
direction_key = ['Key-Up']
if __name__ == '__main__':
root = Tk()
invalid = []
valid = []
l = modifiers + alpha_lowercase_key + \
alpha_uppercase_key + direction + direction_key + \
alpha_lowercase + alpha_uppercase
for i in (2,3,4):
perm = permutations(l, i)
for _ in perm:
keyseq = '-'.join(_)
keyseq = '<' + keyseq + '>'
try:
root.bind(keyseq, lambda e: "break")
valid.append(keyseq)
except TclError:
invalid.append(keyseq)
assert False == is_keyseq_valid('<Shift-Up-Key-a>')
assert False == is_keyseq_valid('<Key-a-Shift-Control>')
assert False == is_keyseq_valid('<Up-Shift-Key-a>')
assert False == is_keyseq_valid('<Up-Key-a>')
assert True == is_keyseq_valid('<Alt-Key-Up>')
assert False == is_keyseq_valid('<Alt-Key-up>')
assert False == is_keyseq_valid('<Shift-Key-Up-Control>')
assert False == is_keyseq_valid('<Shift-Key-Up-Up>')
assert True == is_keyseq_valid('<Control-Key-a>')
assert True == is_keyseq_valid('<Control-Key-A>')
assert True == is_keyseq_valid('<Control-a>')
assert True == is_keyseq_valid('<Control-A>')
assert False == is_keyseq_valid('<Shift-Key-Up-a>')
assert False == is_keyseq_valid('<Up-Shift-a>')
assert False == is_keyseq_valid('<a-Shift-Key-a>')
assert False == is_keyseq_valid('<a-Shift-A>')
assert False == is_keyseq_valid('<Key-b-Key-B>')
assert False == is_keyseq_valid('<Key-B-Key-b>')
assert True == is_keyseq_valid('<Shift-Control-Alt-Key-a>')
assert True == is_keyseq_valid('<Shift-Control-Alt-Up>')
assert True == is_keyseq_valid('<Shift-Control-Key-a>')
assert False == is_keyseq_valid('<Up-Shift-Control-Key-a>')
assert True == is_keyseq_valid('<Shift-Up>')
print(len(valid) + len(invalid)) # == 10p2 + 10p3 + 10p4, 10 = length of list 'l'
for i in invalid:
assert False == is_keyseq_valid(i)
for i in valid:
assert True == is_keyseq_valid(i)
diff -r bec6f18dd636 Lib/idlelib/keybindingDialog.py
--- a/Lib/idlelib/keybindingDialog.py Thu Jun 12 23:36:33 2014 +0100
+++ b/Lib/idlelib/keybindingDialog.py Fri Jun 13 19:59:14 2014 +0530
@@ -261,6 +261,205 @@
keysOK = True
return keysOK
+def is_keyseq_valid(keyseq):
+ modifiers = ['Shift', 'Control', 'Alt', 'Meta']
+
+ direction = ['Up']
+ key_direction = ['Key-Up']
+
+ modifier_regex = '(' + ')|('.join(modifiers) + ')'
+ direction_regex = '(' + ')|('.join(direction) + ')'
+ modifer_direction_regex = modifier_regex + '|' + direction_regex
+ key_alpha_regex = 'Key-(?P<test>[A-z])'
+ alpha_regex = '[A-z]'
+ key_direction_regex = '(' + ')|('.join(key_direction) + ')'
+ keyseq = keyseq[1:-1]
+
+ # some dont bother conditions to make parsing easier
+ # starts with Key
+ if keyseq.startswith('Key'):
+ return False
+
+ # starts with alpha
+ pat = '^'+alpha_regex+'-'
+ p = re.search(pat, keyseq)
+ if p:
+ return False
+
+
+ # prefixKey-a-Key-Asuffix
+ pat = 'Key-[A-z]-Key-[A-z]'
+ p = re.search(pat, keyseq)
+ if p:
+ return False
+ pat = key_direction_regex + '-' + direction_regex
+ p = re.search(pat, keyseq)
+ if p:
+ return False
+ pat = key_direction_regex + '-' + alpha_regex + '$'
+ p = re.search(pat, keyseq)
+ if p:
+ return False
+
+ #starts with direction
+ pat = '^' + direction_regex + '-'
+ p = re.search(pat, keyseq)
+ if p:
+ return False
+
+
+ # prefixKey-a-a
+ pat = 'Key-[A-z]-[A-z]'
+ p = re.search(pat, keyseq)
+ if p:
+ return False
+
+ # ends with modifier
+ pat = '(' + modifier_regex + ')' + '$'
+ p = re.search(pat, keyseq)
+ if p:
+ return False
+
+ # modifier-direction/alpha
+ pat = '^(' + modifier_regex + ')-' + direction_regex + '$'
+ p = re.search(pat, keyseq)
+ if p:
+ return True
+
+ # modifier-modifier-direction/alpha
+ pat = '(' + modifier_regex + ')-'
+ pat = pat*2 + '(('+direction_regex +')|(' + alpha_regex + '))$'
+ p = re.search(pat, keyseq)
+ if p:
+ return True
+
+ #(modifier/direction)-(modifier/direction)-(modifier/direction)
+ if set(keyseq.split('-')).issubset(modifiers):
+ if set(keyseq.split('-')).issubset(modifiers + direction):
+ return False
+
+ #(modifier)-(modifier)-(modifier)-(keyalpha/direction)
+ pat = '(' + modifier_regex + ')' + '-'
+ pat = pat * 3 + '((' + key_alpha_regex + ')|(' + direction_regex + ')|(' + alpha_regex +'))'
+ p = re.search(pat, keyseq)
+ if p:
+ return True
+ #(modifier/direction)-alpha-(modifier/direction)
+ p = re.search('(' + modifer_direction_regex + ')-' + key_alpha_regex +
+ '-(' + modifer_direction_regex + ')', keyseq, flags=re.IGNORECASE)
+ try:
+ l = p.group('test')
+ if l and l in string.ascii_letters:
+ return False
+ except AttributeError:
+ pass
+
+ #(modifier)-(direction)-keyalpha
+ pat = '(' + modifier_regex + ')' + '-' + \
+ direction_regex + '-' + key_alpha_regex
+ p = re.search(pat, keyseq, flags=re.IGNORECASE)
+ try:
+ l = p.group('test')
+ if l and l in string.ascii_letters:
+ return False
+ except:
+ pass
+
+ # alpha-modifier-modifer
+ pat = key_alpha_regex + '-(' + modifer_direction_regex + ')'
+ p = re.search(pat, keyseq, flags=re.IGNORECASE)
+ try:
+ l = p.group('test')
+ if l and l in string.ascii_letters:
+ return False
+ except:
+ pass
+
+ # direction-modifier-alpha
+ pat = direction_regex + '-(' + modifier_regex + ')-' + key_alpha_regex
+ p = re.search(pat, keyseq, flags=re.IGNORECASE)
+ try:
+ l = p.group('test')
+ if l and l in string.ascii_letters:
+ return False
+ except:
+ pass
+
+ # direction-alpha
+ pat = direction_regex + '-' + key_alpha_regex
+ p = re.search(pat, keyseq, flags=re.IGNORECASE)
+ try:
+ l = p.group('test')
+ if l and l in string.ascii_letters:
+ return False
+ except:
+ pass
+
+ # modifier-modifier-keyalpha
+ pat = '(' + modifier_regex + ')' + '-'
+ pat = pat*2 + key_alpha_regex
+ p = re.search(pat, keyseq)
+ if p:
+ return True
+
+ # alpha-modifier-alphakey
+ pat = alpha_regex + '-' + '(' + modifier_regex + ')-' + key_alpha_regex
+ p = re.search(pat, keyseq)
+ if p:
+ return False
+
+ # modifier-alphakey
+ pat = '(' + modifier_regex + ')-' + key_alpha_regex + '$'
+ p = re.search(pat, keyseq)
+ if p:
+ return True
+
+ # direction-modifier-alpha
+ pat = direction_regex + '-(' + modifier_regex + ')-' + alpha_regex
+ p = re.search(pat, keyseq)
+ if p:
+ return False
+
+ # alpha-modifier-alpha
+ pat = alpha_regex + '-(' + modifier_regex + ')-' + alpha_regex
+ p = re.search(pat, keyseq)
+ if p:
+ return False
+
+ # modifier-alpha
+ pat = '(' + modifier_regex + ')-' + alpha_regex + '$'
+ p = re.search(pat, keyseq)
+ if p:
+ return True
+
+ # modifier-directionkey
+ pat = '(' + modifier_regex + ')-' + key_direction_regex
+ p = re.search(pat, keyseq)
+ if not p:
+ return False
+
+ # modifier-directionkey-modifier
+ pat = '(' + modifier_regex + ')-' + \
+ key_direction_regex + '-(' + modifier_regex + ')'
+ p = re.search(pat, keyseq)
+ if p:
+ return False
+
+ # modifier-directionkey-direction
+ pat = '(' + modifier_regex + ')-' + \
+ key_direction_regex + '-(' + direction_regex + ')'
+ p = re.search(pat, keyseq)
+ if p:
+ return False
+
+ # modifier-directionkey-alpha
+ pat = '(' + modifier_regex + ')-' + key_direction_regex + '-' + alpha_regex
+ p = re.search(pat, keyseq)
+ if p:
+ return False
+
+ return True
+
if __name__ == '__main__':
from idlelib.idle_test.htest import run
run(GetKeysDialog)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment