Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c628a06

Browse files
author
Steven M. Gava
committed
further work on keybinding configuration
1 parent 68d7336 commit c628a06

3 files changed

Lines changed: 123 additions & 15 deletions

File tree

Lib/idlelib/configDialog.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ def LoadKeyCfg(self):
583583
self.optMenuKeysBuiltin.SetMenu(itemList,itemList[0])
584584
self.SetKeysType()
585585
##load keyset element list
586-
keySet=idleConf.GetKeys(currentOption)
586+
keySet=idleConf.GetCurrentKeySet()
587587
bindNames=keySet.keys()
588588
bindNames.sort()
589589
for bindName in bindNames:
@@ -595,8 +595,7 @@ def GetNewKeys(self):
595595
listIndex=self.listBindings.index(ANCHOR)
596596
binding=self.listBindings.get(listIndex)
597597
bindName=binding.split()[0] #first part, up to first space
598-
currentKeySet=idleConf.CurrentKeys()
599-
currentKeySequences=idleConf.GetKeys(currentKeySet).values()
598+
currentKeySequences=idleConf.GetCurrentKeySet().values()
600599
newKeys=GetKeysDialog(self,'Get New Keys',bindName,currentKeySequences)
601600
if newKeys.result: #new keys were specified
602601
self.listBindings.delete(listIndex)

Lib/idlelib/configHandler.py

Lines changed: 95 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ def GetSectionList(self, configSet, configType):
153153
cfgParser=self.defaultCfg[configType]
154154
else:
155155
raise 'Invalid configSet specified'
156-
157156
return cfgParser.sections()
158157

159158
def GetHighlight(self, theme, element, fgBg=None):
@@ -215,8 +214,10 @@ def GetExtensions(self, activeOnly=1):
215214
Gets a list of all idle extensions declared in the config files.
216215
activeOnly - boolean, if true only return active (enabled) extensions
217216
"""
218-
extns=self.GetSectionList('default','extensions')
219-
userExtns=self.GetSectionList('user','extensions')
217+
extns=self.RemoveKeyBindNames(
218+
self.GetSectionList('default','extensions'))
219+
userExtns=self.RemoveKeyBindNames(
220+
self.GetSectionList('user','extensions'))
220221
for extn in userExtns:
221222
if extn not in extns: #user has added own extension
222223
extns.append(extn)
@@ -230,6 +231,75 @@ def GetExtensions(self, activeOnly=1):
230231
else:
231232
return extns
232233

234+
def RemoveKeyBindNames(self,extnNameList):
235+
#get rid of keybinding section names
236+
names=extnNameList
237+
kbNameIndicies=[]
238+
for name in names:
239+
if name.endswith('_bindings') or name.endswith('_cfgBindings'):
240+
kbNameIndicies.append(names.index(name))
241+
kbNameIndicies.sort()
242+
kbNameIndicies.reverse()
243+
for index in kbNameIndicies: #delete each keybinding section name
244+
del(names[index])
245+
return names
246+
247+
def GetExtensionKeys(self,extensionName):
248+
"""
249+
returns a dictionary of the configurable keybindings for a particular
250+
extension,as they exist in the dictionary returned by GetCurrentKeySet;
251+
that is, where previously re-used bindings are disabled.
252+
"""
253+
keysName=extensionName+'_cfgBindings'
254+
activeKeys=self.GetCurrentKeySet()
255+
extKeys={}
256+
if self.defaultCfg['extensions'].has_section(keysName):
257+
eventNames=self.defaultCfg['extensions'].GetOptionList(keysName)
258+
for eventName in eventNames:
259+
event='<<'+eventName+'>>'
260+
binding=activeKeys[event]
261+
extKeys[event]=binding
262+
return extKeys
263+
264+
def __GetRawExtensionKeys(self,extensionName):
265+
"""
266+
returns a dictionary of the configurable keybindings for a particular
267+
extension, as defined in the configuration files, or an empty dictionary
268+
if no bindings are found
269+
"""
270+
keysName=extensionName+'_cfgBindings'
271+
extKeys={}
272+
if self.defaultCfg['extensions'].has_section(keysName):
273+
eventNames=self.defaultCfg['extensions'].GetOptionList(keysName)
274+
for eventName in eventNames:
275+
binding=self.GetOption('extensions',keysName,
276+
eventName,default='').split()
277+
event='<<'+eventName+'>>'
278+
extKeys[event]=binding
279+
return extKeys
280+
281+
def GetExtensionBindings(self,extensionName):
282+
"""
283+
Returns a dictionary of all the event bindings for a particular
284+
extension. The configurable keybindings are returned as they exist in
285+
the dictionary returned by GetCurrentKeySet; that is, where re-used
286+
keybindings are disabled.
287+
"""
288+
bindsName=extensionName+'_bindings'
289+
extBinds=self.GetExtensionKeys(extensionName)
290+
#add the non-configurable bindings
291+
if self.defaultCfg['extensions'].has_section(bindsName):
292+
eventNames=self.defaultCfg['extensions'].GetOptionList(bindsName)
293+
for eventName in eventNames:
294+
binding=self.GetOption('extensions',bindsName,
295+
eventName,default='').split()
296+
event='<<'+eventName+'>>'
297+
extBinds[event]=binding
298+
299+
return extBinds
300+
301+
302+
233303
def GetKeyBinding(self, keySetName, eventStr):
234304
"""
235305
returns the keybinding for a specific event.
@@ -241,12 +311,31 @@ def GetKeyBinding(self, keySetName, eventStr):
241311
binding=self.GetOption('keys',keySetName,eventName,default='').split()
242312
return binding
243313

