jorgenschaefer / elpy

Emacs Python Development Environment
GNU General Public License v3.0
1.89k stars 259 forks source link

Support ipython kernel connections #626

Open lentils opened 9 years ago

lentils commented 9 years ago

Hi, great progress with elpy since I last checked in!

Working fast in the repl, I sometimes print a large object that causes emacs to hang. One idea I've had is to send commands to an ipython kernel, that way if emacs chokes on that buffer I can still work from another shell. Usually the issue is not python related but emacs related, since it can't handle lots of input at once very well (or can it?).

Anyway, it would be cool to have an easy interface to connect to existing or brand new ipython kernels. Kind of like how CIDER works for clojure, or SLIME.

Curious to hear your thoughts about this. I'm still getting up to speed with how elpy makes it all happen, but I would love to contribute! Let me know what I can do to help.

Thanks again for a great package.

jorgenschaefer commented 9 years ago

Hello, and thanks for the report! There are two topics you address here.

The first is about printing large objects. Emacs actually has very few problems with this conceptually. What Emacs does have a problem with is long lines. If printing a large object results in a single long line, Emacs will start to become unresponsive (see my answer to a Stack Exchange question for some details). It might be possible for the inferior shell code in python.el to break up long lines to avoid this problem, but it will skew results.

Something like this might work, even:

(defun my/split-long-line (line len)
  (let ((lines nil)
        (i 0))
    (while (> (length line) (+ i len))
      (setq lines (cons (substring line i (+ i len))
                        lines)
            i (+ i len)))
    (setq lines (cons (substring line i) lines))
    (mapconcat #'identity (nreverse lines) "\n")))

(defun my/comint-break-long-lines (string)
  (mapconcat (lambda (line)
               (my/split-long-line line 100))
             (split-string string "\n")
             "\n"))

(add-hook 'inferior-python-mode-hook
          (lambda ()
            (setq comint-preoutput-filter-functions
                  '(my/comint-break-long-lines))))

The other is about talking with IPython. I do not use IPython myself, so I have not much of an idea about it, but there is an ipython notebook implementation for Emacs that might solve that problem?

lentils commented 9 years ago

Thanks for your advice. I didn't know that it was long lines in particular that caused the problem. I will try out your suggestion.

As for EIN (the IPython Notebook package), I don't think it's under active development anymore. The IPython kernel is actually a lot more flexible than just hosting Notebooks. I haven't looked too carefully into it, but IPython could be an interesting way of running remote python processes (of course, you need to install IPython there), and I think it has it's own completion backend which could be useful for completion remotely. It also has a lot of configuration options which could add another dimension to elpy customization.

I don't necessarily use notebooks, but I enjoy using the IPython repl over the default. I would like to explore its potential more.

Maybe I will play around and submit a PR if it looks like it could be useful for elpy.

jorgenschaefer commented 9 years ago

Maybe I will play around and submit a PR if it looks like it could be useful for elpy.

This all sounds interesting. I would be highly reluctant to require ipython when using Elpy, but if Elpy can add useful features in case ipython is available, that'd be great.

It might be more sensible to have this as a separate package, depending on what this will do.

I'm looking forward to what you come up with! :-)

arvids commented 9 years ago

@lentils I think EIN switched maintainer a while back this is the correct link: https://github.com/millejoh/emacs-ipython-notebook/ But oh how I would love all of the elpy functionality inside an emacs notebook.