Commit | Line | Data |
---|---|---|
20908596 CD |
1 | ;;; org-compat.el --- Compatibility code for Org-mode |
2 | ||
ab422c4d | 3 | ;; Copyright (C) 2004-2013 Free Software Foundation, Inc. |
20908596 CD |
4 | |
5 | ;; Author: Carsten Dominik <carsten at orgmode dot org> | |
6 | ;; Keywords: outlines, hypermedia, calendar, wp | |
7 | ;; Homepage: http://orgmode.org | |
20908596 CD |
8 | ;; |
9 | ;; This file is part of GNU Emacs. | |
10 | ;; | |
b1fc2b50 | 11 | ;; GNU Emacs is free software: you can redistribute it and/or modify |
20908596 | 12 | ;; it under the terms of the GNU General Public License as published by |
b1fc2b50 GM |
13 | ;; the Free Software Foundation, either version 3 of the License, or |
14 | ;; (at your option) any later version. | |
20908596 CD |
15 | |
16 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | ;; GNU General Public License for more details. | |
20 | ||
21 | ;; You should have received a copy of the GNU General Public License | |
b1fc2b50 | 22 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
20908596 CD |
23 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
24 | ;; | |
25 | ;;; Commentary: | |
26 | ||
27 | ;; This file contains code needed for compatibility with XEmacs and older | |
28 | ;; versions of GNU Emacs. | |
29 | ||
30 | ;;; Code: | |
31 | ||
c8d0cf5c CD |
32 | (eval-when-compile |
33 | (require 'cl)) | |
34 | ||
621f83e4 CD |
35 | (require 'org-macs) |
36 | ||
9d459fc5 | 37 | (declare-function w32-focus-frame "term/w32-win" (frame)) |
c8d0cf5c | 38 | |
86fbb8ca CD |
39 | ;; The following constant is for backward compatibility. We do not use |
40 | ;; it in org-mode, because the Byte compiler evaluates (featurep 'xemacs) | |
41 | ;; at compilation time and can therefore optimize code better. | |
42 | (defconst org-xemacs-p (featurep 'xemacs)) | |
20908596 CD |
43 | (defconst org-format-transports-properties-p |
44 | (let ((x "a")) | |
45 | (add-text-properties 0 1 '(test t) x) | |
46 | (get-text-property 0 'test (format "%s" x))) | |
47 | "Does format transport text properties?") | |
48 | ||
49 | (defun org-compatible-face (inherits specs) | |
50 | "Make a compatible face specification. | |
51 | If INHERITS is an existing face and if the Emacs version supports it, | |
c8d0cf5c CD |
52 | just inherit the face. If INHERITS is set and the Emacs version does |
53 | not support it, copy the face specification from the inheritance face. | |
54 | If INHERITS is not given and SPECS is, use SPECS to define the face. | |
20908596 CD |
55 | XEmacs and Emacs 21 do not know about the `min-colors' attribute. |
56 | For them we convert a (min-colors 8) entry to a `tty' entry and move it | |
57 | to the top of the list. The `min-colors' attribute will be removed from | |
58 | any other entries, and any resulting duplicates will be removed entirely." | |
c8d0cf5c CD |
59 | (when (and inherits (facep inherits) (not specs)) |
60 | (setq specs (or specs | |
61 | (get inherits 'saved-face) | |
62 | (get inherits 'face-defface-spec)))) | |
20908596 CD |
63 | (cond |
64 | ((and inherits (facep inherits) | |
c8d0cf5c CD |
65 | (not (featurep 'xemacs)) |
66 | (>= emacs-major-version 22) | |
67 | ;; do not inherit outline faces before Emacs 23 | |
68 | (or (>= emacs-major-version 23) | |
69 | (not (string-match "\\`outline-[0-9]+" | |
70 | (symbol-name inherits))))) | |
20908596 CD |
71 | (list (list t :inherit inherits))) |
72 | ((or (featurep 'xemacs) (< emacs-major-version 22)) | |
73 | ;; These do not understand the `min-colors' attribute. | |
74 | (let (r e a) | |
75 | (while (setq e (pop specs)) | |
76 | (cond | |
77 | ((memq (car e) '(t default)) (push e r)) | |
78 | ((setq a (member '(min-colors 8) (car e))) | |
79 | (nconc r (list (cons (cons '(type tty) (delq (car a) (car e))) | |
80 | (cdr e))))) | |
81 | ((setq a (assq 'min-colors (car e))) | |
82 | (setq e (cons (delq a (car e)) (cdr e))) | |
83 | (or (assoc (car e) r) (push e r))) | |
84 | (t (or (assoc (car e) r) (push e r))))) | |
85 | (nreverse r))) | |
86 | (t specs))) | |
87 | (put 'org-compatible-face 'lisp-indent-function 1) | |
88 | ||
86fbb8ca CD |
89 | (defun org-version-check (version feature level) |
90 | (let* ((v1 (mapcar 'string-to-number (split-string version "[.]"))) | |
91 | (v2 (mapcar 'string-to-number (split-string emacs-version "[.]"))) | |
92 | (rmaj (or (nth 0 v1) 99)) | |
93 | (rmin (or (nth 1 v1) 99)) | |
94 | (rbld (or (nth 2 v1) 99)) | |
95 | (maj (or (nth 0 v2) 0)) | |
96 | (min (or (nth 1 v2) 0)) | |
97 | (bld (or (nth 2 v2) 0))) | |
98 | (if (or (< maj rmaj) | |
99 | (and (= maj rmaj) | |
100 | (< min rmin)) | |
101 | (and (= maj rmaj) | |
102 | (= min rmin) | |
103 | (< bld rbld))) | |
104 | (if (eq level :predicate) | |
105 | ;; just return if we have the version | |
106 | nil | |
107 | (let ((msg (format "Emacs %s or greater is recommended for %s" | |
108 | version feature))) | |
109 | (display-warning 'org msg level) | |
110 | t)) | |
111 | t))) | |
112 | ||
8223b1d2 | 113 | \f |
20908596 CD |
114 | ;;;; Emacs/XEmacs compatibility |
115 | ||
86fbb8ca CD |
116 | ;; Keys |
117 | (defconst org-xemacs-key-equivalents | |
118 | '(([mouse-1] . [button1]) | |
119 | ([mouse-2] . [button2]) | |
120 | ([mouse-3] . [button3]) | |
121 | ([C-mouse-4] . [(control mouse-4)]) | |
122 | ([C-mouse-5] . [(control mouse-5)])) | |
123 | "Translation alist for a couple of keys.") | |
124 | ||
20908596 | 125 | ;; Overlay compatibility functions |
20908596 CD |
126 | (defun org-detach-overlay (ovl) |
127 | (if (featurep 'xemacs) (detach-extent ovl) (delete-overlay ovl))) | |
20908596 CD |
128 | (defun org-overlay-display (ovl text &optional face evap) |
129 | "Make overlay OVL display TEXT with face FACE." | |
130 | (if (featurep 'xemacs) | |
131 | (let ((gl (make-glyph text))) | |
132 | (and face (set-glyph-face gl face)) | |
133 | (set-extent-property ovl 'invisible t) | |
134 | (set-extent-property ovl 'end-glyph gl)) | |
135 | (overlay-put ovl 'display text) | |
136 | (if face (overlay-put ovl 'face face)) | |
137 | (if evap (overlay-put ovl 'evaporate t)))) | |
138 | (defun org-overlay-before-string (ovl text &optional face evap) | |
139 | "Make overlay OVL display TEXT with face FACE." | |
140 | (if (featurep 'xemacs) | |
141 | (let ((gl (make-glyph text))) | |
142 | (and face (set-glyph-face gl face)) | |
143 | (set-extent-property ovl 'begin-glyph gl)) | |
144 | (if face (org-add-props text nil 'face face)) | |
145 | (overlay-put ovl 'before-string text) | |
146 | (if evap (overlay-put ovl 'evaporate t)))) | |
20908596 CD |
147 | (defun org-find-overlays (prop &optional pos delete) |
148 | "Find all overlays specifying PROP at POS or point. | |
149 | If DELETE is non-nil, delete all those overlays." | |
86fbb8ca | 150 | (let ((overlays (overlays-at (or pos (point)))) |
20908596 CD |
151 | ov found) |
152 | (while (setq ov (pop overlays)) | |
86fbb8ca CD |
153 | (if (overlay-get ov prop) |
154 | (if delete (delete-overlay ov) (push ov found)))) | |
20908596 CD |
155 | found)) |
156 | ||
86fbb8ca CD |
157 | (defun org-get-x-clipboard (value) |
158 | "Get the value of the x clipboard, compatible with XEmacs, and GNU Emacs 21." | |
159 | (if (eq window-system 'x) | |
160 | (let ((x (org-get-x-clipboard-compat value))) | |
161 | (if x (org-no-properties x))))) | |
162 | ||
afe98dfa CD |
163 | (defsubst org-decompose-region (beg end) |
164 | "Decompose from BEG to END." | |
165 | (if (featurep 'xemacs) | |
166 | (let ((modified-p (buffer-modified-p)) | |
167 | (buffer-read-only nil)) | |
168 | (remove-text-properties beg end '(composition nil)) | |
169 | (set-buffer-modified-p modified-p)) | |
170 | (decompose-region beg end))) | |
171 | ||
86fbb8ca CD |
172 | ;; Miscellaneous functions |
173 | ||
20908596 CD |
174 | (defun org-add-hook (hook function &optional append local) |
175 | "Add-hook, compatible with both Emacsen." | |
176 | (if (and local (featurep 'xemacs)) | |
177 | (add-local-hook hook function append) | |
178 | (add-hook hook function append local))) | |
179 | ||
180 | (defun org-add-props (string plist &rest props) | |
181 | "Add text properties to entire string, from beginning to end. | |
182 | PLIST may be a list of properties, PROPS are individual properties and values | |
183 | that will be added to PLIST. Returns the string that was modified." | |
184 | (add-text-properties | |
185 | 0 (length string) (if props (append plist props) plist) string) | |
186 | string) | |
187 | (put 'org-add-props 'lisp-indent-function 2) | |
188 | ||
93b62de8 CD |
189 | (defun org-fit-window-to-buffer (&optional window max-height min-height |
190 | shrink-only) | |
191 | "Fit WINDOW to the buffer, but only if it is not a side-by-side window. | |
192 | WINDOW defaults to the selected window. MAX-HEIGHT and MIN-HEIGHT are | |
193 | passed through to `fit-window-to-buffer'. If SHRINK-ONLY is set, call | |
86fbb8ca | 194 | `shrink-window-if-larger-than-buffer' instead, the height limit is |
93b62de8 | 195 | ignored in this case." |
0bd48b37 CD |
196 | (cond ((if (fboundp 'window-full-width-p) |
197 | (not (window-full-width-p window)) | |
c7cf0ebc BG |
198 | ;; do nothing if another window would suffer |
199 | (> (frame-width) (window-width window)))) | |
93b62de8 CD |
200 | ((and (fboundp 'fit-window-to-buffer) (not shrink-only)) |
201 | (fit-window-to-buffer window max-height min-height)) | |
202 | ((fboundp 'shrink-window-if-larger-than-buffer) | |
203 | (shrink-window-if-larger-than-buffer window))) | |
204 | (or window (selected-window))) | |
205 | ||
afe98dfa CD |
206 | (defun org-number-sequence (from &optional to inc) |
207 | "Call `number-sequence or emulate it." | |
208 | (if (fboundp 'number-sequence) | |
209 | (number-sequence from to inc) | |
210 | (if (or (not to) (= from to)) | |
211 | (list from) | |
212 | (or inc (setq inc 1)) | |
213 | (when (zerop inc) (error "The increment can not be zero")) | |
214 | (let (seq (n 0) (next from)) | |
215 | (if (> inc 0) | |
216 | (while (<= next to) | |
217 | (setq seq (cons next seq) | |
218 | n (1+ n) | |
219 | next (+ from (* n inc)))) | |
220 | (while (>= next to) | |
221 | (setq seq (cons next seq) | |
222 | n (1+ n) | |
223 | next (+ from (* n inc))))) | |
224 | (nreverse seq))))) | |
225 | ||
20908596 CD |
226 | ;; Region compatibility |
227 | ||
228 | (defvar org-ignore-region nil | |
229 | "To temporarily disable the active region.") | |
230 | ||
231 | (defun org-region-active-p () | |
232 | "Is `transient-mark-mode' on and the region active? | |
233 | Works on both Emacs and XEmacs." | |
234 | (if org-ignore-region | |
235 | nil | |
236 | (if (featurep 'xemacs) | |
237 | (and zmacs-regions (region-active-p)) | |
238 | (if (fboundp 'use-region-p) | |
239 | (use-region-p) | |
240 | (and transient-mark-mode mark-active))))) ; Emacs 22 and before | |
241 | ||
c8d0cf5c CD |
242 | (defun org-cursor-to-region-beginning () |
243 | (when (and (org-region-active-p) | |
244 | (> (point) (region-beginning))) | |
245 | (exchange-point-and-mark))) | |
246 | ||
3ab2c837 BG |
247 | ;; Emacs 22 misses `activate-mark' |
248 | (if (fboundp 'activate-mark) | |
249 | (defalias 'org-activate-mark 'activate-mark) | |
250 | (defun org-activate-mark () | |
251 | (when (mark t) | |
252 | (setq mark-active t) | |
e66ba1df BG |
253 | (when (and (boundp 'transient-mark-mode) |
254 | (not transient-mark-mode)) | |
255 | (setq transient-mark-mode 'lambda)) | |
256 | (when (boundp 'zmacs-regions) | |
257 | (setq zmacs-regions t))))) | |
258 | ||
20908596 CD |
259 | ;; Invisibility compatibility |
260 | ||
20908596 CD |
261 | (defun org-remove-from-invisibility-spec (arg) |
262 | "Remove elements from `buffer-invisibility-spec'." | |
263 | (if (fboundp 'remove-from-invisibility-spec) | |
264 | (remove-from-invisibility-spec arg) | |
265 | (if (consp buffer-invisibility-spec) | |
266 | (setq buffer-invisibility-spec | |
267 | (delete arg buffer-invisibility-spec))))) | |
268 | ||
269 | (defun org-in-invisibility-spec-p (arg) | |
270 | "Is ARG a member of `buffer-invisibility-spec'?" | |
271 | (if (consp buffer-invisibility-spec) | |
272 | (member arg buffer-invisibility-spec) | |
273 | nil)) | |
274 | ||
86fbb8ca | 275 | (defmacro org-xemacs-without-invisibility (&rest body) |
27e428e7 | 276 | "Turn off extents with invisibility while executing BODY." |
86fbb8ca CD |
277 | `(let ((ext-inv (extent-list nil (point-at-bol) (point-at-eol) |
278 | 'all-extents-closed-open 'invisible)) | |
279 | ext-inv-specs) | |
280 | (dolist (ext ext-inv) | |
281 | (when (extent-property ext 'invisible) | |
282 | (add-to-list 'ext-inv-specs (list ext (extent-property | |
283 | ext 'invisible))) | |
284 | (set-extent-property ext 'invisible nil))) | |
285 | ,@body | |
286 | (dolist (ext-inv-spec ext-inv-specs) | |
287 | (set-extent-property (car ext-inv-spec) 'invisible | |
288 | (cadr ext-inv-spec))))) | |
e66ba1df | 289 | (def-edebug-spec org-xemacs-without-invisibility (body)) |
86fbb8ca | 290 | |
20908596 CD |
291 | (defun org-indent-to-column (column &optional minimum buffer) |
292 | "Work around a bug with extents with invisibility in XEmacs." | |
71d35b24 | 293 | (if (featurep 'xemacs) |
86fbb8ca | 294 | (org-xemacs-without-invisibility (indent-to-column column minimum buffer)) |
71d35b24 | 295 | (indent-to-column column minimum))) |
20908596 CD |
296 | |
297 | (defun org-indent-line-to (column) | |
298 | "Work around a bug with extents with invisibility in XEmacs." | |
71d35b24 | 299 | (if (featurep 'xemacs) |
86fbb8ca | 300 | (org-xemacs-without-invisibility (indent-line-to column)) |
71d35b24 | 301 | (indent-line-to column))) |
20908596 CD |
302 | |
303 | (defun org-move-to-column (column &optional force buffer) | |
71d35b24 | 304 | (if (featurep 'xemacs) |
86fbb8ca | 305 | (org-xemacs-without-invisibility (move-to-column column force buffer)) |
71d35b24 | 306 | (move-to-column column force))) |
621f83e4 CD |
307 | |
308 | (defun org-get-x-clipboard-compat (value) | |
86fbb8ca CD |
309 | "Get the clipboard value on XEmacs or Emacs 21." |
310 | (cond ((featurep 'xemacs) | |
311 | (org-no-warnings (get-selection-no-error value))) | |
621f83e4 CD |
312 | ((fboundp 'x-get-selection) |
313 | (condition-case nil | |
314 | (or (x-get-selection value 'UTF8_STRING) | |
315 | (x-get-selection value 'COMPOUND_TEXT) | |
316 | (x-get-selection value 'STRING) | |
317 | (x-get-selection value 'TEXT)) | |
318 | (error nil))))) | |
319 | ||
320 | (defun org-propertize (string &rest properties) | |
321 | (if (featurep 'xemacs) | |
ce4fdcb9 CD |
322 | (progn |
323 | (add-text-properties 0 (length string) properties string) | |
324 | string) | |
621f83e4 | 325 | (apply 'propertize string properties))) |
71d35b24 | 326 | |
8223b1d2 | 327 | (defmacro org-find-library-dir (library) |
bdebdb64 | 328 | `(file-name-directory (or (locate-library ,library) ""))) |
c8d0cf5c | 329 | |
0bd48b37 CD |
330 | (defun org-count-lines (s) |
331 | "How many lines in string S?" | |
332 | (let ((start 0) (n 1)) | |
333 | (while (string-match "\n" s start) | |
334 | (setq start (match-end 0) n (1+ n))) | |
335 | (if (and (> (length s) 0) (= (aref s (1- (length s))) ?\n)) | |
336 | (setq n (1- n))) | |
337 | n)) | |
338 | ||
c8d0cf5c CD |
339 | (defun org-kill-new (string &rest args) |
340 | (remove-text-properties 0 (length string) '(line-prefix t wrap-prefix t) | |
341 | string) | |
342 | (apply 'kill-new string args)) | |
343 | ||
54a0dee5 CD |
344 | (defun org-select-frame-set-input-focus (frame) |
345 | "Select FRAME, raise it, and set input focus, if possible." | |
346 | (cond ((featurep 'xemacs) | |
347 | (if (fboundp 'select-frame-set-input-focus) | |
348 | (select-frame-set-input-focus frame) | |
349 | (raise-frame frame) | |
350 | (select-frame frame) | |
351 | (focus-frame frame))) | |
352 | ;; `select-frame-set-input-focus' defined in Emacs 21 will not | |
353 | ;; set the input focus. | |
354 | ((>= emacs-major-version 22) | |
355 | (select-frame-set-input-focus frame)) | |
356 | (t | |
357 | (raise-frame frame) | |
358 | (select-frame frame) | |
359 | (cond ((memq window-system '(x ns mac)) | |
360 | (x-focus-frame frame)) | |
361 | ((eq window-system 'w32) | |
362 | (w32-focus-frame frame))) | |
363 | (when focus-follows-mouse | |
364 | (set-mouse-position frame (1- (frame-width frame)) 0))))) | |
365 | ||
366 | (defun org-float-time (&optional time) | |
367 | "Convert time value TIME to a floating point number. | |
368 | TIME defaults to the current time." | |
369 | (if (featurep 'xemacs) | |
370 | (time-to-seconds (or time (current-time))) | |
371 | (float-time time))) | |
372 | ||
c7cf0ebc BG |
373 | ;; `user-error' is only available from 24.2.50 on |
374 | (unless (fboundp 'user-error) | |
375 | (defalias 'user-error 'error)) | |
376 | ||
377 | (defmacro org-no-popups (&rest body) | |
378 | "Suppress popup windows. | |
379 | Let-bind some variables to nil around BODY to achieve the desired | |
380 | effect, which variables to use depends on the Emacs version." | |
381 | (if (org-version-check "24.2.50" "" :predicate) | |
382 | `(let (pop-up-frames display-buffer-alist) | |
383 | ,@body) | |
384 | `(let (pop-up-frames special-display-buffer-names special-display-regexps special-display-function) | |
385 | ,@body))) | |
386 | ||
acedf35c CD |
387 | (if (fboundp 'string-match-p) |
388 | (defalias 'org-string-match-p 'string-match-p) | |
389 | (defun org-string-match-p (regexp string &optional start) | |
86fbb8ca | 390 | (save-match-data |
acedf35c | 391 | (funcall 'string-match regexp string start)))) |
86fbb8ca | 392 | |
acedf35c CD |
393 | (if (fboundp 'looking-at-p) |
394 | (defalias 'org-looking-at-p 'looking-at-p) | |
395 | (defun org-looking-at-p (&rest args) | |
86fbb8ca | 396 | (save-match-data |
afe98dfa | 397 | (apply 'looking-at args)))) |
86fbb8ca | 398 | |
c7cf0ebc | 399 | ;; XEmacs does not have `looking-back'. |
ed21c5c8 CD |
400 | (if (fboundp 'looking-back) |
401 | (defalias 'org-looking-back 'looking-back) | |
402 | (defun org-looking-back (regexp &optional limit greedy) | |
403 | "Return non-nil if text before point matches regular expression REGEXP. | |
404 | Like `looking-at' except matches before point, and is slower. | |
405 | LIMIT if non-nil speeds up the search by specifying a minimum | |
406 | starting position, to avoid checking matches that would start | |
407 | before LIMIT. | |
408 | ||
409 | If GREEDY is non-nil, extend the match backwards as far as | |
410 | possible, stopping when a single additional previous character | |
411 | cannot be part of a match for REGEXP. When the match is | |
412 | extended, its starting position is allowed to occur before | |
413 | LIMIT." | |
414 | (let ((start (point)) | |
415 | (pos | |
416 | (save-excursion | |
417 | (and (re-search-backward (concat "\\(?:" regexp "\\)\\=") limit t) | |
418 | (point))))) | |
419 | (if (and greedy pos) | |
420 | (save-restriction | |
421 | (narrow-to-region (point-min) start) | |
422 | (while (and (> pos (point-min)) | |
423 | (save-excursion | |
424 | (goto-char pos) | |
425 | (backward-char 1) | |
426 | (looking-at (concat "\\(?:" regexp "\\)\\'")))) | |
427 | (setq pos (1- pos))) | |
428 | (save-excursion | |
429 | (goto-char pos) | |
430 | (looking-at (concat "\\(?:" regexp "\\)\\'"))))) | |
431 | (not (null pos))))) | |
432 | ||
acedf35c CD |
433 | (defun org-floor* (x &optional y) |
434 | "Return a list of the floor of X and the fractional part of X. | |
435 | With two arguments, return floor and remainder of their quotient." | |
436 | (let ((q (floor x y))) | |
437 | (list q (- x (if y (* y q) q))))) | |
438 | ||
8223b1d2 | 439 | ;; `pop-to-buffer-same-window' has been introduced in Emacs 24.1. |
e66ba1df BG |
440 | (defun org-pop-to-buffer-same-window |
441 | (&optional buffer-or-name norecord label) | |
442 | "Pop to buffer specified by BUFFER-OR-NAME in the selected window." | |
443 | (if (fboundp 'pop-to-buffer-same-window) | |
444 | (funcall | |
445 | 'pop-to-buffer-same-window buffer-or-name norecord) | |
446 | (funcall 'switch-to-buffer buffer-or-name norecord))) | |
5b409b39 | 447 | |
c7cf0ebc BG |
448 | ;; RECURSIVE has been introduced with Emacs 23.2. |
449 | ;; This is copying and adapted from `tramp-compat-delete-directory' | |
450 | (defun org-delete-directory (directory &optional recursive) | |
451 | "Compatibility function for `delete-directory'." | |
452 | (if (null recursive) | |
453 | (delete-directory directory) | |
454 | (condition-case nil | |
455 | (funcall 'delete-directory directory recursive) | |
456 | ;; This Emacs version does not support the RECURSIVE flag. We | |
457 | ;; use the implementation from Emacs 23.2. | |
458 | (wrong-number-of-arguments | |
459 | (setq directory (directory-file-name (expand-file-name directory))) | |
460 | (if (not (file-symlink-p directory)) | |
461 | (mapc (lambda (file) | |
462 | (if (eq t (car (file-attributes file))) | |
463 | (org-delete-directory file recursive) | |
464 | (delete-file file))) | |
465 | (directory-files | |
466 | directory 'full "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*"))) | |
467 | (delete-directory directory))))) | |
8223b1d2 BG |
468 | |
469 | ;;;###autoload | |
470 | (defmacro org-check-version () | |
471 | "Try very hard to provide sensible version strings." | |
472 | (let* ((org-dir (org-find-library-dir "org")) | |
473 | (org-version.el (concat org-dir "org-version.el")) | |
474 | (org-fixup.el (concat org-dir "../mk/org-fixup.el"))) | |
475 | (if (require 'org-version org-version.el 'noerror) | |
476 | '(progn | |
477 | (autoload 'org-release "org-version.el") | |
478 | (autoload 'org-git-version "org-version.el")) | |
479 | (if (require 'org-fixup org-fixup.el 'noerror) | |
480 | '(org-fixup) | |
481 | ;; provide fallback definitions and complain | |
482 | (warn "Could not define org version correctly. Check installation!") | |
483 | '(progn | |
484 | (defun org-release () "N/A") | |
485 | (defun org-git-version () "N/A !!check installation!!")))))) | |
486 | ||
e66ba1df | 487 | (provide 'org-compat) |
b349f79f | 488 | |
20908596 | 489 | ;;; org-compat.el ends here |