further work on keybinding configuration
diff --git a/Lib/idlelib/configDialog.py b/Lib/idlelib/configDialog.py
index 2b13391..42df594 100644
--- a/Lib/idlelib/configDialog.py
+++ b/Lib/idlelib/configDialog.py
@@ -583,7 +583,7 @@
             self.optMenuKeysBuiltin.SetMenu(itemList,itemList[0])
         self.SetKeysType()   
         ##load keyset element list
-        keySet=idleConf.GetKeys(currentOption)
+        keySet=idleConf.GetCurrentKeySet()
         bindNames=keySet.keys()
         bindNames.sort()
         for bindName in bindNames: 
@@ -595,8 +595,7 @@
         listIndex=self.listBindings.index(ANCHOR)
         binding=self.listBindings.get(listIndex)
         bindName=binding.split()[0] #first part, up to first space
-        currentKeySet=idleConf.CurrentKeys()
-        currentKeySequences=idleConf.GetKeys(currentKeySet).values()
+        currentKeySequences=idleConf.GetCurrentKeySet().values()
         newKeys=GetKeysDialog(self,'Get New Keys',bindName,currentKeySequences)
         if newKeys.result: #new keys were specified
             self.listBindings.delete(listIndex)
diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py
index b78ae75..34be897 100644
--- a/Lib/idlelib/configHandler.py
+++ b/Lib/idlelib/configHandler.py
@@ -153,7 +153,6 @@
             cfgParser=self.defaultCfg[configType]
         else:
             raise 'Invalid configSet specified'
-        
         return cfgParser.sections()
     
     def GetHighlight(self, theme, element, fgBg=None):
@@ -215,8 +214,10 @@
         Gets a list of all idle extensions declared in the config files.
         activeOnly - boolean, if true only return active (enabled) extensions
         """
-        extns=self.GetSectionList('default','extensions')
-        userExtns=self.GetSectionList('user','extensions')
+        extns=self.RemoveKeyBindNames(
+                self.GetSectionList('default','extensions'))
+        userExtns=self.RemoveKeyBindNames(
+                self.GetSectionList('user','extensions'))
         for extn in userExtns:
             if extn not in extns: #user has added own extension
                 extns.append(extn) 
@@ -230,6 +231,75 @@
         else:
             return extns        
 
+    def RemoveKeyBindNames(self,extnNameList):
+        #get rid of keybinding section names
+        names=extnNameList
+        kbNameIndicies=[]
+        for name in names:
+            if name.endswith('_bindings') or name.endswith('_cfgBindings'): 
+                    kbNameIndicies.append(names.index(name))
+        kbNameIndicies.sort()
+        kbNameIndicies.reverse()
+        for index in kbNameIndicies: #delete each keybinding section name    
+            del(names[index])
+        return names
+        
+    def GetExtensionKeys(self,extensionName):
+        """
+        returns a dictionary of the configurable keybindings for a particular
+        extension,as they exist in the dictionary returned by GetCurrentKeySet;
+        that is, where previously re-used bindings are disabled.
+        """
+        keysName=extensionName+'_cfgBindings'
+        activeKeys=self.GetCurrentKeySet()
+        extKeys={}
+        if self.defaultCfg['extensions'].has_section(keysName):
+            eventNames=self.defaultCfg['extensions'].GetOptionList(keysName)
+            for eventName in eventNames:
+                event='<<'+eventName+'>>'
+                binding=activeKeys[event]
+                extKeys[event]=binding
+        return extKeys 
+        
+    def __GetRawExtensionKeys(self,extensionName):
+        """
+        returns a dictionary of the configurable keybindings for a particular
+        extension, as defined in the configuration files, or an empty dictionary
+        if no bindings are found
+        """
+        keysName=extensionName+'_cfgBindings'
+        extKeys={}
+        if self.defaultCfg['extensions'].has_section(keysName):
+            eventNames=self.defaultCfg['extensions'].GetOptionList(keysName)
+            for eventName in eventNames:
+                binding=self.GetOption('extensions',keysName,
+                        eventName,default='').split()
+                event='<<'+eventName+'>>'
+                extKeys[event]=binding
+        return extKeys 
+    
+    def GetExtensionBindings(self,extensionName):
+        """
+        Returns a dictionary of all the event bindings for a particular
+        extension. The configurable keybindings are returned as they exist in
+        the dictionary returned by GetCurrentKeySet; that is, where re-used 
+        keybindings are disabled.
+        """
+        bindsName=extensionName+'_bindings'
+        extBinds=self.GetExtensionKeys(extensionName)
+        #add the non-configurable bindings
+        if self.defaultCfg['extensions'].has_section(bindsName):
+            eventNames=self.defaultCfg['extensions'].GetOptionList(bindsName)
+            for eventName in eventNames:
+                binding=self.GetOption('extensions',bindsName,
+                        eventName,default='').split()
+                event='<<'+eventName+'>>'
+                extBinds[event]=binding
+        
+        return extBinds 
+        
+    
+    
     def GetKeyBinding(self, keySetName, eventStr):
         """
         returns the keybinding for a specific event.
