Mercurial > hg > xemacs-beta
comparison lisp/subr.el @ 5522:544e6336d37c
Reimplement a few GNU functions in terms of CL functions, subr.el
2011-06-19 Aidan Kehoe <kehoea@parhasard.net>
* cl-macs.el:
* cl-macs.el (assoc-ignore-case, assoc-ignore-representation):
* cl-macs.el (member-ignore-case): New compiler macros.
* subr.el (assoc-ignore-case):
* subr.el (assoc-ignore-representation):
* subr.el (member-ignore-case):
* subr.el (split-path):
* subr.el (delete-dups):
Reimplement a few GNU functions in terms of their CL counterparts,
for the sake of circularity checking and some speed; add type
checking (used in interpreted code and with low speed and safety
checking) for the sake of revealing incompatibilities when
developing.
* subr.el (remove-hook):
There's no need for flet here, an explicit lambda is enough.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sun, 19 Jun 2011 17:43:03 +0100 |
parents | b0d87f92e60b |
children | b908c7265a2b |
comparison
equal
deleted
inserted
replaced
5521:3310f36295a0 | 5522:544e6336d37c |
---|---|
109 ;; Built-in. Our `last' is more powerful in that it handles circularity. | 109 ;; Built-in. Our `last' is more powerful in that it handles circularity. |
110 ;(defun last (x &optional n) | 110 ;(defun last (x &optional n) |
111 ;(defun butlast (x &optional n) | 111 ;(defun butlast (x &optional n) |
112 ;(defun nbutlast (x &optional n) | 112 ;(defun nbutlast (x &optional n) |
113 | 113 |
114 ;; In cl-seq.el. | |
115 ;(defun remove (elt seq) | |
116 ;(defun remq (elt list) | |
117 | |
118 (defmacro defun-when-void (&rest args) | 114 (defmacro defun-when-void (&rest args) |
119 "Define a function, just like `defun', unless it's already defined. | 115 "Define a function, just like `defun', unless it's already defined. |
120 Used for compatibility among different emacs variants." | 116 Used for compatibility among different emacs variants." |
121 `(if (fboundp ',(car args)) | 117 `(if (fboundp ',(car args)) |
122 nil | 118 nil |
183 value)) | 179 value)) |
184 | 180 |
185 (defun assoc-ignore-case (key alist) | 181 (defun assoc-ignore-case (key alist) |
186 "Like `assoc', but ignores differences in case and text representation. | 182 "Like `assoc', but ignores differences in case and text representation. |
187 KEY must be a string. Upper-case and lower-case letters are treated as equal." | 183 KEY must be a string. Upper-case and lower-case letters are treated as equal." |
188 (let (element) | 184 (assoc* (the string key) |
189 (while (and alist (not element)) | 185 (the (and list (satisfies (lambda (list) |
190 (if (eq t (compare-strings key 0 nil (car (car alist)) 0 nil t)) | 186 (not (find-if-not 'stringp list |
191 (setq element (car alist))) | 187 :key 'car))))) alist) |
192 (setq alist (cdr alist))) | 188 :test 'equalp)) |
193 element)) | |
194 | 189 |
195 (defun assoc-ignore-representation (key alist) | 190 (defun assoc-ignore-representation (key alist) |
196 "Like `assoc', but ignores differences in text representation. | 191 "Like `assoc', but ignores differences in text representation. |
197 KEY must be a string." | 192 KEY must be a string." |
198 (let (element) | 193 (assoc* (the string key) |
199 (while (and alist (not element)) | 194 (the (and list (satisfies (lambda (list) |
200 (if (eq t (compare-strings key 0 nil (car (car alist)) 0 nil)) | 195 (not (find-if-not 'stringp list |
201 (setq element (car alist))) | 196 :key 'car))))) alist) |
202 (setq alist (cdr alist))) | 197 :test 'equalp)) |
203 element)) | |
204 | 198 |
205 (defun member-ignore-case (elt list) | 199 (defun member-ignore-case (elt list) |
206 "Like `member', but ignores differences in case and text representation. | 200 "Like `member', but ignores differences in case and text representation. |
207 ELT must be a string. Upper-case and lower-case letters are treated as equal." | 201 ELT must be a string. Upper-case and lower-case letters are treated as equal." |
208 (while (and list (not (eq t (compare-strings elt 0 nil (car list) 0 nil t)))) | 202 (member* (the string elt) |
209 (setq list (cdr list))) | 203 (the (and list (satisfies (lambda (list) (every 'stringp list)))) |
210 list) | 204 list) |
211 | 205 :test 'equalp)) |
212 | 206 |
213 ;;;; Keymap support. | 207 ;;;; Keymap support. |
214 ;; XEmacs: removed to keymap.el | 208 ;; XEmacs: removed to keymap.el |
215 | 209 |
216 ;;;; The global keymap tree. | 210 ;;;; The global keymap tree. |
349 ;; and do what we used to do. | 343 ;; and do what we used to do. |
350 (unless (and (consp (symbol-value hook)) (memq t (symbol-value hook))) | 344 (unless (and (consp (symbol-value hook)) (memq t (symbol-value hook))) |
351 (setq local t))) | 345 (setq local t))) |
352 (let ((hook-value (if local (symbol-value hook) (default-value hook)))) | 346 (let ((hook-value (if local (symbol-value hook) (default-value hook)))) |
353 ;; Remove the function, for both the list and the non-list cases. | 347 ;; Remove the function, for both the list and the non-list cases. |
354 ;; XEmacs: add hook-test, for handling one-shot hooks. | 348 ;; XEmacs: call #'remove-if, rather than delete, since we check for |
355 (flet ((hook-test | 349 ;; one-shot hooks too. |
356 (fn hel) | 350 (if (or (not (listp hook-value)) (eq (car hook-value) 'lambda)) |
357 (or (equal fn hel) | 351 (if (equal hook-value function) (setq hook-value nil)) |
358 (and (symbolp hel) | 352 (setq hook-value |
359 (equal fn | 353 (remove-if #'(lambda (elt) |
360 (get hel 'one-shot-hook-fun)))))) | 354 (or (equal function elt) |
361 (if (or (not (listp hook-value)) (eq (car hook-value) 'lambda)) | 355 (and (symbolp elt) |
362 (if (equal hook-value function) (setq hook-value nil)) | 356 (equal function |
363 (setq hook-value (delete* function (copy-sequence hook-value) | 357 (get elt 'one-shot-hook-fun))))) |
364 :test 'hook-test))) | 358 hook-value)) |
365 ;; If the function is on the global hook, we need to shadow it locally | |
366 ;;(when (and local (member* function (default-value hook) | |
367 ;; :test 'hook-test) | |
368 ;; (not (member* (cons 'not function) hook-value | |
369 ;; :test 'hook-test))) | |
370 ;; (push (cons 'not function) hook-value)) | |
371 ;; Set the actual variable | 359 ;; Set the actual variable |
372 (if local (set hook hook-value) (set-default hook hook-value))))) | 360 (if local (set hook hook-value) (set-default hook hook-value))))) |
373 | 361 |
374 ;; XEmacs addition | 362 ;; XEmacs addition |
375 ;; #### we need a coherent scheme for indicating compatibility info, | 363 ;; #### we need a coherent scheme for indicating compatibility info, |
491 | 479 |
492 (defun split-path (path) | 480 (defun split-path (path) |
493 "Explode a search path into a list of strings. | 481 "Explode a search path into a list of strings. |
494 The path components are separated with the characters specified | 482 The path components are separated with the characters specified |
495 with `path-separator'." | 483 with `path-separator'." |
496 (while (or (not (stringp path-separator)) | 484 (while (not (and (stringp path-separator) (eql (length path-separator) 1))) |
497 (/= (length path-separator) 1)) | |
498 (setq path-separator (signal 'error (list "\ | 485 (setq path-separator (signal 'error (list "\ |
499 `path-separator' should be set to a single-character string" | 486 `path-separator' should be set to a single-character string" |
500 path-separator)))) | 487 path-separator)))) |
501 (split-string-by-char path (aref path-separator 0))) | 488 (split-string-by-char path (aref path-separator 0))) |
502 | 489 |
1720 (defun delete-dups (list) | 1707 (defun delete-dups (list) |
1721 "Destructively remove `equal' duplicates from LIST. | 1708 "Destructively remove `equal' duplicates from LIST. |
1722 Store the result in LIST and return it. LIST must be a proper list. | 1709 Store the result in LIST and return it. LIST must be a proper list. |
1723 Of several `equal' occurrences of an element in LIST, the first | 1710 Of several `equal' occurrences of an element in LIST, the first |
1724 one is kept." | 1711 one is kept." |
1725 (let ((tail list)) | 1712 (delete-duplicates (the list list) :test 'equal :from-end t)) |
1726 (while tail | |
1727 (setcdr tail (delete (car tail) (cdr tail))) | |
1728 (setq tail (cdr tail)))) | |
1729 list) | |
1730 | 1713 |
1731 ;; END SYNC WITH FSF 22.0.50.1 (CVS) | 1714 ;; END SYNC WITH FSF 22.0.50.1 (CVS) |
1732 | 1715 |
1733 ;; (defun shell-quote-argument (argument) in process.el. | 1716 ;; (defun shell-quote-argument (argument) in process.el. |
1734 | 1717 |