410
+ − 1 ;;; compat.el --- Mechanism for non-intrusively providing compatibility funs.
+ − 2
826
+ − 3 ;; Copyright (C) 2000, 2002 Ben Wing.
410
+ − 4
+ − 5 ;; Author: Ben Wing <ben@xemacs.org>
+ − 6 ;; Maintainer: Ben Wing
+ − 7 ;; Keywords: internal
+ − 8
+ − 9 ;; This file is part of XEmacs.
+ − 10
+ − 11 ;; XEmacs is free software; you can redistribute it and/or modify it
+ − 12 ;; under the terms of the GNU General Public License as published by
+ − 13 ;; the Free Software Foundation; either version 2, or (at your option)
+ − 14 ;; any later version.
+ − 15
+ − 16 ;; XEmacs is distributed in the hope that it will be useful, but
+ − 17 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
+ − 18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ − 19 ;; General Public License for more details.
+ − 20
+ − 21 ;; You should have received a copy of the GNU General Public License
+ − 22 ;; along with XEmacs; see the file COPYING. If not, write to the
+ − 23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ − 24 ;; Boston, MA 02111-1307, USA.
+ − 25
+ − 26 ;;; Synched up with: Not in FSF.
+ − 27
+ − 28 ;;; Authorship:
+ − 29
+ − 30 ; Written May 2000 by Ben Wing.
+ − 31
+ − 32 ;;; Commentary:
+ − 33
826
+ − 34 ;; The idea is to provide emulation of API's in a namespace-clean way. Lots of packages are filled with declarations such as
+ − 35
+ − 36 ;; (defalias 'gnus-overlay-get 'extent-property)
+ − 37
+ − 38 ; There should be a single package to provide such compatibility code. The
+ − 39 ; tricky part is how to do it in a clean way, without packages interfering
+ − 40 ; with each other.
+ − 41
+ − 42 ; The basic usage of compat is:
+ − 43
+ − 44 ; (1) Each package copies compat.el and renames it, e.g. gnus-compat.el.
+ − 45
+ − 46 ; (2) `compat' defines various API's that can be activated. To use them in a
+ − 47 ; file, first place code like this at the top of the file:
+ − 48
+ − 49 ;(let ((compat-current-package 'Gnus))
+ − 50 ; (require 'gnus-compat))
+ − 51
+ − 52 ; then wrap the rest of the code like this:
+ − 53
+ − 54 ; (Gnus-compat-wrap '(overlays events)
+ − 55
+ − 56 ;;; Commentary
+ − 57
+ − 58 ;; blah
+ − 59
+ − 60 ;;; Code
+ − 61
+ − 62 ;(defun random-module-my-fun (bar baz)
+ − 63 ; ...
+ − 64 ; (overlay-put overlay 'face 'bold)
+ − 65 ; ...
+ − 66 ;)
+ − 67 ;
+ − 68 ;(defun ...
+ − 69 ;)
+ − 70 ;
+ − 71 ;
+ − 72 ;
+ − 73 ;
+ − 74 ;) ;; end of (Gnus-compat)
+ − 75
+ − 76 ;;;; random-module.el ends here
+ − 77
+ − 78 ; (3) What this does is implement the requested API's (in this case, the
+ − 79 ; overlay API from GNU Emacs and event API from XEmacs) in whichever
+ − 80 ; version of Emacs is running, with names such as
+ − 81 ; `Gnus-compat-overlay-put', and then it uses `macrolet' to map the
+ − 82 ; generic names in the wrapped code into namespace-clean names. The
+ − 83 ; result of loading `gnus-compat' leaves around only functions beginning
+ − 84 ; with `Gnus-compat' (or whatever prefix was specified in
+ − 85 ; `compat-current-package'). This way, various packages, with various
+ − 86 ; versions of `compat' as part of them, can coexist, with each package
+ − 87 ; running the version of `compat' that it's been tested with. The use of
+ − 88 ; `macrolet' ensures that only code that's lexically wrapped -- not code
+ − 89 ; that's called from that code -- is affected by the API mapping.
+ − 90
410
+ − 91 ;; Typical usage:
+ − 92
+ − 93 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ − 94 ;; 1. Wrap modules that define compatibility functions like this: ;;
+ − 95 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ − 96
+ − 97 ;(compat-define-group 'fsf-compat)
+ − 98
+ − 99 ;(compat-define-functions 'fsf-compat
+ − 100
826
+ − 101 ;(defun overlay-put (overlay prop value)
+ − 102 ; "Set property PROP to VALUE in overlay OVERLAY."
+ − 103 ; (set-extent-property overlay prop value))
410
+ − 104
+ − 105 ;(defun make-overlay (beg end &optional buffer front-advance rear-advance)
+ − 106 ; ...)
+ − 107
+ − 108 ;...
+ − 109
+ − 110 ;) ;; end of (compat-define-group 'fsf-compat)
+ − 111
+ − 112 ;;;; overlay.el ends here
+ − 113
+ − 114
+ − 115 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ − 116 ;; 2. Wrap modules that use the compatibility functions like this: ;;
+ − 117 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ − 118
826
+ − 119 ;(let ((compat-current-package 'gnus))
+ − 120 ; (require 'gnus-compat))
+ − 121 ;
+ − 122 ;(gnus-compat 'fsf-compat
+ − 123 ;
+ − 124 ;; Code:
+ − 125 ;;
+ − 126 ;;
410
+ − 127 ;(defun random-module-my-fun (bar baz)
826
+ − 128 ; ...
+ − 129 ; (overlay-put overlay 'face 'bold)
+ − 130 ; ...
+ − 131 ;)
+ − 132 ;
+ − 133 ;(defun ...
+ − 134 ;)
+ − 135 ;
+ − 136 ;
+ − 137 ;
+ − 138 ;
410
+ − 139 ;) ;; end of (compat 'fsf-compat)
+ − 140
+ − 141 ;;;; random-module.el ends here
+ − 142
826
+ − 143 (defvar compat-current-package)
+ − 144
+ − 145 (eval-when-compile
+ − 146 (setq compat-current-package 'compat))
+ − 147
+ − 148 ;; #### not yet working
+ − 149 '(
+ − 150
+ − 151 (defmacro compat-define-compat-functions (&rest body)
+ − 152 "Define the functions of the `compat' package in a namespace-clean way.
+ − 153 This relies on `compat-current-package' being set. If `compat-current-package'
+ − 154 is equal to the symbol `foo', and within BODY is something like
+ − 155
+ − 156 \(defmacro compat-define-group (group)
+ − 157 ...
+ − 158 )
+ − 159
+ − 160 then this turns into
+ − 161
+ − 162 \(defmacro foo-compat-define-group (group)
+ − 163 ...
+ − 164 )
+ − 165
+ − 166 and all calls are replaced accordingly.
+ − 167
+ − 168
+ − 169
+ − 170
+ − 171 Functions such as
+ − 172 compatibility functions in GROUP.
+ − 173 You should simply wrap this around the code that defines the functions.
+ − 174 Any functions and macros defined at top level using `defun' or `defmacro'
+ − 175 will be noticed and added to GROUP. Other top-level code will be executed
+ − 176 normally. All code and definitions in this group can safely reference any
+ − 177 other functions in this group -- the code is effectively wrapped in a
+ − 178 `compat' call. You can call `compat-define-functions' more than once, if
+ − 179 necessary, for a single group.
+ − 180
+ − 181 What actually happens is that the functions and macros defined here are in
+ − 182 fact defined using names prefixed with GROUP. To use these functions,
+ − 183 wrap any calling code with the `compat' macro, which lexically renames
+ − 184 the function and macro calls appropriately."
+ − 185 (let ((prefix (if (boundp 'compat-current-package)
+ − 186 compat-current-package
+ − 187 (error
+ − 188 "`compat-current-package' must be defined when loading this module")))
+ − 189 (defs-to-munge '(defun defmacro))
+ − 190 mappings)
+ − 191 (if (symbolp prefix) (setq prefix (symbol-name prefix)))
+ − 192 ;; first, note all defuns and defmacros
+ − 193 (let (fundef
+ − 194 (body-tail body))
+ − 195 (while body-tail
+ − 196 (setq fundef (car body-tail))
+ − 197 (when (and (consp fundef) (memq (car fundef) defs-to-munge))
+ − 198 (push (cons (second fundef) (third fundef)) mappings))
+ − 199 (setq body-tail (cdr body-tail))))
+ − 200 ;; now, munge the definitions with the new names
+ − 201 (let (fundef
+ − 202 (body-tail body)
+ − 203 result
+ − 204 defs)
+ − 205 (while body-tail
+ − 206 (setq fundef (car body-tail))
+ − 207 (push
+ − 208 (cond ((and (consp fundef) (memq (car fundef) defs-to-munge))
+ − 209 (nconc (list (car fundef)
+ − 210 (intern (concat prefix "-"
+ − 211 (symbol-name (second fundef))))
+ − 212 (third fundef))
+ − 213 (nthcdr 3 fundef)))
+ − 214 (t fundef))
+ − 215 result)
+ − 216 (setq body-tail (cdr body-tail)))
+ − 217 (setq result (nreverse result))
+ − 218 ;; now, generate the munged code, with the references to the functions
+ − 219 ;; macroletted
+ − 220 (mapc
+ − 221 #'(lambda (acons)
+ − 222 (let ((fun (car acons))
+ − 223 (args (cdr acons)))
+ − 224 (push
+ − 225 (list fun args
+ − 226 (nconc
+ − 227 (list 'list
+ − 228 (list 'quote
+ − 229 (intern (concat prefix "-"
+ − 230 (symbol-name fun)))))
+ − 231 args))
+ − 232 defs)))
+ − 233 mappings)
+ − 234 ;; it would be cleaner to use `lexical-let' instead of `let', but that
+ − 235 ;; causes function definitions to have obnoxious, unreadable junk in
+ − 236 ;; them. #### Move `lexical-let' into C!!!
+ − 237 `(macrolet ((compat-current-package () ,compat-current-package)
+ − 238 ,@defs)
+ − 239 ,@result))))
+ − 240
+ − 241 (compat-define-compat-functions
410
+ − 242
+ − 243 (defun compat-hash-table (group)
+ − 244 (get group 'compat-table))
+ − 245
+ − 246 (defun compat-make-hash-table (group)
+ − 247 (put group 'compat-table (make-hash-table)))
+ − 248
826
+ − 249 (defmacro compat-define-group (group &rest body)
410
+ − 250 "Define GROUP as a group of compatibility functions.
826
+ − 251 This macro should wrap individual Individual functions are defined using `compat-define-functions'.
410
+ − 252 Once defined, the functions can be used by wrapping your code in the
+ − 253 `compat' macro.
+ − 254
+ − 255 If GROUP is already defined, nothing happens."
+ − 256 (let ((group (eval group)))
+ − 257 (or (hash-table-p (compat-hash-table group))
+ − 258 (compat-make-hash-table group))))
+ − 259
+ − 260 (defmacro compat-clear-functions (group)
+ − 261 "Clear all defined functions and macros out of GROUP."
+ − 262 (let ((group (eval group)))
+ − 263 (clrhash (compat-hash-table group))))
+ − 264
826
+ − 265 (defmacro compat-defun (args &rest body)
+ − 266
+ − 267 (defmacro compat-define-function (props name arglist &rest body)
+ − 268 "Define a compatibility function.
+ − 269 PROPS are properties controlling how the function should be defined.
+ − 270 control how the should simply wrap this around the code that defines the functions.
410
+ − 271 Any functions and macros defined at top level using `defun' or `defmacro'
+ − 272 will be noticed and added to GROUP. Other top-level code will be executed
+ − 273 normally. All code and definitions in this group can safely reference any
+ − 274 other functions in this group -- the code is effectively wrapped in a
+ − 275 `compat' call. You can call `compat-define-functions' more than once, if
+ − 276 necessary, for a single group.
+ − 277
+ − 278 What actually happens is that the functions and macros defined here are in
+ − 279 fact defined using names prefixed with GROUP. To use these functions,
+ − 280 wrap any calling code with the `compat' macro, which lexically renames
+ − 281 the function and macro calls appropriately."
826
+ − 282 (let ((group (eval group))
+ − 283 (defs-to-munge '(defun defmacro))
+ − 284 )
410
+ − 285 (let (fundef
+ − 286 (body-tail body))
+ − 287 (while body-tail
+ − 288 (setq fundef (car body-tail))
826
+ − 289 (when (and (consp fundef) (memq (car fundef) defs-to-munge))
410
+ − 290 (puthash (second fundef) (third fundef) (compat-hash-table group)))
+ − 291 (setq body-tail (cdr body-tail))))
+ − 292 (let (fundef
+ − 293 (body-tail body)
+ − 294 result)
+ − 295 (while body-tail
+ − 296 (setq fundef (car body-tail))
+ − 297 (push
826
+ − 298 (cond ((and (consp fundef) (memq (car fundef) defs-to-munge))
+ − 299 (nconc (list (car fundef)
410
+ − 300 (intern (concat (symbol-name group) "-"
+ − 301 (symbol-name (second fundef))))
+ − 302 (third fundef))
+ − 303 (nthcdr 3 fundef)))
+ − 304 (t fundef))
+ − 305 result)
+ − 306 (setq body-tail (cdr body-tail)))
826
+ − 307 (nconc (list 'compat-wrap (list 'quote group)) (nreverse result)))))
410
+ − 308
+ − 309 (defvar compat-active-groups nil)
+ − 310
+ − 311 (defun compat-fboundp (groups fun)
+ − 312 "T if FUN is either `fboundp' or one of the compatibility funs in GROUPS.
+ − 313 GROUPS is a list of compatibility groups as defined using
+ − 314 `compat-define-group'."
+ − 315 (or (fboundp fun)
+ − 316 (block nil
+ − 317 (mapcar #'(lambda (group)
+ − 318 (if (gethash fun (compat-hash-table group))
+ − 319 (return t)))
+ − 320 groups))))
+ − 321
826
+ − 322 (defmacro compat-wrap-runtime (groups &rest body))
+ − 323
+ − 324 (defmacro compat-wrap (groups &rest body)
+ − 325 "Make use of compatibility functions and macros in GROUPS.
+ − 326 GROUPS is a symbol, an API group, or list of API groups. Each API group
+ − 327 defines a set of functions, macros, variables, etc. and that will (or
+ − 328 should ideally) work on all recent versions of both GNU Emacs and XEmacs,
+ − 329 and (to some extent, depending on how the functions were designed) on older
+ − 330 version. When this function is used, it will generally not be named
+ − 331 `compat-wrap', but have some name such as `Gnus-compat-wrap', if this is
+ − 332 wrapping something in `gnus'. (The renaming happened when the `compat'
+ − 333 package was loaded -- see discussion at top).
+ − 334
+ − 335 To use `compat' in your package (assume your package is `gnus'), you first
+ − 336 have to do a bit if setup.
+ − 337
+ − 338 -- Copy and rename compat.el, e.g. to `gnus-compat.el'. The name must be
+ − 339 globally unique across everything on the load path (that means all
+ − 340 packages).
+ − 341 -- Incude this file in your package. It will not interfere with any other
+ − 342 versions of compat (earlier, later, etc.) provided in other packages
+ − 343 and similarly renamed.
+ − 344
+ − 345 To make use of the API's provided:
+ − 346
+ − 347 -- First place code like this at the top of the file, after the copyright
+ − 348 notices and comments:
+ − 349
+ − 350 \(let ((compat-current-package 'Gnus))
+ − 351 (require 'gnus-compat))
+ − 352
+ − 353 -- then wrap the rest of the code like this, assuming you want access to
+ − 354 the GNU Emacs overlays API, and the XEmacs events API:
+ − 355
+ − 356 \(Gnus-compat-wrap '(overlays xem-events)
+ − 357
+ − 358 ...
+ − 359 ...
+ − 360 ...
+ − 361
+ − 362 \(defun gnus-random-fun (overlay baz)
+ − 363 ...
+ − 364 (overlay-put overlay 'face 'bold)
+ − 365 ...
+ − 366 )
+ − 367
+ − 368 ...
+ − 369 ...
+ − 370
+ − 371 \(defun gnus-random-fun-2 (event)
+ − 372 (interactive "e")
+ − 373 (let ((x (event-x event))
+ − 374 (y (event-y event)))
+ − 375 ...
+ − 376 )
+ − 377 )
+ − 378
+ − 379 ) ;; end of (Gnus-compat)
+ − 380
+ − 381 ;;;; random-module.el ends here
+ − 382
+ − 383 Both the requested API's will be implemented whichever version of Emacs
+ − 384 \(GNU Emacs, XEmacs, etc.) is running, and (with limitations) on older
+ − 385 versions as well. Furthermore, the API's are provided *ONLY* to code
+ − 386 that's actually, lexically wrapped by `compat-wrap' (or its renamed
+ − 387 version). All other code, including code that's called by the wrapped
+ − 388 code, is not affected -- e.g. if we're on XEmacs, and `overlay-put' isn't
+ − 389 normally defined, then it won't be defined in code other than the wrapped
+ − 390 code, even if the wrapped code calls that code. Clever, huh?
+ − 391
+ − 392 What happens is that the `compat-wrap' actually uses `macrolet' to
+ − 393 inline-substitute calls to `overlay-put' to (in this case)
+ − 394 `Gnus-compat-overlay-put', which was defined when `gnus-compat' was loaded.
+ − 395
+ − 396 What happens is that is implement the requested API's (in this case, the
+ − 397 overlay API from GNU Emacs and event API from XEmacs) in whichever
+ − 398 version of Emacs is running, with names such as
+ − 399 `Gnus-compat-overlay-put', and then it uses `macrolet' to map the
+ − 400 generic names in the wrapped code into namespace-clean names. The
+ − 401 result of loading `gnus-compat' leaves around only functions beginning
+ − 402 with `Gnus-compat' (or whatever prefix was specified in
+ − 403 `compat-current-package'). This way, various packages, with various
+ − 404 versions of `compat' as part of them, can coexist, with each package
+ − 405 running the version of `compat' that it's been tested with. The use of
+ − 406 `macrolet' ensures that only code that's lexically wrapped -- not code
+ − 407 that's called from that code -- is affected by the API mapping.
+ − 408
+ − 409 Before using `compat'
+ − 410
+ − 411 For any file where you want to make use of one or more API's provided by
+ − 412 `compat', first do this:
+ − 413
+ − 414 Wrap a call to `compat-wrap' around your entire file, like this:
+ − 415
+ − 416 ;; First, you copied compat.el into your package -- we're assuming \"gnus\" --
+ − 417 ;; and renamed it, e.g. gnus-compat.el. Now we load it and tell it to
+ − 418 ;; use `Gnus' as the prefix for all stuff it defines. (Use a capital letter
+ − 419 ;; or some similar convention so that these names are not so easy to see.)
+ − 420
+ − 421 \(let ((current-compat-package 'Gnus))
+ − 422 (require 'gnus-compat))
+ − 423
+ − 424 ;; The function `compat-wrap' was mapped to `Gnus-compat-wrap'. The idea
+ − 425 ;; is that the raw functions beginning with `compat-' are never actually
+ − 426 ;; defined. They may appear as function calls inside of functions, but
+ − 427 ;; they will always be mapped to something beginning with the given prefix.
+ − 428
+ − 429 \(Gnus-compat-wrap '(overlays xem-events)
+ − 430
+ − 431 ...
+ − 432
+ − 433 )
+ − 434
410
+ − 435 You should simply wrap this around the code that uses the functions
826
+ − 436 and macros in GROUPS. Typically, a call to `compat' should be placed
410
+ − 437 at the top of an ELisp module, with the closing parenthesis at the
+ − 438 bottom; use this in place of a `require' statement. Wrapped code can
+ − 439 be either function or macro definitions or other ELisp code, and
+ − 440 wrapped function or macro definitions need not be at top level. All
+ − 441 calls to the compatibility functions or macros will be noticed anywhere
+ − 442 within the wrapped code. Calls to `fboundp' within the wrapped code
+ − 443 will also behave correctly when called on compatibility functions and
+ − 444 macros, even though they would return nil elsewhere (including in code
+ − 445 in other modules called dynamically from the wrapped code).
+ − 446
+ − 447 The functions and macros define in GROUP are actually defined under
+ − 448 prefixed names, to avoid namespace clashes and bad interactions with
+ − 449 other code that calls `fboundp'. All calls inside of the wrapped code
+ − 450 to the compatibility functions and macros in GROUP are lexically
+ − 451 mapped to the prefixed names. Since this is a lexical mapping, code
+ − 452 in other modules that is called by functions in this module will not
+ − 453 be affected."
+ − 454 (let ((group (eval group))
+ − 455 defs)
+ − 456 (maphash
+ − 457 #'(lambda (fun args)
+ − 458 (push
+ − 459 (list fun args
+ − 460 (nconc
+ − 461 (list 'list
+ − 462 (list 'quote
+ − 463 (intern (concat (symbol-name group) "-"
+ − 464 (symbol-name fun)))))
+ − 465 args))
+ − 466 defs))
+ − 467 (compat-hash-table group))
+ − 468 ;; it would be cleaner to use `lexical-let' instead of `let', but that
+ − 469 ;; causes function definitions to have obnoxious, unreadable junk in
+ − 470 ;; them. #### Move `lexical-let' into C!!!
+ − 471 `(let ((compat-active-groups (cons ',group compat-active-groups)))
+ − 472 (macrolet ((fboundp (fun) `(compat-fboundp ',compat-active-groups ,fun))
+ − 473 ,@defs)
+ − 474 ,@body))))
826
+ − 475
+ − 476 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ − 477 ;; Define the compat groups ;;
+ − 478 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ − 479
+ − 480 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; overlays ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ − 481
+ − 482 (compat-define-group 'overlays
+ − 483
+ − 484 (defun-compat overlayp (object)
+ − 485 "Return t if OBJECT is an overlay."
+ − 486 (and (extentp object)
+ − 487 (extent-property object 'overlay)))
+ − 488
+ − 489 (defun-compat make-overlay (beg end &optional buffer front-advance rear-advance)
+ − 490 "Create a new overlay with range BEG to END in BUFFER.
+ − 491 If omitted, BUFFER defaults to the current buffer.
+ − 492 BEG and END may be integers or markers.
+ − 493 The fourth arg FRONT-ADVANCE, if non-nil, makes the
+ − 494 front delimiter advance when text is inserted there.
+ − 495 The fifth arg REAR-ADVANCE, if non-nil, makes the
+ − 496 rear delimiter advance when text is inserted there."
+ − 497 (if (null buffer)
+ − 498 (setq buffer (current-buffer))
+ − 499 (check-argument-type 'bufferp buffer))
+ − 500 (when (> beg end)
+ − 501 (setq beg (prog1 end (setq end beg))))
+ − 502
+ − 503 (let ((overlay (make-extent beg end buffer)))
+ − 504 (set-extent-property overlay 'overlay t)
+ − 505 (if front-advance
+ − 506 (set-extent-property overlay 'start-open t)
+ − 507 (set-extent-property overlay 'start-closed t))
+ − 508 (if rear-advance
+ − 509 (set-extent-property overlay 'end-closed t)
+ − 510 (set-extent-property overlay 'end-open t))
+ − 511
+ − 512 overlay))
+ − 513
+ − 514 (defun-compat move-overlay (overlay beg end &optional buffer)
+ − 515 "Set the endpoints of OVERLAY to BEG and END in BUFFER.
+ − 516 If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now.
+ − 517 If BUFFER is omitted, and OVERLAY is in no buffer, put it in the current
+ − 518 buffer."
+ − 519 (check-argument-type 'overlayp overlay)
+ − 520 (if (null buffer)
+ − 521 (setq buffer (extent-object overlay)))
+ − 522 (if (null buffer)
+ − 523 (setq buffer (current-buffer)))
+ − 524 (check-argument-type 'bufferp buffer)
+ − 525 (and (= beg end)
+ − 526 (extent-property overlay 'evaporate)
+ − 527 (delete-overlay overlay))
+ − 528 (when (> beg end)
+ − 529 (setq beg (prog1 end (setq end beg))))
+ − 530 (set-extent-endpoints overlay beg end buffer)
+ − 531 overlay)
+ − 532
+ − 533 (defun-compat delete-overlay (overlay)
+ − 534 "Delete the overlay OVERLAY from its buffer."
+ − 535 (check-argument-type 'overlayp overlay)
+ − 536 (detach-extent overlay)
+ − 537 nil)
+ − 538
+ − 539 (defun-compat overlay-start (overlay)
+ − 540 "Return the position at which OVERLAY starts."
+ − 541 (check-argument-type 'overlayp overlay)
+ − 542 (extent-start-position overlay))
+ − 543
+ − 544 (defun-compat overlay-end (overlay)
+ − 545 "Return the position at which OVERLAY ends."
+ − 546 (check-argument-type 'overlayp overlay)
+ − 547 (extent-end-position overlay))
+ − 548
+ − 549 (defun-compat overlay-buffer (overlay)
+ − 550 "Return the buffer OVERLAY belongs to."
+ − 551 (check-argument-type 'overlayp overlay)
+ − 552 (extent-object overlay))
+ − 553
+ − 554 (defun-compat overlay-properties (overlay)
+ − 555 "Return a list of the properties on OVERLAY.
+ − 556 This is a copy of OVERLAY's plist; modifying its conses has no effect on
+ − 557 OVERLAY."
+ − 558 (check-argument-type 'overlayp overlay)
+ − 559 (extent-properties overlay))
+ − 560
+ − 561 (defun-compat overlays-at (pos)
+ − 562 "Return a list of the overlays that contain position POS."
+ − 563 (overlays-in pos pos))
+ − 564
+ − 565 (defun-compat overlays-in (beg end)
+ − 566 "Return a list of the overlays that overlap the region BEG ... END.
+ − 567 Overlap means that at least one character is contained within the overlay
+ − 568 and also contained within the specified region.
+ − 569 Empty overlays are included in the result if they are located at BEG
+ − 570 or between BEG and END."
+ − 571 (if (featurep 'xemacs)
+ − 572 (mapcar-extents #'identity nil nil beg end
+ − 573 'all-extents-closed-open 'overlay)
+ − 574 (let ((ovls (overlay-lists))
+ − 575 tmp retval)
+ − 576 (if (< end beg)
+ − 577 (setq tmp end
+ − 578 end beg
+ − 579 beg tmp))
+ − 580 (setq ovls (nconc (car ovls) (cdr ovls)))
+ − 581 (while ovls
+ − 582 (setq tmp (car ovls)
+ − 583 ovls (cdr ovls))
+ − 584 (if (or (and (<= (overlay-start tmp) end)
+ − 585 (>= (overlay-start tmp) beg))
+ − 586 (and (<= (overlay-end tmp) end)
+ − 587 (>= (overlay-end tmp) beg)))
+ − 588 (setq retval (cons tmp retval))))
+ − 589 retval)))
+ − 590
+ − 591 (defun-compat next-overlay-change (pos)
+ − 592 "Return the next position after POS where an overlay starts or ends.
+ − 593 If there are no more overlay boundaries after POS, return (point-max)."
+ − 594 (let ((next (point-max))
+ − 595 tmp)
+ − 596 (map-extents
+ − 597 (lambda (overlay ignore)
+ − 598 (when (or (and (< (setq tmp (extent-start-position overlay)) next)
+ − 599 (> tmp pos))
+ − 600 (and (< (setq tmp (extent-end-position overlay)) next)
+ − 601 (> tmp pos)))
+ − 602 (setq next tmp))
+ − 603 nil)
+ − 604 nil pos nil nil 'all-extents-closed-open 'overlay)
+ − 605 next))
+ − 606
+ − 607 (defun-compat previous-overlay-change (pos)
+ − 608 "Return the previous position before POS where an overlay starts or ends.
+ − 609 If there are no more overlay boundaries before POS, return (point-min)."
+ − 610 (let ((prev (point-min))
+ − 611 tmp)
+ − 612 (map-extents
+ − 613 (lambda (overlay ignore)
+ − 614 (when (or (and (> (setq tmp (extent-end-position overlay)) prev)
+ − 615 (< tmp pos))
+ − 616 (and (> (setq tmp (extent-start-position overlay)) prev)
+ − 617 (< tmp pos)))
+ − 618 (setq prev tmp))
+ − 619 nil)
+ − 620 nil nil pos nil 'all-extents-closed-open 'overlay)
+ − 621 prev))
+ − 622
+ − 623 (defun-compat overlay-lists ()
+ − 624 "Return a pair of lists giving all the overlays of the current buffer.
+ − 625 The car has all the overlays before the overlay center;
+ − 626 the cdr has all the overlays after the overlay center.
+ − 627 Recentering overlays moves overlays between these lists.
+ − 628 The lists you get are copies, so that changing them has no effect.
+ − 629 However, the overlays you get are the real objects that the buffer uses."
+ − 630 (or (boundp 'xemacs-internal-overlay-center-pos)
+ − 631 (overlay-recenter (1+ (/ (- (point-max) (point-min)) 2))))
+ − 632 (let ((pos xemacs-internal-overlay-center-pos)
+ − 633 before after)
+ − 634 (map-extents (lambda (overlay ignore)
+ − 635 (if (> pos (extent-end-position overlay))
+ − 636 (push overlay before)
+ − 637 (push overlay after))
+ − 638 nil)
+ − 639 nil nil nil nil 'all-extents-closed-open 'overlay)
+ − 640 (cons (nreverse before) (nreverse after))))
+ − 641
+ − 642 (defun-compat overlay-recenter (pos)
+ − 643 "Recenter the overlays of the current buffer around position POS."
+ − 644 (set (make-local-variable 'xemacs-internal-overlay-center-pos) pos))
+ − 645
+ − 646 (defun-compat overlay-get (overlay prop)
+ − 647 "Get the property of overlay OVERLAY with property name PROP."
+ − 648 (check-argument-type 'overlayp overlay)
+ − 649 (let ((value (extent-property overlay prop))
+ − 650 category)
+ − 651 (if (and (null value)
+ − 652 (setq category (extent-property overlay 'category)))
+ − 653 (get category prop)
+ − 654 value)))
+ − 655
+ − 656 (defun-compat overlay-put (overlay prop value)
+ − 657 "Set one property of overlay OVERLAY: give property PROP value VALUE."
+ − 658 (check-argument-type 'overlayp overlay)
+ − 659 (cond ((eq prop 'evaporate)
+ − 660 (set-extent-property overlay 'detachable value))
+ − 661 ((eq prop 'before-string)
+ − 662 (set-extent-property overlay 'begin-glyph
+ − 663 (make-glyph (vector 'string :data value))))
+ − 664 ((eq prop 'after-string)
+ − 665 (set-extent-property overlay 'end-glyph
+ − 666 (make-glyph (vector 'string :data value))))
+ − 667 ((eq prop 'local-map)
+ − 668 (set-extent-property overlay 'keymap value))
+ − 669 ((memq prop '(window insert-in-front-hooks insert-behind-hooks
+ − 670 modification-hooks))
+ − 671 (error "cannot support overlay '%s property under XEmacs"
+ − 672 prop)))
+ − 673 (set-extent-property overlay prop value))
+ − 674 )
+ − 675
+ − 676 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; extents ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ − 677
+ − 678 (defalias-compat 'delete-extent 'delete-overlay)
+ − 679 (defalias-compat 'extent-end-position 'overlay-end)
+ − 680 (defalias-compat 'extent-start-position 'overlay-start)
+ − 681 (defalias-compat 'set-extent-endpoints 'move-overlay)
+ − 682 (defalias-compat 'set-extent-property 'overlay-put)
+ − 683 (defalias-compat 'make-extent 'make-overlay)
+ − 684
+ − 685 (defun-compat extent-property (extent property &optional default)
+ − 686 (or (overlay-get extent property) default))
+ − 687
+ − 688 (defun-compat extent-at (pos &optional object property before at-flag)
+ − 689 (let ((tmp (overlays-at (point)))
+ − 690 ovls)
+ − 691 (if property
+ − 692 (while tmp
+ − 693 (if (extent-property (car tmp) property)
+ − 694 (setq ovls (cons (car tmp) ovls)))
+ − 695 (setq tmp (cdr tmp)))
+ − 696 (setq ovls tmp
+ − 697 tmp nil))
+ − 698 (car-safe
+ − 699 (sort ovls
+ − 700 (function
+ − 701 (lambda (a b)
+ − 702 (< (- (extent-end-position a) (extent-start-position a))
+ − 703 (- (extent-end-position b) (extent-start-position b)))))))))
+ − 704
+ − 705 (defun-compat map-extents (function &optional object from to
+ − 706 maparg flags property value)
+ − 707 (let ((tmp (overlays-in (or from (point-min))
+ − 708 (or to (point-max))))
+ − 709 ovls)
+ − 710 (if property
+ − 711 (while tmp
+ − 712 (if (extent-property (car tmp) property)
+ − 713 (setq ovls (cons (car tmp) ovls)))
+ − 714 (setq tmp (cdr tmp)))
+ − 715 (setq ovls tmp
+ − 716 tmp nil))
+ − 717 (catch 'done
+ − 718 (while ovls
+ − 719 (setq tmp (funcall function (car ovls) maparg)
+ − 720 ovls (cdr ovls))
+ − 721 (if tmp
+ − 722 (throw 'done tmp))))))
+ − 723
+ − 724 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; extents ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ − 725
+ − 726
+ − 727 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; events ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ − 728
+ − 729 ) ;; group overlays
+ − 730
+ − 731 ) ;; compat-define-compat-functions
+ − 732
+ − 733 (fmakunbound 'compat-define-compat-functions)
+ − 734
+ − 735 )