@@ -241,12 +311,31 @@
         binding=self.GetOption('keys',keySetName,eventName,default='').split()
         return binding
 
-    def GetKeys(self, keySetName=None):
+    def GetCurrentKeySet(self):
         """
-        returns the requested set of keybindings, with fallbacks if required.
+        Returns a dictionary of: all current core keybindings, plus the 
+        keybindings for all currently active extensions. If a binding defined
+        in an extension is already in use, that binding is disabled.
+        """
+        currentKeySet=self.GetCoreKeys(keySetName=self.CurrentKeys())
+        activeExtns=self.GetExtensions(activeOnly=1)
+        for extn in activeExtns:
+            extKeys=self.__GetRawExtensionKeys(extn)
+            if extKeys: #the extension defines keybindings
+                for event in extKeys.keys():
+                    if extKeys[event] in currentKeySet.values():
+                        #the binding is already in use
+                        extKeys[event]='' #disable this binding
+                    currentKeySet[event]=extKeys[event] #add binding
+        return currentKeySet
+    
+    def GetCoreKeys(self, keySetName=None):
+        """
+        returns the requested set of core keybindings, with fallbacks if
+        required.
         """
         #keybindings loaded from the config file(s) are loaded _over_ these
-        #defaults, so if there is a problem getting any binding there will
+        #defaults, so if there is a problem getting any core binding there will
         #be an 'ultimate last resort fallback' to the CUA-ish bindings
         #defined here.
         keyBindings={
diff --git a/Lib/idlelib/keybindingDialog.py b/Lib/idlelib/keybindingDialog.py
index 0958578..c510257 100644
--- a/Lib/idlelib/keybindingDialog.py
+++ b/Lib/idlelib/keybindingDialog.py
@@ -161,9 +161,10 @@
         keyList=keyList+modifiers
         if finalKey: 
             if (not modifiers) and (finalKey in self.functionKeys):
-                finalKey='<'+finalKey
+                finalKey='<'+self.TranslateKey(finalKey)
+            else:
+                finalKey=self.TranslateKey(finalKey)
             keyList.append(finalKey+'>')
-                
         keyStr=string.join(keyList,'-')
         self.keyString.set(keyStr)
         
@@ -189,15 +190,34 @@
         #these tuples are also available for use in validity checks
         self.functionKeys=('F1','F2','F2','F4','F5','F6','F7','F8','F9',
                 'F10','F11','F12')
-        self.punctuationKeys=tuple('~!@#%^&*()_-+={}[]|;:,./?')
-        self.specialKeys=('tab','space')
         self.alphanumKeys=tuple(string.ascii_lowercase+string.digits)
+        self.punctuationKeys=tuple('~!@#%^&*()_-+={}[]|;:,.<>/?')
+        self.whitespaceKeys=('Tab','Space','Return')
+        self.editKeys=('BackSpace','Delete','Insert')
+        self.moveKeys=('Home','End','Page Up','Page Down','Left Arrow',
+                'Right Arrow','Up Arrow','Down Arrow')
         #make a tuple of most of the useful common 'final' keys
-        keys=(self.alphanumKeys+self.punctuationKeys+self.specialKeys+
-                self.functionKeys)
+        keys=(self.alphanumKeys+self.punctuationKeys+self.functionKeys+
+                self.whitespaceKeys+self.editKeys+self.moveKeys)
         apply(self.listKeysFinal.insert,
             (END,)+keys)
     
+    def TranslateKey(self,key):
+        #translate from key list value to tkinter key-id
+        translateDict={'~':'asciitilde','!':'exclam','@':'at','#':'numbersign',
+                '%':'percent','^':'asciicircum','&':'ampersand','*':'asterisk',
+                '(':'parenleft',')':'parenright','_':'underscore','-':'minus',
+                '+':'plus','=':'equal','{':'braceleft','}':'braceright',
+                '[':'bracketleft',']':'bracketright','|':'bar',';':'semicolon',
+                ':':'colon',',':'comma','.':'period','<':'less','>':'greater',
+                '/':'slash','?':'question','Page Up':'Prior','Page Down':'Next',
+                'Left Arrow':'Left','Right Arrow':'Right','Up Arrow':'Up',
+                'Down Arrow': 'Down'}
+        if key in translateDict.keys():
+            key=translateDict[key]
+        key='Key-'+key
+        return key
+    
     def Ok(self, event=None):
         if self.KeysOk():
             self.result=self.keyString.get()