*** empty log message ***
[ess.git] / lisp / essdsp6w.el
blobcb6f77a8558f4cee2c12bb96aea02055b7771201
1 ;;; essdsp6w.el --- S-PLUS 6.x for Windows customization
3 ;;; copied and edited from essd-sp4.el - Richard M. Heiberger, April 2001
5 ;; Copyright (C) 2001 Richard M. Heiberger <rmh@sbm.temple.edu>
6 ;; Copyright (C) 2002--2004 A.J. Rossini, Rich M. Heiberger, Martin
7 ;; Maechler, Kurt Hornik, Rodney Sparapani, and Stephen Eglen.
9 ;; Original Author: Richard M. Heiberger <rmh@sbm.temple.edu>
10 ;; Created: April 2001
11 ;; Maintainers: ESS-core <ESS-core@stat.math.ethz.ch>
13 ;; Keywords: start up, configuration.
15 ;; This file is part of ESS.
17 ;; This file is free software; you can redistribute it and/or modify
18 ;; it under the terms of the GNU General Public License as published by
19 ;; the Free Software Foundation; either version 2, or (at your option)
20 ;; any later version.
22 ;; This file is distributed in the hope that it will be useful,
23 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
24 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 ;; GNU General Public License for more details.
27 ;; You should have received a copy of the GNU General Public License
28 ;; along with GNU Emacs; see the file COPYING. If not, write to
29 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
31 ;;; Commentary:
32 ;;;
33 ;;; This file defines all the S-PLUS 6.x for Windows customizations
34 ;;; for ess-mode with ddeclient.
36 ;;; Requires and Autoloads:
38 (require 'essl-s)
39 (require 'ess-iw32)
41 (autoload 'inferior-ess "ess-inf" "Run an ESS process.")
42 (autoload 'ess-mode "ess-mode" "Edit an ESS process.")
44 ;;; Code:
46 (defvar S+6-dialect-name "S+6"
47 "Name of 'dialect' for S-PLUS 6.x.
48 Easily changeable in a user's `.emacs'.")
50 (defvar inferior-S+6-start-args " "
51 "Default is empty. Can be used for license manager information, for example
52 `(setq inferior-S+6-start-args \" S_ELMHOST=\\\\\\\\@123.456.789.012 ELMTIMEOUT=60 \")'."
53 ;; (setq inferior-S+6-start-args " S_ELMHOST=\\\\@123.456.789.012 ELMTIMEOUT=60 ") ;; use this line as the model for your site-start.el
56 (defvar inferior-Sqpe-start-args " "
57 "Default is empty. Can be used for license manager information, for example
58 `(setq inferior-Sqpe-start-args \" S_ELMHOST=@123.456.789.012 ELMTIMEOUT=60 \")'."
59 ;; (setq inferior-Sqpe-start-args " S_ELMHOST=@123.456.789.012 ELMTIMEOUT=60 ") ;; use this line as the model for your site-start.el
62 (defvar inferior-S+6-multipleinstances "/MULTIPLEINSTANCES"
63 "Default \"/MULTIPLEINSTANCES\" opens up a new instance of S+6 in a
64 GUI window and connects it to the '(ddeESS [S+6])' window. The
65 alternative nil uses an existing S+6 GUI (if there is one) and
66 connects it to the '(ddeESS [S+6])' window.")
68 (defvar S+6-customize-alist
69 '((ess-local-customize-alist . 'S+6-customize-alist)
70 (ess-language . "S")
71 (ess-dialect . S+6-dialect-name)
72 (ess-suffix . "S")
73 (ess-mode-editing-alist . S-editing-alist)
74 (ess-mode-syntax-table . S-syntax-table)
75 (ess-help-sec-regex . ess-help-S+-sec-regex)
76 (ess-help-sec-keys-alist . S+-help-sec-keys-alist)
77 (ess-loop-timeout . ess-S-loop-timeout)
78 (ess-object-name-db-file . "ess-sp6-namedb.el" )
79 (ess-retr-lastvalue-command
80 . ".Last.value <- get(\".ess.lvsave\",frame=0)\n")
81 (ess-save-lastvalue-command
82 . "assign(\".ess.lvsave\",.Last.value,frame=0)\n")
83 (inferior-ess-program . inferior-S+6-program-name)
84 ;; (inferior-ess-ddeclient . "ddeclient")
85 ;; (inferior-ess-client-name . "S-PLUS")
86 ;; (inferior-ess-client-command . "SCommand")
87 (inferior-ess-objects-command . "objects(%d)\n")
88 (inferior-ess-help-command . "help(\"%s\")\n")
89 (inferior-ess-exit-command . "q()\n")
90 (inferior-ess-primary-prompt . "[a-zA-Z0-9() ]*> ?")
91 (inferior-ess-secondary-prompt . "+ ?")
92 (comint-use-prompt-regexp-instead-of-fields . t) ;; emacs 21 and up
93 (inferior-ess-start-file . nil) ;"~/.ess-S+6")
94 (inferior-ess-start-args . (concat
95 inferior-S+6-multipleinstances
96 " "
97 inferior-S+6-start-args
98 " "
99 inferior-S+6-print-command
100 " S_PROJ="
101 (directory-file-name default-directory))
103 (ess-STERM . "ddeESS")
104 (ess-editor . S-editor)
105 (ess-pager . S-pager)
106 (inferior-ess-language-start . (eval inferior-S-language-start))
108 "Variables to customize for S+6")
111 (defvar Sqpe+6-customize-alist
112 '((ess-local-customize-alist . 'Sqpe+6-customize-alist)
113 (ess-language . "S")
114 (ess-dialect . S+6-dialect-name)
115 (ess-suffix . "S")
116 (ess-mode-editing-alist . S-editing-alist)
117 (ess-mode-syntax-table . S-syntax-table)
118 (ess-help-sec-regex . ess-help-S+-sec-regex)
119 (ess-help-sec-keys-alist . S+-help-sec-keys-alist)
120 (ess-loop-timeout . 500000 )
121 (ess-object-name-db-file . "ess-sp6-namedb.el" )
122 (ess-retr-lastvalue-command
123 . ".Last.value <- get(\".ess.lvsave\",frame=0)\n")
124 (ess-save-lastvalue-command
125 . "assign(\".ess.lvsave\",.Last.value,frame=0)\n")
126 (inferior-ess-program . inferior-Sqpe+6-program-name)
127 (inferior-ess-objects-command . "objects(%d)\n")
128 (inferior-ess-help-command . "help(\"%s\")\n")
129 (inferior-ess-exit-command . "q()\n")
130 (inferior-ess-primary-prompt . "[a-zA-Z0-9() ]*> ?")
131 (inferior-ess-secondary-prompt . "+ ?")
132 (comint-use-prompt-regexp-instead-of-fields . t) ;; emacs 21 and up
133 (inferior-ess-start-file . nil) ;"~/.ess-S+6")
134 (inferior-ess-start-args . (concat
135 "ALWAYS_PROMPT=X" ;;workaround for bug in S-Plus 6 for Windows
137 inferior-Sqpe-start-args ;; license manager for example
139 (ess-STERM . "iESS")
140 (ess-editor . S-editor)
141 (ess-pager . S-pager)
142 (inferior-ess-language-start . (eval inferior-S-language-start))
144 "Variables to customize for Sqpe+6.")
148 ;;; There are extra complications in S+6 (compared to S+3) because
150 ;;; (1) The StatSci supplied Splus.exe doesn't work in an emacs
151 ;;; buffer. It works as as a GUI window and we must send commands
152 ;;; to it through ddeclient. Nonetheless, we need to give it a
153 ;;; process name and be sure that that there is a valid running
154 ;;; process in the '(ddeESS [S+6])' buffer. Therefore we create an
155 ;;; ESS process in the buffer as a placeholder and start a shell
156 ;;; in the ESS buffer. From the shell we start Splus. Once Splus
157 ;;; finishes initializing and kills the original shell, we start
158 ;;; another shell. We have a buffer-local variable
159 ;;; inferior-ess-ddeclient, initialized to nil. When there is a
160 ;;; non-nil value of inferior-ess-ddeclient we send lines to
161 ;;; inferior-ess-ddeclient rather than to the Splus process.
162 ;;; (2) There is no Splus process running in the '(ddeESS [S+6])'
163 ;;; buffer. Therefore inferior-ess will never see a prompt,
164 ;;; unless we first change it to the null prompt "^". Then once
165 ;;; the process has started, we change it back.
166 ;;; (3) When M-x S+6 starts Splus by a shell command, then Splus is an
167 ;;; independent process and will be survive if the '(ddeESS [S+6])'
168 ;;; buffer is killed (or emacs is quit). The '(ddeESS [S+6])' is
169 ;;; made read-only and a warning is placed in it saying that "You
170 ;;; can't type anything here." Actually, if thestandalone Splus
171 ;;; is killed and the '(ddeESS [S+6])' is made writable (C-x C-q),
172 ;;; then '(ddeESS [S+6])' becomes a shell buffer.
174 (defun S+6 (&optional proc-name)
175 "Verify that `inferior-S+6-program-name' points to S-Plus 6.
176 Start normally for S-Plus 6.1. Inform the user to start S-Plus 6.0
177 from the icon and then connect to it with `S+6-existing'. Give an error
178 message if `inferior-S+6-program-name' doesn't point to S-Plus 6."
179 (interactive)
180 (save-excursion
181 (set-buffer (find-file-noselect
182 (concat (executable-find inferior-S+6-program-name)
183 "/../../versions") t))
184 (toggle-read-only 1)
185 (forward-line)
186 (if (not (search-backward-regexp "6.[1-9]" (point-min) t))
187 (if (search-backward "6.0" (point-min) t)
188 (error "S-Plus 6.0 for Microsoft Windows has a bug that
189 prevents it from being started by emacs. Instead, you must start it
190 by double-clicking an icon. Then you can connect to it with
191 `S+6-existing'. You should consider upgrading to S-Plus 6.1 or higher.")
192 (error "The emacs variable `inferior-S+6-program-name' does
193 not point to S-Plus 6. Please add `splus6?/cmd'
194 (expand the `?' to match your setup) to your `exec-path' or
195 specify the complete path to `Splus.exe' in the variable
196 `inferior-S+6-program-name' in your `.emacs' file."))))
197 (S+6-initiate proc-name)) ;; normal start
199 (defun S+6-initiate (&optional proc-name)
200 "Call 'S-PLUS 6.x for Windows', the 'GUI Thing' from StatSci. Put
201 S-Plus in an independent MS-Window (Splus persists even if the
202 '(ddeESS [S+6])' window is killed in emacs). Do this by creating a
203 comint process that calls sh. Send a shell command in that sh buffer
204 to call Splus. When it completes set up a shell as a placeholder in
205 the '(ddeESS [S+6])' buffer. The S-Plus options are correctly set.
206 In particular, the S-Plus Commands window is opened if the
207 Options/General Settings/Startup menu says it should be. There is a
208 startup delay of `ess-S+6-startup-delay' seconds during which the
209 screen will not be refreshed. This delay is here to allow slow disks
210 to start the Splus program."
211 (interactive)
212 (save-excursion
213 (setq ess-customize-alist S+6-customize-alist)
214 (ess-write-to-dribble-buffer
215 (format "\n(S+6): ess-dialect=%s, buf=%s\n" ess-dialect
216 (current-buffer)))
217 (setq ess-customize-alist ; change inferior-ess-program
218 (append ess-customize-alist '((inferior-ess-program . "sh"))))
219 (setq ess-customize-alist ; change inferior-ess-primary-prompt
220 (append ess-customize-alist '((inferior-ess-primary-prompt . "^"))))
221 (setq ess-customize-alist ; change inferior-ess-start-args
222 (append ess-customize-alist '((inferior-ess-start-args . "-i"))))
223 (let ((s-proj (getenv "S_PROJ")))
224 (cd (w32-short-file-name (directory-file-name default-directory)))
225 (setenv "S_PROJ" default-directory)
226 (inferior-ess)
227 (sleep-for 2) ; need to wait, else working too fast! The Splus
228 ; command in '(ddeESS [S+6])' should follow the "$"
229 ; prompt. If not, then increase the sleep-for time!
230 (setenv "S_PROJ" s-proj))
231 (setq ess-customize-alist S+6-customize-alist)
232 (ess-setq-vars-local ess-customize-alist)
233 ;;; the next three lines belong in customize-alist, but can't be there
234 ;;; because of the broken ess-setq-vars-default usage in ess-inf.el
235 (setq inferior-ess-ddeclient "ddeclient")
236 (setq inferior-ess-client-name "S-PLUS")
237 (setq inferior-ess-client-command "SCommand")
238 ;;; end of what belongs in customize-alist
239 (setq comint-process-echoes nil)
240 (setq comint-input-sender 'comint-simple-send)
241 (goto-char (point-max))
242 (insert (concat inferior-S+6-program-name " "
243 inferior-ess-start-args)) ; Note: there is no final "&".
244 ;; Without the "&", the results of !system.command come to '(ddeESS [S+6])'
245 ;; With the "&", the results of !system.command in S get lost.
246 (inferior-ess-send-input)
247 (sleep-for ess-S+6-startup-delay) ; Need to wait, else working too fast!
248 ; If the ess-current-process-name doesn't appear in the
249 ; Splus Commands window increase the sleep-for time!
250 (setq ess-local-process-name ess-current-process-name)
251 (ess-eval-linewise (concat "#" ess-current-process-name))
252 (beginning-of-buffer)
253 (insert
254 "This is a placeholder buffer. You can't type anything here.
255 Use `C-x b RET' to return to your file.\n
256 Anything sent to this process from an S-mode buffer goes
257 directly to the associated Splus Commands window.\n
258 The S-Plus Commands window must be visible.
259 You may need to open the S-Plus Commands window manually (by clicking on
260 Splus/Window/Commands Window).\n
261 Any results of the !system.command typed at the S prompt in the
262 Splus Commands window appear in this buffer.\n\n")
263 (goto-char (point-max)) ; comint-mode-map makes '(ddeESS [S+6])'
264 ;; (use-local-map comint-mode-map) ;a shell buffer after Splus is finished.
265 (set-buffer-process-coding-system 'raw-text-dos 'raw-text-unix)
266 (toggle-read-only t) ; force buffer to be read-only
267 (setq mode-name "ddeESS")
268 ;; (ess-eval-linewise inferior-S+6-editor-pager-command)
269 (if inferior-ess-language-start
270 (ess-eval-linewise inferior-ess-language-start))
276 (defun S+6-existing (&optional proc-name)
277 "Call 'S-PLUS 6.x for Windows', the 'GUI Thing' from StatSci. Do so by
278 finding an existing S-Plus in an independent MS-Window (if there is one) and
279 set up a '(ddeESS [S+6])' buffer in emacs. If there is no existing
280 S-Plus, then a new one will be opened in the default directory,
281 usually something like c:/Program Files/spls45se/users/yourname.
282 If you have a HOME environment variable, it will open it there."
283 (interactive)
284 (let* ((inferior-S+6-multipleinstances " & # ") ; Note: there is a final "&".
285 (ess-S+6-startup-delay 0)) ;; No delay for existing S-Plus
286 ;; Without the "&", there is a core dump.
287 ;; With the "&", the results of !system.command in S get lost.
288 ;; We are picking up an existing S-Plus process for sending to.
289 ;; It doesn't know about us, so nothing comes back.
290 (S+6-initiate proc-name))
291 (save-excursion
292 (set-buffer (car (buffer-list))) ; get the ESS buffer just created
293 (toggle-read-only nil) ; permit writing in ESS buffer
294 (goto-char (point-max))
295 (beginning-of-line)
296 (forward-line -1)
297 (insert
298 "This is S+6-existing.
299 Results of the !system.command typed at the S prompt in the
300 Splus Commands window blink a DOS window and you won't see them.\n\n")
301 (toggle-read-only t) ; restore ESS buffer to be read-only
305 ;;; There are extra complications in Sqpe+6 (compared to S+3) because
306 ;;; (1) The StatSci supplied Sqpe.exe won't work without SHOME as an
307 ;;; environment variable and Sqpe does not take command line
308 ;;; arguments and
309 ;;; (2) Sqpe.exe comes up with options(interactive=F), which means it
310 ;;; doesn't provide prompts by default, and we must change it to T so
311 ;;; it will provide prompts.
313 (defun Sqpe+6 (&optional proc-name)
314 "Call 'Sqpe' from 'S-PLUS 6.x for Windows', the 'Real Thing' from StatSci."
315 (interactive)
316 (setq ess-customize-alist Sqpe+6-customize-alist)
317 (let* ((shome-nil-p (equal (getenv "SHOME") nil)))
318 (if shome-nil-p (setenv "SHOME" inferior-Sqpe+6-SHOME-name))
319 (ess-write-to-dribble-buffer
320 (format "\n(Sqpe+6): ess-dialect=%s, buf=%s\n" ess-dialect
321 (current-buffer)))
322 (setq ess-customize-alist ; change inferior-ess-primary-prompt
323 (append ess-customize-alist '((inferior-ess-primary-prompt . "^"))))
324 (inferior-ess)
325 (setq ess-customize-alist Sqpe+6-customize-alist) ; restore i-e-p-p in alist
326 (ess-setq-vars-local ess-customize-alist) ; restore i-e-p-p in buffer
327 (setq inferior-ess-prompt ; define with correct i-e-p-p
328 ;; Do not anchor to bol with `^' ; (copied from ess-inf.el)
329 (concat "\\("
330 inferior-ess-primary-prompt
331 "\\|"
332 inferior-ess-secondary-prompt
333 "\\)"))
334 (setq comint-prompt-regexp (concat "^" inferior-ess-prompt))
335 ; define with correct i-e-p-p
336 (setq comint-input-sender 'inferior-ess-input-sender)
337 (add-hook 'comint-output-filter-functions 'shell-strip-ctrl-m nil t)
338 (goto-char (point-max))
339 (insert "options(interactive=T)")
340 (inferior-ess-send-input)
341 (setq mode-name "iESS(Sqpe)")
342 ;; (ess-eval-linewise inferior-S+6-editor-pager-command)
343 (if inferior-ess-language-start
344 (ess-eval-linewise inferior-ess-language-start))
345 (if shome-nil-p (setenv "SHOME" nil))))
349 (defun S+6-mode (&optional proc-name)
350 "Major mode for editing S+6 source. See `ess-mode' for more help."
351 (interactive)
352 (setq ess-customize-alist S+6-customize-alist)
353 (ess-mode S+6-customize-alist proc-name)
354 (if ess-imenu-use-S (ess-imenu-R)))
357 (defun S+6-transcript-mode ()
358 "S-PLUS 6.x transcript mode."
359 (interactive)
360 (ess-transcript-mode S+6-customize-alist))
363 (defun S+6-msdos (&optional proc-name)
364 "Verify that `inferior-S+6-program-name' points to S-Plus 6.
365 Start normally for S-Plus 6.1. Inform the user to start S-Plus 6.0
366 from the icon and then connect to it with `S+6-msdos-existing'. Give an error
367 message if `inferior-S+6-program-name' doesn't point to S-Plus 6."
368 (interactive)
369 (save-excursion
370 (set-buffer (find-file-noselect
371 (concat (executable-find inferior-S+6-program-name)
372 "/../../versions") t))
373 (toggle-read-only 1)
374 (forward-line)
375 (if (not (search-backward-regexp "6.[1-9]" (point-min) t))
376 (if (search-backward "6.0" (point-min) t)
377 (error "S-Plus 6.0 for Microsoft Windows has a bug that
378 prevents it from being started by emacs. Instead, you must start it
379 by double-clicking an icon. Then you can connect to it with
380 `S+6-msdos-existing'. You should consider upgrading to S-Plus 6.1 or higher.")
381 (error "The emacs variable `inferior-S+6-program-name' does
382 not point to S-Plus 6. Please add `splus6?/cmd'
383 (expand the `?' to match your setup) to your `exec-path' or
384 specify the complete path to `Splus.exe' in the variable
385 `inferior-S+6-program-name' in your `.emacs' file."))))
386 (S+6-msdos-initiate proc-name)) ;; normal start
389 (defun S+6-msdos-initiate (&optional proc-name)
390 "Call 'S-PLUS 6.x for Windows', the 'GUI Thing' from StatSci. Put
391 S-Plus in an independent MS-Window (Splus persists even if the
392 '(ddeESS [S+6])' window is killed in emacs). Do this by creating a
393 comint process that calls sh. Send a shell command in that sh buffer
394 to call Splus. When it completes set up a shell as a placeholder in
395 the '(ddeESS [S+6])' buffer. The S-Plus options are correctly set.
396 In particular, the S-Plus Commands window is opened if the
397 Options/General Settings/Startup menu says it should be. There is a
398 startup delay of `ess-S+6-startup-delay' seconds during which the
399 screen will not be refreshed. This delay is here to allow slow disks
400 to start the Splus program."
401 (interactive)
402 (save-excursion
403 (setq ess-customize-alist S+6-customize-alist)
404 (ess-write-to-dribble-buffer
405 (format "\n(S+6): ess-dialect=%s, buf=%s\n" ess-dialect
406 (current-buffer)))
407 (setq ess-customize-alist ; change inferior-ess-program
408 (append ess-customize-alist '((inferior-ess-program
409 . (getenv "COMSPEC")))))
410 (setq ess-customize-alist ; change inferior-ess-primary-prompt
411 (append ess-customize-alist '((inferior-ess-primary-prompt . "^"))))
412 (setq ess-customize-alist ; change inferior-ess-start-args
413 (append ess-customize-alist '((inferior-ess-start-args . ""))))
414 (let ((s-proj (getenv "S_PROJ")))
415 (cd (w32-short-file-name (directory-file-name default-directory)))
416 (setenv "S_PROJ" default-directory)
417 (inferior-ess)
418 (sleep-for 2) ; need to wait, else working too fast! The Splus
419 ; command in '(ddeESS [S+6])' should follow the "$"
420 ; prompt. If not, then increase the sleep-for time!
421 (setenv "S_PROJ" s-proj))
422 (setq ess-customize-alist S+6-customize-alist)
423 (ess-setq-vars-local ess-customize-alist)
424 ;;; the next three lines belong in customize-alist, but can't be there
425 ;;; because of the broken ess-setq-vars-default usage in ess-inf.el
426 (setq inferior-ess-ddeclient "ddeclient")
427 (setq inferior-ess-client-name "S-PLUS")
428 (setq inferior-ess-client-command "SCommand")
429 ;;; end of what belongs in customize-alist
430 (setq comint-input-sender 'comint-simple-send)
431 (setq comint-process-echoes nil)
432 (set-buffer-process-coding-system 'raw-text-dos 'raw-text-dos)
433 (goto-char (point-max))
434 (insert (concat inferior-S+6-program-name " "
435 inferior-ess-start-args)) ; Note: there is no final "&".
436 ;; Without the "&", the results of !system.command come to '(ddeESS [S+6])'
437 ;; With the "&", the results of !system.command in S get lost.
438 (inferior-ess-send-input)
439 (sleep-for ess-S+6-startup-delay) ; Need to wait, else working too fast!
440 ; If the ess-current-process-name doesn't appear in the
441 ; Splus Commands window increase the sleep-for time!
442 ;;; from msdos-minor-mode
443 (setq comint-process-echoes t)
444 (add-hook 'comint-output-filter-functions 'shell-strip-ctrl-m nil t)
445 ;;; end from msdos-minor-mode
446 (setq ess-local-process-name ess-current-process-name)
447 (ess-eval-linewise (concat "#" ess-current-process-name))
448 (beginning-of-buffer)
449 (insert
450 "This is a placeholder buffer. You can't type anything here.
451 Use `C-x b RET' to return to your file.\n
452 Anything sent to this process from an S-mode buffer goes
453 directly to the associated Splus Commands window.\n
454 The S-Plus Commands window must be visible.
455 You may need to open the S-Plus Commands window manually
456 (by clicking on Splus/Window/Commands Window).\n
457 There is a `ess-S+6-startup-delay' second delay when this program starts
458 during which the emacs screen will be partially blank.\n
459 Remember to 'q()' from S-Plus and
460 then C-x C-q exit from the '(ddeESS [S+6])' buffer,
461 or take the risk of not being able to shut down your computer
462 and suffering through scandisk.\n
463 Any results of the !system.command typed at the S prompt in the
464 Splus Commands window (are supposed to) appear in this buffer.\n\n")
465 (goto-char (point-max)) ; comint-mode-map makes '(ddeESS [S+6])'
466 (use-local-map comint-mode-map) ; a shell buffer after Splus is finished.
467 (toggle-read-only t) ; force buffer to be read-only
468 (setq mode-name "ddeESS")
469 ;; (ess-eval-linewise inferior-S+6-editor-pager-command)
470 (if inferior-ess-language-start
471 (ess-eval-linewise inferior-ess-language-start))
474 (defun S+6-msdos-existing (&optional proc-name)
475 "Call 'S-PLUS 6.x for Windows', the 'GUI Thing' from StatSci. Do so by
476 finding an existing S-Plus in an independent MS-Window (if there is one) and
477 set up a '(ddeESS [S+6])' buffer in emacs. If there is no existing
478 S-Plus, then a new one will be opened in the default directory,
479 usually something like c:/Program Files/spls45se/users/yourname.
480 If you have a HOME environment variable, it will open it there."
481 (interactive)
482 (let* ((inferior-S+6-multipleinstances "")
483 (ess-S+6-startup-delay 0)) ;; No delay for existing S-Plus
484 (S+6-msdos-initiate proc-name))
485 (save-excursion
486 (set-buffer (car (buffer-list))) ; get the ESS buffer just created
487 (toggle-read-only nil) ; permit writing in ESS buffer
488 (goto-char (point-max))
489 (beginning-of-line)
490 (forward-line -1)
491 (insert
492 "This is S+6-msdos-existing.
493 Results of the !system.command typed at the S prompt in the
494 Splus Commands window blink a DOS window and you won't see them.\n\n")
495 (toggle-read-only t) ; restore ESS buffer to be read-only
498 (defun ess-sqpe-versions-create ()
499 "Generate the `M-x splusxy' functions for starting other versions of
500 Sqpe. See `ess-sqpe-versions' for strings that determine which
501 functions are created. This works by creating a temp buffer where the
502 template function `Sqpe+template' is edited by replacing the string
503 'Sqpe+template' by the version name. The list of functions actually
504 created appears in the *ESS* buffer.
506 The result `ess-sqpe-versions-created' will store a list of the new
507 Sqpe defuns, if any, that were created. The defuns will normally be
508 placed on the menubar upon ESS initialisation."
509 (let ((beg)
510 (versions)
511 (version)
512 (eval-buf (get-buffer-create "*ess-temp-sqpe-evals*"))
513 (ess-sqpe-versions-created)
516 (save-excursion
517 (set-buffer eval-buf)
518 ;; clear the buffer.
519 (delete-region (point-min) (point-max))
521 ;; Find which versions of Sqpe we want.
522 (setq versions (ess-uniq-list ess-SHOME-versions))
523 ;; Iterate over each string in VERSIONS, creating a new defun each time.
524 (while versions
525 (setq version (car versions)
526 versions (cdr versions))
527 (if (file-executable-p version)
528 (progn
529 (setq beg (point))
530 (prin1 (symbol-function 'Sqpe+template) eval-buf)
531 (insert "\n\n")
532 (goto-char beg)
533 (while (search-forward "lambda" nil t 1)
534 (replace-match
535 (concat "defun " (file-name-nondirectory version))
536 t t))
537 (while (search-forward "ess-SHOME" nil t)
538 (replace-match version t t))
539 (goto-char (point-max))
540 (setq ess-sqpe-versions-created
541 (cons (file-name-nondirectory version)
542 ess-sqpe-versions-created))
543 (ess-write-to-dribble-buffer
544 (format
545 "(Sqpe): ess-sqpe-versions-create making M-x defun %s for %s \n"
546 (file-name-nondirectory version) version))
548 ;; buffer has now been created with defuns, so eval them!
549 (eval-buffer)
550 (kill-buffer eval-buf))
551 ess-sqpe-versions-created))
553 ;; template function used by ess-sqpe-versions-create
554 (defun Sqpe+template (&optional proc-name)
555 "Call 'Sqpe' from 'S-PLUS for Windows ess-SHOME',
556 the 'Real Thing' from StatSci.
557 This function was generated by `ess-sqpe-versions-create'."
558 (interactive)
559 (setq ess-customize-alist Sqpe+6-customize-alist)
560 (let* ((shome-old (getenv "SHOME"))
561 (inferior-Sqpe+6-SHOME-name "ess-SHOME")
562 (inferior-Sqpe+6-program-name (concat "ess-SHOME" "/cmd/sqpe.exe")))
563 (setenv "SHOME" "ess-SHOME")
564 (ess-write-to-dribble-buffer
565 (format "\n(Sqpe+template): ess-dialect=%s, buf=%s\n" ess-dialect
566 (current-buffer)))
567 (setq ess-customize-alist ; change inferior-ess-primary-prompt
568 (append ess-customize-alist
569 '((inferior-ess-primary-prompt . "^"))))
570 (inferior-ess)
571 (setq ess-customize-alist Sqpe+6-customize-alist) ; restore i-e-p-p in alist
572 (ess-setq-vars-local ess-customize-alist) ; restore i-e-p-p in buffer
573 (setq inferior-ess-prompt ; define with correct i-e-p-p
574 ;; Do not anchor to bol with `^' ; (copied from ess-inf.el)
575 (concat "\\("
576 inferior-ess-primary-prompt
577 "\\|"
578 inferior-ess-secondary-prompt
579 "\\)"))
580 (setq comint-prompt-regexp (concat "^" inferior-ess-prompt))
581 ; define with correct i-e-p-p
582 (setq comint-input-sender 'inferior-ess-input-sender)
583 (add-hook 'comint-output-filter-functions 'shell-strip-ctrl-m nil t)
584 (goto-char (point-max))
585 (insert "options(interactive=T)")
586 (inferior-ess-send-input)
587 (setq mode-name "iESS(Sqpe)")
588 ;; (ess-eval-linewise inferior-S+6-editor-pager-command)
589 (if inferior-ess-language-start
590 (ess-eval-linewise inferior-ess-language-start))
591 (setenv "SHOME" shome-old)))
594 \f ; Provide package
596 (provide 'essdsp6w)
598 \f ; Local variables section
600 ;;; This file is automatically placed in Outline minor mode.
601 ;;; The file is structured as follows:
602 ;;; Chapters: ^L ;
603 ;;; Sections: ;;*;;
604 ;;; Subsections: ;;;*;;;
605 ;;; Components: defuns, defvars, defconsts
606 ;;; Random code beginning with a ;;;;* comment
608 ;;; Local variables:
609 ;;; mode: emacs-lisp
610 ;;; outline-minor-mode: nil
611 ;;; mode: outline-minor
612 ;;; outline-regexp: "\^L\\|\\`;\\|;;\\*\\|;;;\\*\\|(def[cvu]\\|(setq\\|;;;;\\*"
613 ;;; End:
615 ;;; essdsp6w.el ends here