A modest indentation proposal

C. Laurence Gonsalves clgonsal at kami.com
Tue Dec 4 12:07:47 EST 2001


On Sat, 01 Dec 2001 00:46:42 GMT, Fredrik Lundh <fredrik at pythonware.com> wrote:
>> I believe effbot and the other people at Python Labs are working
>> on a "refactoring browser" for Python.
>
>Secret Labs != Python Labs.
>
>and yes, we have a refactoring browser for PythonWorks.  it
>does a lot more than keeping the indentation intact, though;
>it helps you reorganize code (inline functions, move code
>fragments into a separate functions, encapsulate attributes,
>rename classes/methods/attributes, get rid of arguments,
>etc) while doing its best to make sure that the resulting code
>has *exactly* the same meaning as before.

If I have the following piece of code to start with:

    while A():
        B()
        C()
        if D():
            E()
            F()
    I()
    J()

then suppose I paste a chunk of code after the "F()" line. What
indentation would your refactoring browser give that new chunk of code?
There are three possible valid indentations, and unless your editor is
smart enough that it can actually understand what your code is supposed
to do, I don't see how it can make the right decision.

I think this is the problem Erann is getting at: Python doesn't have any
(redundant) notation after a block closing that indicates that a block
was closed. It does however have redundant information before a block
opening (the colon). Because of this (the lack of redundant info at the
end of a scope), editors cannot always determine how to auto-indent
pasted chunks of code, because there are multiple "right answers" for
certain lines.

I don't actually like Erann's semicolon suggestion though. I think it
would have equally annoying problems, in addition to breaking all of the
code that people wrote in Python when they first switched from
C/C++/Java... :-)

Incidently, I ran into a related problem a couple of years ago when I
was trying to make mappings in VIM for [{ and ]} that worked in Python
code. In VIM, [{ and ]} normally go to the beginning or end of the
current scope, assuming your language uses curly-braces for scoping
blocks. So if I was on the "E()" line of the following piece of C code:

    while (A()) {
        B();
        C();
        if (D()) {
            E();
            F();
        }
    }
    I();
    J();

and then I hit [{, it would bring me to the D() line. Hitting [{ again
would bring me to the A() line.

Going in the other direction, if I started at the E() line again,
hitting ]} would bring me to the first curly brace after the F() line.
Hitting ]} again would bring me to the next curly brace.

The Python equivalent I wrote worked very well for [{. Using the Python
code at the top of this post, starting at the E() line, and then hitting
[{ would bring you to the D() line, and hitting [{ again would bring you
to the A() line.

Unfortunately, ]} didn't work so well. Starting at the E() line,
hitting ]} would bring you to the I() line. So it actually caused the
cursor to move two scopes. This is unavoidable, because there is no
character position after the F() but before the I() that is inside the
while but outside of the if.

-- 
  C. Laurence Gonsalves
  clgonsal at kami.com



More information about the Python-list mailing list