237 lines
8.8 KiB
EmacsLisp
237 lines
8.8 KiB
EmacsLisp
|
;;; ess-install.el --- Automatic installation of ESS.
|
||
|
;; Auto-install procedure. EXPERIMENTAL!
|
||
|
|
||
|
;; Copyright (C) 2006 A.J. Rossini, Richard M. Heiberger, Martin
|
||
|
;; Maechler, Kurt Hornik, Rodney Sparapani, and Stephen Eglen.
|
||
|
|
||
|
;; Author: Stephen Eglen
|
||
|
|
||
|
;; This file is part of ESS
|
||
|
|
||
|
;; This file is free software; you can redistribute it and/or modify
|
||
|
;; it under the terms of the GNU General Public License as published by
|
||
|
;; the Free Software Foundation; either version 2, or (at your option)
|
||
|
;; any later version.
|
||
|
;;
|
||
|
;; This file is distributed in the hope that it will be useful,
|
||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
;; GNU General Public License for more details.
|
||
|
;;
|
||
|
;; A copy of the GNU General Public License is available at
|
||
|
;; http://www.r-project.org/Licenses/
|
||
|
;;
|
||
|
;;
|
||
|
;; In short: you may use this code any way you like, as long as you
|
||
|
;; don't charge more than a distribution fee for it, do distribute the
|
||
|
;; source with any binaries, remove this notice, or hold anyone liable
|
||
|
;; for its results.
|
||
|
|
||
|
;;; Commentary:
|
||
|
|
||
|
;; Although installing ESS is relatively simple, sometimes people get
|
||
|
;; confused as to what to add to their init files, or even where their
|
||
|
;; init files are located. The following procedure should be a bit
|
||
|
;; simpler, as Emacs will add the necessary start-up lines itself.
|
||
|
;; (The instructions below assume you have downloaded ess as a zip
|
||
|
;; package, but it will work also for the .tar.gz version of ESS as
|
||
|
;; long as you know how to unpack a .tar.gz in step 3.)
|
||
|
;;
|
||
|
;; Installing ESS for the first time.
|
||
|
;;
|
||
|
;; 1. Create a folder (e.g C:/emacs) where you will store ESS. We will
|
||
|
;; assume that you are installing ESS into C:/emacs (unix users can use
|
||
|
;; ~/emacs).
|
||
|
;;
|
||
|
;; 2. Download ess-5.2.12.zip and store it in the folder you created.
|
||
|
;;
|
||
|
;; 3. Unpack the files from the zip archive, e.g. by right-clicking on it
|
||
|
;; within Windows explorer and selecting "Extract all". On unix, use
|
||
|
;; "unzip ess-5.2.12.zip".
|
||
|
;;
|
||
|
;; 4. Start a new emacs (or xemacs).
|
||
|
;;
|
||
|
;; 5. In the new emacs, you need to open the file "ess-install.el" which
|
||
|
;; is part of ESS. To do this, type:
|
||
|
;;
|
||
|
;; C-x C-f c:/emacs/ess-5.2.12/lisp/ess-install.el RET
|
||
|
;;
|
||
|
;; You should now see a lisp file with the top line:
|
||
|
;; ;;; ess-install.el --- Automatic installation of ESS.
|
||
|
;;
|
||
|
;; 6. Type M-x eval-buffer RET
|
||
|
;;
|
||
|
;; What does this do? This will find your emacs initialisation file, and
|
||
|
;; it will add the following two lines to the end of the file:
|
||
|
;;
|
||
|
;; ;;; ESS setup for version 5.2.12
|
||
|
;; (load "c:/emacs/ess-5.2.12/lisp/ess-site")
|
||
|
;;
|
||
|
;; Do not edit those two lines! They are useful if later you come to
|
||
|
;; upgrade ESS.
|
||
|
;;
|
||
|
;; 7. Start a new Emacs and you should find then that ESS is loaded. For
|
||
|
;; example, create a new file called "foo.R" and check that it opens
|
||
|
;; in R mode by looking at the mode line and menubar.
|
||
|
;;
|
||
|
;; Upgrading your version of ESS.
|
||
|
;;
|
||
|
;; If (and only if) you use the above instructions for installing ESS,
|
||
|
;; when a new version of ESS is released, you can use the same method to
|
||
|
;; install the new version. Repeat steps 2-7 for the new release of ESS,
|
||
|
;; and this time in step 6, if emacs finds that you already have the
|
||
|
;; special line ";;; ESS setup for version 5.2.12", it will highlight
|
||
|
;; those lines, and query whether you want to replace those two lines
|
||
|
;; with the new setup code.
|
||
|
;;
|
||
|
;; If you do upgrade ESS this way, bear in mind that your old version
|
||
|
;; will not be deleted from your filespace -- you will have to delete it
|
||
|
;; yourself.
|
||
|
|
||
|
;; TODO: possibly add a call to (byte-recompile-directory ess-lisp-dir
|
||
|
;; 0) so that lisp files are byte compiled.
|
||
|
|
||
|
;;; Code:
|
||
|
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
;; Location where the new lisp files are stored.
|
||
|
(defvar ess-lisp-dir (file-name-directory
|
||
|
(abbreviate-file-name buffer-file-name))
|
||
|
"Location where the new lisp files are stored.")
|
||
|
|
||
|
(defvar ess-site-file (concat ess-lisp-dir "ess-site")
|
||
|
"Full path to the new ess-site file.
|
||
|
Do not include .el extension in case there is also a .elc around.")
|
||
|
|
||
|
(defvar ess-new-version nil
|
||
|
"Version number of new ESS to be installed.")
|
||
|
|
||
|
(defvar ess-installed nil)
|
||
|
|
||
|
|
||
|
(defun ess-install-byte-compile ()
|
||
|
"Byte compile the ESS files.
|
||
|
This will probably generate warnings, but they can hopefully be
|
||
|
ignored."
|
||
|
;; To do byte compilation, XEmacs seems to want the files on its
|
||
|
;; load-path so that it can do the (require 'xyz) statements.
|
||
|
(add-to-list 'load-path ess-lisp-dir)
|
||
|
(byte-recompile-directory ess-lisp-dir 0))
|
||
|
|
||
|
;; Check that ess-site-file is written using unix directory separators.
|
||
|
;; i.e. need to change c:\\some\\dir\\ess-site.el to
|
||
|
;; c:/some/dir/ess-site.el
|
||
|
;; To do this, we have to load in ess-replace-in-string, from
|
||
|
;; the file ess-inf.el
|
||
|
|
||
|
(save-window-excursion
|
||
|
(find-file (concat ess-lisp-dir "ess-inf.el"))
|
||
|
(goto-char (point-min))
|
||
|
(search-forward-regexp "^(defun ess-replace-in-string " nil t)
|
||
|
(eval-defun nil)
|
||
|
(setq ess-site-file
|
||
|
(ess-replace-in-string ess-site-file "\\\\" "/" t))
|
||
|
)
|
||
|
|
||
|
|
||
|
;; Get the version number of the new software. Open the file
|
||
|
;; ess-custom.el and then find the definition of the variable
|
||
|
;; ess-version.
|
||
|
(save-window-excursion
|
||
|
(let ((beg))
|
||
|
(find-file (concat ess-lisp-dir "ess-custom.el"))
|
||
|
;; go back to start, just in case file was previously open.
|
||
|
(goto-char (point-min))
|
||
|
(search-forward "defvar ess-version \"")
|
||
|
(setq beg (point))
|
||
|
(search-forward "\"")
|
||
|
(setq ess-new-version (buffer-substring beg (1- (point))))))
|
||
|
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
;;; Highlighting (copied from reftex.el -- cheers Carsten!)
|
||
|
;; Only one highlight region is needed, whereas two are provided here,
|
||
|
;; so this code could be simplified. But we may want it again later.
|
||
|
|
||
|
;; Highlighting uses overlays. If this is for XEmacs, we need to load
|
||
|
;; the overlay library, available in version 19.15
|
||
|
(and (not (fboundp 'make-overlay))
|
||
|
(condition-case nil
|
||
|
(require 'overlay)
|
||
|
('error
|
||
|
(error "Fm needs overlay emulation (available in XEmacs 19.15)"))))
|
||
|
|
||
|
;; We keep a vector with several different overlays to do our highlighting.
|
||
|
(defvar ess-highlight-overlays [nil nil])
|
||
|
|
||
|
;; Initialize the overlays (here we provide two overlays)
|
||
|
(aset ess-highlight-overlays 0 (make-overlay 1 1))
|
||
|
(overlay-put (aref ess-highlight-overlays 0) 'face 'highlight)
|
||
|
(aset ess-highlight-overlays 1 (make-overlay 1 1))
|
||
|
(overlay-put (aref ess-highlight-overlays 1) 'face 'highlight)
|
||
|
|
||
|
;; Two functions for activating and deactivation highlight overlays
|
||
|
(defun ess-highlight (index begin end &optional buffer)
|
||
|
"Highlight a region with overlay INDEX."
|
||
|
(move-overlay (aref ess-highlight-overlays index)
|
||
|
begin end (or buffer (current-buffer))))
|
||
|
(defun ess-unhighlight (index)
|
||
|
"Detatch overlay INDEX."
|
||
|
(delete-overlay (aref ess-highlight-overlays index)))
|
||
|
|
||
|
;;; End of highlighting code.
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
|
||
|
;; Try to find the .emacs init file and edit it.
|
||
|
(save-window-excursion
|
||
|
|
||
|
;; Try to find the init file if one already exists,
|
||
|
;; or create a new one if we can't find any.
|
||
|
(if (stringp user-init-file)
|
||
|
(find-file user-init-file)
|
||
|
;; else, let's guess that the init file should be called ".emacs"
|
||
|
;; and the tilde will be resolved okay.
|
||
|
(find-file "~/.emacs"))
|
||
|
(goto-char (point-min))
|
||
|
|
||
|
(let ((ess-commands
|
||
|
(concat "\n;;; ESS setup for version " ess-new-version "\n"
|
||
|
"(load \"" ess-site-file "\")\n"))
|
||
|
(new-install)
|
||
|
(beg))
|
||
|
(if (search-forward ";;; ESS setup for version " nil t)
|
||
|
(progn
|
||
|
(message "You already have ESS installed.")
|
||
|
(setq ess-installed
|
||
|
(buffer-substring (point)
|
||
|
(save-excursion (end-of-line) (point))))
|
||
|
|
||
|
(beginning-of-line)
|
||
|
(setq beg (point))
|
||
|
;; We assume the next line contains a sexp that loads the
|
||
|
;; the ess-site; this sexp can be multiple lines.
|
||
|
(forward-line 1)
|
||
|
(forward-list 1)
|
||
|
(ess-highlight 0 beg (point))
|
||
|
|
||
|
(setq new-install
|
||
|
(yes-or-no-p
|
||
|
(concat "Replace ESS version " ess-installed
|
||
|
" with version "
|
||
|
ess-new-version "? ")))
|
||
|
(when new-install
|
||
|
(kill-region beg (point))
|
||
|
(insert ess-commands)
|
||
|
(save-buffer)
|
||
|
(ess-install-byte-compile)
|
||
|
(message (concat "ESS updated to version " ess-new-version))
|
||
|
))
|
||
|
;; else, just insert commands at end.
|
||
|
(goto-char (point-max))
|
||
|
(insert ess-commands)
|
||
|
(save-buffer)
|
||
|
(ess-install-byte-compile)
|
||
|
(message (concat "ESS version "ess-new-version" installed."))
|
||
|
)))
|
||
|
|
||
|
;;; ess-install.el ends here
|