Title: CodeContext - an extension to show you where you are
Type: Stage:
Components: IDLE Versions:
Status: closed Resolution: accepted
Dependencies: Superseder:
Assigned To: kbk Nosy List: kbk, noamr, taleinat
Priority: normal Keywords: patch

Created on 2004-04-16 08:40 by noamr, last changed 2005-11-18 19:55 by kbk. This issue is now closed.

File name Uploaded Description Edit noamr, 2004-04-16 08:40
codecontextdiff noamr, 2004-04-27 21:24 Diffs to several files, to allow CodeContext intuitive showing and hiding noamr, 2004-09-07 22:42 CodeContext with an improved update algorithm noamr, 2005-02-04 00:17 The same improved algorithm, better documentation
Messages (13)
msg45776 - (view) Author: Noam Raphael (noamr) * Date: 2004-04-16 08:40
Have you ever edited a code, and did not know exactly
which block you were closing? Or didn't know exactly
even in which block you were?
This extension solves this problem, by adding a few
lines (3 by default) above the IDLE edit box, which
show you exactly where you are in your code.
For example, you may be editing a code with three
indentation levels (has three tabs on its left), but to
find the reason for this - to find what is the meaning
of your block - you have to scroll upwards a long distance.
CodeContext will add three lines of text above your
edit box, so your editing window will look like this:
Class MyClass:
    def myMethod(self, arg1, arg2):   <- auto-updated
        if something_happens:
            i += 1
            print "hello"                       <- You
edit here
So you can know that i is incremented by 1, in the
method myMethod of class MyClass, and only if

To make this extension work, you have to put the
attached file,, in your IDLE directory,
and add these lines to config-extensions.def:

A note to KBK: I think this extension can go into the
Python distribution. If you don't like it, or if you
want a testing period, you can put "enable=0" instead
of "enable=1". In this way, most users will not even
know CodeContext exists, but "power users" will be able
to put "enable=1" and have CodeContext if they like it
(- I like it).

Best wishes,
Noam Raphael
msg45777 - (view) Author: Kurt B. Kaiser (kbk) * (Python committer) Date: 2004-04-21 20:09
Logged In: YES 

Cool Extension!  Thanks! 1.1
config-extensions.def 1.13
msg45778 - (view) Author: Noam Raphael (noamr) * Date: 2004-04-22 20:11
Logged In: YES 

I'm glad you like it!
Thanks for the changes - your English is certainly better
than mine.

A buglet you made - in line 91 you added "elif" as a block
opener which should show the previous block opener of the
same indentation, which is a good idea, but you wrote:
    if opener == "else" or "elif":
which is an expression which always yields True. It caused
all block openers to be displayed, not only the relevant ones.
Change it to
    if opener in ("else", "elif"):
and it will work fine.

Happy Israel Independence Day!
(I know you probably don't celebrate it, but it is on 27
April this year)
msg45779 - (view) Author: Kurt B. Kaiser (kbk) * (Python committer) Date: 2004-04-26 22:28
Logged In: YES 

Yeah, I noticed that problem and wasn't sure if I had
caused it.  Thanks, fixed. 1.3.

