(defun ess-running-emacs-version-or-newer (major minor)
(or (> emacs-major-version major)
(and (= emacs-major-version major)
(>= emacs-minor-version minor))))
(defvar ess-local-custom-available (featurep 'custom)
"Value is nil if custom.el not available, t if available.
Only a concern with earlier versions of Emacs.")
(defvar ess-microsoft-p (or (equal window-system 'w32)
(equal window-system 'win32)
(equal window-system 'mswindows))
"Value is t if the OS is one of Microsoft's, nil otherwise.")
(if (not (fboundp 'find-buffer-visiting))
(fset 'find-buffer-visiting 'get-file-buffer))
(defalias 'ess-line-beginning-position
(if (fboundp 'line-beginning-position)
'line-beginning-position
'point-at-bol))
(if (and (not (featurep 'xemacs))
(string-match "XEmacs\\|Lucid" emacs-version))
(provide 'xemacs))
(cond ((fboundp 'replace-regexp-in-string)
(defalias 'ess-replace-regexp-in-string 'replace-regexp-in-string))
((featurep 'xemacs)
(defun ess-replace-regexp-in-string(regexp replace string)
"Mimic GNU Emacs function replace-regexp-in-string with XEmacs' replace-in-string"
(replace-in-string string regexp replace)))
(t (defun ess-replace-regexp-in-string (regexp rep string &optional
fixedcase literal subexp start)
"Replace all matches for REGEXP with REP in STRING.
Return a new string containing the replacements.
Optional arguments FIXEDCASE, LITERAL and SUBEXP are like the
arguments with the same names of function `replace-match'. If START
is non-nil, start replacements at that index in STRING.
REP is either a string used as the NEWTEXT arg of `replace-match' or a
function. If it is a function it is applied to each match to generate
the replacement passed to `replace-match'; the match-data at this
point are such that match 0 is the function's argument.
To replace only the first match (if any), make REGEXP match up to \\'
and replace a sub-expression, e.g.
(ess-replace-regexp-in-string \"\\(foo\\).*\\'\" \"bar\" \" foo foo\" nil nil 1)
=> \" bar foo\"
"
(let ((l (length string))
(start (or start 0))
matches str mb me)
(save-match-data
(while (and (< start l) (string-match regexp string start))
(setq mb (match-beginning 0)
me (match-end 0))
(when (= me mb) (setq me (min l (1+ mb))))
(string-match regexp (setq str (substring string mb me)))
(setq matches
(cons (replace-match (if (stringp rep)
rep
(funcall rep (match-string 0 str)))
fixedcase literal str subexp)
(cons (substring string start mb)
matches)))
(setq start me))
(setq matches (cons (substring string start l) matches))
(apply #'concat (nreverse matches)))))
)
)
(if (not (functionp 'remassoc))
(defun remassoc (key a)
"remove an association pair from an alist"
(if a
(let ((pair (car a)))
(if (equal (car pair) key)
(cdr a)
(cons pair (remassoc key (cdr a))))))))
(if (not (fboundp 'w32-using-nt))
(defun w32-using-nt ()
"Return non-nil if literally running on Windows NT (i.e., not Windows 9X)."
(and (eq system-type 'windows-nt) (getenv "SystemRoot"))))
(if (and (featurep 'xemacs)
(fboundp 'extent-at)
(fboundp 'make-extent)
(fboundp 'set-extent-property))
(defun ess-xemacs-insert-glyph (gl)
"Insert a glyph at the left edge of point."
(let ((prop 'myimage)
extent)
(if (not (setq extent (extent-at (point) (current-buffer) prop)))
(progn
(setq extent (make-extent (point) (point) (current-buffer)))
(set-extent-property extent prop t)
))
(set-extent-property extent 'begin-glyph gl))))
(if (not (boundp 'w32-system-shells))
(defvar w32-system-shells '("cmd" "cmd.exe" "command" "command.com"
"4nt" "4nt.exe" "4dos" "4dos.exe"
"ndos" "ndos.exe")
"List of strings recognized as Windows NT/9X system shells.")
)
(if (not (fboundp 'w32-system-shell-p))
(defun w32-system-shell-p (shell-name)
(and shell-name
(member (downcase (file-name-nondirectory shell-name))
w32-system-shells)))
)
(if (not (fboundp 'w32-shell-name))
(defun w32-shell-name ()
"Return the name of the shell being used."
(or (and (boundp 'explicit-shell-file-name) explicit-shell-file-name)
(getenv "ESHELL")
(getenv "SHELL")
(and (w32-using-nt) "cmd.exe")
"command.com"))
)
(if (not (fboundp 'w32-shell-dos-semantics)) (defun w32-shell-dos-semantics ()
"Return t if the interactive shell being used expects msdos shell semantics."
(or (w32-system-shell-p (w32-shell-name))
(and (member (downcase (file-name-nondirectory (w32-shell-name)))
'("cmdproxy" "cmdproxy.exe"))
(w32-system-shell-p (getenv "COMSPEC")))))
)
(if (not (boundp 'enable-multibyte-characters))
(defvar enable-multibyte-characters nil
"Non-nil means the buffer contents are regarded as multi-byte characters.
This concept is handled completely differently on Xemacs."))
(defvar ess-has-tooltip
(and (not (featurep 'xemacs))
(>= emacs-major-version 21))
"non-nil if 'tooltip can be required; typically nil for Xemacs.")
(if (and ess-microsoft-p
(not (fboundp 'w32-short-file-name)))
(cond ((fboundp 'win32-short-file-name)
(fset 'w32-short-file-name 'win32-short-file-name))
((fboundp 'mswindows-short-file-name)
(fset 'w32-short-file-name 'mswindows-short-file-name))
(t
(warn "None of 'w32-short-file-name, 'win32-short-file-name,
or 'mswindows-short-file-name are defined!
You will have to manually set ess-program-files (in ess-custom.el) to
the correct \"8.3\"-style directory name."))))
(defun ess-sleep ()
"Put emacs to sleep for `ess-sleep-for-shell' seconds (floats work).
Sometimes its necessary to wait for a shell prompt."
(if (featurep 'xemacs) (sleep-for ess-sleep-for-shell)
(sleep-for 0 (truncate (* ess-sleep-for-shell 1000)))))
(unless (fboundp 'use-region-p)
(defun use-region-p ()
"Return t if the region is active and it is appropriate to act on it.
This is used by commands that act specially on the region under
Transient Mark mode.
The return value is t if Transient Mark mode is enabled and the
mark is active; furthermore, if `use-empty-active-region' is nil,
the region must not be empty. Otherwise, the return value is nil.
For some commands, it may be appropriate to ignore the value of
`use-empty-active-region'; in that case, use `region-active-p'."
(and (region-active-p)
(or use-empty-active-region (> (region-end) (region-beginning)))))
(defun region-active-p ()
"Return t if Transient Mark mode is enabled and the mark is active.
Some commands act specially on the region when Transient Mark
mode is enabled. Usually, such commands should use
`use-region-p' instead of this function, because `use-region-p'
also checks the value of `use-empty-active-region'."
(and transient-mark-mode mark-active)))
(provide 'ess-compat)