source: branches/1.2-devel/ccl/cocoa-ide/hemlock/unused/archive/elisp/base.lisp

Last change on this file was 6, checked in by Gary Byers, 21 years ago

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.2 KB
Line 
1(in-package "ELISP")
2
3(defvar load-path nil)
4(defvar features nil)
5(defvar *buffer-locals* (make-hash-table))
6(defvar *current-buffer* nil)
7(define-symbol-macro major-mode (buffer-major-mode (current-buffer)))
8
9
10(cl:defun make-sparse-keymap (&optional string)
11 (if string
12 (list 'keymap string)
13 (list 'keymap)))
14
15(cl:defun make-keymap (&optional string)
16 (if string
17 (list 'keymap string (make-vector 256))
18 (list 'keymap (make-vector 256))))
19
20(cl:defun make-sparse-keymap (&optional string)
21 (if string
22 (list 'keymap string)
23 (list 'keymap)))
24
25(cl:defun buffer-local-p (sym)
26 (multiple-value-bind (expansion expanded) (macroexpand sym)
27 (declare (ignore expansion))
28 expanded))
29
30(cl:defun elisp-value (sym)
31 (cl:let ((marker (gensym)))
32 (multiple-value-bind (value exists)
33 (gethash sym *buffer-locals*)
34 (if exists
35 (hemlock::variable-value sym)
36 (eval sym)))))
37
38(cl:defun = (a b)
39 (cond ((and (characterp a) (characterp b))
40 (char= a b))
41 ((and (numberp a) (characterp b))
42 (cl:= a (char-code b)))
43 ((and (characterp a) (numberp b))
44 (cl:= (char-code a) b))
45 ((and (numberp a) (numberp b))
46 (cl:= a b))
47 (t (error "Wrong type argument ~a" (if (or (numberp a) (characterp a))
48 b
49 a)))))
50
51(cl:defun make-variable-buffer-local (sym)
52 (make-variable-foo-local sym :buffer))
53
54(cl:defun make-variable-foo-local (sym kind)
55 "MAKE-VARIABLES-BUFFER-LOCAL
56Arguments SYMBOL
57
58Will make a variable buffer-local UNLESS it has prior special binding,
59this may be a grave incompatibility with Emacs Lisp.
60
61In a buffer where no dedicated value has been set, will use the
62default-value. The default value is set with SET-DEFAULT."
63 (unless (hemlock::hemlock-bound-p sym)
64 (setf (gethash sym *buffer-locals*) kind)
65 (defhvar sym "Variable automatically set from ELISP" :mode :kind)
66 ))
67
68
69;;; Troublesome? Looks like it IM -- 2003-04-05
70(cl:defun set-default (sym value)
71 "SET-DEFAULT
72Args: SYMBOL VALUE
73
74Will set the default value of (the buffer-local) SYMBOL to VALUE"
75 (if (buffer-local-p sym)
76 (setf (gethash *buffer-locals* (gethash sym *buffer-locals*)) value)
77 (set sym value)))
78
79;;; Troublesome? Looks like it IM -- 2003-04-05
80(cl:defun get-default (sym)
81 "GET-DEFAULT
82Args: SYMBOL
83
84Returns the default value for SYMBOL"
85 (if (buffer-local-p sym)
86 (gethash *buffer-locals* (gethash sym *buffer-locals*))
87 (symbol-value sym)))
88
89(cl:defmacro interactive (&rest spec)
90 (declare (ignore spec))
91 nil)
92
93;;; This really should generate a glue function to handle the differences
94;;; betwen emacs command calling conventions and Hemlock ccc.
95;;; Basically, what we need is a layer that does all the prompting that
96;;; would've been done on an interactive call in emacs. Probably simplest
97;;; to just generate a lambda with the right stuff prompted for, then have
98;;; that call the function proper.
99(cl:defmacro defun (name args &body body)
100 (cl:let ((real-args (elisp-internals:find-lambda-list-variables args))
101 (body (walk-code `(defun ,name ,args ,@body)))
102 (maybe-docstring (car body))
103 (interactive-p (member 'interactive body :key #'(lambda (x) (when (consp x) (car x))))))
104 (if interactive-p
105 `(prog1
106 (cl:defun ,name ,args
107 (declare (special ,@real-args))
108 ,@(cdddr body))
109 (make-command ,(string-downcase (string name))
110 ,(if (stringp maybe-docstring)
111 maybe-docstring
112 (format nil "This implements the elisp command for function ~a." (string name))) ,(elisp-internals:interactive-glue (cadr (car interactive-p)) name)))
113
114 `(cl:defun ,name ,args
115 (declare (special ,@real-args))
116 ,@(cdddr body)))))
117
118(cl:defmacro let (inits &body body)
119 (cl:let ((vars (loop for var in inits
120 collect (cl:if (symbolp var) var (car var)))))
121 `(cl:let ,inits
122 (declare (special ,@vars))
123 ,@body)))
124
125(cl:defmacro if (test true &rest falses)
126 `(cl:if ,test ,true (progn ,@falses)))
127
128(cl:defmacro lexical-let (&rest body)
129 `(cl:let ,@body ))
130
131(cl:defmacro setq (&rest rest)
132 `(cl:setf ,@rest))
133
134(cl:defun provide (feature)
135 (cl:push feature features))
136
137(cl:defun require (feature &optional filename noerror)
138 (let ((*readtable* elisp-internals:*elisp-readtable*))
139 (or
140 (car (member feature features))
141 (loop for directory in load-path
142 if (elisp-internals:require-load directory feature filename)
143 return feature)
144 (unless noerror
145 (error "Cannot open file ~a." (if filename
146 filename
147 (cl:string-downcase feature)))))))
148
149;; Done via CL:DEFUN since the code walker wreaks havoc with the loop macro.
150;; Keep these together for sanity's sake
151(cl:defun load-library (library-name)
152 (loop for directory in load-path
153 do (loop for ext in '(".el" "")
154 for name = (format nil "~a/~a~a" directory library-name ext)
155 if (cl:probe-file name)
156 do (return-from load-library
157 (let (*package* (find-package "ELISP-USER"))
158 (let ((*readtable* elisp-internals:*elisp-readtable*))
159 (cl:load name)))))))
160
161(cl:defun load-file (filename)
162 (let ((*readtable* elisp-internals:*elisp-readtable*)
163 (*package* (find-package "ELISP-USER")))
164 (load filename)))
165
166(make-command "load-file" "Load a file, elisp style" #'(lambda (p) (declare (ignore p)) (load-file (hemlock-internals:prompt-for-file :prompt "Load file: "))))
167(make-command "load-library" "Load a library, elisp-style" #'(lambda (p) (declare (ignore p)) (load-library (hemlock-internals:prompt-for-string :prompt "Load library: "))))
168;; End of things kept together
169
170;; Unfinished, including at least *one* function taht isn't implemented
171;; (and will be hell to make portably, I'm afraid)
172(cl:defun expand-file-name (name &optional default-directory)
173 (cl:let ((result (search "~" name)))
174 (if result
175 (cl:let ((name (subseq name result)))
176 (if (char= (cl:aref name 1) #\/)
177 (merge-pathnames (subseq name 2) (elisp-internals:get-user-homedir))
178 (cl:let ((username (subseq name 1 (search "/" name)))
179 (directory (subseq name (1+ (search "/" name)))))
180 (merge-pathnames directory (elisp-internals:get-user-homedir username)))))
181 name
182 )))
183
184(cl:defmacro while (test &body body)
185 `(cl:do ()
186 ((not ,test) nil)
187 ,@body))
188
189(cl:defmacro aset (array index new-element)
190 `(setf (cl:aref ,array ,index) ,new-element))
191
192(cl:defmacro assq (key list)
193 `(cl:assoc ,key ,list :test 'eq))
194
195(cl:defmacro assoc (key list)
196 `(cl:assoc ,key ,list :test 'equal))
197
198(cl:defun % (x y)
199 "Return the remainder of X divided by Y, both X and Y must be integers"
200 (declare (integer x y))
201 (mod x y))
202
203(cl:defun car-safe (object)
204 (when (consp object)
205 (car object)))
206
207(cl:defun cdr-safe (object)
208 (when (consp object)
209 (cdr object)))
210
211(cl:defun car-less-than-car (a b)
212 (< (car a) (car b)))
213
214(cl:defun bool-vector-p (array)
215 (and (simple-vector-p array)
216 (eq (element-type array) 'bit)))
217
218(cl:defun aref (vector &rest indices)
219 (if (bool-vector-p vector)
220 (= 1 (apply #'cl:aref vector indices))
221 (apply #'cl:aref vector indices)))
222
223(cl:defun make-bool-vector (length init)
224 (make-array (list length) :element-type bit :initial-element (if init 1 0)))
225
226(cl:defun delq (element list)
227 (cl:delete element list :test #'cl:eq))
228
229(cl:defun fset (symbol function)
230 (cl:setf (symbol-function symbol) function))
231
232(cl:defmacro autoload (function file &optional docstring interactive type)
233 (cond ((and docstring interactive)
234 `(defun ,function (&rest args)
235 ,docstring
236 (interactive)
237 (unless (gethash ',function elisp-internals::*autoloads* nil)
238 (setf (gethash ',function elisp-internals::*autoloads*) t)
239 (load ,file))
240 (apply ',function args)))
241 ((and docstring (not interactive))
242 `(defun ,function (&rest args)
243 ,docstring
244 (unless (gethash ',function elisp-internals::*autoloads* nil)
245 (setf (gethash ',function elisp-internals::*autoloads*) t)
246 (load ,file))
247 (apply ',function args)))
248 (interactive
249 `(defun ,function (&rest args)
250 (interactive)
251 (unless (gethash ',function elisp-internals::*autoloads* nil)
252 (setf (gethash ',function elisp-internals::*autoloads*) t)
253 (load ,file))
254 (apply ',function args)))
255 (t
256 `(defun ,function (&rest args)
257 (unless (gethash ',function elisp-internals::*autoloads* nil)
258 (setf (gethash ',function elisp-internals::*autoloads*) t)
259 (load ,file))
260 (apply ',function args)))))
Note: See TracBrowser for help on using the repository browser.