PageRenderTime 19ms CodeModel.GetById 12ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/extras/vim/vimarc.py

http://github.com/alimoeeny/arc
Python | 71 lines | 66 code | 3 blank | 2 comment | 6 complexity | 97366ba89297b945780049a0792231ef MD5 | raw file
 1# Go-between to allow regular repl access + spit pipe input from vim into the repl.
 2# scott.vimarc@h4ck3r.net, 2008.
 3
 4import pexpect, os, sys, tty, select
 5
 6lispCmd = '../arc.sh' # or, 'sbcl', or whatever should probably work
 7pipeLoc = os.path.expanduser("~/.vimarc-pipe") # this path has to be the same as in vimarc.vim
 8if not os.path.exists(pipeLoc):
 9    os.system("mkfifo -m go-rwx " + pipeLoc)
10
11class Funnel(pexpect.spawn):
12    """ hacky monkey patch of pexpect to merge `interact' and input from a pipe. spawn the lisp using
13        this command, and then vim connects to the pipe and you can still see/use the lisp repl in your
14        shell window."""
15
16    def mergePipeAndInteract(self, pipe):
17        self.stdout.write (self.buffer)
18        self.stdout.flush()
19        self.buffer = ''
20        mode = tty.tcgetattr(self.STDIN_FILENO)
21        tty.setraw(self.STDIN_FILENO)
22        try:
23            self.__merge_copy(pipe)
24        finally:
25            tty.tcsetattr(self.STDIN_FILENO, tty.TCSAFLUSH, mode)
26
27    def __interact_writen(self, fd, data):
28        while data != '' and self.isalive():
29            n = os.write(fd, data)
30            data = data[n:]
31    def __interact_read(self, fd):
32        return os.read(fd, 1000)
33
34    def __select (self, iwtd, owtd, ewtd, timeout=None):
35        # if select() is interrupted by a signal (errno==EINTR) then
36        # we loop back and enter the select() again.
37        if timeout is not None:
38            end_time = time.time() + timeout 
39        while True:
40            try:
41                return select.select (iwtd, owtd, ewtd, timeout)
42            except select.error, e:
43                if e[0] == errno.EINTR:
44                    # if we loop back we have to subtract the amount of time we already waited.
45                    if timeout is not None:
46                        timeout = end_time - time.time()
47                        if timeout < 0:
48                            return ([],[],[])
49                else: # something else caused the select.error, so this really is an exception
50                    raise
51
52    def __merge_copy(self, pipe):
53        while self.isalive():
54            r,w,e = self.__select([self.child_fd, self.STDIN_FILENO, pipe], [], [])
55            if self.child_fd in r:
56                data = self.__interact_read(self.child_fd)
57                os.write(self.STDOUT_FILENO, data)
58            if self.STDIN_FILENO in r:
59                data = self.__interact_read(self.STDIN_FILENO)
60                self.__interact_writen(self.child_fd, data)
61            if pipe in r:
62                data = self.__interact_read(pipe)
63                self.__interact_writen(self.child_fd, data)
64
65f = Funnel(lispCmd, logfile=sys.stdout)
66pipe = open(pipeLoc, "r+")
67pipefn = pipe.fileno()
68try:
69    f.mergePipeAndInteract(pipefn)
70except OSError:
71    pass