Sorry I took so long getting back, for some reason I'm
not getting mail from SF when a Tracker item changes
(though I don't have a problem sending mail to myself via

I added an entry for Code Context on the Options menu,
it toggles the context pane.  Any suggestion for a keybinding?

A remaining problem is the text in the Label doesn't quite line
up with the text in the main pane.  Adding a pad of one space
makes it almost perfect.  But maybe using a Text widget instead
of a Label would fix it 100%?
msg45780 - (view) Author: Noam Raphael (noamr) * Date: 2004-04-27 21:24
Logged In: YES 

  I think that showing / not showing the Code Context panel
should be a persistent setting - if the user wants it, it
will appear, and if he doesn't, it won't. The concept of "it
has an initial state, and you can change it afterwards if
you like" is confusing. Using a persistent setting makes a
keyboard shortcut unnecessary - I think that usually the
user will be happy with what he likes, and won't hide/show
the panel many times.
  So I made the <<toggle-code-context>> event save the new
setting in the user's configuration file. The new setting
will be applied also to new windows opened in the same
session. This required me to add a SetOption method to
configHandler.IdleConf. Also, the initialization of the
CodeContext instance required the menu item to be already
installed, but EditorWindow.load_extension installs the menu
items after it initializes the extension's instance. It
turns out that the menu items can be installed before the
instance initialization, so I changed it.
  Another problem was that the Code Context menu item was
installed on shell windows, but wasn't functioning, which
was quite confusing. So I added new optional configurations
for extensions: enable_shell and enable_editor, which allow
you to write extensions only for the editor/shell window,
without using the "isinstance(editwin, PyShell)" trick.
  About using a Text widget instead of a Label - it may
work, I don't know, but making the Label behave as I wanted
was hard enough, and it looks fine to me as it is, so I
leave it for now.

Bye Bye,
msg45781 - (view) Author: Kurt B. Kaiser (kbk) * (Python committer) Date: 2004-06-06 01:33
Logged In: YES 

Checked in Noam Raphael's improvements. 1.4 et. al.
msg45782 - (view) Author: Noam Raphael (noamr) * Date: 2004-09-07 22:42
Logged In: YES 

I improved the algorithm for finding the context lines, so
it now scans the minimum number of lines it needs in order
to update the panel - it uses the information it already has
in a better way. This makes the scrolling of long modules
more "streaming", on my not-that-new computer.
I tried it, and it seems to work just as good as the old
algorithm - it produces the same results.
msg45783 - (view) Author: Kurt B. Kaiser (kbk) * (Python committer) Date: 2005-02-02 22:17
Logged In: YES 

1. Please improve the doc string for interesting_lines(),
it's no longer a generator.
2. You removed a comment from update_label() which
was helpful when studying the code.  What does it do now?
3. The variable 'l' should not be used because it's hard
to discriminate from '1'.  See PEP 8, Naming Conventions.
I suggest 'ln' if it must be short, otherwise 'line'
msg45784 - (view) Author: Noam Raphael (noamr) * Date: 2005-02-04 00:17
Logged In: YES 

Thanks for your comments.
What do you think of the new patch?
msg45785 - (view) Author: Tal Einat (taleinat) * (Python committer) Date: 2005-08-18 15:28
Logged In: YES 

This fixes the text alignment:
(just replace te appropriate code in 
toggle_code_context_event with this)

        if not self.label:
            self.padding_frame = Tkinter.Frame(,
            self.label = Tkinter.Label(self.padding_frame,
                                       text="\n" * (self.numlines - 1),
                                       anchor="w", justify="left",
                                       bg=self.bgcolor, fg=self.fgcolor,
                                       width=1, # Don't request more 
than we get
            self.label.pack(side="top", fill="x", expand=1,
                            padx=4, pady=0)
            self.padding_frame.pack(side="top", fill="x", 
                                    padx=0, pady=0,
            self.label = None

Sorry it's not a diff...
msg45786 - (view) Author: Kurt B. Kaiser (kbk) * (Python committer) Date: 2005-10-03 20:13
Logged In: YES 

Checked in 03Feb05 patch as rev 1.5

Tweaked comments, docstrings, and names;
checked in as rev 1.6

Incorporated Tal Einat's alignment suggestion;
checked in as rev 1.7

It appears to me that the stopindent mechanism to terminate
processing a region is now redundant.  I can comment out
the 'break' in get_context()  [new name!] and everything
still seems to work ok.  Am I missing something?
msg45787 - (view) Author: Noam Raphael (noamr) * Date: 2005-10-09 22:57
Logged In: YES 

It's an optimization: If we scroll up, we know that there
can't be a new context line with a smaller indentation than
that of the deleted context lines, so it lets us stop
searching sooner.

For example, take this class:

class Babonag(object):

    # This is a big class, and a lot of methods are defined

    def ping():
        print "ping"

    def pong():
        pring "pong"

Now say we scroll up: the first line was 'print "pong"', and
it is now 'print "ping"'. If we use stopindent, we know that
we can stop immediately after we have reached "def ping",
because we know that there can't be a line with a smaller
indentation than that. If we don't, we have to scan up to
"class Babonag" to be certain that there aren't any extra
context lines.

(By the way, well done for the tweaked comments docstrings
and names. They seem a lot cleaner.)

msg45788 - (view) Author: Kurt B. Kaiser (kbk) * (Python committer) Date: 2005-11-18 19:55
Logged In: YES 

OK, thanks.
Date User Action Args
2004-04-16 08:40:34noamrcreate