PageRenderTime 53ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/python-packages/pymacs/Pymacs/pymacs.py.in

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