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
|
||||
|
||||
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
|
||||
at the top of each IDLE edit window which provides block structure
|
||||
hints. These hints are the lines which contain the block opening
|
||||
|
@ -12,12 +12,11 @@ the context hints pane.
|
|||
"""
|
||||
import Tkinter
|
||||
from configHandler import idleConf
|
||||
from PyShell import PyShell
|
||||
from sets import Set
|
||||
import re
|
||||
|
||||
BLOCKOPENERS = dict([(x, None) for x in ("class", "def", "elif", "else",
|
||||
"except", "finally", "for", "if",
|
||||
"try", "while")])
|
||||
BLOCKOPENERS = Set(["class", "def", "elif", "else", "except", "finally", "for",
|
||||
"if", "try", "while"])
|
||||
INFINITY = 1 << 30
|
||||
UPDATEINTERVAL = 100 # millisec
|
||||
FONTUPDATEINTERVAL = 1000 # millisec
|
||||
|
@ -33,11 +32,7 @@ class CodeContext:
|
|||
"bgcolor", type="str", default="LightGray")
|
||||
fgcolor = idleConf.GetOption("extensions", "CodeContext",
|
||||
"fgcolor", type="str", default="Black")
|
||||
default_on = idleConf.GetOption("extensions", "CodeContext",
|
||||
"default_on", type="int", default=0)
|
||||
def __init__(self, editwin):
|
||||
if isinstance(editwin, PyShell):
|
||||
return
|
||||
self.editwin = editwin
|
||||
self.text = editwin.text
|
||||
self.textfont = self.text["font"]
|
||||
|
@ -45,7 +40,9 @@ class CodeContext:
|
|||
# Dummy line, which starts the "block" of the whole document:
|
||||
self.info = list(self.interesting_lines(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.editwin.setvar('<<toggle-code-context>>', True)
|
||||
# Start two update cycles, one for context lines, one for font changes.
|
||||
|
@ -67,6 +64,9 @@ class CodeContext:
|
|||
else:
|
||||
self.label.destroy()
|
||||
self.label = None
|
||||
idleConf.SetOption("extensions", "CodeContext", "visible",
|
||||
str(self.label is not None))
|
||||
idleConf.SaveUserCfgFiles()
|
||||
|
||||
def get_line_info(self, linenum):
|
||||
"""Get the line indent value, text, and any block start keyword
|
||||
|
|
|
@ -751,14 +751,16 @@ class EditorWindow:
|
|||
traceback.print_exc()
|
||||
|
||||
def get_standard_extension_names(self):
|
||||
return idleConf.GetExtensions()
|
||||
return idleConf.GetExtensions(editor_only=True)
|
||||
|
||||
def load_extension(self, name):
|
||||
mod = __import__(name, globals(), locals(), [])
|
||||
cls = getattr(mod, name)
|
||||
keydefs = idleConf.GetExtensionBindings(name)
|
||||
if hasattr(cls, "menudefs"):
|
||||
self.fill_menus(cls.menudefs, keydefs)
|
||||
ins = cls(self)
|
||||
self.extensions[name] = ins
|
||||
keydefs=idleConf.GetExtensionBindings(name)
|
||||
if keydefs:
|
||||
self.apply_bindings(keydefs)
|
||||
for vevent in keydefs.keys():
|
||||
|
@ -770,8 +772,6 @@ class EditorWindow:
|
|||
methodname = methodname + "_event"
|
||||
if hasattr(ins, methodname):
|
||||
self.text.bind(vevent, getattr(ins, methodname))
|
||||
if hasattr(ins, "menudefs"):
|
||||
self.fill_menus(ins.menudefs, keydefs)
|
||||
return ins
|
||||
|
||||
def apply_bindings(self, keydefs=None):
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
What's New in IDLE 1.1a0?
|
||||
===================================
|
||||
=========================
|
||||
|
||||
*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
|
||||
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?
|
||||
===================================
|
||||
=======================
|
||||
|
||||
*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?
|
||||
===================================
|
||||
===========================================
|
||||
|
||||
*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?
|
||||
===================================
|
||||
===========================================
|
||||
|
||||
*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?
|
||||
===================================
|
||||
=========================
|
||||
|
||||
*Release date: 29-Jun-2003*
|
||||
|
||||
|
@ -131,7 +139,7 @@ What's New in IDLE 1.0b2?
|
|||
|
||||
|
||||
What's New in IDLEfork 0.9b1?
|
||||
===================================
|
||||
=============================
|
||||
|
||||
*Release date: 02-Jun-2003*
|
||||
|
||||
|
|
|
@ -806,6 +806,9 @@ class PyShell(OutputWindow):
|
|||
#
|
||||
self.pollinterval = 50 # millisec
|
||||
|
||||
def get_standard_extension_names(self):
|
||||
return idleConf.GetExtensions(shell_only=True)
|
||||
|
||||
reading = False
|
||||
executing = False
|
||||
canceled = False
|
||||
|
|
|
@ -1,25 +1,31 @@
|
|||
# config-extensions.def
|
||||
#
|
||||
# IDLE reads several config files to determine user preferences. This
|
||||
# file is the default configuration file for IDLE extensions settings.
|
||||
#
|
||||
# Each extension must have at least one section, named after the extension
|
||||
# module. This section must contain an 'enable' item (=1 to enable the
|
||||
# extension, =0 to disable it) and also contain any other general configuration
|
||||
# items for the extension. Each extension must define at least one section
|
||||
# named ExtensionName_bindings or ExtensionName_cfgBindings. If present,
|
||||
# ExtensionName_bindings defines virtual event bindings for the extension that
|
||||
# are not user re-configurable. 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.)
|
||||
|
||||
# extension, =0 to disable it), it may contain 'enable_editor' or 'enable_shell'
|
||||
# items, to apply it only to editor/shell windows, and may also contain any
|
||||
# other general configuration items for the extension.
|
||||
#
|
||||
# Each extension must define at least one section named ExtensionName_bindings
|
||||
# or ExtensionName_cfgBindings. If present, ExtensionName_bindings defines
|
||||
# virtual event bindings for the extension that are not user re-configurable.
|
||||
# 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
|
||||
# key bindings and default values. To customize, create
|
||||
# ~/.idlerc/config-extensions.cfg and append the appropriate customized
|
||||
# section(s). Those sections will override the defaults in this file.
|
||||
|
||||
#
|
||||
# Note: If a keybinding is already in use when the extension is
|
||||
# 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
|
||||
# information on creating IDLE extensions.
|
||||
|
||||
|
@ -65,8 +71,9 @@ check-restore=<KeyPress>
|
|||
|
||||
[CodeContext]
|
||||
enable=1
|
||||
enable_shell=0
|
||||
numlines=3
|
||||
default_on=0
|
||||
visible=0
|
||||
bgcolor=LightGray
|
||||
fgcolor=Black
|
||||
[CodeContext_bindings]
|
||||
|
|
|
@ -215,7 +215,8 @@ class IdleConf:
|
|||
sys.stderr.write(warn)
|
||||
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
|
||||
configuration section/option or return a default. If type is specified,
|
||||
|
@ -224,13 +225,16 @@ class IdleConf:
|
|||
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 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):
|
||||
return self.userCfg[configType].Get(section, option, type=type)
|
||||
elif self.defaultCfg[configType].has_option(section,option):
|
||||
return self.defaultCfg[configType].Get(section, option, type=type)
|
||||
else: #returning default, print warning
|
||||
if warn_on_default:
|
||||
warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n'
|
||||
' problem retrieving configration option %r\n'
|
||||
' from section %r.\n'
|
||||
|
@ -239,6 +243,12 @@ class IdleConf:
|
|||
sys.stderr.write(warning)
|
||||
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):
|
||||
"""
|
||||
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='')
|
||||
|
||||
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.
|
||||
activeOnly - boolean, if true only return active (enabled) extensions
|
||||
active_only - boolean, if true only return active (enabled) extensions
|
||||
"""
|
||||
extns=self.RemoveKeyBindNames(
|
||||
self.GetSectionList('default','extensions'))
|
||||
|
@ -368,12 +378,22 @@ class IdleConf:
|
|||
for extn in userExtns:
|
||||
if extn not in extns: #user has added own extension
|
||||
extns.append(extn)
|
||||
if activeOnly:
|
||||
if active_only:
|
||||
activeExtns=[]
|
||||
for extn in extns:
|
||||
if self.GetOption('extensions',extn,'enable',default=1,
|
||||
if self.GetOption('extensions', extn, 'enable', default=True,
|
||||
type='bool'):
|
||||
#the extension is enabled
|
||||
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
|
||||
else:
|
||||
|
@ -401,7 +421,7 @@ class IdleConf:
|
|||
"""
|
||||
extName=None
|
||||
vEvent='<<'+virtualEvent+'>>'
|
||||
for extn in self.GetExtensions(activeOnly=0):
|
||||
for extn in self.GetExtensions(active_only=0):
|
||||
for event in self.GetExtensionKeys(extn).keys():
|
||||
if event == vEvent:
|
||||
extName=extn
|
||||
|
@ -482,7 +502,7 @@ class IdleConf:
|
|||
in an extension is already in use, that binding is disabled.
|
||||
"""
|
||||
keySet=self.GetCoreKeys(keySetName)
|
||||
activeExtns=self.GetExtensions(activeOnly=1)
|
||||
activeExtns=self.GetExtensions(active_only=1)
|
||||
for extn in activeExtns:
|
||||
extKeys=self.__GetRawExtensionKeys(extn)
|
||||
if extKeys: #the extension defines keybindings
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue