X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/171eda5358a6c63b4854688a300b0fe22d3fcb38..9a0115abd18f219f234d6dd460cf7f5ed3c0332f:/lisp/org/org-compat.el diff --git a/lisp/org/org-compat.el b/lisp/org/org-compat.el index 80a45d61f2..425e8d816c 100644 --- a/lisp/org/org-compat.el +++ b/lisp/org/org-compat.el @@ -1,12 +1,10 @@ ;;; org-compat.el --- Compatibility code for Org-mode -;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 -;; Free Software Foundation, Inc. +;; Copyright (C) 2004-2012 Free Software Foundation, Inc. ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 6.35i ;; ;; This file is part of GNU Emacs. ;; @@ -39,7 +37,10 @@ (declare-function find-library-name "find-func" (library)) (declare-function w32-focus-frame "term/w32-win" (frame)) -(defconst org-xemacs-p (featurep 'xemacs)) ; not used by org.el itself +;; The following constant is for backward compatibility. We do not use +;; it in org-mode, because the Byte compiler evaluates (featurep 'xemacs) +;; at compilation time and can therefore optimize code better. +(defconst org-xemacs-p (featurep 'xemacs)) (defconst org-format-transports-properties-p (let ((x "a")) (add-text-properties 0 1 '(test t) x) @@ -86,25 +87,44 @@ any other entries, and any resulting duplicates will be removed entirely." (t specs))) (put 'org-compatible-face 'lisp-indent-function 1) +(defun org-version-check (version feature level) + (let* ((v1 (mapcar 'string-to-number (split-string version "[.]"))) + (v2 (mapcar 'string-to-number (split-string emacs-version "[.]"))) + (rmaj (or (nth 0 v1) 99)) + (rmin (or (nth 1 v1) 99)) + (rbld (or (nth 2 v1) 99)) + (maj (or (nth 0 v2) 0)) + (min (or (nth 1 v2) 0)) + (bld (or (nth 2 v2) 0))) + (if (or (< maj rmaj) + (and (= maj rmaj) + (< min rmin)) + (and (= maj rmaj) + (= min rmin) + (< bld rbld))) + (if (eq level :predicate) + ;; just return if we have the version + nil + (let ((msg (format "Emacs %s or greater is recommended for %s" + version feature))) + (display-warning 'org msg level) + t)) + t))) + ;;;; Emacs/XEmacs compatibility +;; Keys +(defconst org-xemacs-key-equivalents + '(([mouse-1] . [button1]) + ([mouse-2] . [button2]) + ([mouse-3] . [button3]) + ([C-mouse-4] . [(control mouse-4)]) + ([C-mouse-5] . [(control mouse-5)])) + "Translation alist for a couple of keys.") + ;; Overlay compatibility functions -(defun org-make-overlay (beg end &optional buffer) - (if (featurep 'xemacs) - (make-extent beg end buffer) - (make-overlay beg end buffer))) -(defun org-delete-overlay (ovl) - (if (featurep 'xemacs) (progn (delete-extent ovl) nil) (delete-overlay ovl))) (defun org-detach-overlay (ovl) (if (featurep 'xemacs) (detach-extent ovl) (delete-overlay ovl))) -(defun org-move-overlay (ovl beg end &optional buffer) - (if (featurep 'xemacs) - (set-extent-endpoints ovl beg end (or buffer (current-buffer))) - (move-overlay ovl beg end buffer))) -(defun org-overlay-put (ovl prop value) - (if (featurep 'xemacs) - (set-extent-property ovl prop value) - (overlay-put ovl prop value))) (defun org-overlay-display (ovl text &optional face evap) "Make overlay OVL display TEXT with face FACE." (if (featurep 'xemacs) @@ -124,32 +144,33 @@ any other entries, and any resulting duplicates will be removed entirely." (if face (org-add-props text nil 'face face)) (overlay-put ovl 'before-string text) (if evap (overlay-put ovl 'evaporate t)))) -(defun org-overlay-get (ovl prop) - (if (featurep 'xemacs) - (extent-property ovl prop) - (overlay-get ovl prop))) -(defun org-overlays-at (pos) - (if (featurep 'xemacs) (extents-at pos) (overlays-at pos))) -(defun org-overlays-in (&optional start end) - (if (featurep 'xemacs) - (extent-list nil start end) - (overlays-in start end))) -(defun org-overlay-start (o) - (if (featurep 'xemacs) (extent-start-position o) (overlay-start o))) -(defun org-overlay-end (o) - (if (featurep 'xemacs) (extent-end-position o) (overlay-end o))) -(defun org-overlay-buffer (o) - (if (featurep 'xemacs) (extent-buffer o) (overlay-buffer o))) (defun org-find-overlays (prop &optional pos delete) "Find all overlays specifying PROP at POS or point. If DELETE is non-nil, delete all those overlays." - (let ((overlays (org-overlays-at (or pos (point)))) + (let ((overlays (overlays-at (or pos (point)))) ov found) (while (setq ov (pop overlays)) - (if (org-overlay-get ov prop) - (if delete (org-delete-overlay ov) (push ov found)))) + (if (overlay-get ov prop) + (if delete (delete-overlay ov) (push ov found)))) found)) +(defun org-get-x-clipboard (value) + "Get the value of the x clipboard, compatible with XEmacs, and GNU Emacs 21." + (if (eq window-system 'x) + (let ((x (org-get-x-clipboard-compat value))) + (if x (org-no-properties x))))) + +(defsubst org-decompose-region (beg end) + "Decompose from BEG to END." + (if (featurep 'xemacs) + (let ((modified-p (buffer-modified-p)) + (buffer-read-only nil)) + (remove-text-properties beg end '(composition nil)) + (set-buffer-modified-p modified-p)) + (decompose-region beg end))) + +;; Miscellaneous functions + (defun org-add-hook (hook function &optional append local) "Add-hook, compatible with both Emacsen." (if (and local (featurep 'xemacs)) @@ -170,7 +191,7 @@ that will be added to PLIST. Returns the string that was modified." "Fit WINDOW to the buffer, but only if it is not a side-by-side window. WINDOW defaults to the selected window. MAX-HEIGHT and MIN-HEIGHT are passed through to `fit-window-to-buffer'. If SHRINK-ONLY is set, call -`shrink-window-if-larger-than-buffer' instead, the hight limit are +`shrink-window-if-larger-than-buffer' instead, the height limit is ignored in this case." (cond ((if (fboundp 'window-full-width-p) (not (window-full-width-p window)) @@ -183,6 +204,26 @@ ignored in this case." (shrink-window-if-larger-than-buffer window))) (or window (selected-window))) +(defun org-number-sequence (from &optional to inc) + "Call `number-sequence or emulate it." + (if (fboundp 'number-sequence) + (number-sequence from to inc) + (if (or (not to) (= from to)) + (list from) + (or inc (setq inc 1)) + (when (zerop inc) (error "The increment can not be zero")) + (let (seq (n 0) (next from)) + (if (> inc 0) + (while (<= next to) + (setq seq (cons next seq) + n (1+ n) + next (+ from (* n inc)))) + (while (>= next to) + (setq seq (cons next seq) + n (1+ n) + next (+ from (* n inc))))) + (nreverse seq))))) + ;; Region compatibility (defvar org-ignore-region nil @@ -204,20 +245,20 @@ Works on both Emacs and XEmacs." (> (point) (region-beginning))) (exchange-point-and-mark))) -;; Invisibility compatibility +;; Emacs 22 misses `activate-mark' +(if (fboundp 'activate-mark) + (defalias 'org-activate-mark 'activate-mark) + (defun org-activate-mark () + (when (mark t) + (setq mark-active t) + (when (and (boundp 'transient-mark-mode) + (not transient-mark-mode)) + (setq transient-mark-mode 'lambda)) + (when (boundp 'zmacs-regions) + (setq zmacs-regions t))))) -(defun org-add-to-invisibility-spec (arg) - "Add elements to `buffer-invisibility-spec'. -See documentation for `buffer-invisibility-spec' for the kind of elements -that can be added." - (cond - ((fboundp 'add-to-invisibility-spec) - (add-to-invisibility-spec arg)) - ((or (null buffer-invisibility-spec) (eq buffer-invisibility-spec t)) - (setq buffer-invisibility-spec (list arg))) - (t - (setq buffer-invisibility-spec - (cons arg buffer-invisibility-spec))))) + +;; Invisibility compatibility (defun org-remove-from-invisibility-spec (arg) "Remove elements from `buffer-invisibility-spec'." @@ -233,62 +274,43 @@ that can be added." (member arg buffer-invisibility-spec) nil)) +(defmacro org-xemacs-without-invisibility (&rest body) + "Turn off exents with invisibility while executing BODY." + `(let ((ext-inv (extent-list nil (point-at-bol) (point-at-eol) + 'all-extents-closed-open 'invisible)) + ext-inv-specs) + (dolist (ext ext-inv) + (when (extent-property ext 'invisible) + (add-to-list 'ext-inv-specs (list ext (extent-property + ext 'invisible))) + (set-extent-property ext 'invisible nil))) + ,@body + (dolist (ext-inv-spec ext-inv-specs) + (set-extent-property (car ext-inv-spec) 'invisible + (cadr ext-inv-spec))))) +(def-edebug-spec org-xemacs-without-invisibility (body)) + (defun org-indent-to-column (column &optional minimum buffer) "Work around a bug with extents with invisibility in XEmacs." (if (featurep 'xemacs) - (let ((ext-inv (extent-list - nil (point-at-bol) (point-at-eol) - 'all-extents-closed-open 'invisible)) - ext-inv-specs) - (dolist (ext ext-inv) - (when (extent-property ext 'invisible) - (add-to-list 'ext-inv-specs (list ext (extent-property - ext 'invisible))) - (set-extent-property ext 'invisible nil))) - (indent-to-column column minimum buffer) - (dolist (ext-inv-spec ext-inv-specs) - (set-extent-property (car ext-inv-spec) 'invisible - (cadr ext-inv-spec)))) + (org-xemacs-without-invisibility (indent-to-column column minimum buffer)) (indent-to-column column minimum))) (defun org-indent-line-to (column) "Work around a bug with extents with invisibility in XEmacs." (if (featurep 'xemacs) - (let ((ext-inv (extent-list - nil (point-at-bol) (point-at-eol) - 'all-extents-closed-open 'invisible)) - ext-inv-specs) - (dolist (ext ext-inv) - (when (extent-property ext 'invisible) - (add-to-list 'ext-inv-specs (list ext (extent-property - ext 'invisible))) - (set-extent-property ext 'invisible nil))) - (indent-line-to column) - (dolist (ext-inv-spec ext-inv-specs) - (set-extent-property (car ext-inv-spec) 'invisible - (cadr ext-inv-spec)))) + (org-xemacs-without-invisibility (indent-line-to column)) (indent-line-to column))) (defun org-move-to-column (column &optional force buffer) (if (featurep 'xemacs) - (let ((ext-inv (extent-list - nil (point-at-bol) (point-at-eol) - 'all-extents-closed-open 'invisible)) - ext-inv-specs) - (dolist (ext ext-inv) - (when (extent-property ext 'invisible) - (add-to-list 'ext-inv-specs (list ext (extent-property ext - 'invisible))) - (set-extent-property ext 'invisible nil))) - (move-to-column column force buffer) - (dolist (ext-inv-spec ext-inv-specs) - (set-extent-property (car ext-inv-spec) 'invisible - (cadr ext-inv-spec)))) + (org-xemacs-without-invisibility (move-to-column column force buffer)) (move-to-column column force))) (defun org-get-x-clipboard-compat (value) - "Get the clipboard value on XEmacs or Emacs 21" - (cond (org-xemacs-p (org-no-warnings (get-selection-no-error value))) + "Get the clipboard value on XEmacs or Emacs 21." + (cond ((featurep 'xemacs) + (org-no-warnings (get-selection-no-error value))) ((fboundp 'x-get-selection) (condition-case nil (or (x-get-selection value 'UTF8_STRING) @@ -362,6 +384,18 @@ TIME defaults to the current time." (time-to-seconds (or time (current-time))) (float-time time))) +(if (fboundp 'string-match-p) + (defalias 'org-string-match-p 'string-match-p) + (defun org-string-match-p (regexp string &optional start) + (save-match-data + (funcall 'string-match regexp string start)))) + +(if (fboundp 'looking-at-p) + (defalias 'org-looking-at-p 'looking-at-p) + (defun org-looking-at-p (&rest args) + (save-match-data + (apply 'looking-at args)))) + ; XEmacs does not have `looking-back'. (if (fboundp 'looking-back) (defalias 'org-looking-back 'looking-back) @@ -396,8 +430,21 @@ LIMIT." (looking-at (concat "\\(?:" regexp "\\)\\'"))))) (not (null pos))))) -(provide 'org-compat) +(defun org-floor* (x &optional y) + "Return a list of the floor of X and the fractional part of X. +With two arguments, return floor and remainder of their quotient." + (let ((q (floor x y))) + (list q (- x (if y (* y q) q))))) + +;; `pop-to-buffer-same-window' has been introduced with Emacs 24.1. +(defun org-pop-to-buffer-same-window + (&optional buffer-or-name norecord label) + "Pop to buffer specified by BUFFER-OR-NAME in the selected window." + (if (fboundp 'pop-to-buffer-same-window) + (funcall + 'pop-to-buffer-same-window buffer-or-name norecord) + (funcall 'switch-to-buffer buffer-or-name norecord))) -;; arch-tag: a0a0579f-e68c-4bdf-9e55-93768b846bbe +(provide 'org-compat) ;;; org-compat.el ends here