|
|
- ;;; ess-sas-a.el --- clean-room implementation of many SAS-mode features
-
- ;; Copyright (C) 1997--2009 A.J. Rossini, Richard M. Heiberger, Martin
- ;; Maechler, Kurt Hornik, Rodney Sparapani, and Stephen Eglen.
-
- ;; Author: Rodney A. Sparapani
- ;; Maintainer: ESS-core@r-project.org
- ;; Created: 17 November 1999
- ;; 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
- ;; https://www.r-project.org/Licenses/
-
- ;;; Code:
-
- (require 'ess-mode)
- ;; Silence the byte compiler
- ;; FIXME: This is a lot, perhaps they can be moved?
- (defvar sas-indent-width)
- (defvar SAS-customize-alist)
- (defvar sas-mode-local-map)
- (declare-function ess-num-or-zero "ess-sas-d")
- ;; FIXME: What is this doing here???
- (declare-function ess-add-ess-process "essd-els")
- (declare-function ess-listing-minor-mode "ess-sas-l")
- ;;; Table of Contents
- ;;; Section 1: Variable Definitions
- ;;; Section 2: Function Definitions
- ;;; Section 3: Key Definitions
-
- ;;; Section 1: Variable Definitions
-
- (defvar ess-sas-file-path "."
- "Full path-name of the sas file to perform operations on.")
-
- (defcustom ess-sas-data-view-libname " "
- "SAS code to define a library for `ess-sas-data-view-fsview'
- or `ess-sas-data-view-insight'."
- :group 'ess-sas
- :type 'string)
-
- (defcustom ess-sas-data-view-submit-options
- (if ess-microsoft-p "-noenhancededitor -nosysin -log NUL:"
- "-nodms -nosysin -log /dev/null -terminal")
- "The command-line options necessary for your OS with respect to
- `ess-sas-data-view-fsview' and `ess-sas-data-view-insight'."
- :group 'ess-sas
- :type 'string)
-
- (defcustom ess-sas-data-view-fsview-command "; proc fsview data="
- "SAS code to open a SAS dataset with `ess-sas-data-view-fsview'."
- :group 'ess-sas
- :type 'string)
-
- (defcustom ess-sas-data-view-fsview-statement " "
- "SAS code to perform a PROC FSVIEW statement with `ess-sas-data-view-fsview'."
- :group 'ess-sas
- :type 'string)
-
-
- (make-variable-buffer-local 'ess-sas-data-view-fsview-statement)
-
- (defcustom ess-sas-data-view-insight-command "; proc insight data="
- "SAS code to open a SAS dataset with `ess-sas-data-view-insight'."
- :group 'ess-sas
- :type 'string)
-
- (defcustom ess-sas-data-view-insight-statement " "
- "SAS code to perform a PROC FSVIEW statement with `ess-sas-data-view-insight'."
- :group 'ess-sas
- :type 'string)
-
- (make-variable-buffer-local 'ess-sas-data-view-insight-statement)
-
- (defcustom ess-sas-graph-view-suffix-regexp
- "[.]\\([eE]?[pP][sS]\\|[pP][dD][fF]\\|[gG][iI][fF]\\|[jJ][pP][eE]?[gG]\\|[tT][iI][fF][fF]?\\)"
- "GSASFILE suffix regexp."
- :group 'ess-sas
- :type 'string)
-
- (defcustom ess-sas-graph-view-viewer-alist
- ;;creates something like
- ;;'(("[pP][dD][fF]" . "/usr/local/bin/acroread") ("[eE]?[pP][sS]" . "/usr/local/bin/gv")))
- (let ((ess-tmp-alist nil)
- (ess-tmp-ps nil) (ess-tmp-pdf nil))
-
- (setq ess-tmp-ps (executable-find (if ess-microsoft-p "gsview32" "gsview")))
-
- (if (not ess-tmp-ps) (setq ess-tmp-ps (executable-find "gv")))
-
- (if (not ess-tmp-ps) (setq ess-tmp-ps (executable-find "ghostview")))
-
- (setq ess-tmp-pdf (executable-find "evince"))
-
- (if (not ess-tmp-pdf) (setq ess-tmp-pdf (executable-find "xpdf")))
-
- (if (not ess-tmp-pdf) (setq ess-tmp-pdf (if ess-microsoft-p "acrord32" "acroread")))
-
- (if (and ess-tmp-ps ess-tmp-pdf)
- (setq ess-tmp-alist (list (cons "[eE]?[pP][sS]" ess-tmp-ps)
- (cons "[pP][dD][fF]" ess-tmp-pdf)))
-
- (if ess-tmp-ps
- (setq ess-tmp-alist (list (cons "[eE]?[pP][sS]" ess-tmp-ps)
- (cons "[pP][dD][fF]" ess-tmp-ps))))))
-
- "Associate file name extensions with graphics image file viewers."
- :group 'ess-sas
- :type '(choice (const nil) (alist)))
-
- (defcustom ess-sas-log-max 0
- "If >0 and .log file exceeds this many bytes, just \"refresh\" this many bytes."
- :group 'ess-sas
- :type 'integer)
-
- (defcustom ess-sas-rtf-font-name "Courier" ; "Bitstream Vera Sans Mono"
- "Name of font with which to create MS RTF."
- :group 'ess-sas
- :type 'string)
-
- (defcustom ess-sas-shell-buffer "*shell*"
- "Name that you want to use for the shell buffer; buffer-local."
- :group 'ess-sas
- :type 'string)
-
- (make-variable-buffer-local 'ess-sas-shell-buffer)
-
- (defcustom ess-sas-shell-buffer-remote-host nil
- "Remote host that you want to open a shell on."
- :group 'ess-sas
- :type '(choice (const nil) string))
-
- (make-variable-buffer-local 'ess-sas-shell-buffer-remote-host)
-
- (defcustom ess-sas-shell-buffer-remote-init "ssh"
- "Command to open a shell on a remote host."
- :group 'ess-sas
- :type 'string)
-
- (make-variable-buffer-local 'ess-sas-shell-buffer-remote-init)
-
- (defcustom ess-sas-submit-mac-virtual-pc nil
- "Non-nil means that you want to run Windows SAS in a
- Virtual PC emulator on your Mac; buffer-local."
- :group 'ess-sas
- :type 'boolean)
-
- (make-variable-buffer-local 'ess-sas-submit-mac-virtual-pc)
-
- (defcustom sas-program "sas"
- "Command to invoke SAS, default for buffer-local `ess-sas-submit-command'."
- :group 'ess-sas
- :type 'string)
-
- (defcustom ess-sas-submit-command sas-program
- "Command to invoke SAS in batch; buffer-local."
- :group 'ess-sas
- :type 'string)
-
- (make-variable-buffer-local 'ess-sas-submit-command)
-
- (defcustom ess-sas-submit-command-options "-rsasuser"
- "Options to pass to SAS in batch; buffer-local."
- :group 'ess-sas
- :type 'string)
-
- (make-variable-buffer-local 'ess-sas-submit-command-options)
-
- (defvar-local ess-sas-submit-method
- (if (and (and ess-microsoft-p
- (fboundp 'w32-shell-dos-semantics))
- (w32-shell-dos-semantics))
- 'ms-dos 'sh)
- "Method used by `ess-sas-submit'.
- The default is based on the value of the emacs variable `system-type'
- and, on Windows, the function `w32-shell-dos-semantics'.
- 'sh if *shell* runs sh, ksh, csh, tcsh or bash
- 'ms-dos if *shell* follows MS-DOS semantics
-
- Unix users will get 'sh by default.
-
- Windows users running bash in *shell* will get 'sh by default.
-
- Windows users running MS-DOS in *shell* will get 'ms-dos by default.
-
- Users accessing a remote machine with `telnet', `rlogin', `ssh', etc.,
- should set this variable to 'sh regardless of their local shell
- (since their remote shell is 'sh).")
-
- (defcustom ess-sas-graph-view-viewer-default
- (if ess-microsoft-p "explorer"
- (if (equal ess-sas-submit-method 'sh) "sdtimage"))
- "Default graphics image file viewer."
- :group 'ess-sas
- :type 'string)
-
- (defcustom ess-sas-submit-post-command
- (if (equal ess-sas-submit-method 'sh) "&"
- (if ess-microsoft-p "-icon"))
- "Command-line statement to post-modify SAS invocation."
- :group 'ess-sas
- :type 'string)
-
- (defcustom ess-sas-submit-pre-command ;;"nohup"
- (if (equal ess-sas-submit-method 'sh)
- ;; nice is tricky, higher numbers give you lower priorities
- ;; if you are using csh/tcsh, the default priority is 4
- ;; if you are using most other shells, the default priority is 10,
- ;; and some implementations are higher, i.e. zsh unless you
- ;; specify "setopt no_bg_nice" in your ~/.zshrc
- ;; therefore, on the same machine, you can run at a higher or
- ;; lower priority by changing shells, although, the command
- ;; line is the same!
- ;; the following code should give you a priority of 10 regardless
- ;; of which shell is in use, but it will default to the old
- ;; behavior if csh or variant is not recognized
- ;; this should avoid the necessity of each user needing to set this
- ;; variable correctly based on the shell that they use and provide
- ;; an environment where all shells are treated equally
-
- (let* ((temp-shell (getenv "SHELL"))
- ;; AJR: old CYGWIN versions return nil for (getenv
- ;; "SHELL"), so we need to deal with it 'cause I have to
- (temp-char (if temp-shell
- (string-match "/" temp-shell)
- nil)))
- (while temp-char
- (setq temp-shell (substring temp-shell (+ 1 temp-char)))
- (setq temp-char (string-match "/" temp-shell)))
-
- (cond ((or (equal temp-shell "csh") (equal temp-shell "tcsh"))
- "nohup nice +6")
- (t "nohup nice")))
- (if ess-microsoft-p "start"))
- "Command-line statement to precede SAS invocation, e.g. start or nohup."
- :group 'ess-sas
- :type 'string)
-
- (defcustom ess-sas-suffix-1 "txt"
- "The first suffix to associate with SAS."
- :group 'ess-sas
- :type 'string)
-
- (defcustom ess-sas-suffix-2 "csv"
- "The second suffix to associate with SAS."
- :group 'ess-sas
- :type 'string)
-
- (defcustom ess-sas-suffix-regexp
- (concat "[.]\\([sS][aA][sS]\\|[lL][oO][gG]\\|[lL][sS][tT]"
- (if ess-sas-suffix-1 (concat
- "\\|" (downcase ess-sas-suffix-1) "\\|" (upcase ess-sas-suffix-1)))
- (if ess-sas-suffix-2 (concat
- "\\|" (downcase ess-sas-suffix-2) "\\|" (upcase ess-sas-suffix-2)))
- "\\)")
- "Regular expression for SAS suffixes."
- :group 'ess-sas
- :type 'string)
-
- (defcustom ess-sas-tab-stop-list
- '(4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120)
- "List of tab stop positions used by `tab-to-tab-stop' in ESS[SAS]."
- :type '(repeat integer)
- :group 'ess-sas)
-
- (defcustom ess-sas-temp-root "-temp"
- "Appended to root name of the temporary .sas file for `ess-sas-submit-region'."
- :group 'ess-sas
- :type 'string)
-
- (defvar ess-sas-versions '("sas")
- "List of partial strings for versions of SAS to access within ESS.
- Each string specifies the start of a filename. If a filename
- beginning with one of these strings is found on `exec-path', a M-x
- command for that version of SAS is made available. For example, if the
- file \"sas8\" is found and this variable includes the string
- \"sas\", a function called `M-x SAS8' will be available to run that
- version of SAS.
- If duplicate versions of the same program are found (which happens if
- the same path is listed on `exec-path' more than once), they are
- ignored by calling `delete-dups'.
- If you set this variable, you need to restart Emacs (and set this variable
- before ess-site is loaded) for it to take effect.")
-
- (defvar ess-sas-global-unix-keys nil
- "Non-nil if function keys use Unix-like SAS key definitions in all modes.")
-
- (defvar ess-sas-local-pc-keys nil
- "Non-nil if function keys use PC-like SAS key definitions
- in SAS-mode and related modes.")
-
- (defvar ess-sas-local-unix-keys nil
- "Non-nil if function keys use Unix-like SAS key definitions
- in SAS-mode and related modes.")
-
- ;;; Section 2: Function Definitions
-
-
- (defun ess-ebcdic-to-ascii-search-and-replace ()
- "Search and replace EBCDIC text with ASCII equivalents."
- (interactive)
- (let ((ess-tmp-dd (executable-find "dd")) (ess-tmp-recode (executable-find "recode"))
- (ess-tmp-util nil) (ess-tmp-util-args nil))
-
- (if ess-tmp-dd (progn
- (setq ess-tmp-util ess-tmp-dd)
- (setq ess-tmp-util-args "conv=ascii"))
-
- (setq ess-tmp-util ess-tmp-recode)
- (setq ess-tmp-util-args "EBCDIC..ISO-8859-1"))
-
- (if ess-tmp-util
- (while (search-forward-regexp "[^\f\t\n -~][^\f\t\n -?A-JQ-Yb-jp-y]*[^\f\t\n -~]?" nil t)
- (call-process-region (match-beginning 0) (match-end 0)
- ess-tmp-util t (list t nil) t ess-tmp-util-args)))))
-
-
- (defun ess-exit-notify-sh (string)
- "Detect completion or failure of submitted job and notify the user."
- (let* ((exit-done "\\[[0-9]+\\] *\\+* *\\(Exit\\|Done\\)[^\r\n]*")
- (beg (string-match exit-done string)))
- (if beg
- (message "%s" (substring string beg (match-end 0))))))
-
-
- (defun ess-sas-append-log ()
- "Append ess-temp.log to the current .log file."
- (interactive)
- (ess-sas-goto "log" 'revert)
- (goto-char (point-max))
- (insert-file-contents (concat (ess-sas-temp-root) ".log"))
- (save-buffer))
-
- (defun ess-sas-append-lst ()
- "Append ess-temp.lst to the current .lst file."
- (interactive)
- (ess-sas-goto "lst" 'revert)
- (goto-char (point-max))
- (insert-file-contents (concat (ess-sas-temp-root) ".lst"))
- (save-buffer))
-
- (defun ess-sas-backward-delete-tab ()
- "Moves the cursor to the previous tab-stop, deleting any characters
- on the way."
- (interactive)
-
- (let* (;; point of search
- ;;(ess-sas-search-point nil)
- ;; column of search
- ;;(ess-sas-search-column nil)
- ;; limit of search
- ;;(ess-sas-search-limit nil)
- ;; text to be inserted after a back-tab, if any
- ;;(ess-sas-end-text "end;")
- ;; current-column
- (ess-sas-column (current-column))
- ;; remainder of current-column and sas-indent-width
- (ess-sas-remainder (% ess-sas-column sas-indent-width)))
-
- (if (not (= ess-sas-column 0))
- (progn
- (if (= ess-sas-remainder 0)
- (setq ess-sas-remainder sas-indent-width))
-
- (let ((backward-delete-char-untabify-method 'nil))
- (backward-delete-char-untabify ess-sas-remainder t)
- (setq ess-sas-column (- ess-sas-column ess-sas-remainder))
- (move-to-column ess-sas-column)
- (setq left-margin ess-sas-column))
- ))
- ))
-
- ;; this feature was far too complicated to perfect
- ;; (if ess-sas-smart-back-tab (progn
- ;; (save-excursion
- ;; (setq ess-sas-search-point
- ;; (search-backward-regexp "end" nil t))
-
- ;; (if (and ess-sas-search-point
- ;; (search-backward-regexp "%" (+ ess-sas-search-point -1) t))
- ;; (setq ess-sas-search-point (+ ess-sas-search-point -1))
- ;; )
-
- ;; (if (and ess-sas-search-point
- ;; (not (equal ess-sas-column (current-column))))
- ;; (setq ess-sas-search-point nil))
- ;; )
-
- ;; (save-excursion
- ;; (setq ess-sas-search-point
- ;; (search-backward-regexp "do\\|select"
- ;; ess-sas-search-point t))
-
- ;; (setq ess-sas-search-column (current-column))
-
- ;; (if ess-sas-search-point (progn
- ;; (save-excursion
- ;; (search-backward-regexp "^" nil t)
- ;; (setq ess-sas-search-limit (point))
- ;; )
-
- ;; (if (search-backward-regexp "if.*then\\|else" ess-sas-search-limit t)
- ;; (setq ess-sas-search-point (point)))
-
- ;; (if (search-backward-regexp "%" ess-sas-search-limit t) (progn
- ;; (setq ess-sas-end-text "%end;")
- ;; (setq ess-sas-search-point (point))
- ;; ))
-
- ;; (setq ess-sas-search-column (current-column))
-
- ;; (if (not (equal ess-sas-column ess-sas-search-column))
- ;; (setq ess-sas-search-point nil))
- ;; )))
-
- ;; (if ess-sas-search-point (insert ess-sas-end-text))
- ;; ))
-
- (defun ess-sas-cd ()
- "Change directory, taking into account various issues with respect to
- `ess-sas-file-path'."
- ;(interactive)
- (ess-sas-file-path)
- (ess-sas-goto-shell t)
- (comint-send-input)
- (if (equal ess-sas-submit-method 'sh)
- (insert "cd \"" (car (last (split-string (file-name-directory ess-sas-file-path)
- "\\([a-zA-Z][a-zA-Z]:\\|]\\)"))) "\"")
- (if (equal ess-sas-submit-method 'ms-dos) (progn
- (if (string-equal ":" (substring ess-sas-file-path 1 2)) (progn
- (insert (substring ess-sas-file-path 0 2))
- (comint-send-input)))
- (insert "cd \"" (convert-standard-filename
- (file-name-directory ess-sas-file-path)) "\""))))
- (comint-send-input))
-
- (defun ess-sas--change-alist (item value alist)
- "Modify ALIST to set VALUE to ITEM.
- If there is a pair whose car is ITEM, replace its cdr by VALUE.
- If there is not such pair, create new pair (ITEM . VALUE) and
- return new alist whose car is the new pair and cdr is ALIST.
- \[tomo's ELIS like function]"
- (let ((pair (assoc item alist)))
- (if pair
- (progn
- (setcdr pair value)
- alist)
- (cons (cons item value) alist))))
-
- (defun ess-sas-create-local-variables-alist (&optional file-or-buffer)
- "Create an alist of local variables from file-or-buffer.
- Use the current buffer if nil."
- (declare (obsolete nil "ESS 19.04"))
- (if file-or-buffer (set-buffer (if (bufferp file-or-buffer)
- file-or-buffer
- (find-buffer-visiting file-or-buffer))))
- (ess-sas--change-alist 'ess-kermit-remote-directory ess-kermit-remote-directory nil))
-
- (define-obsolete-function-alias
- 'ess-change-alist 'ess-sas--change-alist "ESS 18.10")
-
- (defun ess-sas-data-view-fsview (&optional ess-sas-data)
- "Open a dataset for viewing with PROC FSVIEW."
- (interactive)
- (ess-save-and-set-local-variables)
-
- (save-excursion (let ((ess-tmp-sas-data nil)
- (ess-tmp-sas-data-view-fsview-statement ess-sas-data-view-fsview-statement)
- (ess-search-regexp
- "[ \t=]\\([a-zA-Z_][a-zA-Z_0-9]*[.][a-zA-Z_][a-zA-Z_0-9]*\\)\\(&.*\\)?[. ,()\t;/]")
- (ess-search-except
- "^\\([wW][oO][rR][kK]\\|[fF][iI][rR][sS][tT]\\|[lL][aA][sS][tT]\\)[.]"))
-
- (if ess-sas-data nil (save-match-data
- (search-backward-regexp "[ \t=]" nil t)
-
- (save-excursion
- (setq ess-tmp-sas-data
- (ess-search-except ess-search-regexp ess-search-except)))
-
- (if (not ess-tmp-sas-data)
- (setq ess-tmp-sas-data
- (ess-search-except ess-search-regexp ess-search-except t)))
-
- (setq ess-sas-data (read-string "Permanent SAS Dataset: " ess-tmp-sas-data))
-
- ;; (ess-sas-goto-shell t)
- (ess-sas-cd)
-
- (insert (concat ess-sas-submit-pre-command " " ess-sas-submit-command
- " -initstmt \"" ess-sas-data-view-libname ess-sas-data-view-fsview-command
- ess-sas-data ";" ess-tmp-sas-data-view-fsview-statement "; run;\" "
- ess-sas-submit-command-options " "
- ess-sas-data-view-submit-options " " ess-sas-submit-post-command))
- (comint-send-input)
- )))))
-
- (defun ess-sas-data-view-insight (&optional ess-sas-data)
- "Open a dataset for viewing with PROC INSIGHT."
- (interactive)
- (ess-save-and-set-local-variables)
-
- (save-excursion (let ((ess-tmp-sas-data nil)
- (ess-tmp-sas-data-view-insight-statement ess-sas-data-view-insight-statement)
- (ess-search-regexp
- "[ \t=]\\([a-zA-Z_][a-zA-Z_0-9]*[.][a-zA-Z_][a-zA-Z_0-9]*\\)\\(&.*\\)?[. ,()\t;]")
- (ess-search-except
- "^\\([wW][oO][rR][kK]\\|[fF][iI][rR][sS][tT]\\|[lL][aA][sS][tT]\\)[.]"))
-
- (if ess-sas-data nil (save-match-data
- (search-backward-regexp "[ \t=]" nil t)
-
- (save-excursion
- (setq ess-tmp-sas-data
- (ess-search-except ess-search-regexp ess-search-except)))
-
- (if (not ess-tmp-sas-data)
- (setq ess-tmp-sas-data
- (ess-search-except ess-search-regexp ess-search-except t)))
-
- (setq ess-sas-data (read-string "Permanent SAS Dataset: " ess-tmp-sas-data))
-
- ;; (ess-sas-goto-shell t)
- (ess-sas-cd)
-
- (insert (concat ess-sas-submit-pre-command " " ess-sas-submit-command
- " -initstmt \"" ess-sas-data-view-libname ess-sas-data-view-insight-command
- ess-sas-data ";" ess-tmp-sas-data-view-insight-statement "; run;\" "
- ess-sas-data-view-submit-options " " ess-sas-submit-post-command))
- (comint-send-input)
- )))))
-
- (defun ess-sas-graph-view ()
- "Open a GSASFILE for viewing."
- (interactive)
- ;; (ess-sas-goto-shell t)
- (ess-sas-cd)
- (ess-sas-goto-log 'no-error-check)
-
- (save-excursion
- (let (
- (ess-tmp-length (length ess-sas-graph-view-viewer-alist))
- (ess-tmp-counter 0)
- (ess-tmp-graph nil)
- (ess-tmp-graph-alist nil)
- (ess-tmp-glyph nil)
- (ess-tmp-graph-regexp
- (concat "[cCub][oOty][rRpt][dDue][sSt][ ][wW][rR][iI][tT][tT][eE][nN][ ]+[tT][oO][ ]\n?[ ]*\\(.*"
- ;; (concat "[ ][rR][eE][cC][oO][rR][dD][sS][ ][wW][rR][iI][tT][tT][eE][nN][ ]+[tT][oO][ ]\n?[ ]*\\(.*"
- ess-sas-graph-view-suffix-regexp "\\)")))
- ; (concat "['\"]\\(.*" ess-sas-graph-suffix-regexp "\\)['\"]")))
-
- (save-match-data
- (search-backward-regexp "[ \t=]" nil t)
-
- (save-excursion
- (setq ess-tmp-graph (ess-search-except ess-tmp-graph-regexp)))
-
- (if (not ess-tmp-graph)
- (setq ess-tmp-graph (ess-search-except ess-tmp-graph-regexp nil t)))
-
- (setq ess-tmp-graph (read-string "GSASFILE: "
- (or ess-tmp-graph ess-sas-file-path)))
-
- ;;GNU Emacs graphics file image viewing mode loaded?
- (if (and (bound-and-true-p auto-image-file-mode)
- (string-match "[.][jJ][pP][eE]?[gG]" ess-tmp-graph))
- (find-file ess-tmp-graph)
- ;;else XEmacs graphics file image viewing mode loaded?
- (if (and (fboundp 'image-mode)
- (string-match "[.]\\([jJ][pP][eE]?[gG]\\|[gG][iI][fF]\\)"
- ess-tmp-graph))
- (find-file ess-tmp-graph)
- ;;else use the appropriate graphics file image viewer
- (while (< ess-tmp-counter ess-tmp-length)
- (setq ess-tmp-graph-alist
- (nth ess-tmp-counter ess-sas-graph-view-viewer-alist))
- (setq ess-tmp-graph-regexp (car ess-tmp-graph-alist))
-
- (if (string-match
- (concat "[.]" ess-tmp-graph-regexp) ess-tmp-graph)
- (progn
- (ess-sas-goto-shell t)
- (insert ess-sas-submit-pre-command " "
- (cdr ess-tmp-graph-alist) " " ess-tmp-graph
- (if (equal ess-sas-submit-method 'sh) " &"))
- (setq ess-tmp-glyph 'alist)
- (setq ess-tmp-counter ess-tmp-length))
- ;;else
- (setq ess-tmp-counter (+ ess-tmp-counter 1))))
-
- (if (not ess-tmp-glyph)
- (progn
- (ess-sas-goto-shell t)
- (insert ess-sas-submit-pre-command " "
- ess-sas-graph-view-viewer-default " " ess-tmp-graph
- (if (equal ess-sas-submit-method 'sh) " &"))))
-
- (comint-send-input)))))))
-
- (defun ess-sas-file-path (&optional force)
- "Define `ess-sas-file-path' to be the current buffer depending on suffix."
- (interactive)
-
- (save-match-data (let ((ess-sas-temp-file (expand-file-name (buffer-name))))
- (if (or force (string-match ess-sas-suffix-regexp ess-sas-temp-file)) ;;(progn
- (setq ess-sas-file-path
- (nth 0 (split-string ess-sas-temp-file "[<]")))))))
-
- (defun ess-sas-file-path-remote-host ()
- "Return the remote host, if any, associated with `ess-sas-file-path'."
- (interactive)
-
- (let* ((temp-colon-pos (string-match ":" ess-sas-file-path))
- (temp-list
- (if (or (not temp-colon-pos) (> temp-colon-pos 2))
- (if (equal ess-sas-file-path ".") nil
- (split-string (file-name-directory ess-sas-file-path)
- "\\(@\\|:\\|]\\)"))
- (list ess-sas-file-path)))
- (temp-list-length (length temp-list)))
- (if (= temp-list-length 1) (setq temp-list nil)
- (if (= temp-list-length 2) (setq temp-list (car temp-list))
- (setq temp-list (nth 1 temp-list))))
-
- (if temp-list (setq temp-list
- (car (last (split-string temp-list "/")))))
- temp-list))
-
- (defun ess-sas-goto (suffix &optional revert no-create)
- "Find a file associated with a SAS file by suffix and revert if necessary."
- ; (interactive)
- ; (let ((ess-temp-regexp (concat ess-sas-suffix-regexp "[.]?[1-9]?\\'")))
- ; can we identify common nonsense extensions like .log.1 or .sas.2?
- (let ((ess-temp-regexp (concat ess-sas-suffix-regexp "\\(@.+\\)?\\'")))
- (save-match-data
- (if (or (string-match ess-temp-regexp (expand-file-name (buffer-name)))
- (string-match ess-temp-regexp ess-sas-file-path))
- (progn
- (ess-sas-file-path)
- (let* (
- (ess-sas-temp-file (replace-match (concat "." suffix) t t
- ess-sas-file-path))
- (ess-sas-temp-buff (find-buffer-visiting ess-sas-temp-file))
- (ess-temp-kermit-remote-directory ess-kermit-remote-directory))
-
- (if ess-sas-temp-buff (switch-to-buffer ess-sas-temp-buff)
- ;; else
- (if no-create (setq revert nil)
- (if (file-exists-p ess-sas-temp-file)
- (find-file ess-sas-temp-file))))
- ;; else
- ;; (let* ((ess-sas-buffer-list (buffer-list))
- ;; (ess-sas-buffer-list-index 0)
- ;; (ess-sas-buffer-list-file nil)
- ;; (ess-sas-buffer-list-length (length ess-sas-buffer-list)))
- ;; (while (< ess-sas-buffer-list-index ess-sas-buffer-list-length)
- ;; (setq ess-sas-buffer-list-file
- ;; (buffer-file-name (nth ess-sas-buffer-list-index ess-sas-buffer-list)))
- ;; (if (and ess-sas-buffer-list-file
- ;; (string-match (concat "." suffix) ess-sas-buffer-list-file))
- ;; (switch-to-buffer (nth ess-sas-buffer-list-index ess-sas-buffer-list))
- ;; (setq ess-sas-buffer-list-index ess-sas-buffer-list-length)
- ;; )
- ;; (setq ess-sas-buffer-list-index (+ 1 ess-sas-buffer-list-index))
- ;; )))
-
- (if (and (not no-create)
- (or (string-equal suffix "log")
- (string-equal suffix "lst")))
- (ess-kermit-get (file-name-nondirectory ess-sas-temp-file)
- ess-temp-kermit-remote-directory))
-
- (if revert
- (if (and (> ess-sas-log-max 0) (string-equal suffix "log")
- (> (ess-num-or-zero (nth 7 (file-attributes ess-sas-temp-file)))
- ess-sas-log-max))
- (progn
- (insert-file-contents ess-sas-temp-file nil 0
- ess-sas-log-max t)
- t)
-
- (ess-revert-wisely)) nil)))))))
-
- ;;(defun ess-sas-file (suffix &optional revert)
- ;; "Please use `ess-sas-goto' instead."
- ;; (let* ((tail (downcase (car (split-string
- ;; (car (last (split-string (buffer-name) "[.]"))) "[<]"))))
- ;;(if (fboundp 'file-name-extension) (file-name-extension (buffer-name))
- ;; (substring (buffer-name) -3)))
- ;; (tail-in-tail-list (member tail (list "sas" "log" "lst"
- ;; ess-sas-suffix-1 ess-sas-suffix-2)))
- ;; (root (if tail-in-tail-list (expand-file-name (buffer-name))
- ;; ess-sas-file-path))
- ;; (ess-sas-arg (concat (file-name-sans-extension root) "." suffix))
- ;; (ess-sas-buf (find-buffer-visiting ess-sas-arg)))
- ;; (if (equal tail suffix) (if revert (ess-revert-wisely))
- ;; (if (not ess-sas-buf) (find-file ess-sas-arg)
- ;; (switch-to-buffer ess-sas-buf)
- ;; (if revert (ess-revert-wisely))))))
-
-
- (defun ess-sas-goto-file-1 ()
- "Switch to ess-sas-file-1 and revert from disk."
- (interactive)
- (ess-sas-goto ess-sas-suffix-1 'revert))
-
- (defun ess-sas-goto-file-2 ()
- "Switch to ess-sas-file-2 and revert from disk."
- (interactive)
- (ess-sas-goto ess-sas-suffix-2 'revert))
-
- (defun ess-sas-goto-log (&optional ess-tmp-no-error-check)
- "Switch to the .log file, revert from disk and search for error messages."
- (interactive)
-
- (let ((ess-sas-error (concat
- "^ERROR [0-9]+-[0-9]+:\\|^ERROR:\\|_ERROR_=1 _N_=\\|_ERROR_=1[ ]?$"
- "\\|NOTE: MERGE statement has more than one data set with repeats"
- "\\|NOTE: Variable .* is uninitialized."
- "\\|NOTE: SAS went to a new line when INPUT statement reached past"
- "\\|NOTE 485-185: Informat .* was not found"
- "\\|NOTE: Estimated G matrix is not positive definite."
- "\\|NOTE: Compressing data set .* increased size by"
- "\\|NOTE: ERROR DETECTED IN ANNOTATE="
- "\\|WARNING: Apparent symbolic reference .* not resolved."
- "\\|WARNING: Length of character variable has already been set."
- "\\|WARNING: Not all variables in the list "
- "\\|WARNING: RUN statement ignored due to previous errors."
- "\\|WARNING: Values exist outside the axis range"
- "\\|WARNING: Truncated record."
- "\\|Bus Error In Task\\|Segmentation Violation In Task"))
- (ess-sas-save-point nil)); (ess-sas-pop-mark nil))
-
- (if (ess-sas-goto "log" 'revert) (progn
- (setq ess-sas-save-point (point))
- (goto-char (point-min)))
- (setq ess-sas-save-point (point)))
-
- ;(if (number-char-or-marker-p ess-sas-save-point) (progn
- (if ess-tmp-no-error-check (goto-char ess-sas-save-point)
- (if (or (search-forward-regexp ess-sas-error nil t)
- (and (goto-char (point-min))
- (search-forward-regexp ess-sas-error nil t)))
- t
- (goto-char ess-sas-save-point)))))
-
- (defun ess-sas-goto-lst ()
- "Switch to the .lst file and revert from disk."
- (interactive)
- (ess-sas-goto "lst" 'revert))
-
- (defun ess-sas-goto-sas (&optional revert)
- "Switch to the .sas file."
- (interactive)
- (ess-sas-goto "sas" revert))
-
- (defun ess-sas-goto-shell (&optional set-buffer)
- "Set `ess-sas-file-path' and goto `ess-sas-shell-buffer'. If
- optional argument is non-nil, then set-buffer rather than switch."
- (interactive)
- (ess-sas-file-path)
-
- ; The following let* block is an attempt to deal with remote directories.
- (let* ((temp-shell-buffer-remote-host
- (or ess-sas-shell-buffer-remote-host (ess-sas-file-path-remote-host)))
- (temp-shell-buffer-remote-init ess-sas-shell-buffer-remote-init)
- (temp-shell-buffer
- (if temp-shell-buffer-remote-host
- (concat "*" temp-shell-buffer-remote-host "*")
- ess-sas-shell-buffer))
- )
-
- (if (get-buffer temp-shell-buffer)
- (if set-buffer (set-buffer temp-shell-buffer)
- (switch-to-buffer temp-shell-buffer))
- (shell)
- (rename-buffer temp-shell-buffer)
- (ess-sleep) ; GNU Emacs needs this
-
- (if temp-shell-buffer-remote-host (progn
- (insert (concat
- temp-shell-buffer-remote-init " " temp-shell-buffer-remote-host))
- (comint-send-input))
- )
-
- (if (eq ess-sas-submit-method 'sh)
- (add-hook 'comint-output-filter-functions 'ess-exit-notify-sh)) ;; 19.28
- ;; nil t) works for newer emacsen
- )
- )
-
- (goto-char (point-max))
- ; (insert "cd " ess-temp-directory)
- ; (comint-send-input))
- )
-
- (defun ess-sas-interactive ()
- "And now for something completely different."
- (interactive)
- ;;(ess-sas-file-path)
- (setq ess-local-customize-alist SAS-customize-alist)
- ;; (let ((ess-temp-sas-file
- ;; (nth 0 (split-string
- ;; (car (last (split-string ess-sas-file-path "\\([a-zA-Z][a-zA-Z]:\\|]\\)"))) "[.]"))))
- (setq ess-sas-shell-buffer "*iESS[SAS]*")
- (ess-sas-goto-shell)
- (ess-add-ess-process)
- (ess-setq-vars-local ess-local-customize-alist)
- (inferior-ess-mode)
- (ess-eval-linewise (concat ess-sas-submit-command " " ess-sas-submit-command-options " -stdio"))
- ;;" -altlog " ess-temp-sas-file ".log -altprint "
- ;; ess-temp-sas-file ".lst -stdio"))
- (ess-sas-goto-sas)
- (setq ess-sas-submit-method 'iESS)
- (setq ess-eval-visibly-p nil)
- )
-
- ;;(defun ess-sas-interactive ()
- ;; (interactive)
- ;; (ess-sas-file-path)
- ;; (setq ess-sas-submit-method 'iESS)
- ;;
- ;; (let ((ess-temp-stderr " ") (ess-temp-stdout " ") (ess-temp-stdin " "))
- ;; (setq ess-sas-shell-buffer "*LOG*")
- ;; (ess-sas-goto-shell)
- ;; (insert "tty")
- ;; (comint-send-input)
- ;; (sleep-for ess-sleep-for)
- ;; (save-excursion (setq ess-temp-stderr (ess-search-except "\\(/dev/[a-z0-9/]+\\)" nil t)))
- ;; (setq ess-sas-shell-buffer "*OUTPUT*")
- ;; (ess-sas-goto-shell)
- ;; (insert "tty")
- ;; (comint-send-input)
- ;; (sleep-for ess-sleep-for)
- ;; (save-excursion (setq ess-temp-stdout (ess-search-except "\\(/dev/[a-z0-9/]+\\)" nil t)))
- ;; (setq ess-sas-shell-buffer "*PROGRAM*")
- ;; (ess-sas-goto-shell)
- ;;;; (insert "tty")
- ;; (comint-send-input)
- ;; (sleep-for ess-sleep-for)
- ;; (insert "sh")
- ;; (comint-send-input)
- ;; (sleep-for ess-sleep-for)
- ;; (save-excursion (setq ess-temp-stdin (ess-search-except "\\(/dev/[a-z0-9/]+\\)" nil t)))
- ;; (insert (concat ess-sas-submit-command " " ess-sas-submit-command-options " -stdio <"
- ;; ess-temp-stdin " >1 " ess-temp-stdout " >2 " ess-temp-stderr))
- ;; (comint-send-input)
- ;; (ess-add-ess-process)
- ;; (ess-sas-goto-sas)
- ;;))
-
- (defun ess-sas-kill-buffers ()
- "Kill all buffers related to a .sas file."
- (interactive)
- (ess-sas-file-path)
- (ess-sas-goto "log" nil t)
- (kill-buffer nil)
- (ess-sas-goto "lst" nil t)
- (kill-buffer nil)
- (ess-sas-goto ess-sas-suffix-1 nil t)
- (kill-buffer nil)
- (ess-sas-goto ess-sas-suffix-2 nil t)
- (kill-buffer nil)
- (ess-sas-goto "sas" nil t)
- (kill-buffer nil)
- )
-
- ; else
- (defun ess-sas-rtf-portrait (&optional ess-tmp-font-size)
- "Creates an MS RTF portrait file from the current buffer."
- (interactive)
- ; (ess-sas-file-path t)
- (ess-revert-wisely)
-
- (set-visited-file-name (concat (buffer-name) ".rtf"))
- ; (ess-sas-goto "rtf" t)
- (if 'buffer-read-only (setq buffer-read-only nil))
- (ess-rtf-replace-chars)
-
- (goto-char (point-min))
- (insert (concat
- "{\\rtf1\\ansi{\\fonttbl\\f1\\fmodern " ess-sas-rtf-font-name ";}\n"
- "\\margl720\\margr720\\margt720\\margb720\n"
- "{\\colortbl;\\red0\\green0\\blue0;\\red0\\green0\\blue255;\\red0\\green255\\blue255;\\red0\\green255\\blue0;\\red255\\green0\\blue255;\\red255\\green0\\blue0;\\red255\\green255\\blue0;\\red255\\green255\\blue255;\\red0\\green0\\blue128;\\red0\\green128\\blue128;\\red0\\green128\\blue0;\\red128\\green0\\blue128;\\red128\\green0\\blue0;\\red128\\green128\\blue0;\\red128\\green128\\blue128;\\red192\\green192\\blue192;}\n"
- "{\\stylesheet{\\s15\\plain\\f1\\fs16\\cf1\\cb8\\lang1024 Emacs Text;}{\\*\\cs16 \\additive\\f1\\fs16\\cf1\\cb8\\lang1024 Emacs Base Style;}}\n"
- "{\\plain\\s15{\\cs16\\cs16\\f1\\fs16\\cf1\\cb8\\lang1024{\\cs16\\f1\\fs16\\cf1\\cb8\\lang1024\n"))
-
- (goto-char (point-max))
- (insert "}}}}\n")
-
- (save-buffer)
- (kill-buffer (current-buffer)))
-
- (defun ess-rtf-replace-chars ()
- "Convert a text file to an MS RTF file."
- (interactive)
- (goto-char (point-min))
- (while (re-search-forward "\n" nil t) (replace-match "\\par\n" nil t))
- (goto-char (point-min))
- (while (re-search-forward "\f" nil t) (replace-match "\\page\n" nil t))
- (goto-char (point-min))
- (while (re-search-forward "\t" nil t) (replace-match "\\tab" nil t)))
-
- (defun ess-sas-rtf-landscape (&optional ess-tmp-font-size)
- "Creates an MS RTF landscape file from the current buffer."
- (interactive)
- (ess-revert-wisely)
-
- (set-visited-file-name (concat (buffer-name) ".rtf"))
-
- (if 'buffer-read-only (setq buffer-read-only nil))
- (ess-rtf-replace-chars)
-
- (goto-char (point-min))
- (insert (concat
- "{\\rtf1\\ansi{\\fonttbl\\f1\\fmodern " ess-sas-rtf-font-name ";}\n"
- "\\margl720\\margr720\\margt720\\margb720\n"
- "{\\*\\pgdsctbl\n"
- "{\\pgdsc0\\pgdscuse195\\lndscpsxn\\pgwsxn15840\\pghsxn12240\\marglsxn1800\\margrsxn1800\\margtsxn1440\\margbsxn1440\\pgdscnxt0 Default;}}\n"
- "\\landscape\\paperh12240\\paperw15840\\margl1800\\margr1800\\margt1440\\margb1440\\sectd\\sbknone\\lndscpsxn\\pgwsxn15840\\pghsxn12240\\marglsxn1800\\margrsxn1800\\margtsxn1440\\margbsxn1440\\ftnbj\\ftnstart1\\ftnrstcont\\ftnnar\\aenddoc\\aftnrstcont\\aftnstart1\\aftnnrlc\n"
- "{\\colortbl;\\red0\\green0\\blue0;\\red0\\green0\\blue255;\\red0\\green255\\blue255;\\red0\\green255\\blue0;\\red255\\green0\\blue255;\\red255\\green0\\blue0;\\red255\\green255\\blue0;\\red255\\green255\\blue255;\\red0\\green0\\blue128;\\red0\\green128\\blue128;\\red0\\green128\\blue0;\\red128\\green0\\blue128;\\red128\\green0\\blue0;\\red128\\green128\\blue0;\\red128\\green128\\blue128;\\red192\\green192\\blue192;}\n"
- "{\\stylesheet{\\s15\\plain\\f1\\fs16\\cf1\\cb8\\lang1024 Emacs Text;}{\\*\\cs16 \\additive\\f1\\fs16\\cf1\\cb8\\lang1024 Emacs Base Style;}}\n"
- "{\\plain\\s15{\\cs16\\cs16\\f1\\fs16\\cf1\\cb8\\lang1024{\\cs16\\f1\\fs16\\cf1\\cb8\\lang1024\n"))
-
- (goto-char (point-max))
- (insert "}}}}\n")
-
- (save-buffer)
- (kill-buffer (current-buffer)))
-
- (defun ess-sas-rtf-us-landscape ()
- "Creates an MS RTF US landscape file from the current buffer."
- (interactive)
- (ess-sas-rtf-portrait "16")
- (ess-sas-goto "rtf" t)
- (goto-char (point-min))
- (forward-line 3)
- (insert (concat "{\\*\\pgdsctbl\n"
- "{\\pgdsc0\\pgdscuse195\\lndscpsxn\\pgwsxn15840\\pghsxn12240\\marglsxn1800\\margrsxn1800\\margtsxn1440\\margbsxn1440\\pgdscnxt0 Default;}}\n"
- "\\landscape\\paperh12240\\paperw15840\\margl1800\\margr1800\\margt1440\\margb1440\\sectd\\sbknone\\lndscpsxn\\pgwsxn15840\\pghsxn12240\\marglsxn1800\\margrsxn1800\\margtsxn1440\\margbsxn1440\\ftnbj\\ftnstart1\\ftnrstcont\\ftnnar\\aenddoc\\aftnrstcont\\aftnstart1\\aftnnrlc\n"))
- (save-buffer)
- (kill-buffer (current-buffer)))
-
- (defun ess-sas-rtf-a4-landscape ()
- "Creates an MS RTF A4 landscape file from the current buffer."
- (interactive)
- (ess-sas-rtf-portrait "16")
- (ess-sas-goto "rtf" t)
- (goto-char (point-min))
- (forward-line 3)
- (insert (concat "{\\*\\pgdsctbl\n"
- "{\\pgdsc0\\pgdscuse195\\lndscpsxn\\pgwsxn16837\\pghsxn11905\\marglsxn1800\\margrsxn1800\\margtsxn1440\\margbsxn1440\\pgdscnxt0 Default;}}\n"
- "\\landscape\\paperh11905\\paperw16837\\margl1800\\margr1800\\margt1440\\margb1440\\sectd\\sbknone\\lndscpsxn\\pgwsxn16837\\pghsxn11905\\marglsxn1800\\margrsxn1800\\margtsxn1440\\margbsxn1440\\ftnbj\\ftnstart1\\ftnrstcont\\ftnnar\\aenddoc\\aftnrstcont\\aftnstart1\\aftnnrlc\n"))
- (save-buffer)
- (kill-buffer (current-buffer)))
-
- (defun ess-sas-submit ()
- "Save the .sas file and submit to shell using a function that
- depends on the value of `ess-sas-submit-method'"
- (interactive)
- (ess-sas-file-path)
- (ess-sas-goto-sas)
- (save-buffer)
- (hack-local-variables)
- ;(ess-save-and-set-local-variables)
-
- (cond
- ((eq ess-sas-submit-method 'ms-dos)
- (ess-sas-submit-windows ess-sas-submit-command
- ess-sas-submit-command-options))
- ((eq ess-sas-submit-method 'iESS)
- (ess-sas-submit-iESS ess-sas-submit-command
- ess-sas-submit-command-options))
- ((eq ess-sas-submit-method 'sh)
- (ess-sas-submit-sh ess-sas-submit-command
- ess-sas-submit-command-options))
- (t (ess-sas-submit-sh ess-sas-submit-command
- ess-sas-submit-command-options)))
- ; (ess-sas-goto-sas)
- )
-
- (defun ess-sas-submit-iESS (arg1 arg2)
- "iESS
- Submit a batch job in an inferior-ESS buffer. The buffer should
- (1) have telnet access and be running a shell on a remote machine
- or
- (2) be running a shell on the local machine.
-
- The user can telnet to the remote computer and then declare the
- *telnet-buffer* to be an inferior ESS buffer with the `ess-add-ess-process'
- command. When using a remote computer, the .sas file must live on the
- remote computer and be accessed through `ange-ftp'. When
- `ess-sas-submit' saves a file, it is therefore saved on the remote
- computer. The various functions such as `ess-sas-goto-lst' retrieve
- their files from the remote computer. Local copies of the .sas .lst
- .log and others may be made manually with `write-buffer'."
- ;; (ess-eval-linewise (concat "cd default-directory))
- (ess-force-buffer-current "Process to load into: ")
- (ess-eval-linewise
- (concat "cd " (car (last
- (split-string (file-name-directory ess-sas-file-path) "\\(:\\|]\\)")))))
- (ess-eval-linewise (concat arg1 " " arg2 " " (buffer-name) " &")))
-
- (defun ess-sas-submit-region ()
- "Write region to temporary file, and submit to SAS."
- (interactive)
- (ess-sas-file-path)
- (hack-local-variables t)
- (write-region (region-beginning) (region-end)
- (concat (ess-sas-temp-root) ".sas"))
-
- (let ((arg1 ess-sas-submit-command)
- (arg2 ess-sas-submit-command-options))
- (save-excursion
- (ess-sas-goto-shell t)
-
- (if (and (when
- ;; Silence byte compiler warns about w32-fns
- (fboundp 'w32-shell-dos-semantics)
- (w32-shell-dos-semantics))
- (string-equal ":" (substring ess-sas-file-path 1 2)))
- (progn
- (insert (substring ess-sas-file-path 0 2))
- (comint-send-input)
- ))
-
- (insert "cd \"" (convert-standard-filename
- (file-name-directory ess-sas-file-path)) "\"")
- (comint-send-input)
-
- (insert (concat ess-sas-submit-pre-command " " arg1
- " " arg2
- " " (ess-sas-temp-root) " " ess-sas-submit-post-command))
- (comint-send-input)
- ))
- )
-
- (defun ess-sas-submit-sh (arg1 arg2)
- "Unix or bash in the *shell* buffer.
- Multiple processing is supported on this platform.
- SAS may not be found in your PATH. You can alter your PATH to include
- SAS or you can specify the PATHNAME (PATHNAME can NOT contain spaces),
- i.e. let arg1 be your local equivalent of
- \"/usr/local/sas612/sas\"."
- (if (string-equal (substring
- (file-name-nondirectory ess-sas-file-path) 0 1) ess-kermit-prefix)
- (progn
- (ess-kermit-send)
- (ess-sas-goto-shell t)
- (insert ess-sas-submit-pre-command " " arg1 " "
- (substring (file-name-sans-extension
- (file-name-nondirectory ess-sas-file-path)) 1)
- " " arg2 " " ess-sas-submit-post-command)
- (comint-send-input))
- ;;else
- ;; (ess-sas-goto-shell t)
- (ess-sas-cd)
- ; (insert "cd " (car (last (split-string (file-name-directory ess-sas-file-path)
- ;"\\([a-zA-Z][a-zA-Z]:\\|]\\)"))))
- ; (comint-send-input)
- (insert ess-sas-submit-pre-command " " arg1 " "
- (file-name-sans-extension (file-name-nondirectory ess-sas-file-path))
- " " arg2 " " ess-sas-submit-post-command))
- ; (ess-sleep)
- (comint-send-input))
-
- (defun ess-sas-submit-windows (arg1 arg2)
- "Windows using MS-DOS prompt in the *shell* buffer.
- Multiple processing is supported on this platform.
- On most Windows installations, SAS will not be found in your
- PATH so you should alter your PATH to include SAS, i.e.
-
- SET PATH=%PATH%;C:\\Program Files\\SAS
-
- Or you can specify the PATHNAME directly (you must escape
- spaces by enclosing the string in \\\"'s), i.e. let
- `ess-sas-submit-command' be \"\\\"C:\\Program Files\\SAS\\sas.exe\\\"\".
- Keep in mind that the maximum command line length in MS-DOS is
- 127 characters so altering your PATH is preferable."
- ;(ess-save-and-set-local-variables)
- (ess-sas-goto-shell t)
- (if (string-equal ":" (substring ess-sas-file-path 1 2))
- (progn
- (insert (substring ess-sas-file-path 0 2))
- (comint-send-input)
- )
- )
- (insert "cd \"" (convert-standard-filename
- (file-name-directory ess-sas-file-path)) "\"")
- (comint-send-input)
- (insert ess-sas-submit-pre-command " " arg1 " -sysin \""
- (file-name-sans-extension (file-name-nondirectory ess-sas-file-path)) "\" "
- arg2 " " ess-sas-submit-post-command)
- (comint-send-input))
-
- (defun ess-sas-tab-to-tab-stop ()
- "Tab to next tab-stop and set left margin."
- (interactive)
- (tab-to-tab-stop)
- (setq left-margin (current-column))
- )
-
- (defun ess-sas-temp-root ()
- "Return `ess-sas-file-path' sans extension with `ess-sas-temp-root' appended."
- (concat (file-name-sans-extension ess-sas-file-path) ess-sas-temp-root))
-
- (defun ess-sas-transcript (&optional strip)
- "Comment .log messages to create a .sas program; use C-u to strip."
- (interactive "P")
- (save-excursion
- (goto-char (point-min))
-
- (while (search-forward-regexp (concat
- "^\\(\\(1[ \t]+The SAS System\\|\\|NOTE\\|WARNING\\|ERROR\\|"
- "[ \t]+\\(\\(real\\|cpu\\) time\\|Licensed to\\|Engine:\\|"
- "Physical Name:\\|File Name=\\|Owner Name=\\|Group Name=\\|"
- "Access Permission=\\|File Size (bytes)=\\|Pipe command=\\|"
- "RECFM=[DFNPV],LRECL=\\|[0-9]+:[0-9]+[ /t]+[0-9]+:[0-9]+\\|"
- "[1-9][0-9]* at [0-9]+:[0-9]+[ /t]+[1-9][0-9]* at [0-9]+:[0-9]+\\)\\).*$"
- "\\|[0-9]+\\([ \t]+!\\)?\\|MPRINT([_A-Z]+):\\|"
- "[ \t]+\\(values at the places given by: (Line):(Column).\\|"
- "The m\\(in\\|ax\\)imum record length was [1-9][0-9]*.\\|"
- "One or more lines were truncated.\\|"
- "Each place is given by: (Number of times) at (Line):(Column).\\|"
- "[0-9][0-9]:[0-9][0-9] [MTWFS][aeioudhnrst]+day, [JFMASOND]"
- "[aeiouybcghlmnprstv]+ [1-9][0-9]?, 20[0-9][0-9]\\)\\)")
- nil t) (replace-match (if strip " " "/*\\&*/") t))
- ))
-
- (defun ess-sas-toggle-sas-listing-mode (&optional force)
- "Toggle SAS-listing-mode for .lst files."
- (interactive)
- (ess-sas-goto-lst)
-
- (if (equal (cdr (assoc "\\.[lL][sS][tT]\\'" auto-mode-alist)) 'SAS-listing-mode) (progn
- (setq auto-mode-alist (delete '("\\.[lL][sS][tT]\\'" . SAS-listing-mode) auto-mode-alist))
- (setq buffer-read-only nil)
- (ess-listing-minor-mode 0))
- (setq auto-mode-alist (append '(("\\.[lL][sS][tT]\\'" . SAS-listing-mode)) auto-mode-alist))
- (setq buffer-read-only t)
- (ess-listing-minor-mode 1)))
-
- (defun ess-sas-toggle-sas-log-mode ()
- "Toggle SAS-log-mode for .log files."
- (interactive)
-
- (ess-sas-goto-log)
- (kill-buffer nil)
-
- ; (if (equal (cdr (assoc "\\.[lL][oO][gG]\\'" auto-mode-alist)) 'SAS-log-mode) (progn
- ; (setq auto-mode-alist (delete '("\\.[lL][oO][gG]\\'" . SAS-log-mode) auto-mode-alist))
- ; (setq buffer-read-only nil)
- ; (ess-transcript-minor-mode 0)
- ; (font-lock-mode 0))
- ; (setq auto-mode-alist (append '(("\\.[lL][oO][gG]\\'" . SAS-log-mode)) auto-mode-alist))
- ; (setq buffer-read-only t)
- ; (ess-transcript-minor-mode 1)
- ; (font-lock-mode 1)
- ; (font-lock-fontify-buffer))
-
- (if (equal (cdr (assoc "\\.[lL][oO][gG]\\'" auto-mode-alist)) 'SAS-log-mode)
- (setq auto-mode-alist (delete '("\\.[lL][oO][gG]\\'" . SAS-log-mode) auto-mode-alist))
- (setq auto-mode-alist (append '(("\\.[lL][oO][gG]\\'" . SAS-log-mode)) auto-mode-alist)))
- (ess-sas-goto-log))
-
- (define-obsolete-variable-alias
- 'ess-sas-versions-created 'ess-sas-created-runners "ESS 18.10")
- (defvar ess-sas-created-runners)
- (defun ess-sas-define-runners ()
- "Generate the `M-x SASV' functions for starting other versions of SAS.
- See `ess-sas-versions' for strings that determine which functions are created.
-
- The local variable `ess-sas-created-runners' is used to return list of
- the new SAS defuns, if any, that were created. The defuns will normally
- be placed on the menubar upon ESS initialization."
- ;; This works by creating a temp buffer where the template function is
- ;; edited so that V is replaced by the version number
- (let ((versions
- ;; Find which versions of SAS we want. Remove the pathname,
- ;; leaving just the name of the executable.
- (delete-dups
- (mapcar #'file-name-nondirectory
- (apply #'nconc
- (mapcar #'ess-find-exec-completions
- ess-sas-versions))))))
- ;; Iterate over each string in VERSIONS, creating a new defun each time.
- (setq ess-sas-created-runners
- (mapc (lambda (v) (ess-define-runner v "SAS")) versions))))
- (define-obsolete-function-alias
- 'ess-sas-create-versions 'ess-sas-define-runners "ESS 18.10")
-
-
- ;;; Section 3: Key Definitions
-
-
- (defun ess-sas-edit-keys-set (&optional arg)
- "Set TAB/RET key in `SAS-mode'.
- If arg is nil
- TAB is `sas-indent-line' and
- RET is `newline-and-indent'.
- Else
- TAB is `ess-sas-tab-to-tab-stop',
- C-TAB is `ess-sas-backward-delete-tab' and
- RET is `newline'."
- (interactive)
-
- (if arg
- (progn
- (define-key sas-mode-local-map [(control tab)]
- 'ess-sas-backward-delete-tab)
- (define-key sas-mode-local-map [return] 'newline)
- (define-key sas-mode-local-map "\t" 'ess-sas-tab-to-tab-stop))
- ;;else
- (define-key sas-mode-local-map [return] 'newline-and-indent)
- (define-key sas-mode-local-map "\t" 'sas-indent-line)))
-
- (defvar ess-sas-edit-keys-toggle nil
- "Toggle TAB/RET key in `SAS-mode'.
- nil binds TAB to `sas-indent-line' and RET to `newline-and-indent'.
- Non-nil binds TAB to `ess-sas-tab-to-tab-stop',
- C-TAB to `ess-sas-backward-delete-tab', and RET to `newline'.")
-
- (defun ess-sas-edit-keys-toggle (&optional arg)
- "Toggle `ess-sas-edit-keys-toggle'. Optional arg is still
- accepted for backward compatibility, however, arg is ignored."
- (interactive)
-
- (setq ess-sas-edit-keys-toggle (not ess-sas-edit-keys-toggle))
- (ess-sas-edit-keys-set ess-sas-edit-keys-toggle)
- )
-
- (defvar ess-sas-global-pc-keys nil
- "Non-nil if function keys use PC-like SAS key definitions in all modes.")
-
- (defun ess-sas-global-pc-keys ()
- "PC-like SAS key definitions"
- (interactive)
- (global-set-key [(control f1)] 'ess-sas-rtf-portrait)
- (global-set-key [(control f2)] 'ess-sas-rtf-landscape)
- (global-set-key (quote [f2]) 'ess-revert-wisely)
- (global-set-key (quote [f3]) 'ess-sas-goto-shell)
- (global-set-key (quote [f4]) 'ess-sas-goto-file-1)
- (global-set-key (quote [f5]) 'ess-sas-goto-sas)
- (global-set-key (quote [f6]) 'ess-sas-goto-log)
- (global-set-key [(control f6)] 'ess-sas-append-log)
- (global-set-key (quote [f7]) 'ess-sas-goto-lst)
- (global-set-key [(control f7)] 'ess-sas-append-lst)
- (global-set-key (quote [f8]) 'ess-sas-submit)
- (global-set-key [(control f8)] 'ess-sas-submit-region)
- (global-set-key (quote [f9]) 'ess-sas-data-view-fsview)
- (global-set-key [(control f9)] 'ess-sas-data-view-insight)
- ;; (global-set-key (quote [f10]) 'ess-sas-toggle-sas-log-mode)
- ;; (global-set-key [(control f10)] 'ess-sas-toggle-sas-listing-mode)
- ;; (global-set-key (quote [f11]) 'ess-sas-goto-file-2)
- ;; (global-set-key [(control f11)] 'ess-ebcdic-to-ascii-search-and-replace)
- (global-set-key (quote [f12]) 'ess-sas-graph-view)
- (global-set-key [(control tab)] 'ess-sas-backward-delete-tab)
- ;; (define-key sas-mode-local-map "\C-c\C-p" 'ess-sas-file-path)
- (setq ess-sas-global-pc-keys t)
- (setq ess-sas-global-unix-keys nil)
- (setq ess-sas-local-pc-keys nil)
- (setq ess-sas-local-unix-keys nil)
- )
-
- (defun ess-sas-global-unix-keys ()
- "Unix/Mainframe-like SAS key definitions"
- (interactive)
- (global-set-key [(control f1)] 'ess-sas-rtf-portrait)
- (global-set-key [(control f2)] 'ess-sas-rtf-landscape)
- (global-set-key (quote [f2]) 'ess-revert-wisely)
- (global-set-key (quote [f3]) 'ess-sas-submit)
- (global-set-key [(control f3)] 'ess-sas-submit-region)
- (global-set-key (quote [f4]) 'ess-sas-goto-sas)
- (global-set-key (quote [f5]) 'ess-sas-goto-log)
- (global-set-key [(control f5)] 'ess-sas-append-log)
- (global-set-key (quote [f6]) 'ess-sas-goto-lst)
- (global-set-key [(control f6)] 'ess-sas-append-lst)
- (global-set-key (quote [f7]) 'ess-sas-goto-file-1)
- (global-set-key (quote [f8]) 'ess-sas-goto-shell)
- (global-set-key (quote [f9]) 'ess-sas-data-view-fsview)
- (global-set-key [(control f9)] 'ess-sas-data-view-insight)
- ;; (global-set-key (quote [f10]) 'ess-sas-toggle-sas-log-mode)
- ;; (global-set-key [(control f10)] 'ess-sas-toggle-sas-listing-mode)
- ;; (global-set-key (quote [f11]) 'ess-sas-goto-file-2)
- ;; (global-set-key [(control f11)] 'ess-ebcdic-to-ascii-search-and-replace)
- (global-set-key (quote [f12]) 'ess-sas-graph-view)
- (global-set-key [(control tab)] 'ess-sas-backward-delete-tab)
- ;;(define-key sas-mode-local-map "\C-c\C-p" 'ess-sas-file-path)
- (setq ess-sas-global-pc-keys nil)
- (setq ess-sas-global-unix-keys t)
- (setq ess-sas-local-pc-keys nil)
- (setq ess-sas-local-unix-keys nil)
- )
-
- (defun ess-sas-local-pc-keys ()
- "PC-like SAS key definitions."
- (interactive)
- (define-key sas-mode-local-map [(control f1)] 'ess-sas-rtf-portrait)
- (define-key sas-mode-local-map [(control f2)] 'ess-sas-rtf-landscape)
- (define-key sas-mode-local-map (quote [f2]) 'ess-revert-wisely)
- (define-key sas-mode-local-map (quote [f3]) 'ess-sas-goto-shell)
- (define-key sas-mode-local-map (quote [f4]) 'ess-sas-goto-file-1)
- (define-key sas-mode-local-map (quote [f5]) 'ess-sas-goto-sas)
- (define-key sas-mode-local-map (quote [f6]) 'ess-sas-goto-log)
- (define-key sas-mode-local-map [(control f6)] 'ess-sas-append-log)
- (define-key sas-mode-local-map (quote [f7]) 'ess-sas-goto-lst)
- (define-key sas-mode-local-map [(control f7)] 'ess-sas-append-lst)
- (define-key sas-mode-local-map (quote [f8]) 'ess-sas-submit)
- (define-key sas-mode-local-map [(control f8)] 'ess-sas-submit-region)
- (define-key sas-mode-local-map (quote [f9]) 'ess-sas-data-view-fsview)
- (define-key sas-mode-local-map [(control f9)] 'ess-sas-data-view-insight)
- (define-key sas-mode-local-map (quote [f10]) 'ess-sas-toggle-sas-log-mode)
- (define-key sas-mode-local-map [(control f10)] 'ess-sas-toggle-sas-listing-mode)
- (define-key sas-mode-local-map (quote [f11]) 'ess-sas-goto-file-2)
- (define-key sas-mode-local-map [(control f11)] 'ess-ebcdic-to-ascii-search-and-replace)
- (define-key sas-mode-local-map (quote [f12]) 'ess-sas-graph-view)
- ;(define-key sas-mode-local-map "\C-c\C-p" 'ess-sas-file-path)
- (setq ess-sas-global-pc-keys nil)
- (setq ess-sas-global-unix-keys nil)
- (setq ess-sas-local-pc-keys t)
- (setq ess-sas-local-unix-keys nil)
- )
-
- (defun ess-sas-local-unix-keys ()
- "Unix/Mainframe-like SAS key definitions"
- (interactive)
- (define-key sas-mode-local-map [(control f1)] 'ess-sas-rtf-portrait)
- (define-key sas-mode-local-map [(control f2)] 'ess-sas-rtf-landscape)
- (define-key sas-mode-local-map (quote [f2]) 'ess-revert-wisely)
- (define-key sas-mode-local-map (quote [f3]) 'ess-sas-submit)
- (define-key sas-mode-local-map [(control f3)] 'ess-sas-submit-region)
- (define-key sas-mode-local-map (quote [f4]) 'ess-sas-goto-sas)
- (define-key sas-mode-local-map (quote [f5]) 'ess-sas-goto-log)
- (define-key sas-mode-local-map [(control f5)] 'ess-sas-append-log)
- (define-key sas-mode-local-map (quote [f6]) 'ess-sas-goto-lst)
- (define-key sas-mode-local-map [(control f6)] 'ess-sas-append-lst)
- (define-key sas-mode-local-map (quote [f7]) 'ess-sas-goto-file-1)
- (define-key sas-mode-local-map (quote [f8]) 'ess-sas-goto-shell)
- (define-key sas-mode-local-map (quote [f9]) 'ess-sas-data-view-fsview)
- (define-key sas-mode-local-map [(control f9)] 'ess-sas-data-view-insight)
- (define-key sas-mode-local-map (quote [f10]) 'ess-sas-toggle-sas-log-mode)
- (define-key sas-mode-local-map [(control f10)] 'ess-sas-toggle-sas-listing-mode)
- (define-key sas-mode-local-map (quote [f11]) 'ess-sas-goto-file-2)
- (define-key sas-mode-local-map [(control f11)] 'ess-ebcdic-to-ascii-search-and-replace)
- (define-key sas-mode-local-map (quote [f12]) 'ess-sas-graph-view)
- ;(define-key sas-mode-local-map "\C-c\C-p" 'ess-sas-file-path)
- (setq ess-sas-global-pc-keys nil)
- (setq ess-sas-global-unix-keys nil)
- (setq ess-sas-local-pc-keys nil)
- (setq ess-sas-local-unix-keys t)
- )
-
- (defun ess-kermit-get (&optional ess-file-arg ess-dir-arg)
- "Get a file with Kermit. WARNING: Experimental! From your *shell*
- buffer, start kermit and then log in to the remote machine. Open
- a file that starts with `ess-kermit-prefix'. From that buffer,
- execute this command. It will retrieve a file from the remote
- directory that you specify with the same name, but without the
- `ess-kermit-prefix'."
-
- (interactive)
-
- ;; (save-match-data
- (let ((ess-temp-file (if ess-file-arg ess-file-arg (buffer-name)))
- (ess-temp-file-remote-directory ess-dir-arg))
-
- (if (string-equal ess-kermit-prefix (substring ess-temp-file 0 1))
- (progn
- ;; I think there is a bug in the buffer-local variable handling in GNU Emacs 21.3
- ;; Setting ess-kermit-remote-directory every time is somehow resetting it to the
- ;; default on the second pass. So, here's a temporary work-around. It will fail
- ;; if you change the default, so maybe this variable should not be customizable.
- ;; In any case, there is also trouble with local variables in XEmacs 21.4.9 and
- ;; 21.4.10. XEmacs 21.4.8 is fine.
- (if ess-temp-file-remote-directory
- (setq ess-kermit-remote-directory ess-temp-file-remote-directory)
-
- (if (string-equal "." ess-kermit-remote-directory)
- (setq ess-kermit-remote-directory (read-string "Remote directory to transfer file from: "
- ess-kermit-remote-directory))))
-
- (setq ess-temp-file-remote-directory ess-kermit-remote-directory)
- ;; (setq ess-temp-file (substring ess-temp-file (match-end 0)))
- (ess-sas-goto-shell)
- (insert "cd " ess-temp-file-remote-directory "; " ess-kermit-command " -s "
- (substring ess-temp-file 1) " -a " ess-temp-file)
- (comint-send-input)
- ;; (insert (read-string "Press Return to connect to Kermit: " nil nil "\C-\\c"))
- ;; (comint-send-input)
- ;; (insert (read-string "Press Return when Kermit is ready to recieve: " nil nil
- ;; (concat "receive ]" ess-sas-temp-file)))
- ;; (comint-send-input)
- ;; (insert (read-string "Press Return when transfer is complete: " nil nil "c"))
- ;; (comint-send-input)
- (insert (read-string "Press Return when shell is ready: "))
- (comint-send-input)
- (switch-to-buffer (find-buffer-visiting ess-temp-file))
- (ess-revert-wisely)
- ))))
-
- (defun ess-kermit-send ()
- "Send a file with Kermit. WARNING: Experimental! From
- a file that starts with `ess-kermit-prefix',
- execute this command. It will transfer this file to the remote
- directory with the same name, but without the `ess-kermit-prefix'."
-
- (interactive)
-
- ;; (save-match-data
- (let ((ess-temp-file (expand-file-name (buffer-name)))
- (ess-temp-file-remote-directory nil))
-
- (if (string-equal ess-kermit-prefix (substring (file-name-nondirectory ess-temp-file) 0 1))
- (progn
- ;; I think there is a bug in the buffer-local variable handling in GNU Emacs 21.3
- ;; Setting ess-kermit-remote-directory every time is somehow resetting it to the
- ;; default on the second pass. Here's a temporary work-around. It will fail
- ;; if you change the default, so maybe this variable should not be customizable.
- ;; In any case, there is also trouble with local variables in XEmacs 21.4.9 and
- ;; 21.4.10. XEmacs 21.4.8 is fine.
- (if (string-equal "." ess-kermit-remote-directory)
- (setq ess-kermit-remote-directory (read-string "Remote directory to transfer file to: "
- ess-kermit-remote-directory)))
-
- (setq ess-temp-file-remote-directory ess-kermit-remote-directory)
-
- ;; (setq ess-temp-file (substring ess-temp-file (match-end 0)))
- (ess-sas-goto-shell)
- (insert "cd " ess-temp-file-remote-directory "; " ess-kermit-command " -a "
- (substring (file-name-nondirectory ess-temp-file) 1) " -g " ess-temp-file)
- (comint-send-input)
- ;; (insert (read-string "Press Return to connect to Kermit: " nil nil "\C-\\c"))
- ;; (comint-send-input)
- ;; (insert (read-string "Press Return when Kermit is ready to recieve: " nil nil
- ;; (concat "receive ]" ess-sas-temp-file)))
- ;; (comint-send-input)
- ;; (insert (read-string "Press Return when transfer is complete: " nil nil "c"))
- ;; (comint-send-input)
- (insert (read-string "Press Return when shell is ready: "))
- (comint-send-input)
- (switch-to-buffer (find-buffer-visiting ess-temp-file))
- (ess-revert-wisely)
- ))))
-
- (provide 'ess-sas-a)
-
- ;;; ess-sas-a.el ends here
|