[IPython-dev] IPython 0.7.1.rc1 is ready

Fernando Perez Fernando.Perez at colorado.edu
Mon Jan 23 11:43:00 CST 2006


Ville Vainio wrote:
> On 1/23/06, Arnd Baecker <arnd.baecker at web.de> wrote:
> 
> 
>>Hmm, is this the one where pasting multiple lines of code,
>>including single empty lines, should work?
>>
>>For example, pasting the following does not work for me:
>>
>>##################################
>>def f(x):
>>    print x
>>
>>    print x+1
>>##################################
>>
>>In [2]: def f(x):
>>   ...:     print x
>>   ...:
>>
>>In [3]:     print x+1

Well, this feature is a balancing act of tricky heuristics.  It turns out that 
what you want CAN be made to work.  Try pasting this:

def f(x):
     print x

     print 'hi'

Here it is on my system:

In [8]: def f(x):
    ...:     print x
    ...:
    ...:     print 'hi'
    ...:

In [9]: f(1)
1
hi

The following, however, doesn't work:

def f(x):
     print x

     print 'hi'


In [10]: def f(x):
    ....:     print x
    ....:

In [11]:     print 'hi'
------------------------------------------------------------
    File "<ipython console>", line 1
      print 'hi'
      ^
SyntaxError: invalid syntax


In [12]:

The difference between those two seemingly identical chunks of code is that 
the first (that works) has the blank line with consistent indentation compared 
to the rest (the blank line has 4 spaces).  The second code has a purely empty 
blank line.  Note that the second case doesn't even work with plain python:

 >>> def f(x):
...     print x
...
 >>>     print 'hi'
   File "<stdin>", line 1
     print 'hi'
     ^
SyntaxError: invalid syntax

while the first does:

 >>> def f(x):
...     print x
...
...     print 'hi'
...
...
 >>>

So at least I've been able to:

1. Reach parity in behavior regarding lines with whitespace with plain python.

2. Make all of this work even when autoindent is active.

But it is true that the limitation of having the blank lines be consistently 
indented with their surroundings remains.  Given all the magic going on here, 
I think this is impossible to remove, or at least it would be trickier than 
I'm interested in trying to do.  I've already sunk MANY hours of work into 
this little beast alone.

> I admit to not have worked on this feature (it's on fernando's turf)
> but it seems so complicated that I'm starting to think we should add a
> magic %paste that would read a bunch of text and just terminate on
> some special sentinel, e.g. "-- "
> 
> Here's a hypothetical example:
> 
> ipython> %paste

This is not a bad idea at all.  You could even provide the sentinel if you 
wanted to change it, with a default like '--':

%paste

would stop on '--'

but

%paste ...

would use '...' to mark the end.

So that somebody could paste a hypothetical chunk with a string containing a 
single '--' in a line.

But this is 0.7.2 material: given that at least the autoindent/paste combo is 
working as well as it can be made to work right now, I'm going to leave it at 
that.

In my defense, even very mature tools like emacs *running in a terminal* and 
jed also screw up the pasting of indented code by reindenting it.  It boils 
down to the fact that from a terminal, there is no way to distinguish between 
a paste event and input typed by the user manually.  (X)emacs running under 
X11 do the right thing, but because they can process the paste event and 
basically do what Ville suggests automatically.  We could do the same thing if 
we were running in a GUI environment, where we'd get a true paste event.  But 
in a line-oriented terminal we don't have this information, so we're forced to 
try and guess what's going on from analyzing the structure of the input on the 
fly.

I'm still quite happy that it works in most cases, and if you keep your 
whitespace consistenly indented (which emacs does by default when you edit 
code), you can even make it work 'always'.  So I'm calling this feature done.

Cheers,

f




More information about the IPython-dev mailing list