(ess-r-args-get): Do not use zap-to-char within defun,
[ess.git] / lisp / essd-sp6w.el
bloba68bc1d5b2f86a368eb9eb1aa1655da8adb177d4
1 ;;; essd-sp6w.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--2005 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 ;;NO: this is autoloaded from other places (require 'ess-dde)
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+[678] 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 (append
70 '((ess-local-customize-alist . 'S+6-customize-alist)
71 (ess-dialect . S+6-dialect-name)
72 (ess-loop-timeout . ess-S-loop-timeout);fixme: dialect spec.
73 (ess-object-name-db-file . "ess-sp6-namedb.el" )
74 (inferior-ess-program . inferior-S+6-program-name)
75 (inferior-ess-help-command . "help(\"%s\")\n")
76 (inferior-ess-help-filetype . "chm")
77 (inferior-ess-search-list-command . "searchPaths()\n")
78 (inferior-ess-start-file . nil) ;"~/.ess-S+6")
79 (inferior-ess-start-args . (concat
80 inferior-S+6-multipleinstances
81 " "
82 inferior-S+6-start-args
83 " "
84 inferior-S+6-print-command
85 " S_PROJ="
86 (directory-file-name default-directory)))
87 ;; (inferior-ess-ddeclient . "ddeclient")
88 ;; (inferior-ess-client-name . "S-PLUS")
89 ;; (inferior-ess-client-command . "SCommand")
90 (ess-STERM . "ddeESS")
92 S+common-cust-alist)
93 "Variables to customize for S+6")
95 (defvar Sqpe+6-customize-alist
96 (append
97 '((ess-local-customize-alist . 'Sqpe+6-customize-alist)
98 (ess-dialect . S+6-dialect-name)
99 (ess-loop-timeout . 500000 );fixme: dialect specific custom.var
100 (ess-object-name-db-file . "ess-sp6-namedb.el" )
101 (inferior-ess-program . inferior-Sqpe+6-program-name)
102 (inferior-ess-help-command . "help(\"%s\")\n")
103 (inferior-ess-help-filetype . "chm")
104 (inferior-ess-search-list-command . "searchPaths()\n")
105 (inferior-ess-start-file . nil) ;"~/.ess-S+6")
106 (inferior-ess-start-args . (concat
107 ;; workaround for bug in S-Plus 6 for Windows:
108 "ALWAYS_PROMPT=X"
110 inferior-Sqpe-start-args ;; e.g. license manager
112 (ess-STERM . "iESS")
114 S+common-cust-alist)
115 "Variables to customize for Sqpe+6.")
119 ;;; There are extra complications in S+6 and S+7 and S+8 (compared to S+3)
120 ;;; because
122 ;;; (1) The StatSci supplied Splus.exe doesn't work in an emacs
123 ;;; buffer. It works as as a GUI window and we must send commands
124 ;;; to it through ddeclient. Nonetheless, we need to give it a
125 ;;; process name and be sure that that there is a valid running
126 ;;; process in the '(ddeESS [S+6])' buffer. Therefore we create an
127 ;;; ESS process in the buffer as a placeholder and start a shell
128 ;;; in the ESS buffer. From the shell we start Splus. Once Splus
129 ;;; finishes initializing and kills the original shell, we start
130 ;;; another shell. We have a buffer-local variable
131 ;;; inferior-ess-ddeclient, initialized to nil. When there is a
132 ;;; non-nil value of inferior-ess-ddeclient we send lines to
133 ;;; inferior-ess-ddeclient rather than to the Splus process.
134 ;;; (2) There is no Splus process running in the '(ddeESS [S+6])'
135 ;;; buffer. Therefore inferior-ess will never see a prompt,
136 ;;; unless we first change it to the null prompt "^". Then once
137 ;;; the process has started, we change it back.
138 ;;; (3) When M-x S+6 starts Splus by a shell command, then Splus is an
139 ;;; independent process and will be survive if the '(ddeESS [S+6])'
140 ;;; buffer is killed (or emacs is quit). The '(ddeESS [S+6])' is
141 ;;; made read-only and a warning is placed in it saying that "You
142 ;;; can't type anything here." Actually, if thestandalone Splus
143 ;;; is killed and the '(ddeESS [S+6])' is made writable (C-x C-q),
144 ;;; then '(ddeESS [S+6])' becomes a shell buffer.
146 (defun S+6 (&optional proc-name)
147 "Verify that `inferior-S+6-program-name' points to S-Plus 6 or
148 S-Plus 7 or S-Plus 8. Start normally for S-Plus 6.1 and later.
149 Inform the user to start S-Plus 6.0 from the icon and then
150 connect to it with `S+6-existing'. Give an error message if
151 `inferior-S+6-program-name' doesn't point to S-Plus 6 or S-Plus 7
152 or S-Plus 8."
153 (interactive)
154 (save-excursion
155 (set-buffer (find-file-noselect
156 (concat (executable-find inferior-S+6-program-name)
157 "/../../versions") t))
158 (toggle-read-only 1)
159 (forward-line)
160 (if (not (search-backward-regexp "splus\t[678].[0-9]" (point-min) t))
161 (error "The emacs variable `inferior-S+6-program-name' does
162 not point to S-Plus 6 or 7 or 8. Please add `splus[678]?/cmd' (expand the
163 `[678]?' to match your setup) to your `exec-path' or specify the complete
164 path to `Splus.exe' in the variable `inferior-S+6-program-name' in your
165 `.emacs' file.")
166 (forward-line)
167 (if (search-backward "splus\t6.0" (point-min) t)
168 (error "S-Plus 6.0 for Microsoft Windows has a bug that
169 prevents it from being started by emacs. Instead, you must start it
170 by double-clicking an icon. Then you can connect to it with
171 `S+6-existing'. You should consider upgrading to S-Plus 6.1 or higher."))))
172 (S+6-initiate proc-name)) ;; normal start ;
175 (defun S+6-initiate (&optional proc-name)
176 "Call 'S-PLUS [678].x for Windows', the 'GUI Thing' from StatSci. Put
177 S-Plus in an independent MS-Window (Splus persists even if the
178 '(ddeESS [S+6])' window is killed in emacs). Do this by creating a
179 comint process that calls sh. Send a shell command in that sh buffer
180 to call Splus. When it completes set up a shell as a placeholder in
181 the '(ddeESS [S+6])' buffer. The S-Plus options are correctly set.
182 In particular, the S-Plus Commands window is opened if the
183 Options/General Settings/Startup menu says it should be. There is a
184 startup delay of `ess-S+6-startup-delay' seconds during which the
185 screen will not be refreshed. This delay is here to allow slow disks
186 to start the Splus program."
187 (interactive)
188 (save-excursion
189 (setq ess-customize-alist S+6-customize-alist)
190 (ess-write-to-dribble-buffer
191 (format "\n(S+6): ess-dialect=%s, buf=%s\n" ess-dialect
192 (current-buffer)))
193 (setq ess-customize-alist ; change inferior-ess-program
194 (append ess-customize-alist '((inferior-ess-program . "sh"))))
195 (setq ess-customize-alist ; change inferior-ess-primary-prompt
196 (append ess-customize-alist '((inferior-ess-primary-prompt . "^"))))
197 (setq ess-customize-alist ; change inferior-ess-start-args
198 (append ess-customize-alist '((inferior-ess-start-args . "-i"))))
199 (let ((s-proj (getenv "S_PROJ")))
200 (cd (w32-short-file-name (directory-file-name default-directory)))
201 (setenv "S_PROJ" default-directory)
202 (inferior-ess)
203 (sleep-for 2) ; need to wait, else working too fast! The Splus
204 ; command in '(ddeESS [S+6])' should follow the "$"
205 ; prompt. If not, then increase the sleep-for time!
206 (setenv "S_PROJ" s-proj))
207 (setq ess-customize-alist S+6-customize-alist)
208 (ess-setq-vars-local ess-customize-alist)
209 ;;; the next three lines belong in customize-alist, but can't be there
210 ;;; because of the broken ess-setq-vars-default usage in ess-inf.el
211 (setq inferior-ess-ddeclient "ddeclient")
212 (setq inferior-ess-client-name "S-PLUS")
213 (setq inferior-ess-client-command "SCommand")
214 ;;; end of what belongs in customize-alist
215 (setq comint-process-echoes nil)
216 (setq comint-input-sender 'comint-simple-send)
217 (goto-char (point-max))
218 (insert (concat inferior-S+6-program-name " "
219 inferior-ess-start-args)) ; Note: there is no final "&".
220 ;; Without the "&", the results of !system.command come to '(ddeESS [S+6])'
221 ;; With the "&", the results of !system.command in S get lost.
222 (inferior-ess-send-input)
223 (sleep-for ess-S+6-startup-delay) ; Need to wait, else working too fast!
224 ; If the ess-current-process-name doesn't appear in the
225 ; Splus Commands window increase the sleep-for time!
226 (setq ess-local-process-name ess-current-process-name)
227 (ess-eval-linewise (concat "#" ess-current-process-name))
228 (goto-char (point-min))
229 (insert
230 "This is a placeholder buffer. You can't type anything here.
231 Use `C-x b RET' to return to your file.\n
232 Anything sent to this process from an S-mode buffer goes
233 directly to the associated Splus Commands window.\n
234 The S-Plus Commands window must be visible.
235 You may need to open the S-Plus Commands window manually (by clicking on
236 Splus/Window/Commands Window).\n
237 Any results of the !system.command typed at the S prompt in the
238 Splus Commands window appear in this buffer.\n\n")
239 (goto-char (point-max)) ; comint-mode-map makes '(ddeESS [S+6])'
240 ;; (use-local-map comint-mode-map) ;a shell buffer after Splus is finished.
241 (set-buffer-process-coding-system 'raw-text-dos 'raw-text-unix)
242 (toggle-read-only t) ; force buffer to be read-only
243 (setq mode-name "ddeESS")
244 ;; (ess-eval-linewise inferior-S+6-editor-pager-command)
245 (if inferior-ess-language-start
246 (ess-eval-linewise inferior-ess-language-start))
252 (defun S+6-existing (&optional proc-name)
253 "Call 'S-PLUS [678].x for Windows', the 'GUI Thing' from StatSci. Do so by
254 finding an existing S-Plus in an independent MS-Window (if there is one) and
255 set up a '(ddeESS [S+6])' buffer in emacs. If there is no existing
256 S-Plus, then a new one will be opened in the default directory,
257 usually something like c:/Program Files/Insightful/splus70/users/yourname.
258 If you have a HOME environment variable, it will open it there."
259 (interactive)
260 (let* ((inferior-S+6-multipleinstances " & # ") ; Note: there is a final "&".
261 (ess-S+6-startup-delay 0)) ;; No delay for existing S-Plus
262 ;; Without the "&", there is a core dump.
263 ;; With the "&", the results of !system.command in S get lost.
264 ;; We are picking up an existing S-Plus process for sending to.
265 ;; It doesn't know about us, so nothing comes back.
266 (S+6-initiate proc-name))
267 (save-excursion
268 (set-buffer (car (buffer-list))) ; get the ESS buffer just created
269 (toggle-read-only nil) ; permit writing in ESS buffer
270 (goto-char (point-max))
271 (beginning-of-line)
272 (forward-line -1)
273 (insert
274 "This is S+6-existing.
275 Results of the !system.command typed at the S prompt in the
276 Splus Commands window blink a DOS window and you won't see them.\n\n")
277 (toggle-read-only t) ; restore ESS buffer to be read-only
281 ;;; There are extra complications in Sqpe+6 (compared to S+3) because
282 ;;; (1) The StatSci supplied Sqpe.exe won't work without SHOME as an
283 ;;; environment variable and Sqpe does not take command line
284 ;;; arguments and
285 ;;; (2) Sqpe.exe comes up with options(interactive=F), which means it
286 ;;; doesn't provide prompts by default, and we must change it to T so
287 ;;; it will provide prompts.
289 (defun Sqpe+6 (&optional proc-name)
290 "Call 'Sqpe' from 'S-PLUS [678].x for Windows', the 'Real Thing' from StatSci."
291 (interactive)
292 (setq ess-customize-alist Sqpe+6-customize-alist)
293 (let* ((shome-nil-p (equal (getenv "SHOME") nil)))
294 (if shome-nil-p (setenv "SHOME" inferior-Sqpe+6-SHOME-name))
295 (ess-write-to-dribble-buffer
296 (format "\n(Sqpe+6): ess-dialect=%s, buf=%s\n" ess-dialect
297 (current-buffer)))
298 (setq ess-customize-alist ; change inferior-ess-primary-prompt
299 (append ess-customize-alist '((inferior-ess-primary-prompt . "^"))))
300 (inferior-ess)
301 (setq ess-customize-alist Sqpe+6-customize-alist) ; restore i-e-p-p in alist
302 (ess-setq-vars-local ess-customize-alist) ; restore i-e-p-p in buffer
303 (setq inferior-ess-prompt ; define with correct i-e-p-p
304 ;; Do not anchor to bol with `^' ; (copied from ess-inf.el)
305 (concat "\\("
306 inferior-ess-primary-prompt
307 "\\|"
308 inferior-ess-secondary-prompt
309 "\\)"))
310 (setq comint-prompt-regexp (concat "^" inferior-ess-prompt))
311 ; define with correct i-e-p-p
312 (setq comint-input-sender 'inferior-ess-input-sender)
313 (add-hook 'comint-output-filter-functions 'shell-strip-ctrl-m nil t)
314 (goto-char (point-max))
315 (insert "options(interactive=T)")
316 (inferior-ess-send-input)
317 (setq mode-name "iESS(Sqpe)")
318 ;; (ess-eval-linewise inferior-S+6-editor-pager-command)
319 (if inferior-ess-language-start
320 (ess-eval-linewise inferior-ess-language-start))
321 (if shome-nil-p (setenv "SHOME" nil))))
325 (defun S+6-mode (&optional proc-name)
326 "Major mode for editing S+[678] source. See `ess-mode' for more help."
327 (interactive)
328 (setq ess-customize-alist S+6-customize-alist)
329 (ess-mode S+6-customize-alist proc-name)
330 (if ess-imenu-use-S (ess-imenu-R)))
333 (defun S+6-transcript-mode ()
334 "S-PLUS 6.x transcript mode."
335 (interactive)
336 (ess-transcript-mode S+6-customize-alist))
339 (defun S+6-msdos (&optional proc-name)
340 "Verify that `inferior-S+6-program-name' points to S-Plus 6 or
341 S-Plus 7 or S-Plus 8. Start normally for S-Plus 6.1 and later.
342 Inform the user to start S-Plus 6.0 from the icon and then
343 connect to it with `S+6-msdos-existing'. Give an error message
344 if `inferior-S+6-program-name' doesn't point to S-Plus 6 or
345 S-Plus 7 or S-Plus 8."
346 (interactive)
347 (save-excursion
348 (set-buffer (find-file-noselect
349 (concat (executable-find inferior-S+6-program-name)
350 "/../../versions") t))
351 (toggle-read-only 1)
352 (forward-line)
353 (if (not (search-backward-regexp "splus\t[678].[0-9]" (point-min) t))
354 (error "The emacs variable `inferior-S+6-program-name' does
355 not point to S-Plus 6 or 7 or 8. Please add `splus[678]?/cmd'
356 (expand the `[678]?' to match your setup) to your `exec-path' or
357 specify the complete path to `Splus.exe' in the variable
358 `inferior-S+6-program-name' in your `.emacs' file.")
359 (progn
360 (forward-line)
361 (if (search-backward "splus\t6.0" (point-min) t)
362 (error "S-Plus 6.0 for Microsoft Windows has a bug that
363 prevents it from being started by emacs. Instead, you must start it
364 by double-clicking an icon. Then you can connect to it with
365 `S+6-msdos-existing'. You should consider upgrading to S-Plus 6.1 or higher.")
366 (S+6-msdos-initiate proc-name))) ;; normal start ;
370 (defun S+6-msdos-initiate (&optional proc-name)
371 "Call 'S-PLUS [678].x for Windows', the 'GUI Thing' from StatSci. Put
372 S-Plus in an independent MS-Window (Splus persists even if the
373 '(ddeESS [S+6])' window is killed in emacs). Do this by creating a
374 comint process that calls sh. Send a shell command in that sh buffer
375 to call Splus. When it completes set up a shell as a placeholder in
376 the '(ddeESS [S+6])' buffer. The S-Plus options are correctly set.
377 In particular, the S-Plus Commands window is opened if the
378 Options/General Settings/Startup menu says it should be. There is a
379 startup delay of `ess-S+6-startup-delay' seconds during which the
380 screen will not be refreshed. This delay is here to allow slow disks
381 to start the Splus program."
382 (interactive)
383 (save-excursion
384 (setq ess-customize-alist S+6-customize-alist)
385 (ess-write-to-dribble-buffer
386 (format "\n(S+6): ess-dialect=%s, buf=%s\n" ess-dialect
387 (current-buffer)))
388 (setq ess-customize-alist ; change inferior-ess-program
389 (append ess-customize-alist '((inferior-ess-program
390 . (getenv "COMSPEC")))))
391 (setq ess-customize-alist ; change inferior-ess-primary-prompt
392 (append ess-customize-alist '((inferior-ess-primary-prompt . "^"))))
393 (setq ess-customize-alist ; change inferior-ess-start-args
394 (append ess-customize-alist '((inferior-ess-start-args . ""))))
395 (let ((s-proj (getenv "S_PROJ")))
396 (cd (w32-short-file-name (directory-file-name default-directory)))
397 (setenv "S_PROJ" default-directory)
398 (inferior-ess)
399 (sleep-for 2) ; need to wait, else working too fast! The Splus
400 ; command in '(ddeESS [S+6])' should follow the "$"
401 ; prompt. If not, then increase the sleep-for time!
402 (setenv "S_PROJ" s-proj))
403 (setq ess-customize-alist S+6-customize-alist)
404 (ess-setq-vars-local ess-customize-alist)
405 ;;; the next three lines belong in customize-alist, but can't be there
406 ;;; because of the broken ess-setq-vars-default usage in ess-inf.el
407 (setq inferior-ess-ddeclient "ddeclient")
408 (setq inferior-ess-client-name "S-PLUS")
409 (setq inferior-ess-client-command "SCommand")
410 ;;; end of what belongs in customize-alist
411 (setq comint-input-sender 'comint-simple-send)
412 (setq comint-process-echoes nil)
413 (set-buffer-process-coding-system 'raw-text-dos 'raw-text-dos)
414 (goto-char (point-max))
415 (insert (concat inferior-S+6-program-name " "
416 inferior-ess-start-args)) ; Note: there is no final "&".
417 ;; Without the "&", the results of !system.command come to '(ddeESS [S+6])'
418 ;; With the "&", the results of !system.command in S get lost.
419 (inferior-ess-send-input)
420 (sleep-for ess-S+6-startup-delay) ; Need to wait, else working too fast!
421 ; If the ess-current-process-name doesn't appear in the
422 ; Splus Commands window increase the sleep-for time!
423 ;;; from msdos-minor-mode
424 (setq comint-process-echoes t)
425 (add-hook 'comint-output-filter-functions 'shell-strip-ctrl-m nil t)
426 ;;; end from msdos-minor-mode
427 (setq ess-local-process-name ess-current-process-name)
428 (ess-eval-linewise (concat "#" ess-current-process-name))
429 (goto-char (point-min))
430 (insert
431 "This is a placeholder buffer. You can't type anything here.
432 Use `C-x b RET' to return to your file.\n
433 Anything sent to this process from an S-mode buffer goes
434 directly to the associated Splus Commands window.\n
435 The S-Plus Commands window must be visible.
436 You may need to open the S-Plus Commands window manually
437 (by clicking on Splus/Window/Commands Window).\n
438 There is a `ess-S+6-startup-delay' second delay when this program starts
439 during which the emacs screen will be partially blank.\n
440 Remember to 'q()' from S-Plus and
441 then C-x C-q exit from the '(ddeESS [S+6])' buffer,
442 or take the risk of not being able to shut down your computer
443 and suffering through scandisk.\n
444 Any results of the !system.command typed at the S prompt in the
445 Splus Commands window (are supposed to) appear in this buffer.\n\n")
446 (goto-char (point-max)) ; comint-mode-map makes '(ddeESS [S+6])'
447 (use-local-map comint-mode-map) ; a shell buffer after Splus is finished.
448 (toggle-read-only t) ; force buffer to be read-only
449 (setq mode-name "ddeESS")
450 ;; (ess-eval-linewise inferior-S+6-editor-pager-command)
451 (if inferior-ess-language-start
452 (ess-eval-linewise inferior-ess-language-start))
455 (defun S+6-msdos-existing (&optional proc-name)
456 "Call 'S-PLUS [678].x for Windows', the 'GUI Thing' from StatSci. Do so by
457 finding an existing S-Plus in an independent MS-Window (if there is one) and
458 set up a '(ddeESS [S+6])' buffer in emacs. If there is no existing
459 S-Plus, then a new one will be opened in the default directory,
460 usually something like c:/Program Files/Insightful/splus70/users/yourname.
461 If you have a HOME environment variable, it will open it there."
462 (interactive)
463 (let* ((inferior-S+6-multipleinstances "")
464 (ess-S+6-startup-delay 0)) ;; No delay for existing S-Plus
465 (S+6-msdos-initiate proc-name))
466 (save-excursion
467 (set-buffer (car (buffer-list))) ; get the ESS buffer just created
468 (toggle-read-only nil) ; permit writing in ESS buffer
469 (goto-char (point-max))
470 (beginning-of-line)
471 (forward-line -1)
472 (insert
473 "This is S+6-msdos-existing.
474 Results of the !system.command typed at the S prompt in the
475 Splus Commands window blink a DOS window and you won't see them.\n\n")
476 (toggle-read-only t) ; restore ESS buffer to be read-only
479 (defun ess-sqpe-versions-create ()
480 "Generate the `M-x splusxy' functions for starting other versions of
481 Sqpe. See `ess-sqpe-versions' for strings that determine which
482 functions are created. This works by creating a temp buffer where the
483 template function `Sqpe+template' is edited by replacing the string
484 'Sqpe+template' by the version name. The list of functions actually
485 created appears in the *ESS* buffer.
487 The result `ess-sqpe-versions-created' will store a list of the new
488 Sqpe defuns, if any, that were created. The defuns will normally be
489 placed on the menubar upon ESS initialisation."
490 (let ((beg)
491 (versions)
492 (version)
493 (eval-buf (get-buffer-create "*ess-temp-sqpe-evals*"))
494 (ess-sqpe-versions-created)
497 (save-excursion
498 (set-buffer eval-buf)
499 ;; clear the buffer.
500 (delete-region (point-min) (point-max))
502 ;; Find which versions of Sqpe we want.
503 (setq versions (ess-uniq-list ess-SHOME-versions))
504 ;; Iterate over each string in VERSIONS, creating a new defun each time.
505 (while versions
506 (setq version (car versions)
507 versions (cdr versions))
508 (if (file-executable-p version)
509 (progn
510 (setq beg (point))
511 (prin1 (symbol-function 'Sqpe+template) eval-buf)
512 (insert "\n\n")
513 (goto-char beg)
514 (while (search-forward "lambda" nil t 1)
515 (replace-match
516 (concat "defun " (file-name-nondirectory version))
517 t t))
518 (while (search-forward "ess-SHOME" nil t)
519 (replace-match version t t))
520 (goto-char (point-max))
521 (setq ess-sqpe-versions-created
522 (cons (file-name-nondirectory version)
523 ess-sqpe-versions-created))
524 (ess-write-to-dribble-buffer
525 (format
526 "(Sqpe): ess-sqpe-versions-create making M-x defun %s for %s \n"
527 (file-name-nondirectory version) version))
529 ;; buffer has now been created with defuns, so eval them!
530 (eval-buffer)
531 (kill-buffer eval-buf))
532 ess-sqpe-versions-created))
534 ;; template function used by ess-sqpe-versions-create
535 (defun Sqpe+template (&optional proc-name)
536 "Call 'Sqpe' from 'S-PLUS for Windows ess-SHOME',
537 the 'Real Thing' from StatSci.
538 This function was generated by `ess-sqpe-versions-create'."
539 (interactive)
540 (setq ess-customize-alist Sqpe+6-customize-alist)
541 (let* ((use-dialog-box) ;; MS dialog box won't return a directory
542 (shome-old (getenv "SHOME"))
543 (inferior-Sqpe+6-SHOME-name "ess-SHOME")
544 (inferior-Sqpe+6-program-name (concat "ess-SHOME" "/cmd/sqpe.exe")))
545 (setenv "SHOME" "ess-SHOME")
546 (ess-write-to-dribble-buffer
547 (format "\n(Sqpe+template): ess-dialect=%s, buf=%s\n" ess-dialect
548 (current-buffer)))
549 (setq ess-customize-alist ; change inferior-ess-primary-prompt
550 (append ess-customize-alist
551 '((inferior-ess-primary-prompt . "^"))))
552 (inferior-ess)
553 (setq ess-customize-alist Sqpe+6-customize-alist) ; restore i-e-p-p in alist
554 (ess-setq-vars-local ess-customize-alist) ; restore i-e-p-p in buffer
555 (setq inferior-ess-prompt ; define with correct i-e-p-p
556 ;; Do not anchor to bol with `^' ; (copied from ess-inf.el)
557 (concat "\\("
558 inferior-ess-primary-prompt
559 "\\|"
560 inferior-ess-secondary-prompt
561 "\\)"))
562 (setq comint-prompt-regexp (concat "^" inferior-ess-prompt))
563 ; define with correct i-e-p-p
564 (setq comint-input-sender 'inferior-ess-input-sender)
565 (add-hook 'comint-output-filter-functions 'shell-strip-ctrl-m nil t)
566 (goto-char (point-max))
567 (insert "options(interactive=T)")
568 (inferior-ess-send-input)
569 (setq mode-name "iESS(Sqpe)")
570 ;; (ess-eval-linewise inferior-S+6-editor-pager-command)
571 (if inferior-ess-language-start
572 (ess-eval-linewise inferior-ess-language-start))
573 (setenv "SHOME" shome-old)))
576 \f ; Provide package
578 (provide 'essd-sp6w)
580 \f ; Local variables section
582 ;;; This file is automatically placed in Outline minor mode.
583 ;;; The file is structured as follows:
584 ;;; Chapters: ^L ;
585 ;;; Sections: ;;*;;
586 ;;; Subsections: ;;;*;;;
587 ;;; Components: defuns, defvars, defconsts
588 ;;; Random code beginning with a ;;;;* comment
590 ;;; Local variables:
591 ;;; mode: emacs-lisp
592 ;;; outline-minor-mode: nil
593 ;;; mode: outline-minor
594 ;;; outline-regexp: "\^L\\|\\`;\\|;;\\*\\|;;;\\*\\|(def[cvu]\\|(setq\\|;;;;\\*"
595 ;;; End:
597 ;;; essd-sp6w.el ends here