244-
def GetKeys(self, keySetName=None):
314+
def GetCurrentKeySet(self):
315+
"""
316+
Returns a dictionary of: all current core keybindings, plus the
317+
keybindings for all currently active extensions. If a binding defined
318+
in an extension is already in use, that binding is disabled.
319+
"""
320+
currentKeySet=self.GetCoreKeys(keySetName=self.CurrentKeys())
321+
activeExtns=self.GetExtensions(activeOnly=1)
322+
for extn in activeExtns:
323+
extKeys=self.__GetRawExtensionKeys(extn)
324+
if extKeys: #the extension defines keybindings
325+
for event in extKeys.keys():
326+
if extKeys[event] in currentKeySet.values():
327+
#the binding is already in use
328+
extKeys[event]='' #disable this binding
329+
currentKeySet[event]=extKeys[event] #add binding
330+
return currentKeySet
331+
332+
def GetCoreKeys(self, keySetName=None):
245333
"""
246-
returns the requested set of keybindings, with fallbacks if required.
334+
returns the requested set of core keybindings, with fallbacks if
335+
required.
247336
"""
248337
#keybindings loaded from the config file(s) are loaded _over_ these
249-
#defaults, so if there is a problem getting any binding there will
338+
#defaults, so if there is a problem getting any core binding there will
250339
#be an 'ultimate last resort fallback' to the CUA-ish bindings
251340
#defined here.
252341
keyBindings={

Lib/idlelib/keybindingDialog.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,10 @@ def BuildKeyString(self):
161161
keyList=keyList+modifiers
162162
if finalKey:
163163
if (not modifiers) and (finalKey in self.functionKeys):
164-
finalKey='<'+finalKey
164+
finalKey='<'+self.TranslateKey(finalKey)
165+
else:
166+
finalKey=self.TranslateKey(finalKey)
165167
keyList.append(finalKey+'>')
166-
167168
keyStr=string.join(keyList,'-')
168169
self.keyString.set(keyStr)
169170

@@ -189,15 +190,34 @@ def LoadFinalKeyList(self):
189190
#these tuples are also available for use in validity checks
190191
self.functionKeys=('F1','F2','F2','F4','F5','F6','F7','F8','F9',
191192
'F10','F11','F12')
192-
self.punctuationKeys=tuple('~!@#%^&*()_-+={}[]|;:,./?')
193-
self.specialKeys=('tab','space')
194193
self.alphanumKeys=tuple(string.ascii_lowercase+string.digits)
194+
self.punctuationKeys=tuple('~!@#%^&*()_-+={}[]|;:,.<>/?')
195+
self.whitespaceKeys=('Tab','Space','Return')
196+
self.editKeys=('BackSpace','Delete','Insert')
197+
self.moveKeys=('Home','End','Page Up','Page Down','Left Arrow',
198+
'Right Arrow','Up Arrow','Down Arrow')
195199
#make a tuple of most of the useful common 'final' keys
196-
keys=(self.alphanumKeys+self.punctuationKeys+self.specialKeys+
197-
self.functionKeys)
200+
keys=(self.alphanumKeys+self.punctuationKeys+self.functionKeys+
201+
self.whitespaceKeys+self.editKeys+self.moveKeys)
198202
apply(self.listKeysFinal.insert,
199203
(END,)+keys)
200204

205+
def TranslateKey(self,key):
206+
#translate from key list value to tkinter key-id
207+
translateDict={'~':'asciitilde','!':'exclam','@':'at','#':'numbersign',
208+
'%':'percent','^':'asciicircum','&':'ampersand','*':'asterisk',
209+
'(':'parenleft',')':'parenright','_':'underscore','-':'minus',
210+
'+':'plus','=':'equal','{':'braceleft','}':'braceright',
211+
'[':'bracketleft',']':'bracketright','|':'bar',';':'semicolon',
212+
':':'colon',',':'comma','.':'period','<':'less','>':'greater',
213+
'/':'slash','?':'question','Page Up':'Prior','Page Down':'Next',
214+
'Left Arrow':'Left','Right Arrow':'Right','Up Arrow':'Up',
215+
'Down Arrow': 'Down'}
216+
if key in translateDict.keys():
217+
key=translateDict[key]
218+
key='Key-'+key
219+
return key
220+
201221
def Ok(self, event=None):
202222
if self.KeysOk():
203223
self.result=self.keyString.get()

0 commit comments

Comments
 (0)