/extras/vim/vimarc.py

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