blob: f1fbd8d5eb898495cdf6b22f38510de4e64dac2c [file] [log] [blame]
Steven M. Gavac11ccf32001-09-24 09:43:17 +00001##---------------------------------------------------------------------------##
2##
3## idle - configuration data handler, based on and replacing IdleConfig.py
4## elguavas
5##
6##---------------------------------------------------------------------------##
Steven M. Gava2a63a072001-10-26 06:50:54 +00007"""
Steven M. Gava99300612001-11-04 07:03:08 +00008Provides access to stored idle configuration information
Steven M. Gava2a63a072001-10-26 06:50:54 +00009"""
Steven M. Gavac11ccf32001-09-24 09:43:17 +000010
11import 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. Gava429a86af2001-10-23 10:42:12 +000026 def Get(self, section, option, default=None, type=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. Gava429a86af2001-10-23 10:42:12 +000038 #return getVal(section, option, raw, vars)
39 return getVal(section, option)
Steven M. Gavac11ccf32001-09-24 09:43:17 +000040 else:
41 return default
42
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 """
60 IdleConfigParser specialised for user configuration handling
61 """
62 def Save(self):
63 """
64 write loaded user configuration file back to disk
65 """
66 # this is a user config, it can be written to disk
67 self.write()
68
69class IdleConf:
70 """
71 holds config parsers for all idle config files:
72 default config files
73 (idle install dir)/config-main.def
74 (idle install dir)/config-extensions.def
75 (idle install dir)/config-highlight.def
76 (idle install dir)/config-keys.def
77 user config files
78 (user home dir)/.idlerc/idle-main.cfg
79 (user home dir)/.idlerc/idle-extensions.cfg
80 (user home dir)/.idlerc/idle-highlight.cfg
81 (user home dir)/.idlerc/idle-keys.cfg
82 """
83 def __init__(self):
84 self.defaultCfg={}
85 self.userCfg={}
86 self.cfg={}
87 self.CreateConfigHandlers()
88 self.LoadCfgFiles()
89 #self.LoadCfg()
90
91 def CreateConfigHandlers(self):
92 """
93 set up a dictionary config parsers for default and user
94 configurations respectively
95 """
96 #build idle install path
97 if __name__ != '__main__': # we were imported
98 idledir=os.path.dirname(__file__)
99 else: # we were exec'ed (for testing only)
100 idledir=os.path.abspath(sys.path[0])
101 #print idledir
102 try: #build user home path
103 userdir = os.environ['HOME'] #real home directory
104 except KeyError:
105 userdir = os.getcwd() #hack for os'es without real homedirs
106 userdir=os.path.join(userdir,'.idlerc')
107 #print userdir
108 if not os.path.exists(userdir):
109 os.mkdir(userdir)
110 configTypes=('main','extensions','highlight','keys')
111 defCfgFiles={}
112 usrCfgFiles={}
113 for cfgType in configTypes: #build config file names
114 defCfgFiles[cfgType]=os.path.join(idledir,'config-'+cfgType+'.def')
115 usrCfgFiles[cfgType]=os.path.join(userdir,'idle-'+cfgType+'.cfg')
116 for cfgType in configTypes: #create config parsers
117 self.defaultCfg[cfgType]=IdleConfParser(defCfgFiles[cfgType])
118 self.userCfg[cfgType]=IdleUserConfParser(usrCfgFiles[cfgType])
119
Steven M. Gava2a63a072001-10-26 06:50:54 +0000120 def GetOption(self, configType, section, option, default=None, type=None):
Steven M. Gava429a86af2001-10-23 10:42:12 +0000121 """
122 Get an option value for given config type and given general
123 configuration section/option or return a default. If type is specified,
124 return as type. Firstly the user configuration is checked, with a
125 fallback to the default configuration, and a final 'catch all'
126 fallback to a useable passed-in default if the option isn't present in
127 either the user or the default configuration.
128 configType must be one of ('main','extensions','highlight','keys')
129 """
130 if self.userCfg[configType].has_option(section,option):
131 return self.userCfg[configType].Get(section, option, type=type)
132 elif self.defaultCfg[configType].has_option(section,option):
133 return self.defaultCfg[configType].Get(section, option, type=type)
134 else:
135 return default
136
Steven M. Gava2a63a072001-10-26 06:50:54 +0000137 def GetSectionList(self, configSet, configType):
138 """
139 Get a list of sections from either the user or default config for
140 the given config type.
141 configSet must be either 'user' or 'default'
142 configType must be one of ('extensions','highlight','keys')
143 """
144 if not (configType in ('extensions','highlight','keys')):
145 raise 'Invalid configType specified'
146 if configSet == 'user':
147 cfgParser=self.userCfg[configType]
148 elif configSet == 'default':
149 cfgParser=self.defaultCfg[configType]
150 else:
151 raise 'Invalid configSet specified'
152
153 return cfgParser.sections()
154
Steven M. Gavae16d94b2001-11-03 05:07:28 +0000155 def GetHighlight(self, theme, element):
Steven M. Gava99300612001-11-04 07:03:08 +0000156 #get some fallback defaults
157 defaultFg=self.GetOption('highlight', theme, 'normal' + "-foreground",
158 default='#000000')
159 defaultBg=self.GetOption('highlight', theme, 'normal' + "-background",
160 default='#ffffff')
161 #try for requested element colours
Steven M. Gavae16d94b2001-11-03 05:07:28 +0000162 fore = self.GetOption('highlight', theme, element + "-foreground")
163 back = self.GetOption('highlight', theme, element + "-background")
Steven M. Gava99300612001-11-04 07:03:08 +0000164 #fall back if required
165 if not fore: fore=defaultFg
166 if not back: back=defaultBg
Steven M. Gavae16d94b2001-11-03 05:07:28 +0000167 return {"foreground": fore,
168 "background": back}
169
Steven M. Gava2a63a072001-10-26 06:50:54 +0000170 def GetTheme(self, name=None):
171 """
172 Gets the requested theme or returns a final fallback theme in case
173 one can't be obtained from either the user or default config files.
174 """
175 pass
176
Steven M. Gava17d01542001-12-03 00:37:28 +0000177 def GetKeys(self, keySetName=None):
Steven M. Gava2a63a072001-10-26 06:50:54 +0000178 """
Steven M. Gava17d01542001-12-03 00:37:28 +0000179 returns the requested keybindings, with fallbacks if required.
Steven M. Gava2a63a072001-10-26 06:50:54 +0000180 """
Steven M. Gava17d01542001-12-03 00:37:28 +0000181 #default keybindings.
182 #keybindings loaded from the config file(s) are loaded _over_ these
183 #defaults, so if there is a problem getting any binding there will
184 #be an 'ultimate last resort fallback' to the CUA-ish bindings
185 #defined here.
186 keyBindings={
187 '<<Copy>>': ['<Control-c>', '<Control-C>'],
188 '<<Cut>>': ['<Control-x>', '<Control-X>'],
189 '<<Paste>>': ['<Control-v>', '<Control-V>'],
190 '<<beginning-of-line>>': ['<Control-a>', '<Home>'],
191 '<<center-insert>>': ['<Control-l>'],
192 '<<close-all-windows>>': ['<Control-q>'],
193 '<<close-window>>': ['<Alt-F4>'],
194 '<<dump-undo-state>>': ['<Control-backslash>'],
195 '<<end-of-file>>': ['<Control-d>'],
196 '<<python-docs>>': ['<F1>'],
197 '<<python-context-help>>': ['<Shift-F1>'],
198 '<<history-next>>': ['<Alt-n>'],
199 '<<history-previous>>': ['<Alt-p>'],
200 '<<interrupt-execution>>': ['<Control-c>'],
201 '<<open-class-browser>>': ['<Alt-c>'],
202 '<<open-module>>': ['<Alt-m>'],
203 '<<open-new-window>>': ['<Control-n>'],
204 '<<open-window-from-file>>': ['<Control-o>'],
205 '<<plain-newline-and-indent>>': ['<Control-j>'],
206 '<<redo>>': ['<Control-y>'],
207 '<<remove-selection>>': ['<Escape>'],
208 '<<save-copy-of-window-as-file>>': ['<Alt-Shift-s>'],
209 '<<save-window-as-file>>': ['<Alt-s>'],
210 '<<save-window>>': ['<Control-s>'],
211 '<<select-all>>': ['<Alt-a>'],
212 '<<toggle-auto-coloring>>': ['<Control-slash>'],
213 '<<undo>>': ['<Control-z>']}
214 if keySetName:
215 pass
216
217 return keyBindings
218
Steven M. Gava2a63a072001-10-26 06:50:54 +0000219
Steven M. Gavac11ccf32001-09-24 09:43:17 +0000220 def LoadCfgFiles(self):
221 """
222 load all configuration files.
223 """
224 for key in self.defaultCfg.keys():
225 self.defaultCfg[key].Load()
226 self.userCfg[key].Load() #same keys
227
228 def SaveUserCfgFiles(self):
229 """
230 write all loaded user configuration files back to disk
231 """
232 for key in self.userCfg.keys():
233 self.userCfg[key].Save()
234
235idleConf=IdleConf()
236
237### module test
238if __name__ == '__main__':
239 def dumpCfg(cfg):
240 print '\n',cfg,'\n'
241 for key in cfg.keys():
242 sections=cfg[key].sections()
243 print key
244 print sections
245 for section in sections:
246 options=cfg[key].options(section)
247 print section
248 print options
249 for option in options:
250 print option, '=', cfg[key].Get(section,option)
251 dumpCfg(idleConf.defaultCfg)
252 dumpCfg(idleConf.userCfg)
253 print idleConf.userCfg['main'].Get('Theme','name')
254 #print idleConf.userCfg['highlight'].GetDefHighlight('Foo','normal')