Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
32a71457
Commit
32a71457
authored
Oct 06, 2014
by
Terry Jan Reedy
Browse files
Options
Browse Files
Download
Plain Diff
Merge with 3.4: idlelib.configHandler
parents
b91ed56b
deb7bf12
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
233 additions
and
255 deletions
+233
-255
Lib/idlelib/configHandler.py
Lib/idlelib/configHandler.py
+233
-255
No files found.
Lib/idlelib/configHandler.py
View file @
32a71457
...
...
@@ -15,8 +15,9 @@ idle. This is to allow IDLE to continue to function in spite of errors in
the retrieval of config information. When a default is returned instead of
a requested config value, a message is printed to stderr to aid in
configuration problem notification and resolution.
"""
# TODOs added Oct 2014, tjr
import
os
import
sys
...
...
@@ -35,7 +36,7 @@ class IdleConfParser(ConfigParser):
"""
cfgFile - string, fully specified configuration file name
"""
self
.
file
=
cfgFile
self
.
file
=
cfgFile
ConfigParser
.
__init__
(
self
,
defaults
=
cfgDefaults
,
strict
=
False
)
def
Get
(
self
,
section
,
option
,
type
=
None
,
default
=
None
,
raw
=
False
):
...
...
@@ -45,26 +46,22 @@ class IdleConfParser(ConfigParser):
"""
if
not
self
.
has_option
(
section
,
option
):
return
default
if
type
==
'bool'
:
if
type
==
'bool'
:
return
self
.
getboolean
(
section
,
option
)
elif
type
==
'int'
:
elif
type
==
'int'
:
return
self
.
getint
(
section
,
option
)
else
:
return
self
.
get
(
section
,
option
,
raw
=
raw
)
def
GetOptionList
(
self
,
section
):
"""
Get an option list for given section
"""
def
GetOptionList
(
self
,
section
):
"Return a list of options for given section, else []."
if
self
.
has_section
(
section
):
return
self
.
options
(
section
)
else
:
#return a default value
return
[]
def
Load
(
self
):
"""
Load the configuration file from disk
"""
"Load the configuration file from disk."
self
.
read
(
self
.
file
)
class
IdleUserConfParser
(
IdleConfParser
):
...
...
@@ -72,61 +69,50 @@ class IdleUserConfParser(IdleConfParser):
IdleConfigParser specialised for user configuration handling.
"""
def
AddSection
(
self
,
section
):
"""
if section doesn't exist, add it
"""
def
AddSection
(
self
,
section
):
"If section doesn't exist, add it."
if
not
self
.
has_section
(
section
):
self
.
add_section
(
section
)
def
RemoveEmptySections
(
self
):
"""
remove any sections that have no options
"""
"Remove any sections that have no options."
for
section
in
self
.
sections
():
if
not
self
.
GetOptionList
(
section
):
self
.
remove_section
(
section
)
def
IsEmpty
(
self
):
"""
Remove empty sections and then return 1 if parser has no sections
left, else return 0.
"""
"Return True if no sections after removing empty sections."
self
.
RemoveEmptySections
()
if
self
.
sections
():
return
0
else
:
return
1
return
not
self
.
sections
()
def
RemoveOption
(
self
,
section
,
option
):
"""
If section/option exists, remove it.
Returns 1 if option was removed, 0 otherwise
.
def
RemoveOption
(
self
,
section
,
option
):
"""
Return True if option is removed from section, else False.
False if either section does not exist or did not have option
.
"""
if
self
.
has_section
(
section
):
return
self
.
remove_option
(
section
,
option
)
return
self
.
remove_option
(
section
,
option
)
return
False
def
SetOption
(
self
,
section
,
option
,
value
):
"""
Sets option to value, adding section if required.
Returns 1 if option was added or changed, otherwise 0
.
def
SetOption
(
self
,
section
,
option
,
value
):
"""
Return True if option is added or changed to value, else False.
Add section if required. False means option already had value
.
"""
if
self
.
has_option
(
section
,
option
):
if
self
.
get
(
section
,
option
)
==
value
:
return
0
if
self
.
has_option
(
section
,
option
):
if
self
.
get
(
section
,
option
)
==
value
:
return
False
else
:
self
.
set
(
section
,
option
,
value
)
return
1
self
.
set
(
section
,
option
,
value
)
return
True
else
:
if
not
self
.
has_section
(
section
):
self
.
add_section
(
section
)
self
.
set
(
section
,
option
,
value
)
return
1
self
.
set
(
section
,
option
,
value
)
return
True
def
RemoveFile
(
self
):
"""
Removes the user config file from disk if it exists.
"""
"Remove user config file self.file from disk if it exists."
if
os
.
path
.
exists
(
self
.
file
):
os
.
remove
(
self
.
file
)
...
...
@@ -150,60 +136,57 @@ class IdleUserConfParser(IdleConfParser):
self
.
RemoveFile
()
class
IdleConf
:
"""
holds config parsers for all idle config files:
default config files
(idle install dir)/config-main.def
(idle install dir)/config-extensions.def
(idle install dir)/config-highlight.def
(idle install dir)/config-keys.def
user config files
(user home dir)/.idlerc/config-main.cfg
(user home dir)/.idlerc/config-extensions.cfg
(user home dir)/.idlerc/config-highlight.cfg
(user home dir)/.idlerc/config-keys.cfg
"""Hold config parsers for all idle config files in singleton instance.
Default config files, self.defaultCfg --
for config_type in self.config_types:
(idle install dir)/config-{config-type}.def
User config files, self.userCfg --
for config_type in self.config_types:
(user home dir)/.idlerc/config-{config-type}.cfg
"""
def
__init__
(
self
):
self
.
defaultCfg
=
{}
self
.
userCfg
=
{}
self
.
cfg
=
{}
self
.
config_types
=
(
'main'
,
'extensions'
,
'highlight'
,
'keys'
)
self
.
defaultCfg
=
{}
self
.
userCfg
=
{}
self
.
cfg
=
{}
# TODO use to select userCfg vs defaultCfg
self
.
CreateConfigHandlers
()
self
.
LoadCfgFiles
()
#self.LoadCfg()
def
CreateConfigHandlers
(
self
):
"""
set up a dictionary of config parsers for default and user
configurations respectively
"""
"Populate default and user config parser dictionaries."
#build idle install path
if
__name__
!=
'__main__'
:
# we were imported
idleDir
=
os
.
path
.
dirname
(
__file__
)
else
:
# we were exec'ed (for testing only)
idleDir
=
os
.
path
.
abspath
(
sys
.
path
[
0
])
userDir
=
self
.
GetUserCfgDir
()
configTypes
=
(
'main'
,
'extensions'
,
'highlight'
,
'keys'
)
defCfgFiles
=
{}
usrCfgFiles
=
{}
for
cfgType
in
configTypes
:
#build config file names
defCfgFiles
[
cfgType
]
=
os
.
path
.
join
(
idleDir
,
'config-'
+
cfgType
+
'.def'
)
usrCfgFiles
[
cfgType
]
=
os
.
path
.
join
(
userDir
,
'config-'
+
cfgType
+
'.cfg'
)
for
cfgType
in
configTypes
:
#create config parsers
self
.
defaultCfg
[
cfgType
]
=
IdleConfParser
(
defCfgFiles
[
cfgType
])
self
.
userCfg
[
cfgType
]
=
IdleUserConfParser
(
usrCfgFiles
[
cfgType
])
defCfgFiles
=
{}
usrCfgFiles
=
{}
# TODO eliminate these temporaries by combining loops
for
cfgType
in
self
.
config_types
:
#build config file names
defCfgFiles
[
cfgType
]
=
os
.
path
.
join
(
idleDir
,
'config-'
+
cfgType
+
'.def'
)
usrCfgFiles
[
cfgType
]
=
os
.
path
.
join
(
userDir
,
'config-'
+
cfgType
+
'.cfg'
)
for
cfgType
in
self
.
config_types
:
#create config parsers
self
.
defaultCfg
[
cfgType
]
=
IdleConfParser
(
defCfgFiles
[
cfgType
])
self
.
userCfg
[
cfgType
]
=
IdleUserConfParser
(
usrCfgFiles
[
cfgType
])
def
GetUserCfgDir
(
self
):
"""
Creates (if required) and returns a filesystem directory for storing
user config files.
"""Return a filesystem directory for storing user config files.
Creates it if required.
"""
cfgDir
=
'.idlerc'
userDir
=
os
.
path
.
expanduser
(
'~'
)
if
userDir
!=
'~'
:
# expanduser() found user home dir
if
not
os
.
path
.
exists
(
userDir
):
warn
=
(
'
\
n
Warning: os.path.expanduser("~") points to
\
n
'
+
userDir
+
',
\
n
but the path does not exist.'
)
warn
=
(
'
\
n
Warning: os.path.expanduser("~") points to
\
n
'
+
userDir
+
',
\
n
but the path does not exist.'
)
try
:
print
(
warn
,
file
=
sys
.
stderr
)
except
OSError
:
...
...
@@ -217,28 +200,28 @@ class IdleConf:
try
:
os
.
mkdir
(
userDir
)
except
OSError
:
warn
=
(
'
\
n
Warning: unable to create user config directory
\
n
'
+
userDir
+
'
\
n
Check path and permissions.
\
n
Exiting!
\
n
'
)
warn
=
(
'
\
n
Warning: unable to create user config directory
\
n
'
+
userDir
+
'
\
n
Check path and permissions.
\
n
Exiting!
\
n
'
)
print
(
warn
,
file
=
sys
.
stderr
)
raise
SystemExit
# TODO continue without userDIr instead of exit
return
userDir
def
GetOption
(
self
,
configType
,
section
,
option
,
default
=
None
,
type
=
None
,
warn_on_default
=
True
,
raw
=
False
):
"""
Get an option value for given config type and given general
configuration section/option or return a default. If type is specified,
return as type. Firstly the user configuration is checked, with a
fallback to the default configuration, and a final 'catch all'
fallback to a useable passed-in default if the option isn't present in
either the user or the default configuration.
configType must be one of ('main','extensions','highlight','keys')
If a default is returned, and warn_on_default is True, a warning is
printed to stderr.
"""Return a value for configType section option, or default.
If type is not None, return a value of that type. Also pass raw
to the config parser. First try to return a valid value
(including type) from a user configuration. If that fails, try
the default configuration. If that fails, return default, with a
default of None.
Warn if either user or default configurations have an invalid value.
Warn if default is returned and warn_on_default is True.
"""
try
:
if
self
.
userCfg
[
configType
].
has_option
(
section
,
option
):
if
self
.
userCfg
[
configType
].
has_option
(
section
,
option
):
return
self
.
userCfg
[
configType
].
Get
(
section
,
option
,
type
=
type
,
raw
=
raw
)
except
ValueError
:
...
...
@@ -246,16 +229,15 @@ class IdleConf:
' invalid %r value for configuration option %r
\
n
'
' from section %r: %r'
%
(
type
,
option
,
section
,
self
.
userCfg
[
configType
].
Get
(
section
,
option
,
raw
=
raw
)))
self
.
userCfg
[
configType
].
Get
(
section
,
option
,
raw
=
raw
)))
try
:
print
(
warning
,
file
=
sys
.
stderr
)
except
OSError
:
pass
try
:
if
self
.
defaultCfg
[
configType
].
has_option
(
section
,
option
):
return
self
.
defaultCfg
[
configType
].
Get
(
section
,
option
,
type
=
type
,
raw
=
raw
)
return
self
.
defaultCfg
[
configType
].
Get
(
section
,
option
,
type
=
type
,
raw
=
raw
)
except
ValueError
:
pass
#returning default, print warning
...
...
@@ -272,22 +254,19 @@ class IdleConf:
return
default
def
SetOption
(
self
,
configType
,
section
,
option
,
value
):
"""In user's config file, set section's option to value.
"""
"""Set section option to value in user config file."""
self
.
userCfg
[
configType
].
SetOption
(
section
,
option
,
value
)
def
GetSectionList
(
self
,
configSet
,
configType
):
"""
Get a list of sections from either the user or default config for
the given config type.
"""Return sections for configSet configType configuration.
configSet must be either 'user' or 'default'
configType must be
one of ('main','extensions','highlight','keys')
configType must be
in self.config_types.
"""
if
not
(
configType
in
(
'main'
,
'extensions'
,
'highlight'
,
'keys'
)
):
if
not
(
configType
in
self
.
config_types
):
raise
InvalidConfigType
(
'Invalid configType specified'
)
if
configSet
==
'user'
:
cfgParser
=
self
.
userCfg
[
configType
]
cfgParser
=
self
.
userCfg
[
configType
]
elif
configSet
==
'default'
:
cfgParser
=
self
.
defaultCfg
[
configType
]
else
:
...
...
@@ -295,22 +274,22 @@ class IdleConf:
return
cfgParser
.
sections
()
def
GetHighlight
(
self
,
theme
,
element
,
fgBg
=
None
):
"""
return individual highlighting theme elements.
"""
Return individual highlighting theme elements.
fgBg - string ('fg'or'bg') or None, if None return a dictionary
containing fg and bg colours (appropriate for passing to Tkinter in,
e.g., a tag_config call), otherwise fg or bg colour only as specified.
"""
if
self
.
defaultCfg
[
'highlight'
].
has_section
(
theme
):
themeDict
=
self
.
GetThemeDict
(
'default'
,
theme
)
themeDict
=
self
.
GetThemeDict
(
'default'
,
theme
)
else
:
themeDict
=
self
.
GetThemeDict
(
'user'
,
theme
)
fore
=
themeDict
[
element
+
'-foreground'
]
if
element
==
'cursor'
:
#there is no config value for cursor bg
back
=
themeDict
[
'normal-background'
]
themeDict
=
self
.
GetThemeDict
(
'user'
,
theme
)
fore
=
themeDict
[
element
+
'-foreground'
]
if
element
==
'cursor'
:
#there is no config value for cursor bg
back
=
themeDict
[
'normal-background'
]
else
:
back
=
themeDict
[
element
+
'-background'
]
highlight
=
{
"foreground"
:
fore
,
"background"
:
back
}
back
=
themeDict
[
element
+
'-background'
]
highlight
=
{
"foreground"
:
fore
,
"background"
:
back
}
if
not
fgBg
:
#return dict of both colours
return
highlight
else
:
#return specified colour only
...
...
@@ -321,26 +300,26 @@ class IdleConf:
else
:
raise
InvalidFgBg
(
'Invalid fgBg specified'
)
def
GetThemeDict
(
self
,
type
,
themeName
):
"""
def
GetThemeDict
(
self
,
type
,
themeName
):
"""Return {option:value} dict for elements in themeName.
type - string, 'default' or 'user' theme type
themeName - string, theme name
Returns a dictionary which holds {option:value} for each element
in the specified theme. Values are loaded over a set of ultimate last
fallback defaults to guarantee that all theme elements are present in
a newly created theme.
Values are loaded over ultimate fallback defaults to guarantee
that all theme elements are present in a newly created theme.
"""
if
type
==
'user'
:
cfgParser
=
self
.
userCfg
[
'highlight'
]
cfgParser
=
self
.
userCfg
[
'highlight'
]
elif
type
==
'default'
:
cfgParser
=
self
.
defaultCfg
[
'highlight'
]
cfgParser
=
self
.
defaultCfg
[
'highlight'
]
else
:
raise
InvalidTheme
(
'Invalid theme type specified'
)
#foreground and background values are provded for each theme element
#(apart from cursor) even though all these values are not yet used
#by idle, to allow for their use in the future. Default values are
#generally black and white.
theme
=
{
'normal-foreground'
:
'#000000'
,
# TODO make theme, a constant, a module or class attribute
theme
=
{
'normal-foreground'
:
'#000000'
,
'normal-background'
:
'#ffffff'
,
'keyword-foreground'
:
'#000000'
,
'keyword-background'
:
'#ffffff'
,
...
...
@@ -370,9 +349,9 @@ class IdleConf:
'console-foreground'
:
'#000000'
,
'console-background'
:
'#ffffff'
}
for
element
in
theme
:
if
not
cfgParser
.
has_option
(
themeName
,
element
):
if
not
cfgParser
.
has_option
(
themeName
,
element
):
#we are going to return a default, print warning
warning
=
(
'
\
n
Warning: configHandler.py - IdleConf.GetThemeDict'
warning
=
(
'
\
n
Warning: configHandler.py - IdleConf.GetThemeDict'
' -
\
n
problem retrieving theme element %r'
'
\
n
from theme %r.
\
n
'
' returning default value: %r'
%
...
...
@@ -381,41 +360,39 @@ class IdleConf:
print
(
warning
,
file
=
sys
.
stderr
)
except
OSError
:
pass
colour
=
cfgParser
.
Get
(
themeName
,
element
,
default
=
theme
[
element
])
theme
[
element
]
=
colour
colour
=
cfgParser
.
Get
(
themeName
,
element
,
default
=
theme
[
element
])
theme
[
element
]
=
colour
return
theme
def
CurrentTheme
(
self
):
"""
Returns the name of the currently active theme
"""
return
self
.
GetOption
(
'main'
,
'Theme'
,
'name'
,
default
=
''
)
"Return the name of the currently active theme."
return
self
.
GetOption
(
'main'
,
'Theme'
,
'name'
,
default
=
''
)
def
CurrentKeys
(
self
):
"""
Returns the name of the currently active key set
"""
return
self
.
GetOption
(
'main'
,
'Keys'
,
'name'
,
default
=
''
)
"Return the name of the currently active key set."
return
self
.
GetOption
(
'main'
,
'Keys'
,
'name'
,
default
=
''
)
def
GetExtensions
(
self
,
active_only
=
True
,
editor_only
=
False
,
shell_only
=
False
):
"""Return extensions in default and user config-extensions files.
If active_only True, only return active (enabled) extensions
and optionally only editor or shell extensions.
If active_only False, return all extensions.
"""
Gets a list of all idle extensions declared in the config files.
active_only - boolean, if true only return active (enabled) extensions
"""
extns
=
self
.
RemoveKeyBindNames
(
self
.
GetSectionList
(
'default'
,
'extensions'
))
userExtns
=
self
.
RemoveKeyBindNames
(
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
)
if
active_only
:
activeExtns
=
[]
activeExtns
=
[]
for
extn
in
extns
:
if
self
.
GetOption
(
'extensions'
,
extn
,
'enable'
,
default
=
True
,
type
=
'bool'
):
#the extension is enabled
if
editor_only
or
shell_only
:
if
editor_only
or
shell_only
:
# TODO if both, contradictory
if
editor_only
:
option
=
"enable_editor"
else
:
...
...
@@ -430,107 +407,108 @@ class IdleConf:
else
:
return
extns
def
RemoveKeyBindNames
(
self
,
extnNameList
):
#get rid of keybinding section names
names
=
extnNameList
kbNameIndicies
=
[]
def
RemoveKeyBindNames
(
self
,
extnNameList
):
"Return extnNameList with keybinding section names removed."
# TODO Easier to return filtered copy with list comp
names
=
extnNameList
kbNameIndicies
=
[]
for
name
in
names
:
if
name
.
endswith
((
'_bindings'
,
'_cfgBindings'
)):
kbNameIndicies
.
append
(
names
.
index
(
name
))
kbNameIndicies
.
sort
()
kbNameIndicies
.
reverse
()
kbNameIndicies
.
sort
(
reverse
=
True
)
for
index
in
kbNameIndicies
:
#delete each keybinding section name
del
(
names
[
index
])
return
names
def
GetExtnNameForEvent
(
self
,
virtualEvent
):
"""
Returns the name of the extension that virtualEvent is bound in, or
None if not bound in any extension.
virtualEvent - string, name of the virtual event to test for, without
the enclosing '<< >>'
def
GetExtnNameForEvent
(
self
,
virtualEvent
):
"""Return the name of the extension binding virtualEvent, or None.
virtualEvent - string, name of the virtual event to test for,
without the enclosing '<< >>'
"""
extName
=
None
vEvent
=
'<<'
+
virtualEvent
+
'>>'
extName
=
None
vEvent
=
'<<'
+
virtualEvent
+
'>>'
for
extn
in
self
.
GetExtensions
(
active_only
=
0
):
for
event
in
self
.
GetExtensionKeys
(
extn
):
if
event
==
vEvent
:
extName
=
extn
extName
=
extn
# TODO return here?
return
extName
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 used bindings are disabled.
def
GetExtensionKeys
(
self
,
extensionName
):
"""Return dict: {configurable extensionName event : active keybinding}.
Events come from default config extension_cfgBindings section.
Keybindings come from GetCurrentKeySet() active key dict,
where previously used bindings are disabled.
"""
keysName
=
extensionName
+
'_cfgBindings'
activeKeys
=
self
.
GetCurrentKeySet
()
extKeys
=
{}
keysName
=
extensionName
+
'_cfgBindings'
activeKeys
=
self
.
GetCurrentKeySet
()
extKeys
=
{}
if
self
.
defaultCfg
[
'extensions'
].
has_section
(
keysName
):
eventNames
=
self
.
defaultCfg
[
'extensions'
].
GetOptionList
(
keysName
)
eventNames
=
self
.
defaultCfg
[
'extensions'
].
GetOptionList
(
keysName
)
for
eventName
in
eventNames
:
event
=
'<<'
+
eventName
+
'>>'
binding
=
activeKeys
[
event
]
extKeys
[
event
]
=
binding
event
=
'<<'
+
eventName
+
'>>'
binding
=
activeKeys
[
event
]
extKeys
[
event
]
=
binding
return
extKeys
def
__GetRawExtensionKeys
(
self
,
extensionName
):
"""Return dict {configurable extensionName event : keybinding list}.
Events come from default config extension_cfgBindings section.
Keybindings list come from the splitting of GetOption, which
tries user config before default config.
"""
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
=
{}
keysName
=
extensionName
+
'_cfgBindings'
extKeys
=
{}
if
self
.
defaultCfg
[
'extensions'
].
has_section
(
keysName
):
eventNames
=
self
.
defaultCfg
[
'extensions'
].
GetOptionList
(
keysName
)
eventNames
=
self
.
defaultCfg
[
'extensions'
].
GetOptionList
(
keysName
)
for
eventName
in
eventNames
:
binding
=
self
.
GetOption
(
'extensions'
,
keysName
,
eventName
,
default
=
''
).
split
()
event
=
'<<'
+
eventName
+
'>>'
extKeys
[
event
]
=
binding
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
.
def
GetExtensionBindings
(
self
,
extensionName
):
"""
Return dict {extensionName event : active or defined keybinding}.
Augment self.GetExtensionKeys(extensionName) with mapping of non-
configurable events (from default config) to GetOption splits,
as in self.__GetRawExtensionKeys
.
"""
bindsName
=
extensionName
+
'_bindings'
extBinds
=
self
.
GetExtensionKeys
(
extensionName
)
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
)
eventNames
=
self
.
defaultCfg
[
'extensions'
].
GetOptionList
(
bindsName
)
for
eventName
in
eventNames
:
binding
=
self
.
GetOption
(
'extensions'
,
bindsName
,
eventName
,
default
=
''
).
split
()
event
=
'<<'
+
eventName
+
'>>'
extBinds
[
event
]
=
binding
binding
=
self
.
GetOption
(
'extensions'
,
bindsName
,
eventName
,
default
=
''
).
split
()
event
=
'<<'
+
eventName
+
'>>'
extBinds
[
event
]
=
binding
return
extBinds
def
GetKeyBinding
(
self
,
keySetName
,
eventStr
):
"""Return the keybinding list for keySetName eventStr.
keySetName - name of key binding set (config-keys section).
eventStr - virtual event, including brackets, as in '<<event>>'.
"""
returns the keybinding for a specific event.
keySetName - string, name of key binding set
eventStr - string, the virtual event we want the binding for,
represented as a string, eg. '<<event>>'
"""
eventName
=
eventStr
[
2
:
-
2
]
#trim off the angle brackets
binding
=
self
.
GetOption
(
'keys'
,
keySetName
,
eventName
,
default
=
''
).
split
()
eventName
=
eventStr
[
2
:
-
2
]
#trim off the angle brackets
binding
=
self
.
GetOption
(
'keys'
,
keySetName
,
eventName
,
default
=
''
).
split
()
return
binding
def
GetCurrentKeySet
(
self
):
"Return CurrentKeys with 'darwin' modifications."
result
=
self
.
GetKeySet
(
self
.
CurrentKeys
())
if
sys
.
platform
==
"darwin"
:
# OS X Tk variants do not support the "Alt" keyboard modifier.
# So replace all keybingings that use "Alt" with ones that
# use the "Option" keyboard modifier.
# TO
DO
: the "Option" modifier does not work properly for
# TO
DO (Ned?)
: the "Option" modifier does not work properly for
# Cocoa Tk and XQuartz Tk so we should not use it
# in default OS X KeySets.
for
k
,
v
in
result
.
items
():
...
...
@@ -540,40 +518,43 @@ class IdleConf:
return
result
def
GetKeySet
(
self
,
keySetName
):
"""
Returns a dictionary of: all requested 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.
def
GetKeySet
(
self
,
keySetName
):
"""
Return event-key dict for keySetName core plus active extensions.
If a binding defined in an extension is already in use, the
extension binding is disabled by being set to ''
"""
keySet
=
self
.
GetCoreKeys
(
keySetName
)
activeExtns
=
self
.
GetExtensions
(
active_only
=
1
)
keySet
=
self
.
GetCoreKeys
(
keySetName
)
activeExtns
=
self
.
GetExtensions
(
active_only
=
1
)
for
extn
in
activeExtns
:
extKeys
=
self
.
__GetRawExtensionKeys
(
extn
)
extKeys
=
self
.
__GetRawExtensionKeys
(
extn
)
if
extKeys
:
#the extension defines keybindings
for
event
in
extKeys
:
if
extKeys
[
event
]
in
keySet
.
values
():
#the binding is already in use
extKeys
[
event
]
=
''
#disable this binding
keySet
[
event
]
=
extKeys
[
event
]
#add binding
extKeys
[
event
]
=
''
#disable this binding
keySet
[
event
]
=
extKeys
[
event
]
#add binding
return
keySet
def
IsCoreBinding
(
self
,
virtualEvent
):
"""
returns true if the virtual event is bound in the core idle keybindings.
virtualEvent - string, name of the virtual event to test for,
without
the enclosing '<< >>'
def
IsCoreBinding
(
self
,
virtualEvent
):
"""
Return True if the virtual event is one of the core idle key events.
virtualEvent - string, name of the virtual event to test for,
without
the enclosing '<< >>'
"""
return
(
'<<'
+
virtualEvent
+
'>>'
)
in
self
.
GetCoreKeys
()
# TODO make keyBindins a file or class attribute used for test above
# and copied in function below
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 core binding there will
be an 'ultimate last resort fallback' to the CUA-ish bindings
defined here.
"""
Return dict of core virtual-key keybindings for keySetName.
The default keySetName None corresponds to the keyBindings base
dict. If keySetName is not None, bindings from the config
file(s) are loaded _over_ these 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
=
{
'<<copy>>'
:
[
'<Control-c>'
,
'<Control-C>'
],
...
...
@@ -628,9 +609,9 @@ class IdleConf:
}
if
keySetName
:
for
event
in
keyBindings
:
binding
=
self
.
GetKeyBinding
(
keySetName
,
event
)
binding
=
self
.
GetKeyBinding
(
keySetName
,
event
)
if
binding
:
keyBindings
[
event
]
=
binding
keyBindings
[
event
]
=
binding
else
:
#we are going to return a default, print warning
warning
=
(
'
\
n
Warning: configHandler.py - IdleConf.GetCoreKeys'
' -
\
n
problem retrieving key binding for event %r'
...
...
@@ -643,8 +624,8 @@ class IdleConf:
pass
return
keyBindings
def
GetExtraHelpSourceList
(
self
,
configSet
):
"""
Fetch
list of extra help sources from a given configSet.
def
GetExtraHelpSourceList
(
self
,
configSet
):
"""
Return
list of extra help sources from a given configSet.
Valid configSets are 'user' or 'default'. Return a list of tuples of
the form (menu_item , path_to_help_file , option), or return the empty
...
...
@@ -653,19 +634,19 @@ class IdleConf:
therefore the returned list must be sorted by 'option'.
"""
helpSources
=
[]
if
configSet
==
'user'
:
cfgParser
=
self
.
userCfg
[
'main'
]
elif
configSet
==
'default'
:
cfgParser
=
self
.
defaultCfg
[
'main'
]
helpSources
=
[]
if
configSet
==
'user'
:
cfgParser
=
self
.
userCfg
[
'main'
]
elif
configSet
==
'default'
:
cfgParser
=
self
.
defaultCfg
[
'main'
]
else
:
raise
InvalidConfigSet
(
'Invalid configSet specified'
)
options
=
cfgParser
.
GetOptionList
(
'HelpFiles'
)
for
option
in
options
:
value
=
cfgParser
.
Get
(
'HelpFiles'
,
option
,
default
=
';'
)
if
value
.
find
(
';'
)
==
-
1
:
#malformed config entry with no ';'
menuItem
=
''
#make these empty
helpPath
=
''
#so value won't be added to list
value
=
cfgParser
.
Get
(
'HelpFiles'
,
option
,
default
=
';'
)
if
value
.
find
(
';'
)
==
-
1
:
#malformed config entry with no ';'
menuItem
=
''
#make these empty
helpPath
=
''
#so value won't be added to list
else
:
#config entry contains ';' as expected
value
=
value
.
split
(
';'
)
menuItem
=
value
[
0
].
strip
()
...
...
@@ -676,47 +657,44 @@ class IdleConf:
return
helpSources
def
GetAllExtraHelpSourcesList
(
self
):
"""Return a list of the details of all additional help sources.
Tuples in the list are those of GetExtraHelpSourceList.
"""
Returns a list of tuples containing the details of all additional help
sources configured, or an empty list if there are none. Tuples are of
the format returned by GetExtraHelpSourceList.
"""
allHelpSources
=
(
self
.
GetExtraHelpSourceList
(
'default'
)
+
allHelpSources
=
(
self
.
GetExtraHelpSourceList
(
'default'
)
+
self
.
GetExtraHelpSourceList
(
'user'
)
)
return
allHelpSources
def
LoadCfgFiles
(
self
):
"""
load all configuration files.
"""
"Load all configuration files."
for
key
in
self
.
defaultCfg
:
self
.
defaultCfg
[
key
].
Load
()
self
.
userCfg
[
key
].
Load
()
#same keys
def
SaveUserCfgFiles
(
self
):
"""
write all loaded user configuration files back to disk
"""
"Write all loaded user configuration files to disk."
for
key
in
self
.
userCfg
:
self
.
userCfg
[
key
].
Save
()
idleConf
=
IdleConf
()
idleConf
=
IdleConf
()
# TODO Revise test output, write expanded unittest
### module test
if
__name__
==
'__main__'
:
def
dumpCfg
(
cfg
):
print
(
'
\
n
'
,
cfg
,
'
\
n
'
)
print
(
'
\
n
'
,
cfg
,
'
\
n
'
)
for
key
in
cfg
:
sections
=
cfg
[
key
].
sections
()
sections
=
cfg
[
key
].
sections
()
print
(
key
)
print
(
sections
)
for
section
in
sections
:
options
=
cfg
[
key
].
options
(
section
)
options
=
cfg
[
key
].
options
(
section
)
print
(
section
)
print
(
options
)
for
option
in
options
:
print
(
option
,
'='
,
cfg
[
key
].
Get
(
section
,
option
))
print
(
option
,
'='
,
cfg
[
key
].
Get
(
section
,
option
))
dumpCfg
(
idleConf
.
defaultCfg
)
dumpCfg
(
idleConf
.
userCfg
)
print
(
idleConf
.
userCfg
[
'main'
].
Get
(
'Theme'
,
'name'
))
print
(
idleConf
.
userCfg
[
'main'
].
Get
(
'Theme'
,
'name'
))
#print idleConf.userCfg['highlight'].GetDefHighlight('Foo','normal')
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment