mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Noam Raphel: Further developemt of CodeContext feature.
The visibility state of the code context pane is now persistent between sessions and the pane does not appear in the shell window. M CodeContext.py M EditorWindow.py M NEWS.txt M PyShell.py M config-extensions.def M configHandler.py
This commit is contained in:
parent
cfa157d808
commit
4d5bc6031c
6 changed files with 86 additions and 48 deletions
|
@ -1,6 +1,6 @@
|
||||||
"""CodeContext - Display the block context of code at top of edit window
|
"""CodeContext - Display the block context of code at top of edit window
|
||||||
|
|
||||||
Once code has scolled off the top of the screen, it can be difficult
|
Once code has scrolled off the top of the screen, it can be difficult
|
||||||
to determine which block you are in. This extension implements a pane
|
to determine which block you are in. This extension implements a pane
|
||||||
at the top of each IDLE edit window which provides block structure
|
at the top of each IDLE edit window which provides block structure
|
||||||
hints. These hints are the lines which contain the block opening
|
hints. These hints are the lines which contain the block opening
|
||||||
|
@ -12,12 +12,11 @@ the context hints pane.
|
||||||
"""
|
"""
|
||||||
import Tkinter
|
import Tkinter
|
||||||
from configHandler import idleConf
|
from configHandler import idleConf
|
||||||
from PyShell import PyShell
|
from sets import Set
|
||||||
import re
|
import re
|
||||||
|
|
||||||
BLOCKOPENERS = dict([(x, None) for x in ("class", "def", "elif", "else",
|
BLOCKOPENERS = Set(["class", "def", "elif", "else", "except", "finally", "for",
|
||||||
"except", "finally", "for", "if",
|
"if", "try", "while"])
|
||||||
"try", "while")])
|
|
||||||
INFINITY = 1 << 30
|
INFINITY = 1 << 30
|
||||||
UPDATEINTERVAL = 100 # millisec
|
UPDATEINTERVAL = 100 # millisec
|
||||||
FONTUPDATEINTERVAL = 1000 # millisec
|
FONTUPDATEINTERVAL = 1000 # millisec
|
||||||
|
@ -33,11 +32,7 @@ class CodeContext:
|
||||||
"bgcolor", type="str", default="LightGray")
|
"bgcolor", type="str", default="LightGray")
|
||||||
fgcolor = idleConf.GetOption("extensions", "CodeContext",
|
fgcolor = idleConf.GetOption("extensions", "CodeContext",
|
||||||
"fgcolor", type="str", default="Black")
|
"fgcolor", type="str", default="Black")
|
||||||
default_on = idleConf.GetOption("extensions", "CodeContext",
|
|
||||||
"default_on", type="int", default=0)
|
|
||||||
def __init__(self, editwin):
|
def __init__(self, editwin):
|
||||||
if isinstance(editwin, PyShell):
|
|
||||||
return
|
|
||||||
self.editwin = editwin
|
self.editwin = editwin
|
||||||
self.text = editwin.text
|
self.text = editwin.text
|
||||||
self.textfont = self.text["font"]
|
self.textfont = self.text["font"]
|
||||||
|
@ -45,7 +40,9 @@ class CodeContext:
|
||||||
# Dummy line, which starts the "block" of the whole document:
|
# Dummy line, which starts the "block" of the whole document:
|
||||||
self.info = list(self.interesting_lines(1))
|
self.info = list(self.interesting_lines(1))
|
||||||
self.lastfirstline = 1
|
self.lastfirstline = 1
|
||||||
if self.default_on:
|
visible = idleConf.GetOption("extensions", "CodeContext",
|
||||||
|
"visible", type="bool", default=False)
|
||||||
|
if visible:
|
||||||
self.toggle_code_context_event()
|
self.toggle_code_context_event()
|
||||||
self.editwin.setvar('<<toggle-code-context>>', True)
|
self.editwin.setvar('<<toggle-code-context>>', True)
|
||||||
# Start two update cycles, one for context lines, one for font changes.
|
# Start two update cycles, one for context lines, one for font changes.
|
||||||
|
@ -67,6 +64,9 @@ class CodeContext:
|
||||||
else:
|
else:
|
||||||
self.label.destroy()
|
self.label.destroy()
|
||||||
self.label = None
|
self.label = None
|
||||||
|
idleConf.SetOption("extensions", "CodeContext", "visible",
|
||||||
|
str(self.label is not None))
|
||||||
|
idleConf.SaveUserCfgFiles()
|
||||||
|
|
||||||
def get_line_info(self, linenum):
|
def get_line_info(self, linenum):
|
||||||
"""Get the line indent value, text, and any block start keyword
|
"""Get the line indent value, text, and any block start keyword
|
||||||
|
|
|
@ -751,14 +751,16 @@ class EditorWindow:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
def get_standard_extension_names(self):
|
def get_standard_extension_names(self):
|
||||||
return idleConf.GetExtensions()
|
return idleConf.GetExtensions(editor_only=True)
|
||||||
|
|
||||||
def load_extension(self, name):
|
def load_extension(self, name):
|
||||||
mod = __import__(name, globals(), locals(), [])
|
mod = __import__(name, globals(), locals(), [])
|
||||||
cls = getattr(mod, name)
|
cls = getattr(mod, name)
|
||||||
|
keydefs = idleConf.GetExtensionBindings(name)
|
||||||
|
if hasattr(cls, "menudefs"):
|
||||||
|
self.fill_menus(cls.menudefs, keydefs)
|
||||||
ins = cls(self)
|
ins = cls(self)
|
||||||
self.extensions[name] = ins
|
self.extensions[name] = ins
|
||||||
keydefs=idleConf.GetExtensionBindings(name)
|
|
||||||
if keydefs:
|
if keydefs:
|
||||||
self.apply_bindings(keydefs)
|
self.apply_bindings(keydefs)
|
||||||
for vevent in keydefs.keys():
|
for vevent in keydefs.keys():
|
||||||
|
@ -770,8 +772,6 @@ class EditorWindow:
|
||||||
methodname = methodname + "_event"
|
methodname = methodname + "_event"
|
||||||
if hasattr(ins, methodname):
|
if hasattr(ins, methodname):
|
||||||
self.text.bind(vevent, getattr(ins, methodname))
|
self.text.bind(vevent, getattr(ins, methodname))
|
||||||
if hasattr(ins, "menudefs"):
|
|
||||||
self.fill_menus(ins.menudefs, keydefs)
|
|
||||||
return ins
|
return ins
|
||||||
|
|
||||||
def apply_bindings(self, keydefs=None):
|
def apply_bindings(self, keydefs=None):
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
What's New in IDLE 1.1a0?
|
What's New in IDLE 1.1a0?
|
||||||
===================================
|
=========================
|
||||||
|
|
||||||
*Release date: XX-XXX-2004*
|
*Release date: XX-XXX-2004*
|
||||||
|
|
||||||
|
- CodeContext hint pane visibility state is now persistent across sessions.
|
||||||
|
The pane no longer appears in the shell window. Added capability to limit
|
||||||
|
extensions to shell window or editor windows. Noam Raphael addition
|
||||||
|
to Patch 936169.
|
||||||
|
|
||||||
|
- Paragraph reformat width is now a configurable parameter in the
|
||||||
|
Options GUI.
|
||||||
|
|
||||||
- New Extension: CodeContext. Provides block structuring hints for code
|
- New Extension: CodeContext. Provides block structuring hints for code
|
||||||
which has scrolled above an edit window. Patch 936169 Noam Raphael.
|
which has scrolled above an edit window. Patch 936169 Noam Raphael.
|
||||||
|
|
||||||
|
@ -52,7 +60,7 @@ What's New in IDLE 1.1a0?
|
||||||
|
|
||||||
|
|
||||||
What's New in IDLE 1.0?
|
What's New in IDLE 1.0?
|
||||||
===================================
|
=======================
|
||||||
|
|
||||||
*Release date: 29-Jul-2003*
|
*Release date: 29-Jul-2003*
|
||||||
|
|
||||||
|
@ -61,7 +69,7 @@ What's New in IDLE 1.0?
|
||||||
|
|
||||||
|
|
||||||
What's New in IDLE 1.0 release candidate 2?
|
What's New in IDLE 1.0 release candidate 2?
|
||||||
===================================
|
===========================================
|
||||||
|
|
||||||
*Release date: 24-Jul-2003*
|
*Release date: 24-Jul-2003*
|
||||||
|
|
||||||
|
@ -69,7 +77,7 @@ What's New in IDLE 1.0 release candidate 2?
|
||||||
|
|
||||||
|
|
||||||
What's New in IDLE 1.0 release candidate 1?
|
What's New in IDLE 1.0 release candidate 1?
|
||||||
===================================
|
===========================================
|
||||||
|
|
||||||
*Release date: 18-Jul-2003*
|
*Release date: 18-Jul-2003*
|
||||||
|
|
||||||
|
@ -90,7 +98,7 @@ What's New in IDLE 1.0 release candidate 1?
|
||||||
|
|
||||||
|
|
||||||
What's New in IDLE 1.0b2?
|
What's New in IDLE 1.0b2?
|
||||||
===================================
|
=========================
|
||||||
|
|
||||||
*Release date: 29-Jun-2003*
|
*Release date: 29-Jun-2003*
|
||||||
|
|
||||||
|
@ -131,7 +139,7 @@ What's New in IDLE 1.0b2?
|
||||||
|
|
||||||
|
|
||||||
What's New in IDLEfork 0.9b1?
|
What's New in IDLEfork 0.9b1?
|
||||||
===================================
|
=============================
|
||||||
|
|
||||||
*Release date: 02-Jun-2003*
|
*Release date: 02-Jun-2003*
|
||||||
|
|
||||||
|
|
|
@ -806,6 +806,9 @@ class PyShell(OutputWindow):
|
||||||
#
|
#
|
||||||
self.pollinterval = 50 # millisec
|
self.pollinterval = 50 # millisec
|
||||||
|
|
||||||
|
def get_standard_extension_names(self):
|
||||||
|
return idleConf.GetExtensions(shell_only=True)
|
||||||
|
|
||||||
reading = False
|
reading = False
|
||||||
executing = False
|
executing = False
|
||||||
canceled = False
|
canceled = False
|
||||||
|
|
|
@ -1,25 +1,31 @@
|
||||||
|
# config-extensions.def
|
||||||
|
#
|
||||||
# IDLE reads several config files to determine user preferences. This
|
# IDLE reads several config files to determine user preferences. This
|
||||||
# file is the default configuration file for IDLE extensions settings.
|
# file is the default configuration file for IDLE extensions settings.
|
||||||
#
|
#
|
||||||
# Each extension must have at least one section, named after the extension
|
# Each extension must have at least one section, named after the extension
|
||||||
# module. This section must contain an 'enable' item (=1 to enable the
|
# module. This section must contain an 'enable' item (=1 to enable the
|
||||||
# extension, =0 to disable it) and also contain any other general configuration
|
# extension, =0 to disable it), it may contain 'enable_editor' or 'enable_shell'
|
||||||
# items for the extension. Each extension must define at least one section
|
# items, to apply it only to editor/shell windows, and may also contain any
|
||||||
# named ExtensionName_bindings or ExtensionName_cfgBindings. If present,
|
# other general configuration items for the extension.
|
||||||
# ExtensionName_bindings defines virtual event bindings for the extension that
|
#
|
||||||
# are not user re-configurable. If present, ExtensionName_cfgBindings
|
# Each extension must define at least one section named ExtensionName_bindings
|
||||||
# defines virtual event bindings for the extension that may be sensibly
|
# or ExtensionName_cfgBindings. If present, ExtensionName_bindings defines
|
||||||
# re-configured. If there are no keybindings for a menus' virtual events,
|
# virtual event bindings for the extension that are not user re-configurable.
|
||||||
# include lines like <<toggle-code-context>>= (See [CodeContext], below.)
|
# If present, ExtensionName_cfgBindings defines virtual event bindings for the
|
||||||
|
# extension that may be sensibly re-configured.
|
||||||
|
#
|
||||||
|
# If there are no keybindings for a menus' virtual events, include lines like
|
||||||
|
# <<toggle-code-context>>= (See [CodeContext], below.)
|
||||||
|
#
|
||||||
# Currently it is necessary to manually modify this file to change extension
|
# Currently it is necessary to manually modify this file to change extension
|
||||||
# key bindings and default values. To customize, create
|
# key bindings and default values. To customize, create
|
||||||
# ~/.idlerc/config-extensions.cfg and append the appropriate customized
|
# ~/.idlerc/config-extensions.cfg and append the appropriate customized
|
||||||
# section(s). Those sections will override the defaults in this file.
|
# section(s). Those sections will override the defaults in this file.
|
||||||
|
#
|
||||||
# Note: If a keybinding is already in use when the extension is
|
# Note: If a keybinding is already in use when the extension is
|
||||||
# loaded, the extension's virtual event's keybinding will be set to ''.
|
# loaded, the extension's virtual event's keybinding will be set to ''.
|
||||||
|
#
|
||||||
# See config-keys.def for notes on specifying keys and extend.txt for
|
# See config-keys.def for notes on specifying keys and extend.txt for
|
||||||
# information on creating IDLE extensions.
|
# information on creating IDLE extensions.
|
||||||
|
|
||||||
|
@ -65,8 +71,9 @@ check-restore=<KeyPress>
|
||||||
|
|
||||||
[CodeContext]
|
[CodeContext]
|
||||||
enable=1
|
enable=1
|
||||||
|
enable_shell=0
|
||||||
numlines=3
|
numlines=3
|
||||||
default_on=0
|
visible=0
|
||||||
bgcolor=LightGray
|
bgcolor=LightGray
|
||||||
fgcolor=Black
|
fgcolor=Black
|
||||||
[CodeContext_bindings]
|
[CodeContext_bindings]
|
||||||
|
|
|
@ -215,7 +215,8 @@ class IdleConf:
|
||||||
sys.stderr.write(warn)
|
sys.stderr.write(warn)
|
||||||
return userDir
|
return userDir
|
||||||
|
|
||||||
def GetOption(self, configType, section, option, default=None, type=None):
|
def GetOption(self, configType, section, option, default=None, type=None,
|
||||||
|
warn_on_default=True):
|
||||||
"""
|
"""
|
||||||
Get an option value for given config type and given general
|
Get an option value for given config type and given general
|
||||||
configuration section/option or return a default. If type is specified,
|
configuration section/option or return a default. If type is specified,
|
||||||
|
@ -224,21 +225,30 @@ class IdleConf:
|
||||||
fallback to a useable passed-in default if the option isn't present in
|
fallback to a useable passed-in default if the option isn't present in
|
||||||
either the user or the default configuration.
|
either the user or the default configuration.
|
||||||
configType must be one of ('main','extensions','highlight','keys')
|
configType must be one of ('main','extensions','highlight','keys')
|
||||||
If a default is returned a warning is printed to stderr.
|
If a default is returned, and warn_on_default is True, a warning is
|
||||||
|
printed to stderr.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
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)
|
return self.userCfg[configType].Get(section, option, type=type)
|
||||||
elif self.defaultCfg[configType].has_option(section,option):
|
elif self.defaultCfg[configType].has_option(section,option):
|
||||||
return self.defaultCfg[configType].Get(section, option, type=type)
|
return self.defaultCfg[configType].Get(section, option, type=type)
|
||||||
else: #returning default, print warning
|
else: #returning default, print warning
|
||||||
warning=('\n Warning: configHandler.py - IdleConf.GetOption -\n'
|
if warn_on_default:
|
||||||
' problem retrieving configration option %r\n'
|
warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n'
|
||||||
' from section %r.\n'
|
' problem retrieving configration option %r\n'
|
||||||
' returning default value: %r\n' %
|
' from section %r.\n'
|
||||||
(option, section, default))
|
' returning default value: %r\n' %
|
||||||
sys.stderr.write(warning)
|
(option, section, default))
|
||||||
|
sys.stderr.write(warning)
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
def SetOption(self, configType, section, option, value):
|
||||||
|
"""In user's config file, set section's option to value.
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.userCfg[configType].SetOption(section, option, value)
|
||||||
|
|
||||||
def GetSectionList(self, configSet, configType):
|
def GetSectionList(self, configSet, configType):
|
||||||
"""
|
"""
|
||||||
Get a list of sections from either the user or default config for
|
Get a list of sections from either the user or default config for
|
||||||
|
@ -356,10 +366,10 @@ class IdleConf:
|
||||||
"""
|
"""
|
||||||
return self.GetOption('main','Keys','name',default='')
|
return self.GetOption('main','Keys','name',default='')
|
||||||
|
|
||||||
def GetExtensions(self, activeOnly=1):
|
def GetExtensions(self, active_only=True, editor_only=False, shell_only=False):
|
||||||
"""
|
"""
|
||||||
Gets a list of all idle extensions declared in the config files.
|
Gets a list of all idle extensions declared in the config files.
|
||||||
activeOnly - boolean, if true only return active (enabled) extensions
|
active_only - boolean, if true only return active (enabled) extensions
|
||||||
"""
|
"""
|
||||||
extns=self.RemoveKeyBindNames(
|
extns=self.RemoveKeyBindNames(
|
||||||
self.GetSectionList('default','extensions'))
|
self.GetSectionList('default','extensions'))
|
||||||
|
@ -368,13 +378,23 @@ class IdleConf:
|
||||||
for extn in userExtns:
|
for extn in userExtns:
|
||||||
if extn not in extns: #user has added own extension
|
if extn not in extns: #user has added own extension
|
||||||
extns.append(extn)
|
extns.append(extn)
|
||||||
if activeOnly:
|
if active_only:
|
||||||
activeExtns=[]
|
activeExtns=[]
|
||||||
for extn in extns:
|
for extn in extns:
|
||||||
if self.GetOption('extensions',extn,'enable',default=1,
|
if self.GetOption('extensions', extn, 'enable', default=True,
|
||||||
type='bool'):
|
type='bool'):
|
||||||
#the extension is enabled
|
#the extension is enabled
|
||||||
activeExtns.append(extn)
|
if editor_only or shell_only:
|
||||||
|
if editor_only:
|
||||||
|
option = "enable_editor"
|
||||||
|
else:
|
||||||
|
option = "enable_shell"
|
||||||
|
if self.GetOption('extensions', extn,option,
|
||||||
|
default=True, type='bool',
|
||||||
|
warn_on_default=False):
|
||||||
|
activeExtns.append(extn)
|
||||||
|
else:
|
||||||
|
activeExtns.append(extn)
|
||||||
return activeExtns
|
return activeExtns
|
||||||
else:
|
else:
|
||||||
return extns
|
return extns
|
||||||
|
@ -401,7 +421,7 @@ class IdleConf:
|
||||||
"""
|
"""
|
||||||
extName=None
|
extName=None
|
||||||
vEvent='<<'+virtualEvent+'>>'
|
vEvent='<<'+virtualEvent+'>>'
|
||||||
for extn in self.GetExtensions(activeOnly=0):
|
for extn in self.GetExtensions(active_only=0):
|
||||||
for event in self.GetExtensionKeys(extn).keys():
|
for event in self.GetExtensionKeys(extn).keys():
|
||||||
if event == vEvent:
|
if event == vEvent:
|
||||||
extName=extn
|
extName=extn
|
||||||
|
@ -482,7 +502,7 @@ class IdleConf:
|
||||||
in an extension is already in use, that binding is disabled.
|
in an extension is already in use, that binding is disabled.
|
||||||
"""
|
"""
|
||||||
keySet=self.GetCoreKeys(keySetName)
|
keySet=self.GetCoreKeys(keySetName)
|
||||||
activeExtns=self.GetExtensions(activeOnly=1)
|
activeExtns=self.GetExtensions(active_only=1)
|
||||||
for extn in activeExtns:
|
for extn in activeExtns:
|
||||||
extKeys=self.__GetRawExtensionKeys(extn)
|
extKeys=self.__GetRawExtensionKeys(extn)
|
||||||
if extKeys: #the extension defines keybindings
|
if extKeys: #the extension defines keybindings
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue