annotate .elisp/pymacs.el @ 207:c965d5dbd868

emacs localfuncs: add list rotation and string-joining functions I sometimes use
author Augie Fackler <durin42@gmail.com>
date Tue, 11 May 2010 15:32:19 -0500
parents c30d68fbd368
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
1 ;;; Interface between Emacs Lisp and Python - Lisp part. -*- emacs-lisp -*-
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
2 ;;; Copyright © 2001, 2002, 2003 Progiciels Bourbeau-Pinard inc.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
3 ;;; François Pinard <pinard@iro.umontreal.ca>, 2001.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
4
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
5 ;;; This program is free software; you can redistribute it and/or modify
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
6 ;;; it under the terms of the GNU General Public License as published by
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
7 ;;; the Free Software Foundation; either version 2, or (at your option)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
8 ;;; any later version.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
9 ;;;
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
10 ;;; This program is distributed in the hope that it will be useful,
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
11 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
12 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
13 ;;; GNU General Public License for more details.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
14 ;;;
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
15 ;;; You should have received a copy of the GNU General Public License
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
16 ;;; along with this program; if not, write to the Free Software Foundation,
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
17 ;;; Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
18
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
19 ;;; Portability stunts.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
20
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
21 (defvar pymacs-use-hash-tables
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
22 (and (fboundp 'make-hash-table) (fboundp 'gethash) (fboundp 'puthash))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
23 "Set to t if hash tables are available.")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
24
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
25 (eval-and-compile
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
26
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
27 (if (fboundp 'multibyte-string-p)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
28 (defalias 'pymacs-multibyte-string-p 'multibyte-string-p)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
29 (defun pymacs-multibyte-string-p (string)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
30 "Tell XEmacs if STRING should be handled as multibyte."
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
31 (not (equal (find-charset-string string) '(ascii))))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
32
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
33 (defalias 'pymacs-report-error (symbol-function 'error))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
34
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
35 ;;; Published variables and functions.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
36
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
37 (defvar pymacs-load-path nil
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
38 "List of additional directories to search for Python modules.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
39 The directories listed will be searched first, in the order given.")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
40
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
41 (defvar pymacs-trace-transit '(5000 . 30000)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
42 "Keep the communication buffer growing, for debugging.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
43 When this variable is nil, the `*Pymacs*' communication buffer gets erased
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
44 before each communication round-trip. Setting it to `t' guarantees that
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
45 the full communication is saved, which is useful for debugging.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
46 It could also be given as (KEEP . LIMIT): whenever the buffer exceeds LIMIT
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
47 bytes, it is reduced to approximately KEEP bytes.")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
48
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
49 (defvar pymacs-forget-mutability nil
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
50 "Transmit copies to Python instead of Lisp handles, as much as possible.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
51 When this variable is nil, most mutable objects are transmitted as handles.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
52 This variable is meant to be temporarily rebound to force copies.")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
53
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
54 (defvar pymacs-mutable-strings nil
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
55 "Prefer transmitting Lisp strings to Python as handles.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
56 When this variable is nil, strings are transmitted as copies, and the
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
57 Python side thus has no way for modifying the original Lisp strings.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
58 This variable is ignored whenever `forget-mutability' is set.")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
59
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
60 (defvar pymacs-timeout-at-start 30
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
61 "Maximum reasonable time, in seconds, for starting the Pymacs helper.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
62 A machine should be pretty loaded before one needs to increment this.")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
63
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
64 (defvar pymacs-timeout-at-reply 5
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
65 "Expected maximum time, in seconds, to get the first line of a reply.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
66 The status of the Pymacs helper is checked at every such timeout.")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
67
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
68 (defvar pymacs-timeout-at-line 2
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
69 "Expected maximum time, in seconds, to get another line of a reply.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
70 The status of the Pymacs helper is checked at every such timeout.")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
71
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
72 (defvar pymacs-dreadful-zombies nil
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
73 "If zombies should trigger hard errors, whenever they get called.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
74 If `nil', calling a zombie will merely produce a diagnostic message.")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
75
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
76 (defun pymacs-load (module &optional prefix noerror)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
77 "Import the Python module named MODULE into Emacs.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
78 Each function in the Python module is made available as an Emacs function.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
79 The Lisp name of each function is the concatenation of PREFIX with
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
80 the Python name, in which underlines are replaced by dashes. If PREFIX is
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
81 not given, it defaults to MODULE followed by a dash.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
82 If NOERROR is not nil, do not raise error when the module is not found."
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
83 (interactive
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
84 (let* ((module (read-string "Python module? "))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
85 (default (concat (car (last (split-string module "\\."))) "-"))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
86 (prefix (read-string (format "Prefix? [%s] " default)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
87 nil nil default)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
88 (list module prefix)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
89 (message "Pymacs loading %s..." module)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
90 (let ((lisp-code (pymacs-call "pymacs_load_helper" module prefix)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
91 (cond (lisp-code (let ((result (eval lisp-code)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
92 (message "Pymacs loading %s...done" module)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
93 result))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
94 (noerror (message "Pymacs loading %s...failed" module) nil)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
95 (t (pymacs-report-error "Pymacs loading %s...failed" module)))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
96
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
97 (defun pymacs-eval (text)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
98 "Compile TEXT as a Python expression, and return its value."
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
99 (interactive "sPython expression? ")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
100 (let ((value (pymacs-serve-until-reply "eval" `(princ ,text))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
101 (when (interactive-p)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
102 (message "%S" value))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
103 value))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
104
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
105 (defun pymacs-exec (text)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
106 "Compile and execute TEXT as a sequence of Python statements.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
107 This functionality is experimental, and does not appear to be useful."
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
108 (interactive "sPython statements? ")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
109 (let ((value (pymacs-serve-until-reply "exec" `(princ ,text))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
110 (when (interactive-p)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
111 (message "%S" value))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
112 value))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
113
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
114 (defun pymacs-call (function &rest arguments)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
115 "Return the result of calling a Python function FUNCTION over ARGUMENTS.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
116 FUNCTION is a string denoting the Python function, ARGUMENTS are separate
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
117 Lisp expressions, one per argument. Immutable Lisp constants are converted
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
118 to Python equivalents, other structures are converted into Lisp handles."
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
119 (pymacs-serve-until-reply
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
120 "eval" `(pymacs-print-for-apply ',function ',arguments)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
121
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
122 (defun pymacs-apply (function arguments)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
123 "Return the result of calling a Python function FUNCTION over ARGUMENTS.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
124 FUNCTION is a string denoting the Python function, ARGUMENTS is a list of
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
125 Lisp expressions. Immutable Lisp constants are converted to Python
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
126 equivalents, other structures are converted into Lisp handles."
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
127 (pymacs-serve-until-reply
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
128 "eval" `(pymacs-print-for-apply ',function ',arguments)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
129
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
130 ;;; Integration details.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
131
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
132 ;; Python functions and modules should ideally look like Lisp functions and
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
133 ;; modules. This page tries to increase the integration seamlessness.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
134
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
135 (defadvice documentation (around pymacs-ad-documentation activate)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
136 ;; Integration of doc-strings.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
137 (let* ((reference (pymacs-python-reference function))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
138 (python-doc (when reference
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
139 (pymacs-eval (format "doc_string(%s)" reference)))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
140 (if (or reference python-doc)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
141 (setq ad-return-value
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
142 (concat
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
143 "It interfaces to a Python function.\n\n"
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
144 (when python-doc
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
145 (if raw python-doc (substitute-command-keys python-doc)))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
146 ad-do-it)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
147
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
148 (defun pymacs-python-reference (object)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
149 ;; Return the text reference of a Python object if possible, else nil.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
150 (when (functionp object)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
151 (let* ((definition (indirect-function object))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
152 (body (and (pymacs-proper-list-p definition)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
153 (> (length definition) 2)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
154 (eq (car definition) 'lambda)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
155 (cddr definition))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
156 (when (and body (listp (car body)) (eq (caar body) 'interactive))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
157 ;; Skip the interactive specification of a function.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
158 (setq body (cdr body)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
159 (when (and body
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
160 ;; Advised functions start with a string.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
161 (not (stringp (car body)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
162 ;; Python trampolines hold exactly one expression.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
163 (= (length body) 1))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
164 (let ((expression (car body)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
165 ;; EXPRESSION might now hold something like:
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
166 ;; (pymacs-apply (quote (pymacs-python . N)) ARGUMENT-LIST)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
167 (when (and (pymacs-proper-list-p expression)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
168 (= (length expression) 3)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
169 (eq (car expression) 'pymacs-apply)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
170 (eq (car (cadr expression)) 'quote))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
171 (setq object (cadr (cadr expression))))))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
172 (when (eq (car-safe object) 'pymacs-python)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
173 (format "python[%d]" (cdr object))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
174
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
175 ;; The following functions are experimental -- they are not satisfactory yet.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
176
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
177 (defun pymacs-file-handler (operation &rest arguments)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
178 ;; Integration of load-file, autoload, etc.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
179 ;; Emacs might want the contents of some `MODULE.el' which does not exist,
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
180 ;; while there is a `MODULE.py' or `MODULE.pyc' file in the same directory.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
181 ;; The goal is to generate a virtual contents for this `MODULE.el' file, as
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
182 ;; a set of Lisp trampoline functions to the Python module functions.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
183 ;; Python modules can then be loaded or autoloaded as if they were Lisp.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
184 (cond ((and (eq operation 'file-readable-p)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
185 (let ((module (substring (car arguments) 0 -3)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
186 (or (pymacs-file-force operation arguments)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
187 (file-readable-p (concat module ".py"))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
188 (file-readable-p (concat module ".pyc"))))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
189 ((and (eq operation 'load)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
190 (not (pymacs-file-force
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
191 'file-readable-p (list (car arguments))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
192 (file-readable-p (car arguments)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
193 (let ((lisp-code (pymacs-call "pymacs_load_helper"
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
194 (substring (car arguments) 0 -3)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
195 nil)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
196 (unless lisp-code
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
197 (pymacs-report-error "Python import error"))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
198 (eval lisp-code)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
199 ((and (eq operation 'insert-file-contents)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
200 (not (pymacs-file-force
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
201 'file-readable-p (list (car arguments))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
202 (file-readable-p (car arguments)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
203 (let ((lisp-code (pymacs-call "pymacs_load_helper"
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
204 (substring (car arguments) 0 -3)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
205 nil)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
206 (unless lisp-code
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
207 (pymacs-report-error "Python import error"))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
208 (insert (prin1-to-string lisp-code))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
209 (t (pymacs-file-force operation arguments))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
210
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
211 (defun pymacs-file-force (operation arguments)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
212 ;; Bypass the file handler.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
213 (let ((inhibit-file-name-handlers
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
214 (cons 'pymacs-file-handler
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
215 (and (eq inhibit-file-name-operation operation)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
216 inhibit-file-name-handlers)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
217 (inhibit-file-name-operation operation))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
218 (apply operation arguments)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
219
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
220 ;(add-to-list 'file-name-handler-alist '("\\.el\\'" . pymacs-file-handler))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
221
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
222 ;;; Gargabe collection of Python IDs.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
223
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
224 ;; Python objects which have no Lisp representation are allocated on the
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
225 ;; Python side as `python[INDEX]', and INDEX is transmitted to Emacs, with
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
226 ;; the value to use on the Lisp side for it. Whenever Lisp does not need a
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
227 ;; Python object anymore, it should be freed on the Python side. The
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
228 ;; following variables and functions are meant to fill this duty.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
229
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
230 (defvar pymacs-used-ids nil
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
231 "List of received IDs, currently allocated on the Python side.")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
232
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
233 (defvar pymacs-weak-hash nil
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
234 "Weak hash table, meant to find out which IDs are still needed.")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
235
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
236 (defvar pymacs-gc-wanted nil
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
237 "Flag if it is time to clean up unused IDs on the Python side.")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
238
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
239 (defvar pymacs-gc-running nil
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
240 "Flag telling that a Pymacs garbage collection is in progress.")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
241
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
242 (defvar pymacs-gc-timer nil
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
243 "Timer to trigger Pymacs garbage collection at regular time intervals.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
244 The timer is used only if `post-gc-hook' is not available.")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
245
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
246 (defun pymacs-schedule-gc (&optional xemacs-list)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
247 (unless pymacs-gc-running
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
248 (setq pymacs-gc-wanted t)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
249
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
250 (defun pymacs-garbage-collect ()
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
251 ;; Clean up unused IDs on the Python side.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
252 (when pymacs-use-hash-tables
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
253 (let ((pymacs-gc-running t)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
254 (pymacs-forget-mutability t)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
255 (ids pymacs-used-ids)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
256 used-ids unused-ids)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
257 (while ids
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
258 (let ((id (car ids)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
259 (setq ids (cdr ids))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
260 (if (gethash id pymacs-weak-hash)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
261 (setq used-ids (cons id used-ids))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
262 (setq unused-ids (cons id unused-ids)))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
263 (setq pymacs-used-ids used-ids
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
264 pymacs-gc-wanted nil)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
265 (when unused-ids
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
266 (pymacs-apply "free_python" unused-ids)))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
267
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
268 (defun pymacs-defuns (arguments)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
269 ;; Take one argument, a list holding a number of items divisible by 3. The
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
270 ;; first argument is an INDEX, the second is a NAME, the third is the
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
271 ;; INTERACTION specification, and so forth. Register Python INDEX with a
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
272 ;; function with that NAME and INTERACTION on the Lisp side. The strange
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
273 ;; calling convention is to minimise quoting at call time.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
274 (while (>= (length arguments) 3)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
275 (let ((index (nth 0 arguments))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
276 (name (nth 1 arguments))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
277 (interaction (nth 2 arguments)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
278 (fset name (pymacs-defun index interaction))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
279 (setq arguments (nthcdr 3 arguments)))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
280
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
281 (defun pymacs-defun (index interaction)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
282 ;; Register INDEX on the Lisp side with a Python object that is a function,
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
283 ;; and return a lambda form calling that function. If the INTERACTION
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
284 ;; specification is nil, the function is not interactive. Otherwise, the
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
285 ;; function is interactive, INTERACTION is then either a string, or the
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
286 ;; index of an argument-less Python function returning the argument list.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
287 (let ((object (pymacs-python index)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
288 (cond ((null interaction)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
289 `(lambda (&rest arguments)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
290 (pymacs-apply ',object arguments)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
291 ((stringp interaction)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
292 `(lambda (&rest arguments)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
293 (interactive ,interaction)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
294 (pymacs-apply ',object arguments)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
295 (t `(lambda (&rest arguments)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
296 (interactive (pymacs-call ',(pymacs-python interaction)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
297 (pymacs-apply ',object arguments))))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
298
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
299 (defun pymacs-python (index)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
300 ;; Register on the Lisp side a Python object having INDEX, and return it.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
301 ;; The result is meant to be recognised specially by `print-for-eval', and
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
302 ;; in the function position by `print-for-apply'.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
303 (let ((object (cons 'pymacs-python index)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
304 (when pymacs-use-hash-tables
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
305 (puthash index object pymacs-weak-hash)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
306 (setq pymacs-used-ids (cons index pymacs-used-ids)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
307 object))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
308
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
309 ;;; Generating Python code.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
310
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
311 ;; Many Lisp expressions cannot fully be represented in Python, at least
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
312 ;; because the object is mutable on the Lisp side. Such objects are allocated
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
313 ;; somewhere into a vector of handles, and the handle index is used for
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
314 ;; communication instead of the expression itself.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
315
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
316 (defvar pymacs-lisp nil
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
317 "Vector of handles to hold transmitted expressions.")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
318
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
319 (defvar pymacs-freed-list nil
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
320 "List of unallocated indices in Lisp.")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
321
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
322 ;; When the Python GC is done with a Lisp object, a communication occurs so to
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
323 ;; free the object on the Lisp side as well.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
324
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
325 (defun pymacs-allocate-lisp (expression)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
326 ;; This function allocates some handle for an EXPRESSION, and return its
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
327 ;; index.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
328 (unless pymacs-freed-list
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
329 (let* ((previous pymacs-lisp)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
330 (old-size (length previous))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
331 (new-size (if (zerop old-size) 100 (+ old-size (/ old-size 2))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
332 (counter new-size))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
333 (setq pymacs-lisp (make-vector new-size nil))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
334 (while (> counter 0)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
335 (setq counter (1- counter))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
336 (if (< counter old-size)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
337 (aset pymacs-lisp counter (aref previous counter))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
338 (setq pymacs-freed-list (cons counter pymacs-freed-list))))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
339 (let ((index (car pymacs-freed-list)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
340 (setq pymacs-freed-list (cdr pymacs-freed-list))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
341 (aset pymacs-lisp index expression)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
342 index))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
343
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
344 (defun pymacs-free-lisp (indices)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
345 ;; This function is triggered from Python side for Lisp handles which lost
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
346 ;; their last reference. These references should be cut on the Lisp side as
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
347 ;; well, or else, the objects will never be garbage-collected.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
348 (while indices
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
349 (let ((index (car indices)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
350 (aset pymacs-lisp index nil)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
351 (setq pymacs-freed-list (cons index pymacs-freed-list)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
352 indices (cdr indices)))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
353
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
354 (defun pymacs-print-for-apply (function arguments)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
355 ;; This function prints a Python expression calling FUNCTION, which is a
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
356 ;; string naming a Python function, or a Python reference, over all its
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
357 ;; ARGUMENTS, which are Lisp expressions.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
358 (let ((separator "")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
359 argument)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
360 (if (eq (car-safe function) 'pymacs-python)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
361 (princ (format "python[%d]" (cdr function)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
362 (princ function))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
363 (princ "(")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
364 (while arguments
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
365 (setq argument (car arguments)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
366 arguments (cdr arguments))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
367 (princ separator)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
368 (setq separator ", ")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
369 (pymacs-print-for-eval argument))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
370 (princ ")")))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
371
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
372 (defun pymacs-print-for-eval (expression)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
373 ;; This function prints a Python expression out of a Lisp EXPRESSION.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
374 (let (done)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
375 (cond ((not expression)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
376 (princ "None")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
377 (setq done t))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
378 ((eq expression t)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
379 (princ "True")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
380 (setq done t))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
381 ((numberp expression)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
382 (princ expression)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
383 (setq done t))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
384 ((stringp expression)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
385 (when (or pymacs-forget-mutability
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
386 (not pymacs-mutable-strings))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
387 (let* ((multibyte (pymacs-multibyte-string-p expression))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
388 (text (if multibyte
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
389 (encode-coding-string expression 'utf-8)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
390 (copy-sequence expression))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
391 (set-text-properties 0 (length text) nil text)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
392 (princ (mapconcat 'identity
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
393 (split-string (prin1-to-string text) "\n")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
394 "\\n"))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
395 (when (and multibyte
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
396 (not (equal (find-charset-string text) '(ascii))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
397 (princ ".decode('UTF-8')")))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
398 (setq done t)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
399 ((symbolp expression)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
400 (let ((name (symbol-name expression)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
401 ;; The symbol can only be transmitted when in the main oblist.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
402 (when (eq expression (intern-soft name))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
403 (princ "lisp[")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
404 (prin1 name)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
405 (princ "]")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
406 (setq done t))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
407 ((vectorp expression)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
408 (when pymacs-forget-mutability
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
409 (let ((limit (length expression))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
410 (counter 0))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
411 (princ "(")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
412 (while (< counter limit)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
413 (unless (zerop counter)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
414 (princ ", "))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
415 (pymacs-print-for-eval (aref expression counter))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
416 (setq counter (1+ counter)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
417 (when (= limit 1)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
418 (princ ","))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
419 (princ ")")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
420 (setq done t))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
421 ((eq (car-safe expression) 'pymacs-python)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
422 (princ "python[")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
423 (princ (cdr expression))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
424 (princ "]")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
425 (setq done t))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
426 ((pymacs-proper-list-p expression)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
427 (when pymacs-forget-mutability
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
428 (princ "[")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
429 (pymacs-print-for-eval (car expression))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
430 (while (setq expression (cdr expression))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
431 (princ ", ")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
432 (pymacs-print-for-eval (car expression)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
433 (princ "]")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
434 (setq done t))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
435 (unless done
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
436 (let ((class (cond ((vectorp expression) "Vector")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
437 ((and pymacs-use-hash-tables
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
438 (hash-table-p expression))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
439 "Table")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
440 ((bufferp expression) "Buffer")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
441 ((pymacs-proper-list-p expression) "List")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
442 (t "Lisp"))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
443 (princ class)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
444 (princ "(")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
445 (princ (pymacs-allocate-lisp expression))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
446 (princ ")")))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
447
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
448 ;;; Communication protocol.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
449
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
450 (defvar pymacs-transit-buffer nil
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
451 "Communication buffer between Emacs and Python.")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
452
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
453 ;; The principle behind the communication protocol is that it is easier to
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
454 ;; generate than parse, and that each language already has its own parser.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
455 ;; So, the Emacs side generates Python text for the Python side to interpret,
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
456 ;; while the Python side generates Lisp text for the Lisp side to interpret.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
457 ;; About nothing but expressions are transmitted, which are evaluated on
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
458 ;; arrival. The pseudo `reply' function is meant to signal the final result
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
459 ;; of a series of exchanges following a request, while the pseudo `error'
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
460 ;; function is meant to explain why an exchange could not have been completed.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
461
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
462 ;; The protocol itself is rather simple, and contains human readable text
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
463 ;; only. A message starts at the beginning of a line in the communication
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
464 ;; buffer, either with `>' for the Lisp to Python direction, or `<' for the
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
465 ;; Python to Lisp direction. This is followed by a decimal number giving the
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
466 ;; length of the message text, a TAB character, and the message text itself.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
467 ;; Message direction alternates systematically between messages, it never
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
468 ;; occurs that two successive messages are sent in the same direction. The
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
469 ;; first message is received from the Python side, it is `(version VERSION)'.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
470
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
471 (defun pymacs-start-services ()
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
472 ;; This function gets called automatically, as needed.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
473 (let ((buffer (get-buffer-create "*Pymacs*")))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
474 (with-current-buffer buffer
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
475 (buffer-disable-undo)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
476 (set-buffer-multibyte nil)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
477 (set-buffer-file-coding-system 'raw-text)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
478 (save-match-data
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
479 ;; Launch the Pymacs helper.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
480 (let ((process
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
481 (apply 'start-process "pymacs" buffer
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
482 (let ((python (getenv "PYMACS_PYTHON")))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
483 (if (or (null python) (equal python ""))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
484 "python"
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
485 python))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
486 "-c" (concat "import sys;"
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
487 " from Pymacs.pymacs import main;"
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
488 " main(*sys.argv[1:])")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
489 (mapcar 'expand-file-name pymacs-load-path))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
490 (cond ((fboundp 'set-process-query-on-exit-flag)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
491 (set-process-query-on-exit-flag process nil))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
492 ((fboundp 'process-kill-without-query-process)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
493 (process-kill-without-query process)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
494 ;; Receive the synchronising reply.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
495 (while (progn
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
496 (goto-char (point-min))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
497 (not (re-search-forward "<\\([0-9]+\\)\t" nil t)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
498 (unless (accept-process-output process pymacs-timeout-at-start)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
499 (pymacs-report-error
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
500 "Pymacs helper did not start within %d seconds"
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
501 pymacs-timeout-at-start)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
502 (let ((marker (process-mark process))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
503 (limit-position (+ (match-end 0)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
504 (string-to-number (match-string 1)))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
505 (while (< (marker-position marker) limit-position)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
506 (unless (accept-process-output process pymacs-timeout-at-start)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
507 (pymacs-report-error
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
508 "Pymacs helper probably was interrupted at start")))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
509 ;; Check that synchronisation occurred.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
510 (goto-char (match-end 0))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
511 (let ((reply (read (current-buffer))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
512 (if (and (pymacs-proper-list-p reply)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
513 (= (length reply) 2)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
514 (eq (car reply) 'version))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
515 (unless (string-equal (cadr reply) "0.23")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
516 (pymacs-report-error
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
517 "Pymacs Lisp version is 0.23, Python is %s"
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
518 (cadr reply)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
519 (pymacs-report-error "Pymacs got an invalid initial reply")))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
520 (when pymacs-use-hash-tables
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
521 (if pymacs-weak-hash
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
522 ;; A previous Pymacs session occurred in *this* Emacs session. Some
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
523 ;; IDs may hang around, which do not correspond to anything on the
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
524 ;; Python side. Python should not recycle such IDs for new objects.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
525 (when pymacs-used-ids
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
526 (let ((pymacs-transit-buffer buffer)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
527 (pymacs-forget-mutability t))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
528 (pymacs-apply "zombie_python" pymacs-used-ids)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
529 (setq pymacs-weak-hash (make-hash-table :weakness 'value)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
530 (if (boundp 'post-gc-hook)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
531 (add-hook 'post-gc-hook 'pymacs-schedule-gc)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
532 (setq pymacs-gc-timer (run-at-time 20 20 'pymacs-schedule-gc))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
533 ;; If nothing failed, only then declare that Pymacs has started!
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
534 (setq pymacs-transit-buffer buffer)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
535
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
536 (defun pymacs-terminate-services ()
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
537 ;; This function is mainly provided for documentation purposes.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
538 (interactive)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
539 (garbage-collect)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
540 (pymacs-garbage-collect)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
541 (when (or (not pymacs-used-ids)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
542 (yes-or-no-p "\
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
543 Killing the Pymacs helper might create zombie objects. Kill? "))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
544 (cond ((boundp 'post-gc-hook)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
545 (remove-hook 'post-gc-hook 'pymacs-schedule-gc))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
546 ((timerp pymacs-gc-timer)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
547 (cancel-timer pymacs-gc-timer)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
548 (when pymacs-transit-buffer
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
549 (kill-buffer pymacs-transit-buffer))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
550 (setq pymacs-gc-running nil
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
551 pymacs-gc-timer nil
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
552 pymacs-transit-buffer nil
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
553 pymacs-lisp nil
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
554 pymacs-freed-list nil)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
555
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
556 (defun pymacs-serve-until-reply (action inserter)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
557 ;; This function builds a Python request by printing ACTION and
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
558 ;; evaluating INSERTER, which itself prints an argument. It then
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
559 ;; sends the request to the Pymacs helper, and serves all
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
560 ;; sub-requests coming from the Python side, until either a reply or
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
561 ;; an error is finally received.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
562 (unless (and pymacs-transit-buffer
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
563 (buffer-name pymacs-transit-buffer)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
564 (get-buffer-process pymacs-transit-buffer))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
565 (pymacs-start-services))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
566 (when pymacs-gc-wanted
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
567 (pymacs-garbage-collect))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
568 (let ((inhibit-quit t)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
569 done value)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
570 (while (not done)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
571 (let ((form (pymacs-round-trip action inserter)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
572 (setq action (car form))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
573 (when (eq action 'free)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
574 (pymacs-free-lisp (cadr form))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
575 (setq form (cddr form)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
576 action (car form)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
577 (let* ((pair (pymacs-interruptible-eval (cadr form)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
578 (success (cdr pair)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
579 (setq value (car pair))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
580 (cond ((eq action 'eval)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
581 (if success
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
582 (setq action "return"
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
583 inserter `(pymacs-print-for-eval ',value))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
584 (setq action "raise"
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
585 inserter `(let ((pymacs-forget-mutability t))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
586 (pymacs-print-for-eval ,value)))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
587 ((eq action 'expand)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
588 (if success
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
589 (setq action "return"
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
590 inserter `(let ((pymacs-forget-mutability t))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
591 (pymacs-print-for-eval ,value)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
592 (setq action "raise"
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
593 inserter `(let ((pymacs-forget-mutability t))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
594 (pymacs-print-for-eval ,value)))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
595 ((eq action 'return)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
596 (if success
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
597 (setq done t)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
598 (pymacs-report-error "%s" value)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
599 ((eq action 'raise)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
600 (if success
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
601 (pymacs-report-error "Python: %s" value)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
602 (pymacs-report-error "%s" value)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
603 (t (pymacs-report-error "Protocol error: %s" form))))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
604 value))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
605
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
606 (defun pymacs-round-trip (action inserter)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
607 ;; This function produces a Python request by printing and
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
608 ;; evaluating INSERTER, which itself prints an argument. It sends
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
609 ;; the request to the Pymacs helper, awaits for any kind of reply,
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
610 ;; and returns it.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
611 (with-current-buffer pymacs-transit-buffer
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
612 ;; Possibly trim the beginning of the transit buffer.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
613 (cond ((not pymacs-trace-transit)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
614 (erase-buffer))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
615 ((consp pymacs-trace-transit)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
616 (when (> (buffer-size) (cdr pymacs-trace-transit))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
617 (let ((cut (- (buffer-size) (car pymacs-trace-transit))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
618 (when (> cut 0)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
619 (save-excursion
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
620 (goto-char cut)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
621 (unless (memq (preceding-char) '(0 ?\n))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
622 (forward-line 1))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
623 (delete-region (point-min) (point))))))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
624 ;; Send the request, wait for a reply, and process it.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
625 (let* ((process (get-buffer-process pymacs-transit-buffer))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
626 (status (process-status process))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
627 (marker (process-mark process))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
628 (moving (= (point) marker))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
629 send-position reply-position reply)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
630 (save-excursion
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
631 (save-match-data
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
632 ;; Encode request.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
633 (setq send-position (marker-position marker))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
634 (let ((standard-output marker))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
635 (princ action)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
636 (princ " ")
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
637 (eval inserter))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
638 (goto-char marker)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
639 (unless (= (preceding-char) ?\n)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
640 (princ "\n" marker))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
641 ;; Send request text.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
642 (goto-char send-position)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
643 (insert (format ">%d\t" (- marker send-position)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
644 (setq reply-position (marker-position marker))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
645 (process-send-region process send-position marker)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
646 ;; Receive reply text.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
647 (while (and (eq status 'run)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
648 (progn
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
649 (goto-char reply-position)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
650 (not (re-search-forward "<\\([0-9]+\\)\t" nil t))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
651 (unless (accept-process-output process pymacs-timeout-at-reply)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
652 (setq status (process-status process))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
653 (when (eq status 'run)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
654 (let ((limit-position (+ (match-end 0)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
655 (string-to-number (match-string 1)))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
656 (while (and (eq status 'run)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
657 (< (marker-position marker) limit-position))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
658 (unless (accept-process-output process pymacs-timeout-at-line)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
659 (setq status (process-status process))))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
660 ;; Decode reply.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
661 (if (not (eq status 'run))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
662 (pymacs-report-error "Pymacs helper status is `%S'" status)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
663 (goto-char (match-end 0))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
664 (setq reply (read (current-buffer))))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
665 (when (and moving (not pymacs-trace-transit))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
666 (goto-char marker))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
667 reply)))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
668
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
669 (defun pymacs-interruptible-eval (expression)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
670 ;; This function produces a pair (VALUE . SUCCESS) for EXPRESSION.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
671 ;; A cautious evaluation of EXPRESSION is attempted, and any
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
672 ;; error while evaluating is caught, including Emacs quit (C-g).
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
673 ;; Any Emacs quit also gets forward as a SIGINT to the Pymacs handler.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
674 ;; With SUCCESS being true, VALUE is the expression value.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
675 ;; With SUCCESS being false, VALUE is an interruption diagnostic.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
676 (condition-case info
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
677 (cons (let ((inhibit-quit nil)) (eval expression)) t)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
678 (quit (setq quit-flag t)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
679 (interrupt-process pymacs-transit-buffer)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
680 (cons "*Interrupted!*" nil))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
681 (error (cons (prin1-to-string info) nil))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
682
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
683 (defun pymacs-proper-list-p (expression)
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
684 ;; Tell if a list is proper, id est, that it is `nil' or ends with `nil'.
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
685 (cond ((not expression))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
686 ((consp expression) (not (cdr (last expression))))))
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
687
c30d68fbd368 Initial import from svn.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
688 (provide 'pymacs)