603 lines
28 KiB
EmacsLisp
603 lines
28 KiB
EmacsLisp
;;; ess-sp6w-d.el --- S-PLUS 6.x for Windows customization
|
||
|
||
;;; copied and edited from ess-s4-d.el - Richard M. Heiberger, April 2001
|
||
|
||
;; Copyright (C) 2001 Richard M. Heiberger <rmh@temple.edu>
|
||
;; Copyright (C) 2002--2005 A.J. Rossini, Richard M. Heiberger, Martin
|
||
;; Maechler, Kurt Hornik, Rodney Sparapani, and Stephen Eglen.
|
||
|
||
;; Author: Richard M. Heiberger <rmh@temple.edu>
|
||
;; Created: April 2001
|
||
;; Maintainer: ESS-core <ESS-core@r-project.org>
|
||
|
||
;; Keywords: languages
|
||
|
||
;; 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/
|
||
|
||
;;; Commentary:
|
||
|
||
;; This file defines all the S-PLUS 6.x for Windows customizations
|
||
;; for ess-mode with ddeclient.
|
||
|
||
;;; Code:
|
||
|
||
;;; Requires and Autoloads:
|
||
|
||
(require 'ess-s-l)
|
||
;;NO: this is autoloaded from other places (require 'ess-dde)
|
||
|
||
(autoload 'inferior-ess "ess-inf" "Run an ESS process.")
|
||
(autoload 'ess-mode "ess-mode" "Edit an ESS process.")
|
||
|
||
|
||
(defvaralias 'inferior-S+6-multipleinstances 'inferior-S+-multipleinstances)
|
||
(defvar inferior-S+-multipleinstances "/MULTIPLEINSTANCES"
|
||
"Default \"/MULTIPLEINSTANCES\" opens up a new instance of S+[678] in a
|
||
GUI window and connects it to the '(ddeESS [S+])' window. The
|
||
alternative nil uses an existing S+ GUI (if there is one) and
|
||
connects it to the '(ddeESS [S+])' window.")
|
||
|
||
(defvaralias 'S+6-customize-alist 'S+-customize-alist)
|
||
(defvar S+-customize-alist
|
||
(append
|
||
'((ess-local-customize-alist . 'S+-customize-alist)
|
||
(ess-dialect . S+-dialect-name)
|
||
(ess-loop-timeout . ess-S-loop-timeout);fixme: dialect spec.
|
||
(ess-object-name-db-file . "ess-sp6-namedb.el" )
|
||
(inferior-ess-program . inferior-S+-program-name)
|
||
(inferior-ess-help-command . "help(\"%s\")\n")
|
||
(inferior-ess-help-filetype . "chm")
|
||
(inferior-ess-search-list-command . "searchPaths()\n")
|
||
(inferior-ess-start-file . nil) ;"~/.ess-S+")
|
||
(inferior-ess-start-args . (concat
|
||
inferior-S+-multipleinstances
|
||
" "
|
||
inferior-S+-start-args
|
||
" "
|
||
inferior-S+-print-command
|
||
" S_PROJ="
|
||
(w32-short-file-name (directory-file-name default-directory))))
|
||
;; (inferior-ess-ddeclient . "ddeclient")
|
||
;; (inferior-ess-client-name . "S-PLUS")
|
||
;; (inferior-ess-client-command . "SCommand")
|
||
(ess-STERM . "ddeESS")
|
||
)
|
||
S+common-cust-alist)
|
||
"Variables to customize for S+")
|
||
|
||
(defvaralias 'Sqpe+6-customize-alist 'Sqpe+-customize-alist)
|
||
(defvar Sqpe+-customize-alist
|
||
(append
|
||
'((ess-local-customize-alist . 'Sqpe+-customize-alist)
|
||
(ess-dialect . S+-dialect-name)
|
||
(ess-loop-timeout . 500000 );fixme: dialect specific custom.var
|
||
(ess-object-name-db-file . "ess-sp6-namedb.el" )
|
||
(inferior-ess-program . inferior-Sqpe+-program-name)
|
||
(inferior-ess-help-command . "help(\"%s\")\n")
|
||
(inferior-ess-help-filetype . "chm")
|
||
(inferior-ess-search-list-command . "searchPaths()\n")
|
||
(inferior-ess-start-file . nil) ;"~/.ess-S+")
|
||
(inferior-ess-start-args . (concat
|
||
;; workaround for bug in S-Plus 6 for Windows:
|
||
"ALWAYS_PROMPT=X"
|
||
" "
|
||
inferior-Sqpe+-start-args ;; e.g. license manager
|
||
))
|
||
(ess-STERM . "iESS")
|
||
)
|
||
S+common-cust-alist)
|
||
"Variables to customize for Sqpe+.")
|
||
|
||
|
||
|
||
;;; There are extra complications in S+6 and S+7 and S+8 (compared to S+3)
|
||
;;; because
|
||
;;;
|
||
;;; (1) The StatSci supplied Splus.exe doesn't work in an emacs
|
||
;;; buffer. It works as as a GUI window and we must send commands
|
||
;;; to it through ddeclient. Nonetheless, we need to give it a
|
||
;;; process name and be sure that that there is a valid running
|
||
;;; process in the '(ddeESS [S+])' buffer. Therefore we create an
|
||
;;; ESS process in the buffer as a placeholder and start a shell
|
||
;;; in the ESS buffer. From the shell we start Splus. Once Splus
|
||
;;; finishes initializing and kills the original shell, we start
|
||
;;; another shell. We have a buffer-local variable
|
||
;;; inferior-ess-ddeclient, initialized to nil. When there is a
|
||
;;; non-nil value of inferior-ess-ddeclient we send lines to
|
||
;;; inferior-ess-ddeclient rather than to the Splus process.
|
||
;;; (2) There is no Splus process running in the '(ddeESS [S+])'
|
||
;;; buffer. Therefore inferior-ess will never see a prompt,
|
||
;;; unless we first change it to the null prompt "^". Then once
|
||
;;; the process has started, we change it back.
|
||
;;; (3) When M-x S+ starts Splus by a shell command, then Splus is an
|
||
;;; independent process and will be survive if the '(ddeESS [S+])'
|
||
;;; buffer is killed (or emacs is quit). The '(ddeESS [S+])' is
|
||
;;; made read-only and a warning is placed in it saying that "You
|
||
;;; can't type anything here." Actually, if thestandalone Splus
|
||
;;; is killed and the '(ddeESS [S+])' is made writable (C-x C-q),
|
||
;;; then '(ddeESS [S+])' becomes a shell buffer.
|
||
;;;
|
||
(defalias 'S+6 'S+)
|
||
(defun S+ (&optional proc-name)
|
||
"Verify that `inferior-S+-program-name' points to S-Plus 6 or
|
||
S-Plus 7 or S-Plus 8. Start normally for S-Plus 6.1 and later.
|
||
Inform the user to start S-Plus 6.0 from the icon and then
|
||
connect to it with `S+-existing'. Give an error message if
|
||
`inferior-S+-program-name' doesn't point to S-Plus 6 or S-Plus 7
|
||
or S-Plus 8."
|
||
(interactive)
|
||
(with-current-buffer (find-file-noselect
|
||
(concat (executable-find inferior-S+-program-name)
|
||
"/../../versions") t)
|
||
(setq buffer-read-only 1)
|
||
(forward-line)
|
||
(if (not (search-backward-regexp "splus\t[678].[0-9]" (point-min) t))
|
||
(error "The emacs variable `inferior-S+-program-name' does
|
||
not point to S-Plus 6 or 7 or 8. Please add `splus[678]?/cmd' (expand the
|
||
`[678]?' to match your setup) to your `exec-path' or specify the complete
|
||
path to `Splus.exe' in the variable `inferior-S+-program-name' in your
|
||
`.emacs' file.")
|
||
(forward-line)
|
||
(if (search-backward "splus\t6.0" (point-min) t)
|
||
(error "S-Plus 6.0 for Microsoft Windows has a bug that
|
||
prevents it from being started by emacs. Instead, you must start it
|
||
by double-clicking an icon. Then you can connect to it with
|
||
`S+-existing'. You should consider upgrading to a newer
|
||
release of S-Plus."))))
|
||
(S+-initiate proc-name)) ;; normal start ;
|
||
|
||
(defalias 'S+6-initiate 'S+-initiate)
|
||
(defun S+-initiate (&optional proc-name)
|
||
"Call 'S-PLUS [678].x for Windows', the 'GUI Thing' from StatSci. Put
|
||
S-Plus in an independent MS-Window (Splus persists even if the
|
||
'(ddeESS [S+])' window is killed in emacs). Do this by creating a
|
||
comint process that calls sh. Send a shell command in that sh buffer
|
||
to call Splus. When it completes set up a shell as a placeholder in
|
||
the '(ddeESS [S+])' buffer. The S-Plus options are correctly set.
|
||
In particular, the S-Plus Commands window is opened if the
|
||
Options/General Settings/Startup menu says it should be. There is a
|
||
startup delay of `ess-S+-startup-delay' seconds during which the
|
||
screen will not be refreshed. This delay is here to allow slow disks
|
||
to start the Splus program."
|
||
(interactive)
|
||
(save-excursion
|
||
(setq ess-customize-alist S+-customize-alist)
|
||
(ess-write-to-dribble-buffer
|
||
(format "\n(S+): ess-dialect=%s, buf=%s\n" ess-dialect
|
||
(current-buffer)))
|
||
(setq ess-customize-alist ; change inferior-ess-program
|
||
(append ess-customize-alist '((inferior-ess-program . "sh"))))
|
||
(setq ess-customize-alist ; change inferior-ess-primary-prompt
|
||
(append ess-customize-alist '((inferior-ess-primary-prompt . "^"))))
|
||
(setq ess-customize-alist ; change inferior-ess-start-args
|
||
(append ess-customize-alist '((inferior-ess-start-args . "-i"))))
|
||
(let ((s-proj (getenv "S_PROJ"))
|
||
(use-dialog-box (not (or ess-microsoft-p (eq system-type 'cygwin))))
|
||
)
|
||
(cd (w32-short-file-name (directory-file-name default-directory)))
|
||
(setenv "S_PROJ" (w32-short-file-name default-directory))
|
||
(inferior-ess)
|
||
(sleep-for 2) ; need to wait, else working too fast! The Splus
|
||
; command in '(ddeESS [S+])' should follow the "$"
|
||
; prompt. If not, then increase the sleep-for time!
|
||
(setenv "S_PROJ" s-proj))
|
||
(setq ess-customize-alist S+-customize-alist)
|
||
(ess-setq-vars-local ess-customize-alist)
|
||
;;; the next three lines belong in customize-alist, but can't be there
|
||
;;; because of the broken ess-setq-vars-default usage in ess-inf.el
|
||
(setq inferior-ess-ddeclient "ddeclient")
|
||
(setq inferior-ess-client-name "S-PLUS")
|
||
(setq inferior-ess-client-command "SCommand")
|
||
;;; end of what belongs in customize-alist
|
||
(setq comint-process-echoes nil)
|
||
(setq comint-input-sender 'comint-simple-send)
|
||
(goto-char (point-max))
|
||
(insert (concat inferior-S+-program-name " "
|
||
inferior-ess-start-args)) ; Note: there is no final "&".
|
||
;; Without the "&", the results of !system.command come to '(ddeESS [S+])'
|
||
;; With the "&", the results of !system.command in S get lost.
|
||
(inferior-ess-send-input)
|
||
(sleep-for ess-S+-startup-delay) ; Need to wait, else working too fast!
|
||
; If the ess-current-process-name doesn't appear in the
|
||
; Splus Commands window increase the sleep-for time!
|
||
(setq ess-local-process-name ess-current-process-name)
|
||
(ess-eval-linewise (concat "#" ess-current-process-name))
|
||
(goto-char (point-min))
|
||
(insert
|
||
"This is a placeholder buffer. You can't type anything here.
|
||
Use `C-x b RET' to return to your file.\n
|
||
Anything sent to this process from an S-mode buffer goes
|
||
directly to the associated Splus Commands window.\n
|
||
The S-Plus Commands window must be visible.
|
||
You may need to open the S-Plus Commands window manually (by clicking on
|
||
Splus/Window/Commands Window).\n
|
||
Any results of the !system.command typed at the S prompt in the
|
||
Splus Commands window appear in this buffer.\n\n")
|
||
(goto-char (point-max)) ; comint-mode-map makes '(ddeESS [S+])'
|
||
;; (use-local-map comint-mode-map) ;a shell buffer after Splus is finished.
|
||
(set-buffer-process-coding-system 'raw-text-dos 'raw-text-unix)
|
||
(setq buffer-read-only t) ; force buffer to be read-only
|
||
(setq mode-name "ddeESS")
|
||
;; (ess-eval-linewise inferior-S+-editor-pager-command)
|
||
(if inferior-ess-language-start
|
||
(ess-eval-linewise inferior-ess-language-start))
|
||
))
|
||
|
||
|
||
(defalias 'S+6-existing 'S+-existing)
|
||
(defun S+-existing (&optional proc-name)
|
||
"Call 'S-PLUS [678].x for Windows', the 'GUI Thing' from StatSci. Do so by
|
||
finding an existing S-Plus in an independent MS-Window (if there is one) and
|
||
set up a '(ddeESS [S+])' buffer in emacs. If there is no existing
|
||
S-Plus, then a new one will be opened in the default directory. The default
|
||
is usually something like 'c:/Program Files/Insightful/splus70/users/yourname'
|
||
for S-Plus before 8.0.4. Beginning with 8.0.4, S-Plus uses the default directory
|
||
'c:/Documents and Settings/yourname/My Documents/S-PLUS Projects/Project1'.
|
||
Beginning with TIBCO Spotfire S+ Version 8.1.1 for Microsft Windows, the default
|
||
directory is 'c:/DOCUME~1/yourname/MYDOCU~1/SPOTFI~1/Project1'.
|
||
If you have a HOME environment variable, it will open it there."
|
||
(interactive)
|
||
(let* ((inferior-S+-multipleinstances " & # ") ; Note: there is a final "&".
|
||
(ess-S+-startup-delay 0)) ;; No delay for existing S-Plus
|
||
;; Without the "&", there is a core dump.
|
||
;; With the "&", the results of !system.command in S get lost.
|
||
;; We are picking up an existing S-Plus process for sending to.
|
||
;; It doesn't know about us, so nothing comes back.
|
||
(S+-initiate proc-name))
|
||
(with-current-buffer (car (buffer-list)) ; get the ESS buffer just created
|
||
(setq buffer-read-only nil) ; permit writing in ESS buffer
|
||
(goto-char (point-max))
|
||
(beginning-of-line)
|
||
(forward-line -1)
|
||
(insert
|
||
"This is S+-existing.
|
||
Results of the !system.command typed at the S prompt in the
|
||
Splus Commands window blink a DOS window and you won't see them.\n\n")
|
||
(setq buffer-read-only t) ; restore ESS buffer to be read-only
|
||
))
|
||
|
||
|
||
;;; There are extra complications in Sqpe+6 (compared to S+3) because
|
||
;;; (1) The StatSci supplied Sqpe.exe won't work without SHOME as an
|
||
;;; environment variable and Sqpe does not take command line
|
||
;;; arguments and
|
||
;;; (2) Sqpe.exe comes up with options(interactive=FALSE), which means it
|
||
;;; doesn't provide prompts by default, and we must change it to T so
|
||
;;; it will provide prompts.
|
||
;;;
|
||
(defalias 'Sqpe+6 'Sqpe+)
|
||
(defun Sqpe+ (&optional proc-name)
|
||
"Call 'Sqpe' from 'S-PLUS [678].x for Windows', the 'Real Thing' from StatSci."
|
||
(interactive)
|
||
(setq ess-customize-alist Sqpe+-customize-alist)
|
||
(let* ((shome-nil-p (equal (getenv "SHOME") nil))
|
||
(use-dialog-box (not (or ess-microsoft-p (eq system-type 'cygwin))))
|
||
)
|
||
(if shome-nil-p (setenv "SHOME" inferior-Sqpe+-SHOME-name))
|
||
(ess-write-to-dribble-buffer
|
||
(format "\n(Sqpe+6): ess-dialect=%s, buf=%s\n" ess-dialect
|
||
(current-buffer)))
|
||
(setq ess-customize-alist ; change inferior-ess-primary-prompt
|
||
(append ess-customize-alist '((inferior-ess-primary-prompt . "^"))))
|
||
(inferior-ess)
|
||
(setq ess-customize-alist Sqpe+-customize-alist) ; restore i-e-p-p in alist
|
||
(ess-setq-vars-local ess-customize-alist) ; restore i-e-p-p in buffer
|
||
(setq inferior-ess-prompt ; define with correct i-e-p-p
|
||
;; Do not anchor to bol with `^' ; (copied from ess-inf.el)
|
||
(concat "\\("
|
||
inferior-ess-primary-prompt
|
||
"\\|"
|
||
inferior-ess-secondary-prompt
|
||
"\\)"))
|
||
(setq comint-prompt-regexp (concat "^" inferior-ess-prompt))
|
||
; define with correct i-e-p-p
|
||
(setq comint-input-sender 'inferior-ess-input-sender)
|
||
(add-hook 'comint-output-filter-functions 'shell-strip-ctrl-m nil t)
|
||
(goto-char (point-max))
|
||
(insert "options(interactive=TRUE)")
|
||
(inferior-ess-send-input)
|
||
(setq mode-name "iESS(Sqpe)")
|
||
;; (ess-eval-linewise inferior-S+-editor-pager-command)
|
||
(if inferior-ess-language-start
|
||
(ess-eval-linewise inferior-ess-language-start))
|
||
(if shome-nil-p (setenv "SHOME" nil))))
|
||
|
||
|
||
(defalias 'S+6-mode 'S+-mode)
|
||
(defun S+-mode (&optional proc-name)
|
||
"Major mode for editing S+[678] source. See `ess-mode' for more help."
|
||
(interactive)
|
||
(setq ess-customize-alist S+-customize-alist)
|
||
(ess-mode S+-customize-alist proc-name)
|
||
(if ess-imenu-use-S (ess-imenu-S)))
|
||
|
||
(defalias 'S+6-transcript-mode 'S+-transcript-mode)
|
||
(defun S+-transcript-mode ()
|
||
"S-PLUS transcript mode."
|
||
(interactive)
|
||
(ess-transcript-mode S+-customize-alist))
|
||
|
||
(defalias 'S+-msdos 'S+-msdos)
|
||
(defun S+-msdos (&optional proc-name)
|
||
"Verify that `inferior-S+-program-name' points to S-Plus 6 or
|
||
S-Plus 7 or S-Plus 8. Start normally for S-Plus 6.1 and later.
|
||
Inform the user to start S-Plus 6.0 from the icon and then
|
||
connect to it with `S+-msdos-existing'. Give an error message
|
||
if `inferior-S+-program-name' doesn't point to S-Plus 6 or
|
||
S-Plus 7 or S-Plus 8."
|
||
(interactive)
|
||
(with-current-buffer (find-file-noselect
|
||
(concat (executable-find inferior-S+-program-name)
|
||
"/../../versions") t)
|
||
(setq buffer-read-only 1)
|
||
(forward-line)
|
||
(if (not (search-backward-regexp "splus\t[678].[0-9]" (point-min) t))
|
||
(error "The emacs variable `inferior-S+-program-name' does
|
||
not point to S-Plus 6 or 7 or 8. Please add `splus[678]?/cmd'
|
||
(expand the `[678]?' to match your setup) to your `exec-path' or
|
||
specify the complete path to `Splus.exe' in the variable
|
||
`inferior-S+-program-name' in your `.emacs' file.") ;;; " This comment keeps emacs font-lock from getting out of phase.
|
||
|
||
(progn
|
||
(forward-line)
|
||
(if (search-backward "splus\t6.0" (point-min) t)
|
||
(error "S-Plus 6.0 for Microsoft Windows has a bug that
|
||
prevents it from being started by emacs. Instead, you must start it
|
||
by double-clicking an icon. Then you can connect to it with
|
||
`S+-msdos-existing'. You should consider upgrading to a newer
|
||
release of S-Plus.")
|
||
(S+-msdos-initiate proc-name))) ;; normal start ;
|
||
)))
|
||
|
||
(defalias 'S+6-msdos-initiate 'S+-msdos-initiate)
|
||
(defun S+-msdos-initiate (&optional proc-name)
|
||
"Call 'S-PLUS [678].x for Windows', the 'GUI Thing' from StatSci. Put
|
||
S-Plus in an independent MS-Window (Splus persists even if the
|
||
'(ddeESS [S+])' window is killed in emacs). Do this by creating a
|
||
comint process that calls sh. Send a shell command in that sh buffer
|
||
to call Splus. When it completes set up a shell as a placeholder in
|
||
the '(ddeESS [S+])' buffer. The S-Plus options are correctly set.
|
||
In particular, the S-Plus Commands window is opened if the
|
||
Options/General Settings/Startup menu says it should be. There is a
|
||
startup delay of `ess-S+-startup-delay' seconds during which the
|
||
screen will not be refreshed. This delay is here to allow slow disks
|
||
to start the Splus program."
|
||
(interactive)
|
||
(save-excursion
|
||
(setq ess-customize-alist S+-customize-alist)
|
||
(ess-write-to-dribble-buffer
|
||
(format "\n(S+): ess-dialect=%s, buf=%s\n" ess-dialect
|
||
(current-buffer)))
|
||
(setq ess-customize-alist ; change inferior-ess-program
|
||
(append ess-customize-alist '((inferior-ess-program
|
||
. (getenv "COMSPEC")))))
|
||
(setq ess-customize-alist ; change inferior-ess-primary-prompt
|
||
(append ess-customize-alist '((inferior-ess-primary-prompt . "^"))))
|
||
(setq ess-customize-alist ; change inferior-ess-start-args
|
||
(append ess-customize-alist '((inferior-ess-start-args . ""))))
|
||
(let ((s-proj (getenv "S_PROJ"))
|
||
(use-dialog-box (not (or ess-microsoft-p (eq system-type 'cygwin))))
|
||
)
|
||
(cd (w32-short-file-name (directory-file-name default-directory)))
|
||
(setenv "S_PROJ" (w32-short-file-name default-directory))
|
||
(inferior-ess)
|
||
(sleep-for 2) ; need to wait, else working too fast! The Splus
|
||
; command in '(ddeESS [S+])' should follow the "$"
|
||
; prompt. If not, then increase the sleep-for time!
|
||
(setenv "S_PROJ" s-proj))
|
||
(setq ess-customize-alist S+-customize-alist)
|
||
(ess-setq-vars-local ess-customize-alist)
|
||
;;; the next three lines belong in customize-alist, but can't be there
|
||
;;; because of the broken ess-setq-vars-default usage in ess-inf.el
|
||
(setq inferior-ess-ddeclient "ddeclient")
|
||
(setq inferior-ess-client-name "S-PLUS")
|
||
(setq inferior-ess-client-command "SCommand")
|
||
;;; end of what belongs in customize-alist
|
||
(setq comint-input-sender 'comint-simple-send)
|
||
(setq comint-process-echoes nil)
|
||
(set-buffer-process-coding-system 'raw-text-dos 'raw-text-dos)
|
||
(goto-char (point-max))
|
||
(insert (concat inferior-S+-program-name " "
|
||
inferior-ess-start-args)) ; Note: there is no final "&".
|
||
;; Without the "&", the results of !system.command come to '(ddeESS [S+])'
|
||
;; With the "&", the results of !system.command in S get lost.
|
||
(inferior-ess-send-input)
|
||
(sleep-for ess-S+-startup-delay) ; Need to wait, else working too fast!
|
||
; If the ess-current-process-name doesn't appear in the
|
||
; Splus Commands window increase the sleep-for time!
|
||
;;; from msdos-minor-mode
|
||
(setq comint-process-echoes t)
|
||
(add-hook 'comint-output-filter-functions 'shell-strip-ctrl-m nil t)
|
||
;;; end from msdos-minor-mode
|
||
(setq ess-local-process-name ess-current-process-name)
|
||
(ess-eval-linewise (concat "#" ess-current-process-name))
|
||
(goto-char (point-min))
|
||
(insert
|
||
"This is a placeholder buffer. You can't type anything here.
|
||
Use `C-x b RET' to return to your file.\n
|
||
Anything sent to this process from an S-mode buffer goes
|
||
directly to the associated Splus Commands window.\n
|
||
The S-Plus Commands window must be visible.
|
||
You may need to open the S-Plus Commands window manually
|
||
(by clicking on Splus/Window/Commands Window).\n
|
||
There is a `ess-S+-startup-delay' second delay when this program starts
|
||
during which the emacs screen will be partially blank.\n
|
||
Remember to 'q()' from S-Plus and
|
||
then C-x C-q exit from the '(ddeESS [S+])' buffer,
|
||
or take the risk of not being able to shut down your computer
|
||
and suffering through scandisk.\n
|
||
Any results of the !system.command typed at the S prompt in the
|
||
Splus Commands window (are supposed to) appear in this buffer.\n\n")
|
||
(goto-char (point-max)) ; comint-mode-map makes '(ddeESS [S+])'
|
||
(use-local-map comint-mode-map) ; a shell buffer after Splus is finished.
|
||
(setq buffer-read-only t) ; force buffer to be read-only
|
||
(setq mode-name "ddeESS")
|
||
;; (ess-eval-linewise inferior-S+-editor-pager-command)
|
||
(if inferior-ess-language-start
|
||
(ess-eval-linewise inferior-ess-language-start))
|
||
))
|
||
|
||
(defalias 'S+6-msdos-existing 'S+-msdos-existing)
|
||
(defun S+-msdos-existing (&optional proc-name)
|
||
"Call 'S-PLUS [678].x for Windows', the 'GUI Thing' from StatSci. Do so by
|
||
finding an existing S-Plus in an independent MS-Window (if there is one) and
|
||
set up a '(ddeESS [S+])' buffer in emacs. If there is no existing
|
||
S-Plus, then a new one will be opened in the default directory. The default
|
||
is usually something like 'c:/Program Files/Insightful/splus70/users/yourname'
|
||
for S-Plus before 8.0.4. Beginning with 8.0.4, S-Plus uses the default directory
|
||
'c:/Documents and Settings/yourname/My Documents/S-PLUS Projects/Project1'.
|
||
Beginning with TIBCO Spotfire S+ Version 8.1.1 for Microsft Windows, the default
|
||
directory is 'c:/DOCUME~1/yourname/MYDOCU~1/SPOTFI~1/Project1'.
|
||
If you have a HOME environment variable, it will open it there."
|
||
(interactive)
|
||
(let* ((inferior-S+-multipleinstances "")
|
||
(ess-S+-startup-delay 0)) ;; No delay for existing S-Plus
|
||
(S+-msdos-initiate proc-name))
|
||
(with-current-buffer (car (buffer-list)) ; get the ESS buffer just created
|
||
(setq buffer-read-only nil) ; permit writing in ESS buffer
|
||
(goto-char (point-max))
|
||
(beginning-of-line)
|
||
(forward-line -1)
|
||
(insert
|
||
"This is S+-msdos-existing.
|
||
Results of the !system.command typed at the S prompt in the
|
||
Splus Commands window blink a DOS window and you won't see them.\n\n")
|
||
(setq buffer-read-only t) ; restore ESS buffer to be read-only
|
||
))
|
||
|
||
(defun ess-sqpe-versions-create (ess-SHOME-versions &optional x64)
|
||
"Generate the `M-x splusxy' functions for starting other versions of
|
||
Sqpe. `ESS-SHOME-VERSIONS' is normally taken from
|
||
`ess-sqpe-versions', a variable that contains strings that determine which
|
||
functions are created. This works by creating a temp buffer where the
|
||
template function `Sqpe+template' is edited by replacing the string
|
||
'Sqpe+template' by the version name. The list of functions actually
|
||
created appears in the *ESS* buffer. If `X64' is not nil, then
|
||
modify the function name to show \"-64bit\" in its name.
|
||
|
||
The result `ess-sqpe-versions-created' will store a list of the new
|
||
Sqpe defuns, if any, that were created. The defuns will normally be
|
||
placed on the menubar upon ESS initialisation."
|
||
(let ((beg)
|
||
(versions)
|
||
(version)
|
||
(eval-buf (get-buffer-create "*ess-temp-sqpe-evals*"))
|
||
(ess-sqpe-versions-created)
|
||
)
|
||
;;
|
||
(with-current-buffer eval-buf
|
||
;; clear the buffer.
|
||
(delete-region (point-min) (point-max))
|
||
|
||
;; Find which versions of Sqpe we want.
|
||
(setq x64 (if x64 "-64bit"))
|
||
(setq versions (ess-uniq-list ess-SHOME-versions))
|
||
;; Iterate over each string in VERSIONS, creating a new defun each time.
|
||
(while versions
|
||
(setq version (car versions)
|
||
versions (cdr versions))
|
||
(if (file-executable-p version)
|
||
(progn
|
||
(setq beg (point))
|
||
(setq version-function-name (concat (file-name-nondirectory version) x64))
|
||
(prin1 (symbol-function 'Sqpe+template) eval-buf)
|
||
(insert "\n\n")
|
||
(goto-char beg)
|
||
(while (search-forward "lambda" nil t 1)
|
||
(replace-match
|
||
(concat "defun " version-function-name)
|
||
t t))
|
||
(while (search-forward "ess-SHOME" nil t)
|
||
(replace-match version t t))
|
||
(goto-char (point-max))
|
||
(setq ess-sqpe-versions-created
|
||
(cons version-function-name
|
||
ess-sqpe-versions-created))
|
||
(ess-write-to-dribble-buffer
|
||
(format
|
||
"(Sqpe): ess-sqpe-versions-create making M-x defun %s for %s \n"
|
||
version-function-name version))
|
||
)))
|
||
;; buffer has now been created with defuns, so eval them!
|
||
(eval-buffer)
|
||
(kill-buffer eval-buf))
|
||
ess-sqpe-versions-created))
|
||
|
||
;; template function used by ess-sqpe-versions-create
|
||
(defun Sqpe+template (&optional proc-name)
|
||
"Call 'Sqpe' from 'S-PLUS for Windows ess-SHOME',
|
||
the 'Real Thing' from StatSci.
|
||
This function was generated by `ess-sqpe-versions-create'."
|
||
(interactive)
|
||
(setq ess-customize-alist Sqpe+-customize-alist)
|
||
(let* ((use-dialog-box) ;; MS dialog box won't return a directory
|
||
(shome-old (getenv "SHOME"))
|
||
(inferior-Sqpe+-SHOME-name "ess-SHOME")
|
||
(inferior-Sqpe+-program-name (concat "ess-SHOME" "/cmd/sqpe.exe")))
|
||
(setenv "SHOME" "ess-SHOME")
|
||
(ess-write-to-dribble-buffer
|
||
(format "\n(Sqpe+template): ess-dialect=%s, buf=%s\n" ess-dialect
|
||
(current-buffer)))
|
||
(setq ess-customize-alist ; change inferior-ess-primary-prompt
|
||
(append ess-customize-alist
|
||
'((inferior-ess-primary-prompt . "^"))))
|
||
(inferior-ess)
|
||
(setq ess-customize-alist Sqpe+-customize-alist) ; restore i-e-p-p in alist
|
||
(ess-setq-vars-local ess-customize-alist) ; restore i-e-p-p in buffer
|
||
(setq inferior-ess-prompt ; define with correct i-e-p-p
|
||
;; Do not anchor to bol with `^' ; (copied from ess-inf.el)
|
||
(concat "\\("
|
||
inferior-ess-primary-prompt
|
||
"\\|"
|
||
inferior-ess-secondary-prompt
|
||
"\\)"))
|
||
(setq comint-prompt-regexp (concat "^" inferior-ess-prompt))
|
||
; define with correct i-e-p-p
|
||
(setq comint-input-sender 'inferior-ess-input-sender)
|
||
(add-hook 'comint-output-filter-functions 'shell-strip-ctrl-m nil t)
|
||
(goto-char (point-max))
|
||
(insert "options(interactive=TRUE)")
|
||
(inferior-ess-send-input)
|
||
(setq mode-name "iESS(Sqpe)")
|
||
;; (ess-eval-linewise inferior-S+-editor-pager-command)
|
||
(if inferior-ess-language-start
|
||
(ess-eval-linewise inferior-ess-language-start))
|
||
(setenv "SHOME" shome-old)))
|
||
|
||
|
||
; Provide package
|
||
|
||
(provide 'ess-sp6w-d)
|
||
|
||
; Local variables section
|
||
|
||
;;; This file is automatically placed in Outline minor mode.
|
||
;;; The file is structured as follows:
|
||
;;; Chapters: ^L ;
|
||
;;; Sections: ;;*;;
|
||
;;; Subsections: ;;;*;;;
|
||
;;; Components: defuns, defvars, defconsts
|
||
;;; Random code beginning with a ;;;;* comment
|
||
|
||
;;; Local variables:
|
||
;;; mode: emacs-lisp
|
||
;;; outline-minor-mode: nil
|
||
;;; mode: outline-minor
|
||
;;; outline-regexp: "\^L\\|\\`;\\|;;\\*\\|;;;\\*\\|(def[cvu]\\|(setq\\|;;;;\\*"
|
||
;;; End:
|
||
|
||
;;; ess-sp6w-d.el ends here
|