Commits

Anonymous committed 50440d0

sync w/ ESS 5.2.7

  • Participants
  • Parent commits d342a3b

Comments (0)

Files changed (43)

File lisp/ess-cust.el

 ;;; ess-cust.el --- Customize variables for ESS
 
-;; Copyright (C) 1997--2004 A.J. Rossini, Rich M. Heiberger, Martin
+;; Copyright (C) 1997--2005 A.J. Rossini, Rich M. Heiberger, Martin
 ;;	Maechler, Kurt Hornik, Rodney Sparapani, and Stephen Eglen.
 
 ;; Original Author: A.J. Rossini <rossini@u.washington.edu>
   :group 'local)
 
 (defgroup ess-edit nil
-  "ESS: editing behavior."
+  "ESS: editing behavior, including coments/indentation."
   :group 'ess
   :prefix "ess-")
 
 
 ;; Variables (not user-changeable)
 
-(defvar ess-version "5.2.3"
+(defvar ess-version "5.2.7"
   "Version of ESS currently loaded.")
 
 (defvar no-doc
 
 (defcustom ess-S-assign " <- "
   "*String to be used for left assignment in all S dialects.
- Currently only activated by \\[ess-add-MM-keys]."
+ Used by \\[ess-smart-underscore]."
   :group 'ess-S
   :type 'string)
 
 
 ;;;*;;; Indentation parameters
 
-(defvar ess-auto-newline nil
+(defcustom ess-auto-newline nil
   "*Non-nil means automatically newline before and after braces
-inserted in S code.")
+inserted in S code."
+  :type 'boolean
+  :group 'ess-edit)
 
-(defvar ess-tab-always-indent t
+(defcustom ess-tab-always-indent t
   "*Non-nil means TAB in S mode should always reindent the current line,
-regardless of where in the line point is when the TAB command is used.")
+regardless of where in the line point is when the TAB command is used."
+  :type 'boolean
+  :group 'ess-edit)
 
-(defvar ess-indent-level 2
-  "*Indentation of S statements with respect to containing block.")
+(defcustom ess-indent-level 2
+  "*Indentation of S statements with respect to containing block."
+  :type 'integer
+  :group 'ess-edit)
 
-(defvar ess-brace-imaginary-offset 0
-  "*Imagined indentation of an open brace following a statement.")
+(defcustom ess-brace-imaginary-offset 0
+  "*Imagined indentation of an open brace following a statement."
+  :type 'integer
+  :group 'ess-edit)
 
-(defvar ess-brace-offset 0
+(defcustom ess-brace-offset 0
   "*Extra indentation for open braces.
-Compares with other text in same context.")
+Compares with other text in same context."
+  :type 'integer
+  :group 'ess-edit)
 
-(defvar ess-continued-statement-offset 2
-  "*Extra indent for lines not starting new statements.")
+(defcustom ess-continued-statement-offset 2
+  "*Extra indent for lines not starting new statements."
+  :type 'integer
+  :group 'ess-edit)
 
-(defvar ess-continued-brace-offset 0
+(defcustom ess-continued-brace-offset 0
   "*Extra indent for substatements that start with open-braces.
-This is in addition to ess-continued-statement-offset.")
+This is in addition to ess-continued-statement-offset."
+  :type 'integer
+  :group 'ess-edit)
 
-(defvar ess-arg-function-offset 2
+(defcustom ess-arg-function-offset 2
   "*Extra indent for internal substatements of function `foo' that called
 in `arg=foo(...)' form.
-If not number, the statements are indented at open-parenthesis following foo.")
+If not number, the statements are indented at open-parenthesis following foo."
+  :type 'integer
+  :group 'ess-edit)
 
 ;;added rmh 2Nov97 at request of Terry Therneau
-(defvar ess-close-brace-offset 0
-  "*Extra indentation for closing braces.")
+(defcustom ess-close-brace-offset 0
+  "*Extra indentation for closing braces."
+  :type 'integer
+  :group 'ess-edit)
 
 ;;added rmh 2Nov97 at request of Terry Therneau
-(defvar ess-fancy-comments t
-  "*Non-nil means distiguish between #, ##, and ### for indentation.")
+(defcustom ess-fancy-comments t
+  "*Non-nil means distiguish between #, ##, and ### for indentation."
+  :type 'boolean
+  :group 'ess-edit)
 
 
 ;; PeterDalgaard, 1Apr97 :
 ;;The default ess-else-offset should be 0, not 2 IMHO (try looking at
 ;;the ls() function, for instance).  Was 2.
-(defvar ess-else-offset 0
-  "*Extra indent for `else' lines.")
+(defcustom ess-else-offset 0
+  "*Extra indent for `else' lines."
+  :type 'integer
+  :group 'ess-edit)
 
-(defvar ess-expression-offset 4
+(defcustom ess-expression-offset 4
   "*Extra indent for internal substatements of `expression' that specified
 in `obj <- expression(...)' form.
 If not number, the statements are indented at open-parenthesis following
-`expression'.")
+`expression'."
+  :type 'integer
+  :group 'ess-edit)
 
 ;;;*;;; Editing styles
 
 ;;; **FIXME**  The following NEEDS to be customized.
-
+;; SJE: I disagree; this variable should not be customized; individual vars,
+;; such as ess-indent-level are already customizable.
 (defvar ess-default-style-list
   (list 'DEFAULT
 	(cons 'ess-indent-level ess-indent-level)
 	       (ess-expression-offset . 4)
 	       (ess-else-offset . 0)
 	       (ess-close-brace-offset . 2))))
-  "Predefined formatting styles for ess code")
+  "Predefined formatting styles for ESS code.
+Values for all groups, except DEFAULT, are fixed.
+To change the value of variables in the DEFAULT group, change
+the corresponding variables, e.g. `ess-indent-level'.
+The default style in use is controlled by `ess-default-style'.")
 
-(defvar ess-default-style 'DEFAULT
-  "*The default value of `ess-style'.")
+(defcustom ess-default-style 'DEFAULT
+  "*The default value of `ess-style'.
+See the variable `ess-style-alist' for how these groups (DEFAULT,
+GNU, BSD, ...) map onto different settings for variables."
+  :type '(choice (const DEFAULT)
+		 (const GNU)
+		 (const BSD)
+		 (const K&R)
+		 (const C++)
+		 (const :tag "Common R" :value 'RRR)
+		 (const CLB))
+  :group 'ess-edit)
 
 (defvar ess-style ess-default-style
   "*The buffer specific ESS indentation style.")
 ;; FIXME : This is just for the S dialects;  need to define this for others,
 ;; -----
 ;;  {however  "XLS-mode" should just use standard lisp "beginning of function"}
-(defcustom ess-function-pattern
+
+(defcustom ess-R-function-pattern
   (concat
-;;-    "\\(" ; EITHER
-;;-    "\\s\"" ; quote
-;;-    "\\(\\sw\\|\\s_\\)+" ; symbol
-;;-    "\\s\"" ; quote
-;;-    "\\s-*\\(<-\\|_\\)\\(\\s-\\|\n\\)*" ; whitespace, assign, whitespace/nl
-;;-    "function\\s-*(" ; function keyword, parenthesis
-;;-    "\\)\\|\\(" ; OR
-;;-    "\\<\\(\\sw\\|\\s_\\)+" ; symbol
-;;-    "\\s-*\\(<-\\|_\\)\\(\\s-\\|\n\\)*" ; whitespace, assign, whitespace/nl
-;;-    "function\\s-*(" ; function keyword, parenthesis
-;;-    "\\)")
-   ;;----- new version by  "Stephen C. Pope" <scp@predict.com> :
+   "\\(\\(" ; EITHER
+   "\\s\"" ; quote
+   "\\(\\sw\\|\\s_\\)+\\(<-\\)?" ; symbol (replacement?)
+   "\\s\"" ; quote
+   "\\)\\|\\(" ; OR
+   "\\(^\\|[ ]\\)" ; beginning of name
+   "\\(\\sw\\|\\s_\\)+" ; symbol
+   "\\)\\)" ; END EITHER OR
+   "\\s-*\\(<-\\|=\\)" ; whitespace, assign, whitespace/nl
+   "\\(\\(\\s-\\|\n\\)*\\s<.*\\s>\\)*" ; whitespace, comment
+   "\\(\\s-\\|\n\\)*function\\s-*(" ; whitespace, function keyword, parenthesis
+   )
+  "The regular expression for matching the beginning of an R function."
+  :group 'ess
+  :type 'regexp)
+
+(defcustom ess-S-function-pattern
+  ;; the same as "R" - but allowing "_" in assign
+  (concat
    "\\(\\(" ; EITHER
    "\\s\"" ; quote
    "\\(\\sw\\|\\s_\\)+\\(<-\\)?" ; symbol (replacement?)
   :group 'ess
   :type 'regexp)
 
+
 ;; Fixme: the following is just for S dialects :
 (defcustom ess-dumped-missing-re
   "\\(<-\nDumped\n\\'\\)\\|\\(<-\\(\\s \\|\n\\)*\\'\\)"
   :type 'regexp)
 
 ;;;; This is tested for S dialects (actually only for R) -- be careful with it!
-;;(defcustom ess-help-arg-regexp "\\(['\"]?\\)\\([^,=)'\"]*\\)\\1"
-;;  "Reg(ular) Ex(pression) of help(.) arguments.  MUST: 2nd \\(.\\) = arg."
-;;  :group 'ess
-;;  :type  'regexp)
-
 (defvar ess-help-arg-regexp "\\(['\"]?\\)\\([^,=)'\"]*\\)\\1"
   "Reg(ular) Ex(pression) of help(.) arguments.  MUST: 2nd \\(.\\) = arg.")
 
   :group 'ess-R
   :type 'string)
 
+(defcustom inferior-R-objects-command "objects(pos=%d, all.names=TRUE)\n"
+  "Format string for R command to get a list of objects at position %d.
+Used in e.g., \\[ess-execute-objects] or \\[ess-display-help-on-object]."
+  :group 'ess-command
+  :type 'string)
+
 (defcustom ess-r-versions '( "R-1" "R-2")
   "*List of partial strings for versions of R to access within ESS.
 Each string specifies the start of a filename.  If a filename
     "c:/progra~1/Insightful/splus61net/server"
     "c:/progra~1/Insightful/splus6se"
     "c:/progra~1/Insightful/splus61se"
-    "c:/progra~1/Insightful/splus62se")
+    "c:/progra~1/Insightful/splus62se"
+    "c:/progra~1/Insightful/splus70"
+    "c:/progra~1/Insightful/splus71")
   "*List of possible values of the environment variable SHOME for recent
 releases of S-Plus.  These are the default locations for several
 current and recent releases of S-Plus.  If any of these pathnames
   :group 'ess-S
   :type 'string)
 
+(defcustom inferior-Splus-objects-command "objects(where=%d)\n"
+  "Format string for R command to get a list of objects at position %d.
+Used in e.g., \\[ess-execute-objects] or \\[ess-display-help-on-object]."
+  :group 'ess-command
+  :type 'string)
+
 (defcustom inferior-S+6-print-command "S_PRINT_COMMAND=gnuclientw.exe"
   "*Destination of print icon in S+6 for Windows Commands window."
   :group 'ess-S
 ;;		(setq SHOME (expand-file-name (concat pathname "/../..")))))))
 ;;      (setq-default inferior-Sqpe+6-SHOME-name SHOME)))
 
+(defcustom ess-S-quit-kill-buffers-p nil
+  "Controls whether S buffers should also be killed once a process is killed.
+This is used only when an iESS process is killed using C-c C-q.
+Possible values:
+nil - do not kill any S buffers associated with the process.
+t - kill S buffers associated with the process.
+ask - ask the user whether the S buffers should be killed."
+  :group 'ess-S
+  :type '(choice (const nil) (const t) (const ask)))
+
 (defcustom inferior-XLS-program-name "xlispstat"
   "*Program name for invoking an inferior ESS with \\[XLS]."
   :group 'ess-XLS
 ;;; ess-editor and ess-pager,
 ;;; and inferior-ess-language-start
 ;;; apply in principle to the 15 files essd[s-]*.el
-;;; Several of the files (essd-sp4.el and essdsp6w.el) have more
+;;; Several of the files (essd-sp4.el and essd-sp6w.el) have more
 ;;; than one *-customize-alist.
 ;;; These variables are currently used only with the S language files for
 ;;; S S-Plus R.
     (if (equal system-type 'Apple-Macintosh) nil
       (if (featurep 'xemacs) "gnuclient -q" "emacsclient")))
   "*Pager called by S process with 'page()' command."
-;; Change made to provide a better help(function) experience with
-;; S+6 and xemacs
-;; gnuclient -q will open a buffer with an HTML help file
-;; you can view it with M-x browse-url-of-buffer
-:group 'ess
-:type 'string)
-
-(defcustom ess-editor nil
-  "*Editor by which the process sends information to an emacs buffer
-for editing and then to be returned to the process."
-  :group 'ess-proc
+  ;; Change made to provide a better help(function) experience with
+  ;; S+6 and xemacs
+  ;; gnuclient -q will open a buffer with an HTML help file
+  ;; you can view it with M-x browse-url-of-buffer
+  :group 'ess
   :type 'string)
 
-(defcustom ess-pager nil
-  "*Pager by which the process sends information to an emacs buffer."
-  :group 'ess-proc
-  :type '(choice (const nil) string))
+(defvar ess-editor nil
+  "*Editor by which the process sends information to an emacs buffer
+for editing and then to be returned to the process.")
 
-(defcustom inferior-ess-language-start nil
-  "*Initialization commands sent to the ESS process."
-  :group 'ess-proc
-  :type 'string)
+(defvar ess-pager nil
+  "*Pager by which the process sends information to an emacs buffer.")
+
+(defvar inferior-ess-language-start nil
+  "*Initialization commands sent to the ESS process.")
 
 (make-variable-buffer-local 'ess-editor)
 (make-variable-buffer-local 'ess-pager)
 ;;;;; user settable defaults
 (defvar inferior-S-program-name  inferior-S+3-program-name
   "*Program name for invoking an inferior ESS with S().")
+;;- (setq inferior-S-program
+;;-       (cond ((string= S-proc-prefix "S") "Splus")
+;;- 	    ((string= S-proc-prefix "R") "R")
+;;- 	    (t "S")
+;;- 	    ))
+;;(make-local-variable 'inferior-S-program)
 
 (defvar inferior-ess-program nil ;inferior-S-program-name
   "*Default program name for invoking inferior-ess().
 The other variables ...-program-name should be changed, for the
 corresponding program.")
 
-;;(make-local-variable 'inferior-S-program)
 (make-variable-buffer-local 'inferior-ess-program)
 (setq-default inferior-ess-program inferior-S-program-name)
-;;- (setq inferior-S-program
-;;-       (cond ((string= S-proc-prefix "S") "Splus")
-;;- 	    ((string= S-proc-prefix "R") "R")
-;;- 	    (t "S")
-;;- 	    ))
 
 
 (defvar inferior-ess-start-args ""
   :group 'ess-proc
   :type 'boolean)
 
-;;; SJE - suggest this is not defcustom, looks like each mode sets this.
-;;; SJE - this still produces mismatch.
-(defcustom ess-save-lastvalue-command nil
-  "Default depends on the ESS language/dialect.
-
-This is the command to save the last value.  See S section for more details.
-
-Might have to:"
-;;(make-variable-buffer-local 'ess-save-lastvalue-command)
-;;(setq-default ess-save-lastvalue-command
-;;	      "assign(\"smode.lvsave\",.Last.value,frame=0)\n")
-  :group 'ess-command
-  :type 'string)
-
-;;; SJE - suggest this is not defcustom, looks like each mode sets this.
-;;; SJE - this still produces mismatch.
-(defcustom ess-retr-lastvalue-command nil
-  "Default is currently the S+ version."
-  :group 'ess-command
-  :type 'string)
-
-;;(make-variable-buffer-local 'ess-retr-lastvalue-command)
-;;(setq-default ess-retr-lastvalue-command
-;;	      ".Last.value <- get(\"smode.lvsave\",frame=0)\n")
-
 
 ; System variables
 
 ;;*;; Variables relating to multiple processes
 (make-variable-buffer-local 'inferior-ess-exit-command)
 (setq-default inferior-ess-exit-command "q()\n")
 
-(defcustom inferior-ess-search-list-command "search()\n"
+(defvar inferior-ess-search-list-command nil
   "`ess-language' command that prints out the search list;
 i.e. the list of directories and (recursive) objects that `ess-language' uses
 when it searches for objects.
 
-Really set in <ess-lang>-customize-alist in ess[dl]-*.el"
-  :group 'ess-command
-  :type 'string)
-
+Really set in <ess-lang>-customize-alist in ess[dl]-*.el")
+;; and hence made buffer-local via that scheme...
 
 (defcustom inferior-ess-names-command "names(%s)\n"
   "Format string for ESS command to extract names from an object.
   :group 'ess-command
   :type 'string)
 
-(defcustom inferior-ess-objects-command "ls()\n" ;; others: in (S) or (R)
-  "Format string for ESS command to get a list of objects at position %d.
-
-Don't include a newline at the end! Used in ess-execute-objects."
-  :group 'ess-command
-  :type 'string)
-
-(make-variable-buffer-local 'inferior-ess-objects-command)
-(setq-default inferior-ess-objects-command "ls()\n")
-
 (defcustom inferior-ess-get-prompt-command "options()$prompt\n"
   "Command to find the value of the current S prompt."
   :group 'ess-command
   :type 'string)
 
+(defvar ess-cmd-delay nil
+  "*Set to a positive number if ESS will include delays proportional to
+`ess-cmd-delay'  in some places. These delays are introduced to
+prevent timeouts in certain processes, such as completion.")
+(make-variable-buffer-local 'ess-cmd-delay)
+
+(defcustom ess-R-cmd-delay nil
+  "used to initialize `ess-cmd-delay'."
+  :group 'ess-command
+  :type '(choice (const nil) number))
+
+(defcustom ess-S+-cmd-delay 1.0
+  "used to initialize `ess-cmd-delay'."
+  :group 'ess-command
+  :type '(choice (const nil) number))
+
 ;;*;; Regular expressions
 
-(defcustom inferior-ess-prompt nil
+(defvar inferior-ess-prompt nil
   "The regular expression inferior ess mode uses for recognizing prompts.
  Constructed at run time from `inferior-ess-primary-prompt' and
-`inferior-ess-secondary-prompt'."
-  :group 'ess-proc
-  :type '(choice (const nil) string))
+`inferior-ess-secondary-prompt' within `inferior-ess-mode'.")
 
 (make-variable-buffer-local 'inferior-ess-prompt)
 
-(defcustom ess-change-sp-regexp
-  "\\(attach(\\([^)]\\|$\\)\\|detach(\\|collection(\\|library(\\|require(\\|source(\\)"
-  "The regexp for matching the ESS commands that change the search path."
+(defvar ess-change-sp-regexp ""
+  "The regexp for matching the S/R/.. commands that change the search path.")
+(make-variable-buffer-local 'ess-change-sp-regexp)
+
+(defcustom ess-S+-change-sp-regexp
+  "\\(attach(\\([^)]\\|$\\)\\|detach(\\|collection(\\|library(\\|module(\\|source(\\)"
+  "The regexp for matching the S-plus commands that change the search path."
   :group 'ess-proc
   :type 'regexp)
 
+(defcustom ess-S-change-sp-regexp
+  "\\(attach(\\([^)]\\|$\\)\\|detach(\\|library(\\|source(\\)"
+  "The regexp for matching the S commands that change the search path."
+  :group 'ess-proc
+  :type 'regexp)
+
+(defcustom ess-R-change-sp-regexp
+  "\\(attach(\\([^)]\\|$\\)\\|detach(\\|library(\\|require(\\|source(\\)"
+  "The regexp for matching the R commands that change the search path."
+  :group 'ess-proc
+  :type 'regexp)
+
+
 ;;*;; Process-dependent variables
 
 (defvar ess-search-list nil
 
 (defvar ess-mode-minibuffer-map nil)
 
-(defcustom ess-object-name-db-file "ess-namedb"
-  "File containing definitions for `ess-object-name-db'."
-  :group 'ess
-  :type 'file)
+;; SJE: Wed 29 Dec 2004 - following 3 ess-object* variables can be removed
+;; soon if no-one needs the completion code.
+(defvar ess-object-name-db-file "ess-namedb"
+  "File containing definitions for `ess-object-name-db'.")
 
 (defvar ess-object-name-db-file-loaded '()
   "List of programs whose name-db file has been loaded.")
 (make-variable-buffer-local 'ess-object-name-db)
 (setq-default ess-object-name-db nil)
 
-(defcustom ess-S-loop-timeout 1200000
+(defcustom ess-S-loop-timeout 2000000
   "Integer specifying how many loops ess-mode will wait for the prompt
 before signaling an error. Will be set to `ess-loop-timeout' in the S dialects'
 alists.  Increase this, if you have a fast(er) machine."
   :group 'ess
   :type 'boolean)
 
-(defvar ess-mode-font-lock-keywords
-  '(("<<-\\|<-\\|->" ; 2004-01: dropped "_" -- TODO later: for function-name
-     . font-lock-reference-face)
-    ("\\<\\(TRUE\\|FALSE\\|T\\|F\\|NA\\|NULL\\|Inf\\|NaN\\)\\>"
-     . font-lock-type-face)
-    ("\\<\\(library\\|require\\|attach\\|detach\\|source\\)\\>"
-     . font-lock-reference-face)
-    ("\\<\\(while\\|for\\|in\\|repeat\\|if\\|else\\|switch\\|break\\|next\\|return\\|stop\\|warning\\|function\\)\\>"
-     . font-lock-keyword-face) ; TODO : drop "_" (here and below)
-    ("\\s\"?\\(\\(\\sw\\|\\s_\\)+\\(<-\\)?\\)\\s\"?\\s-*\\(<-\\|_\\|=\\)\\(\\s-\\|\n\\)*function"
-     1 font-lock-function-name-face t))
-  "Font-lock patterns used in `ess-mode' buffers.")
+(defvar ess-R-constants
+  '("TRUE" "FALSE" "NA" "NULL" "Inf" "NaN"))
 
-(defvar inferior-ess-font-lock-keywords
-  '(("<<-\\|<-\\|->"
-     . font-lock-reference-face)		; assign
-    ("^\\*\\*\\*.*\\*\\*\\*\\s *$"
-     . font-lock-comment-face) ; ess-mode msg
-    ("\\[,?[1-9][0-9]*,?\\]"
-     . font-lock-reference-face)	; Vector/matrix labels
-    ("\\<\\(TRUE\\|FALSE\\|T\\|F\\|NA\\|NULL\\|Inf\\|NaN\\)\\>"
-     . font-lock-type-face) ; keywords
-    ("\\<\\(library\\|attach\\|detach\\|source\\)\\>"
-     . font-lock-reference-face) ; modify search list or source new definitions
-    ("^Syntax error:"
-     . font-lock-reference-face);inferior-ess problems or errors
-    ("^Error:"
-     . font-lock-reference-face)
-    ("^Error in"
-     . font-lock-reference-face)
-    ("^Dumped"
-     . font-lock-reference-face)
-    ("^Warning messages:"
-     . font-lock-reference-face)
-    ("#"
-     . font-lock-comment-face) ; comment
-    ("^[^#]*#\\(.*$\\)"
-     (1 font-lock-comment-face keep t)) ; comments
-    ("\\s\"?\\(\\(\\sw\\|\\s_\\)+\\)\\s\"?\\s-*\\(<-\\|_\\)\\(\\s-\\|\n\\)*function"
-     1 font-lock-function-name-face t) ; function name
-    ("\\<\\(while\\|for\\|in\\|repeat\\|if\\|else\\|switch\\|break\\|next\\|return\\|stop\\|warning\\|function\\)\\>"
-     . font-lock-keyword-face) ; keywords
-    )
-  "Font-lock patterns used in inferior-ess-mode buffers.")
+(defvar ess-S-constants
+  (append ess-R-constants '("T" "F")))
 
-;; add-to-list() places keywords in front of the previous keywords
-;; input and prompt must appear in inferior-ess-font-lock-keywords
-;; in the order  prompt error, hence they appear here in the reverse
-;; order.
+;; first the common ones
+(defvar ess-S-modifyiers
+  '("library" "attach" "detach" "source" "module"))
+(defvar ess-R-modifyiers
+  '("library" "attach" "detach" "source" "require"))
 
-(if (not inferior-ess-font-lock-input)
-    (add-to-list 'inferior-ess-font-lock-keywords
-		 '("^[a-zA-Z0-9 ]*[>+]\\(.*$\\)"
-		   (1 font-lock-variable-name-face keep t));don't font-lock input
-		 ))
-(add-to-list 'inferior-ess-font-lock-keywords
-	     '("^[a-zA-Z0-9 ]*[>+]" . font-lock-keyword-face))	; prompt
+(defvar ess-R-keywords
+  '("while" "for" "in" "repeat" "if" "else" "switch" "break" "next"
+    "function" "return" "message" "warning" "stop"))
+(defvar ess-S-keywords
+  (append ess-R-keywords '("terminate")))
 
-(defvar ess-trans-font-lock-keywords
- inferior-ess-font-lock-keywords
- "Font-lock patterns used in `ess-transcript-mode' buffers.")
+(defvar ess-R-message-prefixes
+  '("Error:" "Error in"
+    "Warning:" "Warning in"
+    "Warning messages?"))
+(defvar ess-S-message-prefixes
+  (append ess-R-message-prefixes
+	  '("Syntax error:" "Dumped")))
 
 ;;
-;;(defvar ess-mode-font-lock-keywords
-;; '(("\\s\"?\\(\\(\\sw\\|\\s_\\)+\\)\\s\"?\\s-*\\(<-\\|_\\)\\(\\s-\\|\n\\)*function" 1 font-lock-function-name-face t)
-;;   ("<<?-\\|_" . font-lock-reference-face)
-;;   ("\\<\\(TRUE\\|FALSE\\|T\\|F\\|NA\\|NULL\\|Inf\\|NaN\\)\\>" . font-lock-type-face)
-;;   ("\\<\\(library\\|attach\\|detach\\|source\\)\\>" . font-lock-reference-face)
-;;   "\\<\\(while\\|for\\|in\\|repeat\\|if\\|else\\|switch\\|break\\|next\\|return\\|stop\\|warning\\|function\\)\\>")
-;; "Font-lock patterns used in ess-mode bufffers.")
-;;
-;;(defvar essd-S-inferior-font-lock-keywords
-;; '(("^[a-zA-Z0-9 ]*[>+]" . font-lock-keyword-face)	; prompt
-;;   ("^[a-zA-Z0-9 ]*[>+]\\(.*$\\)"
-;;    (1 font-lock-variable-name-face keep t)) ; input
-;;   ("<-\\|_" . font-lock-reference-face)		; assign
-;;   ("^\\*\\*\\\*.*\\*\\*\\*\\s *$" . font-lock-comment-face) ; ess-mode msg
-;;   ("\\[,?[1-9][0-9]*,?\\]" . font-lock-reference-face)	; Vector/matrix labels
-;;   ("^Syntax error:" . font-lock-reference-face) ; error message
-;;   ("^Error:" . font-lock-reference-face) ; error message
-;;   ("^Error in" . font-lock-reference-face) ; error message
-;;   ("^Dumped" . font-lock-reference-face) ; error message
-;;   ("^Warning:" . font-lock-reference-face) ; warning message
-;;   ("\\<\\(TRUE\\|FALSE\\|T\\|F\\|NA\\|NULL\\|Inf\\|NaN\\)\\>"
-;;    . font-lock-type-face)) ; keywords
-;; "Font-lock patterns for dialects of S, used in highlighting process
-;; buffers and transcripts.")
-;;
-;;(defvar inferior-ess-font-lock-keywords
-;;  essd-S-inferior-font-lock-keywords
-;; "Font-lock patterns used in inferior-ess-mode buffers.")
-;;
-;;(defvar ess-trans-font-lock-keywords
-;;  essd-S-inferior-font-lock-keywords
-;; "Font-lock patterns used in ess-transcript-mode buffers.")
+(defvar ess-R-assign-ops
+  '("<<-" "<-" "->") ; don't want "=" here which is not only for assign
+)
+(defvar ess-S-assign-ops
+  '("<<-" "<-" "_" "->") ; don't want "=" here which is not only for assign
+)
+
+(defvar ess-R-function-name-regexp
+  (concat "\\s\"?\\(\\(\\sw\\|\\s_\\)+"
+	  "\\(<-\\)?\\)\\s\"?\\s-*\\(<-\\)"
+	  "\\(\\s-\\|\n\\)*function")
+)
+(defvar ess-S-function-name-regexp
+  ess-R-function-name-regexp ; since "_" is deprecated for S-plus as well
+)
+
+
+(defvar ess-R-mode-font-lock-keywords
+  (list
+   (cons (regexp-opt ess-R-assign-ops)
+	 'font-lock-reference-face)	; assign
+   (cons (concat "\\<" (regexp-opt ess-R-constants 'enc-paren) "\\>")
+	 'font-lock-type-face)		; constants
+   (cons (concat "\\<" (regexp-opt ess-R-modifyiers 'enc-paren) "\\>")
+	 'font-lock-reference-face)	; modify search list or source
+					; new definitions
+   (cons (concat "\\<" (regexp-opt ess-R-keywords 'enc-paren) "\\>")
+	 'font-lock-keyword-face)	; keywords
+   (cons ess-R-function-name-regexp
+	 '(1 font-lock-function-name-face t))
+					; function name
+    )
+  "Font-lock patterns used in `R-mode' buffers.")
+
+(defvar ess-S-mode-font-lock-keywords
+  (list
+   (cons (regexp-opt ess-S-assign-ops)
+	 'font-lock-reference-face)	; assign
+   (cons (concat "\\<" (regexp-opt ess-S-constants 'enc-paren) "\\>")
+	 'font-lock-type-face)		; constants
+   (cons (concat "\\<" (regexp-opt ess-S-modifyiers 'enc-paren) "\\>")
+	 'font-lock-reference-face)	; modify search list or source
+					; new definitions
+   (cons (concat "\\<" (regexp-opt ess-S-keywords 'enc-paren) "\\>")
+	 'font-lock-keyword-face)	; keywords
+   (cons ess-S-function-name-regexp
+	 '(1 font-lock-function-name-face t))
+					; function name
+   )
+  "Font-lock patterns used in `S-mode' buffers.")
+
+
+
+
+(defvar inferior-ess-R-font-lock-keywords
+  (append
+   '(("^[a-zA-Z0-9 ]*[>+]" . font-lock-keyword-face)) ; "prompt" must be first
+
+   (if (not inferior-ess-font-lock-input) ;; don't font-lock input :
+       (list (cons "^[a-zA-Z0-9 ]*[>+]\\(.*$\\)"
+		   '(1 font-lock-variable-name-face keep t))) )
+
+   ess-R-mode-font-lock-keywords
+
+   (list
+    (cons "^\\*\\*\\*.*\\*\\*\\*\\s *$" 'font-lock-comment-face); ess-mode msg
+    (cons "\\[,?[1-9][0-9]*,?\\]" 'font-lock-reference-face);Vector/matrix labels
+    (cons (concat "^" (regexp-opt ess-R-message-prefixes 'enc-paren))
+	  'font-lock-reference-face) ; inferior-ess problems or errors
+    (cons "#" 	'font-lock-comment-face) ; comment
+    (cons "^[^#]*#\\(.*$\\)" '(1 font-lock-comment-face keep t)) ; comments
+		 ))
+  "Font-lock patterns used in inferior-R-mode buffers.")
+
+(defvar inferior-ess-S-font-lock-keywords
+  (append
+   '(("^[a-zA-Z0-9 ]*[>+]" . font-lock-keyword-face)) ; "prompt" must be first
+
+   (if (not inferior-ess-font-lock-input) ;; don't font-lock input :
+       (list (cons "^[a-zA-Z0-9 ]*[>+]\\(.*$\\)"
+		   '(1 font-lock-variable-name-face keep t))) )
+
+   ess-S-mode-font-lock-keywords
+
+   (list
+    (cons "^\\*\\*\\*.*\\*\\*\\*\\s *$" 'font-lock-comment-face) ; ess-mode msg
+    (cons "\\[,?[1-9][0-9]*,?\\]" 'font-lock-reference-face);Vector/matrix labels
+    (cons (concat "^" (regexp-opt ess-S-message-prefixes 'enc-paren))
+	  'font-lock-reference-face) ; inferior-ess problems or errors
+    (cons "#" 'font-lock-comment-face)	; comment
+    (cons "^[^#]*#\\(.*$\\)" '(1 font-lock-comment-face keep t)) ; comments
+    ))
+  "Font-lock patterns used in inferior-S-mode buffers.")
+
+;; use the inferior-* ones directly in ess-trns.el
+;; (defvar ess-trans-font-lock-keywords
+;;   inferior-ess-font-lock-keywords
+;;   "Font-lock patterns used in `ess-transcript-mode' buffers.")
 
 
 ;;;*;;; ess-help variables
   :group 'ess-help
   :type 'alist)
 
-(defconst ess-help-S-sec-regex "^[A-Z. ---]+:$"
-  "Reg(ular) Ex(pression) of section headers in help file")
-
-
 
 
 ; User changeable variables
 ;;;=====================================================
 
 ;;*;; Variables relating to ess-help-mode
 
-;;-- ess-help-S-.. and  ess-help-R-.. constants now  in   S.el (are used in ess-inf).
+;;-- ess-help-S-.. and  ess-help-R-.. : in  essl-s.el (are used in ess-inf).
 
 (defvar ess-help-sec-keys-alist nil
   "Alist of (key . string) pairs for use in section searching.")
   :group 'ess-proc
   :type 'string)
 
+(defcustom ess-verbose nil
+  "if non-nil, write more information to `ess-dribble-buffer' than usual."
+  :group 'ess-proc
+  :type 'boolean)
+
 (defvar ess-dribble-buffer (generate-new-buffer "*ESS*")
   "Buffer for temporary use for setting default variable values.
 Used for recording status of the program, mainly for debugging.")

File lisp/ess-emcs.el

 ;;; ess-emcs.el --- simple determination of Emacs/XEmacs and version #.
 
-;; Copyright (C) 2000--2004 A.J. Rossini, Rich M. Heiberger, Martin
+;; Copyright (C) 2000--2005 A.J. Rossini, Rich M. Heiberger, Martin
 ;;	Maechler, Kurt Hornik, Rodney Sparapani, and Stephen Eglen.
 
 ;; Original Author: A.J. Rossini <rossini@biostat.washington.edu>
   "Value is nil if custom.el not available, t if available.
 Only a concern with earlier versions of Emacs.")
 
+;; FIXME:  When emacs is started from Cygwin shell in Windows,
+;;         we have (equal window-system 'x) -and should use "--ess" in *d-r.el
 (defvar ess-microsoft-p (or (equal window-system 'w32)
 			    ;; XEmacs only...
 ;;;			    (equal (console-type) 'pc)
 ;; XEmacs 20.x needs this
 (if (not (fboundp 'find-buffer-visiting))
     (fset 'find-buffer-visiting 'get-file-buffer))
+;; XEmacs <= 21.4.15 needs this
+(if (not (fboundp 'line-beginning-position))
+    (defalias 'line-beginning-position 'point-at-bol))
 
 (if (and (not (featurep 'xemacs))
 	 (string-match "XEmacs\\|Lucid" emacs-version))
     (provide 'xemacs))
 
 ;; XEmacs 21.x and Emacs 20.x need this
-(if (not (fboundp 'replace-regexp-in-string))
-    (if (featurep 'xemacs)
-	(defun replace-regexp-in-string(regexp replace string)
+(cond ((fboundp 'replace-regexp-in-string)
+       (defalias 'ess-replace-regexp-in-string 'replace-regexp-in-string))
+      ((featurep 'xemacs)
+	(defun ess-replace-regexp-in-string(regexp replace string)
 	  "Mimic GNU Emacs function replace-regexp-in-string with XEmacs' replace-in-string"
-	  (replace-in-string string regexp replace))
+	  (replace-in-string string regexp replace)))
 
       ;; GNU emacs <= 20 -- take Emacs' 21(.3)'s definition:
-      (defun replace-regexp-in-string (regexp rep string &optional
+      (t (defun ess-replace-regexp-in-string (regexp rep string &optional
 					      fixedcase literal subexp start)
 	"Replace all matches for REGEXP with REP in STRING.
 
 
 To replace only the first match (if any), make REGEXP match up to \\'
 and replace a sub-expression, e.g.
-  (replace-regexp-in-string \"\\(foo\\).*\\'\" \"bar\" \" foo foo\" nil nil 1)
+  (ess-replace-regexp-in-string \"\\(foo\\).*\\'\" \"bar\" \" foo foo\" nil nil 1)
     => \" bar foo\"
 "
 
       )
 )
 
+;; remassoc exists as a built-in function in xemacs, but
+;; not in GNU emacs
+;;
+(if (not (functionp 'remassoc))
+    (defun remassoc (key a)
+      "remove an association pair from an alist"
+      (if a
+	  (let ((pair (car a)))
+	    (if (equal (car pair) key)
+		(cdr a)
+		(cons pair (remassoc key (cdr a))))))))
+
 (if (not (fboundp 'w32-using-nt))
 (defun w32-using-nt ()
   "Return non-nil if literally running on Windows NT (i.e., not Windows 9X)."
   (and (eq system-type 'windows-nt) (getenv "SystemRoot"))))
 
-(if (and (featurep 'xemacs) (fboundp 'extent-at)
-	(fboundp 'make-extent) (fboundp 'set-extent-property))
+(if (and (featurep 'xemacs)
+	 (fboundp 'extent-at)
+	 (fboundp 'make-extent)
+	 (fboundp 'set-extent-property))
   (defun ess-xemacs-insert-glyph (gl)
      "Insert a glyph at the left edge of point."
-     (let ( (prop 'myimage)        ;; myimage is an arbitrary name, chosen 
-                                   ;; to (hopefully) not conflict with any
-                                   ;; other properties.  Change it if
-                                   ;; necessary.
-            extent )
+     (let ((prop 'myimage) ;; myimage is an arbitrary name, chosen to
+	   ;;                 (hopefully) not conflict with any other
+	   ;;                 properties. Change it if necessary.
+            extent)
        ;; First, check to see if one of our extents already exists at
        ;; point.  For ease-of-programming, we are creating and using our
        ;; own extents (multiple extents are allowed to exist/overlap at the
 	   (w32-system-shell-p (getenv "COMSPEC")))))
 )
 
+;; XEmacs need this (unless configured with  --with-mule=yes)
+(if (not (boundp 'enable-multibyte-characters))
+    (defvar enable-multibyte-characters nil
+      "Non-nil means the buffer contents are regarded as multi-byte characters.
+ This concept is handled completely differently on Xemacs."))
+
+
 ;; XEmacs on Windows needs this
 (if (and ess-microsoft-p
 	 (not (fboundp 'w32-short-file-name)))

File lisp/ess-help.el

 	      (if (not (listp nodocs))
 		  (setq nodocs (list PM (point-max))))
 	      (ess-write-to-dribble-buffer
-	       (format "(ess-help: error-buffer %s nodocs (%d %d)\n"
+	       (format "(ess-help: error-buffer '%s' nodocs (%d %d)\n"
 		       (buffer-name) (car nodocs) (cadr nodocs)))
 	      ;; Avoid using 'message here -- may be %'s in string
 	      ;;(princ (buffer-substring (car nodocs) (cadr nodocs)) t)
 	  ;; else : show it
 
 	  ;;dbg (ess-write-to-dribble-buffer
-	  ;;dbg  (format "(ess-help %s before switch-to..\n" hb-name)
+	  ;;dbg	 (format "(ess-help '%s' before switch-to..\n" hb-name)
 	  (let ((special-display-regexps 
 		 (if ess-help-own-frame '(".") nil))
 		(special-display-frame-alist ess-help-frame-alist)
 
 ;;; THIS WORKS!
 ;;(require 'w3)
-(defun ess-display-w3-help-on-object-other-window (object)
-  "Display R-documentation for OBJECT using W3"
-  (interactive "s Help on :")
-  (let* ((ess-help-url (concat ess-help-w3-url-prefix
-			       ess-help-w3-url-funs
-			       object
-			       ".html")))
+;(defun ess-display-w3-help-on-object-other-window (object)
+;  "Display R-documentation for OBJECT using W3"
+;  (interactive "s Help on :")
+;  (let* ((ess-help-url (concat ess-help-w3-url-prefix
+;			       ess-help-w3-url-funs
+;			       object
+;			       ".html")))
     ;;(w3-fetch-other-window ess-help-url)
-    ))
+;    ))
 
 
 ;;*;; Major mode definition
   (define-key ess-help-mode-map "\177" 'scroll-down) ; DEL
   (define-key ess-help-mode-map "s" ess-help-sec-map)
   (define-key ess-help-mode-map "h" 'ess-display-help-on-object)
+;; TODO: `electric mouse-2'
+;; (define-key ess-help-mode-map [mouse-2] 'ess-display-help-on-object)
   (define-key ess-help-mode-map "l" 'ess-eval-line-and-step)
   (define-key ess-help-mode-map "r" 'ess-eval-region-and-go)
   (define-key ess-help-mode-map "n" 'ess-skip-to-next-section)
 		    "Menu keymap for ess-help mode." ess-help-mode-menu)
   (easy-menu-add ess-help-mode-menu-map ess-help-mode-map)
 
-  (run-hooks ess-help-mode-hook))
+  (run-hooks 'ess-help-mode-hook))
 
 ;;*;; User commands defined in ESS help mode
 

File lisp/ess-inf.el

 ;; Copyright (C) 1989-1994 Bates, Kademan, Ritter and Smith
 ;; Copyright (C) 1997-1999 A.J. Rossini <rossini@u.washington.edu>,
 ;; Martin Maechler <maechler@stat.math.ethz.ch>.
-;; Copyright (C) 2000--2004 A.J. Rossini, Rich M. Heiberger, Martin
+;; Copyright (C) 2000--2005 A.J. Rossini, Rich M. Heiberger, Martin
 ;;	Maechler, Kurt Hornik, Rodney Sparapani, and Stephen Eglen.
 
 ;; Original Author: David Smith <dsmith@stats.adelaide.edu.au>
 (autoload 'ess-beginning-of-function	    "ess-mode"  "(autoload)." t)
 (autoload 'ess-end-of-function		    "ess-mode"  "(autoload)." t)
 (autoload 'ess-extract-word-name	    "ess-utils" "(autoload)." t)
+(autoload 'ess-uniq-list		    "ess-utils" "(autoload)." t)
 
 (autoload 'ess-transcript-send-command-and-move "ess-trns" "(autoload)." t)
 
         (ess-multi procname buf inferior-ess-start-args)))))
 
 
+(defvar inferior-ess-objects-command nil
+  "The language/dialect specific command for listing objects.
+It is initialized from the corresponding inferior-<lang>-objects-command
+and then made buffer local."); and the *-<lang>-* ones are customized!
+(make-variable-buffer-local 'inferior-ess-objects-command)
+
+(defvar ess-save-lastvalue-command nil
+  "The command to save the last value.  See S section for more details.
+Default depends on the ESS language/dialect and hence made buffer local")
+(make-variable-buffer-local 'ess-save-lastvalue-command)
+
+(defvar ess-retr-lastvalue-command nil
+  "The command to retrieve the last value.  See S section for more details.
+Default depends on the ESS language/dialect and hence made buffer local")
+(make-variable-buffer-local 'ess-retr-lastvalue-command)
+
 ;;; A note on multiple processes: the following variables
 ;;;	ess-local-process-name
 ;;;	ess-search-list
 	 (format "(ess-multi 0):  inf-ess-start-args=%s, comint-..echoes=%s\n"
 	       inf-ess-start-args comint-process-echoes))
 	(set-buffer buffer)
-	(setq-default inferior-ess-prompt
-		      ;; shouldn't be setq-default!  And I've
-		      ;; forgotten why!   (AJR)
-
-		      ;; Do not anchor to bol with `^'
-		      (concat "\\("
-			      inferior-ess-primary-prompt
-			      "\\|"
-			      inferior-ess-secondary-prompt
-			      "\\)"))
 	(inferior-ess-mode)
 	(ess-write-to-dribble-buffer
 	 (format "(ess-multi post inf-ess: start-args=%s, comint-echoes=%s\n"
 	(setq ess-sl-modtime-alist nil)
 	;; Get search list when needed
 	(setq ess-sp-change t)
+
+	;; Add the process filter to catch certain output.
+	(set-process-filter (get-process proc-name)
+			    'inferior-ess-output-filter)
+	
 	(run-hooks 'ess-post-run-hook))
-      (if inferior-ess-same-window
+      (if (and inferior-ess-same-window (not inferior-ess-own-frame))
 	  (switch-to-buffer (process-buffer (get-process proc-name)))
 	(pop-to-buffer (process-buffer (get-process proc-name)))))))
 
+(defun inferior-ess-output-filter (proc string)
+  "Standard output filter for the inferior ESS process.
+Ring Emacs bell if process output starts with an ASCII bell, and pass
+the rest to `comint-output-filter'.
+Taken from octave-mod.el."
+  (comint-output-filter proc (inferior-ess-strip-ctrl-g string)))
+
+(defun inferior-ess-strip-ctrl-g (string)
+  "Strip leading `^G' character.
+If STRING starts with a `^G', ring the Emacs bell and strip it.
+Depending on the value of `visible-bell', either the frame will
+flash or you'll hear a beep.  Taken from octave-mod.el."
+  (if (string-match "^\a" string)
+      (progn
+        (ding)
+        (setq string (substring string 1))))
+  string)
+
 
 (defun ess-process-sentinel (proc message)
   "Sentinel for use with ESS processes.
 		   ess-local-process-name 'inferior-ess-ddeclient)
 		  (default-value 'inferior-ess-ddeclient)))))
 
-(defun ess-prompt-wait (proc &optional start-of-output)
+(defun ess-prompt-wait (proc &optional start-of-output sleep)
   "Wait for a prompt to appear at BOL of current buffer.
 PROC is the ESS process. Does not change point"
+  (if sleep (sleep-for sleep)); we sleep here, *and* wait below
   (if start-of-output nil (setq start-of-output (point-min)))
   (save-excursion
     (while (progn
 	     ;; get output if there is some ready
-	     (if (or (equal window-system 'w32) (equal window-system 'win32))
-		 (accept-process-output proc 0 1500) ; Microsoft is slow
-	       (accept-process-output proc 0 500))
+
+;; 	     (if (and ess-microsoft-p ess-ms-slow)
+;; 		 (accept-process-output proc 0 1500) ; Microsoft is slow
+	       (accept-process-output proc 0 500)
+;; 	       )
 	     (goto-char (marker-position (process-mark proc)))
 	     (beginning-of-line)
 	     (if (< (point) start-of-output) (goto-char start-of-output))
 	  (if moving (goto-char (process-mark proc))))
       (set-buffer old-buffer))))
 
-(defun ess-command (com &optional buf)
+(defun ess-command (com &optional buf sleep)
   "Send the ESS process command COM and delete the output
 from the ESS process buffer.  If an optional second argument BUF exists
 save the output in that buffer. BUF is erased before use.
 COM should have a terminating newline.
-Guarantees that the value of .Last.value will be preserved."
-  ;; Use this function when you need to evaluate so S code, and the
+Guarantees that the value of .Last.value will be preserved.
+When optional third arg SLEEP is non-nil, `(sleep-for (* a SLEEP))'
+will be used in a few places where `a' is proportional to `ess-cmd-delay'."
+  ;; Use this function when you need to evaluate some S code, and the
   ;; result is needed immediately. Waits until the output is ready
   (let* ((sprocess (get-ess-process ess-current-process-name))
 	 sbuffer
-	 end-of-output
-	 oldpb
-	 oldpf
-	 oldpm)
+	 do-sleep end-of-output
+	 oldpb oldpf oldpm
+	 my-retr-cmd my-save-cmd)
     (if sprocess nil
       (error "Process %s is not running!" ess-current-process-name))
     (setq sbuffer (process-buffer sprocess))
     (save-excursion
       (set-buffer sbuffer)
+      (setq do-sleep		    ; only now when in sprocess buffer
+	    (progn
+	      (if sleep (if (numberp sleep) nil (setq sleep 1))); t means 1
+	      (and ess-cmd-delay sleep)))
+      (if do-sleep (setq sleep (* sleep ess-cmd-delay)))
       (save-excursion
 	(goto-char (marker-position (process-mark sprocess)))
 	(beginning-of-line)
       (setq oldpf (process-filter sprocess))
       (setq oldpb (process-buffer sprocess))
       (setq oldpm (marker-position (process-mark sprocess)))
+      ;; need the buffer-local values in result buffer "buf":
+      (setq my-retr-cmd ess-retr-lastvalue-command)
+      (setq my-save-cmd ess-save-lastvalue-command)
       (unwind-protect
 	  (progn
 	    (set-process-buffer sprocess buf)
 	    (set-process-filter sprocess 'ordinary-insertion-filter)
-	    ;; Output is now going to BUF
+	    ;; Output is now going to BUF:
 	    (save-excursion
 	      (set-buffer buf)
 	      (erase-buffer)
 	      (set-marker (process-mark sprocess) (point-min))
-	      (process-send-string sprocess ess-save-lastvalue-command)
-	      (if (or (equal window-system 'w32) (equal window-system 'win32))
-		  (sleep-for 0.5))
-	      (ess-prompt-wait sprocess)
+	      (process-send-string sprocess my-save-cmd)
+
+	      (ess-prompt-wait sprocess nil (and do-sleep (* 0.05 sleep)))
 	      (erase-buffer)
 	      (process-send-string sprocess com)
-	      (if (or (equal window-system 'w32) (equal window-system 'win32))
-		  (sleep-for 4))	;this much time is needed for
-					;ess-create-object-name-db on PC
-	      (ess-prompt-wait sprocess)
-	      (if (or (equal window-system 'w32) (equal window-system 'win32))
-		  (sleep-for 0.5))
+
+	      ;; need time for ess-create-object-name-db on PC
+	      (ess-prompt-wait sprocess nil (and do-sleep (* 0.4 sleep)));MS: 4
+	      ;;(if do-sleep (sleep-for (* 0.0 sleep))); microsoft: 0.5
 	      (goto-char (point-max))
 	      (save-excursion
 		(beginning-of-line)	; so prompt will be deleted
 		(setq end-of-output (point)))
-	      (process-send-string sprocess ess-retr-lastvalue-command)
+	      (process-send-string sprocess my-retr-cmd)
 
-	      ;; For S+4
-	      (if (or (equal window-system 'w32) (equal window-system 'win32))
-		  (sleep-for 0.5))
-	      (ess-prompt-wait sprocess end-of-output)
+	      (ess-prompt-wait sprocess end-of-output
+			       (and do-sleep (* 0.05 sleep))); microsoft: 0.5)
 
-	      ;; Old version.
-	      ;;(ess-prompt-wait sprocess (point))
-
-	      ;; Get rid out output from last assin
+	      ;; Get rid out output from last assign
 	      (delete-region end-of-output (point-max))))
 	;; Restore old values for process filter
 	(set-process-buffer sprocess oldpb)
 	(insert-before-markers (concat "*** " invisibly " ***\n")))
     ;; dbg:
     ;; dbg (ess-write-to-dribble-buffer
-    ;; dbg  (format "(eval-visibly 2): text[%d]= %s\n" (length text) text))
+    ;; dbg  (format "(eval-visibly 2): text[%d]= '%s'\n" (length text) text))
     (while (or (setq txt-gt-0 (> (length text) 0))
 	       even-empty)
       (if even-empty (setq even-empty nil))
 	    (ess-check-modifications))))
     (let ((errbuffer (ess-create-temp-buffer ess-error-buffer-name))
 	  error-occurred nomessage)
-      (ess-command (format inferior-ess-load-command filename) errbuffer)
+      (ess-command (format inferior-ess-load-command filename) errbuffer);sleep ?
       (save-excursion
 	(set-buffer errbuffer)
 	(goto-char (point-max))
   ;;	   inferior-ess-prompt)
   (comint-mode)
   ;;
+
+  ;; SJE: is this the proper place for setting inferior-ess-prompt,
+  ;; rather than within ess-multi?  Tony - have you remembered yet
+
+  ;; about the setq-default, as I changed it back to setq.
+  (setq inferior-ess-prompt
+	;; shouldn't be setq-default!  And I've
+	;; forgotten why!   (AJR)
+	;; Do not anchor to bol with `^'
+	(concat "\\("
+		inferior-ess-primary-prompt
+		"\\|"
+		inferior-ess-secondary-prompt
+		"\\)"))
   (setq comint-prompt-regexp (concat "^" inferior-ess-prompt))
   (setq major-mode 'inferior-ess-mode)
   (setq mode-name "iESS") ;(concat "iESS:" ess-dialect))
 	   (current-buffer) comint-process-echoes comint-input-sender))
 
   ;; Completion support
-  (setq comint-dynamic-complete-functions
-	'(ess-complete-filename
-	  ess-complete-object-name
-	  comint-replace-by-expanded-history))
+  ;; SJE: comint-dynamic-complete-functions is regarded as a hook, rather
+  ;; than a regular variable.
+  (add-hook 'comint-dynamic-complete-functions
+	    'ess-complete-object-name nil 'local)
+  (add-hook 'comint-dynamic-complete-functions
+	     'comint-replace-by-expanded-history 'append 'local)
+  (add-hook 'comint-dynamic-complete-functions
+	    'ess-complete-filename 'append 'local)
+
+
 
   ;; (setq comint-completion-addsuffix nil) ; To avoid spaces after filenames
   ;; KH: next 2 lines solve.
   (make-local-variable 'paragraph-separate)
   (setq paragraph-separate "\^L")
 
-
-  (ess-load-object-name-db-file)
-  (sleep-for 0.5)
+  ;; SJE Tue 28 Dec 2004: do not attempt to load object name db.
+  ;; (ess-load-object-name-db-file)
+  ;; (sleep-for 0.5)
   (make-local-variable 'kill-buffer-hook)
   (add-hook 'kill-buffer-hook 'ess-kill-buffer-function)
   (run-hooks 'inferior-ess-mode-hook)
 
 (defun inferior-R-input-sender (proc string)
   ;; REALLY only for debugging: this S_L_O_W_S D_O_W_N   [here AND below]
-  ;;(ess-write-to-dribble-buffer (format "(inf..-R-..): string=%s; " string))
+  ;;(ess-write-to-dribble-buffer (format "(inf..-R-..): string='%s'; " string))
   ;; rmh: 2002-01-12 catch page() in R
   (let ((help-string (or (string-match inferior-R-1-input-help string)
 			 (string-match inferior-R-2-input-help string)))
     (if (or help-string page-string)
 	(let* ((string2 (match-string 2 string))
 	       (string2-rt (concat string2 ".rt")))
-	  ;; (ess-write-to-dribble-buffer (format " new string=%s\n" string2))
+	  ;; (ess-write-to-dribble-buffer (format " new string='%s'\n" string2))
 	  (beginning-of-line)
 	  (if (looking-at inferior-ess-primary-prompt)
 	      (progn
       (let ((buff (ess-create-temp-buffer buff-name)))
 	(save-excursion
 	  (set-buffer buff)
-	  (ess-command the-command (get-buffer buff-name))
+	  (ess-command the-command (get-buffer buff-name));; sleep?
 	  (goto-char (point-min))
 	  (if message (insert message)
 	    (if buff nil
 ;;;*;;; Quitting
 
 (defun ess-quit ()
-  "Issue an exiting command to the inferior process, and clean up."
+  "Issue an exiting command to the inferior process, additionally
+also running \\[ess-cleanup].  For R, runs \\[ess-quit-r], see there."
   (interactive)
+  (if (string-equal ess-dialect "R")
+      (ess-quit-r)
   (ess-force-buffer-current "Process to quit: ")
   (ess-make-buffer-current)
-  ;;  Modified to handle R (rmh 2002 Mar 12)
   (let ((sprocess (get-ess-process ess-current-process-name)))
     (if (not sprocess) (error "No ESS process running."))
-    (if (yes-or-no-p (format "Really quit ESS process %s? " sprocess))
-	(progn   ;;;;previouslyl (save-excursion
+      (when (yes-or-no-p (format "Really quit ESS process %s? " sprocess))
 	  (ess-cleanup)
 	  (goto-char (marker-position (process-mark sprocess)))
 	  (insert inferior-ess-exit-command)
-	  (if (string-equal ess-dialect "R")
-	      (progn
-		(inferior-ess-send-input)
-		(setq inferior-ess-prompt inferior-ess-exit-prompt)
-		(inferior-ess-wait-for-prompt))
-	    (process-send-string sprocess inferior-ess-exit-command))
-	  (rename-buffer (concat (buffer-name) "-exited") t)))))
+	(process-send-string sprocess inferior-ess-exit-command)
+	;;SJE - suggest no need to rename buffer upon exit.
+	;;(rename-buffer (concat (buffer-name) "-exited") t)
+	))))
+
+(defun ess-quit-r ()
+  "Issue an exiting command to an inferior R process, and optionally clean up.
+This version is for killing *R* processes; it asks the extra question
+regarding whether the workspace image should be saved."
+  (ess-force-buffer-current "Process to quit: ")
+  (ess-make-buffer-current)
+  (let (cmd
+;;Q 	response
+	(sprocess (get-ess-process ess-current-process-name)))
+    (if (not sprocess) (error "No ESS process running."))
+;;Q     (setq response (completing-read "Save workspace image? "
+;;Q 				    '( ( "yes".1) ("no" . 1) ("cancel" . 1))
+;;Q 				    nil t))
+;;Q     (if (string-equal response "")
+;;Q 	(setq response "default")); which will ask again (in most situations)
+;;Q     (unless (string-equal response "cancel")
+      (ess-cleanup)
+;;Q   (setq cmd (format "q(\"%s\")\n" response))
+      (setq cmd "q()\n")
+      (goto-char (marker-position (process-mark sprocess)))
+      (process-send-string sprocess cmd)
+      ;;(rename-buffer (concat (buffer-name) "-exited") t)
+;;Q      )
+  ))
 
 (defun ess-abort ()
   "Kill the ESS process, without executing .Last or terminating devices.
     (message "Good move.")))
 
 (defun ess-cleanup ()
-  "Kill (or offer to kill) all buffers associated with this ESS process.
+  "Possibly kill or offer to kill, depending on the value of
+`ess-S-quit-kill-buffers-p', all buffers associated with this ESS process.
 Leaves you in the ESS process buffer.  It's a good idea to run this
 before you quit.  It is run automatically by \\[ess-quit]."
   (interactive)
   (let ((the-procname (or (ess-make-buffer-current) ess-local-process-name)))
     (if the-procname nil
       (error "I don't know which ESS process to clean up after!"))
-    (if (y-or-n-p
+    (if
+	(or (eq ess-S-quit-kill-buffers-p t)
+	    (and
+	     (eq ess-S-quit-kill-buffers-p 'ask)
+	     (y-or-n-p
 	 (format
-	  "Delete all buffers associated with process %s? "
-	  the-procname))
-	(progn
+	       "Delete all buffers associated with process %s? " the-procname))))
 	  (save-excursion
 	  (mapcar '(lambda (buf)
 		     (set-buffer buf)
 		     ;; the-procname
 		     (if (and (not (get-buffer-process buf))
 			      ess-local-process-name
-			      (equal ess-local-process-name
-				     the-procname))
+			      (equal ess-local-process-name the-procname))
 			 (kill-buffer buf)))
-		    (buffer-list)))))
+		  (buffer-list))))
     (ess-switch-to-ESS nil)))
 
 (defun ess-kill-buffer-function nil
 			(point))
 		    (set-syntax-table buffer-syntax)))
 	     (full-prefix (buffer-substring beg end))
+	     (pattern full-prefix)
 	     ;; See if we're indexing a list with `$'
-	     (pattern full-prefix)
-	     ;; components  ; WHY IS THIS HERE?
 	     (listname (if (string-match "\\(.+\\)\\$\\(\\(\\sw\\|\\s_\\)*\\)$"
 					 full-prefix)
 			   (progn
 						(match-end 2))))
 			     (substring full-prefix (match-beginning 1)
 					(match-end 1)))))
-	     (components (if listname (ess-object-names listname)
-			   (ess-get-object-list
-			    ess-current-process-name))))
+	     ;; are we trying to get a slot via `@' ?
+	     (classname (if (string-match "\\(.+\\)@\\(\\(\\sw\\|\\s_\\)*\\)$"
+					 full-prefix)
+			   (progn
+			     (setq pattern
+				   (if (not (match-beginning 2)) ""
+				     (substring full-prefix
+						(match-beginning 2)
+						(match-end 2))))
+			     (ess-write-to-dribble-buffer
+			      (format "(ess-C-O-Name : slots..) : patt=%s"
+				      pattern))
+			     (substring full-prefix (match-beginning 1)
+					(match-end 1)))))
+	     (components (if listname
+			     (ess-object-names listname)
+			   (if classname
+			       (ess-slot-names classname)
+			     (ess-get-object-list ess-current-process-name)))))
 	;; always return a non-nil value to prevent history expansions
 	(or (comint-dynamic-simple-complete  pattern components) 'none))))
 
 ;;;*;;; Support functions
 (defun ess-extract-onames-from-alist (alist posn &optional force)
   "Return the object names in position POSN of ALIST.
-ALIST is an alist like `ess-sl-modtime alist'. POSN should be 1 .. (length
+ALIST is an alist like `ess-sl-modtime-alist'. POSN should be in 1 .. (length
 ALIST).	 If optional third arg FORCE is t, the corresponding element
 of the search list is re-read. Otherwise it is only re-read if it's a
 directory and has been modified since it was last read."
 	 (timestamp (car (cdr entry)))
 	 (new-modtime (ess-dir-modtime dir)))
     ;; Refresh the object listing if necessary
-    (if (and (not force) (equal new-modtime timestamp)) nil
-      (setq timestamp new-modtime)
+    (if (or force (not (equal new-modtime timestamp)))
       (setcdr (cdr entry) (ess-object-names dir posn)))
     (cdr (cdr entry))))
 
 (defun ess-dir-modtime (dir)
   "Return the last modtime if DIR is a directory, and nil otherwise."
-  ;; Attached dataframes return a modtime of nil.
   (and ess-filenames-map
-       (file-directory-p dir); was (string-match "^/" dir)
+       (file-directory-p dir)
        (nth 5 (file-attributes dir))))
 
 (defun ess-object-modtime (object)
   "Return the modtime of the S object OBJECT (a string).
 Searches along the search list for a file named OBJECT and returns its modtime
-Returns nil if that file cannot be found.
-Does NOT (yet) work for R or any non-S language!"
+Returns nil if that file cannot be found, i.e., for R or any non-S language!"
   (let ((path (ess-search-list))
 	result)
     (while (and (not result) path)
 		(> (car (cdr mod1)) (car (cdr mod2)))))))
 
 (defun ess-get-object-list (name)
-  "Return an alist of current S object names associated with process NAME."
+  "Return a list of current S object names associated with process NAME,
+using `ess-object-list' if that is non-nil."
   (or ess-object-list
       (save-excursion
 	(set-buffer (process-buffer (get-ess-process name)))
 	(ess-make-buffer-current)
+	(ess-write-to-dribble-buffer (format "(get-object-list %s) .." name))
 	(if (or (not ess-sl-modtime-alist) ess-sp-change)
+	    (progn (ess-write-to-dribble-buffer "--> (ess-get-modtime-list)\n")
 	    (ess-get-modtime-list))
+	  ;;else
+	  (ess-write-to-dribble-buffer " using existing ess-*-alist\n")
+	  )
 	(let* ((alist ess-sl-modtime-alist)
 	       (i 2)
 	       (n (length alist))
 	       result)
-	  ;; Always force a re-read of position 1 if it's a database
-	  (setq result (ess-extract-onames-from-alist alist 1 t))
+	  ;; Always force a re-read of position 1 :
+	  (setq result (ess-extract-onames-from-alist alist 1 'force))
 	  ;; Re-read remaining directories if necessary.
 	  (while (<= i n)
 	    (setq result
 		  (append result
 			  (ess-extract-onames-from-alist alist i)))
 	    (setq i (1+ i)))
-	  (setq ess-object-list result)))))
+	  (setq ess-object-list (ess-uniq-list result))))))
 
 (defun ess-get-words-from-vector (command)
   "Evaluate the S command COMMAND, which returns a character vector.
 Return the elements of the result of COMMAND as an alist of strings.
 A newline is automatically added to COMMAND."
-  (let ((tbuffer (get-buffer-create " *ess-names-list*"))
+  (let ((tbuffer (get-buffer-create
+		  " *ess-names-list*")); initial space: disable-undo
 	names)
     (save-excursion
       (set-buffer tbuffer)
-      ;; guaranteed by the initial space:(buffer-disable-undo)
-      (ess-command command tbuffer)
+      (ess-command command tbuffer 'sleep)
       (goto-char (point-min))
+      (if ess-verbose (ess-write-to-dribble-buffer "ess-get-words-.. "))
       (if (not (looking-at "\\s-*\\[1\\]"))
+	  (progn (if ess-verbose
+		     (ess-write-to-dribble-buffer "not seeing \"[1]\".. "))
 	  (setq names nil)
+	  )
 	(goto-char (point-max))
 	(while (re-search-backward "\"\\([^\"]*\\)\"" nil t)
 	  (setq names (cons (buffer-substring (match-beginning 1)
 					      (match-end 1)) names))))
-      (kill-buffer tbuffer))
-    ;;DBG: (ess-write-to-dribble-buffer (format " --> names �%s�\n" names))
+      ;;DBG, do *not* (i.e., comment):
+      (kill-buffer tbuffer)
+      )
+    (if ess-verbose
+	(ess-write-to-dribble-buffer
+	 (if (> (length names) 5)
+	     (format " |-> (length names)= %d\n" (length names))
+	   (format " |-> names= '%s'\n" names))))
     names))
 
 (defun ess-compiled-dir (dir)
   "Return non-nil if DIR is an S object directory with special files.
 I.e. if the filenames in DIR are not representative of the objects in DIR."
-  (or (file-exists-p (concat (file-name-as-directory dir) "__BIGIN"))
+  (or (file-exists-p (concat (file-name-as-directory dir) "___nonfile"))
+      (file-exists-p (concat (file-name-as-directory dir) "__BIGIN"))
       (file-exists-p (concat (file-name-as-directory dir) "___NONFI"))))
 
 (defun ess-object-names (obj &optional pos)
 If OBJ is a directory name (begins with `/') returns a listing of that dir.
    This may use the search list position POS if necessary.
 If OBJ is an object name, returns result of S command names(OBJ).
-If OBJ is nil, POS must be supplied, and objects(POS) is returned.
+If OBJ is nil or not a directory, POS must be supplied, and objects(POS) is returned.
 In all cases, the value is an list of object names."
+
+;; FIXME: in both cases below, use the same fallback "objects(POS)" -- merge!
   (if (and obj (file-accessible-directory-p obj))
       ;; Check the pre-compiled object list in ess-object-name-db first
+
+      ;; FIXME: If used at all, ess-object-name-db should not only
+      ;; -----  be used in the directory case !!
       (or (cdr-safe (assoc obj ess-object-name-db))
 	  ;; Take a directory listing
-	  (and ess-filenames-map (not (ess-compiled-dir obj))
-	       (directory-files obj))
+	  (and ess-filenames-map
+	       ;; first try .Data subdirectory:
+	       ;;FIXME: move ".Data" or ``this function'' to essd-sp6.el etc:
+	       (let ((dir (concat (file-name-as-directory obj) ".Data")))
+		 (if (not (file-accessible-directory-p dir))
+		     (setq dir obj))
+		 (and (not (ess-compiled-dir dir))
+		      (directory-files dir))))
 	  ;; Get objects(pos) instead
+	  (and (or (ess-write-to-dribble-buffer
+		    (format "(ess-object-names ..): directory %s not used\n" obj))
+		   t)
+	       pos
 	  (ess-get-words-from-vector
-	   (format inferior-ess-objects-command pos ".*")))
-    ;; Want names(obj)
-    (or (and obj (ess-get-words-from-vector
+		(format inferior-ess-objects-command pos))))
+	  ;; "else" should really give an error!
+	  ;; would need  pos = which(obj = search())
+
+    ;; else
+    (or (and obj  ;; want names(obj)
+	     (or (ess-write-to-dribble-buffer
+		  (format "(ess-object-names obj=%s): no directory - trying names\n"
+			  obj))
+		 t)
+	     (ess-get-words-from-vector
 		  (format inferior-ess-names-command obj)))
+	(and nil; must return nil
+	     (ess-write-to-dribble-buffer
+	      (format "(ess-object-names obj=%s): no dir.; -> objects()\n" obj)))
 	;; get objects(pos)
 	(ess-get-words-from-vector
-	 (format inferior-ess-objects-command pos ".*"))))) ; s4 needs 2
+	 (format inferior-ess-objects-command pos))))) ; had 2nd arg ".*"
+					; s4 needs 2
 					; args, rest only need 1 ?
 					; changes needed to allow for
 					; pattern argument to
 					; .SmodeObs
 
+(defun ess-slot-names (obj)
+  "Return alist of S4 slot names of S4 object OBJ."
+  (ess-get-words-from-vector (format "slotNames(%s)\n" obj)))
 
+
+;;; SJE: Wed 29 Dec 2004 --- remove this function.
+;;; rmh: Wed 5 Jan 2005 --- bring it back for use on Windows
 (defun ess-create-object-name-db ()
   "Create a database of object names in standard S directories.  This
 database is saved in the file specified by `ess-object-name-db-file',
 and (indirectly) by \\[ess-get-help-files-list]."
   (save-excursion
     (let ((result nil))
-      (set-buffer (get-ess-buffer ess-current-process-name))
-      (if (and ess-search-list (not ess-sp-change)); use cache
+      (set-buffer (get-ess-buffer ess-current-process-name));to get *its* local vars
+      (if (and ess-search-list (not ess-sp-change))
+	  ;; use cache:
 	  ess-search-list
+	;; else, re-compute:
 	(let ((tbuffer (get-buffer-create " *search-list*"))
 	      (homedir ess-directory)
+	      (my-search-cmd inferior-ess-search-list-command); from ess-buffer
 	      elt)
 	  (save-excursion
 	    (set-buffer tbuffer)
-	    ;; guaranteed by the initial space:(buffer-disable-undo)
-	    ;; dbg:
-;;- 	    (ess-write-to-dribble-buffer
-;;- 	     (format "(ess-search-list ..): tbuffer %s\n"
-;;- 		     (buffer-name tbuffer)))
-
-	    ;;unnecessary; ess-command does (erase-buffer)
-	    (ess-command inferior-ess-search-list-command tbuffer)
+	    ;; guaranteed by the initial space in its name: (buffer-disable-undo)
+	    (ess-command my-search-cmd tbuffer 0.2); <- sleep; does (erase-buffer)
 	    (goto-char (point-min))
 	    (while (re-search-forward "\"\\([^\"]*\\)\"" nil t)
 	      (setq elt (buffer-substring (match-beginning 1) (match-end 1)))
 		    (setq elt (concat homedir elt)))
 		;;else
 		;;dbg
-;;- 		(ess-write-to-dribble-buffer "not dir.\n")
+		;;-		(ess-write-to-dribble-buffer "not dir.\n")
 		)
 	      (setq result (append result (list elt))))
 	    (kill-buffer tbuffer)))
 ;;;  * key	       (directory or object name)
 ;;;  * modtime	       (list of 2 integers)
 ;;;  * name, name ...  (accessible objects in search list posn labeled by key)
-;;; It has the same number of elements and is in the same order as the
+;;; It is a buffer-local variable (belonging to e.g. *R*, *S+6*, .. etc)
+;;; and has the same number of elements and is in the same order as the
 ;;; S search list
 
 (defun ess-get-modtime-list ()
 			  ))))))
       (setq index (1+ index))
       (setq searchlist (cdr searchlist)))
+    ;;DBG:
+    (ess-write-to-dribble-buffer
+     (format "ess-get-modtime-list: new alist of length %d\n"
+	     (length newalist)));; todo : also give length of components!
+
     (setq ess-sl-modtime-alist newalist)))
 
 
 (defun ess-search-path-tracker (str)
   "Check if input STR changed the search path.
 This function monitors user input to the inferior ESS process so that
-Emacs can keep the variable `ess-search-list' up to date.
-'completing-read' uses this list indirectly when it prompts for help or
+Emacs can keep the variable `ess-search-list' up to date. `completing-read' in
+\\[ess-read-object-name] uses this list indirectly when it prompts for help or
 for an object to dump."
   (if (string-match ess-change-sp-regexp str)
       (setq ess-sp-change t)))
 	 (prompt-string (if default
 			    (format "%s(default %s) " p-string default)
 			  p-string))
-	 (ess-object-list (mapcar 'list (ess-get-object-list
-					 ess-local-process-name)))
-	 (spec (completing-read prompt-string ess-object-list)))
+	 (object-list (mapcar 'list (ess-get-object-list ess-local-process-name)))
+	 (spec (completing-read prompt-string object-list)))
     (list (cond
 	   ((string= spec "") default)
 	   (t spec)))))

File lisp/ess-iw32.el

 
 (fset 'ess-command-original (symbol-function 'ess-command))
 
-(defun ess-command (com &optional buf)
-  "Send the ESS process command COM and delete the output
-from the ESS process buffer.  If an optional second argument BUF exists
-save the output in that buffer. BUF is erased before use.
-COM should have a terminating newline.
-Guarantees that the value of .Last.value will be preserved."
+(defun ess-command (com &optional buf sleep)
+  "This is the 'w32' version. Either calls the original `ess-command-original'
+(see its doc) or `ess-command-ddeclient'."
   (interactive)
   (if buf                ;;Mar 01 2002 rmh
       (save-excursion
 	(set-buffer buf)
 	(setq ess-local-process-name ess-current-process-name)))
   (if (not (ess-ddeclient-p))
-      (ess-command-original com buf)
+      (ess-command-original com buf sleep)
     (ess-force-buffer-current "Process to load into: ")
     (ess-command-ddeclient com buf)))
 

File lisp/ess-latex.el

              (setq mode (concat                                            
                          (downcase (buffer-substring beg end))             
                          "-mode"))
-             (if (and (>= (length mode) 11)
+             (if ;(and 
+		 (>= (length mode) 11)
                       (progn
                         (if
                             (equal (substring mode -10 -5) "-mode")
                             (setq mode (substring mode 0 -5)))
                         (if 
                             (equal (substring mode 0 5) "mode:")
-                            (setq mode (substring mode 6))))))
+                            (setq mode (substring mode 6)))))
              (intern mode))))))
 
 (defun ess-latex-find-chunk-index-buffer ()

File lisp/ess-menu.el

     ("Data" "^\\(.+\\)\\s-*<-[ \t\n]*\\(read\\|.*data\.frame\\).*(" 1)))
 
 (defun ess-imenu-S (&optional arg)
-  "S Language Imenu support for ESS.
-Initial version from Stephen Eglen <stephen@cogsci.ed.ac.uk>."
+  "S Language Imenu support for ESS."
   (interactive)
   (setq imenu-generic-expression ess-imenu-S-generic-expression)
   (imenu-add-to-menubar "Imenu-S"))

File lisp/ess-mode.el

 ;;; ess-mode.el --- Support for editing ESS source code
 
 ;; Copyright (C) 1989-1994 Doug Bates, Ed Kademan, Frank Ritter, David Smith.
-;; Copyright (C) 1997--2004 A.J. Rossini, Rich M. Heiberger, Martin
+;; Copyright (C) 1997--2005 A.J. Rossini, Rich M. Heiberger, Martin
 ;;	Maechler, Kurt Hornik, Rodney Sparapani, and Stephen Eglen.
 
 ;; Original Author: David Smith <dsmith@stats.adelaide.edu.au>
     ["Mark function"	 ess-mark-function			t]
     ["Indent expression" ess-indent-exp				t]
     ["Indent line"	 ess-indent-command			t]
+    ["Toggle Auto-Fill Mode" auto-fill-mode			t]
     ["Undo"		 undo					t]
     ["About"		 (ess-goto-info "Edit buffer")		t]
     )
   (put 'ess-local-process-name 'permanent-local t) ; protect from RCS
   (setq mode-line-process ;; AJR: in future, XEmacs will use modeline-process.
 	'(" [" (ess-local-process-name ess-local-process-name "none") "]"))
-
-  (ess-load-object-name-db-file)
+  ;; SJE Tue 28 Dec 2004: do not attempt to load object name db.
+  ;; (ess-load-object-name-db-file)
   (run-hooks 'ess-mode-hook)
   (ess-write-to-dribble-buffer "\nFinished setting up ESS-mode.\n"))
 
     ;;of the mess generated by sending TAB characters to the readline
     ;;functions in R when you eval-buffer-*.
     (indent-region (point-min-marker) (point-max-marker) nil)
+    (set-buffer-modified-p nil); no need to safe just because of indenting
 
     ;; Don't make backups for temporary files; it only causes clutter.
     ;; The ESS object itself is a kind of backup, anyway.
-    (if ess-keep-dump-files nil
+    (unless ess-keep-dump-files
       (make-local-variable 'make-backup-files)
       (setq make-backup-files nil))
 
 		  (down-list 1)
 		(error nil)))))))
 
+;; AJR: XEmacs, makes sense to dump into "other frame".
 (defun ess-dump-object-into-edit-buffer-other-frame (object)
   "Edit an ESS object in its own frame."
   (switch-to-buffer-other-frame (ess-dump-object-into-edit-buffer object)))

File lisp/ess-noweb.el

   "Set to t if you want to use font-locking in ESS noweb buffers.")
 
 ;; this helps with XEmacs barfing, sigh...
-(setq global-font-lock-mode t)
+;; but is *NOT* okay to do *globally*: (setq global-font-lock-mode t)
 
 (if ess-noweb-use-font-lock
      (require 'noweb-font-lock-mode))

File lisp/ess-site.el

-;;; ess-site.el --- user customization of ess-mode
+;;; ess-site.el --- user customization of ESS
 
 ;; Copyright (C) 1993 David M. Smith
 ;; Copyright (C) 1997--2004 A.J. Rossini, Rich M. Heiberger, Martin
 ;;; directory location of this file must be supplied in
 ;;; ess-lisp-directory.	 The editing of remaining sections is
 ;;; optional.  It should then be byte-compiled, and users who wish to
-;;; use ess-mode should add the line:
+;;; use ESS should add the line:
 ;;;    (load "/PATH/TO/THIS/FILE/ess-site")
 ;;; (where /PATH/TO/THIS/FILE is the path to ess-site.elc: i.e. the
 ;;; value of ess-lisp-directory, below) to their .emacs file.
 
 (autoload 'Rd-mode "essddr" "Major mode for editing R documentation." t)
 
-;; remassoc exists as a built-in function in xemacs, but
-;; not in GNU emacs
-;;
-(if (not (functionp 'remassoc))
-    (defun remassoc (key a)
-      "remove an association pair from an alist"
-      (if a
-	  (let ((pair (car a)))
-	    (if (equal (car pair) key)
-		(cdr a)
-		(cons pair (remassoc key (cdr a))))))))
-
 ;; This is thanks to  Ed L Cashin <ecashin@uga.edu>, 03 Mar 2004 :
 (defun ess-restore-asm-extns ()
   "take away the S-Plus mode association for .s and .S files added by ESS
 	   ("\\.lsp\\'"		. XLS-mode)
 	   ("\\.do\\'"		. STA-mode)
 	   ("\\.ado\\'"		. STA-mode)
-	   ("\\.sas\\'"		. SAS-mode)
-	   ("\\.SAS\\'"		. SAS-mode)
-	   ;;("\\.lst\\'"		. SAS-listing-mode);sasl
-	   ;; Too many *.log files, not only SAS :
-	   ;;("\\.log\\'"	. SAS-log-mode);sasl
+	   ("\\.[Ss][Aa][Ss]\\'"	. SAS-mode)
+	   ;; Many .log/.lst files, not just SAS
+	   ;;("\\.log\\'"	. SAS-log-mode)
+	   ;;("\\.lst\\'"	. SAS-listing-mode)
 	   ("\\.[Ss]t\\'"	. S-transcript-mode)
 	   ("\\.[Ss]out"	. S-transcript-mode)
 	   ("\\.[Rr]t\\'"	. R-transcript-mode)
 ;;; These commands are for running the PC version of Sqpe of S+4 and
 ;;; S+6 in an emacs buffer, using the same technology as ESS uses for
 ;;; Unix S-Plus.  Interactive graphics are unavailable in this mode.
-;;; See essd-sp4.el or essdsp6w.el
+;;; See essd-sp4.el or essd-sp6w.el
 
 ;;; These are the defaults.  Change them here if the defaults don't work.
 ;;; Use the 8.3 version of the pathname because embedded blanks will cause
 ;;; control to the user.  On a 300 MHz machine with 96MB of RAM the
 ;;; delay is 60 seconds.  On a ???? MHz machine with 523MB the delay is
 ;;; 10 seconds.  The user may need to adjust this number.
-(defvar ess-S+6-startup-delay 60
+(defvar ess-S+6-startup-delay 15 ;; <- 2005-01-03; MM
 "*Number of seconds to wait for the Commands window to appear before
 sending `inferior-ess-language-start' to S-Plus.")
 
 
 (ess-message "[ess-site:] Before requiring dialect 'essd-** ....")
 (ess-message "[ess-site:] require 'essd-r ...")
-(require 'essd-r)    ;; S and common variants
-(ess-message "[ess-site:] require 'essd-s4 ...")
-(require 'essd-s4)
+(require 'essd-r)    ;; R
+;; (ess-message "[ess-site:] require 'essd-s4 ...")
+;; (require 'essd-s4) ; has become VERY RARE ..
+
 ;;(ess-message "[ess-site:] require 'essd-s3 ...")
 ;;(require 'essd-s3)  ; THIS IS RARE.  You probably do not have this.
+
+;; "sp" refers to S-PLUS (MathSoft/StatSci/Insightful):
 (ess-message "[ess-site:] require 'essd-sp3 ...")
-(require 'essd-sp3)  ;; "sp" refers to S-PLUS (MathSoft/StatSci).
+(require 'essd-sp3)
 
 (if ess-microsoft-p
     (progn
       (ess-message "[ess-site:] require 'essd-sp4 ...")
       (require 'essd-sp4)
-      (ess-message "[ess-site:] require 'essdsp6w ...")
-      (require 'essdsp6w))
+      (ess-message "[ess-site:] require 'essd-sp6w ...")
+      (require 'essd-sp6w))
   ;; else: decent OS
   (ess-message "[ess-site:] require 'essd-sp5 ...")
   (require 'essd-sp5)
 
 ;;; (1.7) Literate Data Analysis
 (require 'ess-noweb)
+(require 'ess-swv); for Sweave
 
 ;; ALWAYS:
-(require 'ess)
+(require 'ess); -> loads ess-cust.el and more
 
 (ess-write-to-dribble-buffer
    (format "[ess-site.el _2_]: ess-customize-alist=%s \n"
 ;; The following two expressions automatically enable font-lock-mode
 ;; for ess-mode and inferior-ess-mode buffers.
 
-;; XEmacs has font-lock for ttys, as well.  So we need a better check!
+;; FIXME: XEmacs and Emacs 21.x has font-lock for ttys, as well.
+;; So we need a better check! [or do this unconditionally -working everywhere ??]
 (if window-system
     (progn
       (add-hook 'ess-mode-hook 'turn-on-font-lock t)
 ;;;(setq ess-sas-edit-keys-toggle t)   ;; optional TAB and C-TAB in sas-mode
 ;;;   Use the function call (ess-sas-edit-keys-toggle)
 ;;;   to change the setting after the first SAS-mode buffer has been created.
-;;;   1c. You can also define C-TAB in all modes by specifying either
-;;;(setq ess-sas-global-unix-keys t) ;; optional C-TAB bound in all modes
-;;;(setq ess-sas-global-pc-keys t)   ;; optional C-TAB bound in all modes
-;;;       See below.
+;;;   1c. You can also define C-TAB in all modes by Option 2b (below).
 ;;;
 ;;;   2. Managing submitted SAS jobs with function keys.
-;;;   2a. Default: Function keys retain their global bindings.
-;;;   2b. Options: Uncomment at most one of the following four lines.
-;;;(setq ess-sas-local-unix-keys t)  ;; [f2]--[f8] bound in sas-mode and related modes
-;;;(setq ess-sas-local-pc-keys t)    ;; [f2]--[f8] bound in sas-mode and related modes
-;;;(setq ess-sas-global-unix-keys t) ;; [f2]--[f8] bound in all modes
-;;;(setq ess-sas-global-pc-keys t)   ;; [f2]--[f8] bound in all modes
+;;;   2a. Default: To define the function keys in ESS[SAS] mode only,
+;;;   uncomment at most one of the following two lines.
+;;;(setq ess-sas-local-unix-keys t)  ;; F2-F12 bound in ESS[SAS] mode
+;;;(setq ess-sas-local-pc-keys t)    ;; F2-F12 bound in ESS[SAS] mode
+;;;
+;;;   2b. Options: To define the function keys in all modes,
+;;;   uncomment at most one of the following two lines.
+;;;(setq ess-sas-global-unix-keys t) ;; F2-F12 bound in all modes
+;;;(setq ess-sas-global-pc-keys t)   ;; F2-F12 bound in all modes
 ;;;
 ;;;   3. If it is more convenient to have "*Async Shell Command*"
 ;;;      in same-window-buffer-names, then uncomment the following line

File lisp/ess-toolbar.el

 ;;; This code is experimental, and runs best on Emacs 21 and XEmacs
 ;;; 21.  It has been tested only on Linux machines.  All feedback
 ;;; appreciated.
-;;; To use this code, place the following in .emacs after you have
-;;; loaded ess-site:
 ;;;
-;;; (setq ess-use-toolbar t)
-;;; (if (fboundp 'tool-bar-mode) (tool-bar-mode t))	;Emacs 21.
-;;; (require 'ess-toolbar)
+;;; If your emacs can support images, the ESS toolbar should be loaded.
+;;; 
 ;;; If you see a toolbar, but no icons, check out the value of
 ;;; ess-icon-directory.
 ;;; 
 ;;; The toolbar can be customized in several ways.  To see options, do:
 ;;; M-x customize-group RET ess-toolbar RET
-;;; If you change any of the variables, you may need to restart Emacs
-;;; to see any effect.
+;;; If you change any of the variables, you _may_ need to restart Emacs
+;;; to see any effect.  See also the documentation for ess-toolbar-items
+;;; if you wish to change its value.
 ;;;
 ;;; Technical issues.
 ;; Emacs vs XEmacs.
 3. the tooltip doc string (XEmacs only; Emacs gets doc string from menu items.
 
 General toolbar items are also added to the ESS toolbar 
-iff `ess-toolbar-own-icons' is nil." 
+iff `ess-toolbar-own-icons' is nil.
+
+Setting this variable with setq doesn't take effect once you have
+loaded ess-site, unless you follow it by a call to
+`ess-make-toolbar' afterwards.  Instead, change its value using
+Custom, and then on all new ESS buffers you should see the
+toolbar has changed."
   :group 'ess-toolbar
+  :set (lambda (symbol value)
+	 (set-default symbol value)
+	 (if (fboundp 'ess-make-toolbar)
+	     (ess-make-toolbar)))
   :type '(repeat (list (function :tag "Function to run")
 		       (string  :tag "Icon")
 		       (string  :tag "Tooltip"))))
   "Make the ESS toolbar."
   (if (featurep 'xemacs)
       (ess-make-toolbar-xemacs)
-    (ess-make-toolbar-emacs)))
+    ;; Under Emacs, only worth building the toolbar if tool-bar-map is 
+    ;; available.  e.g. when running Emacs within a terminal, tool-bar-map
+    ;; is not available, so no need to make the tool-bar.
+    (if (boundp 'tool-bar-map)
+	(ess-make-toolbar-emacs))))
 
 (defun ess-make-toolbar-emacs ()
   "Make the ESS toolbar under Emacs."

File lisp/ess-trns.el

   ;; font-lock support
   (make-local-variable 'font-lock-defaults)
   (setq font-lock-defaults
-	'(ess-trans-font-lock-keywords nil nil ((?' . "."))))
+	'(inferior-ess-font-lock-keywords nil nil ((?' . "."))))
 
   ;;; Keep <tabs> out of the code.
   (make-local-variable 'indent-tabs-mode)

File lisp/ess-utils.el

 ;;; ess-utils.el --- General Emacs utility functions used by ESS
 
-;; Copyright (C) 1998--2004 A.J. Rossini, Rich M. Heiberger, Martin
+;; Copyright (C) 1998--2005 A.J. Rossini, Rich M. Heiberger, Martin
 ;;	Maechler, Kurt Hornik, Rodney Sparapani, and Stephen Eglen.
 
 ;; Original Author: Martin Maechler <maechler@stat.math.ethz.ch>
 
 ;;;-- Emacs Utilities --- Generally useful --- used by (but not requiring) ESS
 
-(defun inside-string/comment-p (pos)
-  "Return non-nil if POSition [defaults to (point) is inside string or comment
+(defun ess-inside-string-or-comment-p (pos)
+  "Return non-nil if POSition [defaults to (point)] is inside string or comment
  (according to syntax). NOT OKAY for multi-line comments!!"
   ;;FIXME (defun S-calculate-indent ..) in ./essl-s.el can do that ...
   (interactive "d");point by default
 		pos))))
     (or (nth 3 pps) (nth 4 pps)))); 3: string,  4: comment
 
+(defsubst ess-inside-string-p ()
+  "Return non-nil if point is inside string (according to syntax)."
+  (interactive)
+  (save-excursion
+    (nth 3 (parse-partial-sexp (line-beginning-position) (point)))))
+
 ;; simple alternative to ess-read-object-name-default of ./ess-inf.el :
 (defun ess-extract-word-name ()
   "Get the word you're on."
 			       (not fixedcase))); t  <==> ignore case in search
 	(pl) (p))
     (while (setq p (re-search-forward regexp nil t))
-      (cond ((not (inside-string/comment-p (1- p)))
+      (cond ((not (ess-inside-string-or-comment-p (1- p)))
 	     (if verbose
 		 (let ((beg (match-beginning 0)))
 		   (message "(beg,p)= (%d,%d) = %s"
 ;; 	  '(lambda ()
 ;; 	     (add-hook 'local-write-file-hooks 'nuke-trailing-whitespace)))
 
-(defvar nuke-trailing-whitespace-p nil;disabled by default  'ask
-  "*[Dis]activates (nuke-trailing-whitespace).
+(defvar ess-nuke-trailing-whitespace-p nil;disabled by default  'ask
+  "*[Dis]activates (ess-nuke-trailing-whitespace).
  Disabled if `nil'; if `t', it works unconditionally, otherwise,
  the user is queried.
  Note that setting the default to `t' may not be a good idea when you edit
 
 ;;; MM: Newer Emacsen now have  delete-trailing-whitespace
 ;;; --  but no customization like  nuke-trailing-whitespace-p ..
-(defun nuke-trailing-whitespace ()
+(defun ess-nuke-trailing-whitespace ()
   "Nuke all trailing whitespace in the buffer.
 Whitespace in this case is just spaces or tabs.
 This is a useful function to put on write-file-hooks.
 
-If the variable `nuke-trailing-whitespace-p' is `nil', this function is
+If the variable `ess-nuke-trailing-whitespace-p' is `nil', this function is
 disabled.  If `t', unreservedly strip trailing whitespace.