blob: a3230cc522baab2e7e4cde53f9194422334ec928 [file] [log] [blame]
Steven M. Gava2a63a072001-10-26 06:50:54 +00001"""
Steven M. Gavaad4f5322002-01-03 12:05:17 +00002Provides access to stored idle configuration information.
Steven M. Gavaad4f5322002-01-03 12:05:17 +00003"""
Steven M. Gavac5976402002-01-04 03:06:08 +00004# Throughout this module there is an emphasis on returning useable defaults
5# when a problem occurs in returning a requested configuration value back to
6# idle. This is to allow idle to continue to function in spite of errors in
7# the retrieval of config information. When a default is returned instead of
8# a requested config value, a message is printed to stderr to aid in
9# configuration problem notification and resolution.
10
Steven M. Gavac11ccf32001-09-24 09:43:17 +000011import os
12import sys
13from ConfigParser import ConfigParser, NoOptionError, NoSectionError
14
15class IdleConfParser(ConfigParser):
16 """
17 A ConfigParser specialised for idle configuration file handling
18 """
19 def __init__(self, cfgFile, cfgDefaults=None):
20 """
21 cfgFile - string, fully specified configuration file name
22 """
23 self.file=cfgFile
24 ConfigParser.__init__(self,defaults=cfgDefaults)
25
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +000026 def Get(self, section, option, type=None, default=None):
Steven M. Gavac11ccf32001-09-24 09:43:17 +000027 """
28 Get an option value for given section/option or return default.
29 If type is specified, return as type.
30 """
Steven M. Gava41a85322001-10-29 08:05:34 +000031 if type=='bool':
32 getVal=self.getboolean
33 elif type=='int':
34 getVal=self.getint
35 else:
36 getVal=self.get
Steven M. Gavac11ccf32001-09-24 09:43:17 +000037 if self.has_option(section,option):
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +000038 #return getVal(section, option, raw, vars, default)
Steven M. Gava429a86a2001-10-23 10:42:12 +000039 return getVal(section, option)
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +000040 else:
41 return default
Steven M. Gavac11ccf32001-09-24 09:43:17 +000042
Steven M. Gavac11ccf32001-09-24 09:43:17 +000043 def GetOptionList(self,section):
44 """
45 Get an option list for given section
46 """
47 if self.has_section:
48 return self.options(section)
49 else: #return a default value
50 return []
51
Steven M. Gavac11ccf32001-09-24 09:43:17 +000052 def Load(self):
53 """
54 Load the configuration file from disk
55 """
56 self.read(self.file)
57
58class IdleUserConfParser(IdleConfParser):
59 """
Steven M. Gava2d7bb3f2002-01-29 08:35:29 +000060 IdleConfigParser specialised for user configuration handling.
Steven M. Gavac11ccf32001-09-24 09:43:17 +000061 """
Steven M. Gava2d7bb3f2002-01-29 08:35:29 +000062
63 def AddSection(self,section):
64 """
65 if section doesn't exist, add it
66 """
67 if not self.has_section(section):
68 self.add_section(section)
69
70 def RemoveEmptySections(self):
71 """
72 remove any sections that have no options
73 """
74 for section in self.sections():
75 if not self.GetOptionList(section):
76 self.remove_section(section)
77
78 def IsEmpty(self):
79 """
80 Remove empty sections and then return 1 if parser has no sections
81 left, else return 0.
82 """
83 self.RemoveEmptySections()
84 if self.sections():
85 return 0
86 else:
87 return 1
88
89 def RemoveOption(self,section,option):
90 """
91 If section/option exists, remove it.
92 Returns 1 if option was removed, 0 otherwise.
93 """
94 if self.has_section(section):
95 return self.remove_option(section,option)
96
97 def SetOption(self,section,option,value):
98 """
99 Sets option to value, adding section if required.
100 Returns 1 if option was added or changed, otherwise 0.
101 """
102 if self.has_option(section,option):
103 if self.get(section,option)==value:
104 return 0
105 else:
106 self.set(section,option,value)
107 return 1
108 else:
109 if not self.has_section(section):
110 self.add_section(section)
111 self.set(section,option,value)
112 return 1
113
Steven M. Gavac11ccf32001-09-24 09:43:17 +0000114 def Save(self):
115 """
Steven M. Gava2d7bb3f2002-01-29 08:35:29 +0000116 If config isn't empty, write file to disk. If config is empty,
117 remove the file from disk if it exists.
Steven M. Gavac11ccf32001-09-24 09:43:17 +0000118 """
Steven M. Gava2d7bb3f2002-01-29 08:35:29 +0000119 if not self.IsEmpty():
120 cfgFile=open(self.file,'w')
121 self.write(cfgFile)
122 else:
123 if os.path.exists(self.file):
124 os.remove(self.file)
Steven M. Gavac11ccf32001-09-24 09:43:17 +0000125
126class IdleConf:
127 """
128 holds config parsers for all idle config files:
129 default config files
130 (idle install dir)/config-main.def
131 (idle install dir)/config-extensions.def
132 (idle install dir)/config-highlight.def
133 (idle install dir)/config-keys.def
134 user config files
Steven M. Gavaad4f5322002-01-03 12:05:17 +0000135 (user home dir)/.idlerc/config-main.cfg
136 (user home dir)/.idlerc/config-extensions.cfg
137 (user home dir)/.idlerc/config-highlight.cfg
138 (user home dir)/.idlerc/config-keys.cfg
Steven M. Gavac11ccf32001-09-24 09:43:17 +0000139 """
140 def __init__(self):
141 self.defaultCfg={}
142 self.userCfg={}
143 self.cfg={}
144 self.CreateConfigHandlers()
145 self.LoadCfgFiles()
146 #self.LoadCfg()
147
148 def CreateConfigHandlers(self):
149 """
Steven M. Gavaad4f5322002-01-03 12:05:17 +0000150 set up a dictionary of config parsers for default and user
Steven M. Gavac11ccf32001-09-24 09:43:17 +0000151 configurations respectively
152 """
153 #build idle install path
154 if __name__ != '__main__': # we were imported
Steven M. Gava7cff66d2002-02-01 03:02:37 +0000155 idleDir=os.path.dirname(__file__)
Steven M. Gavac11ccf32001-09-24 09:43:17 +0000156 else: # we were exec'ed (for testing only)
Steven M. Gava7cff66d2002-02-01 03:02:37 +0000157 idleDir=os.path.abspath(sys.path[0])
158 userDir=self.GetUserCfgDir()
Steven M. Gavac11ccf32001-09-24 09:43:17 +0000159 configTypes=('main','extensions','highlight','keys')
160 defCfgFiles={}
161 usrCfgFiles={}
162 for cfgType in configTypes: #build config file names
Steven M. Gava7cff66d2002-02-01 03:02:37 +0000163 defCfgFiles[cfgType]=os.path.join(idleDir,'config-'+cfgType+'.def')
164 usrCfgFiles[cfgType]=os.path.join(userDir,'config-'+cfgType+'.cfg')
Steven M. Gavac11ccf32001-09-24 09:43:17 +0000165 for cfgType in configTypes: #create config parsers
166 self.defaultCfg[cfgType]=IdleConfParser(defCfgFiles[cfgType])
167 self.userCfg[cfgType]=IdleUserConfParser(usrCfgFiles[cfgType])
168
Steven M. Gava7cff66d2002-02-01 03:02:37 +0000169 def GetUserCfgDir(self):
170 """
171 Creates (if required) and returns a filesystem directory for storing
172 user config files.
173 """
174 cfgDir='.idlerc'
175 userDir=os.path.expanduser('~')
176 if userDir != '~': #'HOME' exists as a key in os.environ
177 if not os.path.exists(userDir):
178 warn=('\n Warning: HOME environment variable points to\n '+
179 userDir+'\n but the path does not exist.\n')
180 sys.stderr.write(warn)
181 userDir='~'
182 if userDir=='~': #we still don't have a home directory
183 #traditionally idle has defaulted to os.getcwd(), is this adeqate?
184 userDir = os.getcwd() #hack for no real homedir
185 userDir=os.path.join(userDir,cfgDir)
186 if not os.path.exists(userDir):
187 try: #make the config dir if it doesn't exist yet
188 os.mkdir(userDir)
189 except IOError:
190 warn=('\n Warning: unable to create user config directory\n '+
191 userDir+'\n')
192 sys.stderr.write(warn)
193 return userDir
194
Steven M. Gava2a63a072001-10-26 06:50:54 +0000195 def GetOption(self, configType, section, option, default=None, type=None):
Steven M. Gava429a86a2001-10-23 10:42:12 +0000196 """
197 Get an option value for given config type and given general
198 configuration section/option or return a default. If type is specified,
199 return as type. Firstly the user configuration is checked, with a
200 fallback to the default configuration, and a final 'catch all'
201 fallback to a useable passed-in default if the option isn't present in
202 either the user or the default configuration.
203 configType must be one of ('main','extensions','highlight','keys')
Steven M. Gava0cae01c2002-01-04 07:53:06 +0000204 If a default is returned a warning is printed to stderr.
Steven M. Gava429a86a2001-10-23 10:42:12 +0000205 """
206 if self.userCfg[configType].has_option(section,option):
207 return self.userCfg[configType].Get(section, option, type=type)
208 elif self.defaultCfg[configType].has_option(section,option):
209 return self.defaultCfg[configType].Get(section, option, type=type)
210 else:
Steven M. Gavaad4f5322002-01-03 12:05:17 +0000211 warning=('\n Warning: configHandler.py - IdleConf.GetOption -\n'+
212 ' problem retrieving configration option '+`option`+'\n'+
213 ' from section '+`section`+'.\n'+
214 ' returning default value: '+`default`+'\n')
215 sys.stderr.write(warning)
Steven M. Gava429a86a2001-10-23 10:42:12 +0000216 return default
217
Steven M. Gava2a63a072001-10-26 06:50:54 +0000218 def GetSectionList(self, configSet, configType):
219 """
220 Get a list of sections from either the user or default config for
221 the given config type.
222 configSet must be either 'user' or 'default'
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000223 configType must be one of ('main','extensions','highlight','keys')
Steven M. Gava2a63a072001-10-26 06:50:54 +0000224 """
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000225 if not (configType in ('main','extensions','highlight','keys')):
Steven M. Gava2a63a072001-10-26 06:50:54 +0000226 raise 'Invalid configType specified'
227 if configSet == 'user':
228 cfgParser=self.userCfg[configType]
229 elif configSet == 'default':
230 cfgParser=self.defaultCfg[configType]
231 else:
232 raise 'Invalid configSet specified'
Steven M. Gava2a63a072001-10-26 06:50:54 +0000233 return cfgParser.sections()
234
Steven M. Gavaad4f5322002-01-03 12:05:17 +0000235 def GetHighlight(self, theme, element, fgBg=None):
236 """
237 return individual highlighting theme elements.
238 fgBg - string ('fg'or'bg') or None, if None return a dictionary
239 containing fg and bg colours (appropriate for passing to Tkinter in,
240 e.g., a tag_config call), otherwise fg or bg colour only as specified.
241 """
Steven M. Gava99300612001-11-04 07:03:08 +0000242 #get some fallback defaults
243 defaultFg=self.GetOption('highlight', theme, 'normal' + "-foreground",
244 default='#000000')
245 defaultBg=self.GetOption('highlight', theme, 'normal' + "-background",
246 default='#ffffff')
247 #try for requested element colours
Steven M. Gavae16d94b2001-11-03 05:07:28 +0000248 fore = self.GetOption('highlight', theme, element + "-foreground")
Steven M. Gavaad4f5322002-01-03 12:05:17 +0000249 back = None
250 if element == 'cursor': #there is no config value for cursor bg
251 back = None
252 else:
253 back = self.GetOption('highlight', theme, element + "-background")
Steven M. Gava99300612001-11-04 07:03:08 +0000254 #fall back if required
255 if not fore: fore=defaultFg
256 if not back: back=defaultBg
Steven M. Gavaad4f5322002-01-03 12:05:17 +0000257 highlight={"foreground": fore,"background": back}
258 if not fgBg: #return dict of both colours
259 return highlight
260 else: #return specified colour only
261 if fgBg == 'fg':
262 return highlight["foreground"]
263 if fgBg == 'bg':
264 return highlight["background"]
265 else:
266 raise 'Invalid fgBg specified'
267
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000268 def GetThemeDict(self,type,themeName):
Steven M. Gava2a63a072001-10-26 06:50:54 +0000269 """
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000270 type - string, 'default' or 'user' theme type
271 themeName - string, theme name
272 Returns a dictionary which holds {option:value} for each element
273 in the specified theme. Values are loaded over a set of ultimate last
274 fallback defaults to guarantee that all theme elements are present in
275 a newly created theme.
Steven M. Gava2a63a072001-10-26 06:50:54 +0000276 """
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000277 if type == 'user':
278 cfgParser=self.userCfg['highlight']
279 elif type == 'default':
280 cfgParser=self.defaultCfg['highlight']
281 else:
282 raise 'Invalid theme type specified'
283 #foreground and background values are provded for each theme element
284 #(apart from cursor) even though all these values are not yet used
285 #by idle, to allow for their use in the future. Default values are
286 #generally black and white.
287 theme={ 'normal-foreground':'#000000',
288 'normal-background':'#ffffff',
289 'keyword-foreground':'#000000',
290 'keyword-background':'#ffffff',
291 'comment-foreground':'#000000',
292 'comment-background':'#ffffff',
293 'string-foreground':'#000000',
294 'string-background':'#ffffff',
295 'definition-foreground':'#000000',
296 'definition-background':'#ffffff',
297 'hilite-foreground':'#000000',
298 'hilite-background':'gray',
299 'break-foreground':'#ffffff',
300 'break-background':'#000000',
301 'hit-foreground':'#ffffff',
302 'hit-background':'#000000',
303 'error-foreground':'#ffffff',
304 'error-background':'#000000',
305 #cursor (only foreground can be set)
306 'cursor-foreground':'#000000',
307 #shell window
308 'stdout-foreground':'#000000',
309 'stdout-background':'#ffffff',
310 'stderr-foreground':'#000000',
311 'stderr-background':'#ffffff',
312 'console-foreground':'#000000',
313 'console-background':'#ffffff' }
314 for element in theme.keys():
315 colour=cfgParser.Get(type,themeName,element,default=theme[element])
316 theme[element]=colour
317 return theme
318
Steven M. Gavaad4f5322002-01-03 12:05:17 +0000319 def CurrentTheme(self):
320 """
321 Returns the name of the currently active theme
322 """
Steven M. Gava0cae01c2002-01-04 07:53:06 +0000323 return self.GetOption('main','Theme','name',default='')
Steven M. Gavaad4f5322002-01-03 12:05:17 +0000324
Steven M. Gavaad4f5322002-01-03 12:05:17 +0000325 def CurrentKeys(self):
326 """
327 Returns the name of the currently active theme
328 """
Steven M. Gava0cae01c2002-01-04 07:53:06 +0000329 return self.GetOption('main','Keys','name',default='')
Steven M. Gavaad4f5322002-01-03 12:05:17 +0000330
331 def GetExtensions(self, activeOnly=1):
332 """
333 Gets a list of all idle extensions declared in the config files.
334 activeOnly - boolean, if true only return active (enabled) extensions
335 """
Steven M. Gavac628a062002-01-19 10:33:21 +0000336 extns=self.RemoveKeyBindNames(
337 self.GetSectionList('default','extensions'))
338 userExtns=self.RemoveKeyBindNames(
339 self.GetSectionList('user','extensions'))
Steven M. Gavaad4f5322002-01-03 12:05:17 +0000340 for extn in userExtns:
341 if extn not in extns: #user has added own extension
342 extns.append(extn)
343 if activeOnly:
344 activeExtns=[]
345 for extn in extns:
Steven M. Gava5f28e8f2002-01-21 06:38:21 +0000346 if self.GetOption('extensions',extn,'enable',default=1,
347 type='bool'):
Steven M. Gavaad4f5322002-01-03 12:05:17 +0000348 #the extension is enabled
349 activeExtns.append(extn)
350 return activeExtns
351 else:
352 return extns
353
Steven M. Gavac628a062002-01-19 10:33:21 +0000354 def RemoveKeyBindNames(self,extnNameList):
355 #get rid of keybinding section names
356 names=extnNameList
357 kbNameIndicies=[]
358 for name in names:
359 if name.endswith('_bindings') or name.endswith('_cfgBindings'):
360 kbNameIndicies.append(names.index(name))
361 kbNameIndicies.sort()
362 kbNameIndicies.reverse()
363 for index in kbNameIndicies: #delete each keybinding section name
364 del(names[index])
365 return names
366
Steven M. Gavaa498af22002-02-01 01:33:36 +0000367 def GetExtnNameForEvent(self,virtualEvent):
368 """
369 Returns the name of the extension that virtualEvent is bound in, or
370 None if not bound in any extension.
371 virtualEvent - string, name of the virtual event to test for, without
372 the enclosing '<< >>'
373 """
374 extName=None
375 vEvent='<<'+virtualEvent+'>>'
376 for extn in self.GetExtensions(activeOnly=0):
377 for event in self.GetExtensionKeys(extn).keys():
378 if event == vEvent:
379 extName=extn
380 print extName
381 return extName
382
Steven M. Gavac628a062002-01-19 10:33:21 +0000383 def GetExtensionKeys(self,extensionName):
384 """
385 returns a dictionary of the configurable keybindings for a particular
386 extension,as they exist in the dictionary returned by GetCurrentKeySet;
Steven M. Gavaa498af22002-02-01 01:33:36 +0000387 that is, where previously used bindings are disabled.
Steven M. Gavac628a062002-01-19 10:33:21 +0000388 """
389 keysName=extensionName+'_cfgBindings'
390 activeKeys=self.GetCurrentKeySet()
391 extKeys={}
392 if self.defaultCfg['extensions'].has_section(keysName):
393 eventNames=self.defaultCfg['extensions'].GetOptionList(keysName)
394 for eventName in eventNames:
395 event='<<'+eventName+'>>'
396 binding=activeKeys[event]
397 extKeys[event]=binding
398 return extKeys
399
400 def __GetRawExtensionKeys(self,extensionName):
401 """
402 returns a dictionary of the configurable keybindings for a particular
403 extension, as defined in the configuration files, or an empty dictionary
404 if no bindings are found
405 """
406 keysName=extensionName+'_cfgBindings'
407 extKeys={}
408 if self.defaultCfg['extensions'].has_section(keysName):
409 eventNames=self.defaultCfg['extensions'].GetOptionList(keysName)
410 for eventName in eventNames:
411 binding=self.GetOption('extensions',keysName,
412 eventName,default='').split()
413 event='<<'+eventName+'>>'
414 extKeys[event]=binding
415 return extKeys
416
417 def GetExtensionBindings(self,extensionName):
418 """
419 Returns a dictionary of all the event bindings for a particular
420 extension. The configurable keybindings are returned as they exist in
421 the dictionary returned by GetCurrentKeySet; that is, where re-used
422 keybindings are disabled.
423 """
424 bindsName=extensionName+'_bindings'
425 extBinds=self.GetExtensionKeys(extensionName)
426 #add the non-configurable bindings
427 if self.defaultCfg['extensions'].has_section(bindsName):
428 eventNames=self.defaultCfg['extensions'].GetOptionList(bindsName)
429 for eventName in eventNames:
430 binding=self.GetOption('extensions',bindsName,
431 eventName,default='').split()
432 event='<<'+eventName+'>>'
433 extBinds[event]=binding
434
435 return extBinds
436
Steven M. Gava0cae01c2002-01-04 07:53:06 +0000437 def GetKeyBinding(self, keySetName, eventStr):
438 """
439 returns the keybinding for a specific event.
440 keySetName - string, name of key binding set
441 eventStr - string, the virtual event we want the binding for,
442 represented as a string, eg. '<<event>>'
443 """
444 eventName=eventStr[2:-2] #trim off the angle brackets
445 binding=self.GetOption('keys',keySetName,eventName,default='').split()
446 return binding
447
Steven M. Gavac628a062002-01-19 10:33:21 +0000448 def GetCurrentKeySet(self):
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000449 return self.GetKeySet(self.CurrentKeys())
450
451 def GetKeySet(self,keySetName):
Steven M. Gava2a63a072001-10-26 06:50:54 +0000452 """
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000453 Returns a dictionary of: all requested core keybindings, plus the
Steven M. Gavac628a062002-01-19 10:33:21 +0000454 keybindings for all currently active extensions. If a binding defined
455 in an extension is already in use, that binding is disabled.
456 """
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000457 keySet=self.GetCoreKeys(keySetName)
Steven M. Gavac628a062002-01-19 10:33:21 +0000458 activeExtns=self.GetExtensions(activeOnly=1)
459 for extn in activeExtns:
460 extKeys=self.__GetRawExtensionKeys(extn)
461 if extKeys: #the extension defines keybindings
462 for event in extKeys.keys():
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000463 if extKeys[event] in keySet.values():
Steven M. Gavac628a062002-01-19 10:33:21 +0000464 #the binding is already in use
465 extKeys[event]='' #disable this binding
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000466 keySet[event]=extKeys[event] #add binding
467 return keySet
468
Steven M. Gavaa498af22002-02-01 01:33:36 +0000469 def IsCoreBinding(self,virtualEvent):
470 """
471 returns true if the virtual event is bound in the core idle keybindings.
472 virtualEvent - string, name of the virtual event to test for, without
473 the enclosing '<< >>'
474 """
475 return ('<<'+virtualEvent+'>>') in self.GetCoreKeys().keys()
476
Steven M. Gavac628a062002-01-19 10:33:21 +0000477 def GetCoreKeys(self, keySetName=None):
478 """
479 returns the requested set of core keybindings, with fallbacks if
480 required.
Steven M. Gavaf9bb90e2002-01-24 06:02:50 +0000481 Keybindings loaded from the config file(s) are loaded _over_ these
482 defaults, so if there is a problem getting any core binding there will
483 be an 'ultimate last resort fallback' to the CUA-ish bindings
484 defined here.
Steven M. Gava2a63a072001-10-26 06:50:54 +0000485 """
Steven M. Gava17d01542001-12-03 00:37:28 +0000486 keyBindings={
Steven M. Gavaa498af22002-02-01 01:33:36 +0000487 '<<copy>>': ['<Control-c>', '<Control-C>'],
488 '<<cut>>': ['<Control-x>', '<Control-X>'],
489 '<<paste>>': ['<Control-v>', '<Control-V>'],
Steven M. Gava17d01542001-12-03 00:37:28 +0000490 '<<beginning-of-line>>': ['<Control-a>', '<Home>'],
491 '<<center-insert>>': ['<Control-l>'],
492 '<<close-all-windows>>': ['<Control-q>'],
493 '<<close-window>>': ['<Alt-F4>'],
Steven M. Gava17d01542001-12-03 00:37:28 +0000494 '<<end-of-file>>': ['<Control-d>'],
495 '<<python-docs>>': ['<F1>'],
496 '<<python-context-help>>': ['<Shift-F1>'],
497 '<<history-next>>': ['<Alt-n>'],
498 '<<history-previous>>': ['<Alt-p>'],
499 '<<interrupt-execution>>': ['<Control-c>'],
500 '<<open-class-browser>>': ['<Alt-c>'],
501 '<<open-module>>': ['<Alt-m>'],
502 '<<open-new-window>>': ['<Control-n>'],
503 '<<open-window-from-file>>': ['<Control-o>'],
504 '<<plain-newline-and-indent>>': ['<Control-j>'],
505 '<<redo>>': ['<Control-y>'],
506 '<<remove-selection>>': ['<Escape>'],
507 '<<save-copy-of-window-as-file>>': ['<Alt-Shift-s>'],
508 '<<save-window-as-file>>': ['<Alt-s>'],
509 '<<save-window>>': ['<Control-s>'],
510 '<<select-all>>': ['<Alt-a>'],
511 '<<toggle-auto-coloring>>': ['<Control-slash>'],
Steven M. Gava0cae01c2002-01-04 07:53:06 +0000512 '<<undo>>': ['<Control-z>'],
513 '<<find-again>>': ['<Control-g>', '<F3>'],
514 '<<find-in-files>>': ['<Alt-F3>'],
515 '<<find-selection>>': ['<Control-F3>'],
516 '<<find>>': ['<Control-f>'],
517 '<<replace>>': ['<Control-h>'],
518 '<<goto-line>>': ['<Alt-g>'] }
519
Steven M. Gava17d01542001-12-03 00:37:28 +0000520 if keySetName:
Steven M. Gava0cae01c2002-01-04 07:53:06 +0000521 for event in keyBindings.keys():
522 binding=self.GetKeyBinding(keySetName,event)
523 if binding: #otherwise will keep default
524 keyBindings[event]=binding
Steven M. Gava17d01542001-12-03 00:37:28 +0000525
526 return keyBindings
527
Steven M. Gava2a63a072001-10-26 06:50:54 +0000528
Steven M. Gavac11ccf32001-09-24 09:43:17 +0000529 def LoadCfgFiles(self):
530 """
531 load all configuration files.
532 """
533 for key in self.defaultCfg.keys():
534 self.defaultCfg[key].Load()
535 self.userCfg[key].Load() #same keys
536
537 def SaveUserCfgFiles(self):
538 """
539 write all loaded user configuration files back to disk
540 """
541 for key in self.userCfg.keys():
542 self.userCfg[key].Save()
543
544idleConf=IdleConf()
545
546### module test
547if __name__ == '__main__':
548 def dumpCfg(cfg):
549 print '\n',cfg,'\n'
550 for key in cfg.keys():
551 sections=cfg[key].sections()
552 print key
553 print sections
554 for section in sections:
555 options=cfg[key].options(section)
556 print section
557 print options
558 for option in options:
559 print option, '=', cfg[key].Get(section,option)
560 dumpCfg(idleConf.defaultCfg)
561 dumpCfg(idleConf.userCfg)
562 print idleConf.userCfg['main'].Get('Theme','name')
563 #print idleConf.userCfg['highlight'].GetDefHighlight('Foo','normal')