python IDE: vim + ipython

Executable shell script

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env bash
 
IPYFILE=$1
if [ $PWD == "/" ]
then
    DIR=$HOME
else
    DIR=$PWD
fi
 
gnome-terminal --working-directory=$DIR -x sh -c "export IPYFILE=$IPYFILE; ipython -wthread"

.vim/plugin/ipy.vim

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
if !exists("$IPY_SESSION")
    finish
endif
 
" set up the python interpreter within vim, to have all the right modules
" imported, as well as certain useful globals set
python import socket
python import os
python import vim
"python from IPython.Debugger import Pdb
python IPYSERVER = None
python reselect = True
 
python << EOF
# do we have a connection to the ipython instance?
def check_server():
    global IPYSERVER
    if IPYSERVER:
        return True
    else:
        return False
 
# connect to the ipython server, if we need to
def connect():
    global IPYSERVER
    if check_server():
        return
    try:
        IPYSERVER = socket.socket(socket.AF_UNIX)
        IPYSERVER.connect(os.environ.get('IPY_SERVER'))
    except:
        IPYSERVER = None
 
def disconnect():
    if IPYSERVER:
        IPYSERVER.close()
 
def send(cmd):
    x = 0
    while True:
        x += IPYSERVER.send(cmd)
        if x < len(cmd):
            cmd = cmd[x:]
        else:
            break
 
def run_this_file():
    if check_server():
        send('run -i  %s' % (vim.current.buffer.name,))
    else:
        raise Exception, "Not connected to an IPython server"
    print "\'run -i %s\' sent to ipython" % vim.current.buffer.name
 
def run_these_lines(mode='norm'):
    if check_server():
        r = vim.current.range
        #send(str((vim.current.range.start,vim.current.range.end)))
        for l in vim.current.buffer[r.start:r.end+1]:
            send(str(l)+'\n')
            #send(str(vim.current.buffer[vim.current.range.start:vim.current.range.end]).join("\n"))
        if mode == 'norm':
            print "line %d sent to ipython"% (r.start+1)
        elif mode == 'vis':
            #reselect the previously highlighted block
            if reselect:
                vim.command("normal gv")
            #vim lines start with 1
            print "lines %d-%d sent to ipython"% (r.start+1,r.end+1)
        else:
            raise Exception, "mode not recognized"
    else:
        raise Exception, "Not connected to an IPython server"
 
def toggle_reselect():
    global reselect
    reselect=not reselect
    print "F9 will%sreselect lines after sending to ipython"% (reselect and " " or " not ")
 
def set_breakpoint():
    if check_server():
        send("__IP.InteractiveTB.pdb.set_break('%s',%d)" % (vim.current.buffer.name,
                                                            vim.current.window.cursor[0]))
        print "set breakpoint in %s:%d"% (vim.current.buffer.name, 
                                          vim.current.window.cursor[0])
    else:
        raise Exception, "Not connected to an IPython server"
 
def clear_breakpoint():
    if check_server():
        send("__IP.InteractiveTB.pdb.clear_break('%s',%d)" % (vim.current.buffer.name,
                                                              vim.current.window.cursor[0]))
        print "clearing breakpoint in %s:%d" % (vim.current.buffer.name,
                                                vim.current.window.cursor[0])
    else:
        raise Exception, "Not connected to an IPython server"
 
def clear_all_breakpoints():
    if check_server():
        send("__IP.InteractiveTB.pdb.clear_all_breaks()");
        print "clearing all breakpoints"
    else:
        raise Exception, "Not connected to an IPython server"
 
def run_this_file_pdb():
    if check_server():
        send(' __IP.InteractiveTB.pdb.run(\'execfile("%s")\')' % (vim.current.buffer.name,))
    else:
        raise Exception, "Not connected to an IPython server"
    print "\'run %s\' using pdb sent to ipython" % vim.current.buffer.name
 
    #XXX: have IPYSERVER print the prompt (look at Leo example)
EOF
 
fun! <SID>toggle_send_on_save()
    if exists("s:ssos") && s:ssos == 1
        let s:ssos = 0
        au! BufWritePost *.py
        echo "Autosend Off"
    else
        let s:ssos = 1
        au BufWritePost *.py :py run_this_file()
        echo "Autosend On"
    endif
endfun
 
map <silent> <F5> :python run_this_file()<CR>
map <silent> <S-F5> :python run_these_lines(mode='norm')<CR>
vmap <silent> <S-F5> :python run_these_lines(mode='vis')<CR>
map <silent> <C-F6> :python send('%pdb')<CR>
map <silent> <F6> :python set_breakpoint()<CR>
map <silent> <s-F6> :python clear_breakpoint()<CR>
map <silent> <F7> :python run_this_file_pdb()<CR>
map <silent> <s-F7> :python clear_all_breaks()<CR>
imap <C-F5> <ESC><C-F5>a
imap <S-F5> <ESC><S-F5>a
imap <silent> <F5> <ESC><F5>a
map <F9> :call <SID>toggle_send_on_save()<CR>
map <silent> <S-F9> :python toggle_reselect()<CR>
py connect()

$PYTHONPATH/ipythonhooks.py

1
2
3
4
5
6
7
import os
 
def fix_error_editor(self,filename,linenum,column,msg):
    ipython_pid = os.getpid()
    print ipython_pid
    cmd='gvim --servername ipython_session_%d --remote +%d %s'% (ipython_pid,linenum,filename,)
    os.system(cmd)

Leave a Reply