PageRenderTime 55ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/plugins/el-get/pymacs/Pymacs.py.in

https://github.com/Artoria-0x04/.emacs.d
Autoconf | 969 lines | 736 code | 133 blank | 100 comment | 135 complexity | 0e6365d0ba75388dea5c0fa0307315e4 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Copyright © 2001, 2002, 2003, 2012 Progiciels Bourbeau-Pinard inc.
  4. # François Pinard <pinard@iro.umontreal.ca>, 2001.
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2, or (at your option)
  8. # any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software Foundation,
  17. # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
  18. """\
  19. Interface between Emacs Lisp and Python - Python part.
  20. Emacs may launch this module as a stand-alone program, in which case it
  21. acts as a server of Python facilities for that Emacs session, reading
  22. requests from standard input and writing replies on standard output.
  23. When used in this way, the program is called "the Pymacs helper".
  24. This module may also be usefully imported by other Python modules.
  25. See the Pymacs documentation (check `README') for more information.
  26. """
  27. # Identification of version.
  28. package = 'Pymacs'
  29. version = '@VERSION@'
  30. import os
  31. import sys
  32. if PYTHON3:
  33. import collections
  34. def callable(value):
  35. return isinstance(value, collections.Callable)
  36. basestring = str
  37. from imp import reload
  38. else:
  39. __metaclass__ = type
  40. def fixup_icanon():
  41. # Otherwise sys.stdin.read hangs for large inputs in emacs 24.
  42. # See comment in emacs source code sysdep.c.
  43. import termios
  44. a = termios.tcgetattr(1)
  45. a[3] &= ~termios.ICANON
  46. termios.tcsetattr(1, termios.TCSANOW, a)
  47. try:
  48. import signal
  49. except ImportError:
  50. # Jython does not have signal.
  51. signal = None
  52. ## Python services for Emacs applications.
  53. class Main:
  54. debug_file = None
  55. signal_file = None
  56. def main(self, *arguments):
  57. """\
  58. Execute Python services for Emacs, and Emacs services for Python.
  59. This program is meant to be called from Emacs, using `pymacs.el'.
  60. Debugging options:
  61. -d FILE Debug the protocol to FILE.
  62. -s FILE Trace received signals to FILE.
  63. Arguments are added to the search path for Python modules.
  64. """
  65. # Decode options.
  66. arguments = (os.environ.get('PYMACS_OPTIONS', '').split()
  67. + list(arguments))
  68. import getopt
  69. options, arguments = getopt.getopt(arguments, 'fd:s:')
  70. for option, value in options:
  71. if option == '-d':
  72. self.debug_file = value
  73. elif option == '-s':
  74. self.signal_file = value
  75. elif option == '-f':
  76. try:
  77. fixup_icanon()
  78. except:
  79. pass
  80. arguments.reverse()
  81. for argument in arguments:
  82. if os.path.isdir(argument):
  83. sys.path.insert(0, argument)
  84. # Inhibit signals. The Interrupt signal is temporary enabled, however,
  85. # while executing any Python code received from the Lisp side.
  86. if signal is not None:
  87. if IO_ERRORS_WITH_SIGNALS:
  88. # See the comment for IO_ERRORS_WITH_SIGNALS in ppppconfig.py.
  89. self.original_handler = signal.signal(
  90. signal.SIGINT, self.interrupt_handler)
  91. else:
  92. for counter in range(1, signal.NSIG):
  93. if counter == signal.SIGINT:
  94. self.original_handler = signal.signal(
  95. counter, self.interrupt_handler)
  96. else:
  97. try:
  98. signal.signal(counter, self.generic_handler)
  99. except RuntimeError:
  100. pass
  101. self.inhibit_quit = True
  102. if not PYTHON3:
  103. # Re-open standard input and output in binary mode.
  104. sys.stdin = os.fdopen(sys.stdin.fileno(), 'rb')
  105. sys.stdout = os.fdopen(sys.stdout.fileno(), 'wb')
  106. # Start protocol and services.
  107. lisp._protocol.send('version', '"%s"' % version)
  108. lisp._protocol.loop()
  109. def generic_handler(self, number, frame):
  110. if self.signal_file:
  111. handle = open(self.signal_file, 'a')
  112. handle.write('%d\n' % number)
  113. handle.close()
  114. def interrupt_handler(self, number, frame):
  115. if self.signal_file:
  116. star = (' *', '')[self.inhibit_quit]
  117. handle = open(self.signal_file, 'a')
  118. handle.write('%d%s\n' % (number, star))
  119. handle.close()
  120. if not self.inhibit_quit:
  121. self.original_handler(number, frame)
  122. run = Main()
  123. main = run.main
  124. if OLD_EXCEPTIONS:
  125. ProtocolError = 'ProtocolError'
  126. ZombieError = 'ZombieError'
  127. else:
  128. class error(Exception):
  129. pass
  130. class ProtocolError(error):
  131. pass
  132. class ZombieError(error):
  133. pass
  134. class Protocol:
  135. # All exec's and eval's triggered from the Emacs side are all executed
  136. # within the "loop" method below, so all user context is kept as
  137. # local variables within this single routine. Different instances
  138. # of this Protocol class would yield independant evaluation contexts.
  139. # But in the usual case, there is only one such instance kept within a
  140. # Lisp_Interface instance, and the "lisp" global variable within this
  141. # module holds such a Lisp_Interface instance.
  142. def __init__(self):
  143. self.freed = []
  144. if PYTHON3:
  145. def loop(self):
  146. # The server loop repeatedly receives a request from Emacs and
  147. # returns a response, which is either the value of the received
  148. # Python expression, or the Python traceback if an error occurs
  149. # while evaluating the expression.
  150. # The server loop may also be executed, as a recursive invocation,
  151. # in the context of Emacs serving a Python request. In which
  152. # case, we might also receive a notification from Emacs telling
  153. # that the reply has been transmitted, or that an error occurred.
  154. # A reply notification from Emacs interrupts the loop: the result
  155. # of this function is then the value returned from Emacs.
  156. done = False
  157. while not done:
  158. try:
  159. action, text = self.receive()
  160. if action == 'eval':
  161. action = 'return'
  162. try:
  163. run.inhibit_quit = False
  164. value = eval(text)
  165. finally:
  166. run.inhibit_quit = True
  167. elif action == 'exec':
  168. action = 'return'
  169. value = None
  170. try:
  171. run.inhibit_quit = False
  172. exec(text)
  173. finally:
  174. run.inhibit_quit = True
  175. elif action == 'return':
  176. done = True
  177. try:
  178. run.inhibit_quit = False
  179. value = eval(text)
  180. finally:
  181. run.inhibit_quit = True
  182. elif action == 'raise':
  183. action = 'raise'
  184. value = 'Emacs: ' + text
  185. else:
  186. raise ProtocolError("Unknown action %r" % action)
  187. except KeyboardInterrupt:
  188. if done:
  189. raise
  190. action = 'raise'
  191. value = '*Interrupted*'
  192. except ProtocolError as exception:
  193. sys.exit("Protocol error: %s\n" % exception)
  194. except:
  195. import traceback
  196. action = 'raise'
  197. if lisp.debug_on_error.value() is None:
  198. value = traceback.format_exception_only(
  199. sys.exc_info[0], sys.exc_info[1])
  200. value = ''.join(value).rstrip()
  201. else:
  202. value = traceback.format_exc()
  203. if not done:
  204. fragments = []
  205. print_lisp(value, fragments.append, True)
  206. self.send(action, ''.join(fragments))
  207. return value
  208. else:
  209. def loop(self):
  210. # The server loop repeatedly receives a request from Emacs and
  211. # returns a response, which is either the value of the received
  212. # Python expression, or the Python traceback if an error occurs
  213. # while evaluating the expression.
  214. # The server loop may also be executed, as a recursive invocation,
  215. # in the context of Emacs serving a Python request. In which
  216. # case, we might also receive a notification from Emacs telling
  217. # that the reply has been transmitted, or that an error occurred.
  218. # A reply notification from Emacs interrupts the loop: the result
  219. # of this function is then the value returned from Emacs.
  220. done = False
  221. while not done:
  222. try:
  223. action, text = self.receive()
  224. if action == 'eval':
  225. action = 'return'
  226. try:
  227. run.inhibit_quit = False
  228. value = eval(text)
  229. finally:
  230. run.inhibit_quit = True
  231. elif action == 'exec':
  232. action = 'return'
  233. value = None
  234. try:
  235. run.inhibit_quit = False
  236. exec(text)
  237. finally:
  238. run.inhibit_quit = True
  239. elif action == 'return':
  240. done = True
  241. try:
  242. run.inhibit_quit = False
  243. value = eval(text)
  244. finally:
  245. run.inhibit_quit = True
  246. elif action == 'raise':
  247. action = 'raise'
  248. value = 'Emacs: ' + text
  249. else:
  250. if OLD_EXCEPTIONS:
  251. raise ProtocolError, "Unknown action %r" % action
  252. else:
  253. raise ProtocolError("Unknown action %r" % action)
  254. except KeyboardInterrupt:
  255. if done:
  256. raise
  257. action = 'raise'
  258. value = '*Interrupted*'
  259. except ProtocolError, exception:
  260. sys.exit("Protocol error: %s\n" % exception)
  261. except:
  262. import traceback
  263. action = 'raise'
  264. if lisp.debug_on_error.value() is None:
  265. value = traceback.format_exception_only(
  266. sys.exc_type, sys.exc_value)
  267. value = ''.join(value).rstrip()
  268. else:
  269. value = traceback.format_exc()
  270. if not done:
  271. fragments = []
  272. print_lisp(value, fragments.append, True)
  273. self.send(action, ''.join(fragments))
  274. return value
  275. if PYTHON3:
  276. def receive(self):
  277. # Receive a Python expression from Emacs, return (ACTION, TEXT).
  278. prefix = sys.stdin.buffer.read(3)
  279. if not prefix or prefix[0] != ord(b'>'):
  280. raise ProtocolError("`>' expected.")
  281. while prefix[-1] != ord(b'\t'):
  282. character = sys.stdin.buffer.read(1)
  283. if not character:
  284. raise ProtocolError("Empty stdin read.")
  285. prefix += character
  286. data = sys.stdin.buffer.read(int(prefix[1:-1]))
  287. try:
  288. text = data.decode('UTF-8')
  289. except UnicodeDecodeError:
  290. #assert False, ('***', data)
  291. text = data.decode('ISO-8859-1')
  292. if run.debug_file is not None:
  293. handle = open(run.debug_file, 'a')
  294. handle.write(prefix.decode('ASCII') + text)
  295. handle.close()
  296. return text.split(None, 1)
  297. else:
  298. def receive(self):
  299. # Receive a Python expression from Emacs, return (ACTION, TEXT).
  300. prefix = sys.stdin.read(3)
  301. if not prefix or prefix[0] != '>':
  302. if OLD_EXCEPTIONS:
  303. raise ProtocolError, "`>' expected."
  304. else:
  305. raise ProtocolError("`>' expected.")
  306. while prefix[-1] != '\t':
  307. character = sys.stdin.read(1)
  308. if not character:
  309. if OLD_EXCEPTIONS:
  310. raise ProtocolError, "Empty stdin read."
  311. else:
  312. raise ProtocolError("Empty stdin read.")
  313. prefix += character
  314. text = sys.stdin.read(int(prefix[1:-1]))
  315. if run.debug_file is not None:
  316. handle = open(run.debug_file, 'a')
  317. handle.write(prefix + text)
  318. handle.close()
  319. return text.split(None, 1)
  320. if PYTHON3:
  321. def send(self, action, text):
  322. # Send ACTION and its TEXT argument to Emacs.
  323. if self.freed:
  324. # All delayed Lisp cleanup is piggied back on the transmission.
  325. text = ('(free (%s) %s %s)\n'
  326. % (' '.join(map(str, self.freed)), action, text))
  327. self.freed = []
  328. else:
  329. text = '(%s %s)\n' % (action, text)
  330. data = text.encode('UTF-8')
  331. prefix = '<%d\t' % len(data)
  332. if run.debug_file is not None:
  333. handle = open(run.debug_file, 'a')
  334. handle.write(prefix + text)
  335. handle.close()
  336. sys.stdout.buffer.write(prefix.encode('ASCII'))
  337. sys.stdout.buffer.write(data)
  338. sys.stdout.buffer.flush()
  339. else:
  340. def send(self, action, text):
  341. # Send ACTION and its TEXT argument to Emacs.
  342. if self.freed:
  343. # All delayed Lisp cleanup is piggied back on the transmission.
  344. text = ('(free (%s) %s %s)\n'
  345. % (' '.join(map(str, self.freed)), action, text))
  346. self.freed = []
  347. else:
  348. text = '(%s %s)\n' % (action, text)
  349. prefix = '<%d\t' % len(text)
  350. if run.debug_file is not None:
  351. handle = open(run.debug_file, 'a')
  352. handle.write(prefix + text)
  353. handle.close()
  354. sys.stdout.write(prefix + text)
  355. sys.stdout.flush()
  356. def pymacs_load_helper(file_without_extension, prefix, noerror=None):
  357. # This function imports a Python module, then returns a Lisp expression
  358. # which, when later evaluated, will install trampoline definitions
  359. # in Emacs for accessing the Python module facilities. Module, given
  360. # through FILE_WITHOUT_EXTENSION, may be a full path, yet without the
  361. # `.py' or `.pyc' suffix, in which case the directory is temporarily
  362. # added to the Python search path for the sole duration of that import.
  363. # All defined symbols on the Lisp side have have PREFIX prepended,
  364. # and have Python underlines in Python turned into dashes. If PREFIX
  365. # is None, it then defaults to the base name of MODULE with underlines
  366. # turned to dashes, followed by a dash.
  367. directory, module_name = os.path.split(file_without_extension)
  368. module_components = module_name.split('.')
  369. if prefix is None:
  370. prefix = module_components[-1].replace('_', '-') + '-'
  371. try:
  372. module = sys.modules.get(module_name)
  373. if module:
  374. reload(module)
  375. else:
  376. try:
  377. if directory:
  378. sys.path.insert(0, directory)
  379. module = __import__(module_name)
  380. finally:
  381. if directory:
  382. del sys.path[0]
  383. # Whenever MODULE_NAME is of the form [PACKAGE.]...MODULE,
  384. # __import__ returns the outer PACKAGE, not the module.
  385. for component in module_components[1:]:
  386. module = getattr(module, component)
  387. except ImportError:
  388. if noerror:
  389. return None
  390. else:
  391. raise
  392. load_hook = module.__dict__.get('pymacs_load_hook')
  393. if load_hook:
  394. load_hook()
  395. interactions = module.__dict__.get('interactions', {})
  396. if not isinstance(interactions, dict):
  397. interactions = {}
  398. arguments = []
  399. for name, value in module.__dict__.items():
  400. if callable(value) and value is not lisp:
  401. arguments.append(allocate_python(value))
  402. arguments.append(lisp[prefix + name.replace('_', '-')])
  403. try:
  404. interaction = value.interaction
  405. except AttributeError:
  406. interaction = interactions.get(value)
  407. if callable(interaction):
  408. arguments.append(allocate_python(interaction))
  409. else:
  410. arguments.append(interaction)
  411. if arguments:
  412. return [lisp.progn,
  413. [lisp.pymacs_defuns, [lisp.quote, arguments]],
  414. module]
  415. return [lisp.quote, module]
  416. def doc_string(function):
  417. import inspect
  418. return inspect.getdoc(function)
  419. ## Garbage collection matters.
  420. # Many Python types do not have direct Lisp equivalents, and may not be
  421. # directly returned to Lisp for this reason. They are rather allocated in
  422. # a list of handles, below, and a handle index is used for communication
  423. # instead of the Python value. Whenever such a handle is freed from the
  424. # Lisp side, its index is added of a freed list for later reuse.
  425. python = []
  426. freed_list = []
  427. def allocate_python(value):
  428. assert not isinstance(value, str), (type(value), repr(value))
  429. # Allocate some handle to hold VALUE, return its index.
  430. if freed_list:
  431. index = freed_list[-1]
  432. del freed_list[-1]
  433. python[index] = value
  434. else:
  435. index = len(python)
  436. python.append(value)
  437. return index
  438. def free_python(indices):
  439. # Return many handles to the pool.
  440. for index in indices:
  441. python[index] = None
  442. freed_list.append(index)
  443. def zombie_python(indices):
  444. # Ensure that some handles are _not_ in the pool.
  445. for index in indices:
  446. while index >= len(python):
  447. freed_list.append(len(python))
  448. python.append(None)
  449. python[index] = zombie
  450. freed_list.remove(index)
  451. # Merely to make `*Pymacs*' a bit more readable.
  452. freed_list.sort()
  453. def zombie(*arguments):
  454. # This catch-all function is set as the value for any function which
  455. # disappeared with a previous Pymacs helper process, so calling
  456. # such a function from Emacs will trigger a decipherable diagnostic.
  457. diagnostic = "Object vanished when the Pymacs helper was killed"
  458. if lisp.pymacs_dreadful_zombies.value():
  459. if OLD_EXCEPTIONS:
  460. raise ZombieError, diagnostic
  461. else:
  462. raise ZombieError(diagnostic)
  463. lisp.message(diagnostic)
  464. ## Emacs services for Python applications.
  465. class Let:
  466. def __init__(self, **keywords):
  467. # The stack holds (METHOD, DATA) pairs, where METHOD is the expected
  468. # unbound pop_* method, and DATA holds information to be restored.
  469. # METHOD may not be bound to the instance, as this would induce
  470. # reference cycles, and then, __del__ would not be called timely.
  471. self.stack = []
  472. if keywords:
  473. self.push(**keywords)
  474. def __del__(self):
  475. self.pops()
  476. if PYTHON3:
  477. def __bool__(self):
  478. # So stylistic `if let:' executes faster.
  479. return True
  480. else:
  481. def __nonzero__(self):
  482. # So stylistic `if let:' executes faster.
  483. return True
  484. def pops(self):
  485. while self.stack:
  486. self.stack[-1][0](self)
  487. def push(self, **keywords):
  488. data = []
  489. for name, value in keywords.items():
  490. data.append((name, getattr(lisp, name).value()))
  491. setattr(lisp, name, value)
  492. self.stack.append((Let.pop, data))
  493. return self
  494. def pop(self):
  495. method, data = self.stack.pop()
  496. assert method == Let.pop, (method, data)
  497. for name, value in data:
  498. setattr(lisp, name, value)
  499. def push_excursion(self):
  500. self.stack.append((Let.pop_excursion, (lisp.current_buffer(),
  501. lisp.point_marker(),
  502. lisp.mark_marker())))
  503. return self
  504. def pop_excursion(self):
  505. method, data = self.stack.pop()
  506. assert method == Let.pop_excursion, (method, data)
  507. buffer, point_marker, mark_marker = data
  508. lisp.set_buffer(buffer)
  509. lisp.goto_char(point_marker)
  510. lisp.set_mark(mark_marker)
  511. lisp.set_marker(point_marker, None)
  512. lisp.set_marker(mark_marker, None)
  513. def push_match_data(self):
  514. self.stack.append((Let.pop_match_data, lisp.match_data()))
  515. return self
  516. def pop_match_data(self):
  517. method, data = self.stack.pop()
  518. assert method == Let.pop_match_data, (method, data)
  519. lisp.set_match_data(data)
  520. def push_restriction(self):
  521. self.stack.append((Let.pop_restriction, (lisp.point_min_marker(),
  522. lisp.point_max_marker())))
  523. return self
  524. def pop_restriction(self):
  525. method, data = self.stack.pop()
  526. assert method == Let.pop_restriction, (method, data)
  527. point_min_marker, point_max_marker = data
  528. lisp.narrow_to_region(point_min_marker, point_max_marker)
  529. lisp.set_marker(point_min_marker, None)
  530. lisp.set_marker(point_max_marker, None)
  531. def push_selected_window(self):
  532. self.stack.append((Let.pop_selected_window, lisp.selected_window()))
  533. return self
  534. def pop_selected_window(self):
  535. method, data = self.stack.pop()
  536. assert method == Let.pop_selected_window, (method, data)
  537. lisp.select_window(data)
  538. def push_window_excursion(self):
  539. self.stack.append((Let.pop_window_excursion,
  540. lisp.current_window_configuration()))
  541. return self
  542. def pop_window_excursion(self):
  543. method, data = self.stack.pop()
  544. assert method == Let.pop_window_excursion, (method, data)
  545. lisp.set_window_configuration(data)
  546. class Symbol:
  547. def __init__(self, text):
  548. self.text = text
  549. def __repr__(self):
  550. return 'lisp[%s]' % repr(self.text)
  551. def __str__(self):
  552. return '\'' + self.text
  553. def value(self):
  554. return lisp._eval(self.text)
  555. def copy(self):
  556. return lisp._expand(self.text)
  557. def set(self, value):
  558. if value is None:
  559. lisp._eval('(setq %s nil)' % self.text)
  560. else:
  561. fragments = []
  562. write = fragments.append
  563. write('(progn (setq %s ' % self.text)
  564. print_lisp(value, write, True)
  565. write(') nil)')
  566. lisp._eval(''.join(fragments))
  567. def __call__(self, *arguments):
  568. fragments = []
  569. write = fragments.append
  570. write('(%s' % self.text)
  571. for argument in arguments:
  572. write(' ')
  573. print_lisp(argument, write, True)
  574. write(')')
  575. return lisp._eval(''.join(fragments))
  576. class Lisp:
  577. def __init__(self, index):
  578. self.index = index
  579. def __del__(self):
  580. lisp._protocol.freed.append(self.index)
  581. def __repr__(self):
  582. return ('lisp(%s)' % repr(lisp('(prin1-to-string %s)' % self)))
  583. def __str__(self):
  584. return '(aref pymacs-lisp %d)' % self.index
  585. def value(self):
  586. return self
  587. def copy(self):
  588. return lisp._expand(str(self))
  589. class Buffer(Lisp):
  590. pass
  591. #def write(text):
  592. # # So you could do things like
  593. # # print >>lisp.current_buffer(), "Hello World"
  594. # lisp.insert(text, self)
  595. #def point(self):
  596. # return lisp.point(self)
  597. class List(Lisp):
  598. def __call__(self, *arguments):
  599. fragments = []
  600. write = fragments.append
  601. write('(%s' % self)
  602. for argument in arguments:
  603. write(' ')
  604. print_lisp(argument, write, True)
  605. write(')')
  606. return lisp._eval(''.join(fragments))
  607. def __len__(self):
  608. return lisp._eval('(length %s)' % self)
  609. def __getitem__(self, key):
  610. value = lisp._eval('(nth %d %s)' % (key, self))
  611. if value is None and key >= len(self):
  612. if OLD_EXCEPTIONS:
  613. raise IndexError, key
  614. else:
  615. raise IndexError(key)
  616. return value
  617. def __setitem__(self, key, value):
  618. fragments = []
  619. write = fragments.append
  620. write('(setcar (nthcdr %d %s) ' % (key, self))
  621. print_lisp(value, write, True)
  622. write(')')
  623. lisp._eval(''.join(fragments))
  624. class Table(Lisp):
  625. def __getitem__(self, key):
  626. fragments = []
  627. write = fragments.append
  628. write('(gethash ')
  629. print_lisp(key, write, True)
  630. write(' %s)' % self)
  631. return lisp._eval(''.join(fragments))
  632. def __setitem__(self, key, value):
  633. fragments = []
  634. write = fragments.append
  635. write('(puthash ')
  636. print_lisp(key, write, True)
  637. write(' ')
  638. print_lisp(value, write, True)
  639. write(' %s)' % self)
  640. lisp._eval(''.join(fragments))
  641. class Vector(Lisp):
  642. def __len__(self):
  643. return lisp._eval('(length %s)' % self)
  644. def __getitem__(self, key):
  645. return lisp._eval('(aref %s %d)' % (self, key))
  646. def __setitem__(self, key, value):
  647. fragments = []
  648. write = fragments.append
  649. write('(aset %s %d ' % (self, key))
  650. print_lisp(value, write, True)
  651. write(')')
  652. lisp._eval(''.join(fragments))
  653. class Lisp_Interface:
  654. def __init__(self):
  655. self.__dict__['_cache'] = {'nil': None}
  656. self.__dict__['_protocol'] = Protocol()
  657. def __call__(self, text):
  658. return self._eval('(progn %s)' % text)
  659. def _eval(self, text):
  660. self._protocol.send('eval', text)
  661. return self._protocol.loop()
  662. def _expand(self, text):
  663. self._protocol.send('expand', text)
  664. return self._protocol.loop()
  665. def __getattr__(self, name):
  666. if name[0] == '_':
  667. if OLD_EXCEPTIONS:
  668. raise AttributeError, name
  669. else:
  670. raise AttributeError(name)
  671. return self[name.replace('_', '-')]
  672. def __setattr__(self, name, value):
  673. if name[0] == '_':
  674. if OLD_EXCEPTIONS:
  675. raise AttributeError, name
  676. else:
  677. raise AttributeError(name)
  678. self[name.replace('_', '-')] = value
  679. def __getitem__(self, name):
  680. try:
  681. return self._cache[name]
  682. except KeyError:
  683. symbol = self._cache[name] = Symbol(name)
  684. return symbol
  685. def __setitem__(self, name, value):
  686. try:
  687. symbol = self._cache[name]
  688. except KeyError:
  689. symbol = self._cache[name] = Symbol(name)
  690. symbol.set(value)
  691. lisp = Lisp_Interface()
  692. if PYTHON3:
  693. print_lisp_quoted_specials = {
  694. ord('"'): '\\"', ord('\\'): '\\\\', ord('\b'): '\\b',
  695. ord('\f'): '\\f',
  696. ord('\n'): '\\n', ord('\r'): '\\r', ord('\t'): '\\t'}
  697. def print_lisp(value, write, quoted):
  698. if value is None:
  699. write('nil')
  700. elif isinstance(bool, type) and isinstance(value, bool):
  701. write(('nil', 't')[value])
  702. elif isinstance(value, int):
  703. write(repr(value))
  704. elif isinstance(value, float):
  705. write(repr(value))
  706. elif isinstance(value, str):
  707. try:
  708. value.encode('ASCII')
  709. except UnicodeError:
  710. write('(decode-coding-string "')
  711. for byte in value.encode('UTF-8'):
  712. special = print_lisp_quoted_specials.get(byte)
  713. if special is not None:
  714. write(special)
  715. elif 32 <= byte < 127:
  716. write(chr(byte))
  717. else:
  718. write('\\%.3o' % byte)
  719. write('" \'utf-8)')
  720. else:
  721. write('"')
  722. for character in value:
  723. special = print_lisp_quoted_specials.get(ord(character))
  724. if special is not None:
  725. write(special)
  726. elif 32 <= ord(character) < 127:
  727. write(character)
  728. else:
  729. write('\\%.3o' % ord(character))
  730. write('"')
  731. elif isinstance(value, list):
  732. if quoted:
  733. write("'")
  734. if len(value) == 0:
  735. write('nil')
  736. elif len(value) == 2 and value[0] == lisp.quote:
  737. write("'")
  738. print_lisp(value[1], write, False)
  739. else:
  740. write('(')
  741. print_lisp(value[0], write, False)
  742. for sub_value in value[1:]:
  743. write(' ')
  744. print_lisp(sub_value, write, False)
  745. write(')')
  746. elif isinstance(value, tuple):
  747. write('[')
  748. if len(value) > 0:
  749. print_lisp(value[0], write, False)
  750. for sub_value in value[1:]:
  751. write(' ')
  752. print_lisp(sub_value, write, False)
  753. write(']')
  754. elif isinstance(value, Lisp):
  755. write(str(value))
  756. elif isinstance(value, Symbol):
  757. if quoted:
  758. write("'")
  759. write(value.text)
  760. elif callable(value):
  761. write('(pymacs-defun %d nil)' % allocate_python(value))
  762. else:
  763. write('(pymacs-python %d)' % allocate_python(value))
  764. else:
  765. print_lisp_quoted_specials = {
  766. '"': '\\"', '\\': '\\\\', '\b': '\\b', '\f': '\\f',
  767. '\n': '\\n', '\r': '\\r', '\t': '\\t'}
  768. def print_lisp(value, write, quoted):
  769. if value is None:
  770. write('nil')
  771. elif isinstance(bool, type) and isinstance(value, bool):
  772. write(('nil', 't')[value])
  773. elif isinstance(value, int):
  774. write(repr(value))
  775. elif isinstance(value, float):
  776. write(repr(value))
  777. elif isinstance(value, basestring):
  778. multibyte = False
  779. if isinstance(value, unicode):
  780. try:
  781. value = value.encode('ASCII')
  782. except UnicodeError:
  783. value = value.encode('UTF-8')
  784. multibyte = True
  785. if multibyte:
  786. write('(decode-coding-string ')
  787. write('"')
  788. for character in value:
  789. special = print_lisp_quoted_specials.get(character)
  790. if special is not None:
  791. write(special)
  792. elif 32 <= ord(character) < 127:
  793. write(character)
  794. else:
  795. write('\\%.3o' % ord(character))
  796. write('"')
  797. if multibyte:
  798. write(' \'utf-8)')
  799. elif isinstance(value, list):
  800. if quoted:
  801. write("'")
  802. if len(value) == 0:
  803. write('nil')
  804. elif len(value) == 2 and value[0] == lisp.quote:
  805. write("'")
  806. print_lisp(value[1], write, False)
  807. else:
  808. write('(')
  809. print_lisp(value[0], write, False)
  810. for sub_value in value[1:]:
  811. write(' ')
  812. print_lisp(sub_value, write, False)
  813. write(')')
  814. elif isinstance(value, tuple):
  815. write('[')
  816. if len(value) > 0:
  817. print_lisp(value[0], write, False)
  818. for sub_value in value[1:]:
  819. write(' ')
  820. print_lisp(sub_value, write, False)
  821. write(']')
  822. elif isinstance(value, Lisp):
  823. write(str(value))
  824. elif isinstance(value, Symbol):
  825. if quoted:
  826. write("'")
  827. write(value.text)
  828. elif callable(value):
  829. write('(pymacs-defun %d nil)' % allocate_python(value))
  830. else:
  831. write('(pymacs-python %d)' % allocate_python(value))
  832. if __name__ == '__main__':
  833. main(*sys.argv[1:])