]> git.bundesbrandschatzamt.de Git - emacsconfig.git/commitdiff
update ess
authorAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Sun, 26 Apr 2026 17:49:31 +0000 (19:49 +0200)
committerAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Sun, 26 Apr 2026 17:49:31 +0000 (19:49 +0200)
117 files changed:
elpa/ess-20251212.937/dir [deleted file]
elpa/ess-20251212.937/ess-autoloads.el [deleted file]
elpa/ess-20251212.937/ess-bugs-d.el [deleted file]
elpa/ess-20251212.937/ess-bugs-l.el [deleted file]
elpa/ess-20251212.937/ess-custom.el [deleted file]
elpa/ess-20251212.937/ess-gretl.el [deleted file]
elpa/ess-20251212.937/ess-help.el [deleted file]
elpa/ess-20251212.937/ess-inf.el [deleted file]
elpa/ess-20251212.937/ess-jags-d.el [deleted file]
elpa/ess-20251212.937/ess-julia.el [deleted file]
elpa/ess-20251212.937/ess-mode.el [deleted file]
elpa/ess-20251212.937/ess-pkg.el [deleted file]
elpa/ess-20251212.937/ess-r-completion.el [deleted file]
elpa/ess-20251212.937/ess-r-flymake.el [deleted file]
elpa/ess-20251212.937/ess-r-mode.el [deleted file]
elpa/ess-20251212.937/ess-r-package.el [deleted file]
elpa/ess-20251212.937/ess-r-syntax.el [deleted file]
elpa/ess-20251212.937/ess-r-xref.el [deleted file]
elpa/ess-20251212.937/ess-rd.el [deleted file]
elpa/ess-20251212.937/ess-rdired.el [deleted file]
elpa/ess-20251212.937/ess-roxy.el [deleted file]
elpa/ess-20251212.937/ess-s-lang.el [deleted file]
elpa/ess-20251212.937/ess-sas-a.el [deleted file]
elpa/ess-20251212.937/ess-sas-d.el [deleted file]
elpa/ess-20251212.937/ess-sas-l.el [deleted file]
elpa/ess-20251212.937/ess-site.el [deleted file]
elpa/ess-20251212.937/ess-sp6-d.el [deleted file]
elpa/ess-20251212.937/ess-toolbar.el [deleted file]
elpa/ess-20251212.937/ess-tracebug.el [deleted file]
elpa/ess-20251212.937/ess-trns.el [deleted file]
elpa/ess-20251212.937/ess-utils.el [deleted file]
elpa/ess-20251212.937/ess.el [deleted file]
elpa/ess-20251212.937/ess.info [deleted file]
elpa/ess-20251212.937/essd-els.el [deleted file]
elpa/ess-20251212.937/etc/ESSR.rds [deleted file]
elpa/ess-20251212.937/etc/ESSR/BUILDESSR [deleted file]
elpa/ess-20251212.937/etc/ESSR/LOADREMOTE [deleted file]
elpa/ess-20251212.937/etc/ESSR/R/.basic.R [deleted file]
elpa/ess-20251212.937/etc/ESSR/R/.load.R [deleted file]
elpa/ess-20251212.937/etc/ESSR/R/completion.R [deleted file]
elpa/ess-20251212.937/etc/ESSR/R/debug.R [deleted file]
elpa/ess-20251212.937/etc/ESSR/R/misc.R [deleted file]
elpa/ess-20251212.937/etc/ESSR/R/mpi.R [deleted file]
elpa/ess-20251212.937/etc/ESSR/R/ns-eval.R [deleted file]
elpa/ess-20251212.937/etc/ESSR/R/pkg.R [deleted file]
elpa/ess-20251212.937/etc/Makefile [deleted file]
elpa/ess-20251212.937/etc/all.txt [deleted file]
elpa/ess-20251212.937/etc/ess-julia.jl [deleted file]
elpa/ess-20251212.937/etc/ess-sas-sh-command [deleted file]
elpa/ess-20251212.937/etc/func.sas [deleted file]
elpa/ess-20251212.937/etc/proc.sas [deleted file]
elpa/ess-20251212.937/etc/proc.txt [deleted file]
elpa/ess-20251212.937/obsolete/ess-eldoc.el [deleted file]
elpa/ess-20251212.937/obsolete/ess-font-lock.el [deleted file]
elpa/ess-20251212.937/obsolete/ess-mouse.el [deleted file]
elpa/ess-20251212.937/obsolete/ess-r-a.el [deleted file]
elpa/ess-20251212.937/obsolete/mouseme.el [deleted file]
elpa/ess-20251212.937/obsolete/msdos.el [deleted file]
elpa/ess-20260424.1544/README-elpa [new file with mode: 0644]
elpa/ess-20260424.1544/dir [new file with mode: 0644]
elpa/ess-20260424.1544/ess-autoloads.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-bugs-d.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-bugs-l.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-custom.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-gretl.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-help.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-inf.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-julia.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-mode.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-pkg.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-r-completion.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-r-flymake.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-r-mode.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-r-package.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-r-syntax.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-r-xref.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-rd.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-rdired.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-roxy.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-s-lang.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-sas-a.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-sas-d.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-sas-l.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-site.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-sp6-d.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-toolbar.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-tracebug.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-trns.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess-utils.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess.el [new file with mode: 0644]
elpa/ess-20260424.1544/ess.info [new file with mode: 0644]
elpa/ess-20260424.1544/essd-els.el [new file with mode: 0644]
elpa/ess-20260424.1544/etc/ESSR.rds [new file with mode: 0644]
elpa/ess-20260424.1544/etc/ESSR/BUILDESSR [new file with mode: 0755]
elpa/ess-20260424.1544/etc/ESSR/LOADREMOTE [new file with mode: 0644]
elpa/ess-20260424.1544/etc/ESSR/R/.basic.R [new file with mode: 0644]
elpa/ess-20260424.1544/etc/ESSR/R/.load.R [new file with mode: 0644]
elpa/ess-20260424.1544/etc/ESSR/R/completion.R [new file with mode: 0644]
elpa/ess-20260424.1544/etc/ESSR/R/debug.R [new file with mode: 0644]
elpa/ess-20260424.1544/etc/ESSR/R/misc.R [new file with mode: 0644]
elpa/ess-20260424.1544/etc/ESSR/R/mpi.R [new file with mode: 0644]
elpa/ess-20260424.1544/etc/ESSR/R/ns-eval.R [new file with mode: 0644]
elpa/ess-20260424.1544/etc/ESSR/R/pkg.R [new file with mode: 0644]
elpa/ess-20260424.1544/etc/Makefile [new file with mode: 0644]
elpa/ess-20260424.1544/etc/all.txt [new file with mode: 0644]
elpa/ess-20260424.1544/etc/ess-julia.jl [new file with mode: 0644]
elpa/ess-20260424.1544/etc/ess-sas-sh-command [new file with mode: 0755]
elpa/ess-20260424.1544/etc/func.sas [new file with mode: 0644]
elpa/ess-20260424.1544/etc/proc.sas [new file with mode: 0644]
elpa/ess-20260424.1544/etc/proc.txt [new file with mode: 0644]
elpa/ess-20260424.1544/obsolete/ess-eldoc.el [new file with mode: 0644]
elpa/ess-20260424.1544/obsolete/ess-font-lock.el [new file with mode: 0755]
elpa/ess-20260424.1544/obsolete/ess-jags-d.el [new file with mode: 0644]
elpa/ess-20260424.1544/obsolete/ess-mouse.el [new file with mode: 0644]
elpa/ess-20260424.1544/obsolete/ess-r-a.el [new file with mode: 0644]
elpa/ess-20260424.1544/obsolete/mouseme.el [new file with mode: 0644]
elpa/ess-20260424.1544/obsolete/msdos.el [new file with mode: 0644]

diff --git a/elpa/ess-20251212.937/dir b/elpa/ess-20251212.937/dir
deleted file mode 100644 (file)
index 02022aa..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-This is the file .../info/dir, which contains the
-topmost node of the Info hierarchy, called (dir)Top.
-The first time you invoke Info you start off looking at this node.
-\1f
-File: dir,     Node: Top       This is the top of the INFO tree
-
-  This (the Directory node) gives a menu of major topics.
-  Typing "q" exits, "H" lists all Info commands, "d" returns here,
-  "h" gives a primer for first-timers,
-  "mEmacs<Return>" visits the Emacs manual, etc.
-
-  In Emacs, you can click mouse button 2 on a menu item or cross reference
-  to select it.
-
-* Menu:
-
-Emacs
-* ESS: (ess).                   Emacs Speaks Statistics (R/S/S+, SAS, 
-                                  BUGS/JAGS and Stata).
diff --git a/elpa/ess-20251212.937/ess-autoloads.el b/elpa/ess-20251212.937/ess-autoloads.el
deleted file mode 100644 (file)
index d7a926d..0000000
+++ /dev/null
@@ -1,435 +0,0 @@
-;;; ess-autoloads.el --- automatically extracted autoloads (do not edit)   -*- lexical-binding: t -*-
-;; Generated by the `loaddefs-generate' function.
-
-;; This file is part of GNU Emacs.
-
-;;; Code:
-
-(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
-
-
-\f
-;;; Generated autoloads from ess.el
-
-(autoload 'ess-version "ess" "\
-Return a string with ESS version information." t)
-(autoload 'ess-submit-bug-report "ess" "\
-Submit a bug report to the ESS maintainers." t)
-(register-definition-prefixes "ess" '("ess"))
-
-\f
-;;; Generated autoloads from ess-bugs-d.el
-
-(autoload 'ess-bugs-mode "ess-bugs-d" "\
-Major mode for BUGS.
-
-(fn)" t)
-(add-to-list 'auto-mode-alist '("\\.[Bb][Uu][Gg]\\'" . ess-bugs-mode))
-(add-to-list 'auto-mode-alist '("\\.[Bb][Oo][Gg]\\'" . ess-bugs-mode))
-(add-to-list 'auto-mode-alist '("\\.[Bb][Mm][Dd]\\'" . ess-bugs-mode))
-(register-definition-prefixes "ess-bugs-d" '("ess-"))
-
-\f
-;;; Generated autoloads from ess-bugs-l.el
-
-(register-definition-prefixes "ess-bugs-l" '("ess-bugs-"))
-
-\f
-;;; Generated autoloads from ess-custom.el
-
-(defvar ess-lisp-directory (file-name-directory (or load-file-name buffer-file-name)) "\
-Directory containing ess-site.el(c) and other ESS Lisp files.")
-(custom-autoload 'ess-lisp-directory "ess-custom" t)
-(add-to-list 'load-path (directory-file-name ess-lisp-directory))
-(add-to-list 'load-path (directory-file-name (expand-file-name "obsolete" ess-lisp-directory)))
-(put 'ess-indent-offset 'safe-local-variable #'numberp)
-(put 'ess-style 'safe-local-variable #'symbolp)
-(register-definition-prefixes "ess-custom" '("R-" "S+" "S-" "comint-highlight-prompt" "ess-" "inferior-"))
-
-\f
-;;; Generated autoloads from ess-gretl.el
-
-(autoload 'ess-gretl-mode "ess-gretl" "\
-Major mode for editing gretl source.  See `ess-mode' for more help.
-
-(fn)" t)
-(autoload 'gretl "ess-gretl" "\
-Call `gretl',
-Optional prefix (C-u) allows to set command line arguments, such as
---vsize.  This should be OS agnostic.
-If you have certain command line arguments that should always be passed
-to gretl, put them in the variable `inferior-gretl-args'.
-
-(fn &optional START-ARGS)" t)
-(register-definition-prefixes "ess-gretl" '("ess-gretl-" "gretl-" "inferior-gretl-args"))
-
-\f
-;;; Generated autoloads from ess-help.el
-
-(register-definition-prefixes "ess-help" '("ess-"))
-
-\f
-;;; Generated autoloads from ess-inf.el
-
-(autoload 'ess-load-file "ess-inf" "\
-Load FILENAME into an inferior ESS process.
-This handles Tramp when working on a remote.
-
-(fn &optional FILENAME)" t)
-(register-definition-prefixes "ess-inf" '("ess-" "inferior-ess" "update-ess-process-name-list"))
-
-\f
-;;; Generated autoloads from ess-jags-d.el
-
-(autoload 'ess-jags-mode "ess-jags-d" "\
-Major mode for JAGS.
-
-(fn)" t)
-(add-to-list 'auto-mode-alist '("\\.[Jj][Aa][Gg]\\'" . ess-jags-mode))
-(register-definition-prefixes "ess-jags-d" '("ess-jags-"))
-
-\f
-;;; Generated autoloads from ess-julia.el
-
-(autoload 'ess-julia-mode "ess-julia" "\
-Major mode for julia files.
-
-(fn)" t)
-(autoload 'run-ess-julia "ess-julia" "\
-Start an inferior julia process.
-Optional prefix START-ARGS (\\[universal-argument]) allows to set
-command line arguments, such as --load=<file>. This should be OS
-agnostic. If you have certain command line arguments that should
-always be passed to julia, put them in the variable
-`inferior-julia-args'.
-
-(fn &optional START-ARGS)" t)
-(defalias 'julia #'run-ess-julia)
-(register-definition-prefixes "ess-julia" '("ac-source-ess-julia-objects" "company-ess-julia-objects" "ess-" "inferior-"))
-
-\f
-;;; Generated autoloads from ess-mode.el
-
-(autoload 'ess-mode "ess-mode" "\
-Major mode for editing ESS source.
-Optional arg ALIST describes how to customize the editing mode.
-Optional arg PROC-NAME is name of associated inferior process.
-
-\\{ess-mode-map}
-
-You can send text to the inferior ESS process from other buffers containing
-ESS source.
-    `ess-eval-region' sends the current region to the ESS process.
-    `ess-eval-buffer' sends the current buffer to the ESS process.
-    `ess-eval-function' sends the current function to the ESS process.
-    `ess-eval-line' sends the current line to the ESS process.
-    `ess-switch-to-ESS' switches the current buffer to the ESS process buffer.
-    `ess-switch-to-end-of-ESS' switches the current buffer to the ESS process
-        buffer and puts point at the end of it.
-
-    `ess-eval-region-and-go', `ess-eval-buffer-and-go',
-        `ess-eval-function-and-go', and `ess-eval-line-and-go' switch to the S
-        process buffer after sending their text.
-
-    `ess-load-file' sources a file of commands to the ESS process.
-
-\\[ess-indent-command] indents for ESS code.
-\\[backward-delete-char-untabify] converts tabs to spaces as it moves back.
-Comments are indented in a similar way to Emacs-lisp mode:
-       `###'     beginning of line
-       `##'      the same level of indentation as the code
-       `#'       the same column on the right, or to the right of such a
-                 column if that is not possible.(default value 40).
-                 \\[indent-for-comment] command automatically inserts such a
-                 `#' in the right place, or aligns such a comment if it is
-                 already inserted.
-\\[ess-indent-exp] command indents each line of the syntactic unit following point.
-
-Variables controlling indentation style:
- `ess-indent-offset'
-    Indentation of ESS statements within surrounding block.
-    The surrounding block's indentation is the indentation of the line on
-    which the open-brace appears.
- `ess-offset-block'
-    Indentation of blocks opened with curly braces or anonymous parentheses.
- `ess-offset-arguments'
-    Indentation of function arguments or bracket indices.
- `ess-offset-arguments-newline'
-    Indentation of function arguments or bracket indices when the opening
-    delimiter is immediately followed by a newline.
- `ess-offset-continued'
-    Indentation style for continued statements.
- `ess-align-nested-calls'
-    Functions whose nested calls should be aligned.
- `ess-align-arguments-in-calls'
-    Calls in which arguments should be aligned.
- `ess-align-continuations-in-calls'
-    Whether ignore indentation after an operator in calls
- `ess-align-blocks'
-    Blocks that should always be aligned vertically.
- `ess-indent-from-lhs'
-    Whether function calls given as argument should be indented from the
-    parameter name.
- `ess-indent-from-chain-start'
-    Whether to indent arguments from the first of several consecutive calls.
- `ess-indent-with-fancy-comments'
-    Non-nil means distinguish between #, ##, and ### for indentation.
-
-Furthermore, \\[ess-set-style] command enables you to set up predefined ess-mode
-indentation style. See `ess-style-alist' for predefined styles.
-
-(fn)" t)
-(register-definition-prefixes "ess-mode" '("ess-"))
-
-\f
-;;; Generated autoloads from ess-r-completion.el
-
-(register-definition-prefixes "ess-r-completion" '("ac-source-R" "company-R-" "ess-"))
-
-\f
-;;; Generated autoloads from ess-r-flymake.el
-
-(register-definition-prefixes "ess-r-flymake" '("ess-r-"))
-
-\f
-;;; Generated autoloads from ess-r-mode.el
-
-(autoload 'run-ess-r "ess-r-mode" "\
-Call \\='R\\=', the \\='GNU S\\=' system from the R Foundation.
-Optional prefix (\\[universal-argument]) allows to set command line arguments, such as
---vsize.  This should be OS agnostic.
-If you have certain command line arguments that should always be passed
-to R, put them in the variable `inferior-R-args'.
-
-START-ARGS can be a string representing an argument, a list of
-such strings, or any other non-nil value.  In the latter case, you
-will be prompted to enter arguments interactively.
-
-(fn &optional START-ARGS)" t)
-(autoload 'R "ess-r-mode" "\
-
-
-(fn &optional START-ARGS)" t)
-(autoload 'ess-r-mode "ess-r-mode" "\
-Major mode for editing R source.  See `ess-mode' for more help.
-
-(fn)" t)
-(defalias 'R-mode #'ess-r-mode)
-(defalias 'r-mode #'ess-r-mode)
-(add-to-list 'auto-mode-alist '("/R/.*\\.q\\'" . ess-r-mode))
-(add-to-list 'auto-mode-alist '("\\.[rR]\\'" . ess-r-mode))
-(add-to-list 'auto-mode-alist '("\\.[rR]profile\\'" . ess-r-mode))
-(add-to-list 'auto-mode-alist '("NAMESPACE\\'" . ess-r-mode))
-(add-to-list 'auto-mode-alist '("CITATION\\'" . ess-r-mode))
-(autoload 'ess-r-transcript-mode "ess-r-mode" "\
-A Major mode for R transcript files.
-
-(fn)" t)
-(add-to-list 'auto-mode-alist '("\\.[Rr]out\\'" . ess-r-transcript-mode))
-(add-to-list 'interpreter-mode-alist '("Rscript" . ess-r-mode))
-(add-to-list 'interpreter-mode-alist '("r" . ess-r-mode))
-(add-to-list 'auto-mode-alist '("/Makevars\\(\\.win\\)?\\'" . makefile-mode))
-(add-to-list 'auto-mode-alist '("DESCRIPTION\\'" . conf-colon-mode))
-(register-definition-prefixes "ess-r-mode" '("R-" "ess-" "inferior-ess-r-" "r-transcript-mode" "run-ess-r-newest"))
-
-\f
-;;; Generated autoloads from ess-r-package.el
-
-(register-definition-prefixes "ess-r-package" '("ess-"))
-
-\f
-;;; Generated autoloads from ess-r-syntax.el
-
-(register-definition-prefixes "ess-r-syntax" '("ess-"))
-
-\f
-;;; Generated autoloads from ess-r-xref.el
-
-(register-definition-prefixes "ess-r-xref" '("ess-r-xref-"))
-
-\f
-;;; Generated autoloads from ess-rd.el
-
-(autoload 'Rd-mode "ess-rd" "\
-Major mode for editing R documentation source files.
-
-Type \\[list-abbrevs] to display the built-in abbrevs for Rd
-keywords.To automatically turn on the abbrev(iate) features, add
-the following to your Emacs configuration file:
-
-  (add-hook \\='Rd-mode-hook #\\='abbrev-mode)
-
-(fn)" t)
-(add-to-list 'auto-mode-alist '("\\.Rd\\'" . Rd-mode))
-(register-definition-prefixes "ess-rd" '("Rd-"))
-
-\f
-;;; Generated autoloads from ess-rdired.el
-
-(autoload 'ess-rdired "ess-rdired" "\
-Show R objects from the global environment in a separate buffer.
-You may interact with these objects, see `ess-rdired-mode' for
-details." t)
-(register-definition-prefixes "ess-rdired" '("ess-rdired-"))
-
-\f
-;;; Generated autoloads from ess-roxy.el
-
-(autoload 'ess-roxy-mode "ess-roxy" "\
-Minor mode for editing ROxygen documentation.
-
-This is a minor mode.  If called interactively, toggle the `Ess-Roxy
-mode' mode.  If the prefix argument is positive, enable the mode, and if
-it is zero or negative, disable the mode.
-
-If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
-mode if ARG is nil, omitted, or is a positive number.  Disable the mode
-if ARG is a negative number.
-
-To check whether the minor mode is enabled in the current buffer,
-evaluate the variable `ess-roxy-mode'.
-
-The mode's hook is called both when the mode is enabled and when it is
-disabled.
-
-\\{ess-roxy-mode-map}
-
-(fn &optional ARG)" t)
-(register-definition-prefixes "ess-roxy" '("ess-"))
-
-\f
-;;; Generated autoloads from ess-s-lang.el
-
-(add-to-list 'auto-mode-alist '("\\.[Ss]t\\'" . S-transcript-mode))
-(add-to-list 'auto-mode-alist '("\\.Sout\\'" . S-transcript-mode))
-(register-definition-prefixes "ess-s-lang" '("S+common-cust-alist" "S-" "ess-" "inferior-S-language-start"))
-
-\f
-;;; Generated autoloads from ess-sas-a.el
-
-(register-definition-prefixes "ess-sas-a" '("ess-" "sas-program"))
-
-\f
-;;; Generated autoloads from ess-sas-d.el
-
-(autoload 'SAS-mode "ess-sas-d" "\
-Major mode for editing SAS source.  See `ess-mode' for more help.
-
-(fn)" t)
-(add-to-list 'auto-mode-alist '("\\.[Ss][Aa][Ss]\\'" . SAS-mode))
-(register-definition-prefixes "ess-sas-d" '("SAS" "ess-" "inferior-SAS-args"))
-
-\f
-;;; Generated autoloads from ess-sas-l.el
-
-(register-definition-prefixes "ess-sas-l" '("SAS-" "backward-page-top-of-window" "beginning-of-sas-" "ess-" "fix-page-breaks" "forward-page-top-of-window" "indent-sas-statement" "next-sas-proc" "sas-" "set-sas-file-" "submit-sas" "switch-to-"))
-
-\f
-;;; Generated autoloads from ess-sp6-d.el
-
-(autoload 'S+-mode "ess-sp6-d" "\
-Major mode for editing S+ source.  See `ess-mode' for more help.
-
-(fn &optional PROC-NAME)" t)
-(register-definition-prefixes "ess-sp6-d" '("S+" "ess-"))
-
-\f
-;;; Generated autoloads from ess-toolbar.el
-
-(register-definition-prefixes "ess-toolbar" '("ess-"))
-
-\f
-;;; Generated autoloads from ess-tracebug.el
-
-(register-definition-prefixes "ess-tracebug" '("ess-" "inferior-ess-" "org-"))
-
-\f
-;;; Generated autoloads from ess-trns.el
-
-(autoload 'ess-transcript-mode "ess-trns" "\
-Major mode for transcript files.
-
-Type \\[ess-transcript-send-command] to send a command in the
-transcript to the current inferior process. \\[ess-transcript-copy-command]
-copies the command but does not execute it, allowing you to edit it in
-the process buffer first.
-
-Type \\[ess-transcript-clean-region] to delete all outputs and prompts
-in the region, leaving only the commands.
-
-(fn)" t)
-(register-definition-prefixes "ess-trns" '("ess-transcript-"))
-
-\f
-;;; Generated autoloads from ess-utils.el
-
-(defvar ess-elisp-trace-mode nil "\
-Non-nil if Ess-Elisp-Trace mode is enabled.
-See the `ess-elisp-trace-mode' command
-for a description of this minor mode.
-Setting this variable directly does not take effect;
-either customize it (see the info node `Easy Customization')
-or call the function `ess-elisp-trace-mode'.")
-(custom-autoload 'ess-elisp-trace-mode "ess-utils" nil)
-(autoload 'ess-elisp-trace-mode "ess-utils" "\
-Toggle tracing of ess-prefixed functions.
-
-Tracing is useful for debugging background ESS behaviour. When
-enabled, all functions prefixed in `ess-' and `inferior-ess' are
-instrumented with `trace-function'. Tracing is turned off by
-calling `untrace-function' on these functions.
-
-This is a global minor mode.  If called interactively, toggle the
-`Ess-Elisp-Trace mode' mode.  If the prefix argument is positive, enable
-the mode, and if it is zero or negative, disable the mode.
-
-If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
-mode if ARG is nil, omitted, or is a positive number.  Disable the mode
-if ARG is a negative number.
-
-To check whether the minor mode is enabled in the current buffer,
-evaluate `(default-value \\='ess-elisp-trace-mode)'.
-
-The mode's hook is called both when the mode is enabled and when it is
-disabled.
-
-(fn &optional ARG)" t)
-(register-definition-prefixes "ess-utils" '("ess-" "with-ess-process-buffer"))
-
-\f
-;;; Generated autoloads from essd-els.el
-
-(autoload 'ess-remote "essd-els" "\
-Execute this command from within a buffer running a process.
-It runs `ess-add-ess-process' to add the PROC-NAME to
-`ess-process-name-alist' and to make it the
-`ess-current-process-name'. It then prompts the user for an ESS
-language and sets the editing characteristics appropriately.
-
-To use this command, first start a process on a remote computer by
-manual use of telnet, rlogin, ssh, or some other protocol.  Start the
-relevant program (\"S\" or \"R\" or \"sas -stdio\") in that buffer.  Once
-you are talking to S or R or SAS, then do \\[ess-remote] to make
-the current buffer an inferior-ess buffer with the right behavior for
-the language you are currently working with.  With S and R, use C-c
-C-n to send lines over.  With SAS, use C-c i
-`ess-eval-line-and-step-invisibly' to send lines over invisibly.
-
-DIALECT is the desired ess-dialect. If nil, ask for dialect
-
-(fn &optional PROC-NAME DIALECT)" t)
-(register-definition-prefixes "essd-els" '("S+elsewhere" "ess-" "inferior-ess-remote-pager"))
-\f
-;;; End of scraped data
-
-(provide 'ess-autoloads)
-
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; no-native-compile: t
-;; coding: utf-8-emacs-unix
-;; End:
-
-;;; ess-autoloads.el ends here
diff --git a/elpa/ess-20251212.937/ess-bugs-d.el b/elpa/ess-20251212.937/ess-bugs-d.el
deleted file mode 100644 (file)
index 4460585..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-;;; ess-bugs-d.el --- ESS[BUGS] dialect  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2008-2022 Free Software Foundation, Inc.
-
-;; Author: Rodney Sparapani
-;; Maintainer: ESS-help <ess-helpNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Code:
-
-(require 'ess-bugs-l)
-(require 'ess-utils)
-(require 'ess-inf)
-(require 'ess-mode)
-
-(defvar ess-bugs-command "OpenBUGS" "Default BUGS program in PATH.")
-(make-local-variable 'ess-bugs-command)
-
-(defvar ess-bugs-monitor '("") "Default list of variables to monitor.")
-(make-local-variable 'ess-bugs-monitor)
-
-(defvar ess-bugs-thin 1 "Default thinning parameter.")
-(make-local-variable 'ess-bugs-thin)
-
-(defvar ess-bugs-chains 1 "Default number of chains.")
-(make-local-variable 'ess-bugs-chains)
-
-(defvar ess-bugs-burnin 10000 "Default burn-in.")
-(make-local-variable 'ess-bugs-burnin)
-
-(defvar ess-bugs-update 10000 "Default number of updates after burnin.")
-(make-local-variable 'ess-bugs-update)
-
-(defvar ess-bugs-system nil "Default whether BUGS recognizes the system command.")
-
-(defvar ess-bugs-font-lock-keywords
-  (list
-   ;; .bug files
-   (cons "#.*\n"                        font-lock-comment-face)
-
-   (cons "^[ \t]*\\(model\\|var\\)\\>"
-         font-lock-keyword-face)
-
-   (cons (concat "\\<d\\(bern\\|beta\\|bin\\|cat\\|chisq\\|"
-                 "dexp\\|dirch\\|exp\\|\\(gen[.]\\)?gamma\\|hyper\\|"
-                 "interval\\|lnorm\\|logis\\|mnorm\\|mt\\|multi\\|"
-                 "negbin\\|norm\\(mix\\)?\\|par\\|pois\\|sum\\|t\\|"
-                 "unif\\|weib\\|wish\\)[ \t\n]*(")
-         font-lock-constant-face)
-
-   (cons (concat "\\<\\(abs\\|cos\\|C\\|dim\\|\\(i\\)?cloglog\\|equals\\|"
-                 "exp\\|for\\|inprod\\|interp[.]line\\|inverse\\|length\\|"
-                 "\\(i\\)?logit\\|logdet\\|logfact\\|loggam\\|max\\|mean\\|"
-                 "mexp\\|min\\|phi\\|pow\\|probit\\|prod\\|rank\\|round\\|"
-                 "sd\\|sin\\|sort\\|sqrt\\|step\\|sum\\|t\\|trunc\\|T\\)[ \t\n]*(")
-         font-lock-function-name-face)
-
-   ;; .bmd files
-   (cons (concat (regexp-opt '(
-                               "dicClear" "dicSet" "dicStats"
-                               "infoMemory" "infoModules" "infoNodeMethods"
-                               "infoNodeTypes" "infoNodeValues"
-                               "infoUpdatersbyDepth" "infoUpdatersbyName"
-                               "modelCheck" "modelCompile" "modelData"
-                               "modelDisable" "modelEnable" "modelGenInits"
-                               "modelInits" "modelPrecision" "modelQuit"
-                               "modelSaveState" "modelSetAP" "modelSetIts"
-                               "modelSetOR" "modelSetRN" "modelUpdate"
-                               "ranksClear" "ranksSet" "ranksStats"
-                               "samplesAutoC" "samplesBgr" "samplesCoda"
-                               "samplesDensity" "samplesHistory" "samplesSet"
-                               "sampleStats" "samplesThin"
-                               "summaryClear" "summarySet" "summaryStats"
-                               ) 'words) "(")
-         font-lock-function-name-face)
-
-   (cons (concat (regexp-opt '("Local Variables" "End") 'words) ":")
-         font-lock-keyword-face)
-   )
-  "ESS[BUGS]: Font lock keywords."
-  )
-
-(defun ess-bugs-switch-to-suffix (suffix &optional bugs-chains bugs-monitor bugs-thin
-                                         bugs-burnin bugs-update)
-  "ESS[BUGS]: Switch to file with suffix."
-  (find-file (concat ess-bugs-file-dir ess-bugs-file-root suffix))
-
-  (if (equal 0 (buffer-size)) (progn
-                                (if (equal ".bug" suffix) (progn
-                                        ;(insert "var ;\n")
-                                                            (insert "model {\n")
-                                                            (insert "    for (i in 1:N) {\n    \n")
-                                                            (insert "    }\n")
-                                                            (insert "}\n")
-                                                            (insert "#Local Variables" ":\n")
-                                        ;           (insert "#enable-local-variables: :all\n")
-                                                            (insert "#ess-bugs-chains:1\n")
-                                                            (insert "#ess-bugs-monitor:(\"\")\n")
-                                                            (insert "#ess-bugs-thin:1\n")
-                                                            (insert "#ess-bugs-burnin:10000\n")
-                                                            (insert "#ess-bugs-update:10000\n")
-                                                            (insert "#End:\n")
-                                                            ))
-
-                                (if (equal ".bmd" suffix) (let
-                                                              ((ess-bugs-temp-chains "") (ess-bugs-temp-monitor ""))
-
-                                                            (if bugs-chains (setq ess-bugs-chains bugs-chains))
-                                                            (if bugs-monitor (setq ess-bugs-monitor bugs-monitor))
-                                                            (if bugs-thin (setq ess-bugs-thin bugs-thin))
-
-                                                            (setq ess-bugs-temp-chains
-                                                                  (concat "modelCompile(" (format "%d" ess-bugs-chains) ")\n"))
-
-                                                            (setq bugs-chains ess-bugs-chains)
-
-                                                            (while (< 0 bugs-chains)
-                                                              (setq ess-bugs-temp-chains
-                                                                    (concat ess-bugs-temp-chains
-                                                                            "modelInits('" ess-bugs-file-root
-                                                                            ".##" (format "%d" bugs-chains) "', "
-                                                                            (format "%d" bugs-chains) ")\n"))
-                                                              (setq bugs-chains (- bugs-chains 1)))
-
-                                                            (setq ess-bugs-temp-monitor "")
-
-                                                            (while (and (listp ess-bugs-monitor) (consp ess-bugs-monitor))
-                                                              (if (not (string-equal "" (car ess-bugs-monitor)))
-                                                                  (setq ess-bugs-temp-monitor
-                                                                        (concat ess-bugs-temp-monitor "samplesSet('"
-                                                                                (car ess-bugs-monitor)
-                                        ;", thin(" (format "%d" ess-bugs-thin)
-                                                                                "')\n")))
-                                                              (setq ess-bugs-monitor (cdr ess-bugs-monitor)))
-
-                                                            (insert "modelCheck('" ess-bugs-file-root ".bug')\n")
-                                                            (insert "modelData('" ess-bugs-file-root ".bdt')\n")
-                                                            (insert (ess-replace-in-string ess-bugs-temp-chains "##" "in"))
-                                                            (insert "modelGenInits()\n")
-                                                            (insert "modelUpdate(" (format "%d" bugs-burnin) ")\n")
-                                        ;(insert "modelUpdate(" (format "%d" (* bugs-thin bugs-burnin)) ")\n")
-                                                            (insert ess-bugs-temp-monitor)
-                                                            (insert "modelUpdate(" (format "%d" (* bugs-thin bugs-update)) ")\n")
-                                        ;           (insert (ess-replace-in-string
-                                        ;               (ess-replace-in-string ess-bugs-temp-chains
-                                        ;                   "modelCompile([0-9]+)" "#") "##" "to"))
-
-                                                            (if (< 1 bugs-thin) (insert "samplesThin(" (format "%d" bugs-thin) ")\n"))
-
-                                                            (insert "samplesCoda('*', '" ess-bugs-file-root "')\n")
-
-                                        ;           (if ess-bugs-system (progn
-                                        ;               (insert "system rm -f " ess-bugs-file-root ".ind\n")
-                                        ;               (insert "system ln -s " ess-bugs-file-root "index.txt " ess-bugs-file-root ".ind\n")
-
-                                        ;               (setq bugs-chains ess-bugs-chains)
-
-                                        ;               (while (< 0 bugs-chains)
-                                        ;                   (setq ess-bugs-temp-chain (format "%d" bugs-chains))
-
-                                        ;                   ;.txt not recognized by BOA and impractical to over-ride
-                                        ;                   (insert "system rm -f " ess-bugs-file-root ess-bugs-temp-chain ".out\n")
-                                        ;                   (insert "system ln -s " ess-bugs-file-root "chain" ess-bugs-temp-chain ".txt "
-                                        ;                       ess-bugs-file-root ess-bugs-temp-chain ".out\n")
-                                        ;                   (setq bugs-chains (- bugs-chains 1)))))
-
-                                                            (insert "modelQuit()\n")
-                                                            (insert "Local Variables" ":\n")
-                                        ;           (insert "enable-local-variables: :all\n")
-                                                            (insert "ess-bugs-chains:" (format "%d" ess-bugs-chains) "\n")
-                                                            (insert "ess-bugs-command:\"" ess-bugs-command "\"\n")
-                                                            (insert "End:\n")
-                                                            ))
-                                ))
-  )
-
-(defun ess-bugs-na-bmd (bugs-command)
-  "ESS[BUGS]: Perform the Next-Action for .bmd."
-                                        ;(ess-save-and-set-local-variables)
-  (if (equal 0 (buffer-size)) (ess-bugs-switch-to-suffix ".bmd")
-                                        ;else
-    (shell)
-    (ess-sleep)
-
-    (when (and (when (fboundp 'w32-shell-dos-semantics)
-                 (w32-shell-dos-semantics))
-               (string-equal ":" (substring ess-bugs-file 1 2)))
-      (insert (substring ess-bugs-file 0 2)))
-
-    (comint-send-input)
-    (insert "cd \"" ess-bugs-file-dir "\"")
-    (comint-send-input)
-
-                                        ;    (let ((ess-bugs-temp-chains ""))
-                                        ;
-                                        ;       (while (< 0 bugs-chains)
-                                        ;           (setq ess-bugs-temp-chains
-                                        ;               (concat (format "%d " bugs-chains) ess-bugs-temp-chains))
-                                        ;           (setq bugs-chains (- bugs-chains 1)))
-
-    ;; (insert "echo '"
-    ;;       ess-bugs-batch-pre-command " " bugs-command " < "
-    ;;       ess-bugs-file-root ".bmd > " ess-bugs-file-root ".bog 2>&1 "
-    ;;       ess-bugs-batch-post-command "' > " ess-bugs-file-root ".bsh")
-    ;; (comint-send-input)
-
-    ;; (insert "at -f " ess-bugs-file-root ".bsh now")
-
-    ;; (comint-send-input)
-
-    (insert "echo '"
-            ess-bugs-batch-pre-command " " bugs-command " < "
-            ess-bugs-file-root ".bmd > " ess-bugs-file-root ".bog 2>&1 "
-            ess-bugs-batch-post-command "' | at now")
-
-    (comint-send-input)
-    ))
-
-(defun ess-bugs-na-bug ()
-  "ESS[BUGS]: Perform Next-Action for .bug"
-
-  (if (equal 0 (buffer-size)) (ess-bugs-switch-to-suffix ".bug")
-                                        ;else
-    (ess-save-and-set-local-variables)
-    (ess-bugs-switch-to-suffix ".bmd"
-                               ess-bugs-chains ess-bugs-monitor ess-bugs-thin ess-bugs-burnin ess-bugs-update))
-  )
-
-;;;###autoload
-(define-derived-mode ess-bugs-mode ess-mode "ESS[BUGS]"
-  "Major mode for BUGS."
-  (setq-local comment-start "#")
-  (setq font-lock-defaults '(ess-bugs-font-lock-keywords nil t))
-  (setq ess-language "S") ; mimic S for ess-smart-underscore
-  (unless (when (fboundp 'w32-shell-dos-semantics)
-            (w32-shell-dos-semantics))
-    (add-hook 'comint-output-filter-functions #'ess-bugs-exit-notify-sh)))
-
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.[Bb][Uu][Gg]\\'" . ess-bugs-mode))
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.[Bb][Oo][Gg]\\'" . ess-bugs-mode))
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.[Bb][Mm][Dd]\\'" . ess-bugs-mode))
-
-(defun ess-sci-to-dec ()
-  "For BUGS/S family: Express +/-0.000E+/-0 or +/-0.0e+/-00 as a decimal."
-  (interactive)
-  (setq buffer-read-only nil)
-  (save-excursion (goto-char 0)
-                  (save-match-data (let ((ess-temp-replacement-string nil)
-                                         (ess-temp-replacement-9 0)
-                                         (ess-temp-replacement-diff 0))
-                                     (while (search-forward-regexp "-?[0-9][.][0-9][0-9]?[0-9]?[Ee][+-][0-9][0-9]?" nil t)
-                                       (setq ess-temp-replacement-string
-                                             (int-to-string (string-to-number (match-string 0))))
-                                       (setq ess-temp-replacement-diff (- (match-end 0) (match-beginning 0)))
-                                       (save-match-data
-                                         (setq ess-temp-replacement-9
-                                               (string-match "99999999999$" ess-temp-replacement-string))
-
-                                         (if (not ess-temp-replacement-9)
-                                             (setq ess-temp-replacement-9
-                                                   (string-match "000000000001$" ess-temp-replacement-string))))
-
-                                       (if ess-temp-replacement-9
-                                           (setq ess-temp-replacement-string
-                                                 (substring ess-temp-replacement-string 0 ess-temp-replacement-9)))
-
-                                       (setq ess-temp-replacement-diff
-                                             (- ess-temp-replacement-diff (string-width ess-temp-replacement-string)))
-
-                                       (while (> ess-temp-replacement-diff 0)
-                                         (setq ess-temp-replacement-string (concat ess-temp-replacement-string " "))
-                                         (setq ess-temp-replacement-diff (- ess-temp-replacement-diff 1)))
-
-                                       (replace-match ess-temp-replacement-string))))))
-
-(provide 'ess-bugs-d)
-
-;;; ess-bugs-d.el ends here
diff --git a/elpa/ess-20251212.937/ess-bugs-l.el b/elpa/ess-20251212.937/ess-bugs-l.el
deleted file mode 100644 (file)
index 1123ef1..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-;;; ess-bugs-l.el --- ESS[BUGS] languages  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2006-2020 Free Software Foundation, Inc.
-
-;; Author: Rodney Sparapani
-;; Maintainer: ESS-help <ess-helpNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Code:
-
-(require 'shell)
-(require 'ess-utils)
-(defvar ess-bugs-command)
-(defvar ess-bugs-chains)
-(defvar ess-jags-command)
-(defvar ess-jags-chains)
-(defvar ess-bugs-default-bins)
-
-(declare-function ess-bugs-na-bug "ess-bugs-d")
-(declare-function ess-jags-na-bug "ess-jags-d")
-(declare-function ess-bugs-na-bmd "ess-bugs-d")
-(declare-function ess-jags-na-jmd "ess-jags-d")
-
-(defgroup ess-bugs nil
-  "ESS: BUGS."
-  :group 'ess
-  :prefix "ess-")
-
-(defcustom ess-bugs-batch-method
-  (if (and ess-microsoft-p
-           (fboundp 'w32-shell-dos-semantics)
-           (w32-shell-dos-semantics))
-      'dos
-    'sh)
-  "Method used by `ess-bugs-batch'.
-The default is based on the value of the Emacs variable `system-type'
-and, on Windows machines, the function `w32-shell-dos-semantics'.
-\\='sh           if *shell* runs a Bourne-like or a C-like Unix shell
-\\='dos          if *shell* runs a DOS-like Windows shell
-
-Unix users will get \\='sh by default.
-
-Windows users running a DOS-like *shell* will get \\='dos by default,
-while those running a Unix-like *shell* will get \\='sh by default.
-
-Users whose default is not \\='sh, but are accessing a remote machine with
-`telnet' or `ssh', should have the following in their init file:
-   (setq-default ess-bugs-batch-method \\='sh)"
-  :group 'ess-bugs
-  :type '(choice (const :tag "Bourne/C-like Unix Shell" sh)
-                 (const :tag "DOS-like Windows shell" dos)))
-
-(defcustom ess-bugs-batch-post-command
-  (if (equal ess-bugs-batch-method 'sh) "&" " ")
-  "ESS[BUGS]: Modifiers at the end of the batch BUGS command line."
-  :group 'ess-bugs
-  :type  'string
-  )
-
-(defcustom ess-bugs-batch-pre-command
-  (if (equal ess-bugs-batch-method 'sh) "nohup nice time"
-    (if ess-microsoft-p "start"))
-  "ESS[BUGS]: Modifiers at the beginning of the batch BUGS command line."
-  :group 'ess-bugs
-  :type  'string
-  )
-
-
-(defcustom ess-bugs-default-burn-in "500"
-  "ESS[BUGS]: Burn-in iterations to discard."
-  :group 'ess-bugs
-  :type  'string
-  )
-
-(defcustom ess-bugs-default-update "1000"
-  "ESS[BUGS]: Iterations to store."
-  :group 'ess-bugs
-  :type  'string
-  )
-
-(defvar ess-bugs-batch-command ";"
-  "ESS[BUGS]: The name of the command to run BUGS in batch mode."
-  )
-
-(defvar ess-bugs-file "."
-  "ESS[BUGS]: BUGS file with PATH.")
-
-(defvar ess-bugs-file-root "."
-  "ESS[BUGS]: Root of BUGS file.")
-
-(defvar ess-bugs-file-suffix "."
-  "ESS[BUGS]: Suffix of BUGS file.")
-
-(defvar ess-bugs-file-dir "."
-  "ESS[BUGS]: Directory of BUGS file.")
-
-(defvar ess-bugs-file-data "..."
-  "ESS[BUGS]: BUGS data file.")
-
-(defcustom ess-bugs-inits-suffix ".in"
-  "ESS[BUGS]: BUGS init file suffix."
-  :group 'ess-bugs
-  :type  'string
-  )
-
-(defcustom ess-bugs-data-suffix ".dat"
-  "ESS[BUGS]: BUGS data file suffix."
-  :group 'ess-bugs
-  :type  'string
-  )
-
-(defcustom ess-bugs-mode-hook nil
-  "ESS[BUGS]: List of functions to call upon entering mode."
-  :group 'ess-bugs
-  :type 'hook)
-
-(defvar ess-bugs-monitor-vars " "
-  "ESS[BUGS]: List of BUGS variables to be written out to a file.")
-
-(defvar ess-bugs-stats-vars " "
-  "ESS[BUGS]: List of BUGS variables to be summarized with statistics.")
-
-(defvar ess-bugs-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (quote [f2])  #'ess-revert-wisely)
-    (define-key map "\C-c\C-c" #'ess-bugs-next-action)
-    (define-key map "=" #'ess-bugs-hot-arrow)
-;;    (define-key map "_" #'ess-bugs-hot-arrow)
-    map)
-  "ESS[BUGS]: Keymap for mode.")
-
-(defvar ess-bugs-syntax-table
-  (let ((table (make-syntax-table)))
-    (modify-syntax-entry ?\\ "." table)
-    (modify-syntax-entry ?# "<" table)
-    (modify-syntax-entry ?\n ">" table)
-    (modify-syntax-entry ?\( "()" table)
-    (modify-syntax-entry ?\)  ")(" table)
-    (modify-syntax-entry ?. "w" table)
-    table)
-  "ESS[BUGS]: Syntax table for mode.")
-
-(defun ess-bugs-file ()
-  "ESS[BUGS]: Set internal variables dealing with BUGS files.
-Set `ess-bugs-file', `ess-bugs-file-root', `ess-bugs-file-suffix'
-and `ess-bugs-file-dir'."
-  (let ((ess-bugs-temp-string (buffer-name)))
-    (setq ess-bugs-file (expand-file-name ess-bugs-temp-string))
-    (setq ess-bugs-file-dir
-          (convert-standard-filename (file-name-directory ess-bugs-file)))
-    (setq ess-bugs-file-root
-          (file-name-nondirectory (file-name-sans-extension ess-bugs-file)))
-
-    (if (fboundp 'file-name-extension)
-        (setq ess-bugs-file-suffix (file-name-extension ess-bugs-temp-string))
-      ;;else
-      (setq ess-bugs-file-suffix (car (last (split-string ess-bugs-temp-string "[.]")))))
-
-    (setq ess-bugs-file-suffix
-          (downcase (car (split-string (concat "." ess-bugs-file-suffix) "[<]"))))
-
-    (setq ess-bugs-file (concat ess-bugs-file-dir ess-bugs-file-root ess-bugs-file-suffix))
-    )
-  )
-
-(defun ess-bugs-exit-notify-sh (string)
-  "ESS[BUGS]: 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-bugs-hot-arrow ()
-  "ESS[BUGS]: Substitute <- for = key press"
-  (interactive)
-  (insert " <- "))
-
-(defun ess-bugs-next-action ()
-  "ESS[BUGS/JAGS]: Perform the appropriate next action."
-  (interactive)
-  (ess-bugs-file)
-
-  (cond ((equal ".bug" ess-bugs-file-suffix) (ess-bugs-na-bug))
-        ((equal ".jag" ess-bugs-file-suffix) (ess-jags-na-bug))
-        ((equal ".bmd" ess-bugs-file-suffix)
-         (ess-save-and-set-local-variables)
-         (ess-bugs-na-bmd ess-bugs-command ess-bugs-chains))
-        ((equal ".jmd" ess-bugs-file-suffix)
-         (ess-save-and-set-local-variables)
-         (ess-jags-na-jmd ess-jags-command ess-jags-chains)))
-  )
-
-(defun ess-bugs-sci-to-round-4-dp ()
-  "ESS[BUGS]: round output from +/-0.000E+/-0 to 4 decimal places."
-  (interactive)
-  (setq buffer-read-only nil)
-  (save-excursion (goto-char 0)
-                  (save-match-data (let ((ess-bugs-replacement-string nil)
-                                         (ess-bugs-replacement-9 0)
-                                         (ess-bugs-replacement-diff 0))
-                                     (while (search-forward-regexp "-?[0-9][.][0-9][0-9][0-9]E[+-][0-9]" nil t)
-                                       (setq ess-bugs-replacement-string
-                                             (int-to-string (string-to-number (match-string 0))))
-                                       (setq ess-bugs-replacement-diff (- (match-end 0) (match-beginning 0)))
-                                       (save-match-data
-                                         (setq ess-bugs-replacement-9
-                                               (string-match "99999999999$" ess-bugs-replacement-string))
-
-                                         (if (not ess-bugs-replacement-9)
-                                             (setq ess-bugs-replacement-9
-                                                   (string-match "000000000001$" ess-bugs-replacement-string))))
-
-                                       (if ess-bugs-replacement-9
-                                           (setq ess-bugs-replacement-string
-                                                 (substring ess-bugs-replacement-string 0 ess-bugs-replacement-9)))
-
-                                       (setq ess-bugs-replacement-diff
-                                             (- ess-bugs-replacement-diff (string-width ess-bugs-replacement-string)))
-
-                                       (while (> ess-bugs-replacement-diff 0)
-                                         (setq ess-bugs-replacement-string (concat ess-bugs-replacement-string " "))
-                                         (setq ess-bugs-replacement-diff (- ess-bugs-replacement-diff 1)))
-
-                                       (replace-match ess-bugs-replacement-string))))))
-
-;;; ESS[BUGS-Shell] for running BUGS interactively
-(defgroup ess-bugs-shell nil
-  "ESS: BUGS-Shell."
-  :group 'ess-bugs
-  :prefix "ess-")
-
-(defcustom ess-bugs-shell-buffer-name "BUGS"
-  "ESS[BUGS-Shell]: The name of the BUGS-Shell buffer."
-  :group 'ess-bugs-shell
-  :type  'string)
-
-(defcustom ess-bugs-shell-command "OpenBUGS"
-  "ESS[BUGS-Shell]: The name of the command to run BUGS interactively.
-
-Set to the name of the batch BUGS script that comes with ESS or
-to the name of BUGS command. Make sure it is in your PATH or
-add path to the command name."
-  :group 'ess-bugs-shell
-  :type  'string)
-
-(defcustom ess-bugs-shell-default-output-file-root "bugs"
-  "ESS[BUGS-Shell]: Default value for the root of output files."
-  :group 'ess-bugs-shell
-  :type  'string)
-
-(defcustom ess-bugs-shell-mode-hook nil
-  "ESS[BUGS-Shell]: List of functions to call upon entering mode."
-  :group 'ess-bugs-shell
-  :type 'hook)
-
-(defun ess-bugs-shell ()
-  "Create a buffer with BUGS running as a subprocess."
-  (interactive)
-  (pop-to-buffer-same-window (concat "*" ess-bugs-shell-buffer-name "*"))
-  (make-comint ess-bugs-shell-buffer-name ess-bugs-shell-command nil
-               ess-bugs-default-bins ess-bugs-shell-default-output-file-root)
-  (comint-mode)
-  (setq shell-dirtrackp t
-        major-mode 'bugs-shell-mode
-        mode-name "ESS[BUGS-Shell]"
-        comint-prompt-regexp "^Bugs> *")
-  (make-local-variable 'font-lock-defaults)
-  (setq font-lock-defaults '(ess-bugs-font-lock-keywords nil t))
-  (run-mode-hooks 'ess-bugs-shell-mode-hook)
-  )
-
-(provide 'ess-bugs-l)
-
-;;; ess-bugs-l.el ends here
diff --git a/elpa/ess-20251212.937/ess-custom.el b/elpa/ess-20251212.937/ess-custom.el
deleted file mode 100644 (file)
index 6610822..0000000
+++ /dev/null
@@ -1,2519 +0,0 @@
-;;; ess-custom.el --- Customize variables for ESS  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1997-2025 Free Software Foundation, Inc.
-
-;; Author: Rodney Sparapani
-;; Maintainer: ESS-help <ess-helpNOSPAMr-project.org>
-;; Keywords: languages
-
-;; This file is part of GNU Emacs
-
-;; 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/
-
-
-
-;; 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/
-
-
-;;; Commentary:
-;; This file holds defcustoms for ESS. It is required by ess-utils.el,
-;; which in turn is required by almost every other ESS file.
-
-;;; Code:
-(require 'comint)
-
-;; 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 (memq system-type '(ms-dos windows-nt))
-  "Value is t if the OS is one of Microsoft's, nil otherwise.")
-
-;; Customization Groups
-
-(defgroup ess nil
-  "ESS: Emacs Speaks Statistics."
-  :group 'languages
-  :link '(info-link "(ESS)")
-  :link '(url-link "https://ess.r-project.org/"))
-
-(defgroup ess-edit nil
-  "ESS: editing behavior, including comments/indentation."
-  :group 'ess
-  :prefix "ess-")
-
-(defgroup ess-proc nil
-  "ESS: process control."
-  :group 'ess
-  :prefix "ess-")
-
-(defgroup ess-command nil
-  "ESS: Commands for various things."
-  :group 'ess
-  :prefix "ess-")
-
-(defgroup ess-help nil
-  "ESS: help functions."
-  :group 'ess
-  :prefix "ess-")
-
-(defgroup ess-hooks nil
-  "ESS: hooks for customization."
-  :group 'ess
-  :prefix "ess-")
-
-(defgroup ess-S nil
-  "ESS: S Languages."
-  :group 'ess
-  :prefix "ess-")
-
-(defgroup ess-SPLUS nil
-  "ESS: S-PLUS Dialect of S."
-  :group 'ess-S
-  :prefix "ess-")
-
-(defgroup ess-R nil
-  "ESS: R Dialect of S."
-  :group 'ess-S
-  :prefix "ess-")
-
-(defgroup ess-Julia nil
-  "ESS: Julia."
-  :group 'ess
-  :prefix "julia-")
-
-(defgroup ess-sas nil
-  "ESS: SAS."
-  :group 'ess
-  :prefix "ess-")
-
-(defgroup ess-roxy nil
-  "Mode for editing in-code Roxygen documentation."
-  :group 'ess
-  :group 'convenience
-  :group 'ess-extras
-  :prefix "ess-"
-  :group 'tools)
-
-(defgroup ess-extras nil
-  "Extra utilities for ESS."
-  :group 'ess
-  :prefix "ess-")
-
-(defgroup ess-faces nil
-  "Faces and face options for ESS modes."
-  :group 'ess
-  :group 'faces
-  :prefix "ess-")
-
-
-\f ; User changeable variables
-
-;;*;; Options and Initialization
-
-;;;###autoload
-(defcustom ess-lisp-directory
-  (file-name-directory
-   (or load-file-name
-       buffer-file-name))
-  "Directory containing ess-site.el(c) and other ESS Lisp files."
-  :group 'ess
-  :type 'directory
-  :package-version '(ess . "25.01.1"))
-
-(defcustom ess-etc-directory
-  ;; Try to detect the `etc' folder only if not already set up by distribution
-  (let (dir)
-    (dolist (d '("./etc/" "../../etc/ess/" "../etc/" "../etc/ess/"))
-      (setq d (expand-file-name d ess-lisp-directory))
-      (when (file-directory-p d)
-        (setq dir d)))
-    dir)
-  "Location of the ESS etc/ directory.
-The ESS etc directory stores various auxiliary files that are useful
-for ESS, such as icons."
-  :group 'ess
-  :type 'directory
-  :package-version '(ess . "25.01.1"))
-
-;; Depending on how ESS is loaded the `load-path' might not contain
-;; the `lisp' directory. For this reason we need to add it before we
-;; start requiring ESS files
-;;;###autoload
-(add-to-list 'load-path (directory-file-name ess-lisp-directory))
-;; Add ess-lisp-directory/obsolete to load-path; files here will
-;; automatically warn that they are obsolete when loaded.
-;;;###autoload
-(add-to-list 'load-path (directory-file-name (expand-file-name "obsolete" ess-lisp-directory)))
-
-(unless (file-directory-p ess-etc-directory)
-  (display-warning 'ess (format "Could not find directory `ess-etc-directory': %s"
-                                ess-etc-directory) :error))
-
-;; Menus and pulldowns.
-
-(defcustom ess-imenu-use-p (fboundp 'imenu)
-  "Non-nil means use imenu facility.
-This value can be overridden by mode-specific variables, such
-as `ess-imenu-use-S'."
-  :group 'ess
-  :type  'boolean)
-
-(defcustom ess-imenu-use-S ess-imenu-use-p
-  "Non-nil means include an Imenu menu item in S buffers."
-  :group 'ess
-  :type  'boolean)
-
-(defcustom ess-auto-width-visible nil
-  "When non-nil, echo width setting in the inferior buffer.
-See `ess-auto-width'. Be warned that ESS can set the width a
-lot."
-  :group 'ess
-  :type 'boolean
-  :package-version '(ess . "25.01.1"))
-
-(defcustom ess-auto-width nil
-  "When non-nil, set the width option when the window configuration changes.
-When \\='frame, set the width to the frame width. When \\='window, set
-the width to the window width. If an integer, set the width to
-that integer. If it's a negative integer, set the width to the
-window's width minus that number. Anything else is treated as
-\\='window."
-  :group 'ess
-  :type '(choice (const :tag "Do nothing" :value nil)
-                 (const :tag "Frame width" :value frame)
-                 (const :tag "Window width" :value window)
-                 (integer :tag "Integer value"))
-  :package-version '(ess . "25.01.1"))
-
-(defcustom ess-handy-commands '(("change-directory"     . ess-change-directory)
-                                ("install.packages"     . ess-install-library)
-                                ("library"              . ess-library)
-                                ("objects[ls]"          . ess-execute-objects)
-                                ("help-apropos"         . ess-display-help-apropos)
-                                ("help-index"           . ess-display-package-index)
-                                ("help-object"          . ess-display-help-on-object)
-                                ("search"               . ess-execute-search)
-                                ("set-width"            . ess-execute-screen-options)
-                                ("setRepos"             . ess-setRepositories)
-                                ("sos"                  . ess-sos)
-                                ("vignettes"            . ess-display-vignettes)
-                                )
-  "An alist of custom ESS commands.
-These are available for call by function `ess-handy-commands' and
-`ess-smart-comma' function."
-  :group 'ess
-  :type 'alist)
-
-(defvar-local ess--local-handy-commands nil
-  "Store handy commands locally.")
-
-(defcustom ess-describe-at-point-method nil
-  "Whether `ess-describe-object-at-point' should use a tooltip.
-If nil display in an electric buffer. If \\='tooltip display in
-a tooltip.
-
-See also `tooltip-hide-delay' and variable `tooltip-delay'."
-  :group 'ess-utils
-  :type '(choice (const :tag "buffer" :value nil ) (const tooltip)))
-
-(defvaralias
-  'ess-R-describe-object-at-point-commands
-  'ess-r-describe-object-at-point-commands)
-(defcustom ess-r-describe-object-at-point-commands
-  '(("str(%s)")
-    (".ess_htsummary(%s, hlength = 20, tlength = 20)")
-    ("summary(%s, maxsum = 20)"))
-  "A list of commands cycled by `ess-describe-object-at-point'.
-%s is substituted with the name at point.
-
-The value of each element is nil and is not used in current
-implementation."
-  :group 'ess-R
-  :type 'alist)
-
-(defcustom ess-S-describe-object-at-point-commands
-  ess-R-describe-object-at-point-commands
-  "An alist of commands cycled by `ess-describe-object-at-point'.
-%s is substitute with the name at point. The value is not used as
- yet."
-  :group 'S+
-  :type 'alist)
-
-
-(defcustom ess-can-eval-in-background t
-  "If non-nil ESS can perform caching and other background activities.
-This allows ESS to call the subprocess on idle time."
-  :group 'ess
-  :type 'boolean)
-
-(defcustom ess-user-full-name (user-full-name)
-  "The full name of the user."
-  :group 'ess
-  :type 'string)
-
-(defcustom ess-blink-region t
-  "If t evaluated region is highlighted for a shortwhile.
-See also `ess-blink-delay'"
-  :group 'ess
-  :type 'boolean)
-
-(defcustom ess-blink-delay .3
-  "Number of seconds to highlight the evaluated region."
-  :group 'ess
-  :type 'number)
-
-(defcustom ess-ask-for-ess-directory t
-  "When non-nil ask the process directory when ESS process starts.
-When set to nil, and the process is invoked with an universal
-argument, the directory is prompted for."
-  :group 'ess
-  :type 'boolean)
-
-(defcustom ess-ask-about-transfile nil
-  "Non-nil means ask about a transcript file before running ESS."
-  :group 'ess
-  :type 'boolean)
-
-(defcustom ess-display-buffer-reuse-frames t
-  "Non-nil means \\[display-buffer] reuses existing frames.
-See `display-buffer-reuse-frames'."
-  :group 'ess
-  :type 'boolean)
-
-(defvar-local ess-language nil
-  "Determines the language to use for the current buffer.
-See also `ess-dialect'.")
-
-(defvar-local ess-dialect nil
-  "String version of the dialect being run for the inferior process.
-This, plus `ess-language', should be able to determine the exact
-version of the statistical package being executed in the particular
-buffer.")
-
-(defvaralias 'ess-directory-function 'ess-startup-directory-function)
-(defcustom ess-startup-directory-function nil
-  "Function to return the directory that ESS is run from.
-Value of `ess-startup-directory' has precedence over this function."
-  :group 'ess
-  :type '(choice (const nil) function))
-
-(defvaralias 'ess-directory 'ess-startup-directory)
-(defcustom ess-startup-directory nil
-  "The directory to run ESS processes from.
-If a string it should be a directory from which to start the
-process. If a symbol, the symbol's value should be a directory.
-
-For example, the following setting would always start the process
-in the directory of the current file:
-
-   (setq ess-startup-directory \\='default-directory)
-
-If `ess-startup-directory' is nil (the default) and
-`ess-startup-directory-function' is non-nil, the value returned
-by `ess-startup-directory-function' is used as a directory.
-
-If `ess-startup-directory-function' is nil, then the current
-project as returned by `project-current' is used. For files which
-mark an R project see `ess-r-project'. For example you can add
-.Rprofile to a sub-directory of a project to mark it as R
-sub-project.
-
-Finally, if not in a project (`project-current' returned nil) the
-`default-directory' is used. It is normally the directory of the
-current file.
-
-See also `ess-ask-for-ess-directory'."
-  :group 'ess
-  :type '(choice (const nil) directory symbol))
-
-
-(defcustom ess-history-directory nil
-  "Directory to pick up `ess-history-file' from.
-If this is nil, the history file is relative to the startup
-directory of the inferior process (see `ess-startup-directory')."
-  :group 'ess
-  :type '(choice (const nil) directory))
-
-(defcustom ess-history-file t
-  "File to pick up history from.  nil means *no* history is read or written.
-t means something like \".Rhistory\".
-If this is a relative file name, it is relative to `ess-history-directory'.
-Consequently, if that is set explicitly, you will have one history file
-for all projects."
-  :group 'ess
-  :type '(choice (const :tag "Off" nil)
-                 (const :tag "On" t)
-                 file))
-
-(defcustom ess-plain-first-buffername t
-  "When non-nil, the first process buffer created does not have a number.
-In other words, it is R:foo rather than R:1:foo. Subsequent
-processes buffers are always numbered (e.g. R:2:foo."
-  :group 'ess
-  :type 'boolean)
-
-
-(define-obsolete-variable-alias
-  'ess-use-inferior-program-name-in-buffer-name
-  'ess-use-inferior-program-in-buffer-name "ESS 18.10")
-(defcustom ess-use-inferior-program-in-buffer-name nil
-  "For R, use e.g., `R-2.1.0' or `R-devel' (the program name) for buffer name.
-Avoids the plain dialect name."
-  :group 'ess
-  :type 'boolean)
-
-(defcustom  ess-use-ido t
-  "If t ess will try to use ido completion whenever possible.
-
-By default ESS uses enables IDO flex matching. See
-`ido-enable-flex-matching' for details on flex matching and
-`ess-ido-flex-matching' on how to disable it for ESS, if you
-don't want it.
-
-See info node `(ido) Top' for more information about how ido
-works."
-  :group 'ess
-  :require 'ido
-  :type 'boolean)
-
-
-(defcustom ess-tab-complete-in-script nil
-  "If non-nil, TAB tries to complete if it does not indent in script buffers.
-See also `ess-first-tab-never-complete'."
-  :group 'ess
-  :type 'boolean)
-(make-obsolete-variable 'ess-tab-complete-in-script 'tab-always-indent "ESS 19.04" 'set)
-
-(define-obsolete-variable-alias 'ess-first-tab-never-completes-p
-  'ess-first-tab-never-complete "ESS 19.04")
-(defcustom ess-first-tab-never-complete 'symbol
-  "If t, first TAB never tries to complete in `ess-mode'.
-If \\='symbol first TAB doesn't try to complete if next char is a
-valid symbol constituent.
-
-If \\='symbol-or-paren  don't complete if next char is closed paren
-)}] or symbol character.
-
-If \\='symbol-or-paren-or-punct don't complete if next char is
-punctuation +-=% etc, or closed paren or symbol.
-
-If \\='unless-eol - first TAB completes only at end of line.
-
-If nil first TAB always tries to complete (this might be too
-aggressive and dangerous)."
-  :group 'ess
-  :type '(choice (const nil)
-                 (const symbol)
-                 (const symbol-or-paren)
-                 (const symbol-or-paren-or-punct)
-                 (const unless-eol)
-                 (const t)))
-
-(defcustom ess-use-eldoc t
-  "If t, activate eldoc in `ess-mode' and `inferior-ess-mode' buffers.
-If \\='script-only activate in `ess-mode' buffers only.
-
-See also `ess-eldoc-show-on-symbol'."
-  :group 'ess-extras
-  :type '(choice (const t) (const script-only) (const nil)))
-
-
-(defcustom ess-eldoc-show-on-symbol nil
-  "If non-nil, show help string whenever the point is on a symbol.
-If nil show only when the point is in a function call, i.e. after (."
-  :group 'ess-extras
-  :type  'boolean)
-
-(defcustom ess-eldoc-abbreviation-style 'normal
-  "Controls how `eldoc' displays information that does not fit on a line.
-
-A symbol which can be
-
-- nil: do nothing
-- mild: Replace TRUE, FALSE with T,F
-- normal: Try mild + shorten the default values longer than 10
-  characters.
-- strong: Try normal + completely remove default values except
-  =F,=T,=d where d is a digit.
-- aggressive (or t): Try strong + truncate the doc string to fit
-  into minibuffer.
-
-The default style is \\='normal.
-
-Ess-eldoc also honors the value of
-`eldoc-echo-area-use-multiline-p'. If this variable is not t (the
-default), doc strings are truncated to fit into minibufer. This
-allows the use of different abbreviation styles with the
-truncation."
-  :group 'ess
-  :type '(choice (const nil) (const mild) (const normal) (const strong) (const aggressive) (const t)))
-
-(defcustom ess-use-flymake t
-  "If non-nil activate flymake in `ess-mode' buffers.
-If \\='process, only check if the buffer has an inferior process."
-  :group 'ess
-  :type '(choice (const :tag "Always" t)
-                 (const :tag "With running inferior process" process)
-                 (const :tag "Never" nil))
-  :package-version '(ess . "25.01.1"))
-
-(defcustom ess-use-auto-complete t
-  "If non-nil, activate auto-complete support.
-If t, activate auto-complete support in `ess-mode' and
-`inferior-ess-mode' buffers. If \\='script-only activate in `ess-mode'
-buffers only.
-
-If non-nil add `ac-source-R' and `ac-source-filename' to the
-`ac-sources' buffer local variable.
-
-ESS defines three AC sources `ac-source-R',`ac-source-R-objects'
-and `ac-source-R-args'. See auto-complete package
-documentation (http://cx4a.org/software/auto-complete/) for how
-to install your custom sources."
-  :group 'ess-extras
-  :type '(choice (const t) (const script-only) (const nil)))
-(make-obsolete-variable 'ess-use-auto-complete "Auto-complete is unmaintained; use company-mode instead"
-                        "ESS 19.04" 'set)
-
-(defcustom ess-use-company t
-  "If t, activate company support in `ess-mode' and `inferior-ess-mode' buffers.
-If non-nil add `company-R-args' and `company-R-objects' to the
-`company-backends'. If \\='script-only activate in `ess-mode' buffers
-only."
-  :group 'ess-extras
-  :type '(choice (const t) (const script-only) (const nil)))
-
-(defcustom ess-company-arg-prefix-length nil
-  "Minimum prefix for ess company function argument completion."
-  :group 'ess-extras
-  :type '(choice (const :tag "Default" nil)
-                 integer))
-
-(defcustom ess-use-tracebug t
-  "If t, load `ess-tracebug' when R process starts."
-  :group 'ess-extras
-  :type  'boolean)
-
-(defcustom  ess-ido-flex-matching t
-  "If t, ido for ESS completion uses flex matching.
-See `ido-enable-flex-matching' for details.
-If you have an old computer, or you load lot of packages, you
-might want to set this to nil."
-  :group 'ess
-  :type 'boolean)
-
-(defvar ess--completing-hist nil
-  "Variable to store completion history.
-Used by `ess-completion-read' command.")
-
-(defvar-local ess-smart-operators ()
-  "List of smart operators to be used in ESS and IESS modes.
-Not to be set by users. It is redefined by mode specific
-settings, such as `ess-r-smart-operators'.")
-
-(defvaralias 'ess-R-smart-operators 'ess-r-smart-operators)
-(defvar ess-r-smart-operators nil
-  "If nil, don't use any of smart operators.
-If t, use all. If an explicit list of operators, use only those
-operators.
-
-In current version of ESS, it controls the behavior of
-`ess-smart-comma' only, but will be enriched in the near future.")
-
-
-(defvar ess-no-skip-regexp "[ \t\n]*\\'"
-  "If `ess-next-code-line' sees this line, it doesn't jump over.
-
-Used to avoid annoying jumping by ess-eval.*-and-step to end of
-buffer or end chunks etc.")
-
-(make-obsolete-variable 'ess-smart-S-assign-key nil "ESS 18.10")
-
-(defcustom ess-assign-list (cons (or (bound-and-true-p ess-S-assign) " <- ")
-                                 '(" <<- " " = " " -> " " ->> "))
-  "List of assignment operators.
-`ess-cycle-assign' uses this list.  These strings must
-contain spaces on either side."
-  ;; Note that spaces on either side is not strictly true (as in the
-  ;; function won't error), but matching <-/<<- is broken without
-  ;; them.
-  :type '(repeat string)
-  :group 'ess
-  :package-version '(ess . "25.01.1"))
-
-(defvar ess-S-assign)
-(make-obsolete-variable 'ess-S-assign 'ess-assign-list "ESS 18.10")
-
-(defcustom ess-r-prettify-symbols
-  '(("<-" . (?\s (Br . Bl) ?\s (Bc . Bc) ?←))
-    ("->" . (?\s (Br . Bl) ?\s (Bc . Bc) ?→))
-    ("->>" .  (?\s (Br . Bl) ?\s (Br . Bl) ?\s
-                   (Bl . Bl) ?- (Bc . Br) ?- (Bc . Bc) ?>
-                   (Bc . Bl) ?- (Br . Br) ?>))
-    ("<<-" .  (?\s (Br . Bl) ?\s (Br . Bl) ?\s
-                   (Bl . Bl) ?< (Bc . Br) ?- (Bc . Bc) ?-
-                   (Bc . Bl) ?< (Br . Br) ?-)))
-  ;; Setup prettify-symbols-alist to show "pretty" arrows, but make
-  ;; sure that they arrows use the same amount of spacing as <- and
-  ;; <<- to ensure indentation does not change when
-  ;; prettify-symbols-mode is turned on/off.
-  "Alist of symbols prettifications, see `prettify-symbols-alist'.
-This gets appended to `prettify-symbols-alist', so set it to nil
-if you want to disable R specific prettification."
-  :group 'ess-R
-  :type '(alist :key-type string :value-type symbol)
-  :package-version '(ess . "25.01.1"))
-
-;;*;; Variables concerning editing behavior
-
-(defcustom ess-filenames-map t
-  "If non-nil, filenames and objects are the same in an attached directory.
-This is not true for DOS and other OS's with limited filename
-lengths. Even if this is set incorrectly, the right things will
-probably still happen, however."
-  :group 'ess-edit
-  :type 'boolean)
-
-(defcustom ess-keep-dump-files t
-  "Variable controlling whether to delete dump files after a successful load.
-If nil: always delete.  If `ask', confirm to delete.  If `check', confirm
-to delete, except for files created with `ess-dump-object-into-edit-buffer'.
-Anything else, never delete.  This variable only affects the behavior
-of `ess-load-file'.  Dump files are never deleted if an error occurs
-during the load."
-  :group 'ess-edit
-  :type '(choice (const :tag "Check" :value check)
-                 (const :tag "Ask" :value ask)
-                 (const :tag "Always keep" :value t)
-                 (const :tag "Always delete" :value nil)))
-
-(defcustom ess-delete-dump-files nil
-  "Non-nil means delete dump files after they are created.
-This applies to dump files created with
-`ess-dump-object-into-edit-buffer', only.
-
-Boolean flag which determines what to do with the dump files
-generated by \\[ess-dump-object-into-edit-buffer], as follows:
-
-        If non-nil: dump files are deleted after each use, and so appear
-only transiently. The one exception to this is when a loading error
-occurs, in which case the file is retained until the error is
-corrected and the file re-loaded.
-
-        If nil: dump files are not deleted, and backups are kept
-as usual.  This provides a simple method for keeping an archive of S
-functions in text-file form.
-
-Auto-save is always enabled in dump-file buffers to enable recovery
-from crashes.
-
-This is useful to prevent source files being created for objects
-you don't actually modify.  Once the buffer is modified and saved
-however, the file is not subsequently deleted unless
-`ess-keep-dump-files' is nil, and the file is successfully loaded
-back into S."
-  :group 'ess-edit
-  :type 'boolean)
-
-(defcustom ess-fill-calls t
-  "If non-nil, refilling inside a call arranges arguments.
-In other words, refilling a paragraph inside a function or
-indexing call will arrange the arguments according to
-`fill-column' as in:
-
-  fun_call(argument1, argument2,
-           argument3, argument4)
-
-
-Refilling repeatedly cycles through different styles and
-eventually to the original formatting.
-
- The second style formats according to one argument per line:
-
-  fun_call(argument1,
-           argument2,
-           argument3,
-           argument4)
-
-When `ess-fill-calls-newlines' is t, the second style becomes:
-
-  fun_call(
-      argument1,
-      argument2,
-      argument3,
-      argument4
-  )
-
-
-Setting `ess-offset-arguments' to `prev-line' or `prev-call'
-activates a third style. It keeps one argument per line except
-for the first N arguments. N is controlled with a prefix. For
-example, calling \\[fill-paragraph] three times sets N to 1 while
-calling \\[fill-paragraph] twice then \\[universal-argument] 2
-\\[fill-paragraph] sets N to 2. Here what the default produces:
-
-  fun_call(argument1,
-      argument2,
-      argument3,
-      argument4,
-      argument5
-  )
-
-This style is useful for refilling R6 or ggproto class
-definitions.
-
-
-The blinking of the refilled region can be disabled with
-`ess-blink-refilling'."
-  :group 'ess-edit
-  :type 'boolean)
-
-(defcustom ess-fill-continuations t
-  "Controls filling of continuations.
-If non-nil, refilling a paragraph inside a continuation of
-statements (expressions separated by operators) will arrange all
-its elements, never going past `fill-column'.
-
-  lm(outcome ~ pred1 + pred2 +
-       pred3 + pred4, data)
-
-Refilling repeatedly cycles through different styles and
-eventually to the original formatting.
-
-The second style lay out the statements according to one
-expression per line:
-
-  lm(outcome ~
-       pred1 +
-       pred2 +
-       pred3 +
-       pred4, data)
-
-The blinking of the refilled region can be disabled with
-`ess-blink-refilling'."
-  :group 'ess-edit
-  :type 'boolean)
-
-(defcustom ess-fill-calls-newlines nil
-  "When non-nil, refilling may place newlines before and after delimiters.
-When non-nil, the second refilling style produces newlines
-after and before the opening and closing delimiters. This is
-intended for example for dplyr-style code:
-
-  fun_call(
-      argument1,
-      argument2,
-      argument3,
-      argument4
-  )
-
-Note that this setting is temporary and likely to be replaced in
-a future ESS version by a more comprehensive and flexible way to
-set refill styles."
-  :group 'ess-edit
-  :type 'boolean)
-
-(defcustom ess-blink-refilling t
-  "When non-nil, refilling blinks the filling region."
-  :group 'ess-edit
-  :type 'boolean)
-
-(define-obsolete-variable-alias 'ess-mode-silently-save 'ess-save-silently "ESS 19.04")
-(defcustom ess-save-silently 'auto
-  "If non-nil, possibly save buffers without asking.
-If t, save without asking. If \\='auto, save without asking if
-either `compilation-ask-about-save' or variable `auto-save-visited-mode'
-is non-nil. Affects `ess-save-file'."
-  :group 'ess-edit
-  :type '(choice (const :tag "Do not save without asking." :value nil)
-                 (const :tag "Use compilation-ask-about-save and auto-save-visited-mode."
-                        :value auto)
-                 (const :tag "Save without asking." :value t))
-  :package-version '(ess . "25.01.1"))
-
-;;*;; Variables controlling editing
-
-;;;*;;; Edit buffer processing
-(defcustom ess-function-template " <- function( )\n{\n\n}\n"
-  "If non-nil, function template used when editing nonexistent objects.
-
-The edit buffer will contain the object name in quotes, followed by
-this string. Point will be placed after the first parenthesis or
-bracket."
-  :group 'ess-edit
-  :type 'string)
-
-;;;*;;; Indentation parameters
-
-(define-obsolete-variable-alias 'ess-tab-always-indent 'tab-always-indent "ESS 19.04")
-
-(define-obsolete-variable-alias 'ess-indent-level 'ess-indent-offset "15.09")
-(defvar ess-indent-offset 2
-  "Main indentation offset that is commonly inherited by other offsets.
-See `ess-style-alist' for all available offsets.")
-;;;###autoload
-(put 'ess-indent-offset 'safe-local-variable #'numberp)
-
-
-(defvar ess-offset-arguments 'open-delim
-  "Indent for arguments of function calls or indexing brackets.
-This variables has an effect only when the ( or [ are not
-directly followed by a new line. See
-`ess-offset-arguments-newline' for indentation after closing
-newline.
-
-When set to `open-delim', arguments are indented relative to the
-opening parenthesis of the closest function call:
-
-  object <- call(argument, other_call(argument,
-                                      other_argument))
-
-
-When set to `prev-call', arguments are indented relative to the
-closest function call:
-
-  object <- call(argument, other_call(argument,
-                               other_argument))
-
-
-When set to `prev-line', arguments are indented relative to the
-preceding line:
-
-  object <- call(argument, other_call(argument,
-      other_argument))
-
-This setting can also be set to a list containing the the offset
-type and the offset size, such as `'(prev-call 2)'. Otherwise,
-`ess-indent-offset' is used as a default. See `ess-style-alist'
-for other offsets controlling indentation.")
-
-(define-obsolete-variable-alias 'ess-arg-function-offset-new-line 'ess-offset-arguments-newline "15.09")
-(defvar ess-offset-arguments-newline 'prev-call
-  "Indent of arguments when ( or [ is followed by a new line.
-
-When set to `open-delim', arguments on a new line are indented
-relative to the opening parenthesis of the closest function call:
-
-  object <- call(argument, other_call(
-                                      argument,
-                                      other_argument
-                                      ))
-
-
-When set to `prev-call', arguments on a new line are indented relative to
-the closest function call:
-
-  object <- call(argument, other_call(
-                               argument,
-                               other_argument
-                           ))
-
-You can control the details of indentation at `prev-call' with
-`ess-indent-from-lhs' and `ess-indent-from-chain-start'.
-
-
-When set to `prev-line', arguments on a new line are indented
-relative to the preceding line:
-
-  object <- call(argument, other_call(
-      argument,
-      other_argument
-  ))
-
-This setting can also be set to a list containing the the offset
-type and the offset size, such as `'(prev-call 2)'. Otherwise,
-`ess-indent-offset' is used as a default. See `ess-style-alist'
-for other offsets controlling indentation.")
-
-(defvar ess-offset-block 'prev-line
-  "Controls indentation for blocks.
-A block is usually declared with braces but a statement wrapped
-in anonymous parentheses is also considered a block. This offset
-can be either `prev-call', `prev-line' or `open-delim'.
-
-When set to `open-delim', blocks are indented relative to the
-opening parenthesis of the closest function call:
-
-  call(argument, other_call(parameter = {
-                                stuff
-                            }, {
-                                stuff
-                            }))
-
-  call(argument, lapply(data, function(x) {
-                            body
-                        }))
-
-
-When set to `prev-call', blocks are indented relative to the
-closest function call:
-
-  call(argument, other_call(parameter = {
-                     stuff
-                 }, {
-                     stuff
-                 }))
-
-  call(argument, lapply(data, function(x) {
-                     body
-                 }))
-
-You can control the details of indentation at `prev-call' with
-`ess-indent-from-lhs' and `ess-indent-from-chain-start'.
-
-
-When set to `prev-line', blocks are indented relative to the
-preceding line:
-
-  call(argument, other_call(parameter = {
-      stuff
-  }, {
-      stuff
-  }))
-
-  call(argument, lapply(data, function(x) {
-      body
-  }))
-
-This setting can also be set to a list containing the the offset
-type and the offset size, such as `'(prev-call 2)'. Otherwise,
-`ess-indent-offset' is used as a default. See `ess-style-alist'
-for other offsets controlling indentation.")
-
-(define-obsolete-variable-alias 'ess-first-continued-statement-offset 'ess-offset-continued "15.09")
-(define-obsolete-variable-alias 'ess-continued-statement-offset 'ess-offset-continued "15.09")
-(defvar ess-offset-continued 'straight
-  "This setting controls indentation of continued statements.
-That is, consecutive statements separated by operators.
-
-When set to \\='straight, continued statements are indented as follows:
-
-  object %>%
-      some_function() %>%
-      other_function()
-
-When set to \\='cascade:
-
-  object %>%
-      some_function() %>%
-          other_function()
-
-The \\='straight and \\='cascade settings are actually equivalent to
-\\='(straight . t) and \\='(cascade . t), where t represents the
-base indent size. More generally, you can supply \\='(straight . N)
-to control the size of indentation.
-
-See `ess-style-alist' for for an overview of ESS indentation.")
-
-(defvar ess-align-nested-calls '("ifelse")
-  "List of strings for which `ess-offset-arguments-newline' is ignored.
-These calls will be vertically aligned instead. For example, if
-`ifelse' is a member of the list, nested ifelse calls are
-indented like this:
-
-    object <- ifelse(condition1, out1,
-              ifelse(condition2, out2, out3))
-
-See `ess-style-alist' for for an overview of ESS indentation.")
-
-(defvar ess-align-arguments-in-calls '("function[ \t]*(")
-  "A list of regexes where `ess-offset-arguments' is ignored.
-List of regexes specifying the calls where `ess-offset-arguments'
-should have no effect on function declarations. The arguments of
-those calls will be aligned from the opening parenthesis.
-
-By default, function declarations are overridden. If for example
-`ess-offset-arguments' is set to `prev-line', then function calls
-are normally indented as in:
-
-  some_function(argument1,
-      argument2, argument3
-  )
-
-However, the parameters of function declarations will be
-vertically aligned:
-
-  fun <- function(argument1,
-                  argument2
-                  argument3) {
-      body
-  }
-
-See `ess-style-alist' for further details.")
-
-(defvar ess-align-continuations-in-calls t
-  "Whether continuations inside calls are indented from the opening delimiter.
-This produces the following indentation:
-
-  10 + (1 + 2 +
-        3 + 4)
-  object[variable1 +
-         variable2]
-
-  if (test1 || test2 ||
-      test3 || test4) {
-      any(test5 &
-          test6)
-  }
-
-instead of
-
-  10 + (1 + 2 +
-            3 + 4)
-  object[variable1 +
-             variable2]
-
-  if (test1 || test2 ||
-        test3 || test4) {
-      any(test5 &
-            test6)
-  }
-
-Definition operators (`<-', `=', `:=' and `~') still trigger an
-indentation in all cases. Also, operators at top level and in
-curly brackets are not affected by this setting and always induce
-an offset:
-
-  {
-      var1 +
-          var2
-  }
-
-See `ess-style-alist' for for an overview of ESS indentation.")
-
-(defvar ess-align-blocks '(control-flow)
-  "List of block types for which `ess-offset-blocks' is ignored.
-The overridden blocks are vertically aligned. The list can
-contain either or both of the symbols `control-flow' and
-`fun-decl'.
-
-With `control-flow', if, else for and while blocks will always be
-aligned vertically. With `fun-decl', the body of a function
-declaration will always be aligned with the call to
-`function'.")
-
-(define-obsolete-variable-alias 'ess-arg-function-offset 'ess-indent-from-lhs "15.09")
-(defvar ess-indent-from-lhs '(arguments fun-decl-opening)
-  "List of elements that are indented from the left side of an assignment.
-The list accepts the symbol `arguments' and `fun-decl-opening'.
-
-For arguments, this setting only has an effect for offsets set to
-`prev-call'. When set, this indentation is produced:
-
-  some_function(parameter = other_function(
-                                argument
-                            ))
-
-  object <- some_function(
-                argument1,
-                argument2
-            )
-
-instead of:
-
-  some_function(parameter = other_function(
-                    argument
-                ))
-
-  object <- some_function(
-      argument1,
-      argument2
-  )
-
-
-`fun-decl-opening' refers to the opening curly following a function
-declaration. Setting it produces:
-
-  object <-
-      function(argument)
-  {
-      body
-  }
-
-instead of:
-
-  object <-
-      function(argument)
-      {
-          body
-      }
-
-This is useful when (a) you have a long function name and want to
-break a line after `<-' so that you have room to lay out the
-arguments within `fill-column' characters; (b) you still want to
-align the function body from the LHS to save horizontal space.
-
-See `ess-style-alist' for for an overview of ESS indentation.")
-
-(defvar ess-indent-from-chain-start t
-  "When non-nil, chained calls are treated as if they were one call.
-Indentation will start from the first one. This setting only has
-an effect for offsets set to `prev-call' or block offsets set to
-`opening-delim'.
-
-If nil:
-
-  some_function(other_function(
-                    argument
-                ))
-
-If t:
-
-  some_function(other_function(
-      argument
-  ))
-
-See `ess-style-alist' for for an overview of ESS indentation.")
-
-;;added rmh 2Nov97 at request of Terry Therneau
-(define-obsolete-variable-alias 'ess-fancy-comments 'ess-indent-with-fancy-comments "15.09")
-(defcustom ess-indent-with-fancy-comments t
-  "Non-nil means distinguish between #, ##, and ### for indentation.
-See `ess-style-alist' for for an overview of ESS indentation."
-  :type 'boolean
-  :group 'ess-edit)
-
-;;;*;;; Editing styles
-
-(defvar ess-style-alist
-  `((BSD
-     (ess-indent-offset                . 8)
-     (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
-     (ess-offset-arguments-newline     . ,(default-value 'ess-offset-arguments-newline))
-     (ess-offset-block                 . prev-call)
-     (ess-offset-continued             . ,(default-value 'ess-offset-continued))
-     (ess-align-nested-calls           . ,(default-value 'ess-align-nested-calls))
-     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
-     (ess-align-continuations-in-calls . ,(default-value 'ess-align-continuations-in-calls))
-     (ess-align-blocks                 . ,(default-value 'ess-align-blocks))
-     (ess-indent-from-lhs              . ,(default-value 'ess-indent-from-lhs))
-     (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
-     (ess-indent-with-fancy-comments   . ,(default-value 'ess-indent-with-fancy-comments)))
-
-    (C++
-     (ess-indent-offset                . 4)
-     (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
-     (ess-offset-arguments-newline     . ,(default-value 'ess-offset-arguments-newline))
-     (ess-offset-block                 . prev-call)
-     (ess-offset-continued             . ,(default-value 'ess-offset-continued))
-     (ess-align-nested-calls           . ,(default-value 'ess-align-nested-calls))
-     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
-     (ess-align-continuations-in-calls . ,(default-value 'ess-align-continuations-in-calls))
-     (ess-align-blocks                 . ,(default-value 'ess-align-blocks))
-     (ess-indent-from-lhs              . (arguments))
-     (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
-     (ess-indent-with-fancy-comments   . ,(default-value 'ess-indent-with-fancy-comments)))
-
-    ;; CLB added rmh 2Nov97 at request of Terry Therneau
-    (CLB
-     (ess-indent-offset                . ,(default-value 'ess-indent-offset))
-     (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
-     (ess-offset-arguments-newline     . ,(default-value 'ess-offset-arguments-newline))
-     (ess-offset-block                 . ,(default-value 'ess-offset-block))
-     (ess-offset-continued             . (straight 4))
-     (ess-align-nested-calls           . ,(default-value 'ess-align-nested-calls))
-     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
-     (ess-align-continuations-in-calls . ,(default-value 'ess-align-continuations-in-calls))
-     (ess-align-blocks                 . ,(default-value 'ess-align-blocks))
-     (ess-indent-from-lhs              . ,(default-value 'ess-indent-from-lhs))
-     (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
-     (ess-indent-with-fancy-comments   . ,(default-value 'ess-indent-with-fancy-comments)))
-
-    (GNU
-     (ess-indent-offset                . ,(default-value 'ess-indent-offset))
-     (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
-     (ess-offset-arguments-newline     . (prev-call 4))
-     (ess-offset-block                 . ,(default-value 'ess-offset-block))
-     (ess-offset-continued             . ,(default-value 'ess-offset-continued))
-     (ess-align-nested-calls           . ,(default-value 'ess-align-nested-calls))
-     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
-     (ess-align-continuations-in-calls . ,(default-value 'ess-align-continuations-in-calls))
-     (ess-align-blocks                 . ,(default-value 'ess-align-blocks))
-     (ess-indent-from-lhs              . ,(default-value 'ess-indent-from-lhs))
-     (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
-     (ess-indent-with-fancy-comments   . ,(default-value 'ess-indent-with-fancy-comments)))
-
-    (K&R
-     (ess-indent-offset                . 5)
-     (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
-     (ess-offset-arguments-newline     . ,(default-value 'ess-offset-arguments-newline))
-     (ess-offset-block                 . prev-call)
-     (ess-offset-continued             . ,(default-value 'ess-offset-continued))
-     (ess-align-nested-calls           . ,(default-value 'ess-align-nested-calls))
-     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
-     (ess-align-continuations-in-calls . ,(default-value 'ess-align-continuations-in-calls))
-     (ess-align-blocks                 . ,(default-value 'ess-align-blocks))
-     (ess-indent-from-lhs              . ,(default-value 'ess-indent-from-lhs))
-     (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
-     (ess-indent-with-fancy-comments   . ,(default-value 'ess-indent-with-fancy-comments)))
-
-    ;; added ajr 17.Feb'04 to match "common R" use (== DEFAULT apart from  offset = 4)
-    (RRR
-     (ess-indent-offset                . 4)
-     (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
-     (ess-offset-arguments-newline     . ,(default-value 'ess-offset-arguments-newline))
-     (ess-offset-block                 . ,(default-value 'ess-offset-block))
-     (ess-offset-continued             . ,(default-value 'ess-offset-continued))
-     (ess-align-nested-calls           . ,(default-value 'ess-align-nested-calls))
-     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
-     (ess-align-continuations-in-calls . ,(default-value 'ess-align-continuations-in-calls))
-     (ess-align-blocks                 . ,(default-value 'ess-align-blocks))
-     (ess-indent-from-lhs              . ,(default-value 'ess-indent-from-lhs))
-     (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
-     (ess-indent-with-fancy-comments   . ,(default-value 'ess-indent-with-fancy-comments)))
-
-    (RRR+
-     (ess-indent-offset                . 4)
-     (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
-     (ess-offset-arguments-newline     . ,(default-value 'ess-offset-arguments-newline))
-     (ess-offset-block                 . open-delim)
-     (ess-offset-continued             . ,(default-value 'ess-offset-continued))
-     (ess-align-nested-calls           . ,(default-value 'ess-align-nested-calls))
-     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
-     (ess-align-continuations-in-calls . ,(default-value 'ess-align-continuations-in-calls))
-     (ess-align-blocks                 . ,(default-value 'ess-align-blocks))
-     (ess-indent-from-lhs              . (arguments))
-     (ess-indent-from-chain-start      . nil)
-     (ess-indent-with-fancy-comments   . ,(default-value 'ess-indent-with-fancy-comments)))
-
-    (RStudio
-     (ess-indent-offset                . ,(default-value 'ess-indent-offset))
-     (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
-     (ess-offset-arguments-newline     . prev-line)
-     (ess-offset-block                 . ,(default-value 'ess-offset-block))
-     (ess-offset-continued             . ,(default-value 'ess-offset-continued))
-     (ess-align-nested-calls           . nil)
-     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
-     (ess-align-continuations-in-calls . nil)
-     (ess-align-blocks                 . nil)
-     (ess-indent-from-lhs              . (arguments))
-     (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
-     (ess-indent-with-fancy-comments   . nil))
-
-    (RStudio-
-     (ess-indent-offset                . ,(default-value 'ess-indent-offset))
-     (ess-offset-arguments             . prev-line)
-     (ess-offset-arguments-newline     . prev-line)
-     (ess-offset-block                 . ,(default-value 'ess-offset-block))
-     (ess-offset-continued             . ,(default-value 'ess-offset-continued))
-     (ess-align-nested-calls           . nil)
-     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
-     (ess-align-continuations-in-calls . nil)
-     (ess-align-blocks                 . nil)
-     (ess-indent-from-lhs              . (arguments))
-     (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
-     (ess-indent-with-fancy-comments   . nil))
-
-    (DEFAULT
-      (ess-indent-offset                . ,(default-value 'ess-indent-offset))
-      (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
-      (ess-offset-arguments-newline     . ,(default-value 'ess-offset-arguments-newline))
-      (ess-offset-block                 . ,(default-value 'ess-offset-block))
-      (ess-offset-continued             . ,(default-value 'ess-offset-continued))
-      (ess-align-nested-calls           . ,(default-value 'ess-align-nested-calls))
-      (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
-      (ess-align-continuations-in-calls . ,(default-value 'ess-align-continuations-in-calls))
-      (ess-align-blocks                 . ,(default-value 'ess-align-blocks))
-      (ess-indent-from-lhs              . ,(default-value 'ess-indent-from-lhs))
-      (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
-      (ess-indent-with-fancy-comments   . ,(default-value 'ess-indent-with-fancy-comments))))
-
-  "Predefined formatting styles for ESS code.
-Use `ess-set-style' to apply a style in all R buffers. The values of
-all styles except OWN are fixed. To change the value of variables
-in the OWN group, customize the variable `ess-own-style-list'.
-DEFAULT style picks default (aka global) values from ESS
-indentation variables. In addition, ESS provides many indentation
-styles, the most important being the RRR and the RStudio
-variants.
-
-RRR is the common R style that adheres closely to R internal
-standards. RRR+ is the same except it also aligns blocks in
-function calls with the opening delimiter, producing more
-indentation. The C++ style (named like this for historical
-reasons rather than any resemblance to existing C++ indentation
-schemes) is halfway between these two styles and indent block
-arguments from the start of the surrounding function's name.
-
-The RStudio style closely mimics the indentation of the RStudio
-editor. RStudio- is the same except it does not align arguments
-in function calls, which corresponds to the settings of some
-RStudio users.
-
-ESS indentation is fully specified by the following offsets and
-variables. See the documentation of these variables for examples.
-
-Offsets:
-
- - `ess-indent-offset': main offset inherited by other settings
-
- - `ess-offset-arguments': offset type for function and bracket
-   arguments
-
- - `ess-offset-arguments-newline': offset type of arguments
-   when ( or [ is followed by a new line.
-
- - `ess-offset-block': offset type for brace and anonymous
-   parenthesis blocks
-
- - `ess-offset-continued': offset type for continuation lines in
-   multiline statements
-
-
-Overrides (implies vertical alignment):
-
- - `ess-align-nested-calls': functions whose nested calls
-   should be aligned.
-
- - `ess-align-arguments-in-calls': calls where
-   `ess-offset-arguments' should be ignored
-
- - `ess-align-continuations-in-calls': whether to ignore
-   `ess-offset-continued' in calls.
-
- - `ess-align-blocks': whether to ignore `ess-offset-blocks' for
-   function declarations or control flow statements.
-
-
-Control variables:
-
- - `ess-indent-from-lhs': whether to indent arguments from
-   left-hand side of an assignment or parameter declaration.
-
- - `ess-indent-from-chain-start': whether to indent arguments from
-   the first of several consecutive calls.
-
- - `ess-indent-with-fancy-comments': whether to indent #, ## and
-   ### comments distinctly.")
-
-(defun ess-add-style (key entries)
-  "Add a new style to `ess-style-list'.
-The new style has KEY and ENTRIES. Remove any existing entry with
-the same KEY before adding the new one."
-  (setq ess-style-alist (assq-delete-all key ess-style-alist))
-  (add-to-list 'ess-style-alist (cons key entries)))
-
-(defcustom ess-own-style-list (cdr (assoc 'RRR ess-style-alist))
-  "Indentation variables for your own style.
-Set `ess-style' to \='OWN to use these values. To change
-these values, use the customize interface. See the documentation
-of each variable for its meaning."
-  :group 'ess-edit
-  :type 'alist
-  :initialize #'custom-initialize-set
-  :set (lambda (symbol value)
-         (set symbol value)
-         (ess-add-style 'OWN value)))
-
-;;;###autoload
-(put 'ess-style 'safe-local-variable #'symbolp)
-
-(define-obsolete-variable-alias 'ess-default-style 'ess-style "ESS 19.04")
-(defcustom ess-style 'RRR
-  "Current ESS indentation style, see `ess-style-alist' for more.
-See the variable `ess-style-alist' for how these groups (RRR,
-DEFAULT, GNU, BSD, ...) map onto different settings for
-variables. OWN style is defined in `ess-own-style-list' and you
-can customize it to your needs. DEFAULT style picks default (aka
-global) values from ESS indentation variables.
-
-Prefer `ess-set-style' to set the current style. This variable
-has an effect if set before a buffer is visited (e.g. in your
-Emacs initialization file) or as a file or directory local
-variable (see Info node `(Emacs) File Variables'."
-  :type '(choice (const OWN)
-                 (const GNU)
-                 (const BSD)
-                 (const C++)
-                 (const CLB)
-                 (const K&R)
-                 (const RRR)
-                 (const RRR+)
-                 (const RStudio)
-                 (const RStudio-)
-                 (const DEFAULT))
-  :group 'ess-edit
-  :safe #'symbolp)
-
-;;*;; Variables controlling behavior of dump files
-
-(defcustom ess-source-directory
-  (or (getenv "TMPDIR") (getenv "TMP") (getenv "TEMP") temporary-file-directory)
-  "Directory in which to place dump files.
-This can be a string (an absolute directory name ending in a slash) or
-a lambda expression of no arguments which will return a suitable string
-value.  The lambda expression is evaluated with the process buffer as the
-current buffer.
-
-This always dumps to a sub-directory (\".Src\") of the current ess
-working directory (i.e. first elt of search list)."
-  :group 'ess-edit
-  :type 'directory
-  :package-version '(ess . "25.01.1"))
-
-(defvar ess-dump-filename-template nil
-  "Internal. Initialized by dialects.")
-
-(defcustom ess-dump-filename-template-proto (concat (user-login-name) ".%s.S")
-  "Prototype template for filenames of dumped objects.
-The ending `S' is replaced by the current \\[ess-suffix], to give
-`ess-dump-filename-template' when an inferior ESS process starts.
-
-By default, gives filenames like `user.foofun.S', so as not to clash with
-other users if you are using a shared directory. Other alternatives:
-\"%s.S\" ; Don't bother uniquifying if using your own directory(ies)
-\"dumpdir\"; Always dump to a specific filename. This makes it impossible
-to edit more than one object at a time, though.
- (make-temp-name \"scr.\") ; Another way to uniquify"
-  ;; MM: The last 3-4 lines above suck (I don't understand them) -- FIXME --
-
-  :group 'ess-edit
-  :type 'string)
-
-(defcustom ess-pre-run-hook nil
-  "Hook to call before starting up ESS.
-Good for setting up your directory."
-  :group 'ess-hooks
-  :type 'hook)
-
-(defcustom ess-post-run-hook nil
-  "Hook to call just after the ESS process starts up.
-Currently this should not be used to interact with the inferior
-process because this hook runs too early, before the inferior
-mode had a chance to properly start up the process. To interact
-with the process, you must use a mode-specific hook like
-`ess-r-post-run-hook'."
-  :group 'ess-hooks
-  :type 'hook)
-
-(defcustom ess-send-input-hook nil
-  "Hook called just before line input is sent to the process."
-  :group 'ess-hooks
-  :type 'hook)
-
-;; ---- ./ess-roxy.el : ------------
-
-(defcustom ess-roxy-package "roxygen2"
-  "The name of the R package to use for Roxygen."
-  :group 'ess-roxy
-  :type 'string)
-
-(defcustom ess-roxy-tags-noparam '("export" "noRd")
-  "The tags used in roxygen fields that can be used alone.
-Used to decide highlighting and tag completion."
-  :group 'ess-roxy
-  :type '(repeat string))
-
-(defcustom ess-roxy-tags-param '("author" "aliases" "concept" "details"
-                                 "example" "examples" "examplesIf"
-                                 "format" "keywords"
-                                 "method" "exportMethod"
-                                 "name" "note" "param"
-                                 "include" "references" "return" "returns"
-                                 "seealso" "source" "docType"
-                                 "title" "TODO" "usage" "import"
-                                 "exportClass" "exportPattern"
-                                 "exportS3Method" "S3method"
-                                 "inherit" "inheritParams" "inheritSection"
-                                 "importFrom" "importClassesFrom"
-                                 "importMethodsFrom" "useDynLib"
-                                 "rawNamespace"
-                                 "rdname" "section" "slot" "description"
-                                 "md" "eval" "evalNamespace" "family")
-  "The tags used in roxygen fields that require a parameter.
-Used to decide highlighting and tag completion."
-  :group 'ess-roxy
-  :type '(repeat string))
-
-(defcustom ess-roxy-template-alist
-  (list (cons "description"  ".. content for \\description{} (no empty lines) ..")
-        (cons "details" ".. content for \\details{} ..")
-        (cons "title" "")
-        (cons "param"  "")
-        (cons "return" "")
-        (cons "author" ess-user-full-name))
-  "The tags and defaults to insert when creating empty templates.
-Param is a place holder for where to enter
-parameters. Description and details do not use @ tags, but are
-instead placed at the beginning of the entry (and should
-therefore also be at the beginning of this template to give
-syntactically correct roxygen entries)"
-  :group 'ess-roxy
-  :type '(alist :key-type string :value-type string))
-
-(defcustom ess-roxy-fill-param-p nil
-  "When non-nil `ess-roxy-update-entry' fills (wraps) parameters."
-  :group 'ess-roxy
-  :type '(choice (const :tag "Off" nil)
-                 (const :tag "On" t)))
-
-(defcustom ess-roxy-hide-show-p nil
-  "Non-nil means ess-roxy uses function `hs-minor-mode' for block hiding with TAB."
-  :group 'ess-roxy
-  :type '(choice (const :tag "Off" nil)
-                 (const :tag "On" t)))
-
-(defcustom ess-roxy-start-hidden-p nil
-  "Non-nil means all blocks should be hidden from start."
-  :group 'ess-roxy
-  :type '(choice (const :tag "Off" nil)
-                 (const :tag "On" t)))
-
-(defcustom ess-roxy-str "##'"
-  "Prefix string to insert before each line in new roxygen blocks.
-In existing roxygen blocks, the prefix is taken from the line at
-point"
-  :group 'ess-roxy
-  :type 'string)
-
-(defvar ess-roxy-insert-prefix-on-newline t
-  "When non-nil, `ess-roxy-newline' inserts the roxy prefix on newlines.")
-
-\f ; System variables
-
-;; SJE -- this should not be defcustom - user does not set it.
-(defvaralias 'ess-current-process-name 'ess-local-process-name)
-(defvar-local ess-local-process-name nil
-  "The name of the ESS process associated with the current buffer.")
-(put 'ess-local-process-name 'risky-local-variable t)
-(put 'ess-local-process-name 'permanent-local t)
-
-(defcustom ess-switch-to-end-of-proc-buffer t
-  "If non-nil, \\<ess-mode-map>\\[ess-switch-to-inferior-or-script-buffer] goes to the end of the process buffer."
-  :group 'ess
-  :type 'boolean)
-
-(defcustom ess-gen-proc-buffer-name-function 'ess-gen-proc-buffer-name:project-or-simple
-  "Function used for generation of the buffer name of the new ESS processes.
-It should accept one argument PROC-NAME, a string specifying
-internal process name (R, R:2, etc).
-
-Provided default options are:
-
-`ess-gen-proc-buffer-name:simple'
- *proc*
-
-`ess-gen-proc-buffer-name:directory'
-  *proc:dir*
-`ess-gen-proc-buffer-name:abbr-long-directory'
-  *proc:abbr-long-dir*
-`ess-gen-proc-buffer-name:project-or-simple'
-  *proc:project-root* or *proc*
-`ess-gen-proc-buffer-name:project-or-directory'
-  *proc:project-root* or *proc:dir*
-
-Strategies based on projects default to built-in strategies if
-there is no project root in the current directory."
-  :group 'ess
-  :type '(choice (const :tag "*proc*"     ess-gen-proc-buffer-name:simple)
-                 (const :tag "*proc:dir*" ess-gen-proc-buffer-name:directory)
-                 (const :tag "*proc:abbr-long-dir*" ess-gen-proc-buffer-name:abbr-long-directory)
-                 (const :tag "*proc:project-root* or *proc*"     ess-gen-proc-buffer-name:project-or-simple)
-                 (const :tag "*proc:project-root* or *proc:dir*" ess-gen-proc-buffer-name:project-or-directory)
-                 function)
-  :package-version '(ess . "25.01.1"))
-
-
-(defcustom ess-kermit-command "gkermit -T"
-  "Kermit command invoked by `ess-kermit-get' and `ess-kermit-send'."
-  :group 'ess
-  :type  'string)
-
-(defcustom ess-kermit-prefix "#"
-  "String files must begin with to use kermit file transfer."
-  :group 'ess
-  :type  'string)
-
-(defcustom ess-kermit-remote-directory "."
-  "Buffer local variable that designates remote directory of file."
-  :group 'ess
-  :type  'string)
-(make-variable-buffer-local 'ess-kermit-remote-directory)
-
-;;*;; Regular expressions
-
-(defcustom ess-dumped-missing-re
-  "\\(<-\nDumped\n\\'\\)\\|\\(<-\\(\\s \\|\n\\)*\\'\\)"
-  "Regex determines if dumped objects are replaced by `ess-function-template'.
-
-If a dumped object's buffer matches this re, then it is replaced
-by `ess-function-template'."
-  :group 'ess
-  :type 'regexp)
-
-(defcustom ess-dump-error-re
-  (if (string= ess-language "S") "\nDumped\n\\'"
-    "[Ee]rror")
-  "Regexp used to detect an error when loading a file."
-  :group 'ess
-  :type 'regexp)
-
-(defcustom ess-r-outline-regexp
-  "^[ \t]*#+ +.*\\(?:----\\|====\\|####\\)\\s-*$"
-  "Regexp used to detect the beginning of R headings."
-  :group 'ess-R
-  :type 'regexp)
-
-
-\f ; ess-inf: variables for inferior-ess.
-
-(defvar inferior-ess-own-frame nil
-  "Non-nil means that inferior ESS buffers should start in their own frame.
-This variable is deprecated.
-please add an entry to `display-buffer-alist' instead. See Info
-node `(ess)Customizing startup'. For example:
-
-\(add-to-list \\='display-buffer-alist
-             \\='(\"*R\"
-  (display-buffer-reuse-window display-buffer-pop-up-frame)))")
-(make-obsolete-variable 'inferior-ess-own-frame 'display-buffer-alist "ESS 19.04")
-(make-obsolete-variable 'inferior-ess-frame-alist "It is ignored. Use `display-buffer-alist' and `pop-up-frame-alist' instead." "ESS 19.04")
-(make-obsolete-variable 'inferior-ess-same-window 'display-buffer-alist "ESS 19.04")
-
-(defcustom inferior-ess-jit-lock-chunk-size 10000
-  "Default for (buffer local) `jit-lock-chunk-size' in inferior ESS buffers."
-  :group 'ess-proc
-  :type 'integer)
-
-
-(defvaralias 'inferior-R-program 'inferior-ess-r-program)
-(define-obsolete-variable-alias 'inferior-R-program-name
-  'inferior-ess-r-program "ESS 18.10")
-(define-obsolete-variable-alias 'inferior-ess-r-program-name
-  'inferior-ess-r-program "ESS 18.10")
-(defcustom inferior-ess-r-program (if ess-microsoft-p
-                                      "Rterm"
-                                    "R")
-  "Program name for invoking an inferior ESS with \\[R]."
-  :group 'ess-R
-  :type '(choice (string) file))
-
-(defcustom inferior-R-args ""
-  "String of arguments used when starting R.
-See also `ess-R-readline'."
-  :group 'ess-R
-  :type 'string)
-
-(defcustom ess-R-readline nil
-  "When non-nil, use readline in R.
-nil indicates that \"--no-readline \" should be used as argument
-when starting R. This may very slightly speedup interaction. On
-the other hand, readline is necessary for expansion of
-\"~username/\" in paths. Note that readline interprets
-tabs (tabular characters) in R source files as asking for file
-name completion. This can mess up evaluation completely."
-  :group 'ess-R
-  :type 'boolean)
-
-(defvaralias 'inferior-R-objects-command 'inferior-ess-r-objects-command)
-(defcustom inferior-ess-r-objects-command "print(objects(pos=%d, all.names=TRUE), max=1e6)\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)
-
-(defvar ess-getwd-command nil
-  "Command string retrieving the working directory from the process.")
-
-(defvar ess-setwd-command nil
-  "Command string to set working directory.
-Should contain a formatting %s to be replaced by a
-path (as in `setwd(%s)\\n'.")
-
-(defcustom ess-program-files ;; 32 bit version
-  (if (and ess-microsoft-p
-           (fboundp 'w32-short-file-name))
-      (if (getenv "ProgramW6432")
-          (w32-short-file-name (getenv "ProgramFiles(x86)"));; always 32 on 64 bit OS
-        (w32-short-file-name (getenv "ProgramFiles")))      ;; always 32 on 32 bit OS
-    nil)
-  "Name for 32-bit programs.
-
-Safe (no embedded blanks) 8.3 name for 32-bit programs that works
-across internationalization."
-  :group 'ess
-  :type '(choice (string) (const nil)))
-
-(defcustom ess-program-files-64 ;; 64 bit version
-  (when (and ess-microsoft-p (fboundp 'w32-short-file-name) (getenv "ProgramW6432"))
-    (w32-short-file-name (getenv "ProgramW6432")))
-  "Name for 64-bit programs.
-
-Safe (no embedded blanks) 8.3 name for 64-bit programs that works
-across internationalization."
-  :group 'ess
-  :type '(choice (string) (const nil)))
-
-(defcustom ess-directory-containing-R nil
-  "When non-nil, a directory containing R.
-nil means the search for all occurrences of R on the machine will
-use the default location of the R directory
- (inside \"c:/Program Files\" in English locale Windows systems).
-Non-nil values mean use the specified location as the
-directory in which \"R/\" is located.  For example, setting
-`ess-directory-containing-R' to \"c:\" will tell ESS to search
-for R versions with path names of the form \"c:/R/R-x.y.z\".
-
-Currently only used when `ess-microsoft-p'.  If you change the
-value of this variable, you need to restart Emacs for it to take
-effect.  It also needs to be set before you load ess-site as its
-value is used once only when ESS is loaded."
-  :group 'ess
-  :type '(choice (directory) (const nil)))
-
-(defcustom ess-rterm-version-paths nil
-  "Stores the full path file names of Rterm versions computed via \\[ess-find-rterm].
-If you have versions of R in locations other than in
-../../R-*/bin/Rterm.exe or ../../rw*/bin/Rterm.exe, relative to
-the directory in the variable `exec-path' containing your default
-location of Rterm, you will need to redefine this variable with a
-`custom-set-variables' statement in your site-start.el or .emacs
-file."
-  :group 'ess-R
-  :type '(repeat string))
-
-(define-obsolete-variable-alias 'inferior-S3-program-name
-  'inferior-S3-program "ESS 18.10")
-(defcustom inferior-S3-program "/disk05/s/S"
-  "Program name for invoking an inferior ESS with S3()."
-  :group 'ess-S
-  :type 'string)
-
-(define-obsolete-variable-alias
-  'inferior-S-elsewhere-program-name
-  'inferior-S-elsewhere-program "ESS 18.10")
-(defcustom inferior-S-elsewhere-program "sh"
-  "Program name to invoke an inferior ESS with S on a different computer."
-  :group 'ess-proc
-  :type 'string)
-
-(defvaralias 'S+6-dialect-name 'S+-dialect-name)
-(defcustom S+-dialect-name "S+"
-  "Name of `dialect' for S-PLUS 6.x and later.
-Easily changeable in a user's `.emacs'."
-  :group 'ess-SPLUS
-  :type 'string)
-
-(define-obsolete-variable-alias 'inferior-S+-program-name
-  'inferior-S+-program "ESS 18.10")
-(defcustom inferior-S+-program
-  (if ess-microsoft-p
-      (concat ess-program-files "/TIBCO/splus82/cmd/Splus.exe")
-    "Splus")
-  "Program name to invoke S+.
-On Unix/Linux, use the Splus executable.  On Windows, the default
-value is correct for a default installation of S-Plus 8.1 and
-with bash as the shell.  For any other version or location,
-change this value in ess-site.el or site-start.el.  Use the 8.3
-version of the path name.  Use double backslashes if you use the
-msdos shell."
-  :group 'ess-SPLUS
-  :type '(choice (string) (file)))
-
-(defvaralias 'inferior-S+6-start-args 'inferior-S+-start-args)
-(defvaralias 'inferior-Splus-args 'inferior-S+-start-args)
-(defcustom inferior-S+-start-args ""
-  "String of arguments used when starting S.
-These arguments are currently passed only to S+6 and higher."
-  :group 'ess-SPLUS
-  :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 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 \\[ess-quit].
-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)))
-
-(define-obsolete-variable-alias 'inferior-SAS-program-name
-  'inferior-SAS-program "ESS 18.10")
-(defcustom inferior-SAS-program "sas"
-  "Program name for invoking an inferior ESS with SAS()."
-  :group 'ess-sas
-  :type '(choice (string) (file)))
-
-(defvaralias 'R-editor 'ess-r-editor)
-(defcustom ess-r-editor "emacsclient"
-  "Editor called by R process with `edit()' command."
-  :group 'ess
-  :type 'string)
-
-(defvaralias 'R-pager 'ess-r-pager)
-(defcustom ess-r-pager 'nil ; Usually nil is correct as ESS and page() cooperate.
-  "Pager called by R process with `page()' command."
-  :group 'ess
-  :type '(choice (const nil) string))
-
-(defcustom S-editor "emacsclient"
-  "Editor called by S process with `edit()' command."
-  :group 'ess
-  :type 'string)
-
-(defcustom S-pager
-  (if ess-microsoft-p "emacsclientw.exe" "emacsclient")
-  "Pager called by S process with `page()' command."
-  :group 'ess
-  :type 'string)
-
-(defvar-local ess-editor nil
-  "Editor command.
-
-Editor by which the process sends information to an Emacs buffer
-for editing and then to be returned to the process.")
-
-(defvar-local ess-pager nil
-  "Pager by which the process sends information to an Emacs buffer.")
-
-(defvar-local inferior-ess-language-start nil
-  "Initialization commands sent to the ESS process.")
-
-(define-obsolete-variable-alias 'inferior-ess-program-name
-  'inferior-ess-program "ESS 18.10")
-(defvar-local inferior-ess-program nil
-  "Default program name for invoking `inferior-ess'.
-The other variables ...-program should be changed, for the
-corresponding program.")
-
-(make-obsolete-variable 'inferior-ess-start-args
-                        "Use the language specific variables like `inferior-R-args'"
-                        "ESS 19.04")
-(defvar inferior-ess-start-args ""
-  "String of arguments passed to the ESS process.
-If you wish to pass arguments to a process, see e.g. `inferior-R-args'.")
-
-(defcustom inferior-ess-pager (if ess-microsoft-p "console" "cat")
-  "Pager to use for reporting help files and similar things."
-  :group 'ess-proc
-  :type 'string)
-
-(defvar-local inferior-ess-primary-prompt "> "
-  "Regular expression used by `ess-mode' to detect the primary prompt.")
-
-(defvar-local inferior-ess-secondary-prompt nil
-  "Regular expression used by `ess-mode' to detect the secondary prompt.
-This is issued by S to continue an incomplete expression.
-Set to nil if language doesn't support secondary prompt.")
-
-(defvar ess-traceback-command nil
-  "Command to generate error traceback.")
-
-;; Need this to recognize prompts of the form  + + + > > >
-;; and "+ . + ", but not "Abcd. "
-(defvar inferior-S-prompt "[]a-zA-Z0-9.[]*[+ ]*> \\(?:[>+.] \\)*"
-  "Regexp used in S and R inferior and transcript buffers for prompt navigation.
-Must not be anchored to BOL.")
-
-;;*;; Variables controlling interaction with the ESS process
-
-(defcustom ess-execute-in-process-buffer nil
-  "Non-nil means the ess-execute- commands output to the process buffer.
-Otherwise, they get their own temporary buffer."
-  :group 'ess-proc
-  :type 'boolean)
-
-(defcustom ess-eval-empty nil
-  "Non-nil means `ess-eval-line*' will send empty lines to the ESS process."
-  :group 'ess-proc
-  :type 'boolean)
-
-(defvaralias 'ess-eval-visibly-p 'ess-eval-visibly)
-
-(defcustom ess-eval-visibly 'nowait
-  "Non-nil means ess-eval- commands display commands in the process buffer.
-If \\='nowait, ESS shows input commands in the process buffer, but
-doesn't wait for the process. Thus all the output is printed
-after the input lines.
-
-If t, ESS waits after each line of the command for the process
-output. This results in a nice sequence of input and output but
-stalls Emacs on long output (like Sys.sleep(5) in R).
-
-If nil, ESS doesn't print input commands and doesn't wait for the
-process.
-
-This variable also affect the evaluation of input code in
-iESS. The effect is similar to the above. If t then ess waits for
-the process output, otherwise not."
-  :group 'ess-proc
-  :package-version '(ess . "25.01.1")
-  :type '(choice (const t) (const nowait) (const nil)))
-
-(defcustom ess-eval-deactivate-mark (fboundp 'deactivate-mark); was nil till 2010-03-22
-  "Non-nil means that after ess-eval- commands the mark is deactivated."
-  :group 'ess-proc
-  :type 'boolean)
-
-(defcustom ess-use-R-completion t
-  "Non-nil means use R-builtin completion mechanism when available."
-  :group 'ess-proc
-  :type 'boolean)
-
-(defcustom ess-sleep-for-shell (if ess-microsoft-p 5 1)
-  "Pause before sending output to the shell."
-  :group 'ess-proc
-  :type  'number)
-
-\f ; System variables
-;; VS[06-04-2016]: fixme: move all inf vars into ess-inf.el.
-
-;;*;; Variables relating to multiple processes
-
-(defvar-local ess--mode-line-process-indicator '("" ess-local-process-name)
-  "List of ESS mode-line indicators.
-Local in process buffers and must start with a string. Changes of
-this variable are automatically reflected in mode-lines of the
-process and all associated with it buffers.
-
-Each symbol must evaluate to one of the standard mode line
-objects. See info node `(elisp)Mode Line Data').  Add a symbol
-with `add-to-list' and remove with `delq'. Note that the symbols
-which are part of this list should better have
-\\='risky-local-variable property set to t, otherwise the text
-properties are not displayed.
-
-External utilities such as `ess-tracebug' and `ess-developer'
-customize this variable to indicate changes in the process
-status.")
-(put 'ess--mode-line-process-indicator 'risky-local-variable t)
-
-(defvar-local ess--local-mode-line-process-indicator '("")
-  "List of local process indicators.
-See `ess--mode-line-process-indicator' for how to set it.
-
-This is an internal variable used by tools like `ess-developer'
-and `ess-tracebug'.")
-(put 'ess--local-mode-line-process-indicator 'risky-local-variable t)
-
-;;*;; Inferior ESS commands
-
-(defvar-local ess-load-command "source('%s')\n"
-  "Dialect specific format-string for building the ess command to load a file.
-
-This format string should use %s to substitute a file name and should
-result in an ESS expression that will command the inferior ESS to load
-that file.")
-
-(defvar-local ess-eval-command nil
-  "Dialect specific format-string for building the command to evaluate a string.
-
-It is usually faster to send a string to remote processes than a
-file.  The latter involves Tramp and can be quite slow.  When
-possible, a dialect should implement that command and use it
-preferentially.
-
-This format string should use %s as a placeholder for the string
-to be evaluated and, optionally, %f for the file name to be
-reported in the error references.
-
-The resulting command should not echo code or print any
-transitory output.  See also `ess-eval-visibly-command' and
-`ess-eval-visibly-noecho-command'.")
-
-(defvar-local ess-build-eval-message-function nil
-  "Dialect-specific function for formatting an evaluation message.")
-
-(defcustom inferior-ess-dump-command "dump(\"%s\",file=\"%s\")\n"
-  "Format-string for building the ess command to dump an object into a file.
-Use first %s to substitute an object name.
-Use second %s to substitute the dump file name."
-  :group 'ess-command
-  :type 'string)
-
-(defvar-local inferior-ess-help-command "help(\"%s\")\n"
-  "Format-string for building the ESS command to ask for help on an object.
-This format string should use %s to substitute an object name.")
-
-(defcustom inferior-ess-r-help-command ".ess.help('%s')\n"
-  "Format-string for building the R command to ask for help on an object.
-This format string should use %s to substitute an object name.
-If set, changes will take effect when next R session is started."
-  :group 'ess-command
-  :type 'string)
-
-(defvar-local inferior-ess-exit-command "q()\n"
-  "Format-string for building the ess command to exit.
-This format string should use %s to substitute an object name.")
-
-(defvar-local 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")
-
-(defcustom inferior-ess-safe-names-command
-  "tryCatch(base::print(base::names(%s), max=1e6), error=function(e){})\n"
-  "Format string for ESS command to extract names from an object *safely*.
-
-%s is replaced by an \"object name\" -- usually a list or data
-frame, but in R also e.g., `package:stats'."
-  :group 'ess-command
-  :type 'string)
-
-;;*;; Regular expressions
-(defvar-local inferior-ess-prompt nil
-  "The regular expression  used for recognizing prompts.
-
-It is always used in transcript mode.  In inferior ess mode it is
-used only if `comint-use-prompt-regexp' is t.
-
-If not set in language's customize-alist it is constructed at run time
-from `inferior-ess-primary-prompt' and `inferior-ess-secondary-prompt'.")
-
-
-(defvar-local ess-change-sp-regexp ""
-  "The regexp for matching the S/R/.. commands that change the search path.")
-
-(defvar ess-S+-change-sp-regexp
-  "\\(attach(\\([^)]\\|$\\)\\|detach(\\|collection(\\|library(\\|module(\\|source(\\)"
-  "The regexp for matching the S-plus commands that change the search path.")
-
-(defvaralias 'ess-R-change-sp-regexp 'ess-r-change-sp-regexp)
-(defvar ess-r-change-sp-regexp
-  "\\(attach(\\([^)]\\|$\\)\\|detach(\\|library(\\|require(\\|source(\\)"
-  "The regexp for matching the R commands that change the search path.")
-
-;;*;; Process-dependent variables
-
-(defvar-local ess-sl-modtime-alist nil
-  "Alist of modification times for all ess directories accessed this session.")
-
-(defvar-local ess-prev-load-dir/file nil
-  "Cached value for `ess-load-file'.
-
-This symbol saves the (directory . file) pair used in the last
-`ess-load-file' command.  Used for determining the default in the next one.")
-
-(defvar-local ess-object-list nil
-  ;; This is a list of the currently known object names.  It is
-  ;; current only for one command entry; it exists under the
-  ;; assumption that the list of objects doesn't change while entering
-  ;; a command.
-  "Cache of object names.")
-
-(defvar-local ess-help-topics-list nil
-  ;; List of currently known help topics.
-  "Cache of help topics.")
-
-;;*;; Miscellaneous system variables
-
-;; 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.")
-
-(defvar-local ess-object-name-db nil
-  "Alist of lists of object names, with directory names as keys.
-The file ess-namedb.el is loaded (if it exists) to define this variable.
-See also function `ess-create-object-name-db'.")
-
-;;;*;;; Font-lock support
-
-;; "Reserved Words" -- part 1 --
-(defvar ess-RS-constants
-  '("TRUE" "FALSE" "NA" "NULL" "Inf" "NaN"))
-(defvar ess-R-constants
-  (append ess-RS-constants
-          '("NA_integer_" "NA_real_" "NA_complex_" "NA_character_")))
-(defvar ess-S-constants
-  (append ess-RS-constants
-          '("T" "F")))
-
-(defvar ess-R-keywords
-  '("if" "else" "repeat" "while" "function" "for" "in" "next" "break"
-    "switch" "function" "return" "on.exit" "stop" ".Defunct" "tryCatch"
-    "withRestarts" "invokeRestart"
-    "recover" "browser")
-  "Reserved words or special functions in the R language.")
-
-(defvar ess-r--keystrings
-  '("\\" "\?")
-  "Reserved non-word strings or special functions whose names
-include special characters in the R language.
-
-Similar font-locking usage as `ess-R-keywords', but dedicated to
-strings that should not be treated as `words’ by `regexp-opt' in
-`ess-r--find-fl-keyword'.")
-
-(defvar ess-S-keywords
-  (append ess-R-keywords '("terminate")))
-
-;; only some of these keywords "look like functions but are not":
-(defvar ess-S-non-functions
-  '("if" "for" "function" "while"))
-
-;; first the common ones
-(define-obsolete-variable-alias 'ess-S-modifyiers 'ess-S-modifiers "18.10")
-(defvar ess-S-modifiers
-  '("library" "attach" "detach" "source" "module"
-    "message" "warning"))
-
-(define-obsolete-variable-alias 'ess-R-modifyiers 'ess-R-modifiers "18.10")
-(defvar ess-R-modifiers
-  '("library" "attach" "detach" "source" "require"
-    "setwd" "options" "par" "load" "rm"
-    "message" "warning"  ".Deprecated"
-    "signalCondition" "withCallingHandlers"))
-
-(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-R-assign-ops
-  ;; don't want "=" here which is not only for assign
-  '("<<-" "<-" "->" "->>"))
-(defvar ess-S-assign-ops ess-R-assign-ops)
-
-(defvar ess-R-function-name-regexp
-  (concat "\\("      "\\sw+" "\\)"
-          "[ \t]*"   "\\(<-\\)"
-          "[ \t\n]*" "\\(function\\b\\|\\(\\\\[ \t\n(]+\\)\\)"))
-;; "[ \t\n(]+" after "\\\\" since cannot use "\\b" to bound a non-word
-
-(defvar ess-S-function-name-regexp
-  ess-R-function-name-regexp)
-
-(defvar ess-font-lock-keywords nil
-  "A name of the dialect specific font-lock keywords in the current buffer.
-See `ess-R-font-lock-keywords' for an example. This is an
-internal variable.")
-
-(defvar ess-fl-keyword:fun-calls
-  (cons "\\(\\sw+\\)[\t ]*(" '(1 ess-function-call-face keep))
-  "Font lock for function calls.")
-
-(defvar ess-fl-keyword:numbers
-  (cons "\\b\\.?[0-9]+[.eEL]?[0-9]*\\b" 'ess-numbers-face)
-  "Font lock for numbers.")
-
-(defvar ess-fl-keyword:delimiters
-  (cons "\\s(\\|\\s)" 'ess-paren-face)
-  "Font lock for parenthesis.")
-
-(defvar ess-fl-keyword:=
-  (cons "=" 'ess-paren-face)
-  "Font lock for equal sign (=).")
-
-(defvar ess-fl-keyword:operators
-  (cons "[-=+*></|&]+" 'ess-operator-face)
-  "Operators.")
-
-(defvar ess-S-fl-keyword:modifiers
-  (cons (regexp-opt ess-S-modifiers 'words)
-        'ess-modifiers-face)     ; modify search list or source (i.e. directives)
-  "Font lock keyword R modifiers.")
-
-(defvar ess-S-fl-keyword:fun-defs
-  (cons ess-S-function-name-regexp
-        '(1 font-lock-function-name-face t))
-  "Font-lock function definitions keyword.")
-
-(defvar ess-S-fl-keyword:keywords
-  (cons (regexp-opt ess-S-keywords 'words) 'ess-keyword-face))
-
-(defvar ess-S-fl-keyword:assign-ops
-  (cons (regexp-opt ess-S-assign-ops) 'ess-assignment-face)
-  "Font-lock assign operators.")
-
-(defvar ess-S-fl-keyword:constants
-  (cons (regexp-opt ess-S-constants 'words) 'ess-constant-face)
-  "Font-lock constants keyword.")
-
-(defcustom ess-S-font-lock-keywords
-  '((ess-S-fl-keyword:modifiers . t)
-    (ess-S-fl-keyword:fun-defs  . t)
-    (ess-S-fl-keyword:keywords  . t)
-    (ess-S-fl-keyword:assign-ops . t)
-    (ess-S-fl-keyword:constants . t)
-    (ess-fl-keyword:fun-calls)
-    (ess-fl-keyword:numbers)
-    (ess-fl-keyword:operators)
-    (ess-fl-keyword:delimiters)
-    (ess-fl-keyword:=))
-  "An alist of available font-lock keywords for the S mode.
-The key of each cons cell is a name of the keyword. The value
-should be t or nil to indicate if the keyword is activated by
-default or not."
-  :group 'ess-S
-  :group 'ess-faces
-  :type '(repeat (cons symbol boolean)))
-
-(defvar ess-R-fl-keyword:modifiers
-  '(eval . (cons (concat "\\(" (regexp-opt ess-R-modifiers 'words) "\\)\\s-*(")
-                 '(1 ess-modifiers-face)))
-  "Font-lock keyword R modifiers.
-See `ess-R-modifiers' for the list of modifiers.")
-
-(defvar ess-R-fl-keyword:fun-defs
-  '(eval . (cons ess-R-function-name-regexp
-                 '(1 font-lock-function-name-face nil)))
-  "Font-lock keyword for function names in function definitions.
-When this keyword is on, function names on the left hand side of
-<- are highlighted with `font-lock-function-name-face'.")
-
-(defvar ess-R-fl-keyword:keywords
-  '(ess-r--find-fl-keyword . ess-keyword-face)
-  "Font lock keyword for `ess-R-keywords'.")
-
-(defvar ess-R-fl-keyword:assign-ops
-  '(eval . (cons (regexp-opt ess-R-assign-ops) 'ess-assignment-face))
-  "Font-lock assign operators.
-See `ess-R-assign-ops' for the ops.")
-
-(defvar ess-R-fl-keyword:constants
-  '(eval . (cons (regexp-opt ess-R-constants 'words) 'ess-constant-face))
-  "Font-lock constants keyword.
-See `ess-R-constants' for the list of constants.")
-
-(defvar ess-R-fl-keyword:F&T
-  '("\\b[FT]\\b" . ess-constant-face)
-  "Highlight T and F in addition to TRUE and FALSE in R.")
-
-(defvar ess-R-fl-keyword:%op% nil
-  "Highlight %op% operators.")
-
-(defcustom ess-R-font-lock-keywords
-  '((ess-R-fl-keyword:keywords   . t)
-    (ess-R-fl-keyword:constants  . t)
-    (ess-R-fl-keyword:modifiers  . t)
-    (ess-R-fl-keyword:fun-defs   . t)
-    (ess-R-fl-keyword:assign-ops . t)
-    (ess-R-fl-keyword:%op%       . t)
-    (ess-fl-keyword:fun-calls)
-    (ess-fl-keyword:numbers)
-    (ess-fl-keyword:operators)
-    (ess-fl-keyword:delimiters)
-    (ess-fl-keyword:=)
-    (ess-R-fl-keyword:F&T))
-  "An alist of available font-lock keywords for the R mode.
-The key of each cons cell is a name of the keyword. The value
-should be t or nil to indicate if the keyword is active or not."
-  :group 'ess-R
-  :group 'ess-faces
-  :type '(repeat (cons symbol boolean)))
-
-(defvar ess-S-fl-keyword:prompt
-  (cons (concat "^" inferior-S-prompt) 'comint-highlight-prompt)
-  "Highlight prompts missed by comint.")
-
-(defvar ess-fl-keyword:matrix-labels
-  ;; also matches subsetting
-  (cons "\\[,?[1-9][0-9]*,?\\]" 'ess-matrix-face)
-  "Matrix and vector numeric labels.")
-
-(defvar ess-R-fl-keyword:messages
-  (cons (regexp-opt ess-R-message-prefixes 'enc-paren)
-        'font-lock-warning-face)
-  "Inferior-ess problems or errors.")
-
-(defvaralias 'inferior-R-font-lock-keywords 'inferior-ess-r-font-lock-keywords)
-(defcustom inferior-ess-r-font-lock-keywords
-  '((ess-S-fl-keyword:prompt      . t)
-    (ess-R-fl-keyword:keywords    . t)
-    (ess-R-fl-keyword:constants   . t)
-    (ess-R-fl-keyword:modifiers   . t)
-    (ess-R-fl-keyword:messages    . t)
-    (ess-R-fl-keyword:fun-defs    . t)
-    (ess-R-fl-keyword:assign-ops  . t)
-    (ess-fl-keyword:matrix-labels . t)
-    (ess-fl-keyword:fun-calls)
-    (ess-fl-keyword:numbers)
-    (ess-fl-keyword:operators)
-    (ess-fl-keyword:delimiters)
-    (ess-fl-keyword:=)
-    (ess-R-fl-keyword:F&T))
-  "Font-lock patterns used in `inferior-ess-r-mode' buffers.
-The key of each cons cell is a name of the keyword.  The value
-should be t or nil to indicate if the keyword is active or not."
-  :group 'ess-R
-  :group 'ess-faces
-  :type '(repeat (cons symbol boolean)))
-
-(defvar ess-S-fl-keyword:messages
-  (cons (regexp-opt ess-S-message-prefixes 'enc-paren)
-        'font-lock-warning-face)
-  "Inferior-ess problems or errors.")
-
-(defcustom inferior-S-font-lock-keywords
-  '((ess-S-fl-keyword:prompt    . t)
-    (ess-S-fl-keyword:messages  . t)
-    (ess-S-fl-keyword:modifiers . t)
-    (ess-S-fl-keyword:fun-defs  . t)
-    (ess-S-fl-keyword:keywords  . t)
-    (ess-S-fl-keyword:assign-ops        . t)
-    (ess-S-fl-keyword:constants . t)
-    (ess-fl-keyword:fun-calls)
-    (ess-fl-keyword:numbers)
-    (ess-fl-keyword:operators)
-    (ess-fl-keyword:delimiters)
-    (ess-fl-keyword:=))
-  "Font-lock patterns used in inferior-S-mode buffers.
-The key of each cons cell is a name of the keyword.  The value
-should be t or nil to indicate if the keyword is active by
-default."
-  :group 'ess-S
-  :group 'ess-faces
-  :type '(repeat (cons symbol boolean)))
-
-\f
-;;;*;;; ess-help variables
-
-;; This will never need to be loaded independently of any of the other modules,
-;; but they can all call it so we may as well put it here.
-
-(defcustom ess-help-pop-to-buffer t
-  "If non-nil ess-help buffers are given focus during the display.
-If non-nil, `ess-display-help' uses `pop-to-buffer' to display
-help, otherwise it uses `display-buffer', which does not select
-the help window."
-  :group 'ess-help
-  :type 'boolean)
-
-(defcustom ess-help-own-frame nil
-  "Controls whether ESS help buffers should start in a different frame.
-
-Possible values are:
-   nil: Display help in current frame.
-  \\='one: All help buffers are shown in one dedicated frame.
-     t: Each help buffer gets its own frame.
-
-If this is non-nil,`ess-help-reuse-window' is ignored. The
-parameters of the own frame are stored in
-`ess-help-frame-alist'."
-  :group 'ess-help
-  :type '(choice (const :tag "Display in current frame" nil)
-                 (const :tag "Display in one frame" one)
-                 (const :tag "Always display in a new frame" t)))
-
-(defcustom ess-help-reuse-window t
-  "If t, ESS tries to display new help buffers in the existing help window.
-This variable is ignored if `ess-help-own-frame' is non-nil."
-  :type 'boolean
-  :group 'ess-help)
-
-(defcustom ess-help-frame-alist default-frame-alist
-  "Alist of frame parameters used to create help frames.
-This defaults to `default-frame-alist' and is used only when
-the variable `ess-help-own-frame' is non-nil."
-  :group 'ess-help
-  :type 'alist
-  :package-version '(ess . "25.01.1"))
-
-\f ; Faces
-;;;=====================================================
-
-(defconst comint-highlight-prompt 'comint-highlight-prompt)
-
-(defconst ess-function-call-face 'ess-function-call-face)
-(defface ess-function-call-face
-  '((default (:slant normal :inherit font-lock-function-name-face)))
-  "Font Lock face used to highlight function calls in ess buffers."
-  :group 'ess-faces)
-
-(defconst ess-numbers-face 'ess-numbers-face)
-(defface ess-numbers-face
-  '((default (:slant normal :inherit font-lock-type-face)))
-  "Font Lock face used to highlight numbers in `ess-mode' buffers."
-  :group 'ess-faces)
-
-(defconst ess-operator-face 'ess-operator-face)
-(defface ess-operator-face
-  '((default (:inherit font-lock-constant-face)))
-  "Font Lock face for operators."
-  :group 'ess-faces)
-
-(defconst ess-%op%-face 'ess-%op%-face)
-(defface ess-%op%-face
-  '((default (:inherit ess-operator-face)))
-  "Font Lock face used to highlight %op% operators in `ess-mode' buffers."
-  :group 'ess-faces)
-
-(defconst ess-assignment-face 'ess-assignment-face)
-(defface ess-assignment-face
-  '((default (:inherit font-lock-constant-face)))
-  "Font lock face used to highlight assignment operators."
-  :group 'ess-faces)
-
-(defconst ess-paren-face 'ess-paren-face)
-(defface ess-paren-face
-  '((default (:inherit font-lock-constant-face)))
-  "Font lock face used to highlight parentheses."
-  :group 'ess-faces)
-
-(defconst ess-operator-face 'ess-operator-face)
-(defface ess-operator-face
-  '((default (:inherit font-lock-constant-face)))
-  "Font lock face used to highlight operators."
-  :group 'ess-faces)
-
-(defconst ess-modifiers-face 'ess-modifiers-face)
-(defface ess-modifiers-face
-  '((default (:inherit font-lock-constant-face)))
-  "Font lock face used to highlight modifiers.
-In `R-mode', for example, this includes \"library,\" \"attach,\"
-and others. See `ess-R-modifiers'."
-  :group 'ess-faces)
-
-(defconst ess-constant-face 'ess-constant-face)
-(defface ess-constant-face
-  '((default (:inherit font-lock-type-face)))
-  "Font lock face used to highlight constants.
-In `ess-r-mode', for example, this includes TRUE, FALSE, Inf and
-others. See `ess-R-constants'."
-  :group 'ess-faces)
-
-(defconst ess-matrix-face 'ess-matrix-face)
-(defface ess-matrix-face
-  '((default (:inherit font-lock-constant-face)))
-  "Font lock face used to highlight row/column labels in matrices."
-  :group 'ess-faces)
-
-(defconst ess-keyword-face 'ess-keyword-face)
-(defface ess-keyword-face
-  '((default (:inherit font-lock-keyword-face)))
-  "Font lock face used to highlight reserved keywords.
-In `ess-r-mode', for example, this includes \"while,\" \"if/else\",
-\"function,\" and others. See `ess-R-keywords'."
-  :group 'ess-faces)
-
-(defconst ess-r-control-flow-keyword-face 'ess-r-control-flow-keyword-face)
-(defface ess-r-control-flow-keyword-face
-  '((default (:inherit ess-keyword-face)))
-  "Font lock face used to highlight control flow keywords.
-In `R-mode', for example, this includes \"switch(),\"
-\"tryCatch()\", and \"stop(),\". See
-`ess-R-control-flow-keywords'. By default, these keywords are
-highlighted with the same face as `ess-R-keywords'"
-  :group 'ess-faces)
-
-(defcustom ess-help-kill-bogus-buffers t
-  "Non-nil means kill ESS help buffers immediately if they are \"bogus\"."
-  :group 'ess-help
-  :type 'boolean)
-
-(defvar ess-execute-screen-options-command nil
-  "Dialect specific command run by `ess-execute-screen-options'.")
-
-(defvar-local ess-funargs-command  nil
-  "Dialect specific command to return a list of function arguments.
-See `ess-function-arguments' and .ess_funargs command in R and
-S+ for details of the format that should be returned.")
-
-\f ; System variables
-;;;=====================================================
-;;; Users note: You will rarely have to change these
-;;; variables.
-
-;;*;; Variables relating to ess-help-mode
-
-;;-- ess-help-S-.. and  ess-help-R-.. : in  ess-s-lang.el (are used in ess-inf).
-
-(defvar-local ess-help-sec-keys-alist nil
-  "Alist of (key . string) pairs for use in section searching.")
-
-(defvar-local ess-help-sec-regex nil
-  "Reg(ular) Ex(pression) of section headers in help file.")
-
-\f ; julia-mode
-(define-obsolete-variable-alias 'inferior-julia-program-name
-  'inferior-julia-program "ESS 18.10")
-(defcustom inferior-julia-program (or (executable-find "julia-basic")
-                                      "julia")
-  "Executable for Julia.
-Should be an absolute path to the julia executable."
-  :group 'ess-Julia
-  :type '(choice (string) (file)))
-
-;; FIXME
-(defvar-local ess-mode-completion-syntax-table nil "Completion and help syntax table for `ess-mode'.")
-
-\f ; Buffer local customization stuff
-
-(defcustom ess-error-buffer-name "*ESS-errors*"
-  "Name of buffer to keep process error messages in.
-Created for each process."
-  :group 'ess-proc
-  :type 'string)
-
-(defvar ess-error-regexp-alist nil
-  "List of symbols which are looked up in `compilation-error-regexp-alist-alist'.")
-
-(defcustom ess-write-to-dribble t
-  "Non-nil means write to `ess-dribble-buffer'.
-See also `ess-verbose'."
-  :group 'ess-proc
-  :type 'boolean
-  :package-version '(ess . "25.01.1"))
-
-(defcustom ess-verbose nil
-  "Non-nil means write more information to `ess-dribble-buffer' than usual."
-  :group 'ess-proc
-  :type 'boolean)
-
-(defvar ess-dribble-buffer "*ESS*"
-  "Buffer or name of buffer for printing debugging information.")
-
-(defvar-local ess-local-customize-alist nil
-  "Buffer local settings for proper behavior.
-Used to store the values for passing on to newly created buffers.")
-
-(defvar ess-mode-editing-alist nil
-  "Variable settings for `ess-mode'.")
-
-(defvar-local ess-transcript-minor-mode nil
-  "Non-nil if using `ess-transcript-mode' as a minor mode of some other mode.")
-
-(defvar-local ess-listing-minor-mode nil
-  "Non-nil if using `ess-listing-minor-mode'.")
-
-(defvar ess-STERM nil
-  "Placeholder for dialect-specific STERM.")
-
-(make-obsolete-variable 'ess-S-loop-timeout "It is ignored." "ESS 18.10")
-(make-obsolete-variable 'ess-mode-load-hook "It is ignored." "ESS 18.10")
-(make-obsolete-variable 'ess-speedbar-use-p "It is ignored." "ESS 18.10")
-(make-obsolete-variable 'ess-synchronize-evals "It is ignored." "ESS 18.10")
-(make-obsolete-variable 'ess-eval-visibly-at-end "It is ignored." "ESS 18.10")
-(make-obsolete-variable 'ess-font-lock-mode 'global-font-lock-mode "ESS 18.10")
-(provide 'ess-custom)
-
-;;; ess-custom.el ends here
diff --git a/elpa/ess-20251212.937/ess-gretl.el b/elpa/ess-20251212.937/ess-gretl.el
deleted file mode 100644 (file)
index 1d79b5d..0000000
+++ /dev/null
@@ -1,579 +0,0 @@
-;; ess-gretl.el --- ESS gretl mode and inferior interaction  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2012-2022 Free Software Foundation, Inc.
-;; Author: Ahmadou Dicko, Spinu Vitalie and Allin Cottrell
-;; Maintainer: ESS Core Team <ESS-coreNOSPAMr-project.org>
-;; Created: 01-10-2012 (ESS 12.09)
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-;;  start the inferior with M-x gretl.
-
-;;; Code:
-
-(require 'compile); for compilation-* below
-(require 'ess-r-mode)
-
-
-(add-to-list 'auto-mode-alist '("\\.inp\\'" . ess-gretl-mode))
-
-
-(defvar gretl-syntax-table
-  (let ((table (make-syntax-table)))
-    (modify-syntax-entry ?_ "w" table)   ; underscores in words
-    (modify-syntax-entry ?@ "w" table)
-    (modify-syntax-entry ?# "<" table)   ; #  single-line comment start
-    (modify-syntax-entry ?\n ">" table)  ; \n single-line comment end
-    (modify-syntax-entry ?\{ "(} " table)
-    (modify-syntax-entry ?\} "){ " table)
-    (modify-syntax-entry ?\[ "(] " table)
-    (modify-syntax-entry ?\] ")[ " table)
-    (modify-syntax-entry ?\( "() " table)
-    (modify-syntax-entry ?\) ")( " table)
-    (modify-syntax-entry ?\r " "  table)
-    (modify-syntax-entry ?+ "."   table)
-    (modify-syntax-entry ?- "."   table)
-    (modify-syntax-entry ?= "."   table)
-    (modify-syntax-entry ?* "."   table)
-    (modify-syntax-entry ?/ "."   table)
-    (modify-syntax-entry ?> "."   table)
-    (modify-syntax-entry ?< "."   table)
-    (modify-syntax-entry ?& "."   table)
-    (modify-syntax-entry ?| "."   table)
-    (modify-syntax-entry ?! "."   table)
-    (modify-syntax-entry ?\\ "\\" table)
-    (modify-syntax-entry ?\' "."  table)
-    (modify-syntax-entry ?\` "w"  table)
-    (modify-syntax-entry ?\" "\"" table)
-    (modify-syntax-entry ?. "w"   table)
-    (modify-syntax-entry ?_ "w"   table)
-    (modify-syntax-entry ?\% "."  table)
-    (modify-syntax-entry ?\# "<"  table)
-    (modify-syntax-entry ?\n ">"  table)
-    table)
-  "Syntax table for `ess-gretl-mode'.")
-
-;; syntax table that holds within strings
-(defvar ess-gretl-mode-string-syntax-table
-  (let ((table (make-syntax-table)))
-    table)
-  "Syntax table for `ess-gretl-mode' that holds within strings.")
-
-(defcustom gretl-continuation-offset 4
-  "Extra indentation applied to Gretl continuation lines."
-  :type 'integer
-  :group 'ess-gretl)
-
-(defvar gretl-continuation-regexp
-  "[^#%\n]*\\(\\\\\\|\\.\\.\\.\\)\\s-*\\(\\s<.*\\)?$")
-
-(defcustom gretl-continuation-string "\\"
-  "Character string used for Gretl continuation lines.  Normally \\."
-  :type 'string
-  :group 'ess-gretl)
-
-;; (defconst gretl-string-regex
-;;   "\"[^\"]*?\\(\\(\\\\\\\\\\)*\\\\\"[^\"]*?\\)*\"")
-
-(defconst gretl-function-header-regexp
-  (concat "^\\s-*\\<\\(function\\)\\>"
-         "\\([^=;\n]*=[ \t]*\\|[ \t]*\\)\\(\\w+\\)\\>")
-  "Regexp to match a Gretl function header.
-The string `function' and its name are given by the first and third
-parenthetical grouping.")
-
-;; (defconst ess-function-call-regexp
-;;   "\\s\"?\\(\\(\\sw\\|\\s_\\)+\\(<-\\)?\\)\\s\"?*\\s-*("
-;;   "Regexp for function names")
-
-(defvar gretl-command-words
-  '("add" "adf" "anova" "append" "ar" "ar1" "arbond" "arch"
-    "arima" "biprobit" "break" "boxplot" "chow" "clear" "coeffsum" "coint"
-    "coint2" "corr" "corrgm" "cusum" "data" "dataset" "delete" "diff"
-    "difftest" "discrete" "dpanel" "dummify" "duration" "elif" "else" "end"
-    "endif" "endloop" "eqnprint" "equation" "estimate" "fcast" "foreign" "fractint"
-    "freq" "function" "funcerr" "garch" "genr" "gmm" "gnuplot" "graphpg"
-    "hausman" "heckit" "help" "hsk" "hurst" "if" "include" "info"
-    "intreg" "kalman" "kpss" "labels" "lad" "lags" "ldiff" "leverage"
-    "levinlin" "logistic" "logit" "logs" "loop" "mahal" "makepkg" "meantest"
-    "mle" "modeltab" "modprint" "modtest" "mpols" "negbin" "nls" "normtest"
-    "nulldata" "ols" "omit" "open" "orthdev" "outfile" "panel" "pca"
-    "pergm" "textplot" "poisson" "print" "printf" "probit" "pvalue" "quantreg"
-    "qlrtest" "qqplot" "quit" "rename" "reset" "restrict" "rmplot" "run"
-    "runs" "scatters" "sdiff" "set" "setinfo" "setobs" "setmiss" "shell"
-    "smpl" "spearman" "sprintf" "square" "sscanf" "store" "summary" "system"
-    "tabprint" "tobit" "tsls" "var" "varlist" "vartest" "vecm" "vif"
-    "wls" "xcorrgm" "xtab" "debug" "return" "catch" "for" "foreach"
-    "while" "const" "3sls" "liml" "fiml"
-    "sur" "params" "deriv" "orthog" "weights" "series" "scalar")
-  "Commands in Gretl (these names are also reserved).")
-
-(defvar gretl-genr-functions
- '("abs" "sin" "cos" "tan" "asin" "acos" "atan" "sinh"
-   "cosh" "tanh" "asinh" "acosh" "atanh" "log" "ln" "log10"
-   "log2" "exp" "sqrt" "diff" "ldiff" "sdiff" "lags" "int"
-   "round" "ceil" "floor" "sort" "dsort" "sortby" "ranking" "orthdev"
-   "nobs" "firstobs" "lastobs" "uniform" "normal" "cum" "missing" "ok"
-   "misszero" "lrvar" "quantile" "median" "gini" "zeromiss" "sum" "mean"
-   "min" "max" "sd" "var" "sst" "cnorm" "dnorm" "qnorm"
-   "gammafun" "lngamma" "digamma" "resample" "pnobs" "pmin" "pmax" "pmean"
-   "psd" "hpfilt" "bkfilt" "bwfilt" "fracdiff" "boxcox" "cov" "corr"
-   "movavg" "I" "zeros" "ones" "seq" "replace" "muniform" "mnormal"
-   "sumc" "sumr" "meanc" "meanr" "sdc" "minc" "maxc" "minr"
-   "maxr" "iminc" "imaxc" "iminr" "imaxr" "fft" "ffti" "cmult"
-   "cdiv" "mcov" "mcorr" "mxtab" "cdemean" "cholesky" "psdroot" "inv"
-   "invpd" "ginv" "diag" "transp" "vec" "vech" "unvech" "upper"
-   "lower" "rows" "cols" "det" "ldet" "tr" "onenorm" "infnorm"
-   "rcond" "rank" "qform" "mlag" "qrdecomp" "eigensym" "eigengen" "nullspace"
-   "princomp" "mexp" "fdjac" "BFGSmax" "obsnum" "isseries" "isscalar" "islist"
-   "isstring" "isnull" "nelem" "pdf" "cdf" "invcdf" "pvalue" "critical"
-   "randgen" "urcpval" "values" "mshape" "svd" "mols" "mpols" "mrls"
-   "mread" "mwrite" "selifc" "selifr" "polroots" "dummify" "wmean" "wvar"
-   "wsd" "xpx" "filter" "kfilter" "ksmooth" "ksimul" "trimr" "getenv"
-   "argname" "obslabel" "readfile" "grab" "strstr" "strncmp" "strlen" "sscanf"
-   "varname" "varnum" "tolower" "colnames" "rownames" "ljungbox" "msortby" "lincomb"
-   "imhof" "toepsolv" "diagcat" "xmin" "xmax" "corrgm" "mcovg" "fcstats"
-   "bessel" "fraclag" "mreverse" "deseas" "pergm" "irr" "npv" "logistic"
-   "weekday" "kdensity" "monthlen" "epochday" "setnote" "invmills" "polyfit" "chowlin"
-   "varsimul" "strsplit" "inlist" "errmsg" "isconst" "irf" "inbundle")
-  "Builtin functions for Gretl's genr command.")
-
-
-(defvar gretl-option-flags
-  '("addstats" "all" "anova" "append"
-    "arch" "arma-init" "asymptotic" "auto"
-    "autocorr" "auxiliary" "balanced" "bartlett"
-    "between" "bootstrap" "both" "breusch-pagan"
-    "byobs" "by" "c" "close"
-    "coded" "cols" "column" "comfac"
-    "complete" "conditional" "contiguous" "continue"
-    "continuous" "control" "covariance" "cross"
-    "cross-section" "crt" "csv" "ct"
-    "ctt" "cubes-only" "dat" "database"
-    "dataset" "db" "degrees" "dhansen"
-    "difference" "diffuse" "discrete" "dpdstyle"
-    "drop-empty" "drop-first" "drop-last" "dummy"
-    "dynamic" "equal" "exit" "exponential"
-    "fcp" "fixed-effects" "from-file" "full"
-    "func" "gamma" "geomean" "gls"
-    "gmm" "gnu-R" "gnu-octave" "gph"
-    "gzipped" "hausman-reg" "hessian" "hilu"
-    "impulse-responses" "input" "inst" "integrate"
-    "intervals" "inverse-fit" "iterate" "jackknife"
-    "jbera" "jitter" "jmulti" "kendall"
-    "lags" "lagselect" "lbfgs" "lillie"
-    "liml" "linear-fit" "list" "loess-fit"
-    "log" "loglogistic" "lognormal" "logs"
-    "matrix" "matrix-diff" "medians" "ml"
-    "model1" "multi" "multinomial" "nc"
-    "next" "no-corc" "no-dates" "no-df-corr"
-    "no-gradient-check" "no-header" "no-missing" "no-scaling"
-    "no-stats" "normal" "normality" "notches"
-    "numerical" "odbc" "omit-obs" "one-scale"
-    "opg" "orthdev" "other" "out-of-sample"
-    "output" "overwrite" "p-values" "panel"
-    "panel-vars" "plot" "pooled" "preserve"
-    "print-final" "progress-bar" "progressive" "pwe"
-    "quadratic-fit" "quiet" "quit" "radians"
-    "random" "random-effects" "rank-sum" "raw"
-    "rc" "replace" "restrict" "restructure"
-    "reverse" "robust" "rolling" "row"
-    "rtf" "save" "save-all" "save-ehat"
-    "save-xbeta" "scalars" "seasonals" "send-data"
-    "sign" "signed-rank" "silent" "simple"
-    "simple-print" "single-yaxis" "skip-df" "spearman"
-    "special-time-series" "squares" "squares-only" "stacked-cross-section"
-    "stacked-time-series" "static" "stdresid" "suppress-fitted"
-    "swilk" "system" "t-ratios" "tall"
-    "test-down" "tex" "time-dummies" "time-series"
-    "to-file" "to_file" "traditional" "trend"
-    "two-step" "unequal-vars" "uniform" "unit-weights"
-    "variance-decomp" "vcv" "verbose" "wald"
-    "weibull" "weights" "white" "white-nocross"
-    "with-impulses" "with-lines" "write" "www"
-    "x-12-arima" "y-diff-only" "z-scores" "zeros")
-  "Gretl option flags.")
-
-(defvar gretl-internal-vars
- '("Fstat" "T" "ahat" "aic" "bic" "chisq" "coeff_ci"
-   "coeff" "compan" "datatype" "df" "dwpval" "ec" "ehat"
-   "error" "ess" "fcast" "fcerr" "gmmcrit" "hausman" "hqc"
-   "h" "jalpha" "jbeta" "jvbeta" "kalman_llt" "kalman_lnl" "kalman_s2"
-   "kalman_t" "kalman_uhat" "llt" "lnl" "mnlprobs" "ncoeff" "nobs"
-   "nscan" "nvars" "obs" "pd" "pvalue" "rho" "rlnl"
-   "rsq" "s00" "s01" "s11" "sample" "sargan" "sigma"
-   "stderr" "stopwatch" "sysA" "sysB" "sysGamma" "t1" "t2"
-   "test" "trsq" "uhat" "unit" "vcv" "version" "vma"
-   "windows" "xlist" "xtxinv" "yhat" )
-  "Model- and dataset-related variables.")
-
-(defconst gretl-block-start-keywords
-  (list "loop" "foreign" "function" "gmm" "if" "system" "mle" "nls" "restrict"))
-
-(defconst gretl-block-other-keywords
-  (list "else" "elif"))
-
-(defconst gretl-block-end-keywords
-  (list "end" "endif" "endloop"))
-
-(defvar gretl-keywords
-  (append gretl-block-start-keywords
-         gretl-block-other-keywords
-         gretl-block-end-keywords
-         '("break"))
-  "Reserved words in Gretl.")
-
-
-(defun gretl-at-keyword (kw-list)
-  ; not a keyword if used as a field name, X.word, or quoted, :word
-  (and (or (= (point) 1)
-          (and (not (equal (char-before (point)) ?.))
-               (not (equal (char-before (point)) ?:))))
-       (not (ess-inside-string-or-comment-p (point)))
-       (not (ess-inside-brackets-p (point)))
-       (member (current-word) kw-list)))
-
-
-(defconst gretl-font-lock-keywords
-  (list
-   ;; Fontify all builtin keywords.
-   (cons (concat "\\<\\(" (regexp-opt gretl-keywords) "\\)\\>")
-        'font-lock-keyword-face)
-   ;; Fontify all option flags.
-   (cons (concat "[ \t]--\\(" (regexp-opt gretl-option-flags) "\\)")
-        'font-lock-constant-face)
-   ;; Fontify all command words.
-   (cons (concat "\\<\\(" (regexp-opt gretl-command-words) "\\)\\>")
-        'font-lock-builtin-face)
-   ;; Fontify all builtin operators.
-   (cons "\\(&\\||\\|<=\\|>=\\|==\\|<\\|>\\|!=\\|!\\)"
-        (if (boundp 'font-lock-builtin-face)
-            'font-lock-builtin-face
-          'font-lock-preprocessor-face))
-   ;; Fontify all internal variables.
-   (cons (concat "\\$\\(" (regexp-opt gretl-internal-vars) "\\)\\>")
-        'font-lock-variable-name-face)
-
-   ;; Fontify all genr functions.
-   (cons (concat "\\<\\(" (regexp-opt gretl-genr-functions) "\\)\\>")
-        'font-lock-variable-name-face)
-   ;; Fontify all function declarations.
-   (list gretl-function-header-regexp
-        '(1 font-lock-keyword-face)
-        '(3 font-lock-function-name-face nil t)))
-  "Additional Gretl expressions to highlight.")
-
-
-(defvar gretl-block-begin-regexp
-  (concat "\\<\\(" (regexp-opt gretl-block-start-keywords) "\\)\\>"))
-
-(defvar gretl-block-else-regexp
-  (concat "\\<\\(" (regexp-opt gretl-block-other-keywords) "\\)\\>"))
-
-(defvar gretl-block-end-regexp
-  (concat "\\<\\(" (regexp-opt gretl-block-end-keywords) "\\)\\>"))
-
-(defvar gretl-block-begin-or-end-regexp
-  (concat gretl-block-begin-regexp "\\|" gretl-block-end-regexp))
-
-
-(defvar gretl-block-else-or-end-regexp
-  (concat gretl-block-else-regexp "\\|" gretl-block-end-regexp))
-
-(defvar gretl-basic-offset 4)
-
-(defvar gretl-block-match-alist
-  '(("loop" . ("endloop"))
-    ("if" . ("else" "elif" "endif"))
-    ("nls" . ("end"))
-    ("mle" . ("end"))
-    ("gmm" . ("end"))
-    ("foreign" . ("end"))
-    ("restrict" . ("end"))
-    ("kalman" . ("end"))
-    ("system" . ("end")))
-  "Alist with Gretl's matching block keywords.
-Has Gretl's begin keywords as keys and a list of the matching else or
-end keywords as associated values.")
-
-
-
-; get the position of the last open block
-(defun gretl-last-open-block-pos (min)
-  (let ((count 0))
-    (while (not (or (> count 0) (<= (point) min)))
-      (backward-word 1)
-      (setq count
-           (cond ((gretl-at-keyword gretl-block-start-keywords)
-                  (+ count 1))
-                 ((and (zerop (string-match "\\(?:e\\(?:l\\(?:if\\|se\\)\\|nd\\(?:if\\|loop\\)?\\)\\)" (current-word)))
-                       (not (ess-inside-comment-p)) (not (ess-inside-brackets-p)))
-                  (- count 1))
-                 (t count))))
-    (if (> count 0)
-       (point)
-      nil)))
-
-
-(defun gretl-last-open-block (min)
-  (let ((pos (gretl-last-open-block-pos min)))
-    (and pos
-        (progn
-          (goto-char pos)
-          (+ gretl-basic-offset (current-indentation))))))
-
-
-; return indent implied by a special form opening on the previous line, if any
-(defun gretl-form-indent ()
-  (forward-line -1)
-  (end-of-line)
-  (backward-sexp)
-  (if (gretl-at-keyword gretl-block-other-keywords)
-      (+ gretl-basic-offset (current-indentation))
-    (if (char-equal (char-after (point)) ?\()
-        (progn
-          (backward-word 1)
-          (let ((cur (current-indentation)))
-            (if (gretl-at-keyword gretl-block-start-keywords)
-                (+ gretl-basic-offset cur)
-              nil)))
-      nil)))
-
-
-(defun gretl-indent-line ()
-  "Indent current line of gretl code."
-  (interactive)
-  (end-of-line)
-  (indent-line-to
-   (or (and (ess-inside-string-p (line-beginning-position)) 0)
-       (save-excursion (ignore-errors (gretl-form-indent)))
-       (save-excursion
-         (let ((endtok (progn
-                         (beginning-of-line)
-                         (forward-to-indentation 0)
-                         (gretl-at-keyword gretl-block-end-keywords))))
-           (ignore-errors (+ (gretl-last-open-block (point-min))
-                             (if endtok (- gretl-basic-offset) 0)))))
-       ;; previous line ends in =
-       (save-excursion
-            (if (and (not (equal (point-min) (line-beginning-position)))
-                         (progn
-                           (forward-line -1)
-                           (end-of-line) (backward-char 1)
-                           (equal (char-after (point)) ?=)))
-                (+ gretl-basic-offset (current-indentation))
-              nil))
-       ;; take same indentation as previous line
-       (save-excursion (forward-line -1)
-                              (current-indentation))
-       0))
-  (when (gretl-at-keyword gretl-block-end-keywords)
-    (forward-word 1)))
-
-;; (defun gretl-send-string-function (process string visibly)
-;;   (let ((gretl-process (get-process "gretlcli")))
-;;     (process-send-string process (format ess-load-command file)))
-
-
-;; (defun gretl-send-string-function (process string visibly)
-;;   (let ((file (concat temporary-file-directory "gretl_eval_region.inp")))
-;;     (with-temp-file file
-;;       (insert string))
-;;     (process-send-string process (format ess-load-command file))))
-
-(defun gretl--get-words-from-command (command start-reg end-reg proc)
-  (with-current-buffer (ess-command command nil nil nil nil proc)
-    (goto-char (point-min))
-    (let ((beg (or (re-search-forward start-reg nil t)
-                   (point-min)))
-          (end (progn (goto-char (point-max))
-                      (or (re-search-backward end-reg)
-                          (point-max))))
-          acum)
-      (goto-char beg)
-      (skip-chars-forward "\n")
-      (while (re-search-forward "[^ \t\n]+" end t)
-        (push (match-string-no-properties 0) acum))
-      acum)))
-
-(cl-defmethod ess-help-get-topics (proc &context (ess-dialect "gretl"))
-  (delete-dups
-   (append gretl-command-words gretl-genr-functions
-           gretl-block-end-keywords gretl-block-other-keywords
-           gretl-block-start-keywords
-           (gretl--get-words-from-command "help\n" "are:" "^For" proc)
-           (gretl--get-words-from-command "help functions\n" "Accessors:" "^Functions" proc)
-           (gretl--get-words-from-command "help functions\n" "^Functions" "^For" proc)
-           )))
-
-;; (defvar ess-gretl-error-regexp-alist '(gretl-in gretl-at)
-;;   "List of symbols which are looked up in `compilation-error-regexp-alist-alist'.")
-
-;; (add-to-list 'compilation-error-regexp-alist-alist
-;;              '(gretl-in  "^\\s-*in [^ \t\n]* \\(at \\(.*\\):\\([0-9]+\\)\\)" 2 3 nil 2 1))
-;; (add-to-list 'compilation-error-regexp-alist-alist
-;;              '(gretl-at "^\\s-*\\(at \\(.*\\):\\([0-9]+\\)\\)"  2 3 nil 2 1))
-
-
-(defvar gretl-customize-alist
-  '((comint-use-prompt-regexp          . t)
-    (inferior-ess-primary-prompt       . "\\? ")
-    (inferior-ess-secondary-prompt     . "\\ ")
-    (inferior-ess-prompt               . "\\? ")
-    (ess-local-customize-alist         . gretl-customize-alist)
-    (inferior-ess-program              . "gretlcli")
-    (ess-load-command                  . "open \"%s\"\n")
-    ;; (ess-dump-error-re                      . "in \\w* at \\(.*\\):[0-9]+")
-    ;; (ess-error-regexp                       . "\\(^\\s-*at\\s-*\\(?3:.*\\):\\(?2:[0-9]+\\)\\)")
-    ;; (ess-error-regexp-alist         . ess-gretl-error-regexp-alist)
-    ;; (inferior-ess-objects-command   . inferior-gretl-objects-command)
-    ;; (inferior-ess-search-list-command       . "search()\n")
-    ;; inferior-ess-help-command               . gretl-help-command)
-    (inferior-ess-help-command         . "help %s\n")
-    (ess-language                      . "gretl")
-    (ess-dialect                       . "gretl")
-    (ess-suffix                                . "inp")
-    (ess-dump-filename-template                . (replace-regexp-in-string
-                                          "S$" ess-suffix ; in the one from custom:
-                                          ess-dump-filename-template-proto))
-    (ess-change-sp-regexp              . nil );ess-r-change-sp-regexp)
-    (ess-help-sec-regex                        . ess-help-r-sec-regex)
-    (ess-help-sec-keys-alist           . ess-help-r-sec-keys-alist)
-    (ess-function-pattern              . ess-r-function-pattern)
-    (ess-object-name-db-file           . "ess-r-namedb.el" )
-    ;; (ess-imenu-mode-function                . nil)
-    (ess-smart-operators               . ess-r-smart-operators)
-    (inferior-ess-exit-command         . "exit\n")
-    ;;harmful for shell-mode's C-a: -- but "necessary" for ESS-help?
-    (inferior-ess-language-start       . nil)
-    (ess-STERM         . "iESS")
-    )
-  "Variables to customize for Gretl -- set up later than Emacs initialization.")
-
-;; (defcustom inferior-gretl-program "gretlcli"
-;;   "*The program to use for running gretl scripts."
-;;   :type 'string
-;;   :group 'ess-gretl)
-
-;; (defvar ess-gretl-versions '("gretcli")
-;;   "List of partial strings for versions of Julia 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 Julia is made available.  ")
-
-(defcustom inferior-gretl-args ""
-  "String of arguments used when starting gretl."
-  :group 'ess-gretl
-  :type 'string)
-
-;;;###autoload
-(define-derived-mode ess-gretl-mode ess-mode "ESS[gretl]"
-  "Major mode for editing gretl source.  See `ess-mode' for more help."
-  ;;(setq imenu-generic-expression R-imenu-generic-expression)
-  (ess-setq-vars-local gretl-customize-alist)
-  (setq font-lock-defaults `(,gretl-font-lock-keywords))
-  (setq-local paragraph-start (concat "\\s-*$\\|" page-delimiter))
-  (setq-local paragraph-separate (concat "\\s-*$\\|" page-delimiter))
-  (setq-local paragraph-ignore-fill-prefix t)
-  (setq-local comment-start "# ")
-  (setq-local comment-add 1)
-  (setq-local comment-start-skip "\\s<+\\s-*")
-  (setq-local comment-column 40)
-  (setq-local indent-line-function #'gretl-indent-line)
-  (setq-local ess-local-customize-alist gretl-customize-alist)
-  (when (fboundp 'ess-add-toolbar) (ess-add-toolbar)))
-
-
-(defvar ess-gretl-post-run-hook nil
-  "Functions run in process buffer after Gretl starts.")
-
-;;;###autoload
-(defun gretl (&optional start-args)
-  "Call `gretl',
-Optional prefix (C-u) allows to set command line arguments, such as
---vsize.  This should be OS agnostic.
-If you have certain command line arguments that should always be passed
-to gretl, put them in the variable `inferior-gretl-args'."
-  (interactive "P")
-  ;; get settings, notably inferior-ess-r-program :
-  ;; (if (null inferior-gretl-program)
-  ;;     (error "'inferior-gretl-program' does not point to 'gretl-release-basic' executable")
-  (ess-write-to-dribble-buffer   ;; for debugging only
-   (format
-    "\n(Gretl): ess-dialect=%s, buf=%s"
-    ess-dialect (current-buffer)))
-  (let* ((r-start-args
-             (concat inferior-gretl-args " " ; add space just in case
-                         (if start-args
-                             (read-string
-                              (concat "Starting Args [other than `"
-                                          inferior-gretl-args
-                                          "'] ? "))
-                           nil)))
-         (inf-buf (inferior-ess r-start-args gretl-customize-alist)))
-    (setq-local indent-line-function #'gretl-indent-line)
-    (setq-local gretl-basic-offset 4)
-    (setq indent-tabs-mode nil)
-    (goto-char (point-max))
-    ;; (if inferior-ess-language-start
-    ;;         (ess-eval-linewise inferior-ess-language-start
-    ;;                            nil nil nil 'wait-prompt)))
-    (with-current-buffer inf-buf
-      (run-mode-hooks 'ess-gretl-post-run-hook))
-    inf-buf))
-
-
-;;;; IMENU
-
-;; (defvar gretl-imenu-generic-expression
-;;   '(("Function (_)" "^\\s-*function\\s-+\\(_[^ \t\n]*\\)" 1)
-;;     ("Function" "^\\s-*function\\s-+\\([^_][^ \t\n]*\\)" 1)
-;;     ("Const" "^\\s-*const \\([^ \t\n]*\\)" 1)
-;;     ("Type"  "^\\s-*\\w*type\\w* \\([^ \t\n]*\\)" 1)
-;;     ("Load"      " *\\(load\\)(\\([^ \t\n)]*\\)" 2)
-;;     ;; ("Classes" "^.*setClass(\\(.*\\)," 1)
-;;     ;; ("Coercions" "^.*setAs(\\([^,]+,[^,]*\\)," 1) ; show from and to
-;;     ;; ("Generics" "^.*setGeneric(\\([^,]*\\)," 1)
-;;     ;; ("Methods" "^.*set\\(Group\\|Replace\\)?Method(\"\\(.+\\)\"," 2)
-;;     ;; ;;[ ]*\\(signature=\\)?(\\(.*,?\\)*\\)," 1)
-;;     ;; ;;
-;;     ;; ;;("Other" "^\\(.+\\)\\s-*<-[ \t\n]*[^\\(function\\|read\\|.*data\.frame\\)]" 1)
-;;     ;; ("Package" "^.*\\(library\\|require\\)(\\(.*\\)," 2)
-;;     ;; ("Data" "^\\(.+\\)\\s-*<-[ \t\n]*\\(read\\|.*data\.frame\\).*(" 1)))
-;;     ))
-
-
-;; (defun ess-imenu-gretl (&optional arg)
-;;   "Gretl Language Imenu support for ESS."
-;;   (interactive)
-;;   (setq imenu-generic-expression gretl-imenu-generic-expression)
-;;   (imenu-add-to-menubar "Imenu-gretl"))
-
-
-;; (defun ess-imenu-gretl (&optional arg)
-;;   "Gretl Language Imenu support for ESS."
-;;   (interactive)
-;;   (setq imenu-generic-expression gretl-imenu-generic-expression)
-;;   (imenu-add-to-menubar "Imenu-jl"))
-
-
-(provide 'ess-gretl)
-
-;;; ess-gretl.el ends here
diff --git a/elpa/ess-20251212.937/ess-help.el b/elpa/ess-20251212.937/ess-help.el
deleted file mode 100644 (file)
index 7c99708..0000000
+++ /dev/null
@@ -1,864 +0,0 @@
-;;; ess-help.el --- Support for viewing ESS help files  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1989-2022 Free Software Foundation, Inc.
-
-;; Author: David Smith <dsmithNOSPAMstats.adelaide.edu.au>
-;; Created: 7 Jan 1994
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; Code for dealing with ESS help files.  See README.<LANGUAGE> where
-;; <LANGUAGE> is one of `S', `SAS', `Stata' or `XLispStat'.
-
-;;; Code:
-
-\f ; Requires and autoloads
-(require 'cl-lib)
-(eval-when-compile
-  (require 'tramp))
-(require 'info)
-(require 'ess-mode)
-(require 'ess-inf)
-(require 'ess-utils)
-(require 'ansi-color)
-
-(declare-function ess-r-help-mode "ess-r-mode")
-(declare-function ess-stata-help-mode "ess-stata-lang")
-
-
-(defcustom ess-help-mode-hook nil
-  "Functions to call when entering `ess-help-mode'."
-  :group 'ess-hooks
-  :type 'hook)
-
-(defvar ess--help-frame nil
-  "Stores the frame used for displaying R help buffers.")
-
-(defvar ess-help--aliases-timeout 10
-  "The large timeout is necessary for some users (#1025, #1081).")
-
-\f ; ess-help-mode
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;; In this section:
-;;;;
-;;;; * The function ess-display-help-on-object
-;;;; * The major mode ess-help-mode
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(cl-defgeneric ess--help-major-mode ()
-  "Determine which help major mode to call, and call it.
-Uses `ess-dialect' to determine the appropriate help mode."
-  (ess-help-mode))
-
-(defun ess--help-get-bogus-buffer-substring (buffer &optional nr-first)
-  "Return non-nil if BUFFER looks like a bogus ESS help buffer.
-Return the pair (match-beg. match-end) which can be used in error
-message. NR-FIRST is the number of characters at the start of the
-buffer to examine when deciding if the buffer if bogus. If nil,
-the first 150 characters of the buffer are searched."
-  (if (not nr-first) (setq nr-first 150))
-  (with-current-buffer buffer
-    (let ((PM (point-min))
-          (case-fold-search t)
-          searching res)
-      (setq res
-            (or  ;; evaluate up to first non-nil (or end):
-             (< (- (point-max) PM) 80); buffer less than 80 chars
-             (not (setq searching t))
-             ;; todo: move to customize-alist
-             (progn (goto-char PM) ;; R:
-                    (re-search-forward "Error in help"    nr-first t))
-             (progn (goto-char PM) ;; S-plus 5.1 :
-                    (re-search-forward "^cat: .*--"       nr-first t))
-             (progn (goto-char PM) ;; S version 3 ; R :
-                    (re-search-forward "no documentation .+" nr-first t))
-             (progn (goto-char PM) ;; stata
-                    (re-search-forward "^help .*not found" nr-first t))))
-      (ess-write-to-dribble-buffer
-       (format " |--> %s [searching %s]\n" res searching))
-      (when res
-        (if searching
-            (buffer-substring (match-beginning 0) (match-end 0))
-          (buffer-string))))))
-
-(defun ess-help-get-local-help-buffers ()
-  (ess-force-buffer-current)
-  (cl-remove-if-not
-   (lambda (buffer)
-     (let* ((pattern (concat "*help[" ess-current-process-name "]("))
-            (name (buffer-name buffer))
-            (candidate (when (> (length name) (length pattern))
-                         (substring name 0 (length pattern))) ))
-       (when (string= pattern candidate)
-         buffer)))
-   (buffer-list)))
-
-(defvar-local ess-help-type nil
-  "Type of help file, help, index, vignettes etc.
-Local in `ess-help' buffers.")
-
-(defvar-local ess-help-object nil
-  "Name of the object the help is displayed for.
-Is name of the package for package index.
-Local in `ess-help' buffers.")
-(put 'ess-help-object 'permanent-local t)
-
-(defun ess-display-help-on-object (object &optional command)
-  "Display documentation for OBJECT.
-If prefix ARG is given, force an update of the cached help topics
-and query the ESS process for the help file instead of reusing an
-existing buffer if it exists. Uses the variable
-`inferior-ess-help-command' for the actual help command. Prompts
-for the object name based on the cursor location for all cases
-except the S-Plus GUI. With S-Plus on Windows (both GUI and in an
-inferior Emacs buffer) the GUI help window is used. If COMMAND is
-supplied, it is used instead of `inferior-ess-help-command'."
-  (interactive
-   (progn
-     (ess-force-buffer-current)
-     (when current-prefix-arg
-       (ess-help--reset-cache))
-     (list (ess-find-help-file "Help on"))))
-  (let* ((hb-name (concat "*help[" ess-current-process-name "]("
-                          (replace-regexp-in-string "^\\?\\|`" "" object) ")*"))
-         (old-hb-p (get-buffer hb-name))
-         (tbuffer (get-buffer-create hb-name)))
-    (when (or (not old-hb-p)
-              (ess-process-get 'sp-for-help-changed?)
-              (ess--help-get-bogus-buffer-substring old-hb-p))
-      (ess-with-current-buffer tbuffer
-        (ess--flush-help-into-current-buffer object command)
-        (setq ess-help-object object)
-        (ess--help-major-mode)
-        (setq truncate-lines nil
-              ess-help-type 'help)))
-    (unless (ess--help-kill-bogus-buffer-maybe tbuffer)
-      (ess-display-help tbuffer))))
-
-(defun ess-help--reset-cache ()
-  "Reset all cached help files."
-  (ess-process-put 'sp-for-help-changed? t)
-  (ess-help--reset-cache-override))
-
-(cl-defgeneric ess-help--reset-cache-override ())
-
-(defun ess-help-revert-buffer (_ignore-auto _noconfirm)
-  "Revert the current help buffer.
-This reloads the documentation. IGNORE-AUTO and NOCONFIRM are
-ignored."
-  (ess-process-put 'sp-for-help-changed? t)
-  (ess-display-help-on-object ess-help-object))
-
-(defalias 'ess-help #'ess-display-help-on-object)
-
-(cl-defgeneric ess-build-help-command (object)
-  "Build a string command for retrieving help on OBJECT."
-  (format inferior-ess-help-command object))
-
-(defun ess--flush-help-into-current-buffer (object &optional command)
-  (let ((inhibit-modification-hooks t)
-        (inhibit-read-only t))
-    (delete-region (point-min) (point-max))
-    (let ((command (if (and command (string-match-p "%s" command))
-                       (format command object)
-                     command)))
-      (ess-command (or command (ess-build-help-command object))
-                   (current-buffer)))
-    (ess-help-underline)
-    (unless (string= ess-language "STA")
-      (ess-nuke-help-bs))
-    (goto-char (point-min))
-    (set-buffer-modified-p 'nil)))
-
-(defun ess--help-kill-bogus-buffer-maybe (buffer)
-  "Internal, try to kill bogus BUFFER with message. Return t if killed."
-  (when ess-help-kill-bogus-buffers
-    (let ((bog-mes  (ess--help-get-bogus-buffer-substring buffer)))
-      (when bog-mes
-        ;; The following is giving erroneous messages when help is displayed in the browser
-        ;; (when (< (length bog-mes) 10) ;;no message at all, how to treat this properly?
-        ;;   (setq bog-mes (format "No documentation found; %s" bog-mes)))
-        (ess-write-to-dribble-buffer
-         (format "(ess-help: kill bogus buffer %s ..\n" (buffer-name buffer)))
-        (message "%s" (replace-regexp-in-string  "\n" "" bog-mes))
-        ;; (ding) ;; don't ding, in julia a lot of doc strings are very short
-        (kill-buffer buffer)))))
-
-(defun ess-display-help-in-browser ()
-  "Displaying HTML help where available, using \\[browse-url]."
-  (interactive)
-  (unless (string-match "^R" ess-dialect)
-    (user-error "Sorry, not implemented for %s " ess-dialect))
-  (if (or (not ess-help-object)
-          (not (eq ess-help-type 'help)))
-      (message "No help topic found")
-    (ess-command (format "help('%s', help_type='html')\n" ess-help-object))))
-
-(defun ess--button-action (&optional button)
-  "Provide help on object at the beginning of line.
-It's intended to be used in R-index help pages. Load the package
-if necessary.  It is bound to RET and C-m in R-index pages."
-  (let* ((string (button-label button))
-         (command (ess-build-help-command string)))
-    (ess-display-help-on-object string command)))
-
-(cl-defgeneric ess-help-commands ()
-  "Return an alist of dialect specific retriever commands.
-Currently understood commands:
-- package-for-object - command to get the package of current
-  help object
-- packages - command to get a list of available
-  packages (REQUIRED)
-- package-index - command to get the package index (REQUIRED)
-- index-keyword-reg - regexp used to find keywords for linking in
-  index listing only (1st subexpression is used)
-- index-start-reg - regexp from where to start searching for
-   keywords in index listing"
-  (user-error "Not implemented for %s " ess-dialect))
-
-(cl-defmethod ess-help-commands (&context (ess-dialect "R"))
-  '((package-for-object . "sub('package:', '', .ess.findFUN('%s'))\n")
-    (packages           . ".packages(all.available=TRUE)\n")
-    (package-index      . ".ess.help(package='%s', help.type='text')\n")
-    (index-keyword-reg  . "^\\([^ \t\n:]+\\)")
-    (index-start-reg    . "^Index:")))
-
-(defun ess-display-package-index (&optional package)
-  "Prompt for package name and display its index."
-  (interactive
-   (list (let* ((coms (ess-help-commands))
-                (all-packs (ess-get-words-from-vector (cdr (assoc 'packages coms))))
-                (pack (or (when (and ess-help-object
-                                     (cdr (assoc 'package-for-object coms))
-                                     (eq ess-help-type 'help))
-                            (car (ess-get-words-from-vector
-                                  (format (cdr (assoc 'package-for-object coms))
-                                          ess-help-object))))
-                          (car (member (ess-read-object-name-default) all-packs)))))
-           (ess-completing-read "Index of" all-packs nil nil nil nil pack))))
-  (let ((coms (ess-help-commands)))
-    (ess--display-indexed-help-page
-     (format (cdr (assoc 'package-index coms)) package)
-     (cdr (assoc 'index-keyword-reg coms))
-     (format "*help[%s](index:%s)*"  ess-dialect package)
-     'index nil nil (cdr (assoc 'index-start-reg coms)) package)))
-
-(defun ess--display-indexed-help-page (command item-regexp title help-type
-                                               &optional action help-echo reg-start help-object)
-  "Internal function to display help pages with linked actions.
-COMMAND to produce the indexed help page,
-ITEM-REGEXP -- first subexpression is highlighted,
-TITLE of the help page,
-HELP-TYPE to be stored in `ess-help-type' local variable,
-ACTION is a function with no argument (default is `ess--button-action'),
-HELP-ECHO if given becomes the help-echo property of the button,
-REG-START gives the start location from where to search linkifying,
-          and HELP-OBJECT becomes `ess-help-object'."
-  (let ((inhibit-modification-hooks t)
-        (alist          ess-local-customize-alist)
-        (pname ess-local-process-name)
-        (buff (get-buffer-create title)))
-    (ess-with-current-buffer buff
-      (setq buffer-read-only nil)
-      (delete-region (point-min) (point-max))
-      (setq ess-local-process-name pname)
-      (ess--help-major-mode)
-      (ess-setq-vars-local (eval alist t))
-      (setq ess-help-object help-object
-            ess-help-sec-regex "\\(^\\s-.*\n\\)\\|\\(^\n\\)")
-      (ess--foreground-command command buff)
-      (ess-help-underline)
-      (set-buffer-modified-p 'nil)
-      (goto-char (point-min))
-      (when reg-start ;; go to the beginning of listing
-        (re-search-forward  reg-start  nil t))
-      (when item-regexp
-        ;;linkify the buffer
-        (save-excursion
-          (while (re-search-forward item-regexp nil t)
-            (make-text-button (match-beginning 1) (match-end 1)
-                              'mouse-face 'highlight
-                              'action (or action #'ess--button-action)
-                              'help-object (buffer-substring-no-properties (match-beginning 1) (match-end 1))
-                              'follow-link t
-                              'help-echo (or help-echo "help on object")))))
-      (save-excursion ;; why R help adds all these spaces?
-        (goto-char (point-min))
-        (when (re-search-forward "Index:\n\n" nil t)
-          (let ((beg (point)))
-            (forward-paragraph 1)
-            (align-regexp beg (point) "\\(\\s-+\\)"))))
-      (setq buffer-read-only t)
-      (setq ess-help-type help-type)
-      (setq truncate-lines nil))
-    (unless (ess--help-kill-bogus-buffer-maybe buff)
-      (ess-display-help buff))))
-
-(defun ess-display-help-apropos (&optional pattern)
-  "Create an ess-apropos buffer with a *linked* list of apropos topics."
-  (interactive "sPattern: ")
-  (let (com regexp)
-    (cond ((equal ess-dialect "R")
-           (setq com "help.search('%s')\n"
-                 regexp "^\\([^ \t\n:]+::[^ \t\n:]+\\)[ \t\n]+"))
-          ((equal ess-dialect "julia")
-           (setq com "apropos(\"%s\")\n"
-                 regexp "^\\(\\(\\w\\|\\s_\\)+\\)("))
-          ((equal ess-dialect "stata")
-           (setq com "hsearch %s\n"
-                 regexp "^[\t ]*[0-9]+\\.[\t ]+\\(.+\\)$"))
-          (t (error "Not implemented for dialect %s" ess-dialect)))
-    (ess--display-indexed-help-page
-     (format com pattern) regexp
-     (format "*ess-apropos[%s](%s)*" ess-current-process-name pattern)
-     'apropos)))
-
-(defun ess-display-demos ()
-  "Create an ess-demos buffer with a *linked* list of available demos."
-  (interactive)
-  (let (com regexp)
-    (cond ((equal ess-dialect "R")
-           (setq com "demo()\n"
-                 regexp "^\\([^ \n:]+\\)  +"))
-          (t (error "Not implemented for dialect %s" ess-dialect)))
-    (ess--display-indexed-help-page
-     com regexp
-     (format "*ess-demos[%s]*" ess-current-process-name)
-     'demos #'ess--action-demo)))
-
-(defun ess--action-demo (&optional button)
-  "Provide help on object at the beginning of line.
-It's intended to be used in R-index help pages. Load the package
-if necessary.  It is bound to RET and C-m in R-index pages."
-  (let* ((string (button-label button))
-         (command
-          (cond ((equal ess-dialect "R")
-                 (format "demo('%s')\n" string))
-                (t (error "Not implemented for dialect %s" ess-dialect)))))
-    (ess-eval-linewise command)
-    (ess-switch-to-end-of-ESS)))
-
-(defun ess-display-vignettes (&optional all)
-  "Display vignettes if available for the current dialect.
-With (prefix) ALL non-nil, use `vignette(*, all=TRUE)`, i.e., from all installed
- packages, which can be *very* slow."
-  (interactive "P")
-  (ess--display-vignettes-override all))
-
-(cl-defgeneric ess--display-vignettes-override (_all)
-  "Display vignettes for the current dialect.
-See `ess-display-vignettes' for ALL."
-  (user-error "Sorry, not implemented for %s" ess-dialect))
-
-(defun ess--action-open-in-emacs (pos)
-  (display-buffer (find-file-noselect (get-text-property pos 'help-echo))))
-(defun ess--action-R-open-vignette (pos)
-  (ess-eval-linewise (format "vignette('%s', package='%s')\n"
-                             (get-text-property pos 'vignette)
-                             (get-text-property pos 'package))))
-
-(defalias 'ess-help-quit #'quit-window)
-(make-obsolete 'ess-help-quit 'quit-window "16.04")
-
-(defun ess-display-help (buff)
-  "Display buffer BUFF.
-If `ess-help-pop-to-buffer' is non-nil, call `pop-to-buffer',
-otherwise call `display-buffer' to display the buffer.
-
-You may control how help buffers are displayed by EITHER setting
-an entry in `display-buffer-alist' (see examples in info
-node `(ess) Controlling buffer display') OR setting the
-ESS-specific variables `ess-help-own-frame',
-`ess-help-reuse-window', `ess-help-frame-alist', and
-`ess-display-buffer-reuse-frames'."
-  (let* ((action (cond (ess-help-own-frame
-                        '(display-buffer-reuse-window
-                          display-buffer-use-some-frame
-                          display-buffer-pop-up-frame))
-                       (ess-help-reuse-window
-                        '(display-buffer-reuse-window
-                          ess-display-buffer-reuse-mode-window
-                          display-buffer-pop-up-window
-                          display-buffer-use-some-window))
-                       (t '(display-buffer-pop-up-window
-                            display-buffer-use-some-window))))
-         (alist `((mode . (ess-help-mode ess-r-help-mode ess-stata-help-mode ess-julia-help-mode))
-                  (reusable-frames . ,ess-display-buffer-reuse-frames)
-                  ;; `display-buffer-use-some-frame' uses this to
-                  ;; determine whether to use the frame or not.
-                  (frame-predicate . (lambda (f)
-                                       (when (equal ess-help-own-frame 'one)
-                                         ;; Note we're always returning
-                                         ;; nil for `ess-help-own-frame' t.
-                                         (frame-parameter f 'ess-help-frame))))
-                  ;; If `display-buffer' makes a new frame, these are
-                  ;; given as frame parameters.
-                  (pop-up-frame-parameters . ,(append ess-help-frame-alist
-                                                      `((auto-hide-function . delete-frame)
-                                                        (ess-help-frame . ,(equal ess-help-own-frame 'one)))))))
-         (display-alist `(,action . ,alist)))
-    (if ess-help-pop-to-buffer
-        (pop-to-buffer buff display-alist)
-      (display-buffer buff display-alist))))
-
-(defun ess-help-web-search (cmd)
-  "Search the web for documentation on CMD."
-  (interactive "sSearch for: ")
-  (ess--help-web-search-override cmd))
-
-(cl-defgeneric ess--help-web-search-override (_cmd)
-  "Dialect-specific override for `ess-help-web-search', which see for CMD."
-  (error "Not implemented for %s" ess-dialect))
-
-(defun ess-manual-lookup ()
-  "Search manual for documentation."
-  (interactive)
-  (ess--manual-lookup-override))
-
-(cl-defgeneric ess--manual-lookup-override ()
-  "Dialect-specific override for `ess-manual-lookup'."
-  (error "Not implemented for %s" ess-dialect))
-
-(defvar ess-doc-map
-  (let (ess-doc-map)
-    (define-prefix-command 'ess-doc-map)
-    (define-key ess-doc-map "\C-e" #'ess-describe-object-at-point)
-    (define-key ess-doc-map "e" #'ess-describe-object-at-point)
-    (define-key ess-doc-map "\C-d" #'ess-display-help-on-object)
-    (define-key ess-doc-map "d" #'ess-display-help-on-object)
-    (define-key ess-doc-map "\C-i" #'ess-display-package-index)
-    (define-key ess-doc-map "i" #'ess-display-package-index)
-    (define-key ess-doc-map "\C-a" #'ess-display-help-apropos)
-    (define-key ess-doc-map "a" #'ess-display-help-apropos)
-    (define-key ess-doc-map "\C-v" #'ess-display-vignettes)
-    (define-key ess-doc-map "v" #'ess-display-vignettes)
-    (define-key ess-doc-map "\C-o" #'ess-display-demos)
-    (define-key ess-doc-map "o" #'ess-display-demos)
-    (define-key ess-doc-map "\C-w" #'ess-help-web-search)
-    (define-key ess-doc-map "w" #'ess-help-web-search)
-    (define-key ess-doc-map "\C-m" #'ess-manual-lookup)
-    (define-key ess-doc-map "m" #'ess-manual-lookup)
-    ess-doc-map)
-  "ESS documentation map.")
-
-
-(defvar ess-help-mode-map
-  (let ((map (make-keymap)))
-    (define-key map "\C-m" #'next-line)
-    (define-key map "h" #'ess-display-help-on-object)
-    (define-key map "w" #'ess-display-help-in-browser)
-    (define-key map "i" #'ess-display-package-index)
-    (define-key map "a" #'ess-display-help-apropos)
-    (define-key map "v" #'ess-display-vignettes)
-    (define-key map "l" #'ess-eval-line-visibly-and-step)
-    (define-key map "r" #'ess-eval-region-and-go)
-    (define-key map "f" #'ess-eval-function-or-paragraph-and-step)
-    (define-key map "n" #'ess-skip-to-next-section)
-    (define-key map "p" #'ess-skip-to-previous-section)
-    (define-key map "/" #'isearch-forward)
-    (define-key map "x" #'ess-kill-buffer-and-go)
-    (define-key map "k" #'kill-this-buffer)
-    (define-key map "\C-c\C-s" #'ess-switch-process)
-    (define-key map "\C-c\C-r" #'ess-eval-region)
-    (define-key map "\C-c\M-r" #'ess-eval-region-and-go)
-    (define-key map "\C-c\C-f" #'ess-eval-function)
-    (define-key map "\M-\C-x"  #'ess-eval-function)
-    (define-key map "\C-c\M-f" #'ess-eval-function-and-go)
-    (define-key map "\C-c\C-j" #'ess-eval-line)
-    (define-key map "\C-c\C-n" #'ess-eval-line-visibly-and-step)
-    (define-key map "\C-c\C-c"   #'ess-eval-region-or-function-or-paragraph-and-step)
-    (define-key map [(control return)] #'ess-eval-region-or-line-visibly-and-step)
-    (define-key map "\C-c\M-j" #'ess-eval-line-and-go)
-    (define-key map "\M-\C-a"  #'ess-goto-beginning-of-function-or-para)
-    (define-key map "\M-\C-e"  #'ess-goto-end-of-function-or-para)
-    (define-key map "\C-c\C-y" #'ess-switch-to-ESS)
-    (define-key map "\C-c\C-z" #'ess-switch-to-end-of-ESS)
-    (define-key map "\C-c\C-l" #'ess-load-file)
-    (define-key map "\C-c\M-l" #'ess-load-file); alias, as in #'iESS#' where C-c C-l is comint-list-*
-    (define-key map "\C-c\C-v" #'ess-display-help-on-object)
-    (define-key map "\C-c\C-k" #'ess-request-a-process)
-    (define-key map "\C-c\C-d"   'ess-doc-map)
-    (define-key map "\C-c\C-e"   'ess-extra-map)
-    (define-key map "\C-c\C-t"   'ess-dev-map)
-    map)
-  "Keymap for ESS help mode.")
-
-;; One reason for the following menu is to <TEACH> the user about key strokes
-(defvar ess-help-mode-menu
-  '("ESS-help"
-    ["Search forward"          isearch-forward t]
-    ["Next section"            ess-skip-to-next-section t]
-    ["Previous section"                ess-skip-to-previous-section t]
-    ["Help on section skipping"        ess-describe-sec-map t]
-    ["Beginning of buffer"     beginning-of-buffer t]
-    ["End of buffer"           end-of-buffer t]
-    "-"
-    ["Help on ..."             ess-display-help-on-object t]
-    ["Apropos of ..."          ess-display-help-apropos t]
-    ["Index of ..."            ess-display-package-index t]
-    ["Vignettes"               ess-display-vignettes t]
-    ["Open in browser"         ess-display-help-in-browser t]
-    "-"
-    ["Eval line"               ess-eval-line-and-step t]
-    ["Eval paragraph & step"   ess-eval-paragraph-and-step t]
-    ["Eval region & go"                ess-eval-region-and-go t]
-    ["Switch to ESS process"   ess-switch-to-ESS t]
-    ["Switch to end of ESS proc." ess-switch-to-end-of-ESS t]
-    ["Switch _the_ process"    ess-switch-process t]
-    "-"
-    ["Kill buffer"             kill-this-buffer t]
-    ["Kill buffer & go"                ess-kill-buffer-and-go t]
-    "-"
-    ["Handy commands"          ess-handy-commands t])
-  "Menu used in ess-help mode.")
-
-(easy-menu-define ess-help-mode-menu-map ess-help-mode-map
-  "Menu keymap for ess-help mode." ess-help-mode-menu)
-
-(define-derived-mode ess-help-mode special-mode "ESS Help"
-  "Mode for viewing ESS help files."
-  :group 'ess-help
-  ;; FIXME
-  ;; (if ess-mode-syntax-table ;;set in advance by ess-setq-local
-  ;;     (set-syntax-table ess-mode-syntax-table))
-  (setq-local revert-buffer-function #'ess-help-revert-buffer)
-  (setq show-trailing-whitespace nil))
-
-\f
-;;*;; User commands defined in ESS help mode
-
-(defun ess-skip-to-help-section ()
-  "Jump to a section heading of a help buffer.
-The section selected is determined by the command letter used to
-invoke the command, as indicated by `ess-help-sec-keys-alist'.
-Use \\[ess-describe-sec-map] to see which keystrokes find which
-sections."
-  (interactive)
-  (let ((old-point (point))
-        (case-fold-search nil)
-        (the-sec (cdr (assoc last-command-event ess-help-sec-keys-alist))))
-    (cl-assert the-sec nil (format "Invalid section key: %c" last-command-event))
-    (goto-char (point-min))
-    (if (re-search-forward (concat "^" the-sec) nil t)
-        (progn (recenter)
-               (beginning-of-line))
-      (message "No %s section in this help. Sorry." the-sec)
-      (goto-char old-point))))
-
-(defun ess-skip-to-next-section ()
-  "Jump to next section in ESS help buffer."
-  (interactive)
-  (let ((case-fold-search nil))
-    (when (looking-at-p ess-help-sec-regex)
-      (forward-line))
-    (if (re-search-forward ess-help-sec-regex nil 'no-error)
-        (beginning-of-line)
-      (message "No more sections."))))
-
-(defun ess-skip-to-previous-section ()
-  "Jump to previous section in ESS help buffer."
-  (interactive)
-  (let ((case-fold-search nil))
-    (if (re-search-backward ess-help-sec-regex nil 'no-error)
-        (beginning-of-line)
-      (message "No previous section."))))
-
-(defun ess-kill-buffer-and-go nil
-  "Kill the current buffer and switch back to the ESS process."
-  (interactive)
-  (kill-buffer (current-buffer))
-  (when (and ess-current-process-name (get-process ess-current-process-name))
-    (ess-switch-to-ESS nil)))
-
-(defun ess-describe-sec-map nil
-  "Display help for the `s' key."
-  (interactive)
-  (let ((keys-alist ess-help-sec-keys-alist))
-    (describe-function 'ess-skip-to-help-section)
-
-    (with-current-buffer "*Help*"
-      (setq buffer-read-only nil)
-      (goto-char (point-max))
-      (insert "\n\nCurrently defined keys are:
-
-Keystroke    Section
----------    -------\n")
-      (dolist (cs keys-alist)
-        (insert "    "
-                (car cs)
-                "      "
-                (cdr cs) "\n")))))
-
-(defun ess-helpobjs-at-point--read-obj ()
-  (let* ((obj (ess-read-object-name-default)))
-    ;; Exclude numbers
-    (unless (and obj (not (string-match "[[:alpha:]]" obj)))
-      obj)))
-
-(defun ess-unqualify-symbol (object)
-  (if (string-match "^[[:alnum:].]+::?" object)
-      (substring object (match-end 0))
-    object))
-
-(defun ess-helpobjs-at-point (slist)
-  "Return a list (def obj fun).
-Obj is a name at point, fun is the name of the function call
-point is in, and def is either obj or fun (in that order) which
-has a a help file, i.e. it is a member of SLIST (string-list).
-nil otherwise."
-  (let* ((obj (ess-helpobjs-at-point--read-obj))
-         (unqualified-obj (and obj (ess-unqualify-symbol obj)))
-         ;; FIXME: probably should use syntactic logic here
-         (fun (ignore-errors
-                (save-excursion
-                  (save-restriction
-                    (narrow-to-region (max (point-min) (- (point) 1000))
-                                      (point-max))
-                    (backward-up-list 1)
-                    (backward-char 1)
-                    (ess-read-object-name-default))))))
-    (list (or (car (member obj slist))
-              (when (member unqualified-obj slist)
-                obj)
-              (car (member fun slist)))
-          obj fun)))
-
-(cl-defgeneric ess-help-get-topics (proc)
-  "Return a list of help topics from PROC."
-  (user-error "Not supported for %s (process: %s)" ess-dialect proc))
-
-(defun ess-find-help-file (p-string)
-  "Find help, prompting for P-STRING."
-  (ess-make-buffer-current)
-  (let* ((help-files-list (ess-help-get-topics ess-current-process-name))
-         (hlpobjs (delq nil (ess-helpobjs-at-point help-files-list))))
-    (ess-completing-read p-string (append hlpobjs help-files-list)
-                         nil nil nil nil (car hlpobjs))))
-
-\f
-;;*;; Utility functions
-
-(defun ess-get-help-files-list ()
-  "Return a list of files which have help available."
-  (apply #'nconc
-         (mapcar (lambda (str)
-                   (let ((dirname (concat str "/.Help")))
-                     (and (file-directory-p dirname)
-                          (directory-files dirname))))
-                 (ess-search-list))))
-
-(defun ess-get-help-aliases-list ()
-  "Return a list of aliases which have help available."
-  (message "Retrieving RDS aliases...")
-  ;; ess-command locks display, make sure the above message is visible
-  (redisplay t)
-  (ess-write-to-dribble-buffer "Processing RDS files ...\n")
-  ;; FIXME: This should be run asynchronously
-  (prog1 (ess-get-words-from-vector ".ess.getHelpAliases()\n"
-                                    nil nil nil ess-help--aliases-timeout)
-    (message "Retrieving RDS aliases...done")))
-
-(defun ess-nuke-help-bs ()
-  "Remove ASCII underlining and overstriking performed by ^H codes."
-  ;; This function is a modification of nuke-nroff-bs in man.el from the
-  ;; standard Emacs 18 lisp library.
-  ;; Nuke underlining and overstriking (only by the same letter)
-  (goto-char (point-min))
-  (while (search-forward "\b" nil t)
-    (let* ((preceding (char-after (- (point) 2)))
-           (following (following-char)))
-      (cond ((= preceding following)
-             ;; x\bx
-             (delete-char -2))
-            ((= preceding ?\_)
-             ;; _\b
-             (delete-char -2))
-            ((= following ?\_)
-             ;; \b_
-             (delete-region (1- (point)) (1+ (point)))))))
-  (goto-char (point-min))
-  (let ((case-fold-search nil)); 'URL' != 'url' ('libcurl: ' on ?capabilities)
-    (while (re-search-forward "\\bURL: " nil t); test with ?rtags
-      ;; quick fix for C-x f confusion (getting into tramp)
-      (delete-region (match-beginning 0) (match-end 0))))
-  ;; Crunch blank lines
-  (goto-char (point-min))
-  (while (re-search-forward "\n\n\n\n*" nil t)
-    (replace-match "\n\n"))
-  ;; Nuke blanks lines at start.
-  (goto-char (point-min))
-  (skip-chars-forward "\n")
-  (delete-region (point-min) (point)))
-
-(defun ess-help-underline ()
-  "Replace _^H codes with underline face."
-  (save-excursion
-    (goto-char (point-min))
-    (while (search-forward "_\b" nil t)
-      (delete-char -2)
-      (put-text-property (point) (1+ (point)) 'face 'underline))))
-
-;;*;; Link to Info
-(defun ess-goto-info (node)
-  "Display node NODE from `ess-mode' info."
-  (require 'info)
-  (split-window)
-  (Info-goto-node (concat "(ess)" node)))
-
-\f
-;; describe object at point
-
-(defvar-local ess-describe-object-at-point-commands nil
-  "Commands cycled by `ess-describe-object-at-point'.
-Dialect specific.")
-
-(defvar ess--descr-o-a-p-commands nil)
-
-(defun ess-describe-object-at-point ()
-  "Get info for object at point, & display it in an electric buffer or tooltip.
-If region is active use it instead of the object at point.
-
-This is an electric command (`ess--execute-electric-command'),
-which means that you can use the last key to cycle through the
-action set (in this case `C-e'). After invocation of this command
-all standard Emacs commands, except those containing `window' in
-their names, remove the electric *ess-describe* buffer. Use
-`other-window' to switch to *ess-describe* window.
-
-Customize `ess-describe-at-point-method' if you want to display
-the description in a tooltip. See also
-`ess-r-describe-object-at-point-commands' (and similar option for
-other dialects)."
-  (interactive)
-  (if (not ess-describe-object-at-point-commands)
-      (message "Not implemented for dialect %s" ess-dialect)
-    (ess-force-buffer-current)
-    (let ((map (make-sparse-keymap))
-          (objname (or (and (use-region-p)
-                            (buffer-substring-no-properties (point) (mark)))
-                       (ess-symbol-at-point)))
-          ess--descr-o-a-p-commands) ;; used in ess--describe-object-at-point
-      (unless objname (error "No object at point "))
-      (define-key map (vector last-command-event)
-                  #'ess--describe-object-at-point)
-      ;; todo: put digits into the map
-      (let* ((inhibit-quit t) ;; C-g removes the buffer
-             (buf (ess--execute-electric-command
-                   map (format "Press %s to cycle"
-                               (single-key-description last-command-event))
-                   nil nil objname))
-             ;; read full command
-             (keys (read-key-sequence-vector ""))
-             (command (and keys (key-binding keys))))
-        (when (and (commandp command)
-                   (bufferp buf)
-                   (or (not (symbolp command)) ;; kill on lambdas
-                       (not (string-match "window" (symbol-name command)))))
-          (kill-buffer buf)) ;; bury does not work here :( (Emacs bug?)
-        (setq unread-command-events
-              (append keys unread-command-events))))))
-
-(defun ess--describe-object-at-point (_ev objname)
-  (setq ess--descr-o-a-p-commands (or ess--descr-o-a-p-commands
-                                      (symbol-value ess-describe-object-at-point-commands)))
-  (let* ((com (format (car (pop ess--descr-o-a-p-commands)) objname))
-         (buf (get-buffer-create "*ess-describe*"))
-         pos)
-    (unless (eq ess-describe-at-point-method 'tooltip)
-      ;; can take some time for the command to execute
-      (display-buffer buf))
-    (sit-for .01)
-    (ess-command (concat com "\n") buf) ;; erases buf
-    (with-current-buffer buf
-      (goto-char (point-min))
-      (insert (propertize (format "%s:\n\n" com) 'face 'font-lock-string-face))
-      (forward-line -1)
-      (setq pos (point))
-      ;; set the keys that we are used to in help mode
-      (special-mode)
-      (let ((inhibit-read-only t))
-        (ansi-color-apply-on-region (point-min) (point-max))))
-    (if (eq ess-describe-at-point-method 'tooltip)
-        (ess-tooltip-show-at-point
-         (with-current-buffer buf (buffer-string))  0 30)
-      (display-buffer buf)
-      (set-window-point (get-buffer-window buf) pos) ;; don't move window point
-      buf)))
-
-(with-no-warnings
-  ;; We're just backporting here, don't care about compiler warnings
-  (defalias 'ess-display-buffer-reuse-mode-window
-    ;; TODO: Remove once we drop support for Emacs 25
-    (if (fboundp 'display-buffer-reuse-mode-window)
-        'display-buffer-reuse-mode-window
-      (lambda (buffer alist)
-        (let* ((alist-entry (assq 'reusable-frames alist))
-               (alist-mode-entry (assq 'mode alist))
-              (frames (cond (alist-entry (cdr alist-entry))
-                            ((if (eq pop-up-frames 'graphic-only)
-                                 (display-graphic-p)
-                               pop-up-frames)
-                             0)
-                            (display-buffer-reuse-frames 0)
-                            (t (last-nonminibuffer-frame))))
-               (inhibit-same-window-p (cdr (assq 'inhibit-same-window alist)))
-              (windows (window-list-1 nil 'nomini frames))
-               (buffer-mode (with-current-buffer buffer major-mode))
-               (allowed-modes (if alist-mode-entry
-                                  (cdr alist-mode-entry)
-                                buffer-mode))
-               (curwin (selected-window))
-               (curframe (selected-frame)))
-          (unless (listp allowed-modes)
-            (setq allowed-modes (list allowed-modes)))
-          (let (same-mode-same-frame
-                same-mode-other-frame
-                derived-mode-same-frame
-                derived-mode-other-frame)
-            (dolist (window windows)
-              (let ((mode?
-                     (with-current-buffer (window-buffer window)
-                       (cond ((memq major-mode allowed-modes)
-                              'same)
-                             ((derived-mode-p allowed-modes)
-                              'derived)))))
-                (when (and mode?
-                           (not (and inhibit-same-window-p
-                                     (eq window curwin))))
-                  (push window (if (eq curframe (window-frame window))
-                                   (if (eq mode? 'same)
-                                       same-mode-same-frame
-                                     derived-mode-same-frame)
-                                 (if (eq mode? 'same)
-                                     same-mode-other-frame
-                                   derived-mode-other-frame))))))
-            (let ((window (car (nconc same-mode-same-frame
-                                      same-mode-other-frame
-                                      derived-mode-same-frame
-                                      derived-mode-other-frame))))
-              (when (window-live-p window)
-                (prog1 (window--display-buffer buffer window 'reuse alist)
-                  (unless (cdr (assq 'inhibit-switch-frame alist))
-                    (window--maybe-raise-frame (window-frame window))))))))))))
-
-(provide 'ess-help)
-;;; ess-help.el ends here
diff --git a/elpa/ess-20251212.937/ess-inf.el b/elpa/ess-20251212.937/ess-inf.el
deleted file mode 100644 (file)
index 28c7935..0000000
+++ /dev/null
@@ -1,3270 +0,0 @@
-;;; ess-inf.el --- Support for running S as an inferior Emacs process  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1989-2025 Free Software Foundation, Inc.
-
-;; Author: David Smith <dsmithNOSPAMstats.adelaide.edu.au>
-;; Created: 7 Jan 1994
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; Code for handling running ESS processes.
-
-;;; Code:
-
-(eval-when-compile
-  (require 'cl-lib)
-  (require 'tramp)
-  (require 'subr-x))
-(require 'ess-utils)
-(require 'ess)
-(require 'ess-tracebug)
-
-(require 'ansi-color)
-(require 'comint)
-(require 'compile)
-(require 'format-spec)
-(require 'overlay)
-(require 'project)
-
-;; Don't require tramp at run time. It's an expensive library to load.
-;; Instead, guard calls with (require 'tramp) and silence the byte
-;; compiler.
-(declare-function tramp-sh-handle-expand-file-name "tramp-sh" (name &optional dir))
-(declare-function tramp-dissect-file-name "tramp" (name &optional nodefault))
-(declare-function tramp-tramp-file-p "tramp" (name))
-(declare-function inferior-ess-r-mode "ess-r-mode" ())
-(declare-function inferior-ess-julia-mode "ess-julia" ())
-(declare-function inferior-ess-stata-mode "ess-stata-mode" ())
-(declare-function extract-rectangle-bounds "rect" (start end))
-
-(declare-function ess-mode "ess-mode" ())
-(declare-function ess-complete-object-name "ess-r-completion" ())
-;; FIXME:This one should not be necessary
-(declare-function ess-display-help-on-object "ess-help" (object &optional command))
-(declare-function ess-dump-object-into-edit-buffer "ess-mode" (object))
-
-(defvar add-log-current-defun-header-regexp)
-
-;; The following declares can be removed once we drop Emacs 25
-(declare-function tramp-file-name-method "tramp")
-(declare-function tramp-file-name-user "tramp")
-(declare-function tramp-file-name-host "tramp")
-(declare-function tramp-file-name-localname "tramp")
-(declare-function tramp-file-name-hop "tramp")
-
-(defcustom inferior-ess-mode-hook nil
-  "Hook for customizing inferior ESS mode.
-Called after `inferior-ess-mode' is entered and variables have
-been initialized."
-  :group 'ess-hooks
-  :type 'hook)
-
-(defvar inferior-ess-mode-syntax-table
-  (let ((tab (copy-syntax-table comint-mode-syntax-table)))
-    tab)
-  "Syntax table for `inferior-ess-mode'.")
-
-(defun inferior-ess--set-major-mode (dialect)
-  "Set major mode according to DIALECT."
-  (cond ((string= "R" dialect)
-         (progn (require 'ess-r-mode)
-                (inferior-ess-r-mode)))
-        ((string= "julia" dialect)
-         (progn (require 'ess-julia)
-                (inferior-ess-julia-mode)))
-        ((string= "stata" dialect)
-         (progn (require 'ess-stata-mode)
-                (inferior-ess-stata-mode)))
-        ;; FIXME: we need this horrible hack so that
-        ;; inferior-ess-mode-syntax-table gets set for
-        ;; languages that still rely on the old way of doing
-        ;; things (before we used define-derived-mode for
-        ;; inferior modes).
-        (t
-         (progn
-           (setq-local inferior-ess-mode-syntax-table
-                       (eval (or (alist-get 'inferior-ess-mode-syntax-table ess-local-customize-alist)
-                                 (alist-get 'ess-mode-syntax-table ess-local-customize-alist))
-                             t))
-           (inferior-ess-mode)))))
-
-\f ;;*;; Process handling
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; In this section:
-;;;
-;;; * User commands for starting an ESS process
-;;; * Functions called at startup
-;;; * Process handling code
-;;; * Multiple process implementation
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;;*;; Starting a process
-(defun ess-proc-name (n name)
-  "Return name of process N, as a string, with NAME prepended.
-If `ess-plain-first-buffername', then initial process is number-free."
-  (concat name
-          (if (not (and ess-plain-first-buffername
-                        (= n 1))) ; if not both first and plain-first add number
-              (concat ":" (number-to-string n)))))
-
-(defvar-local inferior-ess--local-data nil
-  "Program name and arguments used to start the inferior process.")
-
-(defvar inferior-ess--last-started-process-buffer nil
-  "Useful in unit tests to check initialisation errors.
-In that case the command fails before it can return the process
-buffer to us. This global variable can be checked instead.")
-
-(defun inferior-ess (start-args customize-alist &optional no-wait)
-  "Start inferior ESS process.
-Without a prefix argument, starts a new ESS process, or switches
-to the ESS process associated with the current buffer. With
-START-ARGS (perhaps specified via \\[universal-argument]), starts
-the process with those args. The current buffer is used if it is
-an `inferior-ess-mode' or `ess-transcript-mode' buffer.
-
-If `ess-ask-about-transfile' is non-nil, you will be asked for a
-transcript file to use.  If there is no transcript file, the
-buffer name will be like *R* or *R2*, determined by
-`ess-gen-proc-buffer-name-function'.
-
-Takes the program name from the variable `inferior-ess-program'.
-
-See Info node `(ess)Customizing startup' and
-`display-buffer-alist' to control where and how the buffer is
-displayed.
-
-\(Type \\[describe-mode] in the process buffer for a list of
-commands.)
-
-CUSTOMIZE-ALIST is the list of dialect-specific variables.  When
-non-nil, NO-WAIT tells ESS not to wait for the process to finish.
-This may be useful for debugging."
-  ;; Use the current buffer if it is in inferior-ess-mode or ess-trans-mode
-  ;; If not, maybe ask about starting directory and/or transcript file.
-  ;; If no transfile, use buffer *S*
-  ;; This function is primarily used to figure out the Process and
-  ;; buffer names to use for inferior-ess.
-  (run-hooks 'ess-pre-run-hook)
-  (let* ((dialect (eval (cdr (assoc 'ess-dialect customize-alist)) t))
-         (process-environment process-environment)
-         ;; Use dialect if not R, R program name otherwise
-         (temp-dialect (if ess-use-inferior-program-in-buffer-name ;VS[23-02-2013]: FIXME: this should not be here
-                           (if (string-equal dialect "R")
-                               (file-name-nondirectory inferior-ess-r-program)
-                             dialect)
-                         dialect))
-         (inf-buf (inferior-ess--get-proc-buffer-create temp-dialect))
-         (proc-name (buffer-local-value 'ess-local-process-name inf-buf)))
-    (with-current-buffer inf-buf
-      ;; TODO: Get rid of this, we should rely on modes to set the
-      ;; variables they need.
-      (ess-setq-vars-local customize-alist)
-      (inferior-ess--set-major-mode ess-dialect)
-      ;; Set local variables after changing mode because they might
-      ;; not be permanent
-      (setq default-directory
-            (inferior-ess--maybe-prompt-startup-directory proc-name temp-dialect))
-      (setq inferior-ess--local-data (cons inferior-ess-program start-args))
-      ;; Read the history file
-      (when ess-history-file
-        (setq comint-input-ring-file-name
-              (expand-file-name (if (eql t ess-history-file)
-                                    (concat "." ess-dialect "history")
-                                  ess-history-file)
-                                ess-history-directory))
-        (comint-read-input-ring))
-      ;; Show the buffer
-      ;; TODO: Remove inferior-ess-own-frame after ESS 19.04, then just have:
-      ;; (pop-to-buffer inf-buf)
-      (pop-to-buffer inf-buf (with-no-warnings
-                               (when inferior-ess-own-frame
-                                 '(display-buffer-pop-up-frame))))
-      (let ((proc (inferior-ess--start-process inf-buf proc-name start-args)))
-        (ess-make-buffer-current)
-        (goto-char (point-max))
-        (unless no-wait
-          (ess-write-to-dribble-buffer "(inferior-ess: waiting for process to start (before hook)\n")
-          (ess-wait-for-process proc nil 0.01 t))
-        (unless (and proc (eq (process-status proc) 'run))
-          (error "Process %s failed to start" proc-name))
-        (setq-local font-lock-fontify-region-function #'inferior-ess-fontify-region)
-        (setq-local ess-sl-modtime-alist nil)
-        (run-hooks 'ess-post-run-hook)
-        ;; User initialization can take some time ...
-        (unless no-wait
-          (ess-write-to-dribble-buffer "(inferior-ess): waiting for process (after hook)\n")
-          (ess-wait-for-process proc)))
-      (setq inferior-ess--last-started-process-buffer inf-buf)
-      inf-buf)))
-
-(defun inferior-ess--get-proc-buffer-create (name)
-  "Get a process buffer, creating a new one if needed.
-This always returns a process-less buffer. The variable
-`ess-local-process-name' is set in the buffer with the name of
-the next process to spawn. This name may be different from the
-buffer name, depending on how `ess-gen-proc-buffer-name-function'
-generated the latter from NAME."
-  (let* ((proc-name (let ((ntry 1))
-                      ;; Find the next non-existent process N (*R:N*)
-                      (while (get-process (ess-proc-name ntry name))
-                        (setq ntry (1+ ntry)))
-                      (ess-proc-name ntry name)))
-         (inf-name (funcall ess-gen-proc-buffer-name-function proc-name)))
-    (let ((buf (cond
-                ;; Try to use current buffer, if inferior-ess-mode but
-                ;; no process
-                ((and (not (comint-check-proc (current-buffer)))
-                      (derived-mode-p 'inferior-ess-mode))
-                 ;; Don't change existing buffer name in this case. It
-                 ;; is very common to restart the process in the same
-                 ;; buffer.
-                 (setq proc-name ess-local-process-name)
-                 (current-buffer))
-                ;; Pick up a transcript file
-                (ess-ask-about-transfile
-                 (let ((transfilename (read-file-name
-                                       "Use transcript file (default none):" nil "")))
-                   (if (string= transfilename "")
-                       (get-buffer-create inf-name)
-                     (find-file-noselect (expand-file-name transfilename)))))
-                ;; Create a new buffer or take the *R:N* buffer if
-                ;; already exists (it should contain a dead process)
-                (t
-                 (get-buffer-create inf-name)))))
-      ;; We generated a new process name but there might still be a
-      ;; live process in the buffer in corner cases because of
-      ;; `ess-gen-proc-buffer-name-function` or if the user renames
-      ;; inferior buffers
-      (when (comint-check-proc buf)
-        (error "Can't start a new session in buffer `%s` because one already exists"
-               inf-name))
-      (with-current-buffer buf
-        (setq-local ess-local-process-name proc-name))
-      buf)))
-
-(defun ess--accumulation-buffer (proc)
-  "Return, creating if needed, the accumulation buffer for PROC."
-  (let ((abuf (process-get proc :accum-buffer)))
-    (if (buffer-live-p abuf)
-        abuf
-      (let ((abuf (get-buffer-create (format " *%s:accum*" (process-name proc)))))
-        (process-put proc :accum-buffer abuf)
-        (with-current-buffer abuf
-          (buffer-disable-undo)
-          (setq-local inhibit-modification-hooks t))
-        abuf))))
-
-(defvar-local 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!
-
-(defvar-local 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")
-
-(defvar-local 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")
-
-(defun inferior-ess-fontify-region (beg end &optional verbose)
-  "Fontify output by output to avoid fontification spilling over prompts.
-BEG and END signify the bounds, VERBOSE gets passed to
-`font-lock-default-fontify-region'."
-  (let* ((buffer-undo-list t)
-         (font-lock-dont-widen t)
-         (font-lock-extend-region-functions nil)
-         (pos1 beg)
-         (pos2))
-    (when (< beg end)
-      (with-silent-modifications
-        ;; fontify chunks from prompt to prompt
-        (while (< pos1 end)
-          (goto-char pos1)
-          (comint-next-prompt 1)
-          (setq pos2 (min (point) end))
-          (save-restriction
-            (narrow-to-region pos1 pos2)
-            (font-lock-default-fontify-region pos1 pos2 verbose))
-          (setq pos1 pos2))
-        ;; highlight errors
-        (setq compilation--parsed beg)
-        `(jit-lock-bounds ,beg . ,end)))))
-
-(defun ess-gen-proc-buffer-name:simple (proc-name)
-  "Function to generate buffer name by wrapping PROC-NAME in *proc-name*.
-See `ess-gen-proc-buffer-name-function'."
-  (format "*%s*" proc-name))
-
-(defun ess-gen-proc-buffer-name:directory (proc-name)
-  "Return a buffer name by wrapping PROC-NAME in *PROC-NAME:DIR-NAME*.
-DIR-NAME is a short directory name. See
-`ess-gen-proc-buffer-name-function'."
-  (format "*%s:%s*" proc-name (file-name-nondirectory
-                               (directory-file-name default-directory))))
-
-(defun ess-gen-proc-buffer-name:abbr-long-directory (proc-name)
-  "Return a buffer name in the form *PROC-NAME:ABBREVIATED-LONG-DIR-NAME*.
-PROC-NAME is a string representing an internal process
-name. ABBREVIATED-LONG-DIR-NAME is an abbreviated full directory
-name. Abbreviation is performed by `abbreviate-file-name'. See
-`ess-gen-proc-buffer-name-function'."
-  (format "*%s:%s*" proc-name (abbreviate-file-name default-directory)))
-
-(defun ess-gen-proc-buffer-name:project-or-simple (proc-name)
-  "Function to generate buffer name in the form *PROC-NAME:PROJECT-ROOT*.
-PROC-NAME is a string representing an internal process name. If
-no project directory has been found use
-`ess-gen-proc-buffer-name:simple'. See
-`ess-gen-proc-buffer-name-function'."
-  (if-let ((p (project-current))
-           (proj (ess--project-root p)))
-      (format "*%s:%s*" proc-name (file-name-nondirectory
-                                   (directory-file-name proj)))
-    (ess-gen-proc-buffer-name:simple proc-name)))
-
-(defun ess-gen-proc-buffer-name:project-or-directory (proc-name)
-  "Function to generate buffer name in the form *PROC-NAME:PROJECT-ROOT*.
-PROC-NAME is a string representing an internal process name.
-PROJECT-ROOT is directory name returned by `ess--project-root' if
-defined. If no project directory has been found, use
-`ess-gen-proc-buffer-name:directory'. See
-`ess-gen-proc-buffer-name-function'."
-  (if-let ((p (project-current))
-           (proj (ess--project-root p)))
-      (format "*%s:%s*" proc-name (file-name-nondirectory
-                                   (directory-file-name proj)))
-    (ess-gen-proc-buffer-name:directory proc-name)))
-
-;; This ensures that people who have this set in their init file don't
-;; get errors about undefined functions after upgrading ESS:
-(define-obsolete-function-alias 'ess-gen-proc-buffer-name:projectile-or-simple
-  #'ess-gen-proc-buffer-name:project-or-simple "ESS 19.04")
-(define-obsolete-function-alias 'ess-gen-proc-buffer-name:projectile-or-directory
-  #'ess-gen-proc-buffer-name:project-or-directory "ESS 19.04")
-
-(defun inferior-ess-available-p (&optional proc)
-  "Return non-nil if PROC is not busy."
-  (when-let ((proc (or proc (ess-get-current-process))))
-    (unless (process-get proc 'busy)
-      (or (ess-debug-active-p proc) ; don't send empty lines in debugger
-          (when-let ((last-check (process-get proc 'last-availability-check)))
-            (time-less-p (process-get proc 'last-eval) last-check))
-          (progn
-            ;; Send an empty string and waiting a bit to make sure we are not busy.
-            (process-send-string proc "\n")
-            (inferior-ess-mark-as-busy proc)
-            (process-put proc 'availability-check t)
-            ;; Start with a very conservative waiting time and quickly average
-            ;; down to the actual response.
-            (let ((avresp (or (process-get proc 'average-response-time) 0.1))
-                  (ts (current-time)))
-              (when (accept-process-output proc (max 0.005 (* 2.0 avresp)))
-                (let ((avresp (/ (+ (* 2.0 avresp)
-                                    (float-time (time-subtract (current-time) ts)))
-                                 3.0)))
-                  (process-put proc 'average-response-time avresp)))
-              (process-put proc 'last-availability-check ts))
-            (not (process-get proc 'busy)))))))
-
-(defun inferior-ess--set-status (proc string)
-  "Internal function to set the status of process PROC.
-Return non-nil if the process is in a ready (not busy) state."
-  ;; TODO: do it in one search, use starting position, use prog1
-  (let ((ready (string-match-p (concat "\\(" inferior-ess-primary-prompt "\\)\\'") string)))
-    (process-put proc 'busy-end? (and ready (process-get proc 'busy)))
-    ;; When "\n" inserted from inferior-ess-available-p, delete the prompt.
-    (when (and ready
-               (process-get proc 'availability-check)
-               (string-match-p (concat inferior-ess-primary-prompt "\\'") string))
-      (process-put proc 'suppress-next-output? t))
-    (process-put proc 'availability-check nil)
-    (when ready
-      (process-put proc 'running-async? nil))
-    (process-put proc 'busy (not ready))
-    (process-put proc 'sec-prompt
-                 (when inferior-ess-secondary-prompt
-                   (string-match (concat "\\(" inferior-ess-secondary-prompt "\\)\\'") string)))
-    ready))
-
-(defun ess--command-delimited-output-info (buf delim)
-  "Detect positions of accumulated output.
-Return positions after START, before END, after prompt. If any is
-not found, returns nil. The last position marks the start of new
-output, if any."
-  (with-current-buffer buf
-    (save-excursion
-      (save-match-data
-        (goto-char (point-min))
-        (when (re-search-forward (ess--delimiter-start-re delim) nil t)
-          (let ((start (1+ (match-end 0))))
-            (when (re-search-forward (ess--delimiter-end-re delim) nil t)
-              (when (not (equal (line-beginning-position)
-                                (match-beginning 0)))
-                (error "Missing newline in command output"))
-              (let ((end (max (1- (match-beginning 0))
-                              start)))
-                (goto-char (1+ (match-end 0)))
-                (when (re-search-forward inferior-ess-primary-prompt nil t)
-                  (let* ((prompt-end (match-end 0))
-                         (new (when (> (point-max) prompt-end)
-                                prompt-end)))
-                    (list start end new)))))))))))
-
-(defun ess--command-output-info (buf)
-  "Detect positions of accumulated output.
-Like `ess--command-delimited-output-info' but detects prompts
-without the benefit of output delimiters. This is much less
-robust. This might leave parasite output at the start of BUF
-(e.g. `+' prompts with multiline commands). The result might be
-incomplete if the command output includes a line that ends with
-`> ' and which happens to be the last characters in a partial
-output (process output passed to filters is split in batches at
-arbitrary locations). In that case the rest of the output will be
-inserted in the process buffer instead of the command buffer."
-  (with-current-buffer buf
-    (save-excursion
-      (save-match-data
-        (goto-char (point-min))
-        (when (re-search-forward (concat inferior-ess-primary-prompt
-                                         "\\(\n\\|\\'\\)")
-                                 nil t)
-          (goto-char (match-beginning 0))
-          (let ((end (max (1- (line-beginning-position))
-                          (point-min)))
-                (new (when (> (point-max) (line-end-position))
-                       (1+ (line-end-position)))))
-            (list (point-min) end new)))))))
-
-;; Be careful that new output might come in after the closing
-;; delimiter or prompt. This could happen when a background command is
-;; interrupted asynchronously and the user has sent new inputs before
-;; the process has finished interrupting.
-(defun ess--command-set-status (proc buf info)
-  (with-current-buffer buf
-    (unwind-protect
-        (progn
-          (let* ((beg (nth 0 info))
-                 (end (nth 1 info))
-                 (new (nth 2 info))
-                 (output (buffer-substring beg end))
-                 (new-output (when new
-                               (buffer-substring new (point-max)))))
-            ;; Delete the start delimiter and anything before it.
-            ;; This takes care of `+` continuation lines that occur
-            ;; with multi-line commands. Delete anything after the
-            ;; end delimiter, including the prompt and new output
-            (delete-region (point-min) (point-max))
-            (insert output)
-            new-output))
-      (process-put proc 'busy nil))))
-
-(defun ess--delimiter-start-re (delim)
-  (concat "\\(" delim "-START\r*$\\)"))
-
-(defun ess--delimiter-end-re (delim)
-  (concat "\\(" delim "-END\r*\\)"))
-
-(defun ess--delimiter-error-start-re ()
-  "\1e\1eESSR::ERROR \\(\"\\)")
-
-(defun ess--delimiter-error-end-re ()
-  "\\(\"\\)\1e\1e")
-
-(defun inferior-ess-mark-as-busy (proc)
-  "Put PROC's busy value to t."
-  (process-put proc 'busy t)
-  (process-put proc 'sec-prompt nil))
-
-(defun inferior-ess-run-callback (proc string)
-  ;; callback is stored in 'callbacks proc property. Callbacks is a list that
-  ;; can contain either functions to be called with two arguments PROC and
-  ;; STRING, or cons cells of the form (func . suppress). If SUPPRESS is non-nil
-  ;; next process output will be suppressed.
-  (unless (process-get proc 'busy)
-    ;; only one callback is implemented for now
-    (let* ((cb (car (process-get proc 'callbacks)))
-           (listp (not (functionp cb)))
-           (suppress (and listp (consp cb) (cdr cb)))
-           (cb (if (and listp (consp cb))
-                   (car cb)
-                 cb)))
-      (when cb
-        (when ess-verbose
-          (ess-write-to-dribble-buffer "executing callback ...\n"))
-        (when suppress
-          (process-put proc 'suppress-next-output? t))
-        (process-put proc 'callbacks nil)
-        (condition-case-unless-debug err
-            (funcall cb proc string)
-          (error (message "%s" (error-message-string err))))))))
-
-(defun ess--if-verbose-write-process-state (proc string &optional filter)
-  "Write information about PROC, STRING, and FILTER to the dribble buffer."
-  (ess-if-verbose-write
-   (format "\n%s:
-    --> busy:%s busy-end:%s sec-prompt:%s interruptable:%s <--
-    --> running-async:%s callback:%s suppress-next-output:%s <--
-    --> dbg-active:%s is-recover:%s <--
-    --> cmd-buffer:%s cmd-output-delimiter:%s <--
-    --> string:%s<--\n"
-           (upcase (or filter "normal-filter"))
-           (process-get proc 'busy)
-           (process-get proc 'busy-end?)
-           (process-get proc 'sec-prompt)
-           (process-get proc 'interruptable?)
-           (process-get proc 'running-async?)
-           (if (process-get proc 'callbacks) "yes")
-           (process-get proc 'suppress-next-output?)
-           (process-get proc 'dbg-active)
-           (process-get proc 'is-recover)
-           (process-get proc 'cmd-buffer)
-           (process-get proc 'cmd-output-delimiter)
-           (if (> (length string) 150)
-               (format "%s .... %s" (substring string 0 50) (substring string -50))
-             string))))
-
-(defun inferior-ess-output-filter (proc string)
-  "Standard output filter for the inferior ESS process PROC.
-Ring Emacs bell if process output starts with an ASCII bell, and pass
-the rest to `comint-output-filter'.
-Taken from octave-mod.el."
-  (inferior-ess--set-status proc string)
-  (ess--if-verbose-write-process-state proc string)
-  (inferior-ess-run-callback proc string)
-  (if (process-get proc 'suppress-next-output?)
-      ;; works only for suppressing short output, for time being is enough (for callbacks)
-      (process-put proc 'suppress-next-output? nil)
-    (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 PROC.
-This marks the process with a MESSAGE, at a particular time point."
-  (let ((abuf (process-get proc :accum-buffer)))
-    (when (buffer-live-p abuf)
-      (kill-buffer abuf)))
-  (let ((pbuf (process-buffer proc)))
-    (when (buffer-live-p pbuf)
-      (with-current-buffer pbuf
-        (save-excursion
-          (setq message (substring message 0 -1)) ; strip newline
-          (set-buffer (process-buffer proc))
-          (comint-write-input-ring)
-          (goto-char (point-max))
-          (insert-before-markers
-           (format "\nProcess %s %s at %s\n"
-                   (process-name proc) message (current-time-string))))))))
-
-;; FIXME: This list is structured as '(("R:2") ("R")). It doesn't
-;; appear the CDR are used. Can probably just be '("R:2" "R").
-(defvar ess-process-name-list nil
-  "Alist of active ESS processes.")
-
-(defun inferior-ess--start-process (buf proc-name switches)
-  "Make a comint process in buffer BUF with process PROC-NAME.
-SWITCHES is passed to `comint-exec'. BUF is guaranteed to be a
-process-less buffer because it was created with
-`inferior-ess--get-proc-buffer-create'."
-  (with-current-buffer buf
-    (if (eq (buffer-size) 0) nil
-      (goto-char (point-max))
-      (insert "\^L\n")))
-  (let ((process-environment
-         (nconc
-          (list "STATATERM=emacs"
-                (format "PAGER=%s" inferior-ess-pager))
-          ;; This lets R code know whether Emacs was running with a
-          ;; light or dark background at startup time
-          (let ((bg-mode (frame-parameter nil 'background-mode)))
-            (when (memq bg-mode '(light dark))
-              (list (format "ESS_BACKGROUND_MODE=%s" (symbol-name bg-mode)))))
-          process-environment))
-        (tramp-remote-process-environment
-         (nconc ;; it contains a pager already, so append
-          (when (boundp 'tramp-remote-process-environment)
-            (copy-sequence tramp-remote-process-environment))
-          (list "STATATERM=emacs"
-                (format "PAGER=%s" inferior-ess-pager)))))
-    (comint-exec buf
-                 proc-name
-                 inferior-ess-program
-                 nil
-                 (when switches
-                   (split-string switches))))
-  (let ((proc (get-buffer-process buf)))
-    ;; Set the process hooks
-    (set-process-sentinel proc #'ess-process-sentinel)
-    (set-process-filter proc #'inferior-ess-output-filter)
-    (inferior-ess-mark-as-busy proc)
-    ;; Add this process to ess-process-name-list, if needed
-    (let ((conselt (assoc proc-name ess-process-name-list)))
-      (unless conselt
-        (setq ess-process-name-list
-              (cons (cons proc-name nil) ess-process-name-list))))
-    proc))
-
-
-;;*;; Requester functions called at startup
-(defun inferior-ess--get-startup-directory ()
-  "Return a startup directory."
-  (let ((dir (or (when (boundp 'ess-startup-directory)
-                   (if (symbolp ess-startup-directory)
-                       (symbol-value ess-startup-directory)
-                     ess-startup-directory))
-                 (and ess-startup-directory-function
-                      (funcall ess-startup-directory-function))
-                 (when-let ((proj (project-current)))
-                   (ess--project-root proj))
-                 default-directory)))
-    (directory-file-name dir)))
-
-(defun inferior-ess--maybe-prompt-startup-directory (procname _dialect)
-  "Possibly prompt for a startup directory.
-When `ess-ask-for-ess-directory' is non-nil, prompt.  PROCNAME is
-the name of the inferior process (e.g. \"R:1\"), and DIALECT is
-the language dialect (e.g. \"R\")."
-  (let ((default-dir (inferior-ess--get-startup-directory)))
-    (if ess-ask-for-ess-directory
-        (let ((prompt (format "%s starting project directory? " procname))
-              (display-buffer-overriding-action nil) ; hack to let helm display a buffer
-              )
-          (ess-prompt-for-directory default-dir prompt))
-      default-dir)))
-
-(defun ess-prompt-for-directory (default prompt)
-  "PROMPT for a directory, using DEFAULT as the usual."
-  (let* ((def-dir (file-name-as-directory default))
-         (the-dir (expand-file-name
-                   (file-name-as-directory
-                    (read-directory-name prompt def-dir def-dir t nil)))))
-    (if (file-directory-p the-dir) nil
-      (error "%s is not a valid directory" the-dir))
-    the-dir))
-
-
-;;*;; General process handling code
-
-(defmacro ess-with-current-buffer (buffer &rest body)
-  "Like `with-current-buffer' but with transfer of some essential
-local ESS vars like `ess-local-process-name'."
-  (declare (indent 1) (debug t))
-  (let ((lpn (make-symbol "lpn"))
-        (dialect (make-symbol "dialect"))
-        (alist (make-symbol "alist")))
-    `(let ((,lpn ess-local-process-name)
-           (,dialect ess-dialect)
-           (,alist ess-local-customize-alist))
-       (with-current-buffer ,buffer
-         (ess-setq-vars-local (eval ,alist t))
-         (setq ess-local-process-name ,lpn)
-         (setq ess-dialect ,dialect)
-         ,@body))))
-
-(dolist (mode '(emacs-lisp-mode lisp-interaction-mode))
-  (font-lock-add-keywords
-   mode
-   '(("(\\(ess-with-current-buffer\\)\\s +\\(\\(\\w\\|\\s_\\)+\\)"
-      (1 font-lock-keyword-face)
-      (2 font-lock-variable-name-face)))))
-
-(defun ess-get-process (&optional name use-another)
-  "Return the ESS process named by NAME.
-If USE-ANOTHER is non-nil, and the process NAME is not
-running (anymore), try to connect to another if there is one. By
-default (USE-ANOTHER is nil), the connection to another process
-happens interactively (when possible)."
-  (setq name (or name ess-local-process-name))
-  (cl-assert name nil "No ESS process is associated with this buffer now")
-  (update-ess-process-name-list)
-  (cond ((assoc name ess-process-name-list)
-         (get-process name))
-        ((= 0 (length ess-process-name-list))
-         (save-current-buffer
-           (message "trying to (re)start process %s for language %s ..."
-                    name ess-language)
-           (ess-start-process-specific ess-language ess-dialect)
-           ;; and return the process: "call me again"
-           (ess-get-process name)))
-        ;; else: there are other running processes
-        (use-another ; connect to another running process : the first one
-         (let ((other-name (car (elt ess-process-name-list 0))))
-           ;; "FIXME": try to find the process name that matches *closest*
-           (message "associating with *other* process '%s'" other-name)
-           (ess-get-process other-name)))
-        ((and (not noninteractive)
-              (y-or-n-p
-               (format "Process %s is not running, but others are. Switch? " name)))
-         (ess-force-buffer-current (concat ess-dialect " process to use: ") 'force)
-         (ess-get-process ess-current-process-name))
-        (t (error "Process %s is not running" name))))
-
-(defun inferior-ess-default-directory ()
-  "Return the `default-directory' of the process."
-  (ess-get-process-variable 'default-directory))
-
-;;--- Unfinished idea (ESS-help / R-help ) -- probably not worth it...
-;;- (defun ess-set-inferior-program (filename)
-;;-   "Allows to set or change `inferior-ess-program', the program (file)name."
-;;-   (interactive "fR executable (script) file: ")
-;;-   ;; "f" : existing file {file name completion} !
-;;-   (setq inferior-ess-program filename))
-;; the inferior-ess-program is initialized in the customize..alist,
-;; e.g. from  inferior-ess-r-program ... --> should change rather these.
-;; However these really depend on the current ess-language!
-;; Plan: 1) must know and use ess-language
-;;       2) change the appropriate  inferior-<ESSlang>-program
-;; (how?) in R/S : assign(paste("inferior-",ESSlang,"-p...."),  filename))
-
-
-;;*;; Multiple process handling code
-
-;; FIXME: It seems the only effect of this function is to remove dead
-;; processes from `ess-process-name-list'. Am I missing something?
-(defun ess-make-buffer-current nil
-  "Make the process associated with the current buffer the current ESS process.
-Returns the name of the process, or nil if the current buffer has none."
-  (update-ess-process-name-list)
-  ;; (if ess-local-process-name
-  ;;     (setq ess-current-process-name ess-local-process-name))
-  ess-local-process-name)
-
-(defun ess-get-process-variable (var)
-  "Return the variable VAR (symbol) local to ESS process called NAME (string)."
-  (buffer-local-value var (process-buffer (ess-get-process ess-local-process-name))))
-
-(defun ess-set-process-variable (var val)
-  "Set variable VAR (symbol) local to ESS process called NAME (string) to VAL."
-  (with-current-buffer (process-buffer (ess-get-process ess-local-process-name))
-    (set var val)))
-
-(defun ess-process-live-p (&optional proc)
-  "Check if the local ess process is alive.
-Return nil if current buffer has no associated process, or
-process was killed. PROC defaults to `ess-local-process-name'"
-  (when-let ((proc (or proc (ess-get-current-process))))
-    (process-live-p proc)))
-
-(defun ess-process-get (propname &optional proc)
-  "Return the variable PROPNAME (symbol) of the current ESS process.
-PROC defaults to process with name `ess-local-process-name'."
-  (process-get (or proc (get-process ess-local-process-name)) propname))
-
-(defun ess-process-put (propname value &optional proc)
-  "Set the variable PROPNAME (symbol) to VALUE in the current ESS process.
-PROC defaults to the process given by `ess-local-process-name'"
-  (process-put (or proc (get-process ess-local-process-name)) propname value))
-
-(defun ess-start-process-specific (language dialect)
-  "Start an ESS process.
-Typically from a language-specific buffer, using DIALECT.
-LANGUAGE is ignored."
-  (save-current-buffer
-    (let ((dsymb (intern dialect)))
-      (if (fboundp dsymb)
-          (funcall dsymb)
-        (error "No ESS processes running; not yet implemented to start (%s,%s)"
-               language dialect)))))
-
-(defmacro ess--with-no-pop-to-buffer (&rest body)
-  "Disable some effects of `pop-to-buffer'.
-Prevent `display-buffer' from performing an action and save the
-current buffer to prevent `pop-to-buffer' from setting a new
-current buffer."
-  ;; `pop-to-buffer' might still raise windows and frames so it may be
-  ;; better to have our own configurable `ess--pop-to-buffer' wrapper.
-  (declare (indent 0)
-           (debug (&rest form)))
-  `(let ((display-buffer-overriding-action '(display-buffer-no-window (allow-no-window . t))))
-     (save-current-buffer
-       ,@body)))
-
-(defun ess-request-a-process (message &optional noswitch ask-if-1)
-  "Ask for a process, and make it the current ESS process.
-If there is exactly one process, only ask if ASK-IF-1 is non-nil.
-Also switches to the process buffer unless NOSWITCH is non-nil.
-Interactively, NOSWITCH can be set by giving a prefix argument.
-Returns the name of the selected process. MESSAGE may get passed
-to `ess-completing-read'."
-  (interactive (list "Switch to which ESS process? " current-prefix-arg))
-  (update-ess-process-name-list)
-  (let* ((ess-dialect (or ess-dialect
-                          (ess-completing-read
-                           "Set `ess-dialect'"
-                           (delete-dups (list "R" "S+" (or (bound-and-true-p S+-dialect-name) "S+")
-                                              "stata" (or (bound-and-true-p STA-dialect-name) "stata")
-                                              "julia" "SAS")))))
-         (pname-list (delq nil ;; keep only those matching dialect and `ess-gen-proc-buffer-name-function'
-                           (append
-                            (mapcar (lambda (lproc)
-                                      (and (equal ess-dialect
-                                                  (buffer-local-value
-                                                   'ess-dialect
-                                                   (process-buffer (get-process (car lproc)))))
-                                           (not (equal ess-local-process-name (car lproc)))
-                                           (car lproc)))
-                                    ess-process-name-list)
-                            ;; append local only if running
-                            (when (assoc ess-local-process-name ess-process-name-list)
-                              (list ess-local-process-name)))))
-         (num-processes (length pname-list))
-         proc auto-started?)
-    (when (or (= 0 num-processes)
-              (and (= 1 num-processes)
-                   (not (equal ess-dialect ;; don't auto connect if from different dialect
-                               (buffer-local-value
-                                'ess-dialect
-                                (process-buffer (get-process
-                                                 (car pname-list))))))))
-      ;; Try to start "the appropriate" process, don't show the buffer
-      ;; since we handle that explicitly with no-switch
-      (ess-if-verbose-write
-       "ess-request-a-process: Can't find a process, starting a new one\n")
-      (ess--with-no-pop-to-buffer
-        (ess-start-process-specific ess-language ess-dialect))
-      (setq num-processes 1
-            pname-list (car ess-process-name-list)
-            auto-started? t))
-    ;; now num-processes >= 1 :
-    (let* ((proc-buffers (mapcar (lambda (lproc)
-                                   (buffer-name (process-buffer (get-process lproc))))
-                                 pname-list)))
-      (setq proc
-            (if (or auto-started?
-                    (and (not ask-if-1)
-                         (= 1 num-processes)
-                         (message "Using process `%s'" (car proc-buffers))))
-                (car pname-list)
-              (unless (and ess-current-process-name
-                           (get-process ess-current-process-name))
-                (setq ess-current-process-name nil))
-              ;; ask for buffer name not the *real* process name:
-              (let ((buf (ess-completing-read message (append proc-buffers (list "*new*")) nil t nil nil)))
-                (if (not (equal buf "*new*"))
-                    (process-name (get-buffer-process buf))
-                  ;; Prevent new process buffer from being popped
-                  ;; because we handle display depending on the value
-                  ;; of `no-switch`
-                  (ess-if-verbose-write
-                   "ess-request-a-process: User requested a new process\n")
-                  (ess--with-no-pop-to-buffer
-                    (ess-start-process-specific ess-language ess-dialect))
-                  (caar ess-process-name-list))))))
-    ;; Always display buffer if auto-started but do not select it if
-    ;; NOSWITCH is set
-    (when (or auto-started? (not noswitch))
-      (let ((proc-buf (ess-get-process-buffer proc)))
-        (if noswitch
-            (display-buffer proc-buf)
-          (pop-to-buffer proc-buf))
-        ;; If inferior startup has already finished, set screen
-        ;; options again in case the post-run hook ran before a new
-        ;; screen config was created by `pop-to-buffer' (#1243).
-        (with-current-buffer proc-buf
-          (ess--execute-screen-options-bg))))
-    proc))
-
-(defun ess-force-buffer-current (&optional prompt force no-autostart ask-if-1)
-  "Make sure the current buffer is attached to an ESS process.
-If not, or FORCE (prefix argument) is non-nil, prompt for a
-process name with PROMPT. If NO-AUTOSTART is nil starts the new
-process if process associated with current buffer has
-died. `ess-local-process-name' is set to the name of the process
-selected.  `ess-dialect' is set to the dialect associated with
-the process selected. ASK-IF-1 asks user for the process, even if
-there is only one process running.  Returns the inferior buffer if
-it was successfully forced, throws an error otherwise."
-  (interactive
-   (list (concat ess-dialect " process to use: ") current-prefix-arg nil))
-  (let ((proc-name (ess-make-buffer-current)))
-    (cond ((and (not force) proc-name (get-process proc-name)))
-          ;; Make sure the source buffer is attached to a process
-          ((and ess-local-process-name (not force) no-autostart)
-           (error "Process %s has died" ess-local-process-name))
-          ;; Request a process if `ess-local-process-name' is nil
-          (t
-           (let* ((prompt (or prompt "Process to use: "))
-                  (proc (ess-request-a-process prompt 'no-switch ask-if-1)))
-             (setq ess-local-process-name proc)))))
-  (process-buffer (get-process ess-local-process-name)))
-
-(defalias 'inferior-ess-force #'ess-force-buffer-current)
-
-(defun ess-switch-process ()
-  "Force a switch to a new underlying process."
-  (interactive)
-  (ess-force-buffer-current "Process to use: " 'force nil 'ask-if-1))
-
-(defun ess-get-current-process ()
-  (when ess-local-process-name
-    (get-process ess-local-process-name)))
-
-(defun ess-get-current-process-buffer ()
-  (when-let ((proc (ess-get-current-process)))
-    (process-buffer proc)))
-
-(defun ess-get-next-available-process (&optional dialect ignore-busy background)
-  "Return first available (aka not busy) process of dialect DIALECT.
-DIALECT defaults to the local value of ess-dialect. Return nil if
-no such process has been found. If BACKGROUND is non-nil, only
-processes that are allowed to evaluate in the background are
-matched."
-  (setq dialect (or dialect ess-dialect))
-  (when (and dialect (or (not background)
-                         ess-can-eval-in-background))
-    (let (proc)
-      (catch 'found
-        (dolist (p (cons ess-local-process-name
-                         (mapcar #'car ess-process-name-list)))
-          (when p
-            (setq proc (get-process p))
-            (when (and proc
-                       (process-live-p proc)
-                       (equal dialect
-                              (buffer-local-value 'ess-dialect (process-buffer proc)))
-                       ;; Check that we can evaluate in background
-                       ;; before checking for availability to
-                       ;; avoid issues with newline handshakes
-                       (or (not background)
-                           (ess-can-eval-in-background proc))
-                       (or ignore-busy
-                           (inferior-ess-available-p proc)))
-              (throw 'found proc))))))))
-
-(defun ess-get-next-available-bg-process (&optional proc dialect ignore-busy)
-  "Returns first avaiable process only if background evaluations are allowed.
-Same as `ess-get-next-available-process' but checks for
-`ess-can-eval-in-background'."
-  (if proc
-      (ess-can-eval-in-background proc)
-    (ess-get-next-available-process dialect ignore-busy 'background)))
-
-
-;;*;;; Commands for switching to the process buffer
-
-(defun ess-switch-to-ESS (eob-p)
-  "Switch to the current inferior ESS process buffer.
-With (prefix) EOB-P non-nil, positions cursor at end of buffer."
-  (interactive "P")
-  (ess-force-buffer-current)
-  (pop-to-buffer (buffer-name (process-buffer (get-process ess-current-process-name)))
-                 '(nil . ((inhibit-same-window . t))))
-  (when eob-p (goto-char (point-max))))
-
-(defun ess-switch-to-end-of-ESS ()
-  "Switch to the end of the inferior ESS process buffer."
-  (interactive)
-  (ess-switch-to-ESS t))
-
-(defun ess-switch-to-inferior-or-script-buffer (toggle-eob)
-  "Switch between script and process buffer.
-This is a single-key command. Assuming that it is bound to C-c
-C-z, you can navigate back and forth between iESS and script
-buffer with C-c C-z C-z C-z ... If variable
-`ess-switch-to-end-of-proc-buffer' is t (the default) this
-function switches to the end of process buffer. If TOGGLE-EOB is
-given, the value of `ess-switch-to-end-of-proc-buffer' is
-toggled."
-  (interactive "P")
-  (let ((eob (if toggle-eob
-                 (not ess-switch-to-end-of-proc-buffer)
-               ess-switch-to-end-of-proc-buffer)))
-    (if (derived-mode-p 'inferior-ess-mode)
-        (let ((dialect ess-dialect)
-              (proc-name ess-local-process-name)
-              (blist (buffer-list)))
-          (while (and (pop blist)
-                      (with-current-buffer (car blist)
-                        (not (or (and (ess-derived-mode-p)
-                                      (equal dialect ess-dialect)
-                                      (null ess-local-process-name))
-                                 (and (ess-derived-mode-p)
-                                      (equal proc-name ess-local-process-name)))))))
-          (if blist
-              (pop-to-buffer (car blist))
-            (message "Found no buffers for `ess-dialect' %s associated with process %s"
-                     dialect proc-name)))
-      (ess-switch-to-ESS eob))
-    (when (called-interactively-p 'any)
-      (set-transient-map (let ((map (make-sparse-keymap))
-                               (key (vector last-command-event)))
-                           (define-key map key #'ess-switch-to-inferior-or-script-buffer) map)))))
-
-
-(defun ess-get-process-buffer (&optional name)
-  "Return the buffer associated with the ESS process named by NAME."
-  (process-buffer (ess-get-process (or name ess-local-process-name))))
-
-(defun update-ess-process-name-list ()
-  "Remove names with no process."
-  (let (defunct)
-    (dolist (conselt ess-process-name-list)
-      (let ((proc (get-process (car conselt))))
-        (unless (and proc (eq (process-status proc) 'run))
-          (push conselt defunct))))
-    (dolist (pointer defunct)
-      (setq ess-process-name-list (delq pointer ess-process-name-list))))
-  (if (eq (length ess-process-name-list) 0)
-      (setq ess-current-process-name nil)))
-
-\f
-;;; Functions for evaluating code
-
-;;*;; Utils for evaluation
-
-(defun ess-build-eval-command (string &optional visibly output file &rest args)
-  "Format an evaluation command.
-Wrap STRING with `ess-quote-special-chars' and dispatch on
-`ess-build-eval-command--override'."
-  (setq string (ess-quote-special-chars string))
-  (ess-build-eval-command--override string visibly output file args))
-
-(cl-defgeneric ess-build-eval-command--override
-    (string &optional _visibly _output file &rest _args)
-  "Default method to build eval command."
-  (and ess-eval-command
-       (format-spec ess-eval-command
-                    `((?s . ,string)
-                      (?f . ,file)))))
-
-(cl-defgeneric ess-build-load-command (file &optional _visibly _output &rest _args)
-  "Format a loading command.
-Dispatches on the dialect-specific `ess-build-load-command'
-and `ess-load-command', in that order."
-  (and ess-load-command
-       (format ess-load-command file)))
-
-(defun ess-wait-for-process (&optional proc sec-prompt wait force-redisplay timeout)
-  "Wait for \\='busy property of the process to become nil.
-If SEC-PROMPT is non-nil return if secondary prompt is detected
-regardless of whether primary prompt was detected or not. If WAIT
-is non-nil wait for WAIT seconds for process output before the
-prompt check, default 0.002s. When FORCE-REDISPLAY is non-nil
-force redisplay. You better use WAIT >= 0.1 if you need
-FORCE-REDISPLAY to avoid excessive redisplay. If TIMEOUT is
-non-nil stop waiting for output after TIMEOUT seconds.
-
-Returns nil if TIMEOUT was reached, non-nil otherwise."
-  (setq proc (or proc (get-process ess-local-process-name)))
-  (setq wait (or wait 0.005))
-  (setq timeout (or timeout most-positive-fixnum))
-  (let ((start-time (float-time))
-        (elapsed 0))
-    (save-excursion
-      (while (and
-              (or (eq (process-status proc) 'run)
-                  (progn
-                    (when (process-buffer proc)
-                      (display-buffer (process-buffer proc)))
-                    (error "ESS process has died unexpectedly")))
-              (< elapsed timeout)
-              (or (accept-process-output proc wait)
-                  (unless (and sec-prompt (process-get proc 'sec-prompt))
-                    (process-get proc 'busy))))
-        (when force-redisplay
-          (redisplay 'force))
-        (setq elapsed (- (float-time) start-time))
-        (when (>  elapsed .3)
-          (setq wait .3))))
-    (< elapsed timeout)))
-
-;; This filter is active under `ess-command`
-(defun inferior-ess-ordinary-filter (proc string)
-  (ess--if-verbose-write-process-state proc string "ordinary-filter")
-  (let* ((cmd-buf (process-get proc 'cmd-buffer))
-         (cmd-delim (process-get proc 'cmd-output-delimiter)))
-    (when (buffer-live-p cmd-buf)
-      (ess--exit-protect
-          (progn
-            (with-current-buffer cmd-buf
-              (goto-char (point-max))
-              (insert string))
-            (if-let ((info (if cmd-delim
-                               (ess--command-delimited-output-info cmd-buf cmd-delim)
-                             (ess--command-output-info cmd-buf))))
-                (let ((new-output (ess--command-set-status proc cmd-buf info)))
-                  (ess-if-verbose-write
-                   "ess-command (filter): Found prompt\n")
-                  (when (not (process-get proc 'busy))
-                    ;; Store new output until restoration
-                    (when new-output
-                      (process-put proc 'pending-output new-output))
-                    ;; Restore the user's process filter as soon as process is
-                    ;; available
-                    (funcall (process-get proc 'cmd-restore-function))
-                    ;; Run callback with command output
-                    (when (process-get proc 'callbacks)
-                      (inferior-ess-run-callback proc (with-current-buffer cmd-buf
-                                                        (buffer-string))))))
-              (ess-if-verbose-write
-               "ess-command (filter): Accumulating output\n")))
-        ;; Be defensive when something goes wrong. Restore process to a
-        ;; usable state.
-        (ess-if-verbose-write
-         "ess-command (filter): Early exit\n")
-        (process-put proc 'busy nil)
-        (funcall (process-get proc 'cmd-restore-function))))))
-
-(defvar ess-presend-filter-functions nil
-  "List of functions to call before sending the input string to the process.
-Each function gets one argument, a string containing the text to
-be send to the subprocess.  It should return the string sent,
-perhaps the same string that was received, or perhaps a modified
-or transformed string.
-
-The functions on the list are called sequentially, and each one
-is given the string returned by the previous one. The string
-returned by the last function is the text that is actually sent
-to the process. You can use `add-hook' to add functions to this
-list either globally or locally. The hook is executed in current
-buffer. Before execution, the local value of this hook in the
-process buffer is appended to the hook from the current buffer.")
-
-(defvar ess--inhibit-presend-hooks nil
-  "If non-nil don't run presend hooks.")
-
-(defun ess--run-presend-hooks (process string)
-  ;; run ess-presend-filter-functions and comint-input-filter-functions
-  (if ess--inhibit-presend-hooks
-      string
-    ;;return modified string
-    (let* ((pbuf (process-buffer process))
-           ;; also run proc buffer local hooks
-           (functions (unless (eq pbuf (current-buffer))
-                        (buffer-local-value 'ess-presend-filter-functions pbuf))))
-      (setq functions (append  (delq t (copy-sequence functions)) ;; even in let, delq destructs
-                               ess-presend-filter-functions))
-      (while (and functions string)
-        ;; cannot use run-hook-with-args here because string must be passed from one
-        ;; function to another
-        (if (eq (car functions) t)
-            (let ((functions
-                   (default-value 'ess-presend-filter-functions)))
-              (while (and functions string)
-                (setq string (funcall (car functions) string))
-                (setq functions (cdr functions))))
-          (setq string (funcall (car functions) string)))
-        (setq functions (cdr functions)))
-      (with-current-buffer pbuf
-        (run-hook-with-args 'comint-input-filter-functions string))
-      string)))
-
-(defun ess--concat-new-line-maybe (string)
-  "Append \\n at the end of STRING if missing."
-  (if (string-match "\n\\'" string (max (- (length string) 2) 0))
-      string
-    (concat string "\n")))
-
-(defvar ess--dbg-del-empty-p t
-  "Internal variable to control removal of empty lines during the debugging.
-Let-bind it to nil before calling `ess-send-string' or
-`ess-send-region' if no removal is necessary.")
-
-(defun inferior-ess--interrupt-subjob-maybe (proc)
-  "Internal. Interrupt the process if interruptable? process variable is non-nil.
-Hide all the junk output in temporary buffer."
-  (when (process-get proc 'interruptable?)
-    (let ((cb (cadr (process-get proc 'callbacks)))
-          (buf (get-buffer-create " *ess-temp-buff*"))
-          (old-filter (process-filter proc))
-          (old-buff (process-buffer proc)))
-      (unwind-protect
-          (progn
-            (ess-if-verbose-write "interrupting subjob ... start")
-            (process-put proc 'interruptable? nil)
-            (process-put proc 'callbacks nil)
-            (process-put proc 'running-async? nil)
-            ;; this is to avoid putting junk in user's buffer on process
-            ;; interruption
-            (set-process-buffer proc buf)
-            (set-process-filter proc #'inferior-ess-ordinary-filter)
-            (interrupt-process proc)
-            (when cb
-              (ess-if-verbose-write "executing interruption callback ... ")
-              (funcall cb proc))
-            ;; should be very fast as it inputs only the prompt
-            (ess-wait-for-process proc)
-            (ess-if-verbose-write "interrupting subjob ... finished")
-            )
-        (set-process-buffer proc old-buff)
-        (set-process-filter proc old-filter)))))
-
-\f
-;;*;; Evaluation primitives
-
-(defun ess-send-string (process string &optional visibly message _type)
-  "ESS wrapper for `process-send-string'.
-Run `comint-input-filter-functions' and current buffer's and
-PROCESS' `ess-presend-filter-functions' hooks on the input
-STRING. VISIBLY can be nil, t, \\='nowait or a string.  If string
-the behavior is as with \\='nowait with the differences that
-inserted string is VISIBLY instead of STRING (evaluated command
-is still STRING).  In all other cases the behavior is as
-described in `ess-eval-visibly'. STRING need not end with
-\\n. TYPE is a symbol indicating type of the string.
-MESSAGE is a message to display."
-  ;; No support of `visibly' when there's no secondary prompt
-  (let ((visibly (if (and (eq visibly t)
-                          (null inferior-ess-secondary-prompt))
-                     'nowait
-                   visibly))
-        (string (ess--run-presend-hooks process string)))
-    (inferior-ess--interrupt-subjob-maybe process)
-    (inferior-ess-mark-as-busy process)
-    (process-put process 'last-eval (current-time))
-    (cond
-     ;; Wait after each line
-     ((eq visibly t)
-      (let ((ess--inhibit-presend-hooks t))
-        (ess-eval-linewise string)))
-     ;; Insert command and eval invisibly
-     ((or (stringp visibly)
-          (eq visibly 'nowait))
-      (with-current-buffer (process-buffer process)
-        (save-excursion
-          (goto-char (process-mark process))
-          (insert-before-markers
-           (propertize (format "%s\n"
-                               (replace-regexp-in-string
-                                "\n" "\n+ "
-                                (if (stringp visibly) visibly string)))
-                       'font-lock-face 'comint-highlight-input)))
-        (process-send-string process (ess--concat-new-line-maybe string))))
-     (t
-      (process-send-string process (ess--concat-new-line-maybe string))))
-    (when message
-      (message "%s" message))))
-
-(defun ess-send-region (process start end &optional visibly message type)
-  "Low level ESS version of `process-send-region'.
-If VISIBLY call `ess-eval-linewise', else call
-`ess-send-string'. If MESSAGE is supplied, display it at the
-end. Run current buffer's and PROCESS'
-`ess-presend-filter-functions' hooks. TYPE is a symbol indicating
-type of the region."
-  (cond
-   ((ess-tracebug-p)
-    (ess-tracebug-send-region process start end visibly message type))
-   (t (ess-send-region--override process start end visibly message type))))
-
-(cl-defgeneric ess-send-region--override (process start end visibly message type)
-  (ess-send-string process (buffer-substring start end) visibly message type))
-
-\f
-;;*;; Evaluation commands
-
-(defun ess-load-file--normalise-file (file)
-  "Handle Tramp and system peculiarities."
-  (require 'tramp)
-  (let* ((file (if (tramp-tramp-file-p file)
-                   (tramp-file-name-localname (tramp-dissect-file-name file))
-                 file))
-         (file (if ess-microsoft-p
-                   (ess-replace-in-string file "[\\]" "/")
-                 file)))
-    (abbreviate-file-name file)))
-
-(defun ess-load-file--normalise-buffer (file)
-  (when (ess-save-file file)
-    (error "Buffer %s has not been saved" (buffer-name file)))
-  (let ((source-buffer (get-file-buffer file)))
-    (if source-buffer
-        (with-current-buffer source-buffer
-          (when (buffer-modified-p) (save-buffer))
-          (ess-force-buffer-current "Process to load into: "))
-      (ess-force-buffer-current "Process to load into: "))))
-
-;;;###autoload
-(defun ess-load-file (&optional filename)
-  "Load FILENAME into an inferior ESS process.
-This handles Tramp when working on a remote."
-  (interactive (list (or (and (ess-derived-mode-p)
-                              (buffer-file-name))
-                         (expand-file-name
-                          (read-file-name "Load source file: " nil nil t)))))
-  (ess-load-file--normalise-buffer filename)
-  (setq filename (ess-load-file--normalise-file filename))
-  (ess-load-file--override filename)
-  (message "Loaded %s" filename))
-
-(cl-defgeneric ess-load-file--override (filename)
-  (let ((command (ess-build-load-command filename nil t)))
-    (ess-send-string (ess-get-process) command t)))
-
-;; ;;; VS[03-09-2012]: Test Cases:
-;; (ess-command "a<-0\n" nil nil nil nil (get-process "R"))
-;; (ess-async-command-delayed "Sys.sleep(5);a<-a+1;cat(1:10)\n" nil
-;;                            (get-process "R") (lambda (proc) (message "done")))
-;; (ess-async-command-delayed "Sys.sleep(5)\n" nil (get-process "R")
-;;                            (lambda (proc) (message "done")))
-;; (process-get (get-process "R") 'running-async?)
-
-(defun ess-command--get-proc (proc no-prompt-check)
-  (if proc
-      (unless ess-local-process-name
-        (setq ess-local-process-name (process-name proc)))
-    (setq proc (ess-get-process ess-local-process-name)))
-  (unless no-prompt-check
-    (when (process-get proc 'busy)
-      (user-error "ESS process not ready. Finish your command before trying again")))
-  proc)
-
-(defvar inferior-ess--output-delimiter-count 0)
-(defun inferior-ess--output-delimiter ()
-  (setq inferior-ess--output-delimiter-count (1+ inferior-ess--output-delimiter-count))
-  (format "ess-output-delimiter%s" inferior-ess--output-delimiter-count))
-
-(defvar ess--command-default-timeout most-positive-fixnum)
-
-;; NOTE: We might want to switch to something like `cl-defun' with
-;; keyword arguments given the length of the signature. Would also
-;; make it easier to deprecate arguments.
-(defun ess-command (cmd &optional out-buffer _sleep no-prompt-check wait proc
-                        force-redisplay timeout)
-  "Send the ESS process CMD and delete the output from the ESS process buffer.
-If an optional second argument OUT-BUFFER exists save the output
-in that buffer. OUT-BUFFER is erased before use. CMD should have
-a terminating newline. Guarantees that the value of `.Last.value'
-will be preserved.
-
-`ess-command' is executes CMD in the background synchronously,
-meaning that the Emacs UI blocks while CMD is running. Make sure
-that CMD returns immediately. Blocking the UI for more than 0.1
-seconds should generally be considered a bug.
-
-SLEEP is deprecated and no longer has any effect. WAIT,
-FORCE-REDISPLAY, and TIMEOUT are as in `ess-wait-for-process' and
-are passed to `ess-wait-for-process'. The default timeout is 30
-seconds. The process is interrupted with `interrupt-process' when
-the timeout is reached or when an error occurs.
-
-PROC should be a process, if nil the process name is taken from
-`ess-local-process-name'.  This command doesn't set \\='last-eval
-process variable.
-
-Note: for critical, or error prone code you should consider
-wrapping the code into:
-
- local({
-    olderr <- options(error=NULL)
-    on.exit(options(olderr))
-    ...
- })"
-  (let ((out-buffer (or out-buffer (get-buffer-create " *ess-command-output*")))
-        (proc (ess-command--get-proc proc no-prompt-check))
-        (delim (inferior-ess--output-delimiter))
-        (timeout (or timeout ess--command-default-timeout)))
-    (with-current-buffer (process-buffer proc)
-      (let* ((proc-forward-alist (ess--alist (ess-local-process-name
-                                              inferior-ess-primary-prompt)))
-             (format-command-alist (ess-process-get 'format-command-alist))
-             (use-delimiter (alist-get 'use-delimiter format-command-alist))
-             (rich-cmd (if-let ((cmd-fun (alist-get 'fun format-command-alist)))
-                           (funcall cmd-fun
-                                    (ess--strip-final-newlines cmd)
-                                    (cons 'output-delimiter delim))
-                         cmd))
-             (early-exit t))
-        (ess-if-verbose-write (format "(ess-command '%s' ..)\n" cmd))
-        ;; Swap the process buffer with the output buffer before
-        ;; sending the command
-        (unwind-protect
-            (condition-case err
-                (progn
-                  ;; The process is restored from the filter once it's
-                  ;; available again (i.e. a prompt or delimiter is
-                  ;; detected). This handles the synchronous case when the
-                  ;; command runs to completion, as well as the
-                  ;; asynchronous case when an early exit occurs. The most
-                  ;; common cause of early exits are interrupts sent by
-                  ;; Emacs when the user types (see `when-no-input'). In
-                  ;; these cases we forward the interrupt to the process
-                  ;; and return to the caller right away. We can't restore
-                  ;; synchronously after an interrupt because the output
-                  ;; of the background command would spill into the
-                  ;; process buffer of the user when the process doesn't
-                  ;; interrupt in time.
-                  (process-put proc 'cmd-restore-function
-                               (ess--command-make-restore-function proc))
-                  (when use-delimiter
-                    (process-put proc 'cmd-output-delimiter delim))
-                  (process-put proc 'cmd-buffer out-buffer)
-                  (set-process-filter proc #'inferior-ess-ordinary-filter)
-                  (with-current-buffer out-buffer
-                    (ess-setq-vars-local proc-forward-alist)
-                    (setq buffer-read-only nil)
-                    (erase-buffer)
-                    (inferior-ess-mark-as-busy proc)
-                    (process-send-string proc rich-cmd)
-                    ;; Need time for ess-create-object-name-db on PC
-                    (if no-prompt-check
-                        (sleep-for 0.02) ; 0.1 is noticeable!
-                      (unless (ess-wait-for-process proc nil wait force-redisplay timeout)
-                        (error "Timeout during background ESS command `%s'"
-                               (ess--strip-final-newlines cmd))))
-                    (setq early-exit nil)))
-              (error (setq early-exit err))
-              (quit (setq early-exit err)))
-          (if early-exit
-              (ess--command-error-handler proc out-buffer use-delimiter delim early-exit)
-            (with-current-buffer out-buffer
-              (goto-char (point-min))
-              (when (re-search-forward (ess--delimiter-error-start-re) nil t)
-                (let ((start (1+ (match-beginning 1))))
-                  (when (re-search-forward (ess--delimiter-error-end-re) nil t)
-                    (let ((end (match-beginning 1)))
-                      (error "R error during background ESS command `%s'\nError: %s"
-                             (ess--strip-final-newlines cmd)
-                             (buffer-substring start end)))))))))))
-    out-buffer))
-
-(defun ess--command-error-handler (proc
-                                   out-buffer
-                                   use-delimiter
-                                   delim
-                                   early-exit)
-  (let ((inhibit-quit t))
-    ;; In case of early exit send an interrupt to the
-    ;; process to abort the command
-    (with-current-buffer out-buffer
-      (goto-char (point-min))
-      (when (and use-delimiter
-                 (not (re-search-forward (ess--delimiter-start-re delim) nil t)))
-        ;; CMD probably failed to parse if the start delimiter
-        ;; can't be found in the output. Disable the delimiter
-        ;; before interrupt to avoid a freeze.
-        (ess-write-to-dribble-buffer
-         "Disabling output delimiter because CMD failed to parse\n")
-        (process-put proc 'cmd-output-delimiter nil))
-      (goto-char (point-max))
-      (ess--interrupt proc)))
-  ;; Can be `t` when early exit is caused e.g. by a throw instead of
-  ;; an error or a quit. This happens in tests and within
-  ;; `while-no-input'.
-  (unless (eq early-exit t)
-    (when (and (eq (car early-exit) 'quit)
-               (y-or-n-p (concat "Background background command interrupted with a user quit.\n"
-                                 "Would you like to disable background evaluations in this process?")))
-      (process-put proc 'bg-eval-disabled t))
-    (signal (car early-exit) (cdr early-exit))))
-
-;; (ess-process-get 'ess-format-command-alist)
-;;   "Alist of mode-specific parameters for formatting a command.
-;; All elements are optional.
-;;
-;; - `fun': A formatting function for running a command. First
-;;   argument is the background command to run. Must include a
-;;   catch-all `&rest` parameter for extensibility.
-;;
-;; - `use-delimiter' : Whether to wait for an output sentinel. If
-;;   non-nil, `fun' should get the `cmd-output-delimiter' element of the
-;;   alist of parameters and ensure the sentinel is written to the
-;;   process output at the end of the command."
-
-(defun ess--command-make-restore-function (proc)
-  (let ((old-pf (process-filter proc)))
-    (lambda ()
-      (set-process-filter proc old-pf)
-      (process-put proc 'cmd-output-delimiter nil)
-      (process-put proc 'cmd-buffer nil)
-      (when-let ((pending (process-get proc 'pending-output)))
-        (process-put proc 'pending-output nil)
-        (funcall old-pf proc pending)))))
-
-;; TODO: Needs some Julia tests as well
-(defun ess--foreground-command (cmd &optional out-buffer _sleep no-prompt-check wait proc)
-  "Same as `ess-command' but does not timeout.
-Currently blocks the Emacs UI. Eventually it would make sense to
-lock the inferior to prevent interactions and use
-`ess-async-command' with a callback."
-  (let ((timeout most-positive-fixnum))
-    (ess-command cmd out-buffer nil no-prompt-check wait proc nil timeout)))
-
-(defun ess-boolean-command (com &optional buf wait)
-  "Like `ess-command' but expects COM to print TRUE or FALSE.
-If TRUE (or true) is found return non-nil otherwise nil.
-Example (ess-boolean-command \"2>1\n\")"
-  (with-current-buffer (ess-command com buf nil nil wait)
-    (goto-char (point-min))
-    (let ((case-fold-search t))
-      (re-search-forward "true" nil t))))
-
-(defun ess-string-command (com &optional buf wait)
-  "Returns the output of COM as a string."
-  (with-current-buffer (ess-command com buf nil nil wait)
-    (buffer-substring (point-min) (point-max))))
-
-(defun ess-async-command (com &optional buf proc callback interrupt-callback)
-  "Asynchronous version of `ess-command'.
-COM, BUF, WAIT and PROC are as in `ess-command'.
-
-CALLBACK is a function of two arguments (PROC STRING) to run
-after the successful execution. When INTERRUPT-CALLBACK is
-non-nil, user evaluation can interrupt the
-job. INTERRUPT-CALLBACK should be either t or a function of one
-argument (PROC) to be called on interruption.
-
-NOTE: Currently this function should be used only for background
-jobs like caching. ESS tries to suppress any output from the
-asynchronous command, but long output of COM will most likely end
-up in user's main buffer."
-  (setq proc (or proc (get-process ess-local-process-name)))
-  (cond ((not (and proc (eq (process-status proc) 'run)))
-         (error "Process %s is dead" proc))
-        ((process-get proc 'busy)
-         (error "Process %s is busy" proc))
-        ((process-get proc 'running-async?)
-         (error "Process %s is already running an async command" proc)))
-  (when (eq interrupt-callback t)
-    (setq interrupt-callback (lambda (_proc))))
-  (process-put proc 'callbacks (list (cons callback 'suppress-output)
-                                     interrupt-callback))
-  (process-put proc 'interruptable? (and interrupt-callback t))
-  (process-put proc 'running-async? t)
-  (ess-command com buf nil 'no-prompt-check .01 proc))
-
-(defun ess-async-command-delayed (com buf proc &optional callback delay)
-  "Delayed asynchronous ess-command.
-COM and BUF are as in `ess-command'. DELAY is a number of idle
-seconds to wait before starting the execution of the COM. On
-interruption (by user's evaluation) ESS tries to rerun the job
-after next DELAY seconds, and the whole process repeats itself
-until the command manages to run completely. DELAY defaults to
-`ess-idle-timer-interval' + 3 seconds. You should always provide
-PROC for delayed evaluation, as the current process might change,
-leading to unpredictable consequences. This function is a wrapper
-of `ess-async-command' with an explicit interrupt-callback."
-  (let* ((delay (or delay
-                    (+ ess-idle-timer-interval 3)))
-         (int-cb  `(lambda (proc)
-                     (ess-async-command-delayed ,com ,buf proc ,callback ,delay)))
-         (com-fun `(lambda ()
-                     (when (eq (process-status ,proc)  'run) ; do nothing if not running
-                       (if (or (process-get ,proc 'busy) ; if busy, try later
-                               (process-get ,proc 'running-async?))
-                           ;; idle timer doesn't work here
-                           (run-with-timer ,delay nil 'ess-async-command-delayed
-                                           ,com ,buf ,proc ,callback ,delay))
-                       (ess-async-command ,com ,buf ,proc ,callback ',int-cb)))))
-    (run-with-idle-timer delay nil com-fun)))
-
-(defun ess-load-library ()
-  "Prompt and load dialect specific library/package/module.
-Note that in R these are called `packages' and the name of this
-function has nothing to do with R package mechanism, but it
-rather serves a generic, dialect independent purpose. It is also
-similar to `load-library' Emacs function."
-  (interactive)
-  (let ((ess-eval-visibly-p t)
-        (packs (ess-installed-packages))
-        pack)
-    (setq pack (ess-completing-read "Load" packs))
-    (ess-load-library--override pack)
-    (ess--mark-search-list-as-changed)))
-
-(cl-defgeneric ess-installed-packages ()
-  "Return a list of installed packages.")
-
-(cl-defgeneric ess-load-library--override (pack)
-  "Load library/package PACK.")
-
-\f
-;;*;;  Evaluating lines, paragraphs, regions, and buffers.
-
-(defun ess-eval-linewise (text &optional invisibly eob even-empty
-                               wait-last-prompt sleep-sec wait-sec)
-  "Evaluate TEXT in the ESS process buffer as if typed in w/o tabs.
-Waits for prompt after each line of input, so won't break on large texts.
-
-If optional second arg INVISIBLY is non-nil, don't echo commands.
-If it is a string, just include that string. If optional third
-arg EOB is non-nil, display ESS process buffer after evaluation.
-If optional 4th arg EVEN-EMPTY is non-nil, also send empty
-text (e.g. an empty line). If 5th arg WAIT-LAST-PROMPT is
-non-nil, also wait for the prompt after the last line; if 6th arg
-SLEEP-SEC is a number, ESS will call `(\\[sleep-for] SLEEP-SEC)'
-at the end of this function. If the 7th arg WAIT-SEC is set, it
-will be used instead of the default .001s and be passed to
-\\[ess-wait-for-process].
-
-Run `comint-input-filter-functions' and
-`ess-presend-filter-functions' of the associated PROCESS on the
-TEXT."
-  (ess-force-buffer-current "Process to use: ")
-  ;; Use this to evaluate some code, but don't wait for output.
-  (let* ((deactivate-mark)           ; keep local {do *not* deactivate wrongly}
-         (inf-proc (ess-get-process ess-current-process-name))
-         (inf-buf (process-buffer inf-proc))
-         (win (get-buffer-window inf-buf t)))
-    (setq text (ess--concat-new-line-maybe
-                (ess--run-presend-hooks inf-proc text)))
-    (with-current-buffer inf-buf
-      (setq text (propertize text 'field 'input 'front-sticky t))
-      (goto-char (marker-position (process-mark inf-proc)))
-      (when (stringp invisibly)
-        (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))
-      (while (or (> (length text) 0) even-empty)
-        (setq even-empty nil)
-        (let* ((pos (string-match "\n\\|$" text))
-               (input (if (= (length text) 0)
-                          "\n"
-                        (concat (substring text 0 pos) "\n"))))
-          (setq text (substring text (min (length text) (1+ pos))))
-          (goto-char (marker-position (process-mark inf-proc)))
-          (when win
-            (set-window-point win (process-mark inf-proc)))
-          (unless invisibly
-            ;; for consistency with comint :(
-            (insert (propertize input 'font-lock-face 'comint-highlight-input))
-            (set-marker (process-mark inf-proc) (point)))
-          (inferior-ess-mark-as-busy inf-proc)
-          (process-send-string inf-proc input))
-        (when (or (> (length text) 0)
-                  wait-last-prompt)
-          (ess-wait-for-process inf-proc t (or wait-sec 0.001))))
-      (when eob
-        (display-buffer inf-buf))
-      ;; This used to be conditioned on EOB but this is no longer the
-      ;; case since commit fd90550d in 2012 (probably an accident)
-      (goto-char (marker-position (process-mark inf-proc)))
-      (when win
-        (with-selected-window win
-          (goto-char (point))
-          ;; this is crucial to avoid resetting window-point
-          (recenter (- -1 scroll-margin))))))
-  (when (numberp sleep-sec)
-    (sleep-for sleep-sec)))
-
-\f
-;;;*;;; Evaluate only
-
-(defun ess-eval-region--normalise-region (start end)
-  "Clean the region from START to END for evaluation.
-This trims newlines at beginning and end of the region because
-they might throw off the debugger."
-  (save-excursion
-    (goto-char start)
-    (skip-chars-forward "\n\t ")
-    (setq start (point))
-    (unless mark-active
-      (ess-blink-region start end))
-    (goto-char end)
-    (skip-chars-backward "\n\t ")
-    (setq end (point))
-    (cons start end)))
-
-(defun ess-eval-region (start end vis &optional message type)
-  "Send the region from START to END to the inferior ESS process.
-VIS switches the meaning of `ess-eval-visibly'. If given,
-MESSAGE is `message'ed. TYPE is a symbol indicating what type of
-region this is. If command `rectangle-mark-mode' is active, send
-the lines of the rectangle separately to the inferior process."
-  (interactive "r\nP")
-  (ess-force-buffer-current "Process to use: ")
-  (message "Starting evaluation...")
-  (unless ess-local-customize-alist
-    ;; External applications might call ess-eval-* functions; make it
-    ;; easier for them
-    (ess-setq-vars-local (symbol-value (ess-get-process-variable 'ess-local-customize-alist))))
-  (if (bound-and-true-p rectangle-mark-mode)
-      ;; If we're in rectangle-mark-mode, loop over each line of the
-      ;; rectangle. Send them separately.
-      (let ((reclines (extract-rectangle-bounds (min (mark) (point)) (max (mark) (point)))))
-        (mapc (lambda (l)
-                (ess--eval-region (car l) (cdr l) vis message type))
-              reclines))
-    (ess--eval-region start end vis message type)))
-
-(defun ess--eval-region (start end vis &optional message type)
-  "Helper function for `ess-eval-region', which see.
-START, END, VIS, MESSAGE, and TYPE described there."
-  (let* ((se (ess-eval-region--normalise-region start end))
-         (start (car se))
-         (end (cdr se)))
-    (let ((visibly (if vis (not ess-eval-visibly) ess-eval-visibly))
-          (message (or message "Eval region"))
-          (proc (ess-get-process)))
-      (save-excursion
-        (ess-send-region proc start end visibly message type)))
-    (when ess-eval-deactivate-mark
-      (ess-deactivate-mark))
-    (list start end)))
-
-(defun ess-eval-buffer (&optional vis)
-  "Send the current buffer to the inferior ESS process.
-VIS has same meaning as for `ess-eval-region'."
-  (interactive "P")
-  (ess-eval-region (point-min) (point-max) vis "Eval buffer" 'buffer))
-
-(defun ess-eval-buffer-from-beg-to-here (&optional vis)
-  "Send region from beginning to point to the inferior ESS process.
-VIS has same meaning as for `ess-eval-region'."
-  (interactive "P")
-  (ess-eval-region (point-min) (point) vis "Eval buffer till point"))
-
-(defun ess-eval-buffer-from-here-to-end (&optional vis)
-  "Send region from point to end of buffer to the inferior ESS process.
-VIS has same meaning as for `ess-eval-region'."
-  (interactive "P")
-  (ess-eval-region (point) (point-max) vis "Eval buffer till end"))
-
-(defun ess-eval-function (&optional vis)
-  "Send the current function to the inferior ESS process.
-Prefix arg VIS toggles visibility of ess-code as for
-`ess-eval-region'. Returns nil if not inside a function."
-  (interactive "P")
-  (ess-force-buffer-current)
-  (save-excursion
-    (ignore-errors
-      ;; Evaluation is forward oriented
-      (forward-line -1)
-      (ess-next-code-line 1))
-    (let ((pos (point))
-          beg end msg)
-      (end-of-defun)
-      (beginning-of-defun)
-      ;; While we are the beginning of the function, get the function
-      ;; name. FIXME: should use our ess-function-pattern.
-      (setq msg (format "Eval function: %s"
-                        (if (looking-at add-log-current-defun-header-regexp)
-                            (match-string 1)
-                          (buffer-substring (point) (line-end-position)))))
-      (setq beg (point))
-      (end-of-defun)
-      (setq end (point))
-      (when (or (< pos beg)
-                (< end pos))
-        (error "Not in a function"))
-      (if (ess-tracebug-p)
-          (ess-tracebug-send-function (get-process ess-local-process-name) beg end vis msg)
-        (ess-eval-region beg end vis msg)))))
-
-(defun ess-eval-paragraph (&optional vis)
-  "Send the current paragraph to the inferior ESS process.
-Prefix arg VIS toggles visibility of ess-code as for `ess-eval-region'."
-  (interactive "P")
-  (let ((start-pos (point)))
-    (if (= (line-beginning-position) (point-min))
-        (ess-next-code-line 0)
-      ;; Evaluation is forward oriented
-      (forward-line -1)
-      (ess-next-code-line 1))
-    (when (< (point) start-pos)
-      (goto-char start-pos))
-    (save-excursion
-      (let ((beg (progn (backward-paragraph) (point)))
-            (end (progn (forward-paragraph) (point))))
-        (ess-eval-region beg end vis)))))
-
-(defun ess-eval-function-or-paragraph (&optional vis)
-  "Send the current function if \\[point] is inside one.
-Otherwise send the current paragraph to the inferior ESS process.
-Prefix arg VIS toggles visibility of ess-code as for
-`ess-eval-region'. Returns \\='function if a function was evaluated
-or \\='paragraph if a paragraph."
-  (interactive "P")
-  (condition-case nil
-      (progn (ess-eval-function vis)
-             'function)
-    ;; TODO: Maybe be smarter than just catching all errors?
-    (error (ess-eval-paragraph vis)
-           'paragraph)))
-
-(defun ess-eval-function-or-paragraph-and-step (&optional vis)
-  "Send the current function if \\[point] is inside one.
-Otherwise send the current paragraph to the inferior ESS process.
-Prefix arg VIS toggles visibility of ess-code as for
-`ess-eval-region'."
-  (interactive "P")
-  (ess-skip-thing (ess-eval-function-or-paragraph vis))
-  (ess-next-code-line))
-
-(defun ess-eval-region-or-function-or-paragraph (&optional vis)
-  "Send the region, function, or paragraph depending on context.
-Send the region if it is active. If not, send function if `point'
-is inside one, otherwise the current paragraph. Treats
-rectangular regions as `ess-eval-region' does. Prefix arg VIS
-toggles visibility of ess-code as for `ess-eval-region'."
-  (interactive "P")
-  (if (use-region-p)
-      (ess-eval-region (region-beginning) (region-end) vis)
-    (ess-eval-function-or-paragraph vis)))
-
-(defun ess-eval-region-or-function-or-paragraph-and-step (&optional vis)
-  "Send the region, function, or paragraph depending on context.
-Send the region if it is active. If not, send function if `point'
-is inside one, otherwise the current paragraph. Treats
-rectangular regions as `ess-eval-region' does. After evaluation
-step to the next code line or to the end of region if region was
-active. Prefix arg VIS toggles visibility of ess-code as for
-`ess-eval-region'."
-  (interactive "P")
-  (ess-skip-thing (ess-eval-region-or-function-or-paragraph vis))
-  (ess-next-code-line))
-
-(defun ess-eval-region-or-line-and-step (&optional vis)
-  "Evaluate region if active, otherwise `ess-eval-line-and-step'.
-See `ess-eval-region' for the meaning of VIS. Treats rectangular
-regions as `ess-eval-region' does."
-  (interactive "P")
-  (if (use-region-p)
-      (ess-eval-region (region-beginning) (region-end) vis)
-    (ess-eval-line-and-step)))
-
-(defun ess-eval-region-or-line-visibly-and-step ()
-  "Evaluate region if active, otherwise the current line and step.
-Evaluation is done visibly.
-
-Note that when inside a package and namespaced evaluation is in
-place (see `ess-r-set-evaluation-env') evaluation of multiline
-input will fail."
-  (interactive)
-  (ess-force-buffer-current)
-  (display-buffer (ess-get-process-buffer)
-                  ;; Use a different window for the process buffer:
-                  '(nil (inhibit-same-window . t))
-                  ;; Pass t to reusable-frames if users have help in
-                  ;; own frames, otherwise help frames get split to
-                  ;; display the inferior.
-                  (or (equal ess-help-own-frame 'one)
-                      ess-help-own-frame))
-  (let ((ess-eval-visibly t))
-    (ess-eval-region-or-line-and-step)))
-
-(defun ess-eval-line (&optional vis)
-  "Send the current line to the inferior ESS process.
-VIS has same meaning as for `ess-eval-region'."
-  (interactive "P")
-  (let* ((beg (line-beginning-position))
-         (end (line-end-position))
-         (msg (format "Loading line: %s" (buffer-substring beg end))))
-    (ess-eval-region beg end vis msg)))
-
-(defun ess-eval-line-and-step (&optional vis)
-  "Evaluate the current line and step to the \"next\" line.
-See `ess-eval-region' for VIS."
-  (interactive "P")
-  (ess-eval-line vis)
-  (ess-skip-thing 'line)
-  (ess-next-code-line))
-
-(defun ess-eval-line-visibly-and-step (&optional simple-next)
-  "Evaluate the current line visibly and step to the \"next\" line.
-If SIMPLE-NEXT is non-nil, possibly via prefix arg, first skip
-empty and commented lines. When the variable `ess-eval-empty'
-is non-nil both SIMPLE-NEXT and EVEN-EMPTY are interpreted as
-true.
-
-Note that when inside a package and namespaced evaluation is in
-place (see `ess-r-set-evaluation-env'), the evaluation of
-multiline input will fail."
-  (interactive "P")
-  (ess-force-buffer-current)
-  (display-buffer (ess-get-process-buffer)
-                  ;; Use a different window for the process buffer:
-                  '(nil (inhibit-same-window . t))
-                  ;; Pass t to reusable-frames if users have help in
-                  ;; own frames, otherwise help frames get split to
-                  ;; display the inferior.
-                  (or (equal ess-help-own-frame 'one)
-                      ess-help-own-frame))
-  (let ((ess-eval-visibly t)
-        (ess-eval-empty (or ess-eval-empty simple-next)))
-    (ess-eval-line)
-    (ess-skip-thing 'line)
-    (ess-next-code-line)))
-
-(defun ess-eval-line-invisibly-and-step ()
-  "Evaluate the current line invisibly and step to the next line.
-Evaluate all comments and empty lines."
-  (interactive)
-  (let ((ess-eval-visibly nil))
-    (ess-eval-line-and-step)))
-(define-obsolete-function-alias 'ess-eval-line-and-step-invisibly
-  #'ess-eval-line-invisibly-and-step "18.10")
-
-\f
-;;;*;;; Evaluate and switch to S
-
-(defun ess-eval-region-and-go (start end &optional vis)
-  "Send region from START to END to the inferior process buffer.
-START and END default to the current region, and rectangular
-regions are treated as `ess-eval-region'. VIS has same meaning as
-for `ess-eval-region'."
-  (interactive "r\nP")
-  (ess-eval-region start end vis)
-  (ess-switch-to-ESS t))
-
-(defun ess-eval-buffer-and-go (&optional vis)
-  "Send the current buffer to the inferior S and switch to the process buffer.
-VIS has same meaning as for `ess-eval-region'."
-  (interactive "P")
-  (ess-eval-buffer vis)
-  (ess-switch-to-ESS t))
-
-(defun ess-eval-function-and-go (&optional vis)
-  "Send the current function, then switch to the inferior process buffer.
-VIS has same meaning as for `ess-eval-region'."
-  (interactive "P")
-  (ess-eval-function vis)
-  (ess-switch-to-ESS t))
-
-(defun ess-eval-line-and-go (&optional vis)
-  "Send the current line, then switch to the inferior process buffer.
-VIS has same meaning as for `ess-eval-region'."
-  (interactive "P")
-  (ess-eval-line vis)
-  (ess-switch-to-ESS t))
-
-(defun ess-eval-paragraph-and-go (&optional vis)
-  "Send the current paragraph, then switch to the inferior process buffer.
-VIS has same meaning as for `ess-eval-region'."
-  (interactive "P")
-  (ess-eval-paragraph vis)
-  (ess-switch-to-ESS t))
-
-(defun ess-eval-paragraph-and-step (&optional vis)
-  "Evaluate the current paragraph and move point to the next line.
-If not inside a paragraph, evaluate the next one. VIS has same
-meaning as for `ess-eval-region'."
-  (interactive "P")
-  (ess-eval-paragraph vis)
-  (ess-skip-thing 'paragraph)
-  (ess-next-code-line))
-
-\f ; Inferior ESS mode
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;; In this section:
-;;;;
-;;;; * The major mode inferior-ess-mode
-;;;; * Process handling code
-;;;; * Completion code
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;;*;; Major mode definition
-
-(defvar inferior-ess-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map "\C-y"              #'ess-yank)
-    (define-key map "\r"       #'inferior-ess-send-input)
-    (define-key map "\C-a"     #'comint-bol)
-    ;; 2010-06-03 SJE
-    ;; disabled this in favor of ess-dirs.  Martin was not sure why this
-    ;; key was defined anyway in this mode.
-    ;;(define-key map "\M-\r"    #'ess-transcript-send-command-and-move)
-    (define-key map "\C-c\M-l" #'ess-load-file)
-    (define-key map "\C-c`"    #'ess-show-traceback)
-    (define-key map [(control ?c) ?~] #'ess-show-call-stack)
-    (define-key map "\C-c\C-d" #'ess-dump-object-into-edit-buffer)
-    (define-key map "\C-c\C-v" #'ess-display-help-on-object)
-    (define-key map "\C-c\C-q" #'ess-quit)
-    (define-key map "\C-c\C-s" #'ess-execute-search)
-    (define-key map "\C-c\C-x" #'ess-execute-objects)
-    (define-key map "\C-c\034" #'ess-abort) ; \C-c\C-backslash
-    (define-key map "\C-c\C-z" #'ess-switch-to-inferior-or-script-buffer) ; mask comint map
-    (define-key map "\C-d"     #'delete-char)   ; EOF no good in S
-    (define-key map "\t"       #'completion-at-point)
-    (define-key map "\M-?"     #'ess-complete-object-name); stealing  M-? from xref(standard Emacs)
-    (define-key map "\C-c\C-k" #'ess-request-a-process)
-    (define-key map ","        #'ess-smart-comma)
-    (define-key map "\C-c\C-d"  'ess-doc-map)
-    (define-key map "\C-c\C-e"  'ess-extra-map)
-    (define-key map "\C-c\C-t"  'ess-dev-map)
-    map)
-  "Keymap for `inferior-ess' mode.")
-
-(easy-menu-define
-  inferior-ess-mode-menu inferior-ess-mode-map
-  "Menu for use in Inferior S mode"
-  '("iESS"
-    ["Quit"                    ess-quit                        t]
-    ["Reload process"          inferior-ess-reload             t]
-    ;; ["Send and move"  ess-transcript-send-command-and-move  t]
-    ["Copy command"            comint-copy-old-input           t]
-    ["Send command"            inferior-ess-send-input         t]
-    ["Switch to script buffer" ess-switch-to-inferior-or-script-buffer t]
-    ["Get help on S object"    ess-display-help-on-object      t]
-    "------"
-    ("Process"
-     ["Process Echoes" (lambda () (interactive)
-                         (setq comint-process-echoes (not comint-process-echoes)))
-      :active t
-      :style toggle
-      :selected comint-process-echoes]
-     ("Eval visibly "
-      :filter ess--generate-eval-visibly-submenu ))
-    "------"
-    ("Utils"
-     ["Attach directory"       ess-execute-attach      t]
-     ["Display object list"    ess-execute-objects     t]
-     ["Display search list"    ess-execute-search      t]
-     ["Edit S object"  ess-dump-object-into-edit-buffer t]
-     ["Enter S command"                ess-execute             t]
-     ["Jump to error"          ess-parse-errors        t]
-     ["Load source file"       ess-load-file           t]
-     ["Resynch S completions"  ess-resynch             t]
-     ["Recreate R versions known to ESS"
-      (lambda () (interactive) (ess-r-redefine-runners 'verbose)) t]
-     )
-    "------"
-    ("start-dev" :visible nil); <-- ??
-    ("end-dev" :visible nil)
-    "------"
-    ("Font Lock"
-     :active ess-font-lock-keywords
-     :filter ess--generate-font-lock-submenu)
-    "------"
-    ["Describe"         describe-mode                       t]
-    ["Send bug report"  ess-submit-bug-report               t]
-    ["About"            (ess-goto-info "Entering Commands") t]
-    ))
-
-
-(defvar ess-mode-minibuffer-map
-  (let ((map (make-sparse-keymap)))
-    (set-keymap-parent map minibuffer-local-map)
-    (define-key map "\t"       #'ess-complete-object-name)
-    (define-key map "\C-\M-i"  #'ess-complete-object-name) ;; doesn't work:(
-    (define-key map "\C-c\C-s" #'ess-execute-search)
-    (define-key map "\C-c\C-x" #'ess-execute-objects)
-    map)
-  "Keymap used in `ess-execute'.")
-
-(define-derived-mode inferior-ess-mode comint-mode "iESS"
-  "Major mode for interacting with an inferior ESS process.
-To learn more about how to use inferior ess modes, see Info
-node `(ess)Top'. If you accidentally suspend your process, use
-\\[comint-continue-subjob] to continue it."
-  :group 'ess-proc
-  (setq-local comint-input-sender 'inferior-ess-input-sender)
-  (setq-local font-lock-fontify-region-function
-              #'inferior-ess-fontify-region)
-  ;; If comint-process-echoes is t  inferior-ess-input-sender
-  ;; recopies the input, otherwise not
-  (setq-local comint-process-echoes (not (member ess-language '("SAS" "XLS" "OMG" "julia"))))
-
-  (when comint-use-prompt-regexp ;; why comint is not setting this? bug?
-    (setq-local inhibit-field-text-motion t))
-
-  (unless inferior-ess-prompt ;; build when unset
-    (setq inferior-ess-prompt
-          (concat "\\("
-                  inferior-ess-primary-prompt
-                  (when inferior-ess-secondary-prompt "\\|")
-                  inferior-ess-secondary-prompt
-                  "\\)")))
-  (setq comint-prompt-regexp (concat "^" inferior-ess-prompt))
-
-  (setq mode-line-process
-        '(" ["
-          ess--mode-line-process-indicator
-          ess--local-mode-line-process-indicator
-          "]: %s"))
-
-  ;;; Completion support ----------------
-  (remove-hook 'completion-at-point-functions #'comint-completion-at-point t) ;; reset the hook
-  (add-hook 'completion-at-point-functions
-            #'comint-c-a-p-replace-by-expanded-history nil 'local)
-  (add-hook 'completion-at-point-functions #'ess-filename-completion nil 'local)
-
-  ;; hyperlinks support
-  (goto-address-mode t)
-
-  ;; Avoid spaces after filenames
-  (setq-local comint-completion-addsuffix (cons "/" ""))
-
-  (setq comint-input-autoexpand t) ; Only for completion, not on input.
-
-  (add-hook 'window-configuration-change-hook #'ess-set-width nil t)
-  (setq-local indent-tabs-mode nil)
-
-  (setq-local paragraph-start (concat inferior-ess-primary-prompt "\\|\^L"))
-  (setq-local paragraph-separate "\^L")
-  (setq-local jit-lock-chunk-size inferior-ess-jit-lock-chunk-size))
-
-
-\f
-;;*;; Commands used exclusively in inferior-ess-mode
-
-;;;*;;; Main user commands
-
-(defun inferior-ess-input-sender (proc string)
-  (inferior-ess--interrupt-subjob-maybe proc)
-  (let ((comint-input-filter-functions nil)) ; comint runs them, don't run twice.
-    (if comint-process-echoes
-        (ess-eval-linewise string nil nil ess-eval-empty)
-      (ess-send-string proc string))))
-
-(defvar ess-help-arg-regexp "\\(['\"]?\\)\\([^,=)'\"]*\\)\\1"
-  "Reg(ular) Ex(pression) of help(.) arguments.  MUST: 2nd \\(.\\) = arg.")
-
-(defun inferior-ess-send-input ()
-  "Sends the command on the current line to the ESS process."
-  (interactive)
-  (run-hooks 'ess-send-input-hook)
-  (unless (ess-process-get 'busy)
-    ;; avoid new line insertion
-    (ess-process-put 'prev-prompt nil))
-  (comint-send-input)
-  (setq ess-object-list nil))
-
-(defun inferior-ess--goto-input-start:field ()
-  "Move point to the beginning of input skipping all continuation lines.
-If in the output field, goes to the beginning of previous input
-field.
-Note: `inferior-ess-secondary-prompt' should match exactly."
-  (goto-char (field-beginning))
-  ;; move to the beginning of non-output field
-  (while (and (not (bobp))
-              (eq (field-at-pos (point)) 'output))
-    (goto-char (field-beginning nil t)))
-  ;; skip all secondary prompts
-  (let ((pos (field-beginning (point) t))
-        (secondary-prompt (concat "^" inferior-ess-secondary-prompt)))
-    (while (and pos
-                (if (eq (get-text-property pos 'field) 'output)
-                    (string-match secondary-prompt (field-string-no-properties pos))
-                  t))
-      (goto-char pos)
-      (setq pos (previous-single-property-change pos 'field)))))
-
-(defun inferior-ess--goto-input-end:field ()
-  "Move point to the end of input skipping all continuation lines.
-If in the output field, goes to the beginning of previous input
-field. NOTE: to be used only with fields, see
-`comint-use-prompt-regexp'."
-  ;; this func is not used but might be useful some day
-  (goto-char (field-end))
-  (let ((pos (point))
-        (secondary-prompt (concat "^" inferior-ess-secondary-prompt)))
-    (while (and pos
-                (if (eq (get-text-property pos 'field) 'output)
-                    (string-match secondary-prompt (field-string-no-properties pos))
-                  t))
-      (goto-char pos)
-      (setq pos (next-single-property-change pos 'field)))))
-
-(defun inferior-ess--get-old-input:field ()
-  "Return the ESS command surrounding point (use with fields)."
-  (save-excursion
-    (if (eq (field-at-pos (point)) 'output)
-        (if (called-interactively-p 'any)
-            (error "No command on this line")
-          ;; else, just return ""
-          "")
-      (inferior-ess--goto-input-start:field)
-      (let ((command (field-string-no-properties (point)))
-            (pos (next-single-property-change (point) 'field ))
-            (secondary-prompt (concat "^" inferior-ess-secondary-prompt)))
-        (while (and pos
-                    (cond
-                     ((eq (get-text-property pos 'field) 'input)
-                      (setq command (concat command "\n" (field-string-no-properties pos))))
-                     ((eq (get-text-property pos 'field) 'output)
-                      (string-match secondary-prompt (field-string-no-properties pos)))
-                     (t)));; just skip if unknown
-          (setq pos (next-single-property-change pos 'field)))
-        command))))
-
-;; TODO: error when entering a multiline function
-;; check.integer <- function(N){
-;;      is.integer(N) | !length(grep("[^[:digit:]]", as.character(N)))
-;; }
-(defun inferior-ess--goto-input-start:regexp ()
-  "Move point to the beginning of input skipping all continuation lines.
-If in the output field, goes to the beginning of previous input."
-  (beginning-of-line)
-  (unless (looking-at inferior-ess-prompt)
-    (re-search-backward (concat "^" inferior-ess-prompt) nil t))
-  ;; at bol
-  (when (and inferior-ess-secondary-prompt
-             (looking-at inferior-ess-secondary-prompt))
-    (while (and (> (forward-line -1) -1)
-                (looking-at inferior-ess-secondary-prompt))))
-  (unless (looking-at inferior-ess-prompt)
-    (error "Beginning of input not found"))
-  (comint-skip-prompt))
-
-(defun inferior-ess--get-old-input:regexp ()
-  "Return the ESS command surrounding point (use regexp)."
-  ;;VS[03-09-2012]: This should not rise errors!! Troubles comint-interrupt-subjob
-  (save-excursion
-    (let* ((inhibit-field-text-motion t)
-           command)
-      (beginning-of-line)
-      (when  (and inferior-ess-secondary-prompt
-                  (looking-at inferior-ess-secondary-prompt))
-        (inferior-ess--goto-input-start:regexp))
-      (beginning-of-line)
-      (if (looking-at inferior-ess-prompt) ; cust.var, might not include sec-prompt
-          (progn
-            (comint-skip-prompt)
-            (setq command (buffer-substring-no-properties (point) (line-end-position)))
-            (when inferior-ess-secondary-prompt
-              (while (progn (forward-line 1)
-                            (looking-at inferior-ess-secondary-prompt))
-                (re-search-forward inferior-ess-secondary-prompt (line-end-position) t)
-                (setq command (concat command "\n"
-                                      (buffer-substring-no-properties (point) (line-end-position))))))
-            (forward-line -1)
-            command)
-        (message "No command at this point")
-        ""))))
-
-(defun inferior-ess-get-old-input ()
-  "Return the ESS command surrounding point."
-  (if comint-use-prompt-regexp
-      (inferior-ess--get-old-input:regexp)
-    (inferior-ess--get-old-input:field)))
-
-(defun ess-can-eval-in-background (&optional proc)
-  "Can the current process be used for background commands.
-Inspects the `ess-can-eval-in-background' variable as well as the
-`bg-eval-disabled' property of PROC or of the current process, if
-any. This makes it possible to disable background evals for a
-specific process, for instance in case it was not initialized
-properly."
-  (when ess-can-eval-in-background
-    (when-let ((proc (or proc (ess-get-current-process))))
-      (not (process-get proc 'bg-eval-disabled)))))
-
-\f
-;;;*;;; Hot key commands
-
-(defun ess-execute-objects (posn)
-  "Send the objects() command to the ESS process.
-By default, gives the objects at position 1.
-A prefix argument toggles the meaning of `ess-execute-in-process-buffer'.
-A prefix argument of 2 or more means get objects for that position.
-A negative prefix argument gets the objects for that position
-  and toggles `ess-execute-in-process-buffer' as well."
-  (interactive "P")
-  (ess-make-buffer-current)
-  (let* ((num-arg (if (listp posn)
-                      (if posn -1 1)
-                    (prefix-numeric-value posn)))
-         (the-posn (if (< num-arg 0) (- num-arg) num-arg))
-         (invert (< num-arg 0))
-         (the-command (format inferior-ess-objects-command the-posn ".*"))
-         (the-message (concat ">>> Position "
-                              (number-to-string the-posn)
-                              " ("
-                              (nth (1- the-posn) (ess-search-list))
-                              ")\n")))
-    (ess-execute the-command invert "S objects" the-message)))
-
-(defun ess-execute-search (invert)
-  "Send the `inferior-ess-search-list-command' command.
-INVERT is as in `ess-execute'. E.g. search(..) in S."
-  (interactive "P")
-  (ess-execute inferior-ess-search-list-command  invert "S search list"))
-
-;; FIXME --- this *only* works in S / S-plus; not in R
-;; -----     ("at least" is not assigned to any key by default)
-(defun ess-execute-attach (dir &optional posn)
-  "Attach a directory in the `ess-language' process with the attach() command.
-When used interactively, user is prompted for DIR to attach and
-prefix argument is used for POSN (or 2, if absent.)
-Doesn't work for data frames."
-  (interactive "Attach directory: \nP")
-  (ess-execute (concat "attach(\""
-                       (directory-file-name (expand-file-name dir))
-                       "\""
-                       (if posn (concat "," (number-to-string
-                                             (prefix-numeric-value posn))))
-                       ")") 'buffer)
-  (ess-process-put 'sp-for-help-changed? t))
-
-(defun ess-execute-screen-options (&optional invisibly)
-  "Cause S to set the \"width\" option to 1 less than the window width.
-Also sets the \"length\" option to 99999. When INVISIBLY is
-non-nil, don't echo to R subprocess. This is a good thing to put
-in `ess-r-post-run-hook' or `ess-S+-post-run-hook'."
-  (interactive)
-  (ess-if-verbose-write
-   (format "ess-execute-screen-options: invisibly=%s\n" invisibly))
-  (if (null ess-execute-screen-options-command)
-      (message "Not implemented for '%s'" ess-dialect)
-    (let ((command (ess-calculate-width 'window)))
-      (if invisibly
-          (ess-command command)
-        (ess-eval-linewise command nil nil nil 'wait-prompt)))))
-
-;; Runs in background if inferior is not busy
-(defun ess--execute-screen-options-bg ()
-  (when (and ess-execute-screen-options-command
-             (inferior-ess-available-p))
-    (ess-execute-screen-options t)))
-
-(defun ess-calculate-width (opt)
-  "Calculate width command given OPT.
-OPT can be \\='window, \\='frame, or an integer. Return a command
-suitable to send to the inferior process (e.g.
-\"options(width=80, length=999999)\")."
-  (when (null ess-execute-screen-options-command)
-    (error "Not implemented for %s" ess-dialect))
-  (let (command)
-    (cond ((and (integerp opt)
-                (>= opt 0))
-           (setq command (format ess-execute-screen-options-command opt)))
-          ((or (eql 'window opt)
-               (and (integerp opt)
-                    (> 0 opt)))
-           ;; We cannot use (window-width) here because it returns sizes
-           ;; in default (frame) characters which leads to incorrect
-           ;; sizes with scaled fonts.To solve this we approximate font
-           ;; width in pixels and use window-pixel-width to compute the
-           ;; approximate number of characters that fit into line.
-           (let* ((wedges (window-inside-pixel-edges))
-                  (wwidth (- (nth 2 wedges) (nth 0 wedges)))
-                  (nchars (floor (/ wwidth (default-font-width)))))
-             (when (and (integerp opt)
-                        (> 0 opt))
-               (setq nchars (- nchars (- opt))))
-             (setq command (format ess-execute-screen-options-command
-                                   nchars))))
-          ((eql 'frame opt)
-           (setq command
-                 (format ess-execute-screen-options-command (frame-width))))
-          (t (error "OPT (%s) not 'window, 'frame or an integer" opt)))
-    command))
-
-(defun ess-set-width ()
-  "Set the width option.
-A part of `window-configuration-change-hook' in inferior ESS
-buffers."
-  (when (and ess-auto-width
-             ess-execute-screen-options-command)
-    ;; `window-configuration-change-hook' runs with the window selected.
-    (let ((proc (get-buffer-process (window-buffer)))
-          command)
-      ;; TODO: Set the width once the process is no longer busy.
-      (when (and (process-live-p proc)
-                 (not (process-get proc 'busy)))
-        (setq command (ess-calculate-width ess-auto-width))
-        (if ess-auto-width-visible
-            (ess-eval-linewise command nil nil nil 'wait-prompt)
-          (ess-command command))))))
-
-(defun ess-execute (command &optional invert buff message)
-  "Send a command to the ESS process.
-A newline is automatically added to COMMAND.  Prefix arg (or second arg
-INVERT) means invert the meaning of
-`ess-execute-in-process-buffer'.  If INVERT is \\='buffer, output is
-forced to go to the process buffer.  If the output is going to a
-buffer, name it *BUFF*.  This buffer is erased before use.  Optional
-fourth arg MESSAGE is text to print at the top of the buffer (defaults
-to the command if BUFF is not given.)"
-  (interactive (list
-                ;; simpler way to set proc name in mb?
-                (let ((enable-recursive-minibuffers t)
-                      (proc-name (progn (ess-force-buffer-current)
-                                        ess-local-process-name)))
-                  (with-current-buffer (get-buffer " *Minibuf-1*") ;; FIXME: hardcoded name
-                    (setq ess-local-process-name proc-name))
-                  (read-from-minibuffer "Execute> " nil
-                                        ess-mode-minibuffer-map))
-                current-prefix-arg))
-  (ess-make-buffer-current)
-  (let ((the-command (concat command "\n"))
-        (buff-name (concat "*" (or buff "ess-output") "*"))
-        (in-pbuff (if invert (or (eq invert 'buffer)
-                                 (not ess-execute-in-process-buffer))
-                    ess-execute-in-process-buffer)))
-    (if in-pbuff
-        (ess-eval-linewise the-command)
-      (ess-with-current-buffer (get-buffer-create buff-name)
-        (ess-command the-command (current-buffer) nil nil nil
-                     (get-process ess-local-process-name))
-        (ansi-color-apply-on-region (point-min) (point-max))
-        (goto-char (point-min))
-        (if message (insert message)
-          (insert "> " the-command))
-        (display-buffer (current-buffer))))))
-
-\f
-;;;*;;; Quitting
-
-(cl-defgeneric ess-quit--override (_arg)
-  "Stop the inferior process."
-  (let ((proc (ess-get-process)))
-    (ess-cleanup)
-    (when ess-eval-visibly
-      (goto-char (marker-position (process-mark proc)))
-      (insert inferior-ess-exit-command))
-    (process-send-string proc inferior-ess-exit-command)))
-
-(defun ess-quit (&optional arg)
-  "Issue an exiting command to the inferior process.
-Runs `ess-cleanup'. ARG gets passed to a language specific
-method, see `ess-quit--override'."
-  (interactive "P")
-  (unless (ess-process-live-p)
-    (user-error "No live ESS process associated with this buffer"))
-  (ess-force-buffer-current "Process to quit: ")
-  (ess-interrupt)
-  (ess-make-buffer-current)
-  (ess-quit--override arg))
-
-(defvar ess--interrupt-timeout 5)
-
-(defun ess-interrupt ()
-  "Interrupt the inferior process.
-This sends an interrupt and quits a debugging session."
-  (interactive)
-  (inferior-ess-force)
-  (let ((proc (ess-get-process)))
-    (ess--interrupt proc)
-    (unless (ess-wait-for-process proc nil nil nil
-                                  ess--interrupt-timeout)
-      (error "Timeout while interrupting process"))
-    (with-current-buffer (process-buffer proc)
-      (goto-char (process-mark proc)))))
-
-(defun ess--interrupt (proc)
-  (interrupt-process proc comint-ptyp)
-  ;; Workaround for Windows terminals. NOTE: Is this really needed
-  ;; for background commands? Or just for interactive interrupts?
-  (unless (memq system-type '(gnu/linux darwin))
-    (process-send-string nil "\n")))
-
-(defun ess-abort ()
-  "Kill the ESS process, without executing .Last or terminating devices.
-If you want to finish your session, use \\[ess-quit] instead."
-;;; Provided as a safety measure over the default binding of C-c C-z in
-;;; comint-mode-map.
-  (interactive)
-  (ding)
-  (message "WARNING: \\[inferior-ess-exit-command] will not be executed and graphics devices won't finish properly!")
-  (sit-for 2)
-  (if (y-or-n-p "Still abort? ")
-      (comint-quit-subjob)
-    (message "Good move.")))
-
-(defun ess-cleanup ()
-  "Cleanup buffers associated with the 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. Uses `display-buffer' to display the process buffer. It
-is run automatically by \\[ess-quit]."
-  (interactive)
-  (let* ((the-procname (or (ess-make-buffer-current) ess-local-process-name))
-         (buf (buffer-name (process-buffer (get-process the-procname)))))
-    (unless the-procname
-      (error "I don't know which ESS process to clean up after!"))
-    (when
-        (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))))
-      (dolist (buf (buffer-list))
-        (with-current-buffer buf
-          ;; Consider buffers for which ess-local-process-name is
-          ;; the same as the-procname
-          (when (and (not (get-buffer-process buf))
-                     ess-local-process-name
-                     (equal ess-local-process-name the-procname))
-            (kill-buffer buf)))))
-    (display-buffer buf)
-    buf))
-
-(defun inferior-ess-reload (&optional start-args)
-  "Reload the inferior process.
-START-ARGS gets passed to the dialect-specific
-`inferior-ess-reload-override'."
-  (interactive)
-  (let* ((inf-buf (inferior-ess-force))
-         (inf-proc (get-buffer-process inf-buf))
-         (inf-start-data (buffer-local-value 'inferior-ess--local-data inf-buf))
-         (start-name (car inf-start-data))
-         (start-args (or start-args (cdr inf-start-data))))
-    ;; Interrupt early so we can get working directory
-    (ess-interrupt)
-    ;; Quit debugging session before reloading
-    (when (ess-debug-active-p)
-      (ess-debug-command-quit)
-      (ess-wait-for-process inf-proc nil nil nil 1))
-    (save-window-excursion
-      ;; Make sure we don't ask for directory again
-      ;; Use current working directory as default
-      (let ((project-find-functions nil)
-            (ess-startup-directory-function nil)
-            (ess-startup-directory (ess-get-process-variable 'default-directory))
-            (ess-ask-for-ess-directory nil))
-        (ess-quit 'no-save)
-        (inferior-ess--wait-for-exit inf-proc)
-        (with-current-buffer inf-buf
-          (inferior-ess-reload--override start-name start-args))))))
-
-(cl-defgeneric inferior-ess-reload--override (_start-name _start-args)
-  (user-error "Reloading not implemented for %s" ess-dialect))
-
-(defun inferior-ess--wait-for-exit (proc)
-  "Wait for process PROC to exit.
-This should be used instead of `ess-wait-for-process' for waiting
-after issuing a quit command as the latter assumes a live process."
-  (let ((start-time (float-time)))
-    (while (eq (process-status proc) 'run)
-      (accept-process-output proc 0.002)
-      (when (> (- (float-time) start-time) 30)
-        (error "Timeout while quitting process")))))
-
-\f
-;;;*;;; 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 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."
-  (let* ((entry (nth (1- posn) alist))
-         (dir (car entry))
-         (timestamp (car (cdr entry)))
-         (new-modtime (and timestamp
-                           (ess-dir-modtime dir))))
-    ;; Refresh the object listing if necessary
-    (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."
-  (and ess-filenames-map
-       (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, i.e., for R or any non-S language!"
-  (let ((path (ess-search-list))
-        result)
-    (while (and (not result) path)
-      (setq result (file-attributes
-                    (concat (file-name-as-directory (car path))
-                            object)))
-      (setq path (cdr path)))
-    (nth 5 result)))
-
-(defun ess-modtime-gt (mod1 mod2)
-  "Return t if MOD1 is later than MOD2."
-  (and mod1
-       (or (> (car mod1) (car mod2))
-           (and (= (car mod1) (car mod2))
-                (> (car (cdr mod1)) (car (cdr mod2)))))))
-
-(defun ess-get-object-list (name &optional exclude-first)
-  "Return a list of current S object names associated with process NAME.
-Uses `ess-object-list' if that is non-nil. If EXCLUDE-FIRST is
-non-nil, don't return objects in first position (.GlobalEnv)."
-  (or ess-object-list ;; <<-  MM: this is now always(?) nil; we cache the *-modtime-alist
-      (with-current-buffer (process-buffer (ess-get-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-process-get 'sp-for-help-changed?))
-            (progn (ess-write-to-dribble-buffer "--> (ess-get-modtime-list)\n")
-                   (ess-get-modtime-list))
-          ;;else
-          (ess-write-to-dribble-buffer " using existing ess-sl-modtime-alist\n"))
-        (let* ((alist ess-sl-modtime-alist)
-               (i 2)
-               (n (length alist))
-               result)
-          (ess-write-to-dribble-buffer (format " (length alist) : %d\n" n))
-          (unless exclude-first
-            ;; re-read of position 1 :
-            (setq result (ess-extract-onames-from-alist alist 1 'force)))
-          (ess-write-to-dribble-buffer
-           (format " have re-read pos=1: -> length %d\n" (length result)))
-          ;; 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 (delete-dups result))))))
-
-(defun ess-get-words-from-vector (command &optional no-prompt-check wait proc
-                                          timeout)
-  "Evaluate the S command COMMAND, which returns a character vector.
-Return the elements of the result of COMMAND as an alist of
-strings. COMMAND should have a terminating newline.
-NO-PROMPT-CHECK, WAIT, PROC, and TIMEOUT are passed to `ess-command'.
-
-FILTER may be the keyword \\='non-... or nil. To avoid truncation of
-long vectors, wrap your command (%s) like this, or a version with
-explicit options(max.print=1e6): \"local({ out <- try({%s});
-print(out, max=1e6) })\n\"."
-  (unless proc
-    (inferior-ess-force))
-  (let* ((tbuffer (get-buffer-create
-                   " *ess-get-words*")); initial space: disable-undo
-         (word-RE
-          (concat "\\("
-                  "\\\\\"" "\\|" "[^\"]" ;  \" or non-"-char
-                  "\\)*"))
-         (full-word-regexp
-          (concat "\"" "\\(" word-RE "\\)"
-                  "\""
-                  "\\( \\|$\\)"; space or end
-                  ))
-         words)
-    (ess-command command tbuffer 'sleep no-prompt-check wait proc nil timeout)
-    (with-current-buffer tbuffer
-      (goto-char (point-min))
-      (while (re-search-forward full-word-regexp nil t)
-        (setq words (cons (buffer-substring (match-beginning 1) (match-end 1))
-                          words))))
-    (ess-if-verbose-write
-     (if (> (length words) 5)
-         (format " |-> (length words)= %d\n" (length words))
-       (format " |-> words= '%s'\n" words)))
-    (reverse words)))
-
-(defun ess-get-words-from-vector--foreground (command &optional no-prompt-check wait proc)
-  (let ((timeout most-positive-fixnum))
-    (ess-get-words-from-vector command no-prompt-check wait proc timeout)))
-
-(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) "___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)
-  "Return alist of S object names in directory (or object) OBJ.
-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 the command
-`inferior-ess-safe-names-command'. If POS is supplied return the
-result of the command in `inferior-ess-objects-command'. If OBJ
-is nil or not a directory, POS must be supplied. In all cases,
-the value is an list of object names."
-  (cond ((and (stringp obj)
-              (string-match-p "ESSR" obj))
-         nil)
-        ;; FIXME: in both cases below, the same fallback "objects(POS)" is used -- merge!
-        ((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
-                  ;; first try .Data subdirectory:
-                  ;;FIXME: move ".Data" or ``this function'' to ess-sp6-d.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)))))
-        ((and obj ;; want names(obj)
-              (ess-get-words-from-vector
-               (format inferior-ess-safe-names-command obj))))
-        (pos
-         (ess-get-words-from-vector
-          (format inferior-ess-objects-command pos)))))
-
-(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)))
-
-(defun ess-function-arguments (funname &optional proc)
-  "Get FUNARGS from cache or ask the process for it.
-Return FUNARGS - a list with the first element being a
-cons (PACKAGE_NAME . TIME_STAMP), second element is a string
-giving arguments of the function as they appear in documentation,
-third element is a list of arguments of all methods. If PROC is
-given, it should be an ESS process. If PACKAGE_NAME is nil, and
-TIME_STAMP is less recent than the time of the last user
-interaction to the process, then update the entry. PACKAGE_NAME
-is also nil when FUNNAME was not found, or FUNNAME is a special
-name that contains :,$ or @."
-  (when (and funname ;; usually returned by ess--fn-name-start (might be nil)
-             (or proc (ess-process-live-p)))
-    (let* ((proc (or proc (get-process ess-local-process-name)))
-           (cache (or (process-get proc 'funargs-cache)
-                      (let ((cache (make-hash-table :test 'equal)))
-                        (process-put proc 'funargs-cache cache)
-                        cache)))
-           (args (gethash funname cache))
-           (pack (caar args))
-           (ts   (cdar args)))
-      (when (and args
-                 (and (time-less-p ts (process-get proc 'last-eval))
-                      (or (null pack)
-                          (equal pack ""))))
-        ;; reset cache
-        (setq args nil))
-      (or args
-          (cadr (assoc funname (process-get proc 'funargs-pre-cache)))
-             (and
-              (not (process-get proc 'busy))
-              (with-current-buffer (ess-command (format ess-funargs-command
-                                                                            (ess-quote-special-chars funname))
-                                                                nil nil nil nil proc)
-                (goto-char (point-min))
-                (when (re-search-forward "(list" nil t)
-                  (goto-char (match-beginning 0))
-                  (setq args (ignore-errors (eval (read (current-buffer)) t)))
-                  (when args
-                        (setcar args (cons (car args) (current-time)))))
-                ;; push even if nil
-                (puthash (substring-no-properties funname) args cache)))))))
-
-;;; 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 is loaded when `ess-mode' is
-loaded. It defines the variable `ess-object-name-db', which is
-used for completions. Before you call this function, modify the S
-search list so that it contains all the non-changing (i.e.
-system) S directories. All positions of the search list except
-for position 1 are searched and stored in the database. After
-running this command, you should move ess-namedb.el to a
-directory in the `load-path'."
-  (interactive)
-  (setq ess-object-name-db nil)
-  (let ((search-list (cdr (ess-search-list)))
-        (pos 2)
-        name
-        (buffer (get-buffer-create " *ess-db*"))
-        (temp-object-name-db nil))
-
-    (ess-write-to-dribble-buffer
-     (format "(object db): search-list=%s \n " search-list))
-    (while search-list
-      (message "Searching %s" (car search-list))
-      (setq temp-object-name-db (cons (cons (car search-list)
-                                            (ess-object-names nil pos))
-                                      temp-object-name-db))
-      (setq search-list (cdr search-list))
-      (ess-write-to-dribble-buffer
-       (format "(object db): temp-obj-name-db=%s \n pos=%s"
-               temp-object-name-db pos))
-      (setq pos (1+ pos)))
-    (with-current-buffer buffer
-      (erase-buffer)
-      (insert "(setq ess-object-name-db '")
-      (prin1 temp-object-name-db (current-buffer))
-      (insert ")\n")
-      (setq name (expand-file-name ess-object-name-db-file))
-      (write-region (point-min) (point-max) name)
-      (message "Wrote %s" name))
-    (kill-buffer buffer)
-    (setq ess-object-name-db temp-object-name-db)))
-
-(defun ess-resynch nil
-  "Reread all directories and objects in `ess-search-list' for completions."
-  (interactive)
-  (if (ess-make-buffer-current) nil
-    (error "Not an ESS process buffer"))
-  (setq
-   ess-sl-modtime-alist nil
-   ess-object-list nil
-   ess-object-name-db nil ; perhaps it would be better to reload?
-   )
-  (ess-process-put 'sp-for-help-changed? t)
-  ;; Action! :
-  (ess-get-modtime-list))
-
-(defun ess-filename-completion ()
-  "Return completion only within string or comment."
-  (save-restriction ;; explicitly handle inferior-ess
-    (ignore-errors
-      (when (and (derived-mode-p 'inferior-ess-mode)
-                 (> (point) (process-mark (get-buffer-process (current-buffer)))))
-        (narrow-to-region (process-mark (get-buffer-process (current-buffer)))
-                          (point-max))))
-    (when (and (not (equal ?` (nth 3 (syntax-ppss (point)))))
-               (ess-inside-string-or-comment-p (point)))
-      (append (comint-filename-completion) '(:exclusive no)))))
-
-(defun ess-complete-filename ()
-  "Do file completion only within strings."
-  (declare (obsolete comint-filename-completion "ESS 19.04"))
-  (save-restriction ;; explicitly handle inferior-ess
-    (ignore-errors
-      (when (and (derived-mode-p 'inferior-ess-mode)
-                 (> (point) (process-mark (get-buffer-process (current-buffer)))))
-        (narrow-to-region (process-mark (get-buffer-process (current-buffer)))
-                          (point-max))))
-    (when (or (ess-inside-string-or-comment-p (point))) ;; usable within ess-mode as well
-      (comint-dynamic-complete-filename))))
-
-(defun ess-after-pathname-p nil
-  ;; Heuristic: after partial pathname if it looks like we're in a
-  ;; string, and that string looks like a pathname. Not the best for
-  ;; use with unix() (or it's alias, !). Oh well.
-  (declare (obsolete comint-filename-completion "ESS 19.04"))
-  (save-excursion
-    (save-match-data
-      (let ((opoint (point)))
-        (and (re-search-backward "\\(\"\\|'\\)[~/#$.a-zA-Z0-9][^ \t\n\"']*"
-                                 nil t)
-             (eq opoint (match-end 0)))))))
-
-\f
-;;*;; Functions handling the search list
-
-(defun ess-search-list (&optional force-update)
-  "Return the current search list as a list of strings.
-Elements which are apparently directories are expanded to full
-dirnames. Don't try to use cache if FORCE-UPDATE is non-nil. Is
-*NOT* used by \\[ess-execute-search], but by \\[ess-resynch],
-\\[ess-get-object-list], \\[ess-get-modtime-list],
-\\[ess-execute-objects], \\[ess-object-modtime],
-\\[ess-create-object-name-db], and (indirectly) by
-\\[ess-get-help-files-list]."
-  (with-current-buffer
-      (ess-get-process-buffer ess-current-process-name);to get *its* local vars
-    (let ((result nil)
-          (slist (ess-process-get 'search-list))
-          (tramp-mode nil)) ;; hack for bogus file-directory-p below
-      (if (and slist
-               (not force-update)
-               (not (ess-process-get 'sp-for-help-changed?)))
-          slist
-        ;; else, re-compute:
-        (ess-write-to-dribble-buffer " (ess-search-list ... ) ")
-        (let ((tbuffer (get-buffer-create " *search-list*"))
-              (homedir default-directory)
-              (my-search-cmd inferior-ess-search-list-command); from ess-buffer
-              elt)
-          (ess-command my-search-cmd tbuffer 0.05); <- sleep for dde only; does (erase-buffer)
-          (with-current-buffer tbuffer
-            ;; guaranteed by the initial space in its name: (buffer-disable-undo)
-            (goto-char (point-min))
-            (ess-write-to-dribble-buffer
-             (format "after '%s', point-max=%d\n" my-search-cmd (point-max)))
-            (while (re-search-forward "\"\\([^\"]*\\)\"" nil t)
-              (setq elt (buffer-substring (match-beginning 1) (match-end 1)))
-              ;;Dbg: (ess-write-to-dribble-buffer (format "  .. elt= %s \t" elt))
-              (if (and (string-match "^[^/]" elt)
-                       (file-directory-p (concat homedir elt)))
-                  (progn
-                    ;;Dbg: (ess-write-to-dribble-buffer "*IS* directory\n")
-                    (setq elt (concat homedir elt)))
-                ;;else
-                ;;dbg
-                ;;-             (ess-write-to-dribble-buffer "not dir.\n")
-                )
-              (setq result (append result (list elt))))
-            (kill-buffer tbuffer)))
-        result))))
-
-;;; ess-sl-modtime-alist is a list with elements as follows:
-;;;  * key             (directory or object name)
-;;;  * modtime         (list of 2 integers)
-;;;  * name, name ...  (accessible objects in search list posn labeled by key)
-;;; 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 (&optional cache-var-name exclude-first)
-  "Record directories in the search list, and the objects in those directories.
-The result is stored in CACHE-VAR-NAME. If nil, CACHE-VAR-NAME
-defaults to `ess-sl-modtime-alist'. If EXCLUDE-FIRST is non-nil
-don't recompile first object in the search list."
-  ;; Operation applies to process of current buffer
-  (let* ((searchlist (if exclude-first
-                         (cdr (ess-search-list))
-                       (ess-search-list)))
-         (index (if exclude-first 2 1))
-         (cache-name (or cache-var-name 'ess-sl-modtime-alist))
-         pack newalist)
-    (while searchlist
-      (setq
-       pack  (car searchlist)
-       newalist (append newalist
-                        (list (or (assoc pack (symbol-value cache-name))
-                                  (append
-                                   (list pack (ess-dir-modtime pack))
-                                   (prog2
-                                       (message "Forming completions for %s..." pack)
-                                       (ess-object-names pack index)
-                                     (message "Forming completions for %s...done" pack))))))
-       index  (1+ index)
-       searchlist  (cdr searchlist)))
-    ;;DBG:
-    (ess-write-to-dribble-buffer
-     (format "(%s): created new alist of length %d\n"
-             cache-var-name (length newalist)))
-    (set cache-name 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 process variable `search-list' up to
-date. `ess-completing-read' in \\[ess-read-object-name] uses this
-list indirectly when it prompts for help or for an object to
-dump. From ESS 12.09 this is not necessary anymore, as the search
-path is checked on idle time. It is kept for robustness and
-backward compatibility only."
-  (when ess-change-sp-regexp
-    (if (string-match ess-change-sp-regexp str)
-        (ess-process-put 'sp-for-help-changed? t))))
-
-\f
-;;; Miscellaneous routines
-
-;;;*;;; Routines for reading object names
-(defun ess-read-object-name (p-string)
-  "Read an object name from the minibuffer with completion, and return it.
-P-STRING is the prompt string."
-  (let* ((default (ess-read-object-name-dump))
-         (object-list (ess-get-object-list ess-local-process-name))
-         (spec (ess-completing-read p-string object-list nil nil nil nil default)))
-    (list (cond
-           ((string= spec "") default)
-           (t spec)))))
-
-(defun ess-read-object-name-default ()
-  "Return the object name at point, or nil if none."
-  (ignore-errors
-    (save-excursion
-      ;; The following line circumvents an 18.57 bug in following-char
-      (if (eobp) (backward-char 1))   ; Hopefully buffer is not empty!
-      ;; Get onto a symbol
-      (catch 'nosym          ; bail out if there's no symbol at all before point
-        (while (let ((sc (char-syntax (following-char))))
-                 (not (or (= sc ?w) (= sc ?_))))
-          (if (bobp) (throw 'nosym nil) (backward-char 1))))
-      (let*
-          ((end (progn (forward-sexp 1) (point)))
-           (beg (progn (backward-sexp 1) (point))))
-        (buffer-substring-no-properties beg end)))))
-
-(defun ess-read-object-name-dump ()
-  "Return the object name at point, or \"Temporary\" if none."
-  (ignore-errors
-    (save-excursion
-      ;; Get onto a symbol
-      (catch 'nosym ; bail out if there's no symbol at all before point
-        (while (/= (char-syntax (following-char)) ?w)
-          (if (bobp) (throw 'nosym nil) (backward-char 1)))
-        (let*
-            ((end (progn (forward-sexp 1) (point)))
-             (beg (progn (backward-sexp 1) (point)))
-             (object-name (buffer-substring beg end)))
-          (or object-name "Temporary"))))))
-
-;;;; start of ess-smart-operators
-;;;; inspired by slime repl shortcuts
-
-(defvar ess--handy-history nil)
-
-(defun ess-handy-commands ()
-  "Request and execute a command from variable `ess-handy-commands'."
-  (interactive)
-  (let* ((commands (or ess--local-handy-commands
-                       ess-handy-commands))
-         (hist (and (assoc (car ess--handy-history)
-                           commands)
-                    (car ess--handy-history))))
-    (call-interactively
-     (cdr (assoc (ess-completing-read "Execute"
-                                      (sort (mapcar #'car commands)
-                                            #'string-lessp)
-                                      nil t nil 'ess--handy-history hist)
-                 commands)))))
-
-(defun ess-smart-comma ()
-  "If comma is invoked at the process marker of an ESS inferior
-buffer, request and execute a command from `ess-handy-commands'
-list."
-  (interactive)
-  (let ((proc (get-buffer-process (current-buffer))))
-    (if (and proc
-             (eq (point) (marker-position (process-mark proc))))
-        (ess-handy-commands)
-      (if ess-smart-operators
-          (progn
-            (delete-horizontal-space)
-            (insert ", ")
-            (unless (derived-mode-p 'inferior-ess-mode)
-              (indent-according-to-mode)))
-        (insert ",")))))
-
-\f ; directories
-(defun ess-set-working-directory (path &optional no-error)
-  "Set the current working to PATH for the ESS buffer and iESS process.
-NO-ERROR prevents errors when this has not been implemented for
-`ess-dialect'."
-  (interactive "DChange working directory to: ")
-  (if ess-setwd-command
-      (let* ((remote (file-remote-p path))
-             (path (if remote
-                       (progn
-                         (require 'tramp-sh)
-                         (tramp-sh-handle-expand-file-name path))
-                     path))
-             (lpath (if remote
-                        (with-parsed-tramp-file-name path v v-localname)
-                      path)))
-        (ess-eval-linewise (format ess-setwd-command lpath))
-        (ess-set-process-variable 'default-directory
-                                  (file-name-as-directory path)))
-    (unless no-error
-      (error "Not implemented for dialect %s" ess-dialect))))
-
-(defalias 'ess-change-directory #'ess-set-working-directory)
-(define-obsolete-function-alias
-  'ess-use-dir #'ess-set-working-directory "ESS 18.10")
-
-(defun ess-use-this-dir (&rest _ignore)
-  "Set the current process directory to the directory of this file.
-`default-directory' is used as a fallback."
-  (interactive)
-  (let ((dir (if buffer-file-name
-                 (file-name-directory buffer-file-name)
-               default-directory)))
-    (ess-set-working-directory (abbreviate-file-name dir))))
-
-(defun ess-get-working-directory (&optional no-error)
-  "Retrieve the current working directory from the current ess process."
-  (if ess-getwd-command
-      (abbreviate-file-name (car (ess-get-words-from-vector ess-getwd-command)))
-    (unless no-error
-      (error "Not implemented for dialect %s" ess-dialect))))
-
-(defun ess-synchronize-dirs ()
-  "Set Emacs' current directory to be the same as the subprocess directory.
-To be used in `ess-idle-timer-functions'."
-  (when (and (ess-can-eval-in-background)
-             ess-getwd-command
-             (inferior-ess-available-p))
-    (ess-when-new-input last-sync-dirs
-      (ess-if-verbose-write "\n(ess-synchronize-dirs)\n")
-      (let ((lpath (car (ess-get-words-from-vector ess-getwd-command))))
-        (setq default-directory
-              (file-name-as-directory
-               (ess--derive-connection-path default-directory lpath))))
-      default-directory)))
-
-(defun ess-dirs ()
-  "Set Emacs' current directory to be the same as the *R* process."
-  ;; Note: This function is not necessary anymore. The Emacs
-  ;; default-directory and subprocess working directory are
-  ;; synchronized automatically.
-  (interactive)
-  (let* ((dir (car (ess-get-words-from-vector "getwd()\n")))
-         (new-default-dir (ess--derive-connection-path default-directory dir)))
-    (message "(ESS / default) directory: %s" dir)
-    (setq default-directory (file-name-as-directory new-default-dir))))
-
-(defun ess--derive-connection-path (old new)
-  "Derive a (possibly remote) path with an updated local filename.
-A new connection path is derived from OLD (a path) and NEW (a
-path), in such a way that the host and connection information (if
-any) in OLD is retained in the NEW path. NEW must be an absolute
-path, and can be a remote path"
-  (concat (file-remote-p old)
-          (or (file-remote-p new 'localname) new)))
-
-;; search path
-(defun ess--mark-search-list-as-changed ()
-  "Internal. Mark all the search-list related variables as changed."
-  ;; other guys might track their own
-  (ess-process-put 'sp-for-help-changed? t)
-  (ess-process-put 'sp-for-ac-changed? t))
-
-(defun ess-cache-search-list ()
-  "To be used in `ess-idle-timer-functions', to set search path related variables."
-  (when (and (ess-can-eval-in-background)
-             inferior-ess-search-list-command)
-    (ess-when-new-input last-cache-search-list
-      (let ((path (ess-search-list 'force))
-            (old-path (process-get *proc* 'search-list)))
-        (when (not (equal path old-path))
-          (process-put *proc* 'search-list path)
-          (ess--mark-search-list-as-changed)
-          path)))))
-
-\f
-;;*;; Temporary buffer handling
-(defun ess-display-temp-buffer (buff)
-  "Display the buffer BUFF.
-Uses `temp-buffer-show-function' and respects
-`ess-display-buffer-reuse-frames'."
-  (if (fboundp temp-buffer-show-function)
-      (funcall temp-buffer-show-function buff))
-  (display-buffer buff '(display-buffer-reuse-window) ess-display-buffer-reuse-frames))
-
-(defun ess--inject-code-from-file (file &optional chunked)
-  "Load code from FILE into process.
-If CHUNKED is non-nil, split the file by \\^L separator (must be at
-bol) and load each chunk separately."
-  ;; This is different from ess-load-file as it works by directly loading the
-  ;; string into the process and thus works on remotes.
-  (let ((proc-name ess-local-process-name)
-        (dialect ess-dialect)
-        (send-1 (lambda (str)
-                  (if (string= ess-dialect "R")
-                      ;; avoid detection of intermediate prompts
-                      (ess-command (concat "{" str "}\n"))
-                    (ess-command str)))))
-    (with-temp-buffer
-      (setq ess-local-process-name proc-name
-            ess-dialect dialect)
-      (insert-file-contents-literally file)
-      (if chunked
-          (let ((beg (point-min)))
-            (goto-char beg)
-            (while (re-search-forward "^\f" nil t)
-              (funcall send-1 (buffer-substring beg (point)))
-              (setq beg (point)))
-            (funcall send-1 (buffer-substring (point) (point-max))))
-        (funcall send-1 (buffer-string))))))
-
-(defun ess-check-modifications nil
-  "Check whether loading this file would overwrite some ESS objects
-which have been modified more recently than this file, and confirm
-if this is the case."
-  (declare (obsolete "Do not use" "21.04"))
-  (when (> (length ess-change-sp-regexp) 0)
-    (and (buffer-file-name) ess-filenames-map
-         (let ((sourcemod (nth 5 (file-attributes (buffer-file-name))))
-               (objname))
-           (save-excursion
-             (goto-char (point-min))
-             ;; Get name of assigned object, if we can find it
-             (setq objname
-                   (and
-                    (re-search-forward
-                     "^\\s *\"?\\(\\(\\sw\\|\\s_\\)+\\)\"?\\s *[<_]"
-                     nil
-                     t)
-                    (buffer-substring (match-beginning 1)
-                                      (match-end 1)))))
-           (and
-            sourcemod                  ; the file may have been deleted
-            objname                    ; may not have been able to
-                                        ; find name
-            (ess-modtime-gt (ess-object-modtime objname) sourcemod)
-            (not (y-or-n-p
-                  (format
-                   "The ESS object %s is newer than this file. Continue? "
-                   objname)))
-            (error "Aborted"))))))
-
-(define-obsolete-function-alias 'ess-check-source #'ess-save-file "ESS 19.04")
-(defun ess-save-file (file)
-  "If FILE (a string) has an unsaved buffer, offer to save it.
-Return t if the buffer existed and was modified, but was not
-saved. If `ess-save-silently' is non-nil, the buffer is
-saved without offering."
-  (when-let ((buff (find-buffer-visiting file)))
-    (when (and (buffer-modified-p buff)
-               (or (eql ess-save-silently t)
-                   (and (eql ess-save-silently 'auto)
-                        (or (not compilation-ask-about-save)
-                            (bound-and-true-p
-                             ;; Only added in Emacs 26.1
-                             auto-save-visited-mode)))
-                   (y-or-n-p
-                    (format "Buffer %s is modified. Save? "
-                            (buffer-name buff)))))
-      (with-current-buffer buff
-        (save-buffer)))
-    (buffer-modified-p buff)))
-
-\f
-;;*;; Error messages
-
-(defun ess-parse-errors (&optional showerr _reset)
-  "Jump to error in last loaded ESS source file.
-With prefix argument SHOWERR, only show the errors ESS reported. RESET
-is for compatibility with `next-error' and is ignored."
-  (interactive "P")
-  (ess-make-buffer-current)
-  (let ((errbuff (get-buffer ess-error-buffer-name)))
-    (when (not errbuff)
-      (error "You need to do a load first!"))
-    (set-buffer errbuff)
-    (goto-char (point-max))
-    ;; FIXME: R does not give "useful" error messages by default. We
-    ;; could try to use a more useful one, via
-    ;; options(error=essErrorHandler)
-    (cond ((re-search-backward ess-error-regexp nil t)
-           (let* ((filename (buffer-substring (match-beginning 3) (match-end 3)))
-                  (fbuffer (get-file-buffer filename))
-                  (linenum
-                   (string-to-number
-                    (buffer-substring (match-beginning 2) (match-end 2))))
-                  (errmess (buffer-substring (match-beginning 1) (match-end 1))))
-             (if showerr
-                 (ess-display-temp-buffer errbuff)
-               (if fbuffer nil
-                 (setq fbuffer (find-file-noselect filename))
-                 (with-current-buffer fbuffer
-                   ;; TODO: ess-mode is surely wrong here, but I don't
-                   ;; think we need this whole function anymore?
-                   (when (fboundp 'ess-mode)
-                     (ess-mode))))
-               (pop-to-buffer fbuffer)
-               (ess-goto-line linenum))
-             (princ errmess t)))
-          (t
-           (message "Not a syntax error.")
-           (ess-display-temp-buffer errbuff)))))
-
-(defun ess-error (msg)
-  "Something bad has happened.
-Display the S buffer, and cause an error displaying MSG."
-  (declare (obsolete error "ESS 18.10"))
-  (display-buffer (process-buffer (get-process ess-local-process-name)))
-  (error msg))
-
-(provide 'ess-inf)
-;;; ess-inf.el ends here
diff --git a/elpa/ess-20251212.937/ess-jags-d.el b/elpa/ess-20251212.937/ess-jags-d.el
deleted file mode 100644 (file)
index 5700f33..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-;;; ess-jags-d.el --- ESS[JAGS] dialect  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2009-2022 Free Software Foundation, Inc.
-
-;; Author: Rodney Sparapani
-;; Created: 13 March 2008
-;; Maintainer: ESS Core Team <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Code:
-
-(require 'ess-bugs-d)
-(require 'ess-utils)
-(require 'ess-inf)
-(require 'ess-mode)
-
-(defvar ess-jags-command "jags" "Default JAGS program in PATH.")
-(make-local-variable 'ess-jags-command)
-
-(defvar ess-jags-monitor '("") "Default list of variables to monitor.")
-(make-local-variable 'ess-jags-monitor)
-
-(defvar ess-jags-thin 1 "Default thinning parameter.")
-(make-local-variable 'ess-jags-thin)
-
-(defvar ess-jags-chains 1 "Default number of chains.")
-(make-local-variable 'ess-jags-chains)
-
-(defvar ess-jags-burnin 10000 "Default burn-in.")
-(make-local-variable 'ess-jags-burnin)
-
-(defvar ess-jags-update 10000 "Default number of updates after burnin.")
-(make-local-variable 'ess-jags-update)
-
-(defvar ess-jags-system t "Default whether JAGS recognizes the system command.")
-
-(defvar ess-jags-font-lock-keywords
-  (list
-   ;; .jag files
-   (cons "#.*\n"                        font-lock-comment-face)
-
-   (cons "^[ \t]*\\(model\\|var\\)\\>"
-         font-lock-keyword-face)
-
-   (cons (concat "\\<d\\(bern\\|beta\\|bin\\|cat\\|chisq\\|"
-                 "dexp\\|dirch\\|exp\\|\\(gen[.]\\)?gamma\\|hyper\\|"
-                 "interval\\|lnorm\\|logis\\|mnorm\\|mt\\|multi\\|"
-                 "negbin\\|norm\\(mix\\)?\\|par\\|pois\\|sum\\|t\\|"
-                 "unif\\|weib\\|wish\\)[ \t\n]*(")
-         font-lock-constant-face)
-
-   (cons (concat "\\<\\(abs\\|cos\\|dim\\|\\(i\\)?cloglog\\|equals\\|"
-                 "exp\\|for\\|inprod\\|interp[.]line\\|inverse\\|length\\|"
-                 "\\(i\\)?logit\\|logdet\\|logfact\\|loggam\\|max\\|mean\\|"
-                 "mexp\\|min\\|phi\\|pow\\|probit\\|prod\\|rank\\|round\\|"
-                 "sd\\|sin\\|sort\\|sqrt\\|step\\|sum\\|t\\|trunc\\|T\\)[ \t\n]*(")
-         font-lock-function-name-face)
-
-   ;; .jmd files
-   (cons (concat "\\<\\(adapt\\|cd\\|clear\\|coda\\|data\\|dir\\|"
-                 "exit\\|in\\(itialize\\)?\\|load\\|model\\|monitors\\|parameters\\|"
-                 "pwd\\|run\\|s\\(amplers\\|ystem\\)\\|to\\|update\\)[ \t\n]")
-         font-lock-keyword-face)
-
-   (cons "\\<\\(compile\\|monitor\\)[, \t\n]"
-         font-lock-keyword-face)
-
-   (cons "[, \t\n]\\(by\\|chain\\|nchains\\|stem\\|thin\\|type\\)[ \t\n]*("
-         font-lock-function-name-face)
-   )
-  "ESS[JAGS]: Font lock keywords."
-  )
-
-(defun ess-jags-switch-to-suffix (suffix &optional jags-chains jags-monitor jags-thin
-                                         jags-burnin jags-update)
-  "ESS[JAGS]: Switch to file with suffix."
-  (find-file (concat ess-bugs-file-dir ess-bugs-file-root suffix))
-
-  (if (equal 0 (buffer-size)) (progn
-                                (if (equal ".jag" suffix) (progn
-                                                            (insert "var ;\n")
-                                                            (insert "model {\n")
-                                                            (insert "    for (i in 1:N) {\n    \n")
-                                                            (insert "    }\n")
-                                                            (insert "}\n")
-                                                            (insert "#Local Variables" ":\n")
-                                                            (insert "#ess-jags-chains:1\n")
-                                                            (insert "#ess-jags-monitor:(\"\")\n")
-                                                            (insert "#ess-jags-thin:1\n")
-                                                            (insert "#ess-jags-burnin:10000\n")
-                                                            (insert "#ess-jags-update:10000\n")
-                                                            (insert "#End:\n")
-                                                            ))
-
-                                (if (equal ".jmd" suffix) (let
-                                                              ((ess-jags-temp-chains "") (ess-jags-temp-monitor "") (ess-jags-temp-chain ""))
-
-                                                            (if jags-chains (setq ess-jags-chains jags-chains))
-                                                            (if jags-monitor (setq ess-jags-monitor jags-monitor))
-                                                            (if jags-thin (setq ess-jags-thin jags-thin))
-
-                                                            (setq ess-jags-temp-chains
-                                                                  (concat "compile, nchains(" (format "%d" ess-jags-chains) ")\n"))
-
-                                                            (setq jags-chains ess-jags-chains)
-
-                                                            (while (< 0 jags-chains)
-                                                              (setq ess-jags-temp-chains
-                                                                    (concat ess-jags-temp-chains
-                                                                            "parameters ## \"" ess-bugs-file-root
-                                                                            ".##" (format "%d" jags-chains) "\", chain("
-                                                                            (format "%d" jags-chains) ")\n"))
-                                                              (setq jags-chains (- jags-chains 1)))
-
-                                                            (setq ess-jags-temp-monitor "")
-
-                                                            (while (and (listp ess-jags-monitor) (consp ess-jags-monitor))
-                                                              (if (not (string-equal "" (car ess-jags-monitor)))
-                                                                  (setq ess-jags-temp-monitor
-                                                                        (concat ess-jags-temp-monitor "monitor "
-                                                                                (car ess-jags-monitor) ", thin(" (format "%d" ess-jags-thin) ")\n")))
-                                                              (setq ess-jags-monitor (cdr ess-jags-monitor)))
-
-                                                            (insert "model in \"" ess-bugs-file-root ".jag\"\n")
-                                                            (insert "data in \"" ess-bugs-file-root ".jdt\"\n")
-                                                            (insert (ess-replace-in-string ess-jags-temp-chains "##" "in"))
-                                                            (insert "initialize\n")
-                                                            ;(insert "update " (format "%d" (* jags-thin jags-burnin)) "\n")
-                                                            (insert "update " (format "%d" jags-burnin) "\n")
-                                                            (insert ess-jags-temp-monitor)
-                                                            (insert "update " (format "%d" (* jags-thin jags-update)) "\n")
-                                                            (insert (ess-replace-in-string
-                                                                     (ess-replace-in-string ess-jags-temp-chains
-                                                                                            "compile, nchains([0-9]+)" "#") "##" "to"))
-                                                            (insert "coda "
-                                                                    ;(if ess-microsoft-p (if (w32-shell-dos-semantics) "*" "\\*") "\\*")
-                                                                    "*, stem(\"" ess-bugs-file-root "\")\n")
-
-                                                            (if ess-jags-system (progn
-                                                                                  (insert "system rm -f " ess-bugs-file-root ".ind\n")
-                                                                                  (insert "system ln -s " ess-bugs-file-root "index.txt " ess-bugs-file-root ".ind\n")
-
-                                                                                  (setq jags-chains ess-jags-chains)
-
-                                                                                  (while (< 0 jags-chains)
-                                                                                    (setq ess-jags-temp-chain (format "%d" jags-chains))
-
-                                        ;.txt not recognized by BOA and impractical to over-ride
-                                                                                    (insert "system rm -f " ess-bugs-file-root ess-jags-temp-chain ".out\n")
-                                                                                    (insert "system ln -s " ess-bugs-file-root "chain" ess-jags-temp-chain ".txt "
-                                                                                            ess-bugs-file-root ess-jags-temp-chain ".out\n")
-                                                                                    (setq jags-chains (- jags-chains 1)))))
-
-                                                            (insert "exit\n")
-                                                            (insert "Local Variables" ":\n")
-                                                            (insert "ess-jags-chains:" (format "%d" ess-jags-chains) "\n")
-                                                            (insert "ess-jags-command:\"jags\"\n")
-                                                            (insert "End:\n")
-                                                            ))
-                                ))
-  )
-
-(defun ess-jags-na-jmd (jags-command)
-  "ESS[JAGS]: Perform the Next-Action for .jmd."
-                                        ;(ess-save-and-set-local-variables)
-  (if (equal 0 (buffer-size)) (ess-jags-switch-to-suffix ".jmd")
-                                        ;else
-    (shell)
-    (ess-sleep)
-
-    (if (when (fboundp 'w32-shell-dos-semantics)
-          (w32-shell-dos-semantics))
-        (if (string-equal ":" (substring ess-bugs-file 1 2))
-            (progn
-              (insert (substring ess-bugs-file 0 2))
-              (comint-send-input)
-              )
-          )
-      )
-
-    (insert "cd \"" ess-bugs-file-dir "\"")
-    (comint-send-input)
-
-                                        ;    (let ((ess-jags-temp-chains ""))
-                                        ;
-                                        ;       (while (< 0 jags-chains)
-                                        ;           (setq ess-jags-temp-chains
-                                        ;               (concat (format "%d " jags-chains) ess-jags-temp-chains))
-                                        ;           (setq jags-chains (- jags-chains 1)))
-
-    (insert ess-bugs-batch-pre-command " " jags-command " "
-            ess-bugs-file-root ".jmd "
-
-            (if (or (equal shell-file-name "/bin/csh")
-                    (equal shell-file-name "/bin/tcsh")
-                    (equal shell-file-name "/bin/zsh")
-                    (equal shell-file-name "/bin/bash"))
-                (concat ">& " ess-bugs-file-root ".jog ")
-                                        ;else
-              "> " ess-bugs-file-root ".jog 2>&1 ")
-
-                                        ;               ;.txt not recognized by BOA and impractical to over-ride
-                                        ;               "&& (rm -f " ess-bugs-file-root ".ind; "
-                                        ;               "ln -s " ess-bugs-file-root "index.txt " ess-bugs-file-root ".ind; "
-                                        ;               "for i in " ess-jags-temp-chains "; do; "
-                                        ;               "rm -f " ess-bugs-file-root "$i.out; "
-                                        ;               "ln -s " ess-bugs-file-root "chain$i.txt " ess-bugs-file-root "$i.out; done) "
-
-            ess-bugs-batch-post-command)
-
-    (comint-send-input)
-    ))
-
-(defun ess-jags-na-bug ()
-  "ESS[JAGS]: Perform Next-Action for .jag"
-
-  (if (equal 0 (buffer-size)) (ess-jags-switch-to-suffix ".jag")
-                                        ;else
-    (ess-save-and-set-local-variables)
-    (ess-jags-switch-to-suffix ".jmd"
-                               ess-jags-chains ess-jags-monitor ess-jags-thin ess-jags-burnin ess-jags-update))
-  )
-
-;;;###autoload
-(define-derived-mode ess-jags-mode ess-bugs-mode "ESS[JAGS]"
-  "Major mode for JAGS."
-  (setq-local comment-start "#")
-  (setq font-lock-defaults '(ess-jags-font-lock-keywords nil t))
-  (setq ess-language "S") ; mimic S for ess-smart-underscore
-  (unless (and (fboundp 'w32-shell-dos-semantics)
-               (w32-shell-dos-semantics))
-    (add-hook 'comint-output-filter-functions #'ess-bugs-exit-notify-sh))
-  )
-
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.[Jj][Aa][Gg]\\'" . ess-jags-mode))
-
-(provide 'ess-jags-d)
-
-;;; ess-jags-d.el ends here
diff --git a/elpa/ess-20251212.937/ess-julia.el b/elpa/ess-20251212.937/ess-julia.el
deleted file mode 100644 (file)
index 27ebed2..0000000
+++ /dev/null
@@ -1,460 +0,0 @@
-;; ess-julia.el --- ESS julia mode and inferior interaction  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2012-2022 Free Software Foundation, Inc.
-;; Author: Vitalie Spinu
-;; Maintainer: Vitalie Spinu
-;; Created: 02-04-2012 (ESS 12.03)
-;; Keywords: ESS, julia
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;;  Customize inferior-julia-program to point to your julia binary
-;;  and start the inferior with M-x julia.
-
-;;  As of Sept 2015, this file depends heavily on julia-mode.el from the Julia
-;;  sources.  If you install ESS using `make', this will work fine, otherwise
-;;  ensure that julia-mode.el is on your path before loading this file.
-
-;;; Code:
-
-(require 'ess-help)
-(require 'ess-inf)
-(require 'ess-r-mode)
-(require 'ess-utils)
-;; Don't require `julia-mode' to compile this file.
-(when t (require 'julia-mode))
-(declare-function julia-mode "julia-mode" ())
-(declare-function julia-mode-latexsub-completion-at-point-before "julia-mode" ())
-(declare-function julia-mode-latexsub-completion-at-point-around "julia-mode" ())
-(defvar julia-mode-syntax-table)
-
-(defvar ac-prefix)
-(declare-function company-in-string-or-comment "company")
-(declare-function company-doc-buffer "company")
-
-(defcustom inferior-julia-args ""
-  "String of arguments (see `julia --help') used when starting julia."
-  :group 'ess-julia
-  :type 'string)
-
-(eval-when-compile
-  (require 'cl-lib))
-
-(defun ess-julia-send-string-function (process string _visibly)
-  "Send the Julia STRING to the PROCESS.
-VISIBLY is not currently used."
-  (let ((file (concat temporary-file-directory "julia_eval_region.jl")))
-    (with-temp-file file
-      (insert string))
-    (process-send-string process (format ess-load-command file))))
-
-\f
-;;; HELP
-(cl-defmethod ess-help-get-topics (proc &context (ess-dialect "julia"))
-  (append (with-current-buffer (ess--foreground-command "ESS.all_help_topics()\n")
-            (split-string (buffer-string) "\n"))
-          (ess-julia--get-objects proc)))
-
-(defun ess-julia--retrieve-topics (url)
-  (with-current-buffer (url-retrieve-synchronously url)
-    (require 'url)
-    (goto-char (point-min))
-    (let (out)
-      (while (re-search-forward
-              "toctext[ \"]+href=\"\\([^>]+\\)\">\\([^<]+\\)</a" nil t)
-        (push (propertize (match-string 2)
-                          :manual (concat url (match-string 1)))
-              out))
-      (kill-buffer)
-      (nreverse out))))
-
-(defvar ess-julia--manual-topics nil)
-(cl-defmethod ess--manual-lookup-override (&context (ess-dialect "julia"))
-  "Look up topics at https://docs.julialang.org/en/latest/manual/."
-  (let* ((pages (or ess-julia--manual-topics
-                    (setq ess-julia--manual-topics
-                          (ess-julia--retrieve-topics
-                           "https://docs.julialang.org/en/latest/"))))
-         (page (ess-completing-read "Lookup:" pages nil t)))
-    (browse-url (get-text-property 1 :manual page))))
-
-(defun ess-julia-input-sender (proc string)
-  "Function to send PROC STRING submitted by user.
-See `comint-input-sender'."
-  (save-current-buffer
-    (let* ((help-?-regexp "^ *\\(?:\\(?1: *?\\? *\\)\\(?2:.+\\)\\)")
-           (help-?-match (string-match help-?-regexp string)))
-      (cond (help-?-match
-             (ess-display-help-on-object (match-string 2 string))
-             (process-send-string proc "\n"))
-            (t ;; normal command
-             (inferior-ess-input-sender proc string))))))
-
-(cl-defmethod ess-installed-packages (&context (ess-dialect "julia"))
-  "Return list of installed julia packages."
-  ;; FIXME: This doesn't work if the user hasn't done "using Pkg" yet
-  (ess-get-words-from-vector "keys(Pkg.installed())\n"))
-
-(cl-defmethod ess-load-library--override (pack &context (ess-dialect "julia"))
-  (ess-eval-linewise (format "using %s\n" pack)))
-
-\f
-;;; COMPLETION
-
-(defun ess-julia-object-completion ()
-  "Return completions in format required by `completion-at-point-functions'."
-  (let ((proc (ess-get-next-available-process ess-dialect t))
-        (beg (ess-symbol-start)))
-    (if proc
-        (when beg
-          (let* ((prefix (buffer-substring-no-properties beg (point)))
-                 (obj (and (string-match "\\(.*\\)\\..*$" prefix)
-                           (match-string 1 prefix)))
-                 (beg (if obj
-                          (+ beg 1 (length obj))
-                        beg)))
-            (list beg (point)
-                  (nreverse (mapcar #'car (ess-julia--get-objects proc obj)))
-                  :exclusive 'no)))
-      (when (string-match "complet" (symbol-name last-command))
-        (message "No ESS process of dialect %s started" ess-dialect)
-        nil))))
-
-(defun ess-julia-objects (prefix &optional proc)
-  "Given PREFIX get all cached objects from PROC."
-  (when prefix
-    (let ((proc (or proc (ess-get-next-available-process nil t))))
-      (if (string-match "\\(.*\\)\\..*$" prefix)
-          (let ((module (match-string 1 prefix)))
-            (mapcar (lambda (el) (concat module "." (car el)))
-                    (ess-julia--get-objects proc module)))
-        (ess-julia--get-objects proc)))))
-
-(defun ess-julia--get-objects (&optional proc obj)
-  "Return all available objects.
-Local caching might be used. If MODULE is given, return only
-objects from that MODULE."
-  (setq proc (or proc (ess-get-process)))
-  (when (stringp proc)
-    (setq proc (get-process proc)))
-  (when (process-live-p proc)
-    (let ((objects (process-get proc 'objects)))
-      (if (process-get proc 'busy)
-          (if obj
-              (assoc obj objects)
-            (process-get proc 'objects))
-        (if obj
-            (or (cdr (assoc obj objects))
-                ;; don't cache composite objects and datatypes
-                (ess-julia--get-components proc obj))
-          ;; this segment is entered when user completion at top level is
-          ;; requested, either Tab or AC. Hence Main is always updated.
-          (let ((modules (ess-get-words-from-vector
-                          "ESS.main_modules()\n" nil nil proc))
-                (loc (process-get proc 'last-objects-cache))
-                (lev (process-get proc 'last-eval)))
-            (prog1
-                (apply #'nconc
-                       (mapcar
-                        (lambda (mod)
-                          ;; we are caching all modules, and reinit Main every
-                          ;; time user enters commands
-                          (copy-sequence
-                           (or (and (or (not (equal mod "Main"))
-                                        (ignore-errors (time-less-p lev loc)))
-                                    (cdr (assoc mod objects)))
-                               (ess-julia--get-components proc mod t))))
-                        modules))
-              (process-put proc 'last-objects-cache (current-time)))))))))
-
-(defun ess-julia--get-components (proc obj &optional cache?)
-  (with-current-buffer (ess--foreground-command (format "ESS.components(%s)\n" obj)
-                                                nil nil nil nil proc)
-    (goto-char (point-min))
-    (let (list)
-      (while (re-search-forward
-              "^\\([^ \t\n]+\\) +\\([^ \t\n]+\\)$" nil t)
-        (push (cons (match-string 1) (match-string 2)) list))
-      (when cache?
-        (let ((objects (process-get proc 'objects)))
-          (push (cons obj list) objects)
-          (process-put proc 'objects objects)))
-      list)))
-
-(defun ess-julia-get-object-help-string (sym)
-  "Help string for ac."
-  (let ((proc (ess-get-next-available-process nil t)))
-    (if (null proc)
-        "No free ESS process found"
-      (let ((buf (get-buffer-create " *ess-command-output*")))
-        (with-current-buffer (process-buffer proc)
-          (ess-with-current-buffer buf
-            (ess--flush-help-into-current-buffer sym nil)))
-        (with-current-buffer buf
-          (ess-help-underline)
-          (goto-char (point-min))
-          (buffer-string))))))
-
-(defvar ac-source-ess-julia-objects
-  '((prefix     . ess-symbol-start)
-    (requires   . 2)
-    (candidates . ess-ac-julia-objects)
-    (document   . ess-julia-get-object-help-string))
-  "Auto-completion source for julia objects.")
-
-(defun ess-ac-julia-objects ()
-  (require 'auto-complete)
-  (ess-julia-objects ac-prefix))
-
-(declare-function company-begin-backend "company.el")
-
-(defun company-ess-julia-objects (command &optional arg &rest _ignored)
-  (interactive (list 'interactive))
-  (cl-case command
-    (interactive (company-begin-backend 'company-ess-julia-objects))
-    (prefix (unless (company-in-string-or-comment)
-              (let ((start (ess-symbol-start)))
-                (when start (buffer-substring-no-properties start (point))))))
-    (candidates (let ((proc (ess-get-next-available-process)))
-                  (when proc
-                    (all-completions arg (mapcar (lambda (x) (or (car-safe x) x))
-                                                 (ess-julia-objects arg proc))))))
-    (doc-buffer (company-doc-buffer (ess-julia-get-object-help-string arg)))))
-
-\f
-;;; ERRORS
-(defvar ess-julia-error-regexp-alist '(ess-julia-in ess-julia-at ess-julia-while-load)
-  "List of symbols which are looked up in `compilation-error-regexp-alist-alist'.")
-
-(add-to-list 'compilation-error-regexp-alist-alist
-             '(ess-julia-in  "^\\s-*in [^ \t\n]* \\(at \\(.*\\):\\([0-9]+\\)\\)" 2 3 nil 2 1))
-(add-to-list 'compilation-error-regexp-alist-alist
-             '(ess-julia-at "^\\S-+\\s-+\\(at \\(.*\\):\\([0-9]+\\)\\)"  2 3 nil 2 1))
-(add-to-list 'compilation-error-regexp-alist-alist
-             '(ess-julia-while-load "^\\s-*\\(while loading\\s-\\(.*\\), in .* on line +\\([0-9]+\\)\\)"  2 3 nil 2 1))
-
-\f
-;;; ELDOC
-(defun ess-julia-eldoc-function (&rest _ignored)
-  "Return the doc string, or nil.
-If an ESS process is not associated with the buffer, do not try
-to look up any doc strings. Honors `eldoc-echo-area-use-multiline-p'."
-  (when (and (ess-can-eval-in-background)
-             (ess-process-live-p)
-             (not (ess-process-get 'busy)))
-    (let ((funname (or (and ess-eldoc-show-on-symbol ;; aggressive completion
-                            (symbol-name (ess-symbol-at-point)))
-                       (car (ess--fn-name-start))))
-          (multiline (eq t eldoc-echo-area-use-multiline-p)))
-      (when funname
-        (let* ((args (copy-sequence (nth 2 (ess-function-arguments funname))))
-               (W (- (window-width (minibuffer-window)) (+ 4 (length funname))))
-               (doc (concat (propertize funname 'face font-lock-function-name-face) ": ")))
-          (when args
-            (setq args (sort args (lambda (s1 s2)
-                                    (< (length s1) (length s2)))))
-            (setq doc (concat doc (pop args)))
-            (while (and args (or multiline (< (+ (length doc) (length (car args))) W)))
-              (setq doc (concat doc "  " (pop args))))
-            (when (and args (< (length doc) W))
-              (setq doc (concat doc " {--}")))
-            doc))))))
-
-\f
-;;; CORE
-(defvar ess-julia-customize-alist
-  '((inferior-ess-primary-prompt   . "\\w*> ")
-    (inferior-ess-secondary-prompt . nil)
-    (inferior-ess-prompt           . "\\w*> ")
-    (ess-local-customize-alist     . 'ess-julia-customize-alist)
-    (inferior-ess-program          . inferior-julia-program)
-    (ess-load-command              . "include(expanduser(\"%s\"))\n")
-    (ess-funargs-command           . "ESS.fun_args(\"%s\")\n")
-    (ess-dump-error-re             . "in \\w* at \\(.*\\):[0-9]+")
-    (ess-error-regexp              . "\\(^\\s-*at\\s-*\\(?3:.*\\):\\(?2:[0-9]+\\)\\)")
-    (ess-error-regexp-alist        . ess-julia-error-regexp-alist)
-    (ess-mode-completion-syntax-table . ess-julia-completion-syntax-table)
-    ;; (inferior-ess-objects-command    . inferior-ess-r-objects-command)
-    ;; (inferior-ess-search-list-command        . "search()\n")
-    (inferior-ess-help-command     . "ESS.help(\"%s\")\n")
-    ;; (inferior-ess-help-command       . "help(\"%s\")\n")
-    (ess-language                  . "julia")
-    (ess-dialect                   . "julia")
-    (ess-suffix                    . "jl")
-    (ess-dump-filename-template    . (replace-regexp-in-string
-                                      "S$" ess-suffix ; in the one from custom:
-                                      ess-dump-filename-template-proto))
-    (ess-mode-editing-alist        . nil)
-    (ess-change-sp-regexp          . nil );ess-r-change-sp-regexp)
-    (ess-help-sec-regex            . ess-help-r-sec-regex)
-    (ess-help-sec-keys-alist       . ess-help-r-sec-keys-alist)
-    (ess-function-pattern          . ess-r-function-pattern)
-    (ess-object-name-db-file       . "ess-jl-namedb.el" )
-    (ess-smart-operators           . ess-r-smart-operators)
-    (inferior-ess-exit-command     . "exit()\n")
-    ;;harmful for shell-mode's C-a: -- but "necessary" for ESS-help?
-    (inferior-ess-language-start   . nil)
-    (ess-STERM                     . "iESS")
-    (ess-editor                    . ess-r-editor)
-    (ess-pager                     . ess-r-pager)
-    (ess-getwd-command             . "pwd()\n")
-    (ess-setwd-command             . "cd(expanduser(\"%s\"))\n"))
-  "Variables to customize for Julia.")
-
-(cl-defmethod ess--help-web-search-override (cmd &context (ess-dialect "julia"))
-  "Offer to search the web for a Julia command."
-  (browse-url (format "https://docs.julialang.org/en/latest/search/?q=%s" cmd)))
-
-(defvar ess-julia-completion-syntax-table
-  (let ((table (copy-syntax-table ess-r-mode-syntax-table)))
-    (modify-syntax-entry ?. "_" table)
-    ;; (modify-syntax-entry ?: "_" table)
-    ;; (modify-syntax-entry ?$ "_" table)
-    (modify-syntax-entry ?@ "_" table)
-    table)
-  "Syntax table used for completion and help symbol lookup.
-It makes underscores and dots word constituent chars.")
-
-(cl-defmethod ess-help-commands (&context (ess-dialect "julia"))
-  '((packages      . "_ess_list_categories()\n")
-    (package-index . "_ess_print_index(\"%s\")\n")
-    (index-keyword-reg . "^\\(.*+\\):$*")
-    (index-start-reg   . ":")))
-
-(defvar ess-julia-mode-syntax-table (copy-syntax-table julia-mode-syntax-table))
-
-(defvar ess-julia-mode-map
-  (let ((map (make-sparse-keymap)))
-    (set-keymap-parent map ess-mode-map)
-    map)
-  "Keymap for `ess-julia-mode'.")
-
-;;;###autoload
-(define-derived-mode ess-julia-mode julia-mode "ESS[julia]"
-  "Major mode for julia files."
-  :group 'ess-Julia
-  (setq-local ess-local-customize-alist ess-julia-customize-alist)
-  (setq ess-dialect "julia")
-  (ess-setq-vars-local ess-julia-customize-alist)
-  ;; eldoc
-  (ess--setup-eldoc #'ess-julia-eldoc-function)
-  ;; auto-complete
-  (ess--setup-auto-complete '(ac-source-ess-julia-objects))
-  ;; company
-  (ess--setup-company '(company-ess-julia-objects))
-  ;; for emacs >= 24
-  (remove-hook 'completion-at-point-functions #'ess-filename-completion 'local) ;; should be first
-  (add-hook 'completion-at-point-functions #'ess-julia-object-completion nil 'local)
-  (add-hook 'completion-at-point-functions #'ess-filename-completion nil 'local)
-  (add-hook 'completion-at-point-functions #'julia-mode-latexsub-completion-at-point-before nil 'local)
-  (add-hook 'completion-at-point-functions #'julia-mode-latexsub-completion-at-point-around nil 'local)
-  (if (fboundp 'ess-add-toolbar) (ess-add-toolbar)))
-
-;; Inferior mode
-(defvar inferior-ess-julia-mode-syntax-table
-  (copy-syntax-table ess-julia-mode-syntax-table)
-  "Syntax table for `inferior-ess-julia-mode'.")
-
-(define-derived-mode inferior-ess-julia-mode inferior-ess-mode "iESS[julia]"
-  "Major mode for inferior julia processes."
-  :group 'ess-Julia
-  (ess-setq-vars-local ess-julia-customize-alist)
-  (setq-local comint-use-prompt-regexp t)
-  (setq comint-prompt-regexp (concat "^" inferior-ess-prompt))
-  (setq ess-dialect "julia")
-  ;; eldoc
-  (ess--setup-eldoc #'ess-julia-eldoc-function)
-  ;; auto-complete
-  (ess--setup-auto-complete '(ac-source-ess-julia-objects) t)
-  ;; company
-  (ess--setup-company '(company-ess-julia-objects) t)
-  (remove-hook 'completion-at-point-functions #'ess-filename-completion 'local) ;; should be first
-  (add-hook 'completion-at-point-functions #'ess-julia-object-completion nil 'local)
-  (add-hook 'completion-at-point-functions #'ess-filename-completion nil 'local)
-  (add-hook 'completion-at-point-functions #'julia-mode-latexsub-completion-at-point-before nil 'local)
-  (add-hook 'completion-at-point-functions #'julia-mode-latexsub-completion-at-point-around nil 'local)
-  (setq comint-input-sender #'ess-julia-input-sender))
-
-(defvar ess-julia-mode-hook nil)
-(defvar ess-julia-post-run-hook nil
-  "Functions run in process buffer after starting julia process.")
-
-;;;###autoload
-(defun run-ess-julia (&optional start-args)
-  "Start an inferior julia process.
-Optional prefix START-ARGS (\\[universal-argument]) allows to set
-command line arguments, such as --load=<file>. This should be OS
-agnostic. If you have certain command line arguments that should
-always be passed to julia, put them in the variable
-`inferior-julia-args'."
-  (interactive "P")
-  ;; get settings, notably inferior-julia-program :
-  (if (null inferior-julia-program)
-      (error "'inferior-julia-program' does not point to 'julia' or 'julia-basic' executable")
-    (ess-write-to-dribble-buffer   ;; for debugging only
-     (format
-      "\n(julia): ess-dialect=%s, buf=%s, start-arg=%s\n current-prefix-arg=%s\n"
-      ess-dialect (current-buffer) start-args current-prefix-arg))
-    (let* ((jl-start-args
-               (concat inferior-julia-args " " ; add space just in case
-                           (if start-args
-                                   (read-string
-                         (concat "Starting Args"
-                                 (if inferior-julia-args
-                                     (concat " [other than '" inferior-julia-args "']"))
-                                 " ? "))
-                             nil))))
-      (let ((inf-buf (inferior-ess jl-start-args ess-julia-customize-alist)))
-        (with-current-buffer inf-buf
-          (ess--tb-start)
-          ;; Remove ` from julia's logo
-          (goto-char (point-min))
-          (while (re-search-forward "`" nil t)
-            (replace-match "'"))
-          ;; Remove an offending unmatched parenthesis
-          (goto-char (point-min))
-          (forward-line 4)
-          (when (re-search-forward "(" nil t)
-            (replace-match "|"))
-          (goto-char (point-max))
-          ;; --> julia helpers from ../etc/ess-julia.jl :
-          (ess--inject-code-from-file (format "%sess-julia.jl" ess-etc-directory))
-          (run-mode-hooks 'ess-julia-post-run-hook))
-        inf-buf))))
-
-;;;###autoload
-(defalias 'julia #'run-ess-julia)
-
-(cl-defmethod ess--help-major-mode (&context (ess-dialect "julia"))
-  (ess-julia-help-mode))
-
-(define-derived-mode ess-julia-help-mode ess-help-mode "ESS[Julia] Help"
-  "Major mode for Julia documentation."
-  :group 'ess-help
-  (let ((inhibit-read-only t))
-    ;; Julia help buffers can contain color if julia starts with
-    ;; --color=yes
-    (ansi-color-apply-on-region (point-min) (point-max))))
-
-(add-to-list 'auto-mode-alist '("\\.jl\\'" . ess-julia-mode))
-
-(provide 'ess-julia)
-;;; ess-julia.el ends here
diff --git a/elpa/ess-20251212.937/ess-mode.el b/elpa/ess-20251212.937/ess-mode.el
deleted file mode 100644 (file)
index 4bc3583..0000000
+++ /dev/null
@@ -1,685 +0,0 @@
-;;; ess-mode.el -- Emacs Speaks Statistics root mode.  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1994-2022 Free Software Foundation, Inc.
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-;; This file defines ess-mode from which other modes (like ess-r-mode)
-;; derive.
-
-;;; Code:
-
-(require 'ess)
-
-(eval-when-compile
-  (require 'cl-lib)
-  (require 'subr-x))
-(require 'ess-inf)
-
-;; Silence the byte compiler
-(declare-function R "ess-r-mode" (&optional start-args))
-(declare-function S+ "ess-sp6-d" (&optional proc-name))
-(declare-function SAS "ess-sas-d" ())
-
-;; FIXME:This one should not be necessary
-(declare-function ess-display-help-on-object "ess-help" (object &optional command))
-
-;; ESS mode
-;; Major mode definition
-
-;;*;; Hooks
-
-(defcustom ess-mode-hook nil
-  "Hook for customizing ESS each time it is entered."
-  :group 'ess-hooks
-  :type 'hook)
-
-(defvar ess-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map [remap yank] #'ess-yank)
-    (define-key map "\C-c\C-r"   #'ess-eval-region)
-    (define-key map "\C-c\M-r"   #'ess-eval-region-and-go)
-    (define-key map "\C-c\C-b"   #'ess-eval-buffer)
-    (define-key map "\C-c\M-b"   #'ess-eval-buffer-and-go)
-    (define-key map (kbd "C-c C-<up>")   #'ess-eval-buffer-from-beg-to-here)
-    (define-key map (kbd "C-c C-<down>") #'ess-eval-buffer-from-here-to-end)
-    (define-key map "\C-c\C-f"   #'ess-eval-function)
-    (define-key map "\C-c\M-f"   #'ess-eval-function-and-go)
-    (define-key map "\C-c\C-c"   #'ess-eval-region-or-function-or-paragraph-and-step)
-    (define-key map "\C-c\C-p"   #'ess-eval-paragraph-and-step)
-    (define-key map "\C-c\M-p"   #'ess-eval-paragraph-and-go)
-    (define-key map "\C-\M-x"    #'ess-eval-region-or-function-or-paragraph)
-    (define-key map "\C-c\C-n"   #'ess-eval-line-visibly-and-step)
-    (define-key map "\C-c\C-j"   #'ess-eval-line)
-    (define-key map [(control return)] #'ess-eval-region-or-line-visibly-and-step)
-    (define-key map "\C-c\M-j"   #'ess-eval-line-and-go)
-    ;; FIXME: The next three can only work in S/R - mode
-    (define-key map "\C-\M-a"    #'ess-goto-beginning-of-function-or-para)
-    (define-key map "\C-\M-e"    #'ess-goto-end-of-function-or-para)
-    (define-key map "\C-xnd"     #'ess-narrow-to-defun-or-para)
-    (define-key map "\C-xnf"     #'ess-narrow-to-defun-or-para)
-    (define-key map "\C-c\C-z"   #'ess-switch-to-inferior-or-script-buffer)
-    (define-key map "\C-c\C-l"   #'ess-load-file)
-    ;;; Make an alias because C-c C-l is taken up by comint in inferiors
-    (define-key map "\C-c\M-l"   #'ess-load-file)
-    (define-key map "\C-c\C-v"   #'ess-display-help-on-object)
-    (define-key map "\C-c\C-s"   #'ess-switch-process)
-    (define-key map "\C-c\C-k"   #'ess-force-buffer-current)
-    (define-key map "\C-c`"      #'ess-show-traceback)
-    (define-key map [(control ?c) ?~] #'ess-show-call-stack)
-    (define-key map "\C-\M-q"    #'ess-indent-exp)
-    (define-key map "{"          #'skeleton-pair-insert-maybe)
-    (define-key map "}"          #'skeleton-pair-insert-maybe)
-    (define-key map "\C-\M-h"    #'ess-mark-function-or-para)
-    (define-key map "\t"         #'ess-indent-or-complete)
-    (define-key map "\C-c\C-q"   #'ess-quit)
-    (define-key map "\M-\r"      #'ess-use-this-dir)
-    (define-key map ","          #'ess-smart-comma)
-    (define-key map "\C-c\C-d"   'ess-doc-map)
-    (define-key map "\C-c\C-e"   'ess-extra-map)
-    (define-key map "\C-c\C-t"   'ess-dev-map)
-    map)
-  "Keymap for `ess-mode'.")
-
-;; Redefine `indent-new-comment-line' commands for Emacs < 26. Emacs
-;; 27 binds M-j to `default-indent-new-line' which calls
-;; `comment-line-break-function' if point is in a comment. We set this
-;; function in the mode init.
-(substitute-key-definition #'indent-new-comment-line
-                           #'ess-indent-new-comment-line
-                           ess-mode-map global-map)
-
-(defvar ess-extra-map
-  (let (ess-extra-map)
-    (define-prefix-command 'ess-extra-map)
-    (define-key ess-extra-map "\C-d" #'ess-dump-object-into-edit-buffer)
-    (define-key ess-extra-map "d"    #'ess-dump-object-into-edit-buffer)
-    (define-key ess-extra-map "\C-e" #'ess-execute)
-    (define-key ess-extra-map "e"    #'ess-execute)
-    (define-key ess-extra-map "\C-i" #'ess-install-library)
-    (define-key ess-extra-map "i"    #'ess-install-library)
-    (define-key ess-extra-map "\C-l" #'ess-load-library)
-    (define-key ess-extra-map "l"    #'ess-load-library)
-    (define-key ess-extra-map "\C-r" #'inferior-ess-reload)
-    (define-key ess-extra-map "r"    #'inferior-ess-reload)
-    (define-key ess-extra-map "\C-s" #'ess-set-style)
-    (define-key ess-extra-map "s"    #'ess-set-style)
-    (define-key ess-extra-map "\C-t" #'ess-build-tags-for-directory)
-    (define-key ess-extra-map "t"    #'ess-build-tags-for-directory)
-    (define-key ess-extra-map "\C-w" #'ess-execute-screen-options)
-    (define-key ess-extra-map "w"    #'ess-execute-screen-options)
-    (define-key ess-extra-map "/"    #'ess-set-working-directory)
-    ess-extra-map)
-  "ESS extra map.")
-
-(easy-menu-define
-  ess-mode-menu ess-mode-map
-  "Menu for use in `ess-mode'."
-  '("ESS" ; ESS-mode
-    ["Load file"                ess-load-file t]
-    ["Eval region | func | para" ess-eval-region-or-function-or-paragraph t]
-    ["Eval region | func | para & step" ess-eval-region-or-function-or-paragraph-and-step t]
-    ["Eval region | line" ess-eval-region-or-line-visibly-and-step t]
-    ["Enter expression" ess-execute                 t]
-    ;; sub menus
-    "------"
-    ("Process"
-     ["Goto end of process buffer"  ess-switch-to-end-of-ESS        t]
-     ["Switch to process buffer"    ess-switch-to-inferior-or-script-buffer t]
-     ["Switch process"   ess-switch-process              t]
-     ;; ["Recreate R and S versions known to ESS" (ess-r-s-versions-creation+menu) t]
-     ("Start Process"
-      ["R"     R   :help "Start a new R process" :active t]
-      ["S"     S   :help "Start a new S process" :active t]
-      ["Sqpe" Sqpe ess-microsoft-p] ;; :help "Start a new Sqpe process" :active t
-      ["S+6-existing" S+6-existing ess-microsoft-p] ;; :help "Access an existing S process" :active t
-      ["SAS"   SAS-menu t] ;;  :help "Start a new SAS process" :active t
-      ;; The following menu item "Other" is a place-holder that will
-      ;; be replaced with the other versions of R and Sqpe that can be run.
-      ;; See `ess-r-define-runners' and ess-site.el
-      ("Other"
-       ["No other R or Sqpe versions" nil nil])
-      ["About"
-       (ess-goto-info "Starting up") t]
-      ;; :help "Read about starting a new ESS process" :active t]
-      )
-     ("Eval visibly "
-      :filter ess--generate-eval-visibly-submenu)
-     ["Quit process" ess-quit t]
-     ["Reload process" inferior-ess-reload t])
-    "------"
-    ("ESS Eval"
-     ["Eval region | func | para" ess-eval-region-or-function-or-paragraph t]
-     ["Eval region | func | para & step" ess-eval-region-or-function-or-paragraph-and-step t]
-     ["Eval region | line & step" ess-eval-region-or-line-visibly-and-step t]
-     "-----"
-     ["Eval buffer"     ess-eval-buffer                    t]
-     ["Eval buffer till here" ess-eval-buffer-from-beg-to-here t]
-     ["Eval buffer from here" ess-eval-buffer-from-here-to-end t]
-     ["Eval region"     ess-eval-region                    t]
-     ["Eval function"   ess-eval-function                  t]
-     ["Eval line"       ess-eval-line                      t]
-     ["Eval line & step" ess-eval-line-and-step            t]
-     ["Eval paragraph"   ess-eval-paragraph                t]
-     ["Eval paragraph & step" ess-eval-paragraph-and-step  t]
-     ["About"           (ess-goto-info "Evaluating code")  t]
-     )
-    ("Eval and Go"
-     ["Eval buffer"     ess-eval-buffer-and-go            t]
-     ["Eval region"     ess-eval-region-and-go            t]
-     ["Eval function"   ess-eval-function-and-go          t]
-     ["Eval line"       ess-eval-line-and-go              t]
-     ["Eval paragraph"  ess-eval-paragraph-and-go         t]
-     ["About"           (ess-goto-info "Evaluating code") t]
-     )
-    ("Motion"
-     ["Beginning of function or para"   ess-goto-beginning-of-function-or-para       t]
-     ["End of function or para"         ess-goto-end-of-function-or-para             t]
-     "-----"
-     ["Backward list"           backward-list                   t]
-     ["Forward list"            forward-list                    t]
-     ["Next parenthesis"        down-list                       t]
-     ["Enclosing parenthesis"   backward-up-list                t]
-     ["Backward sexp"           backward-sexp                   t]
-     ["Forward sexp"            forward-sexp                    t]
-     ["About"                   (Info-goto-node "(Emacs)Lists") t]
-     )
-    ("ESS Edit"
-     ["Edit new object"   ess-dump-object-into-edit-buffer      t]
-     ["Complete Filename" comint-replace-by-expanded-filename   t]
-     ["Complete File or Object"   ess-indent-or-complete        t]
-     ["Kill sexp"         kill-sexp                             t]
-     ["Mark function"     ess-mark-function-or-para             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]
-     )
-    "------"
-    ("start-dev" :visible nil)
-    ("end-dev" :visible nil)
-    "------"
-    ("Font Lock"
-     :active ess-font-lock-keywords
-     :filter ess--generate-font-lock-submenu)
-    "------"
-    ["Describe"         describe-mode                   t]
-    ["About editing" (ess-goto-info "Editing")  t]
-    ["Read ESS info" (ess-goto-info "") t]
-    ["Send bug report"  ess-submit-bug-report           t]))
-
-;;;###autoload
-(define-derived-mode ess-mode prog-mode "ESS"
-  "Major mode for editing ESS source.
-Optional arg ALIST describes how to customize the editing mode.
-Optional arg PROC-NAME is name of associated inferior process.
-
-\\{ess-mode-map}
-
-You can send text to the inferior ESS process from other buffers containing
-ESS source.
-    `ess-eval-region' sends the current region to the ESS process.
-    `ess-eval-buffer' sends the current buffer to the ESS process.
-    `ess-eval-function' sends the current function to the ESS process.
-    `ess-eval-line' sends the current line to the ESS process.
-    `ess-switch-to-ESS' switches the current buffer to the ESS process buffer.
-    `ess-switch-to-end-of-ESS' switches the current buffer to the ESS process
-        buffer and puts point at the end of it.
-
-    `ess-eval-region-and-go', `ess-eval-buffer-and-go',
-        `ess-eval-function-and-go', and `ess-eval-line-and-go' switch to the S
-        process buffer after sending their text.
-
-    `ess-load-file' sources a file of commands to the ESS process.
-
-\\[ess-indent-command] indents for ESS code.
-\\[backward-delete-char-untabify] converts tabs to spaces as it moves back.
-Comments are indented in a similar way to Emacs-lisp mode:
-       `###'     beginning of line
-       `##'      the same level of indentation as the code
-       `#'       the same column on the right, or to the right of such a
-                 column if that is not possible.(default value 40).
-                 \\[indent-for-comment] command automatically inserts such a
-                 `#' in the right place, or aligns such a comment if it is
-                 already inserted.
-\\[ess-indent-exp] command indents each line of the syntactic unit following point.
-
-Variables controlling indentation style:
- `ess-indent-offset'
-    Indentation of ESS statements within surrounding block.
-    The surrounding block's indentation is the indentation of the line on
-    which the open-brace appears.
- `ess-offset-block'
-    Indentation of blocks opened with curly braces or anonymous parentheses.
- `ess-offset-arguments'
-    Indentation of function arguments or bracket indices.
- `ess-offset-arguments-newline'
-    Indentation of function arguments or bracket indices when the opening
-    delimiter is immediately followed by a newline.
- `ess-offset-continued'
-    Indentation style for continued statements.
- `ess-align-nested-calls'
-    Functions whose nested calls should be aligned.
- `ess-align-arguments-in-calls'
-    Calls in which arguments should be aligned.
- `ess-align-continuations-in-calls'
-    Whether ignore indentation after an operator in calls
- `ess-align-blocks'
-    Blocks that should always be aligned vertically.
- `ess-indent-from-lhs'
-    Whether function calls given as argument should be indented from the
-    parameter name.
- `ess-indent-from-chain-start'
-    Whether to indent arguments from the first of several consecutive calls.
- `ess-indent-with-fancy-comments'
-    Non-nil means distinguish between #, ##, and ### for indentation.
-
-Furthermore, \\[ess-set-style] command enables you to set up predefined ess-mode
-indentation style. See `ess-style-alist' for predefined styles."
-  :group 'ess
-  ;; TODO: get rid of these and rely on modes to set variables properly
-  (when-let ((alist (buffer-local-value 'ess-local-customize-alist (current-buffer))))
-    (ess-setq-vars-local alist))
-  (when-let ((alist ess-mode-editing-alist))
-    (ess-setq-vars-local alist))
-  ;; Keep <tabs> out of the code.
-  (setq-local indent-tabs-mode nil)
-  (setq-local comment-line-break-function #'ess-newline-and-indent)
-  (setq mode-line-process
-        '(" ["
-          (:eval (ess--get-mode-line-indicator))
-          ess--local-mode-line-process-indicator
-          "]"))
-  (add-hook 'ess-idle-timer-functions #'ess-synchronize-dirs nil 'local))
-
-(defun ess--get-mode-line-indicator ()
-  "Get `ess--mode-line-process-indicator' from process buffer.
-Internal function to be used for dynamic mode-line display in
-`ess-mode'."
-  (if ess-local-process-name
-      (let* ((proc (get-process ess-local-process-name))
-             (buff (when proc (process-buffer proc))))
-        (if (and proc (buffer-live-p buff))
-            (with-current-buffer buff
-              (mapcar (lambda (e) (eval e t)) ess--mode-line-process-indicator))
-          "none"))
-    "none"))
-
-\f
-;;; User commands in ess-mode
-
-(defun ess-install-library (&optional update package)
-  "Install PACKAGE for current dialect.
-With UPDATE, update cached package list."
-  (interactive "P")
-  (ess-install-library--override update package))
-
-(cl-defgeneric ess-install-library--override (update package)
-  "See `ess-install-library' for UPDATE, PACKAGE."
-  (when update (message "Don't know how to update for %s" ess-dialect))
-  (error "Cannot install %s, not available for %s" package ess-dialect))
-
-
-;; Motion / manipulation commands
-
-(defun ess-goto-beginning-of-function-or-para ()
-  "If inside a function go to the beginning of it.
-Otherwise go to the beginning of paragraph."
-  (interactive)
-  (let ((start-pos (point))
-        beg end)
-    (beginning-of-defun)
-    (setq beg (point))
-    (end-of-defun)
-    (setq end (point))
-    (goto-char beg)
-    (unless (and (< beg start-pos)
-                 (> end start-pos))
-      (let ((par-pos (save-excursion
-                       (goto-char start-pos)
-                       (forward-comment most-negative-fixnum)
-                       (backward-paragraph)
-                       (forward-comment most-positive-fixnum)
-                       (point))))
-        (if (< end par-pos)
-            (goto-char par-pos)
-          (goto-char beg))))))
-
-(defun ess-goto-end-of-function-or-para ()
-  "If inside a function go to end of it.
-Otherwise go to the end of paragraph."
-  (interactive)
-  (let ((pos (point))
-        beg end)
-    (end-of-defun)
-    (setq end (point))
-    (beginning-of-defun)
-    (setq beg (point))
-    (goto-char end)
-    (when (or (< beg pos)
-              (> end pos))
-      (let ((par-pos (save-excursion
-                       (goto-char pos)
-                       (forward-comment most-positive-fixnum)
-                       (forward-paragraph)
-                       (point))))
-        (when (<= par-pos beg)
-          (goto-char par-pos))))))
-
-(defun ess-mark-function-or-para ()
-  "Put mark at end of ESS function, point at beginning."
-  (interactive)
-  (ess-goto-beginning-of-function-or-para)
-  (push-mark (point))
-  (ess-goto-end-of-function-or-para)
-  (exchange-point-and-mark))
-
-(define-obsolete-function-alias 'ess-mark-function
-  #'ess-mark-function-or-para "15.09")
-
-(defun ess-narrow-to-defun-or-para ()
-  "Make text outside current function invisible.
-If text is already narrowed, this is removed before narrowing to the
-current function."
-  (interactive)
-  (save-excursion
-    (widen)
-    (let* ((beg (progn (ess-goto-beginning-of-function-or-para)
-                       (point)))
-           (end (progn (ess-goto-end-of-function-or-para)
-                       (point))))
-      (narrow-to-region beg end))))
-
-(define-obsolete-function-alias 'ess-narrow-to-defun
-  #'ess-narrow-to-defun-or-para "15.09")
-
-;; FIXME: Support soft breaks with `insert-and-inherit'. See
-;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Hard-and-Soft-Newlines.html
-(defun ess-newline-and-indent (&optional _soft)
-  (ess-indent-new-comment-line))
-
-(defun ess-indent-new-comment-line ()
-  "Like `indent-new-comment-line' but accounts for roxygen comments."
-  (interactive)
-  (cond ((and (fboundp 'ess-roxy-indent-new-comment-line)
-              (string= ess-dialect "R"))
-         (ess-roxy-indent-new-comment-line))
-        (t
-         (indent-new-comment-line))))
-
-\f
-;;; Formatting / indentation
-(defvar-local ess--installed-style-vars nil
-  "A cons of the form (STYLE . VARS).
-VARS is a list of all style vars which were not set explicitly to
-buffer local values by the user in mode hooks.")
-
-(defun ess-set-style (&optional style _quiet)
-  "Set up the `ess-mode' style variables from the `ess-style' variable.
-If STYLE argument is given, use that instead. It makes the ESS
-indentation style variables buffer local. QUIET is for backward
-compatibility and is ignored.
-
-In programs, when STYLE is nil, the `ess-style' is installed. In
-this case, if `ess-style' is buffer local, all settings are
-overwritten, otherwise only those settings which are not already
-buffer local. For example, `ess-style' is buffer local when it is
-set in .dir-locals and thus must have priority over the user
-settings in the mode hook."
-  (interactive
-   (list (let ((styles (mapcar (lambda (x) (symbol-name (car x)))
-                               ess-style-alist)))
-           (intern (ess-completing-read
-                    "Set ESS mode indentation style"
-                    styles nil t nil nil ess-style)))))
-  (let* ((keep-local (and (null style)
-                          (not (local-variable-p 'ess-style))))
-         (style (or style ess-style))
-         (style-alist (or (cdr (assq style ess-style-alist))
-                          (error "Bad ESS style: %s" style)))
-         (vars (if keep-local
-                   ;; Install, but Keep user's buffer-local settings.
-                   (cl-loop for (var . _) in (cdr (assq 'DEFAULT ess-style-alist))
-                            unless (local-variable-p var)
-                            collect var)
-                 (mapcar #'car style-alist))))
-    (when (called-interactively-p 'any)
-      (message "Set indentation style to %s" style))
-    (mapc (lambda (var)
-            (make-local-variable var)
-            (set var (cdr (assq var style-alist))))
-          vars)
-    style))
-
-(defun ess-indent-command (&optional whole-exp)
-  "Indent current line as ESS code, or in some cases insert a tab character.
-If `tab-always-indent' is non-nil, always indent current line.
-Otherwise, indent the current line only if point is at the left
-margin or in the line's indentation; otherwise insert a tab. If
-given, WHOLE-EXP means indent rigidly all the lines of the
-expression starting after point so that this line becomes
-properly indented. The relative indentation among the lines of
-the expression are preserved.
-
-If in a roxygen block at the beginning of the line with
-`ess-roxy-hide-show-p' non-nil, call `ess-roxy-toggle-hiding'
-instead of indenting."
-  (interactive "P")
-  (cond ((and (fboundp 'ess-roxy-entry-p)
-              (fboundp 'ess-roxy-toggle-hiding)
-              (bolp)
-              (ess-roxy-entry-p)
-              ess-roxy-hide-show-p)
-         (ess-roxy-toggle-hiding))
-        (whole-exp
-         ;; If arg, always indent this line as S
-         ;; and shift remaining lines of expression the same amount.
-         (let ((shift-amt (funcall indent-line-function))
-               beg end)
-           (save-excursion
-             (if tab-always-indent
-                 (beginning-of-line))
-             (setq beg (point))
-             (backward-up-list 1)
-             (forward-list 1)
-             (setq end (point))
-             (goto-char beg)
-             (forward-line 1)
-             (setq beg (point)))
-           (if (> end beg)
-               (indent-code-rigidly beg end shift-amt))))
-        ((and (not tab-always-indent)
-              (save-excursion
-                (skip-chars-backward " \t")
-                (not (bolp))))
-         (insert-tab))
-        (t (funcall indent-line-function))))
-
-(defun ess-indent-or-complete ()
-  "When region is selected indent the region.
-Otherwise, if `tab-always-indent' is \\='complete, try to indent, if
-code is already indented, complete instead. Also see
-`ess-first-tab-never-complete'."
-  (interactive)
-  (if (use-region-p)
-      (indent-region (region-beginning) (region-end))
-    (let ((shift (let ((indent (current-indentation)))
-                   (ess-indent-command)
-                   (- (current-indentation) indent))))
-      (when (and (or (equal tab-always-indent 'complete)
-                     ess-tab-complete-in-script)
-                 (numberp shift) ;; can be nil if tab-always-indent is nil
-                 (equal shift 0)
-                 (or (eq last-command 'ess-indent-or-complete)
-                     (null ess-first-tab-never-complete)
-                     (and (eq ess-first-tab-never-complete 'unless-eol)
-                          (looking-at "\\s-*$"))
-                     (and (eq ess-first-tab-never-complete 'symbol)
-                          (not (looking-at "\\w\\|\\s_")))
-                     (and (eq ess-first-tab-never-complete 'symbol-or-paren)
-                          (not (looking-at "\\w\\|\\s_\\|\\s)")))
-                     (and (eq ess-first-tab-never-complete 'symbol-or-paren-or-punct)
-                          (not (looking-at "\\w\\|\\s_\\|\\s)\\|\\s.")))))
-        (completion-at-point)))))
-
-(defun ess-indent-exp ()
-  "Indent each line of the ESS grouping following point."
-  (interactive)
-  (cond ((and (fboundp 'ess-r-indent-exp)
-              (string= ess-dialect "R"))
-         (ess-r-indent-exp))
-        (t
-         (save-excursion
-           (let ((start (point))
-                 (end (ignore-errors (forward-sexp 1) (point))))
-             (when end
-               (indent-region start end)))))))
-
-(defun ess-indent-line ()
-  "Indent current line as ESS code.
-Return the amount the indentation changed by."
-  (declare (obsolete 'indent-line-function "ESS 19.04"))
-  (funcall indent-line-function))
-
-\f
-;;; Dump Objects
-
-(defun ess-dump-object-into-edit-buffer (object)
-  "Edit an ESS OBJECT in its own buffer.
-Without a prefix argument, this simply finds the file pointed to by
-`ess-source-directory'.  If this file does not exist, or if a
-prefix argument is given, a dump() command is sent to the ESS process to
-generate the source buffer."
-  (interactive
-   (progn
-     (ess-force-buffer-current "Process to dump from: ")
-     (ess-read-object-name "Object to edit")))
-  (let* ((dirname (file-name-as-directory
-                   (if (stringp ess-source-directory)
-                       ess-source-directory
-                     (with-current-buffer (process-buffer (ess-get-process
-                                                           ess-local-process-name))
-                       (ess-setq-vars-local ess-local-customize-alist)
-                       (apply ess-source-directory nil)))))
-         (filename (concat dirname (convert-standard-filename (format ess-dump-filename-template object))))
-         (old-buff (get-file-buffer filename)))
-    ;; If the directory doesn't exist, offer to create it
-    (unless (file-exists-p (directory-file-name dirname))
-      (if (y-or-n-p (format "Directory %s does not exist. Create it? " dirname))
-          (make-directory (directory-file-name dirname))
-        (error "Directory %s does not exist" dirname)))
-    ;; Three options:
-    ;;  (1) Pop to an existing buffer containing the file in question
-    ;;  (2) Find an existing file
-    ;;  (3) Create a new file by issuing a dump() command to S
-    ;; Force option (3) if there is a prefix arg
-    (cond (current-prefix-arg
-           (ess-dump-object object filename))
-          (old-buff
-           (pop-to-buffer old-buff))
-          ((file-exists-p filename)
-           (ess-find-dump-file-other-window filename)
-           (message "Read %s" filename))
-          (t (ess-dump-object object filename)))))
-
-(defun ess-dump-object (object filename)
-  "Dump the ESS object OBJECT into file FILENAME."
-  (unless (file-writable-p filename)
-    (error "Can't dump %s as %f is not writeable" object filename))
-  (let ((dump-cmd (format inferior-ess-dump-command object filename)))
-    ;; Make sure we start fresh
-    (when (get-file-buffer filename)
-      (kill-buffer (get-file-buffer filename)))
-    (ess-command dump-cmd)
-    (message "Dumped in %s" filename)
-    (ess-find-dump-file-other-window filename)
-    ;; PD, 1Apr97
-    ;;This ensures that the object gets indented according to ess-mode,
-    ;;not as the R/S deparser does it. At the same time, it gets rid
-    ;;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.
-    (unless ess-keep-dump-files
-      (make-local-variable 'make-backup-files)
-      (setq make-backup-files nil))
-    ;; Don't get confirmation to delete dumped files when loading
-    (when (eq ess-keep-dump-files 'check)
-      (setq ess-keep-dump-files nil))
-    ;; Delete the file if necessary
-    (when ess-delete-dump-files
-      (delete-file (buffer-file-name)))))
-
-(defun ess-find-dump-file-other-window (filename)
-  "Find ESS source file FILENAME in another window."
-  (unless (file-readable-p filename)
-    (ess-write-to-dribble-buffer
-     (format "%s does not exist. Bad dump, starting fresh." filename)))
-  ;; Generate a buffer with the dumped data
-  (find-file-other-window filename)
-  (auto-save-mode 1)            ; Auto save in this buffer
-  (when (and ess-function-template
-             (goto-char (point-max))
-             (re-search-backward ess-dumped-missing-re nil t))
-    (replace-match ess-function-template t t)
-    (set-buffer-modified-p nil) ; Don't offer to save if killed now
-    (goto-char (point-min))
-    (ignore-errors
-      ;; This may fail if there are no opens
-      (down-list 1))))
-
-\f
-;;; Runners
-
-(defun ess-define-runner (name dialect &optional path)
-  "Create a function NAME.
-This function starts the inferior process with the specified
-version. DIALECT can be \"R,\" \"S,\", \"SAS.\" If given, PATH
-should be the absolute path to the program. It defaults to NAME."
-  (let ((name name)
-        (dialect dialect)
-        (path path))
-    (fset (intern name)
-          (lambda (&optional start-args)
-            "Start this process version in an inferior ESS buffer.
-Function defined using `ess-define-runner'."
-            (interactive "P")
-            (cond ((string= dialect "R")
-                   (let ((inferior-ess-r-program (or path name)))
-                     (require 'ess-r-mode)
-                     (R start-args)))
-                  ((string= dialect "S")
-                   (let ((inferior-S+-program (or path name)))
-                     (require 'ess-sp6-d)
-                     (S+)))
-                  ((string= dialect "SAS")
-                   (let ((inferior-SAS-program (or path name)))
-                     (require 'ess-sas-d)
-                     (SAS))))))))
-
-
-
-(provide 'ess-mode)
-
-;;; ess-mode.el ends here
diff --git a/elpa/ess-20251212.937/ess-pkg.el b/elpa/ess-20251212.937/ess-pkg.el
deleted file mode 100644 (file)
index 90e2bd8..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-;; -*- no-byte-compile: t; lexical-binding: nil -*-
-(define-package "ess" "20251212.937"
-  "Emacs Speaks Statistics."
-  '((emacs "25.1"))
-  :url "https://ess.r-project.org/"
-  :commit "e39ca8fa7fce703aa2851e83987a412737d575f0"
-  :revdesc "e39ca8fa7fce"
-  :authors '(("David Smith" . "dsmithNOSPAMstats.adelaide.edu.au")
-             ("A.J. Rossini" . "blindglobeNOSPAMgmail.com")
-             ("Richard M. Heiberger" . "rmhNOSPAMtemple.edu")
-             ("Kurt Hornik" . "Kurt.HornikNOSPAMR-project.org")
-             ("Martin Maechler" . "maechlerNOSPAMstat.math.ethz.ch")
-             ("Rodney A. Sparapani" . "rsparapaNOSPAMmcw.edu")
-             ("Stephen Eglen" . "stephenNOSPAMgnu.org")
-             ("Sebastian P. Luque" . "spluqueNOSPAMgmail.com")
-             ("Henning Redestig" . "henning.redNOSPAMgooglemail.com")
-             ("Vitalie Spinu" . "spinuvitNOSPAMgmail.com")
-             ("Lionel Henry" . "lionel.hryNOSPAMgmail.com")
-             ("J. Alexander Branham" . "alex.branhamNOSPAMgmail.com"))
-  :maintainers '(("ESS Core Team" . "ESS-coreNOSPAMr-project.org")))
diff --git a/elpa/ess-20251212.937/ess-r-completion.el b/elpa/ess-20251212.937/ess-r-completion.el
deleted file mode 100644 (file)
index 3c388cb..0000000
+++ /dev/null
@@ -1,518 +0,0 @@
-;;; ess-r-completion.el --- R completion  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2015-2022 Free Software Foundation, Inc.
-;; Author: Vitalie Spinu
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-;; Provide completion support in R buffers.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'ess-inf)
-(require 'ess-help)
-
-(eval-when-compile
-  (require 'subr-x))
-
-(defvar ac-auto-start)
-(defvar ac-prefix)
-(defvar ac-point)
-(defvar ac-use-comphist)
-(declare-function company-begin-backend "company")
-(declare-function company-doc-buffer "company")
-
-(defcustom ess-R-argument-suffix " = "
-  "Suffix appended by `ac-source-R' and `ac-source-R-args' to candidates."
-  :group 'ess-R
-  :type 'string)
-
-\f
-;;;*;;; ElDoc
-
-(defun ess-r-eldoc-function (&rest _ignored)
-  "Return the doc string, or nil.
-If an ESS process is not associated with the buffer, do not try
-to look up any doc strings."
-  (when eldoc-mode
-    (when-let ((proc (ess-get-next-available-bg-process))
-               (funname (or (and ess-eldoc-show-on-symbol ;; Aggressive completion
-                                 (thing-at-point 'symbol))
-                            (car (ess--fn-name-start)))))
-      (let* ((args (ess-function-arguments funname proc))
-             (bargs (cadr args))
-             (doc (mapconcat (lambda (el)
-                               (if (equal (car el) "...")
-                                   "..."
-                                 (concat (car el) "=" (cdr el))))
-                             bargs ", "))
-             (margs (nth 2 args))
-             (W (- (window-width (minibuffer-window)) (+ 4 (length funname))))
-             (multiline (eq t eldoc-echo-area-use-multiline-p))
-             doc1)
-        (when doc
-          (setq doc (ess-eldoc-docstring-format funname doc (not multiline)))
-          (when (or multiline (and margs (< (length doc1) W)))
-            (setq doc1 (concat doc (propertize "  || " 'face font-lock-function-name-face)))
-            (while (and margs (< (length doc1) W))
-              (let ((head (pop margs)))
-                (unless (assoc head bargs)
-                  (setq doc doc1
-                        doc1 (concat doc1 head  "=, ")))))
-            (when (equal (substring doc -2) ", ")
-              (setq doc (substring doc 0 -2)))
-            (when (and margs (< (length doc) W))
-              (setq doc (concat doc " {--}"))))
-          doc)))))
-
-(defun ess-eldoc-docstring-format (funname doc &optional truncate)
-  (save-match-data
-    (let* (;; Subtract 1 from window width since will cause a wraparound and
-           ;; resize of the echo area.
-           (W (1- (- (window-width (minibuffer-window))
-                     (+ 2 (length funname))))))
-      (setq doc
-            (if (or (<= (length doc) W)
-                    (null ess-eldoc-abbreviation-style)
-                    (eq 'none ess-eldoc-abbreviation-style))
-                doc
-              ;;MILD filter
-              (setq doc (replace-regexp-in-string "TRUE" "T" doc))
-              (setq doc (replace-regexp-in-string "FALSE" "F" doc))
-              (if (or (<= (length doc) W)
-                      (eq 'mild ess-eldoc-abbreviation-style))
-                  doc
-                ;;NORMAL filter (deal with long defaults)
-                (setq doc (replace-regexp-in-string
-                           ;; function calls inside default docs foo(xxxx{..})
-                           "([^)]\\{8\\}\\([^)]\\{4,\\}\\))"
-                           "{.}" doc nil nil 1))
-                (if (<= (length doc) W)
-                    doc
-                  (setq doc (replace-regexp-in-string
-                             " +[^ \t=,\"\]+=[^ \t]\\{10\\}\\([^ \t]\\{4,\\}\\)\\(,\\|\\'\\)"
-                             "{.}," doc nil nil 1))
-                  (if (<= (length doc) W)
-                      doc
-                    (setq doc (replace-regexp-in-string
-                               " +[^ \t=,\"]+=\\([^ \t]\\{10,\\}\\)\\(,\\|\\'\\)"
-                               "{.}," doc nil nil 1))
-                    (if (or (<= (length doc) W)
-                            (eq 'normal ess-eldoc-abbreviation-style))
-                        doc
-                      ;;STRONG filter (replace defaults)
-                      (setq doc (replace-regexp-in-string
-                                 " *[^ \t=,\"\\]* = \\([^ \t]\\{4,\\}\\)\\(,\\|\\'\\)"
-                                 "{.}," doc nil nil 1))
-                      (if (<= (length doc) W)
-                          doc
-                        (setq doc (replace-regexp-in-string
-                                   "\\(=[^FT0-9].+?\\)\\(, [^ =,\"\\]+=\\|\\'\\)"
-                                   "" doc nil nil 1))
-                        (setq doc (replace-regexp-in-string
-                                   "\\(=[^FT0-9].+?\\)\\(, [^ =,\"\\]+,\\|\\'\\)"
-                                   "" doc nil nil 1))
-                        (if (or (<= (length doc) W)
-                                (eq 'strong ess-eldoc-abbreviation-style))
-                            doc
-                          ;;AGGRESSIVE filter (truncate what is left)
-                          (concat (substring doc 0 (- W 4)) "{--}")))))))))
-      (when (and truncate (> (length doc) W))
-        (setq doc (concat (substring doc 0 (- W 4)) "{--}")))
-      (format "%s: %s" (propertize funname 'face 'font-lock-function-name-face) doc))))
-
-\f
-;;;*;;; OBJECTS
-
-(defun ess-r-object-completion ()
-  "Return completions at point as required in `completion-at-point-functions'."
-  (if (ess-make-buffer-current)
-      (let* ((funstart (cdr (ess--fn-name-start)))
-             (completions (ess-r-get-rcompletions funstart))
-             (token (pop completions)))
-        (when completions
-          (list (- (point) (length token)) (point)
-                completions)))
-    (when (string-match "complete" (symbol-name last-command))
-      (message "No ESS process associated with current buffer")
-      nil)))
-
-(defun ess-complete-object-name ()
-  "Perform completion on object preceding point.
-Uses `ess-r-complete-object-name' when `ess-use-R-completion' is non-nil,
-and `ess-internal-complete-object-name' otherwise."
-  (interactive)
-  (if (ess-make-buffer-current)
-      (if ess-use-R-completion
-          (ess-r-complete-object-name)
-        (ess-internal-complete-object-name))
-    ;; else give a message on second invocation
-    (when (string-match "complete" (symbol-name last-command))
-      (message "No ESS process associated with current buffer")
-      nil)))
-
-(define-obsolete-function-alias 'ess-list-object-completions #'ess-complete-object-name "ESS 19.04")
-
-;; This one is needed for R <= 2.6.x -- hence *not* obsoleting it
-(defun ess-internal-complete-object-name ()
-  "Perform completion on `ess-language' object preceding point.
-The object is compared against those objects known by
-`ess-get-object-list' and any additional characters up to ambiguity are
-inserted.  Completion only works on globally-known objects (including
-elements of attached data frames), and thus is most suitable for
-interactive `command-line' entry, and not so much for function editing
-since local objects (e.g. argument names) aren't known.
-
-Use \\[ess-resynch] to re-read the names of the attached directories.
-This is done automatically (and transparently) if a directory is
-modified (S only!), so the most up-to-date list of object names is always
-available.  However attached dataframes are *not* updated, so this
-command may be necessary if you modify an attached dataframe."
-  (ess-make-buffer-current)
-  (if (memq (char-syntax (preceding-char)) '(?w ?_))
-      (let* ((comint-completion-addsuffix nil)
-             (bounds (ess-bounds-of-symbol))
-             (beg (car bounds))
-             (end (cdr bounds))
-             (full-prefix (buffer-substring beg end))
-             (pattern full-prefix)
-             ;; See if we're indexing a list with `$'
-             (listname (if (string-match "\\(.+\\)\\$\\(\\(\\sw\\|\\s_\\)*\\)$"
-                                         full-prefix)
-                           (progn
-                             (setq pattern
-                                   (if (not (match-beginning 2)) ""
-                                     (substring full-prefix
-                                                (match-beginning 2)
-                                                (match-end 2))))
-                             (substring full-prefix (match-beginning 1)
-                                        (match-end 1)))))
-             ;; 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)
-                             ;; Default case: It hangs here when
-                             ;;    options(error=recover) :
-                             (ess-get-object-list ess-current-process-name)))))
-        ;; always return a non-nil value to prevent history expansions
-        (or (completion-in-region beg end components) 'none))))
-
-(defun ess-r-get-rcompletions (&optional start end prefix allow-3-dots)
-  "Call R internal completion utilities (rcomp) for possible completions.
-Optional START and END delimit the entity to complete, default to
-bol and point.  If PREFIX is given, perform completion on
-PREFIX.  First element of the returned list is the completion
-token.  Needs version of R >= 2.7.0."
-  (let* ((start (or start
-                    (if prefix
-                        0
-                      (save-excursion (comint-bol nil) (point)))))
-         (end (or end (if prefix (length prefix) (point))))
-         (prefix (or prefix (buffer-substring start end)))
-         ;; (opts1 (if no-args "op<-rc.options(args=FALSE)" ""))
-         ;; (opts2 (if no-args "rc.options(op)" ""))
-         (call1 (format ".ess_get_completions(\"%s\", %d, \"%s\")"
-                        (ess-quote-special-chars prefix)
-                        (- end start)
-                        ess-R-argument-suffix))
-         (cmd (if allow-3-dots
-                  (concat call1 "\n")
-                (concat "local({ r <- " call1 "; r[r != '...='] })\n"))))
-    (ess-get-words-from-vector cmd)))
-
-(defun ess-r-complete-object-name ()
-  "Completion in R via R's completion utilities (formerly `rcompgen').
-To be used instead of ESS' completion engine for R versions >= 2.7.0."
-  (let ((possible-completions (ess-r-get-rcompletions))
-        token-string)
-    (when possible-completions
-      (setq token-string (pop possible-completions))
-      (or (completion-in-region (- (point) (length token-string))
-                                (point)
-                                possible-completions)
-          'none))))
-
-(defvar ess--cached-sp-objects nil)
-
-(defun ess--get-cached-completions (prefix &optional _point)
-  (if (string-match-p "[]:$@[]" prefix)
-      ;; call proc for objects
-      (cdr (ess-r-get-rcompletions nil nil prefix))
-    ;; else, get cached list of objects
-    (with-ess-process-buffer 'no-error ;; use proc buf alist
-      (ess-when-new-input last-cached-completions
-        (if (and ess--cached-sp-objects
-                 (not  (process-get *proc* 'sp-for-ac-changed?)))
-            ;; if global cache is already there, only re-read local .GlobalEnv
-            (progn
-              (unless ess-sl-modtime-alist
-                ;; initialize if empty
-                (setq ess-sl-modtime-alist '((".GlobalEnv" nil))))
-              ;; fixme: Make adaptive. Not on all remotes are slow; For lots of
-              ;; objects in .GlobalEnv,locals could also be slow.
-              (unless (file-remote-p default-directory)
-                (ess-extract-onames-from-alist ess-sl-modtime-alist 1 'force)))
-          (if ess--cached-sp-objects
-              (ess-get-modtime-list 'ess--cached-sp-objects 'exclude-first)
-            (ess-get-modtime-list)
-            (setq ess--cached-sp-objects (cdr ess-sl-modtime-alist)))
-          ;; reread new package, but not rda, much faster and not needed anyways
-          (process-put *proc* 'sp-for-ac-changed? nil)))
-      (apply #'append
-             (cl-cddar ess-sl-modtime-alist) ; .GlobalEnv
-             (mapcar #'cddr ess--cached-sp-objects)))))
-
-\f
-;;;*;;; ARGUMENTS
-
-(defvar ess-r--funargs-pre-cache
-  '(("plot"
-     (("graphics")
-      (("x" . "")    ("y" . "NULL")    ("type" . "p")    ("xlim" . "NULL")    ("ylim" . "NULL")    ("log" . "")    ("main" . "NULL")    ("sub" . "NULL")    ("xlab" . "NULL")    ("ylab" . "NULL")
-       ("ann" . "par(\"ann\")")     ("axes" . "TRUE")    ("frame.plot" . "axes")    ("panel.first" . "NULL")    ("panel.last" . "NULL")    ("asp" . "NA")    ("..." . ""))
-      ("x" "y" "..." "ci" "type" "xlab" "ylab" "ylim" "main" "ci.col" "ci.type" "max.mfrow" "ask" "mar" "oma" "mgp" "xpd" "cex.main" "verbose" "scale" "xlim" "log" "sub" "ann" "axes" "frame.plot"
-       "panel.first" "panel.last" "asp" "center" "edge.root" "nodePar" "edgePar" "leaflab" "dLeaf" "xaxt" "yaxt" "horiz"
-       "zero.line" "verticals" "col.01line" "pch" "legend.text" "formula" "data" "subset" "to" "from" "newpage" "vp" "labels"
-       "hang" "freq" "density" "angle" "col" "border" "lty" "add" "predicted.values" "intervals" "separator" "col.predicted"
-       "col.intervals" "col.separator" "lty.predicted" "lty.intervals" "lty.separator" "plot.type" "main2" "par.fit" "grid"
-       "panel" "cex" "dimen" "abbrev" "which" "caption" "sub.caption" "id.n" "labels.id" "cex.id" "qqline" "cook.levels"
-       "add.smooth" "label.pos" "cex.caption" "rows" "levels" "conf" "absVal" "ci.lty" "xval" "do.points" "col.points" "cex.points"
-       "col.hor" "col.vert" "lwd" "set.pars" "range.bars" "col.range" "xy.labels" "xy.lines" "nc" "yax.flip" "mar.multi" "oma.multi")))
-    ("print"
-     (("base")
-      (("x" . "")    ("digits" . "NULL")    ("quote" . "TRUE")    ("na.print" . "NULL")    ("print.gap" . "NULL")    ("right" . "FALSE")    ("max" . "NULL")    ("useSource" . "TRUE")    ("..." . ""))
-      ("x" "..." "digits" "signif.stars" "intercept" "tol" "se" "sort" "verbose" "indent" "style" ".bibstyle" "prefix" "vsep" "minlevel" "quote" "right" "row.names" "max" "na.print" "print.gap"
-       "useSource" "diag" "upper" "justify" "title" "max.levels" "width" "steps" "showEnv" "newpage" "vp" "cutoff" "max.level" "give.attr" "units" "abbrCollate" "print.x" "deparse" "locale" "symbolic.cor"
-       "loadings" "zero.print" "calendar"))))
-  "Alist of cached arguments for time consuming functions.")
-
-\f
-;;;*;;; HELP
-
-(defun ess-r-get-object-help-string (sym)
-  "Help string for ac."
-  (let ((proc (ess-get-next-available-bg-process)))
-    (if (null proc)
-        "No free ESS process found"
-      (let ((buf (get-buffer-create " *ess-command-output*")))
-        (when (string-match ":+\\(.*\\)" sym)
-          (setq sym (match-string 1 sym)))
-        (with-current-buffer (process-buffer proc)
-          (ess-with-current-buffer buf
-            (ess--flush-help-into-current-buffer sym nil)))
-        (with-current-buffer buf
-          (ess-help-underline)
-          (goto-char (point-min))
-          (buffer-string))))))
-
-(defun ess-r-get-arg-help-string (sym &optional proc)
-  "Help string for ac."
-  (setq sym (replace-regexp-in-string " *= *\\'" "" sym))
-  (let ((proc (ess-get-next-available-bg-process proc)))
-    (if (null proc)
-        "No free ESS process found"
-      (let ((fun (car ess--fn-name-start-cache)))
-        (with-current-buffer (ess-command (format ".ess_arg_help('%s','%s')\n" sym fun)
-                                          nil nil nil nil proc)
-          (goto-char (point-min))
-          (forward-line)
-          (buffer-substring-no-properties (point) (point-max)))))))
-
-\f
-;;;*;;; COMPANY
-;; https://company-mode.github.io
-
-(defun company-R-objects (command &optional arg &rest _ignored)
-  (interactive (list 'interactive))
-  (cl-case command
-    (interactive (company-begin-backend 'company-R-objects))
-    (prefix (unless (ess-inside-string-or-comment-p)
-              (let ((start (ess-symbol-start)))
-                (when start
-                  (buffer-substring-no-properties start (point))))))
-    (candidates (when-let ((proc (ess-get-next-available-bg-process)))
-                  (with-current-buffer (process-buffer proc)
-                    (all-completions arg (ess--get-cached-completions arg)))))
-    (doc-buffer (company-doc-buffer (ess-r-get-object-help-string arg)))))
-
-(defun company-R-args (command &optional arg &rest _ignored)
-  (interactive (list 'interactive))
-  (cl-case command
-    (interactive (company-begin-backend 'company-R-args))
-    (prefix (unless (ess-inside-string-or-comment-p)
-              (let ((start (ess-arg-start)))
-                (when start
-                  (let ((prefix (buffer-substring-no-properties start (point))))
-                    (if ess-company-arg-prefix-length
-                        (cons prefix (>= (length prefix)
-                                         ess-company-arg-prefix-length))
-                      prefix))))))
-    (candidates (when-let ((proc (ess-get-next-available-bg-process)))
-                  (let* ((args (delete "..." (nth 2 (ess-function-arguments
-                                                     (car ess--fn-name-start-cache) proc))))
-                         (args (mapcar (lambda (a) (concat a ess-R-argument-suffix))
-                                       args)))
-                    (all-completions arg args))))
-    ;; Displaying help for the argument in the echo area is disabled
-    ;; by default for performance reasons. It causes delays or hangs (#1062).
-    (meta (when (bound-and-true-p ess-r--company-meta)
-            (when-let ((proc (ess-get-next-available-bg-process)))
-              (when (with-current-buffer (process-buffer proc)
-                      (not (file-remote-p default-directory)))
-                ;; fixme: ideally meta should be fetched with args
-                (let ((doc (ess-r-get-arg-help-string arg proc)))
-                  (replace-regexp-in-string "^ +\\| +$" ""
-                                            (replace-regexp-in-string "[ \t\n]+" " " doc)))))))
-    (sorted t)
-    (require-match 'never)
-    (doc-buffer (company-doc-buffer (ess-r-get-arg-help-string arg)))))
-
-(defun company-R-library (command &optional arg &rest _ignored)
-  (interactive (list 'interactive))
-  (cl-case command
-    (interactive (company-begin-backend 'company-R-library))
-    (prefix (and (member (car (ess--fn-name-start))
-                         '("library" "require"))
-                 (let ((start (ess-symbol-start)))
-                   (and start (buffer-substring start (point))))))
-    (candidates (when (ess-can-eval-in-background)
-                  (all-completions arg (ess-installed-packages))))
-    (annotation "<pkg>")
-    (duplicates nil)
-    (sorted t)))
-
-;; FIXME: There's a lot of overlap between `ess-r-package-completion'
-;; and `company-R-library'. Can we merge them somehow?
-(defun ess-r-package-completion ()
-  "Return installed packages if in a call to library or require.
-Return format suitable for `completion-at-point-functions'."
-  (when (and (ess-can-eval-in-background)
-             (member (car (ess--fn-name-start))
-                     '("library" "require")))
-    (list (ess-symbol-start)
-          (point)
-          (ess-installed-packages)
-          :annotation-function
-          (lambda (_) " <pkg>"))))
-
-\f
-;;;*;;; AC SOURCES
-;; http://cx4a.org/software/auto-complete/index.html
-;; auto-complete is de-facto unmaintained, users should switch to `company-mode'.
-
-(defvar ac-source-R
-  '((prefix     . ess-ac-start)
-    ;; (requires   . 0) ::)
-    (candidates . ess-ac-candidates)
-    ;; (action  . ess-ac-action-args) ;; interfere with ac-fallback mechanism on RET (which is extremely annoying in inferior buffers)
-    (document   . ess-ac-help))
-  "Combined ad-completion source for R function arguments and R objects.")
-(make-obsolete-variable 'ac-source-R "Use company-mode instead" "ESS 19.04")
-
-(defun ess-ac-start ()
-  (when (ess-process-live-p)
-    (or (ess-arg-start)
-        (ess-symbol-start))))
-(make-obsolete-variable 'ess-ac-start "Use company-mode instead" "ESS 19.04")
-
-(defun ess-ac-candidates ()
-  "OBJECTS + ARGS."
-  (let ((args (with-no-warnings
-                ;; suppress obsolete warnings
-                (ess-ac-args))))
-    ;; sort of intrusive but right
-    (if (and ac-auto-start
-             (< (length ac-prefix) ac-auto-start))
-        args
-      (if args
-          (append args (with-no-warnings
-                         ;; suppress obsolete warnings
-                         (ess-ac-objects t)))
-        (with-no-warnings
-          ;; suppress obsolete warnings
-          (ess-ac-objects))))))
-(make-obsolete-variable 'ess-ac-candidates "Use company-mode instead" "ESS 19.04")
-
-(defun ess-ac-help (sym)
-  (if (string-match-p "= *\\'" sym)
-      (ess-r-get-arg-help-string sym)
-    (ess-r-get-object-help-string sym)))
-(make-obsolete-variable 'ess-ac-help "Use company-mode instead" "ESS 19.04")
-
-;; OBJECTS
-(defvar  ac-source-R-objects
-  '((prefix     . ess-symbol-start)
-    ;; (requires   . 2)
-    (candidates . ess-ac-objects)
-    (document   . ess-r-get-object-help-string))
-  "Auto-completion source for R objects.")
-(make-obsolete-variable 'ac-source-R-objects "Use company-mode instead" "ESS 19.04")
-
-(defun ess-ac-objects (&optional no-kill)
-  "Get all cached objects."
-  (declare (obsolete "Use company-mode instead" "ESS 19.04"))
-  (let ((aprf ac-prefix))
-    (when (and aprf (ess-process-live-p))
-      (unless no-kill ;; workaround
-        (kill-local-variable 'ac-use-comphist))
-      (ess--get-cached-completions aprf ac-point))))
-
-;; ARGS
-(defvar  ac-source-R-args
-  '((prefix     . ess-arg-start)
-    ;; (requires   . 0)
-    (candidates . ess-ac-args)
-    ;; (action     . ess-ac-action-args)
-    (document   . ess-r-get-arg-help-string))
-  "Auto-completion source for R function arguments.")
-(make-obsolete-variable 'ac-source-R-args "Use company-mode instead" "ESS 19.04")
-
-(defun ess-ac-args ()
-  "Get the args of the function when inside parentheses."
-  (declare (obsolete "Use company-mode-instead" "ESS 19.04"))
-  (when  (and ess--fn-name-start-cache ;; set in a call to ess-arg-start
-              (ess-process-live-p))
-    (let ((args (nth 2 (ess-function-arguments (car ess--fn-name-start-cache)))))
-      (if args
-          (setq-local ac-use-comphist nil)
-        (kill-local-variable 'ac-use-comphist))
-      (delete "..." args)
-      (mapcar (lambda (a) (concat a ess-R-argument-suffix))
-              args))))
-
-(provide 'ess-r-completion)
-
-;;; ess-r-completion.el ends here
diff --git a/elpa/ess-20251212.937/ess-r-flymake.el b/elpa/ess-20251212.937/ess-r-flymake.el
deleted file mode 100644 (file)
index f223a60..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-;;; ess-r-flymake.el --- A ess-r Flymake backend  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2018-2022 Free Software Foundation, Inc.
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; Flymake is the built-in Emacs package that supports on-the-fly
-;; syntax checking.  This file adds support for this in ess-r-mode by
-;; relying on the lintr package, available on CRAN and currently
-;; hosted at https://github.com/r-lib/lintr.
-
-;;; Code:
-
-(eval-when-compile (require 'cl-lib))
-(require 'ess-inf)
-(require 'flymake)
-
-;; Appease the byte compiler for Emacs 25. Remove after dropping
-;; support for Emacs 25.
-(declare-function flymake-diag-region "flymake")
-(declare-function flymake-make-diagnostic "flymake")
-(declare-function flymake--overlays "flymake")
-(declare-function ess-r-project "ess-r-mode")
-(declare-function ess-r-package-project "ess-r-package")
-
-(defcustom ess-r-flymake-linters
-  '("closed_curly_linter = NULL"
-    "commas_linter = NULL"
-    "commented_code_linter = NULL"
-    "infix_spaces_linter = NULL"
-    "line_length_linter = NULL"
-    "object_length_linter = NULL"
-    "object_name_linter = NULL"
-    "object_usage_linter = NULL"
-    "open_curly_linter = NULL"
-    "pipe_continuation_linter = NULL"
-    "single_quotes_linter = NULL"
-    "spaces_inside_linter = NULL"
-    "spaces_left_parentheses_linter = NULL"
-    "trailing_blank_lines_linter = NULL"
-    "trailing_whitespace_linter = NULL")
-  "Default linters to use.
-Can be either a string with R expression to be used as
-is (e.g. `lintr::default_linters').  Or a list of strings where
-each element is passed as argument to `lintr::linters_with_defaults'."
-  :group 'ess-R
-  :type '(choice string (repeat string))
-  :package-version '(ess . "18.10"))
-
-(defcustom ess-r-flymake-lintr-cache t
-  "If non-nil, cache lintr results."
-  :group 'ess-R
-  :type 'boolean
-  :package-version '(ess . "18.10"))
-
-(defvar-local ess-r--flymake-proc nil)
-
-(defvar-local ess-r--lintr-file nil
-  "Location of the .lintr config file for this buffer.")
-
-(defvar ess-r--flymake-def-linter
-  (replace-regexp-in-string
-   "[\n\t ]+" " "
-   "esslint <- function(str, ...) {
-    if (!suppressWarnings(requireNamespace('lintr', quietly=TRUE))) {
-        cat('@@error: @@`lintr` package not installed')
-    } else if (packageVersion('lintr') <= '3.0.0') {
-        cat('@@error: @@Need `lintr` version > v3.0.0')
-    } else {
-        tryCatch(lintr::lint(text=str, ..., parse_settings=TRUE),
-                 error = function(e) {
-                   cat('@@warning: @@', conditionMessage(e))
-                 })
-    }
-};"))
-
-(defun ess-r--find-lintr-file ()
-  "Return the absolute path to the .lintr config file.
-Check first the current directory, then the project root, then
-the package root, then the user's home directory. Return nil if
-we couldn't find a .lintr file."
-  ;; VS[2022-01-26]: Can't this entire thing be replaced by
-  ;; `(locate-dominating-file ".lintr")`?
-  (let* ((cur-file (expand-file-name ".lintr" default-directory))
-         (pkg (cdr (ess-r-package-project)))
-         (pkg-file (and pkg (expand-file-name ".lintr" pkg)))
-         (proj (ess-r-project))
-         (proj-file (and proj (expand-file-name ".lintr" proj)))
-         (home-file (expand-file-name ".lintr" (getenv "HOME"))))
-    (cond ((file-readable-p cur-file)
-           cur-file)
-          ((and proj-file (file-readable-p proj-file))
-           proj-file)
-          ((and pkg-file (file-readable-p pkg-file))
-           pkg-file)
-          ((file-readable-p home-file)
-           home-file))))
-
-(defun ess-r--flymake-linters ()
-  "If `ess-r-flymake-linters' is a string, use that.
-Otherwise, construct a string to pass to lintr::linters_with_defaults."
-  (replace-regexp-in-string
-   "[\n\t ]+" " "
-   (if (stringp ess-r-flymake-linters)
-       ess-r-flymake-linters
-     (concat "lintr::linters_with_defaults("
-             (mapconcat #'identity
-                        ess-r-flymake-linters
-                        ", ")
-             ")"))))
-
-(defun ess-r--flymake-msg-type (str)
-  "Transform STR into log level."
-  (cond ((string= str "error: ") :error)
-        ((string= str "warning: ") :warning)
-        ((string= str "style: ") :note)
-        (t (error "Invalid msg type %s" str))))
-
-(defun ess-r--flymake-check-errors ()
-  "Check for critical errors and return non-nil if such occurred."
-  (goto-char (point-min))
-  (when (re-search-forward "@@\\(\\(error\\|warning\\): \\)@@" nil t)
-    (let ((type (ess-r--flymake-msg-type (match-string 1)))
-          (msg (buffer-substring-no-properties (match-end 0) (point-max))))
-      (flymake-log type msg)
-      (eq type :error))))
-
-(defun ess-r--flymake-parse-output (msg-buffer src-buffer report-fn)
-  "Parse the content of MSG-BUFFER for lint locations.
-SRC-BUFFER is the original source buffer.  Collect all messages
-into a list and call REPORT-FN on it."
-  (with-current-buffer msg-buffer
-    (if (ess-r--flymake-check-errors)
-        (with-current-buffer src-buffer
-          ;; we are in the sentinel here; don't throw but remove our hook instead
-          (remove-hook 'flymake-diagnostic-functions #'ess-r-flymake t))
-      (goto-char (point-min))
-      (cl-loop
-       while (search-forward-regexp
-              ;; Regex to match the output lint() gives us.
-              (rx line-start "<text>:"
-                  ;; row
-                  (group-n 1 (one-or-more num)) ":"
-                  ;; column
-                  (group-n 2 (one-or-more num)) ": "
-                  ;; type
-                  (group-n 3 (| "style: " "warning: " "error: "))
-                  ;; msg
-                  (group-n 4 (one-or-more not-newline)) line-end)
-              nil t)
-       for msg = (match-string 4)
-       for (beg . end) = (let ((line (string-to-number (match-string 1)))
-                               (col (string-to-number (match-string 2))))
-                           (flymake-diag-region src-buffer line col))
-       for type = (ess-r--flymake-msg-type (match-string 3))
-       collect (flymake-make-diagnostic src-buffer beg end type msg)
-       into diags
-       finally (funcall report-fn diags)))))
-
-(defun ess-r-flymake (report-fn &rest _args)
-  "A Flymake backend for ESS-R modes.  Relies on the lintr package.
-REPORT-FN is flymake's callback function."
-  (unless (executable-find inferior-ess-r-program)
-    (error "Cannot find program '%s'" inferior-ess-r-program))
-  ;; Kill the process if earlier check was found. The sentinel of the earlier
-  ;; check will detect this.
-  (when (process-live-p ess-r--flymake-proc)
-    (kill-process ess-r--flymake-proc))
-  (if (and (eql ess-use-flymake 'process)
-           (not (ess-process-live-p)))
-      (progn
-        (funcall report-fn nil)
-        (mapc #'delete-overlay (flymake--overlays)))
-    (let ((src-buffer (current-buffer)))
-      (setq ess-r--flymake-proc
-            (make-process
-             :name "ess-r-flymake" :noquery t :connection-type 'pipe
-             :buffer (generate-new-buffer " *ess-r-flymake*")
-             :command (list inferior-R-program
-                            "--no-save" "--no-restore" "--no-site-file" "--no-init-file" "--slave"
-                            "-e" (concat
-                                  (when ess-r--lintr-file
-                                    (concat "options(lintr.linter_file = \"" ess-r--lintr-file "\");"))
-                                  ess-r--flymake-def-linter
-                                  ;; commandArgs(TRUE) returns everything after
-                                  ;; --args as a character vector
-                                  "esslint(commandArgs(TRUE)"
-                                  (unless ess-r--lintr-file
-                                    (concat ", linters = " (ess-r--flymake-linters)))
-                                  (when ess-r-flymake-lintr-cache
-                                    ", cache = TRUE")
-                                  ")")
-                            "--args" (buffer-substring-no-properties
-                                      (point-min) (point-max)))
-             :sentinel
-             (lambda (proc _event)
-               (cond
-                ((eq 'exit (process-status proc))
-                 (unwind-protect
-                     (if (eq proc (buffer-local-value 'ess-r--flymake-proc src-buffer))
-                         (ess-r--flymake-parse-output (process-buffer proc) src-buffer report-fn)
-                       (flymake-log :warning "Canceling obsolete check %s" proc))
-                   (kill-buffer (process-buffer proc))))
-                ((not (eq 'run (process-status proc)))
-                 (kill-buffer (process-buffer proc))))))))))
-
-(defun ess-r-setup-flymake ()
-  "Setup flymake for ESS.
-Activate flymake only if `ess-use-flymake' is non-nil."
-  (when ess-use-flymake
-    (when (< emacs-major-version 26)
-      (error "ESS-flymake requires Emacs version 26 or later"))
-    (when (string= "R" ess-dialect)
-      (setq ess-r--lintr-file (ess-r--find-lintr-file))
-      (add-hook 'flymake-diagnostic-functions #'ess-r-flymake nil t)
-      ;; Try not to enable flymake if flycheck is already running:
-      (unless (bound-and-true-p flycheck-mode)
-        (flymake-mode)))))
-
-;; Enable flymake in Emacs 26+
-(when (<= 26 emacs-major-version)
-  (if (eval-when-compile (<= 26 emacs-major-version))
-      (add-hook 'ess-r-mode-hook #'ess-r-setup-flymake)
-    (when ess-use-flymake
-      (display-warning 'ess "ESS was compiled with older version of Emacs;\n    `ess-r-flymake' won't be available"))))
-
-(provide 'ess-r-flymake)
-
-;;; ess-r-flymake.el ends here
diff --git a/elpa/ess-20251212.937/ess-r-mode.el b/elpa/ess-20251212.937/ess-r-mode.el
deleted file mode 100644 (file)
index 8cb0d9e..0000000
+++ /dev/null
@@ -1,3051 +0,0 @@
-;;; ess-r-mode.el --- R customization  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1997-2025 Free Software Foundation, Inc.
-;; Author: A.J. Rossini
-;; Created: 12 Jun 1997
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; This file defines all the R customizations for ESS.  See ess-s-lang.el
-;; for general S language customizations.
-
-;;; Code:
-
-(eval-when-compile
-  (require 'subr-x))
-(require 'cl-lib)
-(require 'compile)
-(require 'ess-mode)
-(require 'ess-help)
-(require 'ess-s-lang)
-(require 'ess-roxy)
-(require 'ess-r-completion)
-(require 'ess-r-syntax)
-(require 'ess-r-package)
-(require 'ess-trns)
-(require 'ess-r-xref)
-(when (>= emacs-major-version 26) (require 'ess-r-flymake)) ; Flymake rewrite in Emacs 26
-
-(declare-function ess-rdired "ess-rdired" ())
-
-(defcustom ess-r-mode-hook nil
-  "Hook run when entering `ess-r-mode'."
-  :options '(electric-layout-local-mode)
-  :type 'hook
-  :group 'ess-R)
-
-;; Define and run old hook for backward compatibility. We don't
-;; obsolete it with warnings because this is a historically important
-;; user-facing variable and it would not be worth the trouble.
-(defvar R-mode-hook nil
-  "This variable is obsolete since ESS 19.04;
-use `ess-r-mode-hook' instead.")
-(add-hook 'ess-r-mode-hook (lambda () (run-hooks 'R-mode-hook)))
-
-(defcustom ess-r-fetch-ESSR-on-remotes nil
-  "If non-nil, when loading ESSR, fetch it from the GitHub repository.
-Otherwise source from local ESS installation. When the value is
-\\='ess-remote, fetch only with ess-remote's and not with TRAMP
-connections. When t, always fetch from remotes. Change this
-variable when loading ESSR code on remotes fails for you.
-
-Fetching happens once per new ESSR version. The archive is stored
-in ~/.config/ESSR/ESSRv[VERSION].rds file. You can download and
-place it there manually if the remote has restricted network
-access."
-  :type '(choice (const :tag "Never" nil)
-                 (const :tag "With ess-remote only" ess-remote)
-                 (const :tag "Always" t))
-  :group 'ess-R)
-
-;; Silence the byte compiler
-(defvar add-log-current-defun-header-regexp)
-
-;; TODO: Refactor so as to not rely on dynamic scoping.  After that
-;; refactor, also remove the file-local-variable byte-compile-warnings
-;; (not lexical) at the bottom.
-(defvar containing-sexp)
-(defvar indent-point)
-(defvar prev-containing-sexp)
-
-(define-obsolete-variable-alias 'ess-r-versions 'ess-r-runner-prefixes "ESS 19.04")
-(defcustom ess-r-runner-prefixes
-  (let ((r-ver '("R-1" "R-2" "R-3" "R-4" "R-5" "R-6" "R-7" "R-devel" "R-patched")))
-    (if (eq system-type 'darwin) (append r-ver '("R32" "R64")) r-ver))
-  "List of partial strings for versions of R to access within ESS.
-Each string specifies the start of a filename. If a filename
-beginning with one of these strings is found on variable
-`exec-path', a command for that version of R is made available.
-For example, if the file \"R-1.8.1\" is found and this variable
-includes the string \"R-1\", a function called `R-1.8.1' will be
-available to run that version of R. If duplicate versions of the
-same program are found (which happens if the same path is listed
-on variable `exec-path' more than once), they are ignored by
-calling `delete-dups'. Set this variable to nil to disable
-searching for other versions of R. Setting this variable directly
-does not take effect; use either \\[customize-option] or set the
-value by using `ess-r-runners-reset'."
-  :group 'ess-R
-  :package-version '(ess . "19.04")
-  :type '(repeat string)
-  :set #'ess-r-runners-reset
-  ;; Use `custom-initialize-default' since we call
-  ;; `ess-r-define-runners' at the end of this file directly.
-  :initialize #'custom-initialize-default)
-
-
-\f
-;;*;; Mode definition
-
-;;;*;;; UI (Keymaps / Menus)
-(defvar ess-dev-map
-  (let (ess-dev-map)
-    (define-prefix-command 'ess-dev-map)
-    (define-key ess-dev-map "\C-s" #'ess-r-set-evaluation-env)
-    (define-key ess-dev-map "s"    #'ess-r-set-evaluation-env)
-    (define-key ess-dev-map "T"    #'ess-toggle-tracebug)
-    (define-key ess-dev-map "\C-l" #'ess-r-devtools-load-package)
-    (define-key ess-dev-map "l"    #'ess-r-devtools-load-package)
-    (define-key ess-dev-map "`"    #'ess-show-traceback)
-    (define-key ess-dev-map "~"    #'ess-show-call-stack)
-    (define-key ess-dev-map "\C-w" #'ess-watch)
-    (define-key ess-dev-map "w"    #'ess-watch)
-    (define-key ess-dev-map "\C-d" #'ess-debug-flag-for-debugging)
-    (define-key ess-dev-map "d"    #'ess-debug-flag-for-debugging)
-    (define-key ess-dev-map "\C-u" #'ess-debug-unflag-for-debugging)
-    (define-key ess-dev-map "u"    #'ess-debug-unflag-for-debugging)
-    (define-key ess-dev-map "\ 4"   #'ess-debug-unflag-for-debugging)
-    (define-key ess-dev-map "\C-b" #'ess-bp-set)
-    (define-key ess-dev-map "b"    #'ess-bp-set)
-    (define-key ess-dev-map "\ 2"   #'ess-bp-set-conditional)
-    (define-key ess-dev-map "B"    #'ess-bp-set-conditional)
-    (define-key ess-dev-map "\C-L" #'ess-bp-set-logger)
-    (define-key ess-dev-map "L"    #'ess-bp-set-logger)
-    (define-key ess-dev-map "\C-o" #'ess-bp-toggle-state)
-    (define-key ess-dev-map "o"    #'ess-bp-toggle-state)
-    (define-key ess-dev-map "\C-k" #'ess-bp-kill)
-    (define-key ess-dev-map "k"    #'ess-bp-kill)
-    (define-key ess-dev-map "\C-K" #'ess-bp-kill-all)
-    (define-key ess-dev-map "K"    #'ess-bp-kill-all)
-    (define-key ess-dev-map "\C-n" #'ess-bp-next)
-    (define-key ess-dev-map "n"    #'ess-bp-next)
-    (define-key ess-dev-map "i"    #'ess-debug-goto-input-event-marker)
-    (define-key ess-dev-map "I"    #'ess-debug-goto-input-event-marker)
-    (define-key ess-dev-map "\C-p" #'ess-bp-previous)
-    (define-key ess-dev-map "p"    #'ess-bp-previous)
-    (define-key ess-dev-map "\C-e" #'ess-debug-toggle-error-action)
-    (define-key ess-dev-map "e"    #'ess-debug-toggle-error-action)
-    (define-key ess-dev-map "0"    #'ess-electric-selection)
-    (define-key ess-dev-map "1"    #'ess-electric-selection)
-    (define-key ess-dev-map "2"    #'ess-electric-selection)
-    (define-key ess-dev-map "3"    #'ess-electric-selection)
-    (define-key ess-dev-map "4"    #'ess-electric-selection)
-    (define-key ess-dev-map "5"    #'ess-electric-selection)
-    (define-key ess-dev-map "6"    #'ess-electric-selection)
-    (define-key ess-dev-map "7"    #'ess-electric-selection)
-    (define-key ess-dev-map "8"    #'ess-electric-selection)
-    (define-key ess-dev-map "9"    #'ess-electric-selection)
-    (define-key ess-dev-map "?"    #'ess-tracebug-show-help)
-    ess-dev-map)
-  "Keymap for commands related to development and debugging.")
-
-(defvar ess-r-package-check-map
-  (let (ess-r-package-check-map)
-    (define-prefix-command 'ess-r-package-check-map)
-    (define-key ess-r-package-check-map "\C-c" #'ess-r-devtools-check-package)
-    (define-key ess-r-package-check-map "c"    #'ess-r-devtools-check-package)
-    (define-key ess-r-package-check-map "\C-w" #'ess-r-devtools-check-with-winbuilder)
-    (define-key ess-r-package-check-map "w"    #'ess-r-devtools-check-with-winbuilder)
-    (define-key ess-r-package-check-map "h"    #'ess-r-rhub-check-package)
-    ess-r-package-check-map)
-  "Keymap for R package checks.")
-
-(defvar ess-r-package-dev-map
-  (let (ess-r-package-dev-map)
-    (define-prefix-command 'ess-r-package-dev-map)
-    (define-key ess-r-package-dev-map "\C-s" #'ess-r-set-evaluation-env)
-    (define-key ess-r-package-dev-map "s"    #'ess-r-set-evaluation-env)
-    (define-key ess-r-package-dev-map "\C-a" #'ess-r-devtools-execute-command)
-    (define-key ess-r-package-dev-map "a"    #'ess-r-devtools-execute-command)
-    (define-key ess-r-package-dev-map "\C-e" #'ess-r-devtools-execute-command)
-    (define-key ess-r-package-dev-map "e"    #'ess-r-devtools-execute-command)
-    (define-key ess-r-package-dev-map "\C-b" #'ess-r-devtools-build)
-    (define-key ess-r-package-dev-map "b"    #'ess-r-devtools-build)
-    (define-key ess-r-package-dev-map "\C-c" 'ess-r-package-check-map)
-    (define-key ess-r-package-dev-map "c"    'ess-r-package-check-map)
-    (define-key ess-r-package-dev-map "\C-d" #'ess-r-devtools-document-package)
-    (define-key ess-r-package-dev-map "d"    #'ess-r-devtools-document-package)
-    (define-key ess-r-package-dev-map "g"    #'ess-r-devtools-install-github)
-    (define-key ess-r-package-dev-map "\C-i" #'ess-r-devtools-install-package)
-    (define-key ess-r-package-dev-map "i"    #'ess-r-devtools-install-package)
-    (define-key ess-r-package-dev-map "\C-l" #'ess-r-devtools-load-package)
-    (define-key ess-r-package-dev-map "l"    #'ess-r-devtools-load-package)
-    (define-key ess-r-package-dev-map "\C-t" #'ess-r-devtools-test-package)
-    (define-key ess-r-package-dev-map "t"    #'ess-r-devtools-test-package)
-    (define-key ess-r-package-dev-map "\C-u" #'ess-r-devtools-unload-package)
-    (define-key ess-r-package-dev-map "u"    #'ess-r-devtools-unload-package)
-    ess-r-package-dev-map))
-
-(easy-menu-define ess-roxygen-menu nil
-  "Roxygen submenu."
-  '("Roxygen"
-    :visible (and ess-dialect (string-match "^R" ess-dialect))
-    ["Update/Generate Template" ess-roxy-update-entry           t]
-    ["Preview Rd"        ess-roxy-preview-Rd                    t]
-    ["Preview HTML"      ess-roxy-preview-HTML                  t]
-    ["Preview text"      ess-roxy-preview-text                  t]
-    ["Hide all"          ess-roxy-hide-all                      t]
-    ["Toggle Roxygen Prefix"     ess-roxy-toggle-roxy-region    t]))
-
-(easy-menu-define ess-tracebug-menu nil
-  "Tracebug submenu."
-  '("Tracebug"
-    :visible (and ess-dialect (string-match "^R" ess-dialect))
-    ;; :enable ess-local-process-name
-    ["Active?"  ess-toggle-tracebug
-     :style toggle
-     :selected (or (and (ess-process-live-p)
-                        (ess-process-get 'tracebug))
-                   ess-use-tracebug)]
-    ["Show traceback" ess-show-traceback (ess-process-live-p)]
-    ["Show call stack" ess-show-call-stack (ess-process-live-p)]
-    ["Watch" ess-watch  (and (ess-process-live-p)
-                             (ess-process-get 'tracebug))]
-    ["Error action cycle" ess-debug-toggle-error-action (and (ess-process-live-p)
-                                                             (ess-process-get 'tracebug))]
-    "----"
-    ["Flag for debugging" ess-debug-flag-for-debugging ess-local-process-name]
-    ["Unflag for debugging" ess-debug-unflag-for-debugging ess-local-process-name]
-    "----"
-    ["Set BP" ess-bp-set t]
-    ["Set conditional BP" ess-bp-set-conditional t]
-    ["Set logger BP" ess-bp-set-logger t]
-    ["Kill BP" ess-bp-kill t]
-    ["Kill all BPs" ess-bp-kill-all t]
-    ["Next BP" ess-bp-next t]
-    ["Previous BP" ess-bp-previous t]
-    "-----"
-    ["About" ess-tracebug-show-help t]))
-
-(easy-menu-define ess-r-package-menu nil
-  "Package Development submenu."
-  '("Package development"
-    :visible (and ess-dialect (string-match "^R" ess-dialect))
-    ["Active?" ess-r-package-mode
-     :style toggle
-     :selected ess-r-package-mode]
-    ["Select package for evaluation" ess-r-set-evaluation-env t]))
-
-(easy-menu-add-item ess-mode-menu nil ess-roxygen-menu "end-dev")
-(easy-menu-add-item ess-mode-menu nil ess-r-package-menu "end-dev")
-(easy-menu-add-item ess-mode-menu nil ess-tracebug-menu "end-dev")
-(easy-menu-add-item inferior-ess-mode-menu nil ess-r-package-menu "end-dev")
-(easy-menu-add-item inferior-ess-mode-menu nil ess-tracebug-menu "end-dev")
-
-(defvar ess-r-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "C-c C-=") #'ess-cycle-assign)
-    ;;(define-key map "\M-?" #'ess-complete-object-name); not stealing  M-?  from "standard Emacs"
-    (define-key map (kbd "C-c C-.") 'ess-rutils-map)
-    map))
-
-(defvar ess-r-mode-syntax-table
-  (let ((table (copy-syntax-table S-syntax-table)))
-    ;; Letting Emacs treat backquoted names and %ops% as strings solves
-    ;; many problems with regard to nested strings and quotes
-    (modify-syntax-entry ?` "\"" table)
-    (modify-syntax-entry ?% "\"" table)
-    ;; Underscore is valid in R symbols
-    (modify-syntax-entry ?_ "_" table)
-    (modify-syntax-entry ?: "." table)
-    (modify-syntax-entry ?@ "." table)
-    (modify-syntax-entry ?$ "." table)
-    (modify-syntax-entry ?\\ "." table)
-    table)
-  "Syntax table for `ess-r-mode'.")
-
-(defvar ess-r-completion-syntax-table
-  (let ((table (copy-syntax-table ess-r-mode-syntax-table)))
-    (modify-syntax-entry ?. "_" table)
-    (modify-syntax-entry ?: "_" table)
-    (modify-syntax-entry ?$ "_" table)
-    (modify-syntax-entry ?@ "_" table)
-    table)
-  "Syntax table used for completion and help symbol lookup.
-It makes underscores and dots word constituent chars.")
-
-(defvar ess-r-namespaced-load-verbose t
-  "Whether to display information on namespaced loading.
-When t, loading a file into a namespaced will output information
-about which objects are exported and which stay hidden in the
-namespace.")
-
-(defun ess-r-outline-level ()
-  "R mode `outline-level` function."
-  (save-excursion
-    (beginning-of-line)
-    (if (looking-at "^[ \t]*\\(#+\\)\\s-")
-       (length (match-string 1))
-      1000)))
-
-;; The syntax class for '\' is punctuation character to handle R 4.1
-;; lambdas. Inside strings it should be treated as an escape
-;; character which we ensure here.
-(defun ess-r--syntax-propertize-backslash ()
-  (when (nth 3 (save-excursion (syntax-ppss (1- (point)))))
-    (string-to-syntax "\\")))
-
-;; Adapted from `python-syntax-stringify'
-(defun ess-r--syntax-propertize-raw-string-opening ()
-  (let* ((raw-beg (match-beginning 0))
-         (quote-beg (1+ raw-beg))
-         (ppss (save-excursion (goto-char raw-beg) (syntax-ppss)))
-         (string-start (and (eq t (nth 3 ppss)) (nth 8 ppss))))
-    (cond
-     ;; Inside a comment
-     ((nth 4 ppss)
-      nil)
-     ;; This set of quotes delimits the start of a string
-     ((null string-start)
-      (put-text-property quote-beg (1+ quote-beg)
-                         'syntax-table (string-to-syntax "|"))))))
-
-(defun ess-r--syntax-propertize-raw-string-closing ()
-  (let* ((quote-end (match-end 0))
-         (quote-chr (aref (match-string 3) 0))
-         (dashes (match-string 2))
-         (matching-delim (pcase (match-string 1)
-                           (`")" ?\() (`"}" ?{) (`"]" ?\[)))
-         (ppss (save-excursion (goto-char quote-end) (syntax-ppss)))
-         (string-start (and (eq t (nth 3 ppss)) (nth 8 ppss))))
-    (when string-start
-      (save-match-data
-        (save-excursion
-          (goto-char string-start)
-          (when (equal (char-after) quote-chr)
-            (forward-char)
-            (re-search-forward "-*" nil t)
-            (let ((matching-dashes (match-string 0)))
-              (when (or (not matching-dashes)
-                        (string= matching-dashes dashes))
-                (when (equal (char-after) matching-delim)
-                  (put-text-property (1- quote-end) quote-end
-                                     'syntax-table (string-to-syntax "|")))))))))))
-
-(defconst ess-r--syntax-propertize-function
-  (syntax-propertize-rules
-   ("[rR]\\([\"']\\)\\(-*\\)\\([([{]\\)"
-    (0 (ignore (ess-r--syntax-propertize-raw-string-opening))))
-   ("\\([])}]\\)\\(-*\\)\\([\"']\\)"
-    (0 (ignore (ess-r--syntax-propertize-raw-string-closing))))
-   ("\\\\"
-    (0 (ess-r--syntax-propertize-backslash)))))
-
-(defun ess-r-font-lock-syntactic-face-function (state)
-  (if (nth 3 state)
-      ;; string case
-      (let ((string-end (save-excursion
-                          (ess-goto-char (nth 8 state))
-                          (ess-forward-sexp)
-                          (point))))
-        (cond
-         ((eq (nth 3 state) ?%)
-          (if (eq (point) (1- string-end))
-              (when (cdr (assq 'ess-fl-keyword:operators ess-R-font-lock-keywords))
-                'ess-operator-face)
-            (if (cdr (assq 'ess-R-fl-keyword:%op% ess-R-font-lock-keywords))
-                'ess-%op%-face
-              nil)))
-         ((save-excursion
-            (and (cdr (assq 'ess-R-fl-keyword:fun-defs ess-R-font-lock-keywords))
-                 (ess-goto-char string-end)
-                 (ess-looking-at "<-")
-                 (ess-goto-char (match-end 0))
-                 (ess-looking-at "function\\b\\|\\\\" t)))
-          font-lock-function-name-face)
-         ((save-excursion
-            (and (cdr (assq 'ess-fl-keyword:fun-calls ess-R-font-lock-keywords))
-                 (ess-goto-char string-end)
-                 (ess-looking-at "(")))
-          ess-function-call-face)
-         ((eq (nth 3 state) ?`)
-          nil)
-         (t
-          font-lock-string-face)))
-    font-lock-comment-face))
-
-;; Don't fontify backquoted symbols as strings
-(defun inferior-ess-r-font-lock-syntactic-face-function (state)
-  (if (nth 3 state)
-      (if (eq (nth 3 state) ?`)
-          nil
-        font-lock-string-face)
-    font-lock-comment-face))
-
-(defvar ess-r--non-fn-kwds
-  '("in" "else" "break" "next" "repeat")
-  "Reserved words that should not be treated as names of special
-functions by `ess-r--find-fl-keyword'; such reserved words do
-not need to be followed by an open parenthesis to trigger
-font-locking.
-See also `ess-r--non-fn-kstrs'.")
-
-(defvar ess-r--non-fn-kstrs
-  '("\?")
-  "Reserved non-word strings that should not be treated as names of
-special functions by `ess-r--find-fl-keyword'; such reserved
-strings do not need to be followed by an open parenthesis to
-trigger font-locking.
-See also `ess-r--non-fn-kwds'.")
-
-(defvar-local ess-r--keyword-regexp nil)
-(defun ess-r--find-fl-keyword (limit)
-  "Search for R keyword or keystring and set the match data.
-To be used as part of `font-lock-defaults' keywords."
-  (unless ess-r--keyword-regexp
-    (let (fn-kwds non-fn-kwds fn-kstrs non-fn-kstrs)
-      (dolist (kw ess-R-keywords)
-        (if (member kw ess-r--non-fn-kwds)
-            (push kw non-fn-kwds)
-          (push kw fn-kwds)))
-      (dolist (kw ess-r--keystrings)
-       (if (member kw ess-r--non-fn-kstrs)
-           (push kw non-fn-kstrs)
-         (push kw fn-kstrs)))
-      (setq ess-r--keyword-regexp
-            (concat "\\("
-                    (regexp-opt non-fn-kwds 'words)
-                    "\\|"
-                    (regexp-opt non-fn-kstrs t)
-                    "\\)\\|\\("
-                    (regexp-opt fn-kwds 'words)
-                    "\\|"
-                    (regexp-opt fn-kstrs t)
-                    "\\)"))))
-  (let (out)
-    (while (and (not out)
-                (re-search-forward ess-r--keyword-regexp limit t))
-      (save-match-data
-        (setq out (if (match-beginning 1)
-                      ;; Non-function-like keywords: Always fontified
-                      ;; except for `in` for which we check it's part
-                      ;; of a `for` construct. Ideally we'd check that
-                      ;; other keywords like `break` or `next` are
-                      ;; part of the right syntactic construct but
-                      ;; that requires robust and efficient detection
-                      ;; of complete expressions.
-                      (if (string= (match-string 1) "in")
-                          (save-excursion
-                            (goto-char (match-beginning 1))
-                            (and (ess-backward-up-list)
-                                 (forward-word -1)
-                                 (looking-at "for\\s-*(")))
-                        t)
-                    ;; Function-like keywords: check if they are
-                    ;; followed by an open paren
-                    (looking-at "\\s-*(")))))
-    out))
-
-(define-obsolete-variable-alias 'R-customize-alist 'ess-r-customize-alist "ESS 18.10.2")
-(defvar ess-r-customize-alist
-  (append
-   '((ess-local-customize-alist             . 'ess-r-customize-alist)
-     (ess-dialect                           . "R")
-     (ess-suffix                            . "R")
-     (ess-traceback-command                 . ess-r-traceback-command)
-     (ess-call-stack-command                . ess-r-call-stack-command)
-     (ess-mode-completion-syntax-table      . ess-r-completion-syntax-table)
-     (ess-build-eval-message-function       . #'ess-r-build-eval-message)
-     (ess-dump-filename-template            . ess-r-dump-filename-template)
-     (ess-change-sp-regexp                  . ess-r-change-sp-regexp)
-     (ess-help-sec-regex                    . ess-help-r-sec-regex)
-     (ess-help-sec-keys-alist               . ess-help-r-sec-keys-alist)
-     (ess-function-pattern                  . ess-r-function-pattern)
-     (ess-object-name-db-file               . "ess-r-namedb.el")
-     (ess-smart-operators                   . ess-r-smart-operators)
-     (inferior-ess-program                  . inferior-ess-r-program)
-     (inferior-ess-objects-command          . inferior-ess-r-objects-command)
-     (inferior-ess-search-list-command      . "base::search()\n")
-     (inferior-ess-help-command             . inferior-ess-r-help-command)
-     (inferior-ess-exit-command             . "q()")
-     (ess-error-regexp-alist                . ess-r-error-regexp-alist)
-     (ess-describe-object-at-point-commands . 'ess-r-describe-object-at-point-commands)
-     (ess-STERM                             . "iESS")
-     (ess-editor                            . ess-r-editor)
-     (ess-pager                             . ess-r-pager))
-   S-common-cust-alist)
-  "Variables to customize for R.")
-
-(cl-defmethod ess-build-tags-command (&context (ess-dialect "R"))
-  "Return tags command for R."
-  "rtags('%s', recursive = TRUE, pattern = '\\\\.[RrSs](rw)?$',ofile = '%s')")
-
-(defvar ess-r-traceback-command
-  "local({cat(geterrmessage(), \
-'---------------------------------- \n', \
-fill=TRUE); try(traceback(), silent=TRUE)})\n")
-
-(defvar ess-r-call-stack-command "traceback(1)\n")
-
-(defun ess-r-format-command (cmd &rest args)
-  (let ((sentinel (alist-get 'output-delimiter args)))
-    (ess-r--format-call ".ess.command(local(%s), '%s')\n" cmd sentinel)))
-
-(defvar ess-r-format-command-alist
-  '((fun           . ess-r-format-command)
-    (use-delimiter . t)))
-
-(defvar ess-r-dump-filename-template
-  (replace-regexp-in-string
-   "S$" "R" ess-dump-filename-template-proto))
-
-(defvar ess-r-ac-sources
-  '(ac-source-R))
-
-(defvar ess-r-company-backends
-  '((company-R-library company-R-args company-R-objects :separate)))
-
-(defconst ess-help-r-sec-regex "^[A-Z][A-Za-z].+:$"
-  "Reg(ular) Ex(pression) of section headers in help file.")
-
-(defconst ess-help-r-sec-keys-alist
-  '((?a . "\\s *Arguments:")
-    (?d . "\\s *Description:")
-    (?D . "\\s *Details:")
-    (?t . "\\s *Details:")
-    (?e . "\\s *Examples:")
-    (?n . "\\s *Note:")
-    (?r . "\\s *References:")
-    (?s . "\\s *See Also:")
-    (?u . "\\s *Usage:")
-    (?v . "\\s *Value[s]?")     ;
-    )
-  "Alist of (key . string) pairs for use in help section searching.")
-
-(defvar ess-r-error-regexp-alist '(R R1 R2 R3 R4 R-rlang R-recover)
-  "List of symbols which are looked up in `compilation-error-regexp-alist-alist'.")
-
-(dolist (l '(;; Takes precedence over R1 below in English locales, and allows spaces in file path
-             (R "\\(\\(?: at \\|(@\\)\\([^#()\n:]+\\)[#:]\\([0-9]+\\)\\)"  2 3 nil 2 1)
-             ;; valgrind, testthat, rlang/shiny style
-             ;; e.g. (stl_numeric.h:183), (test-parsers.R:238:3) [.../R/file.R#158]
-             (R1 "\\s(\\([^0-9][^ ():\n]+\\)[#:]\\([0-9]+\\)[#:]?\\([0-9]+\\)?\\s)" 1 2 nil 2)
-             (R2 "(\\(\\w+ \\([^())\n]+\\)#\\([0-9]+\\)\\))"  2 3 nil 2 1)
-             ;; Precedes R4 and allows spaces in file path, Starts at bol or with ": " (patterns 3,4,5,6,9)
-             (R3 "\\(?:^ *\\|: ?\\)\\([^-+[:digit:] \t\n]:?[^: \t\n]*\\):\\([0-9]+\\):\\(?:\\([0-9]+\\):\\)?"  1 2 3 2 1)
-             ;; Don't start with digit; no spaces
-             (R4 "\\([^-+ [:digit:]][^: \t\n]+\\):\\([0-9]+\\):\\([0-9]+\\):"  1 2 3 2 1)
-             (R-rlang "^ *[0-9]+\\..* \\(\\([^ :]+\\):\\([0-9]+\\):\\([0-9]+\\)\\)$" 2 3 4 nil 1)
-             (R-recover " *[0-9]+: +\\([^:\n\t]+?\\)#\\([0-9]+:\\)"  1 2 nil 2 1)))
-  (cl-pushnew l compilation-error-regexp-alist-alist))
-
-(define-obsolete-variable-alias 'ess-r-versions-created 'ess-r-created-runners "ESS 18.10")
-(defvar ess-r-created-runners nil
-  "List of R-versions found from `ess-r-runner-prefixes' on the system.")
-
-
-;;;*;;; Mode init
-
-(define-obsolete-variable-alias 'ess-R-post-run-hook 'ess-r-post-run-hook "ESS 18.10.2")
-
-;; We moved the set-wd instruction from `inferior-ess' to here to
-;; avoid sending R code to gdb or lldb before we had a chance to
-;; send "run". So this is no longer generic and inferior modes need
-;; to call this manually. One way to fix this would be to make
-;; `inferior-ess' a `cl-defgeneric'.
-(defvar ess-r-post-run-hook nil
-  "Functions run in process buffer after the initialization of R process.
-Make sure to call blocking commands (e.g. based on `ess-command')
-first. Streaming commands (e.g. based on `ess-send-string')
-should come last, otherwise they will make R busy and the
-blocking commands will throw an error.")
-
-;;;###autoload
-(defun run-ess-r (&optional start-args)
-  "Call \\='R\\=', the \\='GNU S\\=' system from the R Foundation.
-Optional prefix (\\[universal-argument]) allows to set command line arguments, such as
---vsize.  This should be OS agnostic.
-If you have certain command line arguments that should always be passed
-to R, put them in the variable `inferior-R-args'.
-
-START-ARGS can be a string representing an argument, a list of
-such strings, or any other non-nil value.  In the latter case, you
-will be prompted to enter arguments interactively."
-  (interactive "P")
-  (ess-write-to-dribble-buffer   ;; for debugging only
-   (format
-    "\n(R): ess-dialect=%s, buf=%s, start-arg=%s\n current-prefix-arg=%s\n"
-    ess-dialect (current-buffer) start-args current-prefix-arg))
-  (unless (or (file-remote-p default-directory)
-              (when ess-startup-directory
-                (file-remote-p (if (symbolp ess-startup-directory)
-                                   (symbol-value ess-startup-directory)
-                                 ess-startup-directory)))
-              ;; TODO: Once we drop Emacs 26 support, can probably
-              ;; just use the REMOTE argument of `executable-find'.
-              (executable-find inferior-ess-r-program))
-    (display-warning 'ess (format "%s could not be found on the system. Try running `run-ess-r-newest' instead, which searches your system for R." inferior-ess-r-program) :error)
-    (user-error "%s program not found" inferior-ess-r-program))
-  (let* ((r-always-arg
-          (if (or ess-microsoft-p (eq system-type 'cygwin))
-              "--ess "
-            ;; else: "Unix alike"
-            (if (not ess-R-readline) "--no-readline ")))
-         (start-args
-          (cond ((stringp start-args)
-                 start-args)
-                ((and start-args
-                      (listp start-args)
-                      (cl-every #'stringp start-args))
-                 (mapconcat #'identity start-args " "))
-                (start-args
-                 (read-string
-                  (concat "Starting Args"
-                          (if r-always-arg
-                              (concat " [other than '" r-always-arg "']"))
-                          " ? ")))))
-         (r-start-args
-          (concat r-always-arg
-                  inferior-R-args " "   ; add space just in case
-                  start-args))
-         (debug (string-match-p " -d \\| --debugger=" r-start-args))
-         use-dialog-box)
-    (when (or ess-microsoft-p
-              (eq system-type 'cygwin))
-      (setq use-dialog-box nil)
-      (when ess-microsoft-p ;; default-process-coding-system would break UTF locales on Unix
-        (setq default-process-coding-system '(undecided-dos . undecided-dos))))
-
-    (let ((inf-buf (inferior-ess r-start-args ess-r-customize-alist debug)))
-      (with-current-buffer inf-buf
-        (ess-process-put 'funargs-pre-cache ess-r--funargs-pre-cache)
-        (if debug
-            (progn
-              ;; We need to use callback, because R might start with a gdb process
-              (ess-process-put 'callbacks '(inferior-ess-r--init-callback))
-              ;; Trigger the callback
-              (process-send-string (get-buffer-process inf-buf) "r\n"))
-          (ess-r-initialize)
-          (comint-goto-process-mark)))
-      inf-buf)))
-
-;;;###autoload
-(defun R (&optional start-args)
-  (interactive "P")
-  ;; FIXME: Current ob-R expects current buffer set to process buffer
-  (set-buffer (run-ess-r start-args)))
-
-(defun inferior-ess-r--init-callback (_proc _name)
-  (ess-r-initialize))
-
-(defvar ess-r--init-timeout 5
-  "Maximum time for R to become available on startup.
-If the timeout is reached, an error is thrown advising the user
-to run `ess-r-initialize' again.")
-
-(define-obsolete-function-alias 'R-initialize-on-start
-  #'ess-r-initialize "ESS 19.04")
-
-(defun ess-r-initialize ()
-  "This function is run after the first R prompt.
-Executed in process buffer."
-  (interactive)
-  (condition-case err
-      (progn
-        (unless (ess-wait-for-process nil nil nil nil ess-r--init-timeout)
-          (error "Process is busy"))
-        (ess-command (ess-r--init-options-command))
-        (ess-r-load-ESSR))
-    (error (ess-r--init-error-handler err))
-    (quit (ess-r--init-error-handler)))
-  (ess-process-put 'format-command-alist ess-r-format-command-alist)
-  (ess-process-put 'bg-eval-disabled nil)
-  (ess-execute-screen-options t)
-  (ess-set-working-directory default-directory)
-  (when ess-use-tracebug
-    (ess-tracebug 1))
-  (add-hook 'ess-presend-filter-functions #'ess-R-scan-for-library-call nil 'local)
-  ;; Wait before running user hook so they can call blocking commands
-  (ess-wait-for-process)
-  (run-hooks 'ess-r-post-run-hook)
-  (ess-wait-for-process))
-
-(defun ess-r--init-error-handler (&optional err)
-  (ess-write-to-dribble-buffer "Failed to start ESSR\n")
-  (when-let ((proc (and ess-local-process-name
-                        (get-process ess-local-process-name))))
-    (process-put proc 'bg-eval-disabled t))
-  (let ((msgs `("ESSR failed to start, please call `ess-r-initialize' to recover"
-                ,@(when err
-                    (concat "Caused by error: " (error-message-string err))))))
-    (error (mapconcat 'identity msgs "\n"))))
-
-;; FIXME: Should we stop setting `str.dendogram.last`? See:
-;; https://emacs.stackexchange.com/questions/27673/ess-dendrograms-appearance-of-last-branch/27729#27729
-;;
-;; FIXME: We don't use `ess-r-pager`? It's nil by default and
-;; documented that this should not normally be set
-(defun ess-r--init-options-command ()
-  (let ((args (list (format "STERM = '%s'" ess-STERM)
-                    "str.dendrogram.last = '\\''"
-                    (format "editor = '%s'" ess-r-editor)
-                    (ess-r--update-opt-if-eq "pager"
-                                             "file.path(R.home(), 'bin', 'pager')"
-                                             (format "'%s'" inferior-ess-pager))
-                    "show.error.locations = TRUE")))
-    (format "options(%s)\n" (mapconcat 'identity args ", "))))
-
-(defun ess-r--update-opt-if-eq (opt old new)
-  (let ((actual (format "getOption('%s')" opt)))
-    (format "%s = if (identical(%s, %s)) %s else %s"
-            opt
-            actual
-            old
-            new
-            actual)))
-
-(defun ess-r--skip-function ()
-  ;; Assumes the point is at function start
-  (if (looking-at-p ess-r-set-function-start)
-      (forward-list 1) ; get over the entire setXyz(...)
-    (forward-list 1) ; get over arguments
-    (if (looking-at-p "[ \t\n]*{")
-        (forward-sexp 1) ;; move over {...}
-      ;; {..}-less case
-      (skip-chars-forward " \t\n")
-      (goto-char (cadr (ess-continuations-bounds))))))
-
-;; `beginning-of-defun' protocol:
-;;  1) assumes that defuns are at the top level (e.g. always moves to bol)
-(defun ess-r-beginning-of-defun (&optional arg)
-  "Move to beginning a top level function.
-ARG is as in `beginning-of-defun'."
-  (ess-r-beginning-of-function arg t))
-
-;; `end-of-defun' protocol:
-;;  1) Uses beginning-of-defun-function with negative arg
-;;  2) Assumes that beginning-of-defun-function with -1 arg finds current defun
-;;  when point is just in front of the function
-(defun ess-r-end-of-defun (&optional arg)
-  "End of top level function.
-ARG is as in `end-of-defun'."
-  (ess-r-end-of-function arg t))
-
-(defun ess-r-beginning-of-function (&optional arg top-level)
-  "Leave (and return) the point at the beginning of the current ESS function.
-When ARG is positive, search for beginning of function backward,
-otherwise forward. Value of ARG is currently ignored. Return the
-new position, or nil if no-match. If TOP-LEVEL is non-nil, search
-for top-level functions only."
-  (setq arg (or arg 1))
-  (let ((start-point (point))
-        done)
-    ;; In case we are at the start of a function, skip past new lines.
-    (when (> arg 0)
-      ;; Start search from a forward position in order to capture current
-      ;; function start. But not when arg < 0; see end-of-defun protocol above.
-      (forward-line 2))
-    (while (and (not done)
-                (re-search-backward ess-r-function-pattern nil t arg))
-      (unless (ess-inside-string-or-comment-p)
-        (setq done
-              (if top-level
-                  (= (car (syntax-ppss (match-beginning 0))) 0)
-                t))
-        (if (< arg 0)
-            ;; move to match-end to avoid the infloop in re-search-backward
-            (goto-char (if done (match-beginning 0) (match-end 0)))
-          ;; Backward regexp match stops at the minimal match (e.g. partial
-          ;; function name), so we need a bit more work here.
-          (beginning-of-line)
-          (re-search-forward ess-r-function-pattern)
-          (goto-char (match-beginning 0))
-          (when (<= start-point (point))
-            (setq done nil)))))
-    (if done
-        (point)
-      (goto-char start-point)
-      nil)))
-
-(defun ess-r-end-of-function (&optional arg top-level)
-  "Leave the point at the end of the current function.
-When ARG is positive, search for end of function forward,
-otherwise backward. Move to point and return point if search was
-successful, otherwise nil. If TOP-LEVEL is non-nil, search for
-top level functions only."
-  (setq arg (or arg 1))
-  (let* ((start-pos (point))
-         (search-fn (lambda (lim)
-                      (let ((foundp nil))
-                        (while (and (not foundp)
-                                    (re-search-forward ess-r-function-pattern nil t))
-                          (when (< arg 0)
-                            ;; re-search-backward is a forward search
-                            ;; internally, so we need to bol in order to avoid
-                            ;; the infloop
-                            (beginning-of-line))
-                          (setq foundp
-                                (unless (ess-inside-string-or-comment-p)
-                                  (if top-level
-                                      (= 0 (car (save-excursion (syntax-ppss (match-beginning 0)))))
-                                    (>= (point) lim)))))
-                        (if foundp
-                            (progn (goto-char (match-beginning 0))
-                                   (ess-r--skip-function))
-                          (goto-char start-pos))))))
-    (ess-r-beginning-of-function 1 top-level)
-    (if (< (point) start-pos)
-        ;; Moved back. We were either inside a function or after a function.
-        (progn
-          (ess-r--skip-function)
-          ;; For negative ARG we are done.
-          (when (and (> arg 0)
-                     (<= (point) start-pos))
-            (funcall search-fn start-pos)))
-      ;; No function before point; search forward on positive ARG.
-      (when (> arg 0)
-        (funcall search-fn start-pos)))))
-
-;;;###autoload
-(define-derived-mode ess-r-mode ess-mode "ESS[R]"
-  "Major mode for editing R source.  See `ess-mode' for more help."
-  :group 'ess-R
-  (set-syntax-table ess-r-mode-syntax-table)
-  (ess-setq-vars-local ess-r-customize-alist)
-  (setq-local ess-font-lock-keywords 'ess-R-font-lock-keywords)
-  (setq-local paragraph-start (concat "\\s-*$\\|" page-delimiter))
-  (setq-local paragraph-separate (concat "\\s-*$\\|" page-delimiter))
-  (setq-local paragraph-ignore-fill-prefix t)
-  (setq-local indent-line-function #'ess-r-indent-line)
-  (setq-local comment-indent-function #'ess-calculate-indent)
-  (setq-local add-log-current-defun-header-regexp "^\\(.+\\)\\s-+<-[ \t\n]*function")
-  (setq-local font-lock-syntactic-face-function #'ess-r-font-lock-syntactic-face-function)
-  (setq-local syntax-propertize-function ess-r--syntax-propertize-function)
-  (setq-local electric-layout-rules '((?{ . after)))
-  ;; indentation
-  (add-hook 'hack-local-variables-hook #'ess-set-style nil t)
-  ;; eldoc
-  (ess--setup-eldoc #'ess-r-eldoc-function)
-  ;; auto-complete
-  (ess--setup-auto-complete ess-r-ac-sources)
-  ;; company
-  (ess--setup-company ess-r-company-backends)
-  (setq-local prettify-symbols-alist ess-r-prettify-symbols)
-  (setq font-lock-defaults '(ess-build-font-lock-keywords nil nil ((?\. . "w") (?\_ . "w"))))
-  (remove-hook 'completion-at-point-functions #'ess-filename-completion 'local) ;; should be first
-  (add-hook 'completion-at-point-functions #'ess-r-object-completion nil 'local)
-  (add-hook 'completion-at-point-functions #'ess-r-package-completion nil 'local)
-  (add-hook 'completion-at-point-functions #'ess-filename-completion nil 'local)
-  (add-hook 'xref-backend-functions #'ess-r-xref-backend nil 'local)
-  (add-hook 'project-find-functions #'ess-r-project nil 'local)
-
-  (if (fboundp 'ess-add-toolbar) (ess-add-toolbar))
-  ;; imenu is needed for `which-function'
-  (setq imenu-generic-expression ess-imenu-S-generic-expression)
-  (when ess-imenu-use-S
-    (imenu-add-to-menubar "Imenu-R"))
-  ;; outline
-  (setq-local outline-level #'ess-r-outline-level)
-  (setq-local outline-regexp ess-r-outline-regexp)
-  (setq-local beginning-of-defun-function #'ess-r-beginning-of-defun)
-  (setq-local end-of-defun-function #'ess-r-end-of-defun)
-  (ess-roxy-mode))
-;;;###autoload
-(defalias 'R-mode #'ess-r-mode)
-;;;###autoload
-(defalias 'r-mode #'ess-r-mode)
-
-
-;;;###autoload
-(add-to-list 'auto-mode-alist '("/R/.*\\.q\\'" . ess-r-mode))
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.[rR]\\'" . ess-r-mode))
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.[rR]profile\\'" . ess-r-mode))
-;;;###autoload
-(add-to-list 'auto-mode-alist '("NAMESPACE\\'" . ess-r-mode))
-;;;###autoload
-(add-to-list 'auto-mode-alist '("CITATION\\'" . ess-r-mode))
-
-\f
-;;;*;;; Project detection
-
-(defvar-local ess-r-project--info-cache nil
-  "Current package info cache.
-See `ess-r-project-info' for its structure.")
-
-(defun ess-r-project (&optional dir)
-  "Return the current project as an Emacs project instance.
-R project is a directory XYZ containing either .Rprofile,
-DESCRIPTION or XYZ.Rproj file. Return a list of the form (:name
-\"XYZ\" :root \"/path/to/project\"). If DIR is provided, the
-project is searched from that directory instead of
-`default-directory'."
-  (let ((info (ess-r-project-info dir)))
-    (when (car info)
-      (cons 'ess-r-project (plist-get info :root)))))
-
-;; FIXME: remove when emacs 27 is dropped
-(unless (eval-when-compile
-          (get 'project-roots 'byte-obsolete-info))
-  (cl-defmethod project-roots ((project (head ess-r-project)))
-    "Return the project root for ESS R projects."
-    (list (cdr project))))
-
-(cl-defmethod project-root ((project (head ess-r-project)))
-  "Return the project root for ESS R projects."
-  (cdr project))
-
-(defun ess-r-project-info (&optional dir)
-  "Get the description of the R project in directory DIR.
-Return an plist with the keys :name and :root. When not in a
-project return \\='(nil). This value is cached buffer-locally for
-efficiency reasons."
-  (let ((do-cache (null dir)))
-    (if (and do-cache ess-r-project--info-cache)
-        ess-r-project--info-cache
-      (setq dir (or dir (buffer-file-name) default-directory))
-      (let ((out (or
-                  (unless (file-remote-p dir)
-                    (let ((dir (locate-dominating-file
-                                dir
-                                (lambda (dir)
-                                  (or (file-exists-p (expand-file-name ".Rprofile" dir))
-                                      (file-exists-p (expand-file-name "DESCRIPTION" dir))
-                                      (let ((nm (file-name-nondirectory (directory-file-name dir))))
-                                        (file-exists-p (expand-file-name (concat nm ".Rproj") dir))))))))
-                      (when dir
-                        (let ((dir (directory-file-name dir)))
-                          (unless (member dir (list "~" (getenv "HOME")))
-                            (list :name (file-name-nondirectory dir)
-                                  :root (expand-file-name dir)))))))
-                  '())))
-        (when do-cache
-          (setq ess-r-project--info-cache out))
-        out))))
-
-
-\f
-;;*;; Miscellaneous
-
-(defun ess-R-arch-2-bit (arch)
-  "Translate R's architecture shortcuts/directory names to `bits'.
-ARCH \"32\" or \"64\" (for now)."
-  (if (string= arch "i386")  "32"
-    ;; else:
-    "64"))
-
-(defun ess-rterm-arch-version (long-path &optional give-cons)
-  "Find a name for LONG-PATH, an absolute path to R on Windows.
-Returns either Name, a string, or a (Name . Path) cons, such as
-
-(\"R-2.12.1-64bit\"  .  \"C:/Program Files/R/R-2.12.1/bin/x64/Rterm.exe\")
-
-\"R-x.y.z/bin/Rterm.exe\" will return \"R-x.y.z\", for R-2.11.x and older.
-\"R-x.y.z/bin/i386/Rterm.exe\" return \"R-x.y.z-32bit\", for R-2.12.x and newer.
-\"R-x.y.z/bin/x64/Rterm.exe\"  return \"R-x.y.z-64bit\", for R-2.12.x and newer."
-  (let* ((dir  (directory-file-name (file-name-directory long-path)))
-         (dir2 (directory-file-name (file-name-directory dir)))
-         (v-1up (file-name-nondirectory dir));; one level up
-         (v-2up (file-name-nondirectory dir2));; two levels up; don't want "bin" ...
-         (v-3up (file-name-nondirectory ;; three levels up; no "bin" for i386, x64 ...
-                 (directory-file-name (file-name-directory dir2))))
-         (val (if (string= v-2up "bin")
-                  (concat v-3up "-" (ess-R-arch-2-bit v-1up) "bit")
-                ;; pre R-2.12.x, or when there's no extra arch-specific sub directory:
-                v-2up)))
-    (if give-cons
-        (cons val long-path)
-      val)))
-
-(defun ess-r-define-runners (&optional verbose)
-  "Generate functions for starting other versions of R.
-See `ess-r-runner-prefixes' for strings that determine which functions
-are created.  On MS Windows, this works using
-`ess-rterm-version-paths' instead.
-
-The functions will normally be placed on the menubar and stored
-as `ess-r-created-runners' upon ESS initialization."
-  (when ess-r-runner-prefixes
-    (let ((versions
-           ;; Find which versions of R we want.  Remove the pathname, leaving just
-           ;; the name of the executable.
-           (if ess-microsoft-p
-               (mapcar (lambda (v) (car (ess-rterm-arch-version v 'give-cons)))
-                       ess-rterm-version-paths)
-             (delete-dups
-              (mapcar #'file-name-nondirectory
-                      (apply #'nconc
-                             (mapcar #'ess-find-exec-completions
-                                     ess-r-runner-prefixes)))))))
-      ;; Iterate over each string in VERSIONS, creating a new defun each time.
-      (setq ess-r-created-runners versions)
-      (if verbose
-        (message "Recreated %d R versions known to ESS: %s"
-                 (length versions) versions))
-      (if ess-microsoft-p
-          (cl-mapc (lambda (v p) (ess-define-runner v "R" p)) versions ess-rterm-version-paths)
-        (mapc (lambda (v) (ess-define-runner v "R")) versions))
-      ;; Add to menu
-      (when ess-r-created-runners
-        ;; new-menu will be a list of 3-vectors, of the form:
-        ;; ["R-1.8.1" R-1.8.1 t]
-        (let ((new-menu (mapcar (lambda(x) (vector x (intern x) t))
-                                ess-r-created-runners)))
-          (easy-menu-add-item ess-mode-menu '("Start Process")
-                              (cons "Other" new-menu))
-          (easy-menu-add-item inferior-ess-mode-menu '("Process")
-                              (cons "R processes" new-menu)))))))
-
-(defun ess-r-redefine-runners (&optional verbose)
-  "Regenerate runners, i.e. `M-x R-*` possibilities.
- Call `fmakunbound' on all elements of `ess-r-created-runners',
- then define new runners."
-  (interactive "P")
-  (dolist (f ess-r-created-runners)
-    (fmakunbound (intern f)))
-  (setq ess-r-created-runners nil)
-  (ess-r-define-runners verbose))
-
-(defun ess-r-runners-reset (sym val)
-  "Regenerate runners.
-Set SYM to VAL and call `ess-r-redefine-runners'."
-  (set-default sym val)
-  (ess-r-redefine-runners))
-
-(define-obsolete-function-alias
-  'ess-r-versions-create #'ess-r-define-runners "ESS 18.10")
-
-(defvar ess-newest-R nil
-  "Stores the newest version of R that has been found.
-Used as a cache, within `ess-find-newest-R'. Do not use this value
-directly, but instead call the function \\[ess-find-newest-R].")
-
-
-(defcustom ess-prefer-higher-bit t
-  "Non-nil means prefer higher bit architectures of R.
-e.g. prefer 64 bit over 32 bit.  This is currently used only
-by the code on Windows for finding the newest version of R."
-  :group 'ess-R
-  :type 'boolean)
-
-(defun ess-rterm-prefer-higher-bit ()
-  "Optionally remove 32bit Rterms from being candidate for `run-ess-r-newest'.
-Return the list of candidates for being `run-ess-r-newest'. Filtering is
-done iff `ess-prefer-higher-bit' is non-nil. This is used only by
-Windows when running `ess-find-newest-R'."
-  (if ess-prefer-higher-bit
-      ;; filter out 32 bit elements
-      (let ((filtered
-             (delq nil
-                   (mapcar (lambda (x) (unless (string-match "/i386/Rterm.exe" x) x))
-                           ess-rterm-version-paths))))
-        (if (null filtered)
-            ;; if none survived filtering, keep the original list
-            ess-rterm-version-paths
-          filtered))
-    ess-rterm-version-paths))
-
-(defun run-ess-r-newest (&optional start-args)
-  "Find the newest version of R available, and run it.
-Subsequent calls to `run-ess-r-newest' will run that version,
-rather than searching again for the newest version. Providing
-START-ARGS (interactively, with \\[universal-argument]) will
-prompt for command line arguments."
-  (interactive "P")
-  (unless ess-newest-R
-    (message "Finding all versions of R on your system...")
-    (setq ess-newest-R
-          (ess-find-newest-date
-           (mapcar #'ess-r-version-date
-                   (if ess-microsoft-p
-                       (ess-rterm-prefer-higher-bit)
-                     (add-to-list 'ess-r-created-runners inferior-ess-r-program))))))
-  (let ((inferior-ess-r-program ess-newest-R))
-    (run-ess-r start-args)))
-
-(defun R-newest (&optional start-args)
-  (interactive "P")
-  ;; FIXME: Current ob-R expects current buffer set to process buffer
-  (set-buffer (run-ess-r-newest start-args)))
-
-;; (ess-r-version-date "R-2.5.1") (ess-r-version-date "R-patched")
-;; (ess-r-version-date "R-1.2.1") (ess-r-version-date "R-1.8.1")
-;; Windows:
-;;  (ess-r-version-date "C:/Program Files (x86)/R/R-2.11.1/bin/Rterm.exe")
-;; Note that for R-devel, ver-string is something like
-;; R version 2.6.0 Under development (unstable) (2007-07-14 r42234)
-;; Antique examples are 'R 1.0.1  (April 14, 2000)' or 'R 1.5.1 (2002-06-17).'
-(defun ess-r-version-date (rver)
-  "Return the date of the version of R named RVER.
-The date is returned as a date string.  If the version of R could
-not be found from the output of the RVER program, \"-1\" is
-returned."
-  (let ((date "-1")
-        (ver-string (shell-command-to-string
-                     ;; here, MS Windows (shell-command) needs a short name:
-                     (concat (if (and ess-microsoft-p
-                                      ;; silence byte compiler warns about w32-fns
-                                      (fboundp 'w32-short-file-name))
-                                 (w32-short-file-name rver)
-                               rver)
-                             " --version"))))
-    (when (string-match
-           "R \\(version \\)?[1-9][^\n]+ (\\(2[0-9-]+\\)\\( r[0-9]+\\)?"
-           ver-string)
-      (setq date (match-string 2 ver-string)))
-    (cons date rver)))
-
-(defun ess-current-R-version ()
-  "Get the version of R currently running in the ESS buffer as a string."
-  (ess-make-buffer-current)
-  (car (ess-get-words-from-vector (format "base::as.character(%s)\n"
-                                          (ess-r--format-call ".ess.Rversion")))))
-
-(defun ess-current-R-at-least (version)
-  "Is the version of R (in the ESS buffer) at least (\">=\") VERSION ?
-Examples: (ess-current-R-at-least '2.7.0)
-      or  (ess-current-R-at-least \"2.5.1\")"
-  (ess-make-buffer-current)
-  (string= "TRUE"
-           (car (ess-get-words-from-vector
-                 (format "base::as.character(%s >= \"%s\")\n"
-                         (ess-r--format-call ".ess.Rversion")
-                         version)))))
-(defun ess-find-newest-date (rvers)
-  "Find the newest version of R given in the a-list RVERS.
-Each element of RVERS is a dotted pair (date . R-version), where
-date is given as e.g.\"2007-11-30\" so that we can compare dates
-as strings.  If a date is listed as \"-1\", that version of R
-could not be found.
-
-If the value returned is nil, no valid newest version of R could be found."
-  (let (new-r this-r
-              (new-time "0"))
-    (while rvers
-      (setq this-r (car rvers)
-            rvers (cdr rvers))
-      (when (string< new-time (car this-r))
-        (setq new-time (car this-r)
-              new-r    (cdr this-r))))
-    new-r))
-
-(defun ess-find-rterm (&optional ess-R-root-dir bin-Rterm-exe)
-  "Find the full path of all occurrences of Rterm.exe under the ESS-R-ROOT-DIR.
-If ESS-R-ROOT-DIR is nil, construct it by looking for an
-occurrence of Rterm.exe in the `exec-path'. If there are no
-occurrences of Rterm.exe in the `exec-path', then use
-`ess-program-files' (which evaluates to something like
-\"c:/progra~1/R/\" in English locales) which is the default
-location for the R distribution. If BIN-RTERM-EXE is nil, then
-use \"bin/Rterm.exe\"."
-  (if (not ess-R-root-dir)
-      (let ((Rpath (executable-find "Rterm")))
-        (setq ess-R-root-dir
-              (expand-file-name
-               (if Rpath
-                   (concat (file-name-directory Rpath) "../../")
-                 (concat ess-program-files "/R/"))))
-        (ess-write-to-dribble-buffer
-         (format "(ess-find-rterm): ess-R-root-dir = '%s'\n" ess-R-root-dir))))
-
-  (if (not bin-Rterm-exe) (setq bin-Rterm-exe "bin/Rterm.exe"))
-
-  (when (file-directory-p ess-R-root-dir) ; otherwise file-name-all-.. errors
-    (setq ess-R-root-dir
-          (replace-regexp-in-string "[\\]" "/" ess-R-root-dir))
-    (let ((R-ver
-           (ess-drop-non-directories
-            (ess-flatten-list
-             (mapcar (lambda (r-prefix)
-                       (file-name-all-completions r-prefix ess-R-root-dir))
-                     (append '("rw") ess-r-runner-prefixes))))))
-      (mapcar (lambda (dir)
-                (let ((R-path
-                       (concat ess-R-root-dir
-                               (replace-regexp-in-string "[\\]" "/" dir)
-                               bin-Rterm-exe)))
-                  (if (file-exists-p R-path) R-path)))
-              R-ver))))
-
-;;;###autoload
-(define-derived-mode ess-r-transcript-mode ess-transcript-mode "ESS R Transcript"
-  "A Major mode for R transcript files."
-  :syntax-table ess-r-mode-syntax-table
-  :group 'ess
-  (ess-setq-vars-local ess-r-customize-alist)
-  (setq-local comint-prompt-regexp inferior-S-prompt)
-  (setq-local ess-font-lock-keywords 'ess-R-font-lock-keywords)
-  (setq-local paragraph-start (concat "\\s-*$\\|" page-delimiter))
-  (setq-local paragraph-separate (concat "\\s-*$\\|" page-delimiter))
-  (setq-local paragraph-ignore-fill-prefix t)
-  (setq-local indent-line-function #'ess-r-indent-line)
-  (setq-local add-log-current-defun-header-regexp "^\\(.+\\)\\s-+<-[ \t\n]*function")
-  (setq-local font-lock-syntactic-face-function #'ess-r-font-lock-syntactic-face-function)
-  (setq-local prettify-symbols-alist ess-r-prettify-symbols)
-  (setq font-lock-defaults '(ess-build-font-lock-keywords
-                             nil nil ((?\. . "w") (?\_ . "w") (?' . ".")))))
-
-(defalias 'r-transcript-mode #'ess-r-transcript-mode)
-
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.[Rr]out\\'" . ess-r-transcript-mode))
-;;;###autoload
-(add-to-list 'interpreter-mode-alist '("Rscript" . ess-r-mode))
-;;;###autoload
-(add-to-list 'interpreter-mode-alist '("r" . ess-r-mode))
-
-(defun ess-r-fix-T-F (&optional from quietly)
-  "Change T/F into TRUE and FALSE cautiously.
-Do not change in comments and strings. Start at FROM, which
-defaults to point, and change to end of buffer. When QUIETLY, do
-not issue messages."
-  (interactive "d\nP"); point and prefix (C-u)
-  (save-excursion
-    (goto-char from)
-    (ess-rep-regexp "\\(\\([][=,()]\\|<-\\) *\\)T\\>" "\\1TRUE"
-                    'fixcase nil (not quietly))
-    (goto-char from)
-    (ess-rep-regexp "\\(\\([][=,()]\\|<-\\) *\\)F\\>" "\\1FALSE"
-                    'fixcase nil (not quietly))))
-(define-obsolete-function-alias 'R-fix-T-F #'ess-r-fix-T-F
-  "ESS 18.10")
-
-(defvar ess--packages-cache nil
-  "Cache var to store package names.
-Used by `ess-r-install-library'.")
-
-(defvar ess--CRAN-mirror nil
-  "CRAN mirror name cache.")
-
-(cl-defmethod ess-install-library--override (update package &context (ess-dialect "R"))
-  "Prompt and install R PACKAGE.
-With argument UPDATE, update cached packages list."
-  (inferior-ess-r-force)
-  (when (equal "@CRAN@" (car (ess-get-words-from-vector "getOption('repos')[['CRAN']]\n")))
-    (ess-set-CRAN-mirror ess--CRAN-mirror)
-    (ess-wait-for-process (get-process ess-current-process-name))
-    (unless package (setq update t)))
-  (when (or update
-            (not ess--packages-cache))
-    (message "Fetching R packages ... ")
-    (setq ess--packages-cache
-          (ess-get-words-from-vector--foreground "print(rownames(available.packages()), max=1e6)\n")))
-  (let* ((ess-eval-visibly-p t)
-         (package (or package
-                      (ess-completing-read "Package to install" ess--packages-cache))))
-    (process-send-string (get-process ess-current-process-name)
-                         (format "install.packages('%s')\n" package))
-    (display-buffer (buffer-name (ess-get-process-buffer)))))
-
-(defun ess-setRepositories ()
-  "Call setRepositories()."
-  (interactive)
-  (if (not (string-match "^R" ess-dialect))
-      (message "Sorry, not available for %s" ess-dialect)
-    (ess-eval-linewise "setRepositories(FALSE)\n")))
-
-(defun ess-set-CRAN-mirror (&optional mirror)
-  "Set cran MIRROR."
-  (interactive)
-  (let ((mirror-cmd "local({r <- getOption('repos'); r['CRAN'] <- '%s';options(repos=r)})\n"))
-    (if mirror
-        (ess-command (format mirror-cmd mirror))
-      (when-let ((M1 (ess-get-words-from-vector "local({out <- getCRANmirrors(local.only=TRUE); print(paste(out$Name,'[',out$URL,']', sep=''))})\n"))
-                 (mirror (ess-completing-read "Choose CRAN mirror" M1 nil t))
-                 (url (car (cl-member mirror M1 :test #'string=))))
-        (setq ess--CRAN-mirror (progn (string-match "\\(.*\\)\\[\\(.*\\)\\]$" url)
-                                      (match-string 2 url)))
-        (ess-command (format mirror-cmd ess--CRAN-mirror)))))
-  (message "CRAN mirror: %s" (car (ess-get-words-from-vector "getOption('repos')[['CRAN']]\n"))))
-(define-obsolete-function-alias 'ess-setCRANMiror #'ess-set-CRAN-mirror "ESS 18.10")
-
-(defun ess-r-check-install-package (pkg)
-  "Check if package PKG is installed and offer to install if not."
-  (unless (ess-boolean-command (format "print(requireNamespace('%s', quietly = TRUE))\n" pkg))
-    (if (y-or-n-p (format "Package '%s' is not installed. Install? " pkg))
-        (ess-eval-linewise (format "install.packages('%s')\n" pkg))
-      (signal 'quit nil))))
-
-(define-obsolete-function-alias 'ess-r-sos #'ess-help-web-search "ESS 19.04")
-
-(cl-defmethod ess--help-web-search-override (cmd &context (ess-dialect "R"))
-  (ess-r-check-install-package "sos")
-  (ess-eval-linewise (format "sos::findFn(\"%s\", maxPages=10)" cmd)))
-
-
-(defun ess-R-scan-for-library-call (string)
-  "Detect `library/require' call in STRING and update tracking vars.
-Placed into `ess-presend-filter-functions' for R dialects."
-  (when (string-match-p "\\blibrary(\\|\\brequire(" string)
-    (ess--mark-search-list-as-changed))
-  string)
-
-(cl-defmethod ess-installed-packages (&context (ess-dialect "R"))
-  ;;; FIXME? .packages() does not cache; installed.packages() does but is slower first time
-  (ess-get-words-from-vector--foreground "print(.packages(TRUE), max=1e6)\n"))
-
-(cl-defmethod ess-load-library--override (pack &context (ess-dialect "R"))
-  "Load an R package."
-  (ess-eval-linewise (format "library('%s')\n" pack)))
-
-(define-obsolete-function-alias 'ess-library #'ess-load-library "ESS[12.09-1]")
-
-;;; smart-comma was a bad idea
-(eval-after-load "eldoc"
-  '(eldoc-add-command "ess-smart-comma"))
-
-\f
-;;*;; Interaction with R
-
-;;;*;;; Evaluation
-
-(defun ess-r-arg (param value &optional wrap)
-  (let ((value (if wrap
-                   (concat "'" value "'")
-                 value)))
-    (concat ", " param " = " value)))
-
-(defun ess-r-build-args (visibly output namespace)
-  (let ((visibly (ess-r-arg "visibly" (if visibly "TRUE" "FALSE")))
-        (output (ess-r-arg "output" (if output "TRUE" "FALSE")))
-        (pkg (when namespace (ess-r-arg "package" namespace t)))
-        (verbose (when (and namespace
-                            ess-r-namespaced-load-verbose)
-                   (ess-r-arg "verbose" "TRUE"))))
-    (concat visibly output pkg verbose)))
-
-(defun ess-r--format-call (cmd &rest objects)
-  "Prefix an ESSR command with a namespace qualifier.
-CMD is formatted with OBJECTS using `format'."
-  (concat "base::as.environment('ESSR')$"
-          (apply #'format cmd objects)))
-
-(cl-defmethod ess-build-eval-command--override (string &context (ess-dialect "R")
-                                                       &optional visibly output file &rest args)
-  "R method to build eval command."
-  (let* ((namespace (caar args))
-         (namespace (unless ess-debug-minor-mode
-                      (or namespace (ess-r-get-evaluation-env))))
-         (cmd (ess-r--format-call (if namespace ".ess.ns_eval" ".ess.eval")))
-         (file (when file (ess-r-arg "file" file t)))
-         (rargs (ess-r-build-args visibly output namespace)))
-    (concat cmd "(\"" string "\"" rargs file ")\n")))
-
-(cl-defmethod ess-build-load-command (string &context (ess-dialect "R")
-                                             &optional visibly output file &rest _args)
-  (let* ((namespace (or file (ess-r-get-evaluation-env)))
-         (cmd (ess-r--format-call (if namespace ".ess.ns_source" ".ess.source")))
-         (rargs (ess-r-build-args visibly output namespace)))
-    (concat cmd "('" string "'" rargs ")\n")))
-
-(defun ess-r-build-eval-message (message)
-  (let ((env (cond (ess-debug-minor-mode
-                    (substring-no-properties ess-debug-indicator 1))
-                   ((ess-r-get-evaluation-env)))))
-    (if env
-        (format "[%s] %s" env message)
-      message)))
-
-(defvar-local ess-r-evaluation-env nil
-  "Environment into which code should be evaluated.
-When this variable is nil, code is evaluated in the current
-environment. Currently only packages can be set as evaluation
-environments. Use `ess-r-set-evaluation-env' to set this
-variable.")
-
-(defun ess-r-get-evaluation-env ()
-  "Get current evaluation env."
-  ess-r-evaluation-env)
-
-(defun ess-r-set-evaluation-env (&optional arg)
-  "Select a package namespace for evaluation of R code.
-
-Call interactively with a prefix argument to disable evaluation
-in a namespace.  When calling from a function, ARG can be a
-string giving the package to select, any other non-nil value to
-disable, or nil to prompt for a package.
-
-If `ess-r-prompt-for-attached-pkgs-only' is non-nil, prompt only for
-attached packages."
-  (interactive "P")
-  (let ((env (cond ((stringp arg) arg)
-                   ((null arg) (ess-r--select-package-name))
-                   (t "*none*"))))
-    (if (equal env "*none*")
-        (let ((cur-env (ess-r-get-evaluation-env)))
-          (setq ess-r-evaluation-env nil)
-          (delq 'ess-r--evaluation-env-mode-line ess--local-mode-line-process-indicator)
-          (message (format "Evaluation in %s disabled" (propertize cur-env 'face font-lock-function-name-face))))
-      (setq ess-r-evaluation-env env)
-      (add-to-list 'ess--local-mode-line-process-indicator 'ess-r--evaluation-env-mode-line t)
-      (message (format "Evaluating in %s" (propertize env 'face font-lock-function-name-face))))
-    (force-mode-line-update)))
-
-(defvar-local ess-r--evaluation-env-mode-line
-  '(:eval (let ((env (ess-r-get-evaluation-env)))
-            (if env
-                (format " %s"
-                        (propertize  (if (equal env (ess-r-package-name))
-                                         "pkg"
-                                       env)
-                                     'face 'mode-line-emphasis))
-              ""))))
-(put 'ess-r--evaluation-env-mode-line 'risky-local-variable t)
-
-(defvar ess-r-namespaced-load-only-existing t
-  "Whether to load only objects already existing in a namespace.")
-
-(cl-defmethod ess-load-file--override (file &context (ess-dialect "R"))
-  (cond
-   ;; Namespaced evaluation
-   ((ess-r-get-evaluation-env)
-    (ess-r-load-file-namespaced file))
-   ;; Evaluation into current env via .ess.source()
-   (t
-    (let ((command (ess-build-load-command file nil t)))
-      (ess-send-string (ess-get-process) command)))))
-
-(defun ess-r-load-file-namespaced (&optional file)
-  "Load FILE into a package namespace.
-
-This prompts for a package when no package is currently
-selected (see `ess-r-set-evaluation-env')."
-  (ess-force-buffer-current "R process to use: ")
-  (let* ((pkg-name (ess-r-get-evaluation-env))
-         (command (ess-build-load-command file nil t pkg-name)))
-    (ess-send-string (ess-get-process) command)))
-
-(cl-defmethod ess-send-region--override (process start end visibly message type
-                                                 &context (ess-dialect "R"))
-  (cond
-   ;; Namespaced evaluation
-   ((ess-r-get-evaluation-env)
-    (ess-r-send-region-namespaced process start end visibly message))
-   ;; Evaluation into current env
-   (t
-    (ess-send-string process (buffer-substring start end) visibly message type))))
-
-(defun ess-r-send-region-namespaced (proc start end &optional visibly message)
-  "Ask for for the package and devSource region into it."
-  (or (ess-r-get-evaluation-env)
-      (ess-r-set-evaluation-env))
-  (message (ess-r-build-eval-message (or message "Eval region")))
-  (ess-send-string proc (buffer-substring start end) visibly message))
-
-
-;;;*;;; Help
-
-(cl-defmethod ess-build-help-command (object &context (ess-dialect "R"))
-  (let ((info (ess-r--split-namespace object)))
-    (if info
-        (ess-r-help--build-help-command--qualified (car info) (cdr info))
-      (ess-r-help--build-help-command--unqualified object))))
-
-(defun ess-r--split-namespace (sym)
-  (when (string-match "^[[:alnum:].]+::" sym)
-      (let ((pkg (substring-no-properties sym (match-beginning 0) (- (match-end 0) 2)))
-            (obj (substring-no-properties sym (match-end 0))))
-        (cons pkg obj))))
-
-(defvar-local ess-r-help--local-object nil)
-(defvar-local ess-r-help--local-package nil)
-(put 'ess-r-help--local-object 'permanent-local t)
-(put 'ess-r-help--local-package 'permanent-local t)
-
-(defun ess-r-help--build-help-command--qualified (pkg obj)
-  (setq ess-r-help--local-package pkg)
-  (setq ess-r-help--local-object obj)
-  (let ((obj-arg (concat "'" obj "'"))
-        (pkg-arg (ess-r-arg "package" pkg t)))
-    (ess-r--format-call ".ess.help(%s%s)\n" obj-arg pkg-arg)))
-
-(defun ess-r-help--build-help-command--unqualified (obj)
-  (if (eq ess-help-type 'index)
-      ;; We are in index page, qualify with namespace
-      (ess-r-help--build-help-command--qualified ess-help-object obj)
-    (let ((pkg (ess-r-help--find-package obj)))
-      (unless pkg
-        (error "Can't find documentation for `%s'" obj))
-      (ess-r-help--build-help-command--qualified pkg obj))))
-
-(defun ess-r-help--find-package (object)
-  "Find package where to find OBJECT.
-If there are multiple packages attached to the search path, the
-user is prompted for a package location. If OBJECT is not
-documented, returns nil."
-  (let* ((paths (ess-get-words-from-vector
-                 (format "as.character(utils::help('%s'))\n" object)))
-         (paths (if (> (length paths) 1)
-                    (cl-delete-if
-                     (lambda (x) (string-match-p "reexports$" x))
-                     paths)
-                  paths)))
-    (cond ((not paths)
-           nil)
-          ((and (> (length paths) 1)
-                (not noninteractive))
-           (let ((path (ess-completing-read "Choose location" paths nil t)))
-             (ess-r-help--get-pkg-from-help-path path)))
-          (t
-           (ess-r-help--get-pkg-from-help-path (car paths))))))
-
-(defun ess-r-help--get-pkg-from-help-path (path)
-  (file-name-nondirectory
-   (directory-file-name
-    (file-name-directory
-     (directory-file-name
-      (file-name-directory
-       path))))))
-
-(defconst inferior-ess-r--input-help (format "^ *help *(%s)" ess-help-arg-regexp))
-(defconst inferior-ess-r--input-?-help-regexp "^ *\\(?:\\(?1:[a-zA-Z ]*?\\?\\{1,2\\}\\) *\\(?2:.+\\)\\)")
-(defconst inferior-ess-r--page-regexp (format "^ *page *(%s)" ess-help-arg-regexp))
-
-(defun ess-help-r--process-help-input (proc string)
-  (let ((help-match (and (string-match inferior-ess-r--input-help string)
-                         (match-string 2 string)))
-        (help-?-match (and (string-match inferior-ess-r--input-?-help-regexp string)
-                           string))
-        (page-match   (and (string-match inferior-ess-r--page-regexp string)
-                           (match-string 2 string))))
-    (when (or help-match help-?-match page-match)
-      (cond (help-match
-             (ess-display-help-on-object help-match)
-             (process-send-string proc "\n"))
-            (help-?-match
-             (ess-help-r--display-help-? string help-?-match)
-             (process-send-string proc "\n"))
-            (page-match
-             (switch-to-buffer-other-window
-              (ess-command (concat page-match "\n")
-                           (get-buffer-create (concat page-match ".rt"))))
-             (ess-r-transcript-mode)
-             (process-send-string proc "\n")))
-      t)))
-
-(defun ess-help-r--display-help-? (string help-?-match)
-  (cond ((string-match "\\?\\?\\(.+\\)" help-?-match)
-         (ess--display-indexed-help-page (concat help-?-match "\n")
-                                         "^\\([^ \t\n]+::[^ \t\n]+\\)[ \t\n]+"
-                                         (format "*ess-apropos[%s](%s)*"
-                                                 ess-current-process-name (match-string 1 help-?-match))
-                                         'apropos))
-        ((string-match "^ *\\? *\\([^ \t]+\\)$" help-?-match)
-         (ess-display-help-on-object (match-string 1 help-?-match)))
-        ;; Anything else we send to process almost unchanged
-        (t
-         (let ((help-?-match (and (string-match inferior-ess-r--input-?-help-regexp string)
-                                  (format "%s%s" (match-string 1 string)
-                                          (ess-help-r--sanitize-topic (match-string 2 string))))))
-           (ess-display-help-on-object help-?-match "%s\n")))))
-
-(defun ess-help-r--sanitize-topic (string)
-  "Enclose help topic STRING into `` to avoid ?while ?if etc hangs."
-  (if (string-match "\\([^:]*:+\\)\\(.*\\)$" string) ; treat foo::bar correctly
-      (format "%s`%s`" (match-string 1 string) (match-string 2 string))
-    (format "`%s`" string)))
-
-
-;;;*;;; Utils for inferior R process
-
-(defun inferior-ess-r-input-sender (proc string)
-  (save-current-buffer
-    (or (ess-help-r--process-help-input proc string)
-        (inferior-ess-input-sender proc string))))
-
-(defun ess-r-load-ESSR ()
-  "Load ESSR functionality into ESSR environment.
-On remotes, when `ess-r-fetch-ESSR-on-remotes' is non-nil we
-fetch ESSR environment from github to the remote machine.
-Otherwise (the default) we source ESSR files into the remote
-process."
-  (interactive)
-  ;; `.ess.command()` is not defined until ESSR is loaded so disable
-  ;; it temporarily. Would be helpful to implement an `inferior-ess-let'
-  ;; macro .
-  (cond
-   ((file-remote-p (ess-get-process-variable 'default-directory))
-    (if (eq ess-r-fetch-ESSR-on-remotes t)
-        (or (ess-r--fetch-ESSR-remote)
-            (ess-r--load-ESSR-remote))
-      (ess-r--load-ESSR-remote)))
-   ((and (bound-and-true-p ess-remote))
-    ;; NB: With ess-remote we send by chunks because sending large sources is
-    ;; fragile
-    (if ess-r-fetch-ESSR-on-remotes
-        (or (ess-r--fetch-ESSR-remote)
-            (ess-r--load-ESSR-remote t))
-      (ess-r--load-ESSR-remote t)))
-   (t (ess-r--load-ESSR-local))))
-
-(defun ess-r--load-ESSR-local ()
-  "Load ESSR into a local process.
-Source the etc/ESSR/.load.R file into the R process. The
-.ess.ESSR.load function sources all of the contents of the
-etc/ESSR/R directory into the ESSR environment and attaches the
-environment to the search path."
-  (let* ((src-dir (expand-file-name "ESSR/R" ess-etc-directory))
-         (buf (ess-command (ess-r--load-ESSR-command src-dir))))
-    (with-current-buffer buf
-      (let ((msg (buffer-string)))
-        (when (> (length msg) 1)
-          (message (format "Messages while loading ESSR: %s" msg)))))))
-
-(defun ess-r--load-ESSR-command (src-dir)
-  (format "base::tryCatch(
-             base::local({
-               base::source('%s/.load.R', local=TRUE) #define load.ESSR
-               .ess.ESSR.load('%s')
-             }),
-             error = function(cnd) {
-               msg <- paste0('\1e\1eESSR::ERROR \"', conditionMessage(cnd), '\"\1e\1e')
-               writeLines(msg)
-             }
-           )\n"
-          src-dir
-          src-dir))
-
-(defun ess-r--load-ESSR-remote (&optional chunked)
-  "Load ESSR into a remote process through the process connection.
-Send the contents of the etc/ESSR/R directory to the remote
-process through the process connection file by file. Then,
-collect all the objects into an ESSR environment and attach to
-the search path. If CHUNKED is non-nil, split each file by \\^L
-separators and send chunk by chunk."
-  (ess-command (format ".ess.ESSRversion <<- '%s'\n" essr-version))
-  (with-temp-message "Loading ESSR into remote ..."
-    (let ((src-dir (expand-file-name "ESSR/R" ess-etc-directory)))
-      (dolist (file (directory-files src-dir t "\\.R\\'"))
-        (ess--inject-code-from-file file chunked))
-      (ess-command ".ess.collect.ESSR.objects()\n"))))
-
-(defun ess-r--fetch-ESSR-remote ()
-  "Load ESSR into a remote process through a GitHub download.
-Downloads a file with a serialized version of the R ESSR
-environment from GitHub and attaches it to the search path. If
-the file already exists on disk from a previous download then the
-download step is omitted. This function returns t if the ESSR
-load is successful, and nil otherwise."
-  (let ((loader (ess-file-content (expand-file-name "ESSR/LOADREMOTE" ess-etc-directory)))
-        (essr (or essr-version
-                  ;; FIXME: Hack: on MELPA essr-version is not set
-                  (lm-with-file (expand-file-name "ess.el" ess-lisp-directory)
-                    (lm-header "ESSR-Version"))
-                  (error "`essr-version' could not be automatically inferred from ess.el file"))))
-    (or (with-temp-message "Fetching and loading ESSR into the remote ..."
-          (ess-boolean-command (format loader essr)))
-        (let ((errmsg (with-current-buffer " *ess-command-output*" (buffer-string))))
-          (message (format "Couldn't load or download ESSR.rds on the remote.\n Error: %s\n Injecting local copy of ESSR." errmsg))
-          nil))))
-
-(cl-defmethod ess-quit--override (arg &context (ess-dialect "R"))
-  "With ARG, do not offer to save the workspace."
-  (let ((cmd (format "base::q('%s')\n" (if arg "no" "default")))
-        (sprocess (ess-get-process ess-current-process-name)))
-    (when (not sprocess) (error "No ESS process running"))
-    (ess-cleanup)
-    (ess-send-string sprocess cmd)))
-
-(defcustom inferior-ess-r-reload-hook nil
-  "Hook run when reloading the R inferior buffer."
-  :type 'hook
-  :group 'ess-R)
-
-(cl-defmethod inferior-ess-reload--override (start-name start-args &context (ess-dialect "R"))
-  "Call `run-ess-r' with START-ARGS.
-Then run `inferior-ess-r-reload-hook'."
-  (let ((inferior-ess-r-program start-name))
-    (run-ess-r start-args))
-  (run-hooks 'inferior-ess-r-reload-hook))
-
-(defun inferior-ess-r-force (&optional prompt force no-autostart ask-if-1)
-  (setq-local ess-dialect "R")
-  (ess-force-buffer-current prompt force no-autostart ask-if-1))
-
-\f
-;;*;; Editing Tools
-
-;;;*;;; Indentation Engine
-
-;; Written by Lionel Henry in mid 2015
-
-(defun ess-r-indent-line ()
-  "Indent current line as ESS R code.
-Return the amount the indentation changed by."
-  (when-let ((indent (ess-calculate-indent)))
-    (let ((case-fold-search nil)
-          (pos (- (point-max) (point)))
-          beg shift-amt)
-      (beginning-of-line)
-      (setq beg (point))
-      (skip-chars-forward " \t")
-      (setq shift-amt (- indent (current-column)))
-      (if (zerop shift-amt)
-          (if (> (- (point-max) pos) (point))
-              (goto-char (- (point-max) pos)))
-        (delete-region beg (point))
-        (indent-to indent)
-        ;; If initial point was within line's indentation,
-        ;; position after the indentation.
-        ;; Else stay at same point in text.
-        (when (> (- (point-max) pos) (point))
-          (goto-char (- (point-max) pos))))
-      shift-amt)))
-
-(defun ess-r-indent-exp ()
-  (save-excursion
-    (when current-prefix-arg
-      (ess-climb-to-top-level))
-    (let* ((bounds (ess-continuations-bounds))
-           (end (cadr bounds))
-           (beg (if current-prefix-arg
-                    (car bounds)
-                  (forward-line)
-                  (point))))
-      (indent-region beg end))))
-
-(defun ess-indent-call (&optional start)
-  (save-excursion
-    (when (ess-escape-calls)
-      (setq start (or start (point)))
-      (skip-chars-forward "^[(")
-      (forward-char)
-      (ess-up-list)
-      (indent-region start (point)))))
-
-(defun ess-offset (offset)
-  (setq offset
-        (symbol-value (intern (concat "ess-offset-" (symbol-name offset)))))
-  (when (and (not (eq offset nil))
-             (listp offset)
-             (or (numberp (cadr offset))
-                 (eq (cadr offset) t)
-                 (error "Malformed offset")))
-    (setq offset (cadr offset)))
-  (cond ((numberp offset)
-         offset)
-        ((null offset)
-         0)
-        (t
-         ess-indent-offset)))
-
-(defun ess-offset-type (offset)
-  (setq offset
-        (symbol-value (intern (concat "ess-offset-" (symbol-name offset)))))
-  (if (listp offset)
-      (car offset)
-    offset))
-
-(defun ess-overridden-blocks ()
-  (append (when (memq 'fun-decl ess-align-blocks)
-            (list (car ess-prefixed-block-patterns)))
-          (when (memq 'control-flow ess-align-blocks)
-            (append (cdr ess-prefixed-block-patterns)
-                    '("}?[ \t]*else")))))
-
-(defun ess-calculate-indent ()
-  "Return appropriate indentation for current line as ESS code.
-In usual case returns an integer: the column to indent to.
-Returns nil if line starts inside a string, t if in a comment."
-  (save-excursion
-    (beginning-of-line)
-    (let* ((indent-point (point))
-           (state (syntax-ppss))
-           (containing-sexp (cadr state))
-           (prev-containing-sexp (car (last (butlast (nth 9 state))))))
-      (back-to-indentation)
-      (cond
-       ;; Strings
-       ((ess-inside-string-p)
-        (current-indentation))
-       ;; Comments
-       ((ess-calculate-indent--comments))
-       ;; Indentation of commas
-       ((looking-at ",")
-        (ess-calculate-indent--comma))
-       ;; Arguments: Closing
-       ((ess-call-closing-p)
-        (ess-calculate-indent--call-closing-delim))
-       ;; Block: Contents (easy cases)
-       ((ess-calculate-indent--block-relatively))
-       ;; Block: Prefixed block
-       ((ess-calculate-indent--prefixed-block-curly))
-       ;; Continuations
-       ((ess-calculate-indent--continued))
-       ;; Block: Overridden contents
-       ((ess-calculate-indent--aligned-block))
-       ;; Block: Opening
-       ((ess-block-opening-p)
-        (ess-calculate-indent--block-opening))
-       ;; Bare line
-       ((and (null containing-sexp)
-             (not (ess-unbraced-block-p)))
-        0)
-       ;; Block: Closing
-       ((ess-block-closing-p)
-        (ess-calculate-indent--block 0))
-       ;; Block: Contents
-       ((ess-block-p)
-        (ess-calculate-indent--block))
-       ;; Arguments: Nested calls override
-       ((ess-calculate-indent--nested-calls))
-       ;; Arguments: Contents
-       (t
-        (ess-calculate-indent--args))))))
-
-(defun ess-calculate-indent--comments ()
-  (when ess-indent-with-fancy-comments
-    (cond
-     ;; ### or #!
-     ((or (looking-at "###")
-          (and (looking-at "#!")
-               (= 1 (line-number-at-pos))))
-      0)
-     ;; Single # comment
-     ((looking-at "#[^#']")
-      comment-column))))
-
-(defun ess-calculate-indent--comma ()
-  (when (ess-inside-call-p)
-    (let ((indent (save-excursion
-                    (ess-calculate-indent--args)))
-          (unindent (progn (skip-chars-forward " \t")
-                           ;; return number of skipped chars
-                           (skip-chars-forward ", \t"))))
-      (- indent unindent))))
-
-(defun ess-calculate-indent--call-closing-delim ()
-  (cond ((save-excursion
-           (ess-skip-blanks-backward t)
-           (eq (char-before) ?,))
-         (ess-calculate-indent--args nil))
-        ((save-excursion
-           (and (ess-ahead-operator-p)
-                (or (ess-ahead-definition-op-p)
-                    (not ess-align-continuations-in-calls))))
-         (ess-calculate-indent--continued))
-        (t
-         (ess-calculate-indent--args 0))))
-
-(defun ess-calculate-indent--block-opening ()
-  (cond
-   ;; Block is an argument in a function call
-   ((when containing-sexp
-      (ess-at-containing-sexp
-        (ess-behind-call-opening-p "[[(]")))
-    (ess-calculate-indent--block 0))
-   ;; Top-level block
-   ((null containing-sexp) 0)
-   ;; Block is embedded in another block
-   ((ess-at-containing-sexp
-      (+ (current-indentation)
-         (ess-offset 'block))))))
-
-(defun ess-calculate-indent--aligned-block ()
-  ;; Check for `else' opening
-  (if (and (memq 'control-flow ess-align-blocks)
-           (looking-at "else\\b")
-           (ess-climb-if-else))
-      (progn
-        (when (looking-at "else\\b")
-          (ess-skip-curly-backward))
-        (current-column))
-    ;; Check for braced and unbraced blocks
-    (ess-save-excursion-when-nil
-      (let ((offset (if (looking-at "[{})]")
-                        0 (ess-offset 'block))))
-        (when (and (cond
-                    ;; Unbraced blocks
-                    ((ess-climb-block-prefix))
-                    ;; Braced blocks
-                    (containing-sexp
-                     (when (ess-at-containing-sexp
-                             (looking-at "{"))
-                       (ess-escape-prefixed-block))))
-                   (cl-some #'looking-at
-                            (ess-overridden-blocks)))
-          (+ (current-column) offset))))))
-
-(defun ess-calculate-indent--block-relatively ()
-  (ess-save-excursion-when-nil
-    (let ((offset (if (looking-at "[})]") 0 (ess-offset 'block)))
-          (start-line (line-number-at-pos)))
-      (cond
-       ;; Braceless block continuations: only when not in a call
-       ((ess-save-excursion-when-nil
-          (and (not (looking-at "{"))
-               (ess-goto-char (ess-unbraced-block-p))
-               (not (looking-at "function\\b"))
-               (or (null containing-sexp)
-                   (ess-at-containing-sexp
-                     (not (looking-at "("))))))
-        (ess-maybe-climb-broken-else 'same-line)
-        (ess-skip-curly-backward)
-        (+ (current-column)
-           (ess-offset 'block)))
-       ;; Don't indent relatively other continuations
-       ((ess-ahead-continuation-p)
-        nil)
-       ;; If a block already contains an indented line, we can indent
-       ;; relatively from that first line
-       ((ess-save-excursion-when-nil
-          (and (not (looking-at "}"))
-               containing-sexp
-               (goto-char containing-sexp)
-               (looking-at "{")
-               (progn
-                 (forward-line)
-                 (back-to-indentation)
-                 (/= (line-number-at-pos) start-line))
-               (not (looking-at "[ \t]*\\(#\\|$\\)"))
-               (save-excursion
-                 (or (ess-jump-expression)
-                     (ess-jump-continuations))
-                 (< (line-number-at-pos) start-line))))
-        (current-column))
-       ;; If a block is not part of a call, we can indent relatively
-       ;; from the opening {. First check that enclosing { is first
-       ;; thing on line
-       ((and containing-sexp
-             (not (ess-unbraced-block-p))
-             (goto-char containing-sexp)
-             (ess-block-opening-p)
-             (equal (point) (save-excursion
-                              (back-to-indentation)
-                              (point))))
-        (+ (current-column) offset))))))
-
-(defun ess-arg-block-p ()
-  (unless (or (null containing-sexp)
-              ;; Unbraced blocks in a { block are not arg blocks
-              (and (ess-unbraced-block-p)
-                   (ess-at-containing-sexp
-                     (looking-at "{"))))
-    (cond
-     ;; Unbraced body
-     ((ess-at-indent-point
-        (and (ess-unbraced-block-p)
-             (goto-char containing-sexp)
-             (ess-behind-call-opening-p "[[(]")))
-      'body)
-     ;; Indentation of opening brace as argument
-     ((ess-at-containing-sexp
-        (ess-behind-call-opening-p "[[(]"))
-      'opening)
-     ;; Indentation of body or closing brace as argument
-     ((ess-at-containing-sexp
-        (and (or (looking-at "{")
-                 (ess-behind-block-paren-p))
-             prev-containing-sexp
-             (goto-char prev-containing-sexp)
-             (ess-behind-call-opening-p "[[(]")))
-      'body))))
-
-(defun ess-calculate-indent--block (&optional offset)
-  (let ((arg-block (ess-arg-block-p)))
-    (cond (arg-block
-           (ess-calculate-indent--arg-block offset arg-block))
-          (t
-           ;; Block is not part of an arguments list. Climb over any
-           ;; block opening (function declaration, etc) to indent from
-           ;; starting indentation.
-           (or (ess-climb-block-prefix)
-               (and (goto-char containing-sexp)
-                    (ess-climb-block-prefix)))
-           (+ (current-indentation) (or offset (ess-offset 'block)))))))
-
-(defun ess-calculate-indent--arg-block (offset arg-block)
-  (let* ((block-type (cond ((or (ess-at-containing-sexp
-                                  (and (eq arg-block 'body)
-                                       (ess-climb-block-prefix "function")))
-                                (ess-at-indent-point
-                                  (and (eq arg-block 'opening)
-                                       (ess-backward-sexp 2)
-                                       (looking-at "function\\b"))))
-                            'fun-decl)
-                           ((ess-at-indent-point
-                              (ess-unbraced-block-p))
-                            'unbraced)
-                           ((ess-at-containing-sexp
-                              (not (ess-ahead-attached-name-p)))
-                            'bare-block)
-                           (t)))
-         (call-pos (if (and (not (eq block-type 'unbraced))
-                            (not (eq arg-block 'opening)))
-                       (goto-char prev-containing-sexp)
-                     (prog1 containing-sexp
-                       (goto-char indent-point)))))
-    (ess-calculate-indent--args offset (ess-offset-type 'block)
-                                call-pos indent-point block-type)))
-
-;; This function is currently the speed bottleneck of the indentation
-;; engine. This is due to the need to call (ess-maximum-args-indent)
-;; to check if some previous arguments have been pushed off from their
-;; natural indentation: we need to check the whole call. This is very
-;; inefficient especially when indenting a region containing a large
-;; function call (e.g. some dplyr's data cleaning code). Should be
-;; solved by implementing a cache as in (syntax-ppss), though it's
-;; probably not worth the work.
-(defun ess-calculate-indent--args (&optional offset type call-pos to block)
-  (let* ((call-pos (or call-pos containing-sexp))
-         (max-col (prog1 (unless (eq type 'prev-line)
-                           (ess-maximum-args-indent call-pos to))
-                    (goto-char call-pos)))
-         (override (and ess-align-arguments-in-calls
-                        (save-excursion
-                          (ess-climb-object)
-                          (cl-some #'looking-at
-                                   ess-align-arguments-in-calls))))
-         (type-sym (cond (block 'block)
-                         ((looking-at "[[:blank:]]*[([][[:blank:]]*\\($\\|#\\)")
-                          'arguments-newline)
-                         (t 'arguments)))
-         (type (or type
-                   (and override 'open-delim)
-                   (ess-offset-type type-sym)))
-         (offset (or offset
-                     (and (not block) (eq type 'open-delim) 0)
-                     (ess-offset type-sym)))
-         (indent
-          (cond
-           ;; Indent from opening delimiter
-           ((eq type 'open-delim)
-            (ess-calculate-indent--args-open-delim))
-           ;; Indent from attached name
-           ((eq type 'prev-call)
-            (ess-calculate-indent--args-prev-call block))
-           ;; Indent from previous line indentation
-           ((eq type 'prev-line)
-            (let ((out (ess-calculate-indent--args-prev-line type block offset)))
-              (setq offset (pop out))
-              (pop out)))
-           (t
-            (error "Malformed offset")))))
-    (if max-col
-        (ess-adjust-argument-indent indent offset max-col block)
-      (+ indent offset))))
-
-(defun ess-calculate-indent--args-open-delim ()
-  (forward-char)
-  (current-column))
-
-(defun ess-calculate-indent--args-prev-call (block)
-  ;; Handle brackets chains such as ][ (cf data.table)
-  (ess-climb-chained-delims)
-  ;; Handle call chains
-  (if ess-indent-from-chain-start
-      (while (and (ess-backward-sexp)
-                  (when (looking-back "[[(][ \t,]*" (line-beginning-position))
-                    (goto-char (match-beginning 0)))))
-    (ess-backward-sexp))
-  (when ess-indent-from-lhs
-    (ess-climb-lhs))
-  (if (and nil
-           (eq block 'fun-decl)
-           (not (eq arg-block 'opening))
-           (not (eq (ess-offset-type type-sym) 'open-delim)))
-      (+ (ess-offset 'block) (current-column))
-    (current-column)))
-
-(defun ess-calculate-indent--args-prev-line (type block offset)
-  (ess-at-indent-point
-    (cond
-     ;; Closing delimiters are actually not indented at
-     ;; prev-line, but at opening-line
-     ((looking-at "[]})]")
-      (ess-up-list -1)
-      (when (looking-at "{")
-        (ess-climb-block-prefix))
-      (list offset (current-indentation)))
-     ;; Function blocks need special treatment
-     ((and (eq type 'prev-line)
-           (eq block 'fun-decl))
-      (goto-char containing-sexp)
-      (ess-climb-block-prefix)
-      (list offset (current-indentation)))
-     ;; Regular case
-     (t
-      ;; Find next non-empty line to indent from
-      (while (and (= (forward-line -1) 0)
-                  (looking-at "[ \t]*\\($\\|#\\)")))
-      (goto-char (ess-code-end-position))
-      ;; Climb relevant structures
-      (unless (ess-climb-block-prefix)
-        (when (eq (char-before) ?,)
-          (forward-char -1))
-        (ess-climb-expression)
-        (ess-climb-continuations))
-      ;; The following ensures that only the first line
-      ;; counts. Otherwise consecutive statements would get
-      ;; increasingly more indented.
-      (let ((offset (if (and block
-                             containing-sexp
-                             (not (eq block 'unbraced))
-                             (save-excursion
-                               (/= (line-number-at-pos)
-                                   (progn (goto-char containing-sexp)
-                                          (line-number-at-pos)))))
-                        0
-                      offset)))
-        (list offset (current-indentation)))))))
-
-;; Indentation of arguments needs to keep track of how previous
-;; arguments are indented. If one of those has a smaller indentation,
-;; we push off the current line from its natural indentation. For
-;; block arguments, we still need to push off this column so we ignore
-;; it.
-(defun ess-adjust-argument-indent (base offset max-col push)
-  (if push
-      (+ (min base max-col) offset)
-    (min (+ base offset) max-col)))
-
-;; When previous arguments are shifted to the left (can happen in
-;; several situations) compared to their natural indentation, the
-;; following lines should not get indented past them. The following
-;; function checks the minimum indentation for all arguments of the
-;; current function call or bracket indexing.
-(defun ess-maximum-args-indent (&optional from to)
-  (let* ((to (or to (point)))
-         (to-line (line-number-at-pos to))
-         (from-line (progn
-                      (goto-char (1+ (or from containing-sexp)))
-                      (line-number-at-pos)))
-         max-col)
-    (while (< (line-number-at-pos) to-line)
-      (forward-line)
-      (back-to-indentation)
-      ;; Ignore the line with the function call, the line to be
-      ;; indented, and empty lines.
-      (unless (or (>= (line-number-at-pos) to-line)
-                  (looking-at "[ \t]*\\($\\|#\\)"))
-        (let ((indent (cond
-                       ;; First line: minimum indent is right after (
-                       ((= (line-number-at-pos) from-line)
-                        (save-excursion
-                          (goto-char (1+ containing-sexp))
-                          (current-column)))
-                       ;; Handle lines starting with a comma
-                       ((save-excursion
-                          (looking-at ","))
-                        (+ (current-indentation) 2))
-                       (t
-                        (current-indentation)))))
-          (setq max-col (min indent (or max-col indent))))))
-    max-col))
-
-;; Move to leftmost side of a call (either the first letter of its
-;; name or its closing delim)
-(defun ess-move-to-leftmost-side ()
-  (when (or (looking-at "[({]")
-            (ess-behind-call-p))
-    (ess-save-excursion-when-nil
-      (let ((start-col (current-column)))
-        (skip-chars-forward "^{[(")
-        (forward-char)
-        (ess-up-list)
-        (forward-char -1)
-        (< (current-column) start-col)))))
-
-(defun ess-max-col ()
-  (let ((max-col (point)))
-    (save-excursion
-      (while (< (point) indent-point)
-        (unless (and ess-indent-with-fancy-comments
-                     (looking-at "### "))
-          (setq max-col (min max-col (current-column))))
-        (forward-line)
-        (back-to-indentation)))
-    max-col))
-
-(defun ess-calculate-indent--prefixed-block-curly ()
-  (when (looking-at "{")
-    (ess-save-excursion-when-nil
-      (let ((block-type (ess-climb-block-prefix)))
-        (cond ((ess-save-excursion-when-nil
-                 (and (memq 'fun-decl-opening ess-indent-from-lhs)
-                      (string= block-type "function")
-                      (ess-climb-operator)
-                      (ess-behind-assignment-op-p)
-                      (ess-climb-expression)))
-               (current-column))
-              ((= (save-excursion
-                    (back-to-indentation)
-                    (point))
-                  (point))
-               (ess-calculate-indent--continued)))))))
-
-(defun ess-calculate-indent--continued ()
-  "If a continuation line, return an indent of this line, otherwise nil."
-  (save-excursion
-    (let* ((cascade (eq (ess-offset-type 'continued) 'cascade))
-           (climbed (ess-climb-continuations cascade))
-           max-col)
-      (when climbed
-        (cond
-         ;; Overridden calls
-         ((and ess-align-continuations-in-calls
-               (not (eq climbed 'def-op))
-               containing-sexp
-               (save-excursion
-                 (goto-char containing-sexp)
-                 (looking-at "[[(]")))
-          (setq max-col (ess-max-col))
-          (ess-move-to-leftmost-side)
-          (+ (min (current-column) max-col)
-             (if (eq climbed 'def-op)
-                 (ess-offset 'continued)
-               0)))
-         ;; Regular case
-         (t
-          (let ((first-indent (or (eq climbed 'def-op)
-                                  (save-excursion
-                                    (when (ess-ahead-closing-p)
-                                      (ess-climb-expression))
-                                    (not (ess-climb-continuations cascade))))))
-            ;; Record all indentation levels between indent-point and
-            ;; the line we climbed. Some lines may have been pushed off
-            ;; their natural indentation. These become the new
-            ;; reference.
-            (setq max-col (ess-max-col))
-            ;; Indenting continuations from the front of closing
-            ;; delimiters looks better
-            (when
-                (ess-ahead-closing-p)
-              (backward-char))
-            (+ (min (current-column) max-col)
-               (cond
-                ((eq (ess-offset-type 'continued) 'cascade)
-                 (ess-offset 'continued))
-                (first-indent
-                 (ess-offset 'continued))
-                (t
-                 0))))))))))
-
-(defun ess-calculate-indent--nested-calls ()
-  (when ess-align-nested-calls
-    (let ((calls (mapconcat #'identity ess-align-nested-calls "\\|"))
-          match)
-      (save-excursion
-        (and containing-sexp
-             (looking-at (concat "\\(" calls "\\)("))
-             (setq match (match-string 1))
-             (goto-char containing-sexp)
-             (looking-at "(")
-             (ess-backward-sexp)
-             (looking-at (concat match "("))
-             (current-column))))))
-
-
-;;;*;;; Call filling engine
-
-;; Unroll arguments to a single line until closing marker is found.
-(defun ess-fill--unroll-lines (bounds &optional jump-cont)
-  (let* ((last-pos (point-min))
-         (containing-sexp (ess-containing-sexp-position)))
-    (goto-char (car bounds))
-    (goto-char (ess-code-end-position))
-    (while (and (/= (point) last-pos)
-                (< (line-end-position)
-                   (cadr bounds)))
-      (setq last-pos (point))
-      ;; Check whether we ended up in a sub call. In this case, jump
-      ;; over it, otherwise, join lines.
-      (let ((contained-sexp (ess-containing-sexp-position)))
-        (cond ((and contained-sexp
-                    containing-sexp
-                    (not (= containing-sexp contained-sexp)))
-               (goto-char (1+ contained-sexp))
-               (ess-up-list))
-              ;; Jump over continued statements
-              ((and jump-cont (ess-ahead-operator-p 'strict))
-               (ess-climb-token)
-               (ess-jump-continuations))
-              ;; Jump over comments
-              ((looking-at "#")
-               (forward-line)
-               (funcall indent-line-function))
-              (t
-               (join-line 1))))
-      (goto-char (ess-code-end-position)))
-    (goto-char (car bounds))))
-
-(defvar ess-fill--orig-pos nil
-  "Original position of cursor.")
-
-(defvar ess-fill--orig-state nil
-  "Backup of original code to cycle back to original state.")
-
-(defvar ess-fill--second-state nil
-  "Backup of code produce by very first cycling.
-If this is equal to orig-state, no need to cycle back to original
-state.")
-
-(defvar ess-fill--style-level nil
-  "Filling style used in last cycle.")
-
-(defun ess-fill--substring (bounds)
-  (buffer-substring (car bounds) (marker-position (cadr bounds))))
-
-;; Detect repeated commands
-(defun ess-fill-style (type bounds)
-  (let ((max-level
-         ;; This part will be simpler once we have the style alist
-         (cond ((eq type 'calls)
-                ;; No third style either when ess-offset-arguments is
-                ;; set to 'open-delim, or when ess-fill-calls-newlines
-                ;; is nil and no numeric prefix is given
-                (if (and (not (eq (ess-offset-type 'arguments)
-                                  'open-delim))
-                         (or ess-fill-calls-newlines
-                             (numberp current-prefix-arg)))
-                    3
-                  2))
-               ((eq type 'continuations)
-                2))))
-    (if (not (memq last-command '(fill-paragraph-or-region
-                                  fill-paragraph)))
-        (progn
-          ;; Record original state on first cycling
-          (setq ess-fill--orig-state (ess-fill--substring bounds))
-          (setq ess-fill--orig-pos (point))
-          (setq ess-fill--second-state nil)
-          (setq ess-fill--style-level 1))
-      ;; Also record state on second cycling
-      (when (and (= ess-fill--style-level 1)
-                 (null ess-fill--second-state))
-        (setq ess-fill--second-state (ess-fill--substring bounds)))
-      (cond ((>= ess-fill--style-level max-level)
-             (let ((same-last-and-orig (string= (ess-fill--substring bounds)
-                                                ess-fill--orig-state))
-                   (same-2nd-and-orig (string= ess-fill--orig-state
-                                               ess-fill--second-state)))
-               ;; Avoid cycling to the same state twice
-               (cond ((and same-last-and-orig
-                           same-2nd-and-orig)
-                      (setq ess-fill--style-level 2))
-                     ((or same-last-and-orig
-                          same-2nd-and-orig)
-                      (setq ess-fill--style-level 1))
-                     (t
-                      (setq ess-fill--style-level 0)))))
-            (ess-fill--style-level
-             (setq ess-fill--style-level (1+ ess-fill--style-level))))))
-  ess-fill--style-level)
-
-(let (_)
-  ;; FIXME: Transform these dynamic bindings to a state object
-  (defvar ess--infinite)
-  (defvar ess--prefix-break)
-  (defvar ess--start-pos)
-  (defvar ess--last-pos)
-  (defvar ess--last-newline)
-
-  (declare-function ess-fill-args--roll-lines "ess-r-mode")
-
-  (defun ess-fill-args (&optional style)
-    (let ((ess--start-pos (point-min))
-          (bounds (ess-args-bounds 'marker))
-          ;; Set undo boundaries manually
-          (undo-inhibit-record-point t)
-          ess--last-pos ess--last-newline ess--prefix-break
-          ess--infinite)
-      (when (not bounds)
-        (error "Could not find function bounds"))
-      (setq style (or style (ess-fill-style 'calls bounds)))
-      (if (= style 0)
-          (progn
-            (delete-region (car bounds) (marker-position (cadr bounds)))
-            (insert ess-fill--orig-state)
-            ;; Restore the point manually. (save-excursion) wouldn't
-            ;; work here because we delete the text rather than just
-            ;; modifying it.
-            (goto-char ess-fill--orig-pos)
-            (message "Back to original formatting"))
-        (when ess-blink-refilling
-          (ess-blink-region (nth 2 bounds)
-                            (1+ (marker-position (cadr bounds)))))
-        (undo-boundary)
-        (save-excursion
-          (ess-fill--unroll-lines bounds t)
-          (cond
-           ;; Some styles start with first argument on a newline
-           ((and (memq style '(2 4))
-                 ess-fill-calls-newlines
-                 (not (looking-at "[ \t]*#")))
-            (newline-and-indent))
-           ;; Third level, start a newline after N arguments
-           ((and (= style 3)
-                 (not (looking-at "[ \t]*#")))
-            (let ((i (if (numberp current-prefix-arg)
-                         current-prefix-arg
-                       1)))
-              (while (and (> i 0)
-                          (ess-jump-arg)
-                          (ess-jump-char ","))
-                (setq i (1- i))))
-            (newline-and-indent)))
-          (ess-fill-args--roll-lines style)
-          ;; Reindent surrounding context
-          (ess-indent-call (car bounds)))
-        ;; Signal marker for garbage collection
-        (set-marker (cadr bounds) nil)
-        (undo-boundary))))
-
-  (defun ess-fill-args--roll-lines (style)
-    (while (and (not (looking-at "[])]"))
-                (/= (point) (or ess--last-pos 1))
-                (not ess--infinite))
-      (setq ess--prefix-break nil)
-      ;; Record ess--start-pos as future breaking point to avoid breaking
-      ;; at `=' sign
-      (while (looking-at "[ \t]*[\n#]")
-        (forward-line)
-        (back-to-indentation))
-      (setq ess--start-pos (point))
-      (while (and (< (current-column) fill-column)
-                  (not (looking-at "[])]"))
-                  (/= (point) (or ess--last-pos 1))
-                  ;; Break after one pass if prefix is active
-                  (not ess--prefix-break))
-        (when (memq style '(2 3))
-          (setq ess--prefix-break t))
-        (ess-jump-token ",")
-        (setq ess--last-pos (point))
-        ;; Jump expression and any continuations. Reindent all lines
-        ;; that were jumped over
-        (let ((cur-line (line-number-at-pos))
-              end-line)
-          (cond ((ess-jump-arg)
-                 (setq ess--last-newline nil))
-                ((ess-token-after= ",")
-                 (setq ess--last-newline nil)
-                 (setq ess--last-pos (1- (point)))))
-          (save-excursion
-            (when (< cur-line (line-number-at-pos))
-              (setq end-line (line-number-at-pos))
-              (ess-goto-line (1+ cur-line))
-              (while (and (<= (line-number-at-pos) end-line)
-                          (/= (point) (point-max)))
-                (funcall indent-line-function)
-                (forward-line))))))
-      (when (or (>= (current-column) fill-column)
-                ess--prefix-break
-                ;; Ensures closing delim on a newline
-                (and (= style 4)
-                     (looking-at "[ \t]*[])]")
-                     (setq ess--last-pos (point))))
-        (if (and ess--last-pos (/= ess--last-pos ess--start-pos))
-            (goto-char ess--last-pos)
-          (ess-jump-char ","))
-        (cond ((looking-at "[ \t]*[#\n]")
-               (forward-line)
-               (funcall indent-line-function)
-               (setq ess--last-newline nil))
-              ;; With levels 2 and 3, closing delim goes on a newline
-              ((looking-at "[ \t]*[])]")
-               (when (and (memq style '(2 3 4))
-                          ess-fill-calls-newlines
-                          (not ess--last-newline))
-                 (newline-and-indent)
-                 ;; Prevent indenting infinitely
-                 (setq ess--last-newline t)))
-              ((not ess--last-newline)
-               (newline-and-indent)
-               (setq ess--last-newline t))
-              (t
-               (setq ess--infinite t)))))))
-
-(defun ess-fill-continuations (&optional style)
-  (let ((bounds (ess-continuations-bounds 'marker))
-        (undo-inhibit-record-point t)
-        (last-pos (point-min))
-        last-newline infinite)
-    (when (not bounds)
-      (error "Could not find statements bounds"))
-    (setq style (or style (ess-fill-style 'continuations bounds)))
-    (if (= style 0)
-        (progn
-          (delete-region (car bounds) (marker-position (cadr bounds)))
-          (insert ess-fill--orig-state)
-          (goto-char ess-fill--orig-pos)
-          (message "Back to original formatting"))
-      (when ess-blink-refilling
-        (ess-blink-region (car bounds) (marker-position (cadr bounds))))
-      (undo-boundary)
-      (save-excursion
-        (ess-fill--unroll-lines bounds)
-        (while (and (< (point) (cadr bounds))
-                    (/= (point) (or last-pos 1))
-                    (not infinite))
-          (setq last-pos (point))
-          (when (and (ess-jump-expression)
-                     (indent-according-to-mode)
-                     (not (> (current-column) fill-column)))
-            (setq last-newline nil))
-          (ess-jump-operator)
-          (if (or (and (> (current-column) fill-column)
-                       (goto-char last-pos))
-                  (= style 2))
-              (progn
-                (ess-jump-operator)
-                (unless (= (point) (cadr bounds))
-                  (when last-newline
-                    (setq infinite t))
-                  (newline-and-indent)
-                  (setq last-newline t)))
-            (setq last-newline nil)))
-        (ess-indent-call (car bounds)))
-      (set-marker (cadr bounds) nil)
-      (undo-boundary))))
-
-\f
-
-;;;*;;; Inferior R mode
-
-(defvar inferior-ess-r-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map "\M-\r" #'ess-dirs)
-    (define-key map (kbd "C-c C-=") #'ess-cycle-assign)
-    (define-key map (kbd "C-c C-.") 'ess-rutils-map)
-    map)
-  "Keymap for `inferior-ess-r-mode'.")
-
-;; TOTHINK: Prevent string delimiting characters from messing up output in the
-;; inferior buffer
-(defvar inferior-ess-r-mode-syntax-table
-  (let ((table (copy-syntax-table ess-r-mode-syntax-table)))
-    (modify-syntax-entry ?% "." table)
-    (modify-syntax-entry ?\' "." table)
-    table)
-  "Syntax table for `inferior-ess-r-mode'.")
-
-(define-derived-mode inferior-ess-r-mode inferior-ess-mode "iESS"
-  "Major mode for interacting with inferior R processes."
-  :group 'ess-proc
-  (ess-setq-vars-local ess-r-customize-alist)
-  (setq-local ess-font-lock-keywords 'inferior-ess-r-font-lock-keywords)
-  (setq-local font-lock-syntactic-face-function #'ess-r-font-lock-syntactic-face-function)
-  (setq-local comint-process-echoes (eql ess-eval-visibly t))
-  (setq-local comint-prompt-regexp inferior-S-prompt)
-  (setq-local syntax-propertize-function ess-r--syntax-propertize-function)
-  (setq comint-input-sender 'inferior-ess-r-input-sender)
-  (remove-hook 'completion-at-point-functions #'ess-filename-completion 'local) ;; should be first
-  (add-hook 'completion-at-point-functions #'ess-r-object-completion nil 'local)
-  (add-hook 'completion-at-point-functions #'ess-filename-completion nil 'local)
-  (add-hook 'xref-backend-functions #'ess-r-xref-backend nil 'local)
-  (add-hook 'project-find-functions #'ess-r-project nil 'local)
-  ;; eldoc
-  (ess--setup-eldoc #'ess-r-eldoc-function)
-  ;; auto-complete
-  (ess--setup-auto-complete ess-r-ac-sources t)
-  ;; company
-  (ess--setup-company ess-r-company-backends t)
-  (setq comint-get-old-input #'inferior-ess-get-old-input)
-  (add-hook 'comint-input-filter-functions #'ess-search-path-tracker nil 'local))
-
-
-\f
-;;;*;;; R Help mode
-
-(defvar ess-r-help-mode-map
-  (let ((map (make-sparse-keymap)))
-    (set-keymap-parent map (make-composed-keymap button-buffer-map
-                                                 ess-help-mode-map))
-    (define-key map "s<" #'beginning-of-buffer)
-    (define-key map "s>" #'end-of-buffer)
-    (define-key map "sa" #'ess-skip-to-help-section)
-    (define-key map "sd" #'ess-skip-to-help-section)
-    (define-key map "sD" #'ess-skip-to-help-section)
-    (define-key map "st" #'ess-skip-to-help-section)
-    (define-key map "se" #'ess-skip-to-help-section)
-    (define-key map "sn" #'ess-skip-to-help-section)
-    (define-key map "sr" #'ess-skip-to-help-section)
-    (define-key map "ss" #'ess-skip-to-help-section)
-    (define-key map "su" #'ess-skip-to-help-section)
-    (define-key map "sv" #'ess-skip-to-help-section)
-    map)
-  "Keymap for `ess-r-help-mode'.")
-
-(cl-defmethod ess--help-major-mode (&context (ess-dialect "R"))
-  (ess-r-help-mode))
-
-(define-derived-mode ess-r-help-mode ess-help-mode "R Help"
-  "Major mode for help buffers."
-  :group 'ess-help
-  (setq ess-dialect "R"
-        ess-help-sec-regex ess-help-r-sec-regex
-        ess-help-sec-keys-alist ess-help-r-sec-keys-alist ; TODO: Still necessary?
-        inferior-ess-help-command inferior-ess-r-help-command)
-  (ess-r-help--add-links))
-
-(define-button-type 'ess-r-help--link
-  'follow-link t
-  'action (lambda (_) (ess-r-help--button-action)))
-
-(defun ess-r-help--button-action ()
-  "Display help for button at point."
-  (let ((text (get-text-property (point) 'ess-r-help--link-text)))
-    (ess-display-help-on-object text)))
-
-(defun ess-r-help--add-links ()
-  "Add links to the help buffer."
-  (let ((links (when (ess-process-live-p)
-                 (ess-get-words-from-vector
-                  (ess-r--format-call
-                   ".ess.helpLinks('%s' %s)\n"
-                   ess-r-help--local-object
-                   (ess-r-arg "package" ess-r-help--local-package t)))))
-        (inhibit-read-only t))
-    (save-excursion
-      ;; Search for fancy quotes only. If users have
-      ;; options(useFancyQuotes) set to something other than TRUE this
-      ;; probably won't work. If it's FALSE, R outputs ascii ', but
-      ;; searching through the whole buffer takes too long.
-      (while (re-search-forward "‘\\([^[:space:]]+?\\)’" nil t)
-        (let* ((text (match-string 1))
-               (text-stripped (if (string-match-p ".*()\\'" text)
-                                  (substring text nil (- (length text) 2))
-                                text)))
-          (when (member text-stripped links)
-            (delete-region (match-beginning 0) (match-end 0))
-            (insert-text-button text
-                                'ess-r-help--link-text text-stripped
-                                'type 'ess-r-help--link
-                                'help-echo (format "mouse-2, RET: Help on %s" text))))))))
-
-(cl-defmethod ess--display-vignettes-override (all &context (ess-dialect "R"))
-  "Display R vignettes in ess-help-like buffer..
-With (prefix) ALL non-nil, use `vignette(*, all=TRUE)`, i.e.,
-from all installed packages, which can be very slow."
-  (inferior-ess-r-force)
-  (let* ((vslist (with-current-buffer
-                     (ess-command
-                      (format ".ess_vignettes(%s)\n" (if all "TRUE" "")))
-                   (goto-char (point-min))
-                   (when (re-search-forward "(list" nil t)
-                     (goto-char (match-beginning 0))
-                     (ignore-errors (eval (read (current-buffer)) t)))))
-         (proc-name ess-current-process-name)
-         (alist ess-local-customize-alist)
-         (remote (file-remote-p default-directory))
-         (buff (get-buffer-create (format "*[%s]vignettes*" ess-dialect)))
-         (inhibit-modification-hooks t)
-         (inhibit-read-only t))
-    (with-current-buffer buff
-      (setq buffer-read-only nil)
-      (delete-region (point-min) (point-max))
-      (ess-setq-vars-local (eval alist t))
-      (setq ess-local-process-name proc-name)
-      (ess--help-major-mode)
-      (setq ess-help-sec-regex "^\\w+:$"
-            ess-help-type 'vignettes)
-      (set-buffer-modified-p 'nil)
-      (goto-char (point-min))
-      (dolist (el vslist)
-        (let ((pack (car el)))
-          (insert (format "\n\n%s:\n\n" (propertize pack 'face 'underline)))
-          (dolist (el2 (cdr el))
-            (let ((path (if remote
-                            (with-no-warnings
-                              ;; Have to wrap this in with-no-warnings because
-                              ;; otherwise the byte compiler complains about
-                              ;; calling tramp-make-tramp-file-name with an
-                              ;; incorrect number of arguments on Both 26+ and 25 emacses.
-                              (if (>= emacs-major-version 26)
-                                  (with-parsed-tramp-file-name default-directory nil
-                                    (tramp-make-tramp-file-name method user domain host port (nth 1 el2)))
-                                (with-parsed-tramp-file-name default-directory nil
-                                  (tramp-make-tramp-file-name method user host (nth 1 el2)))))
-                          (nth 1 el2))))
-              (insert-text-button "doc"
-                                  'mouse-face 'highlight
-                                  'action (if remote
-                                              #'ess--action-open-in-emacs
-                                            #'ess--action-R-open-vignette)
-                                  'follow-link t
-                                  'vignette (file-name-sans-extension (nth 2 el2))
-                                  'package pack
-                                  'help-echo (concat path "/doc/" (nth 2 el2)))
-              (insert " ")
-              (insert-text-button "source"
-                                  'mouse-face 'highlight
-                                  'action #'ess--action-open-in-emacs
-                                  'follow-link t
-                                  'help-echo (concat path "/doc/" (nth 3 el2)))
-              (insert " ")
-              (insert-text-button "R"
-                                  'mouse-face 'highlight
-                                  'action #'ess--action-open-in-emacs
-                                  'follow-link t
-                                  'help-echo (concat path "/doc/" (nth 4 el2)))
-              (insert (format "\t%s\n" (nth 0 el2)))))))
-      (goto-char (point-min))
-      (insert (propertize "\t\t**** Vignettes ****\n" 'face 'bold-italic))
-      (unless (eobp) (delete-char 1))
-      (setq buffer-read-only t))
-    (ess-display-help buff)))
-
-\f
-
-;; Support for listing R packages
-
-(define-obsolete-variable-alias 'ess-rutils-buf 'ess-r-package-menu-buf "ESS 19.04")
-(define-obsolete-variable-alias 'ess-rutils-mode-map 'ess-r-package-menu-mode-map "ESS 19.04")
-(define-obsolete-function-alias 'ess-rutils-mode #'ess-r-package-menu-mode "ESS 19.04")
-
-(defvar ess-rutils-map
-  (let ((map (define-prefix-command 'ess-rutils-map)))
-    (define-key map "l" #'ess-r-package-list-local-packages)
-    (define-key map "r" #'ess-r-package-list-available-packages)
-    (define-key map "u" #'ess-r-package-update-packages)
-    (define-key map "a" #'ess-display-help-apropos)
-    (define-key map "m" #'ess-rutils-rm-all)
-    (define-key map "o" #'ess-rdired)
-    (define-key map "w" #'ess-rutils-load-workspace)
-    (define-key map "s" #'ess-rutils-save-workspace)
-    (define-key map "d" #'ess-change-directory)
-    (define-key map "H" #'ess-rutils-html-docs)
-    map))
-
-(easy-menu-define ess-rutils-mode-menu inferior-ess-mode-menu
-  "Package management."
-  '("Package management"
-    ["List local packages" ess-r-package-list-local-packages t]
-    ["List available packages" ess-r-package-list-available-packages t]
-    ["Update packages" ess-r-package-update-packages t]))
-
-(easy-menu-add-item inferior-ess-mode-menu nil ess-rutils-mode-menu "Utils")
-(easy-menu-add-item ess-mode-menu nil ess-rutils-mode-menu "Process")
-
-(defvar ess-r-package-menu-buf "*R packages*"
-  "Name of buffer to display R packages in.")
-
-(defvar ess-r-package-menu-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map "l" #'ess-r-package-load)
-    (define-key map "i" #'ess-r-package-mark-install)
-    (define-key map "x" #'ess-r-package-execute-marks)
-    (define-key map "u" #'ess-r-package-unmark)
-    map)
-  "Keymap for `ess-rutils-mode'.")
-
-(define-derived-mode ess-r-package-menu-mode tabulated-list-mode "R utils"
-  "Major mode for `ess-rutils-local-pkgs' and `ess-rutils-repos-pkgs'."
-  :group 'ess-R
-  (setq ess-dialect "R")
-  (setq mode-name (concat "R packages: " ess-local-process-name))
-  (setq tabulated-list-padding 2)
-  (setq tabulated-list-format
-        `[("Name" 10 t)
-          ("Description" 50 nil)
-          ("Version" 5 t)])
-  (tabulated-list-init-header))
-
-(define-obsolete-function-alias 'ess-rutils-local-pkgs #'ess-r-package-list-local-packages "ESS 19.04")
-
-(defun ess-r-package-list-local-packages ()
-  "List all packages in all libraries."
-  (interactive)
-  (ess-r-package--list-packages (concat ".ess.rutils.ops <- options(width = 10000);"
-                                        "print(installed.packages(fields=c(\"Title\"))[, c(\"Title\", \"Version\")]);"
-                                        "options(.ess.rutils.ops); rm(.ess.rutils.ops);"
-                                        "\n")))
-
-(defun ess-r-package--list-packages (cmd)
-  "Use CMD to list packages."
-  (let ((process ess-local-process-name)
-        des-col-beginning des-col-end entries)
-    (with-current-buffer (ess-command cmd (get-buffer-create " *ess-rutils-pkgs*"))
-      (goto-char (point-min))
-      (delete-region (point) (1+ (line-end-position)))
-      ;; Now we have a buffer with package name, description, and
-      ;; version. description and version are surrounded by quotes,
-      ;; description is separated by whitespace.
-      (re-search-forward "\\>[[:space:]]+")
-      (setq des-col-beginning (current-column))
-      (goto-char (line-end-position))
-      ;; Unless someone has a quote character in their package version,
-      ;; two quotes back will be the end of the package description.
-      (dotimes (_ 2) (search-backward "\""))
-      (re-search-backward "[[:space:]]*")
-      (setq des-col-end (current-column))
-      (beginning-of-line)
-      (while (not (eobp))
-        (beginning-of-line)
-        (let* ((name (string-trim (buffer-substring
-                                   (point)
-                                   (progn (forward-char (1- des-col-beginning))
-                                          (point)))))
-               (description (string-trim (buffer-substring
-                                          (progn (forward-char 1)
-                                                 (point))
-                                          (progn (forward-char (- des-col-end des-col-beginning))
-                                                 (point)))))
-               (version (buffer-substring
-                         (progn (end-of-line)
-                                (search-backward "\"")
-                                (search-backward "\"")
-                                (forward-char 1)
-                                (point))
-                         (progn (search-forward "\"")
-                                (backward-char 1)
-                                (point)))))
-          (push
-           (list name
-                 `[(,name
-                    help-echo "mouse-2, RET: help on this package"
-                    action ess-rutils-help-on-package)
-                   ,description
-                   ,version])
-           entries)
-          (forward-line)))
-      (pop-to-buffer ess-rutils-buf)
-      (setq ess-local-process-name process)
-      (setq tabulated-list-entries entries)
-      (ess-r-package-menu-mode)
-      (tabulated-list-print))))
-
-(define-obsolete-function-alias 'ess-rutils-loadpkg #'ess-r-package-load "ESS 19.04")
-(defun ess-r-package-load ()
-  "Load package from a library."
-  (interactive)
-  (ess-execute (concat "library('" (tabulated-list-get-id)
-                       "', character.only = TRUE)")
-               'buffer))
-
-(defun ess-rutils-help-on-package (&optional _button)
-  "Display help on the package at point."
-  (interactive)
-  ;; FIXME: Should go to a help buffer
-  (ess-execute (concat "help(" (tabulated-list-get-id) ", package = '"
-                       (tabulated-list-get-id)"')")
-               'buffer))
-
-(define-obsolete-function-alias 'ess-rutils-repos-pkgs #'ess-r-package-list-available-packages "ESS 19.04")
-(defun ess-r-package-list-available-packages ()
-  "List available packages.
-Use the repositories as listed by getOptions(\"repos\") in the
-current R session."
-  (interactive)
-  (ess-r-package--list-packages
-   "{
-       .ess.rutils.ops <- options(width = 10000)
-       print(available.packages(fields=c(\"Title\"))[, c(\"Title\", \"Version\")])
-       options(.ess.rutils.ops); rm(.ess.rutils.ops)
-    }\n"))
-
-(define-obsolete-function-alias 'ess-rutils-mark-install #'ess-r-package-mark-install "ESS 19.04")
-(defun ess-r-package-mark-install ()
-  "Mark the current package for installing."
-  (interactive)
-  (tabulated-list-put-tag "i" t))
-
-(define-obsolete-function-alias 'ess-rutils-unmark #'ess-r-package-unmark "ESS 19.04")
-(defun ess-r-package-unmark ()
-  "Unmark the packages."
-  (interactive)
-  (tabulated-list-put-tag " " t))
-
-(define-obsolete-function-alias 'ess-rutils-execute-marks #'ess-r-package-execute-marks "ESS 19.04")
-(defun ess-r-package-execute-marks ()
-  "Perform all marked actions."
-  (interactive)
-  ;; Install
-  (save-excursion
-    (let ((cmd "install.packages(c(")
-          pkgs)
-      (goto-char (point-min))
-      (while (not (eobp))
-        (when (looking-at-p "i")
-          (setq pkgs (concat "\"" (tabulated-list-get-id) "\", " pkgs))
-          (tabulated-list-put-tag " "))
-        (forward-line))
-      (if pkgs
-          (progn (setq pkgs (substring pkgs 0 (- (length pkgs) 2)))
-                 (setq cmd (concat cmd pkgs "))"))
-                 (ess-execute cmd 'buffer))
-        (message "No packages marked for install")))))
-
-(define-obsolete-function-alias 'ess-rutils-update-pkgs #'ess-r-package-update-packages "ESS 19.04")
-(defun ess-r-package-update-packages (lib repo)
-  "Update packages in library LIB and repo REPO.
-This also uses checkBuilt=TRUE to rebuild installed packages if
-needed."
-  (interactive
-   (list (ess-completing-read "Library to update: " (ess-get-words-from-vector
-                                                     "as.character(.libPaths())\n"))
-         (ess-completing-read "Repo: " (ess-get-words-from-vector
-                                        "as.character(getOption(\"repos\"))\n"))))
-  (ess-execute (format "update.packages(lib.loc='%s', repos='%s', ask=FALSE, checkBuilt=TRUE)" lib repo) 'buffer))
-
-(define-obsolete-function-alias 'ess-rutils-apropos #'ess-display-help-apropos "ESS 19.04")
-
-;; Miscellaneous helper functions
-
-(defun ess-rutils-rm-all ()
-  "Remove all R objects."
-  (interactive)
-  (when (y-or-n-p "Delete all objects? ")
-    (ess-execute "rm(list=ls())" 'buffer)))
-
-(defun ess-rutils-load-workspace (file)
-  "Load workspace FILE into R."
-  (interactive "fFile with workspace to load: ")
-  (ess-execute (concat "load('" file "')") 'buffer))
-(define-obsolete-function-alias 'ess-rutils-load-wkspc #'ess-rutils-load-workspace "ESS 19.04")
-
-(defun ess-rutils-save-workspace (file)
-  "Save FILE workspace as file.RData."
-  (interactive "FSave workspace to file (no extension): ")
-  (ess-execute (concat "save.image('" file ".RData')") 'buffer))
-(define-obsolete-function-alias 'ess-rutils-save-wkspc #'ess-rutils-save-workspace "ESS 19.04")
-
-(defun ess-rutils-quit ()
-  "Kill the ess-rutils buffer and return to the iESS buffer."
-  (interactive)
-  (ess-switch-to-end-of-ESS)
-  (kill-buffer ess-rutils-buf))
-
-(defun ess-rutils-html-docs (&optional remote)
-  "Use `browse-url' to navigate R html documentation.
-Documentation is produced by a modified help.start(), that
-returns the URL produced by GNU R\\='s http server. If called with a
-prefix, the modified help.start() is called with update=TRUE. The
-optional REMOTE argument should be a string with a valid URL for
-the \\='R_HOME\\=' directory on a remote server (defaults to NULL)."
-  (interactive)
-  (let* ((update (if current-prefix-arg "update=TRUE" "update=FALSE"))
-         (remote (if (or (and remote (not (string= "" remote))))
-                     (concat "remote=" remote) "remote=NULL"))
-         (proc ess-local-process-name)
-         (rhtml (format ".ess_help_start(%s, %s)\n" update remote)))
-    (with-temp-buffer
-      (ess-command rhtml (current-buffer) nil nil nil (get-process proc))
-      (let* ((begurl (search-backward "http://"))
-             (endurl (search-forward "index.html"))
-             (url (buffer-substring-no-properties begurl endurl)))
-        (browse-url url)))))
-
-(defun ess-rutils-rsitesearch (string)
-  "Search the R archives for STRING, and show results using `browse-url'.
-If called with a prefix, options are offered (with completion)
-for matches per page, sections of the archives to search,
-displaying results in long or short formats, and sorting by any
-given field. Options should be separated by value of
-`crm-default-separator'."
-  (interactive "sSearch string: ")
-  (let ((site "https://search.r-project.org/cgi-bin/namazu.cgi?query=")
-        (okstring (replace-regexp-in-string " +" "+" string)))
-    (browse-url
-     (if current-prefix-arg
-        (let ((mpp (concat
-                    "&max="
-                    (completing-read
-                     "Matches per page: "
-                     '(("20" 1) ("30" 2) ("40" 3) ("50" 4) ("100" 5)))))
-              (format (concat
-                       "&result="
-                       (completing-read
-                        "Format: " '(("normal" 1) ("short" 2))
-                        nil t "normal" nil "normal")))
-              (sortby (concat
-                       "&sort="
-                       (completing-read
-                        "Sort by: "
-                        '(("score" 1) ("date:late" 2) ("date:early" 3)
-                          ("field:subject:ascending" 4)
-                          ("field:subject:descending" 5)
-                          ("field:from:ascending" 6) ("field:from:descending" 7)
-                          ("field:size:ascending" 8) ("field:size:descending" 9))
-                        nil t "score" nil "score")))
-              (restrict (concat
-                         "&idxname="
-                         (mapconcat
-                          #'identity
-                          (completing-read-multiple
-                           "Limit search to: "
-                           '(("Rhelp02a" 1) ("functions" 2)
-                             ("docs" 3) ("Rhelp01" 4))
-                           nil t "Rhelp02a,functions,docs" nil
-                           "Rhelp02a,functions,docs")
-                          "&idxname="))))
-          (concat site okstring mpp format sortby restrict))
-       (concat site okstring "&max=20&result=normal&sort=score"
-               "&idxname=Rhelp02a&idxname=functions&idxname=docs")))))
-
-(defun ess-rutils-help-search (string)
-  "Search for STRING using help.search()."
-  (interactive "sString to search for? ")
-  (let ((proc ess-local-process-name))
-    (pop-to-buffer "foobar")
-    (ess-command (concat "help.search('" string "')\n")
-                 (current-buffer) nil nil nil (get-process proc))))
-
-(make-obsolete 'ess-rutils-rhtml-fn "overwrite .ess_help_start instead." "ESS 18.10")
-
-
-;; Create functions that can be called for running different versions
-;; of R.
-;; FIXME: Should be set in ess-custom
-(setq ess-rterm-version-paths
-      (ess-flatten-list
-       (delete-dups
-        (if (not ess-directory-containing-R)
-            (if (getenv "ProgramW6432")
-                (let ((P-1 (getenv "ProgramFiles(x86)"))
-                      (P-2 (getenv "ProgramW6432")))
-                  (nconc
-                   ;; Always 32 on 64 bit OS, nil on 32 bit OS
-                   (ess-find-rterm (concat P-1 "/R/") "bin/Rterm.exe")
-                   (ess-find-rterm (concat P-1 "/R/") "bin/i386/Rterm.exe")
-
-                   ;; Keep this both for symmetry and because it can happen:
-                   (ess-find-rterm (concat P-1 "/R/") "bin/x64/Rterm.exe")
-
-                   ;; Always 64 on 64 bit OS, nil on 32 bit OS
-                   (ess-find-rterm (concat P-2 "/R/") "bin/Rterm.exe")
-                   (ess-find-rterm (concat P-2 "/R/") "bin/i386/Rterm.exe")
-                   (ess-find-rterm (concat P-2 "/R/") "bin/x64/Rterm.exe")))
-              (let ((PF (getenv "ProgramFiles")))
-                (nconc
-                 ;; Always 32 on 32 bit OS, depends on 32 or 64 process on 64 bit OS
-                 (ess-find-rterm (concat PF "/R/") "bin/Rterm.exe")
-                 (ess-find-rterm (concat PF "/R/") "bin/i386/Rterm.exe")
-                 (ess-find-rterm (concat PF "/R/") "bin/x64/Rterm.exe"))))
-          (let ((PF ess-directory-containing-R))
-            (nconc
-             (ess-find-rterm (concat PF "/R/") "bin/Rterm.exe")
-             (ess-find-rterm (concat PF "/R/") "bin/i386/Rterm.exe")
-             (ess-find-rterm (concat PF "/R/") "bin/x64/Rterm.exe")))))))
-(ess-r-define-runners)
-
-;;*;; Provide and auto-loads
-
-;;;###autoload
-(add-to-list 'auto-mode-alist '("/Makevars\\(\\.win\\)?\\'" . makefile-mode))
-;;;###autoload
-(add-to-list 'auto-mode-alist '("DESCRIPTION\\'" . conf-colon-mode))
-
-(provide 'ess-r-mode)
-
-;;; ess-r-mode.el ends here
diff --git a/elpa/ess-20251212.937/ess-r-package.el b/elpa/ess-20251212.937/ess-r-package.el
deleted file mode 100644 (file)
index 3513cc4..0000000
+++ /dev/null
@@ -1,598 +0,0 @@
-;;; ess-r-package.el --- Package development mode for R.  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2011-2022 Free Software Foundation, Inc.
-;; Author: Lionel Henry, Vitalie Spinu
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; see appropriate documentation section of ESS user manual
-
-;;; Code:
-(require 'cl-lib)
-(require 'ess-inf)
-
-(eval-when-compile
-  (require 'subr-x)
-  (require 'tramp))
-;; Silence the byte compiler, OK because this file is only loaded by
-;; ess-r-mode and has no autoloads.
-(defvar ess-r-customize-alist)
-(declare-function ess-r-project "ess-r-mode")
-(declare-function inferior-ess-r-force "ess-r-mode")
-(declare-function ess-r-get-evaluation-env "ess-r-mode")
-(declare-function ess-r-set-evaluation-env "ess-r-mode")
-(declare-function tramp-dissect-file-name "tramp" (name &optional nodefault))
-;; This can be drop after dropping support for Emacs 25:
-(declare-function tramp-file-name-localname "tramp" (cl-x))
-
-(defvar ess-r-prompt-for-attached-pkgs-only nil
-  "If nil provide completion for all installed R packages.
-If non-nil, only look for attached packages.")
-
-(define-obsolete-variable-alias 'ess-r-package-auto-set-evaluation-env 'ess-r-package-auto-enable-namespaced-evaluation "18.04")
-(define-obsolete-variable-alias 'ess-r-package-auto-set-evaluation-env 'ess-r-package-auto-enable-namespaced-evaluation "18.04")
-(defcustom ess-r-package-auto-enable-namespaced-evaluation t
-  "If non-nil, evaluation env is set to package env automatically.
-See also `ess-r-set-evaluation-env' and `ess-r-evaluation-env'."
-  :group 'ess-r-package
-  :type 'boolean)
-
-(defvar-local ess-r-package--info-cache nil
-  "Current package info cache.
-See `ess-r-package-info' for its structure.")
-
-(defcustom ess-r-package-library-paths nil
-  "Default path to find user packages.
-Can be either a string specifying a directory or a list of
-directories. This variable is also consulted by
-`xref-find-definitions' in R buffers. See `ess-r-xref-backend'."
-  :group 'ess-r-package-library-paths
-  :type `(choice string (repeat string)))
-
-(defvar ess-r-package-root-file "DESCRIPTION"
-  "Presence of this file indicates the project's root.")
-
-(defvar ess-r-package-dirs
-  '(("R"        . 1)
-    ("r"        . 1)
-    ("tests"    . 1)
-    ("testthat" . 2)
-    ("inst"     . 1)
-    ("include"  . 2)
-    ("src"      . 1))
-  "Alist of directories names and their depth in R package hierarchy.
-This list is used to figure out whether the current file belongs
-to an R package. If the file specified in `ess-r-package-root-file'
-\(DESCRIPTION by default) is found at the presumed root directory
-of the package, the current directory is considered to be part of
-a R package.")
-
-(defvar ess-r-package-source-roots
-  '("R" "src" "tests" "inst/include")
-  "List of sub-directories within R package where source files are located.
-All children of these directories are also considered source
-containing directories.  Use `ess-r-package-source-dirs' to get
-all source dirs recursively within the current package.")
-
-\f
-;;;*;;; Package Detection
-
-(defun ess-r-package-project (&optional dir)
-  "Return the current package as an Emacs project instance.
-A project instance is a cons cell of the project type as symbol
-and the project path as string. If DIR is provided, the package
-is searched from that directory instead of `default-directory'."
-  (let ((pkg-info (ess-r-package-info dir)))
-    (when (car pkg-info)
-      (cons 'ess-r-package (plist-get pkg-info :root)))))
-
-
-;; FIXME: remove when emacs 27 is dropped
-(unless (eval-when-compile
-          (get 'project-roots 'byte-obsolete-info))
-  (cl-defmethod project-roots ((project (head ess-r-package)))
-    "Return the project root for ESS R packages"
-    (list (cdr project))))
-
-(cl-defmethod project-root ((project (head ess-r-package)))
-  "Return the project root for ESS R packages"
-  (cdr project))
-
-(defun ess-r-package-name (&optional dir)
-  "Return the name of the current package as a string."
-  (plist-get (ess-r-package-info dir) :name))
-
-(defun ess-r-package-info (&optional dir)
-  "Get the description of the R project in directory DIR.
-Return an plist with the keys :name and :root. When not in a
-package return \\='(nil). This value is cached buffer-locally for
-efficiency reasons."
-  (if (and (null dir) (car ess-r-package--info-cache))
-      ess-r-package--info-cache
-    (let* ((path (ess-r-package--find-package-path (or dir default-directory)))
-           (name (when path
-                   (ess-r-package--find-package-name path)))
-           (local (if (and path (file-remote-p path))
-                      (tramp-file-name-localname (tramp-dissect-file-name path))
-                    path))
-           (info (if name
-                     (list :name name
-                           :root local)
-                   '(nil))))
-      ;; If DIR was supplied we cannot cache in the current buffer.
-      (if dir
-          info
-        (setq-local ess-r-package--info-cache info)))))
-
-(defun ess-r-package--all-source-dirs (dir)
-  (when (file-directory-p dir)
-    (cl-loop for f in (directory-files-and-attributes dir t "\\`[^.]")
-             if (cadr f)
-             append (cons (car f) (ess-r-package--all-source-dirs (car f))))))
-
-(defun ess-r-package-source-dirs ()
-  "Get paths within current R package with source files.
-Return nil if not in a package. Search sub-directories listed in
-`ess-r-package-source-roots' are searched recursively and
-return all physically present directories."
-  (let ((pkg-root (plist-get (ess-r-package-info) :root)))
-    (when pkg-root
-      (let ((files (directory-files-and-attributes pkg-root t "\\`[^.]")))
-        (cl-loop for f in files
-                 if (and (cadr f)
-                         (cl-some (lambda (el) (string-match-p (concat "/" el "$") (car f)))
-                                  ess-r-package-source-roots))
-                 append (cons (car f)
-                              (ess-r-package--all-source-dirs (car f))))))))
-
-(defun ess-r--select-package-name ()
-  (inferior-ess-r-force)
-  (let ((pkgs (ess-get-words-from-vector
-               (format "print(.packages(%s), max = 1e6)\n"
-                       (if ess-r-prompt-for-attached-pkgs-only "FALSE" "TRUE"))))
-        (current-pkg (ess-r-package-name)))
-    (let ((env (ess-r-get-evaluation-env)))
-      (when env
-        (setq pkgs (append '("*none*") pkgs))
-        (when (equal env current-pkg)
-          (setq current-pkg "*none*"))))
-    (ess-completing-read "Package" pkgs nil nil nil nil current-pkg)))
-
-(defun ess-r-package--find-package-path (&optional dir)
-  "Get the root of R package in directory DIR.
-DIR defaults to the current buffer's file name (if non-nil) or
-`default-directory'. Root is determined by locating
-`ess-r-package-root-file'."
-  (when-let ((path (cond
-                    (dir)
-                    ((buffer-file-name)
-                     (file-name-directory (buffer-file-name)))
-                    (t
-                     default-directory)))
-             (pkg-path
-              (when path
-                (or
-                 ;; First check current directory
-                 (and (file-exists-p (expand-file-name ess-r-package-root-file path))
-                      path)
-                 ;; Check for known directories in current path
-                 (let ((current-dir (file-name-nondirectory (directory-file-name path)))
-                       known-pkg-dir known-path presumptive-path)
-                   (while (and path (not presumptive-path))
-                     (setq current-dir (file-name-nondirectory (directory-file-name path)))
-                     (if (and (setq known-pkg-dir (assoc current-dir ess-r-package-dirs))
-                              (setq known-path (ess--parent-dir path (cdr known-pkg-dir)))
-                              (file-exists-p (expand-file-name ess-r-package-root-file known-path)))
-                         (setq presumptive-path known-path)
-                       (setq path (ess--parent-dir path 1))))
-                   presumptive-path)))))
-    (directory-file-name pkg-path)))
-
-(defun ess-r-package--find-package-name (path)
-  (let ((file (expand-file-name ess-r-package-root-file path))
-        (case-fold-search t))
-    (when (file-exists-p file)
-      (with-temp-buffer
-        (insert-file-contents-literally file)
-        (goto-char (point-min))
-        (when (re-search-forward "package: \\(.*\\)" nil t)
-          (match-string 1))))))
-
-\f
-;;;*;;; UI
-
-(defun ess-r-package-use-dir ()
-  "Set process directory to current package directory."
-  (interactive)
-  (let ((pkg-root (plist-get (ess-r-package-info) :root)))
-    (if pkg-root
-        (ess-set-working-directory (abbreviate-file-name pkg-root))
-      (user-error "Not in a project"))))
-
-\f
-;;;*;;; Evaluation
-
-(defun ess-r-package-enable-namespaced-evaluation ()
-  "Enable namespaced evaluation in current buffer.
-Namespaced evaluation is enabled if
-`ess-r-package-auto-enable-namespaced-evaluation' is non-nil."
-  (when ess-r-package-auto-enable-namespaced-evaluation
-    (let ((root (plist-get (ess-r-package-info) :root)))
-      ;; Check that we are in a file within R/
-      (when (and root
-                 default-directory
-                 (> (length default-directory) (1+ (length root)))
-                 (let ((subpath (substring default-directory
-                                           (1+ (length root))
-                                           (length default-directory))))
-                   (string= (directory-file-name subpath) "R")))
-        (ess-r-set-evaluation-env (ess-r-package-name))))))
-
-(add-hook 'ess-r-mode-hook #'ess-r-package-enable-namespaced-evaluation)
-
-(defun ess-r-package-eval-linewise (command &optional msg p actions)
-  "Send COMMAND to R process.
-COMMAND is a command string with %s placeholder for the
-arguments. MSG is the message displayed in minibuffer with %s
-placeholder for the package name. P is the value of universal
-argument usually received from the upstream command and indicates
-which action in ACTIONS list to perform; if 0 or nil, first
-action, if 1 or (4) second if 2 or (16) third etc. ACTIONS is a
-list of strings (R arguments), or functions which return R
-arguments, or expressions which return R arguments."
-  (inferior-ess-r-force)
-  (let ((pkg-info (ess-r-package-info))
-        (args (ess-r-command--build-args p actions)))
-    (unless (car pkg-info)
-      (user-error "Not in a package"))
-    (ess-project-save-buffers)
-    (message msg (plist-get pkg-info :name))
-    (display-buffer (ess-get-process-buffer))
-    (let ((pkg-path (concat "'" (abbreviate-file-name (plist-get pkg-info :root)) "'")))
-      (ess-eval-linewise (format command (concat pkg-path args))))))
-
-(defun ess-r-command--build-args (ix &optional actions)
-  (let* ((n (cond ((null ix) 0)
-                  ((listp ix) (round (log (car ix) 4)))
-                  ((integerp ix) ix)
-                  (t (error "Invalid index"))))
-         (action (nth n actions))
-         (args (cond ((null action) "")
-                     ((stringp action) action)
-                     ((functionp action) (funcall action))
-                     ((listp action) (eval action t))
-                     (t (error "Invalid action")))))
-    (if (string= "" args)
-        args
-      (concat ", " args))))
-
-\f
-;;;*;;; Devtools Integration
-
-(defun ess-r-devtools-load-package (&optional arg)
-  "Interface for `devtools::load_all()'.
-With prefix ARG ask for extra args."
-  (interactive "P")
-  (ess-r-package-eval-linewise
-   "devtools::load_all(%s)\n" "Loading %s" arg
-   '("" (read-string "Arguments: " "recompile = TRUE"))))
-
-(defun ess-r-devtools-unload-package ()
-  "Interface to `devtools::unload()'."
-  (interactive)
-  (ess-r-package-eval-linewise
-   "devtools::unload(%s)\n" "Unloading %s"))
-
-(defun ess-r-devtools-check-package (&optional arg)
-  "Interface for `devtools::check()'.
-With prefix ARG ask for extra args."
-  (interactive "P")
-  (ess-r-package-eval-linewise
-   "devtools::check(%s)\n" "Checking %s" arg
-   '("" (read-string "Arguments: " "vignettes = FALSE"))))
-
-(defun ess-r-devtools-check-with-winbuilder (&optional arg)
-  "Interface for `devtools::check_win_XYZ()'.
-With prefix argument, as for arguments to `devtools::check_win_XYZ()' function."
-  (interactive "P")
-  (let ((type (completing-read "Release: " '("devel" "release" "oldrelease") nil t)))
-    (ess-r-package-eval-linewise
-     (format "devtools:::check_win_%s(%%s)\n" type)
-     "Checking %s on CRAN's Windows server" arg
-     '("" (read-string "Arguments: ")))))
-
-(defvar ess-r-rhub--history nil)
-(declare-function ess-r-check-install-package "ess-r-mode.el")
-(defun ess-r-rhub-check-package (&optional arg)
-  "Interface for `rhub::check()'.
-With prefix ARG allow for editing of the `rhub::check_for_cran()' arguments."
-  (interactive "P")
-  (inferior-ess-r-force)
-  (ess-r-check-install-package "rhub")
-  (let* ((platforms (cons "RECOMMENDED" (ess-get-words-from-vector "rhub::platforms()$name\n")))
-         (platform (completing-read "Platform: " platforms nil t  nil
-                                    ess-r-rhub--history (car ess-r-rhub--history)))
-         (cmd (if (string= "RECOMMENDED" platform)
-                  "rhub::check_for_cran(%s)\n"
-                (format "rhub::check_for_cran(%%s, platforms = '%s')\n" platform)))
-         (msg (format "Checking %%s on RHUB (%s)" platform))
-         ;; Solaris check is flaky and it seems that solaris check is not run on
-         ;; CRAN itself with --as-cran options https://github.com/r-hub/rhub/issues/339
-         (args (cond ((string-match-p "solaris" platform)
-                      "check_args = c('--no-stop-on-test-error', '--no-vignettes')")
-                     (t "check_args = c('--as-cran', '--no-stop-on-test-error')"))))
-    (ess-r-package-eval-linewise cmd msg arg
-                                 `(,args (read-string "Arguments: " ,(concat args ", valgrind = FALSE"))))))
-
-(defun ess-r-devtools-build (&optional arg)
-  "Interface for `devtools::build()'.
-With prefix ARG, build with `vignettes = FALSE'."
-  (interactive "P")
-  (ess-r-package-eval-linewise
-   "devtools::build(%s)\n" "Building %s" arg
-   '("" "vignettes = FALSE")))
-
-(defun ess-r-devtools-test-package (&optional arg)
-  "Interface for `devtools::test()'.
-With prefix argument ARG, run tests on current file only."
-  (interactive "P")
-  (ess-r-package-eval-linewise
-   "devtools::test(%s)\n" "Testing %s" arg
-   '("" ess-r-devtools--cur-file-filter)))
-
-(defun ess-r-devtools--cur-file-filter ()
-  (let ((file (or (and buffer-file-name
-                       (file-name-nondirectory buffer-file-name))
-                  (error "Buffer not visiting a file"))))
-    (format "filter = \"%s\""
-            (if (string-match "test-\\([[:alnum:]_-]+\\)\\.[rR]" file)
-                (match-string-no-properties 1 file)
-              (file-name-base buffer-file-name)))))
-
-(defvar ess-r-devtools-revdep-check-cmd
-  "local({
-  pkg_path <- %s
-  res <- devtools::revdep_check(pkg_path)
-
-  if (file.exists(file.path(pkg_path, 'revdep'))) {
-    save_path <- file.path(pkg_path, 'revdep')
-  } else {
-    save_path <- file.path(pkg_path, '.metadata', 'revdep')
-  }
-  devtools::revdep_check_save_summary(res, save_path)
-
-  logs_path <- file.path(save_path, 'logs')
-  if (!dir.exists(logs_path)) {
-    dir.create(logs_path)
-  }
-  devtools::revdep_check_save_logs(res, logs_path)
-})
-")
-
-(defun ess-project-save-buffers ()
-  "Offer to save modified files in the current project.
-Respects `ess-save-silently', which see."
-  (let ((cur-proj ess-r-package--info-cache))
-    (dolist (buf (buffer-list))
-      (when-let ((file (buffer-file-name buf))
-                 (buf-proj (buffer-local-value 'ess-r-package--info-cache buf)))
-        (when (equal cur-proj buf-proj)
-          (ess-save-file file))))))
-
-(defun ess-r-devtools-document-package (&optional arg)
-  "Interface for `devtools::document()'.
-With prefix ARG ask for extra arguments."
-  (interactive "P")
-  (ess-r-package-eval-linewise
-   "devtools::document(%s)\n" "Documenting %s" arg
-   '("" (read-string "Arguments: "))))
-
-(defun ess-r-devtools-install-package (&optional arg)
-  "Interface to `devtools::install()'.
-By default the installation is \"quick\" with arguments quick =
-TRUE, upgrade = FALSE, build = FALSE. On prefix ARG
-\\[universal-argument] install with the default
-`devtools::install()' arguments."
-  (interactive "P")
-  (ess-r-package-eval-linewise
-   "devtools::install(%s)\n" "Installing %s" arg
-   '("quick = TRUE, build = FALSE, upgrade = FALSE, keep_source = TRUE"
-     (read-string "Arguments: " "keep_source = TRUE, force = TRUE"))))
-
-(defvar ess-r-devtools--install-github-history nil)
-(defun ess-r-devtools-install-github (&optional arg)
-  "Interface to `devtools::install_github()'.
-Asks for GitHub repository in the form of user/repo. Force
-re-installation when called with a prefix ARG."
-  (interactive "P")
-  (let ((command "devtools::install_github(%s%s)")
-        (repo (format "'%s'"
-                      (read-string "User/Repo: " nil
-                                   'ess-r-devtools--install-github-history
-                                   (car ess-r-devtools--install-github-history))))
-        (args (if arg
-                  (ess-r-command--build-args 0 '((read-string "Arguments: " "force = TRUE")))
-                "")))
-    (inferior-ess-r-force)
-    (unless (derived-mode-p 'inferior-ess-mode)
-      (display-buffer (ess-get-process-buffer)
-                      '(nil . ((inhibit-same-window . t)))))
-    (message "Installing %s from github" repo)
-    (ess-eval-linewise (format command repo args))))
-
-(defun ess-r-devtools-create-package ()
-  "Interface to `devtools::create()'.
-Default location is determined by the first element of
-`ess-r-package-library-paths'."
-  (interactive)
-  (let* ((command "devtools::create(\"%s\")")
-         (default-path (if (stringp ess-r-package-library-paths)
-                           ess-r-package-library-paths
-                         (car ess-r-package-library-paths)))
-         (path (read-directory-name "Path: " default-path)))
-    (ess-eval-linewise (format command path))))
-
-(defun ess-r-devtools-execute-command (&optional arg)
-  "Asks with completion for a devtools command.
-When called with prefix ARG asks for additional arguments."
-  (interactive "P")
-  (inferior-ess-r-force)
-  (let* ((devtools-funs (ess-get-words-from-vector ".ess_devtools_functions()\n"))
-         (fun (completing-read "Function: " devtools-funs))
-         (command (format "devtools::%s(%%s)\n" fun)))
-    (ess-r-package-eval-linewise
-     command (format "Running %s" fun) arg
-     '("" (read-string "Arguments: ")))))
-
-\f
-;;;*;;; Minor Mode
-
-(defcustom ess-r-package-auto-activate t
-  "If non-nil, `ess-r-package-mode' is turned on within R packages.
-If `t' the minor mode auto-activates in R packages. See
-`ess-r-package-exclude-modes' if you wish to inhibit
-`ess-r-package-mode' in specific buffers."
-  :group 'ess-r-package
-  :type 'boolean)
-
-(defcustom ess-r-package-exclude-modes '(fundamental-mode)
-  "A list of modes where `ess-r-package' must not be activated.
-The check is done with `derived-mode-p'."
-  :group 'ess-r-package
-  :type '(repeat symbol)
-  :package-version '(ess "18.10"))
-
-(defcustom ess-r-package-enter-hook nil
-  "Normal hook run on entering `ess-r-package-mode'."
-  :group 'ess-r-package
-  :type 'hook)
-
-(defcustom ess-r-package-exit-hook nil
-  "Normal hook run on exiting `ess-r-package-mode'."
-  :group 'ess-r-package
-  :type 'hook)
-
-(defcustom ess-r-package-mode-line
-  ;; FIXME Emacs 25.1: Use `when-let'
-  '(:eval (let ((pkg-name (ess-r-package-name)))
-            (when pkg-name
-              (format " [pkg:%s]" pkg-name))))
-  "Mode line for ESS developer.
-Set this variable to nil to disable the mode line entirely."
-  :group 'ess-r-package
-  :type 'sexp
-  :risky t)
-
-(defvar ess-r-package-mode-map
-  (let ((ess-r-package-mode-map (make-sparse-keymap)))
-    (define-key ess-r-package-mode-map "\C-c\C-w" 'ess-r-package-dev-map)
-    ess-r-package-mode-map))
-
-(define-minor-mode ess-r-package-mode
-  "Minor mode for enabling R package development features.
-
-\\{ess-r-package-mode-map}"
-  :init-value nil
-  :keymap ess-r-package-mode-map
-  :lighter ess-r-package-mode-line
-  (if ess-r-package-mode
-      (progn
-        ;; Forward relevant R settings for interacting with inferior
-        ;; processes from any mode
-        (let ((vars '(ess-dialect
-                      ess-setwd-command
-                      ess-getwd-command
-                      ess-quit-function
-                      inferior-ess-reload-function)))
-          (mapc (lambda (var)
-                  (set (make-local-variable var)
-                       (eval (cdr (assq var ess-r-customize-alist)) t)))
-                vars))
-        (add-hook 'project-find-functions #'ess-r-project nil 'local)
-        (run-hooks 'ess-r-package-enter-hook))
-    (remove-hook 'project-find-functions #'ess-r-project)
-    (run-hooks 'ess-r-package-exit-hook)))
-
-(add-hook 'after-change-major-mode-hook #'ess-r-package-auto-activate)
-
-\f
-;;;*;;; Activation
-
-(defun ess-r-package-auto-activate ()
-  "Activate developer if current file is part of a package."
-  (when (and ess-r-package-auto-activate
-             (or (buffer-name) default-directory)
-             (not (eq major-mode 'minibuffer-inactive-mode))
-             (or
-              ;; users probably have these in fundamental mode
-              (member (buffer-name) '("DESCRIPTION" "NAMESPACE"))
-              (if ess-r-package-exclude-modes
-                  (not (apply #'derived-mode-p ess-r-package-exclude-modes))
-                t)))
-    (when (car (ess-r-package-info))
-      (ess-r-package-mode 1))))
-
-(defun ess-r-package-re-activate ()
-  "Restart `ess-r-package-mode'.
-First, deactivate package mode if active, and activate if in
-package mode. Use this function if state of the buffer such as
-`default-directory' has changed."
-  (when ess-r-package-mode
-    (ess-r-package-mode -1))
-  (setq ess-r-package--info-cache nil)
-  (ess-r-package-auto-activate))
-
-(defvar-local ess-r--old-default-dir nil)
-(defun ess-r-package-default-directory-tracker (&rest _)
-  (unless (equal ess-r--old-default-dir default-directory)
-    (setq ess-r--old-default-dir default-directory)
-    (ess-r-package-re-activate)))
-
-(defun ess-r-package-activate-directory-tracker ()
-  (add-hook 'after-change-functions #'ess-r-package-default-directory-tracker t t))
-
-(add-hook 'shell-mode-hook #'ess-r-package-activate-directory-tracker t)
-(add-hook 'eshell-mode-hook #'ess-r-package-activate-directory-tracker t)
-;; (require 'shell)
-(advice-add 'shell-resync-dirs :after #'ess-r-package-re-activate)
-
-\f
-;;;*;;; Deprecated variables and functions
-(defun ess-developer (&optional _val)
-  (error "As of ESS 16.04, `ess-developer' is deprecated. Use `ess-r-set-evaluation-env' instead"))
-
-(defalias 'ess-toggle-developer #'ess-developer)
-(define-obsolete-function-alias 'ess-r-devtools-check-package-buildwin #'ess-r-devtools-check-with-winbuilder "18.04")
-(define-obsolete-function-alias 'ess-r-devtools-ask #'ess-r-devtools-execute-command "18.04")
-
-(make-obsolete-variable 'ess-developer "Please use `ess-developer-select-package' and `ess-r-set-evaluation-env' instead." "16.04")
-(make-obsolete-variable 'ess-developer-root-file "Please use `ess-r-package-root-file' instead." "16.04")
-(make-obsolete-variable 'ess-developer-packages "Please use `ess-r-package-set-package' and `ess-r-set-evaluation-env' instead." "16.04")
-(make-obsolete-variable 'ess-developer-load-on-add-commands "Please use `ess-r-package-set-package' and `ess-r-set-evaluation-env' instead." "16.04")
-(make-obsolete-variable 'ess-developer-activate-in-package "Please use `ess-r-package-auto-activate' instead." "16.04")
-(make-obsolete-variable 'ess-developer-enter-hook "Please use `ess-r-package-enter-hook' instead." "16.04")
-(make-obsolete-variable 'ess-developer-exit-hook "Please use `ess-r-package-exit-hook' instead." "16.04")
-
-\f
-(provide 'ess-r-package)
-
-;;; ess-r-package.el ends here
diff --git a/elpa/ess-20251212.937/ess-r-syntax.el b/elpa/ess-20251212.937/ess-r-syntax.el
deleted file mode 100644 (file)
index 8b11f02..0000000
+++ /dev/null
@@ -1,1250 +0,0 @@
-;;; ess-r-syntax.el --- Utils to work with R code  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2015-2022 Free Software Foundation, Inc.
-;; Author: Lionel Henry <lionel.hryNOSPAMgmail.com>
-;; Created: 12 Oct 2015
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; API is not yet stable.
-
-;;; Code:
-
-(require 'ess-utils)
-(require 'regexp-opt)
-
-(eval-when-compile
-  (require 'cl-lib))
-
-\f
-;;*;; Utils
-
-;; The three following wrappers return t if successful, nil on error
-(defun ess-backward-sexp (&optional N)
-  (ess-forward-sexp (- (or N 1))))
-
-(defun ess-forward-sexp (&optional N)
-  (or N (setq N 1))
-  (condition-case nil
-      (prog1 t
-        (goto-char (or (scan-sexps (point) N)
-                       (buffer-end N))))
-    (error nil)))
-
-(defun ess-up-list (&optional N)
-  (condition-case nil
-      (let (forward-sexp-function)
-        (progn (up-list N) t))
-    (error nil)))
-
-(defun ess-backward-up-list (&optional N)
-  (ess-up-list (- (or N 1))))
-
-(defun ess-forward-char (&optional N)
-  (unless (= (point) (point-max))
-    (forward-char (or N 1))
-    t))
-
-(defun ess-backward-char (&optional N)
-  (unless (bobp)
-    (forward-char (- (or N 1)))
-    t))
-
-(defun ess-goto-char (pos)
-  "Go to POS if it is non-nil.
-If POS is nil, return nil.  Otherwise return position itself."
-  (when pos
-    (goto-char pos)))
-
-(defun ess-looking-at (regex &optional newlines)
-  "Like `looking-at' but consumes blanks and comments first."
-  (save-excursion
-    (ess-skip-blanks-forward newlines)
-    (looking-at regex)))
-
-(defmacro ess-save-excursion-when-nil (&rest body)
-  (declare (indent 0)
-           (debug (&rest form)))
-  `(let ((orig-point (point)))
-     (cond ((progn ,@body))
-           (t (prog1 nil
-                (goto-char orig-point))))))
-
-(defmacro ess-while (test &rest body)
-  "Like `while' for TEST but return t when BODY gets executed once."
-  (declare (indent 1)
-           (debug (&rest form)))
-  `(let (executed)
-     (while ,test
-       (setq executed t)
-       ,@body)
-     executed))
-
-(defmacro ess-at-indent-point (&rest body)
-  (declare (indent 0)
-           (debug (&rest form)))
-  `(save-excursion
-     (goto-char indent-point)
-     (back-to-indentation)
-     (progn ,@body)))
-
-(defvar containing-sexp)
-(defmacro ess-at-containing-sexp (&rest body)
-  (declare (indent 0)
-           (debug (&rest form)))
-  '(when (not (bound-and-true-p containing-sexp))
-     (error "Internal error: containing-sexp is nil or undefined"))
-  `(save-excursion
-     (goto-char containing-sexp)
-     (progn ,@body)))
-
-(defmacro ess-any (&rest forms)
-  "Evaluate all arguments and return non-nil if one of the arguments is non-nil.
-This is useful to trigger side-effects. FORMS follows the same
-syntax as arguments to `cond'."
-  (declare (indent 0) (debug nil))
-  `(let ((forms (list ,@(mapcar (lambda (form) `(progn ,@form)) forms))))
-     (cl-some #'identity (mapcar (lambda (e) (eval e t)) forms))))
-
-(defun ess-char-syntax (string)
-  (char-to-string (char-syntax (string-to-char string))))
-
-\f
-;;*;; Tokenisation
-
-(defun ess-token-type (token) (car (nth 0 token)))
-(defun ess-token-value (token) (cdr (nth 0 token)))
-(defun ess-token-start (token) (car (nth 1 token)))
-(defun ess-token-end (token) (cdr (nth 1 token)))
-
-(defun ess-token-refined-type (token)
-  (ess-token-type (ess-refine-token token)))
-
-(defun ess-token-after (&optional token)
-  "Return next TOKEN.
-Cons cell containing the token type and string representation."
-  (save-excursion
-    (when token
-      (goto-char (ess-token-end token)))
-    (ess-jump-token)))
-
-(defun ess-token-before (&optional token)
-  "Return previous TOKEN.
-Cons cell containing the token type and string representation."
-  (save-excursion
-    (when token
-      (goto-char (ess-token-start token)))
-    (ess-climb-token)))
-
-(defun ess-climb-token (&optional type string)
-  (ess-save-excursion-when-nil
-    (ess-escape-comment)
-    (ess-skip-blanks-backward t)
-    (let ((token (or (ess-climb-token--back)
-                     (ess-climb-token--back-and-forth)
-                     (progn (forward-char -1) (ess-token-after)))))
-      (if (or type string)
-          (when (ess-token= token type string)
-            token)
-        token))))
-
-(defun ess-token--cons (type value)
-  (if (eq type 'self)
-      (cons value nil)
-    (cons type value)))
-
-(defun ess-climb-token--back ()
-  (let* ((token-end (point))
-         (token-type (if (bobp)
-                         "buffer-start"
-                       (ess-climb-token--operator)))
-         (token-value (buffer-substring-no-properties (point) token-end)))
-    (unless (null token-type)
-      (list (ess-token--cons token-type token-value)
-            (cons (point) token-end)))))
-
-(defsubst ess-climb-token--char (&rest chars)
-  (ess-while (and chars
-                  (eq (char-before) (car chars))
-                  (ess-backward-char))
-    (setq chars (cdr chars))))
-
-;; Difficult to use regexps here because we want to match greedily
-;; backward
-(defun ess-climb-token--operator ()
-  (when (pcase (char-before)
-          ((or `?+ `?/ `?^ `?~ `?? `?!)
-           (ess-backward-char))
-          (`?=
-           (prog1 (ess-backward-char)
-             (or (ess-climb-token--char ?=)
-                 (ess-climb-token--char ?!)
-                 (ess-climb-token--char ?:)
-                 (ess-climb-token--char ?>)
-                 (ess-climb-token--char ?<))))
-          ((or `?& `?| `?* `?@ `?$)
-           (prog1 (ess-backward-char)
-             (ess-climb-token--char (char-after))))
-          (`?<
-           (ess-backward-char))
-          (`?>
-           (prog1 (ess-backward-char)
-             (or (ess-climb-token--char ?|)
-                 (ess-climb-token--char ?=)
-                 (ess-climb-token--char ?-)
-                 (and (looking-back "->" (- (point) 2))
-                      (goto-char (- (point) 2))))))
-          (`?-
-           (prog1 (ess-backward-char)
-             (ess-climb-token--char ?< ?<)))
-          (`?:
-           (prog1 (ess-backward-char)
-             (ess-climb-token--char ?: ?:))))
-    'self))
-
-(defun ess-climb-token--back-and-forth ()
-  (let ((limit (point)))
-    (when (ess-skip-token-backward)
-      (save-restriction
-        (narrow-to-region (point) limit)
-        (ess-token-after)))))
-
-(defun ess-skip-token-backward ()
-  (ess-save-excursion-when-nil
-    (cond
-     ;; Punctuation
-     ((memq (char-before) '(?, ?\;))
-      (ess-backward-char))
-     ;; Quoting delimiters
-     ((memq (char-syntax (char-before)) '(?\" ?$))
-      (ess-backward-sexp))
-     ;; Syntaxic delimiters
-     ((memq (char-syntax (char-before)) '(?\( ?\)))
-      (prog1 (ess-backward-char)
-        ;; Also skip double brackets
-        (ess-save-excursion-when-nil
-          (when (let ((current-delim (char-after)))
-                  (ess-skip-blanks-backward)
-                  (and (memq (char-before) '(?\[ ?\]))
-                       (eq current-delim (char-before))))
-            (ess-backward-char)))))
-     ;; Identifiers and numbers
-     ((/= (skip-syntax-backward "w_") 0)))))
-
-(defun ess-jump-token (&optional type string)
-  "Consume a token forward.
-Return a cons cell containing the token type and the token string
-content. Return nil when the end of the buffer is reached."
-  (ess-save-excursion-when-nil
-    (ess-skip-blanks-forward t)
-    (let* ((token-start (point))
-           (token-type (or (ess-jump-token--regexps)
-                           (ess-jump-token--literal)
-                           (ess-jump-token--infix-op)
-                           (ess-jump-token--punctuation)
-                           (progn (forward-char) "unknown")))
-           (token-value (buffer-substring-no-properties token-start (point))))
-      (let ((token (list (ess-token--cons token-type token-value)
-                         (cons token-start (point)))))
-        (if (or type string)
-            (when (ess-token= token type string)
-              token)
-          token)))))
-
-(defun ess-jump-token--literal ()
-  (cond
-   ;; Simply assume anything starting with a digit is a number. May be
-   ;; too liberal but takes care of fractional numbers, integers such
-   ;; as 10L, etc. False positives are not valid R code anyway.
-   ((looking-at "[0-9]")
-    (ess-forward-sexp)
-    "number")
-   ((or (looking-at "\\sw\\|\\s_")
-        (eq (char-after) ?`))
-    (ess-forward-sexp)
-    "identifier")
-   ((memq (char-after) '(?\" ?\'))
-    (ess-forward-sexp)
-    "string")))
-
-(defun ess-jump-token--punctuation ()
-  (or (when (= (point) (point-max))
-        "buffer-end")
-      (pcase (char-after)
-        (`?\;
-         (forward-char)
-         'self)
-        (`?,
-         (forward-char)
-         ;; Treat blanks after comma as part of an argument
-         (ess-skip-blanks-forward t)
-         ","))))
-
-(defvar ess-r-prefix-keywords-list
-  '("if" "for" "while" "function"))
-
-(defvar ess-r-keywords-list
-  (append ess-r-prefix-keywords-list '("else")))
-
-(defvar ess-r-delimiters-list
-  '("(" ")" "{" "}" "[" "]" "[[" "]]"))
-
-(defvar ess-r-operators-list
-  '("+" "-" "*" "/" "%%" "**" "^"
-    "&" "&&" "|" "||" "!" "?" "~"
-    "==" "!=" "<" "<=" ">=" ">"
-    "=" "<-" "<<-" "->" "->>"
-    "$" "@" ":" "::" ":::" ":="
-    "|>" "=>"))
-
-(defvar ess-r-keywords-re
-  (concat (regexp-opt ess-r-keywords-list) "\\_>"))
-
-(defvar ess-r-delimiters-re
-  (regexp-opt ess-r-delimiters-list))
-
-(defvar ess-r-operators-re
-  (regexp-opt ess-r-operators-list))
-
-(defun ess-jump-token--regexps ()
-  (when (or (looking-at ess-r-keywords-re)
-            (looking-at ess-r-delimiters-re)
-            (looking-at ess-r-operators-re))
-    (goto-char (match-end 0))
-    'self))
-
-(defun ess-jump-token--infix-op ()
-  (or (when (looking-at ess-r-operators-re)
-        (goto-char (match-end 0))
-        'self)
-      (when (eq (char-after) ?%)
-        (ess-forward-sexp)
-        "%infix%")))
-
-(defun ess-refine-token (token)
-  (let ((refined-type
-         (pcase (ess-token-type token)
-           ;; Parameter assignment
-           (`"="
-            (save-excursion
-              (goto-char (ess-token-start token))
-              (let ((containing-sexp (ess-containing-sexp-position)))
-                (when (and containing-sexp
-                           (ess-at-containing-sexp
-                             (and (ess-token-after= "(")
-                                  (ess-token-before= '("identifier" "string"))))
-                           (save-excursion
-                             (and (ess-climb-token)
-                                  (ess-token-before= '("," "(")))))
-                  "param-assign"))))
-           ;; Quoted identifiers
-           (`"string"
-            (when (or
-                   ;; Quoted parameter names
-                   (ess-refined-token= (ess-token-after) "param-assign")
-                   ;; Quoted call names
-                   (ess-token-after= "("))
-              "identifier"))
-           ((or `"(" `")")
-            (or (save-excursion
-                  (if (ess-token-close-delimiter-p token)
-                      (ess-climb-paired-delims nil token)
-                    (goto-char (ess-token-start token)))
-                  (when (ess-token-keyword-p (ess-token-before))
-                    "prefixed-expr-delimiter"))
-                ;; Fixme: probably too crude. Better handled in parser
-                (when (ess-token= token ")")
-                  (save-excursion
-                    (ess-climb-paired-delims ")" token)
-                    (when (ess-token-before= '("identifier" "string" ")" "]" "]]" "}"))
-                      "argslist-delimiter")))))
-           ((or `"{" `"}")
-            (save-excursion
-              (unless (ess-climb-paired-delims "}" token)
-                (goto-char (ess-token-start token)))
-              (when (ess-refined-token= (ess-token-before) "prefixed-expr-delimiter")
-                "prefixed-expr-delimiter"))))))
-    (if refined-type
-        (list (cons refined-type (ess-token-value token))
-              (nth 1 token))
-      token)))
-
-
-;;;*;;; Token predicates
-
-(defun ess-token= (token &optional type string)
-  (when (and (null type)
-             (null string))
-    (error "No condition supplied"))
-  (let ((type (if (stringp type) (list type) type))
-        (string (if (stringp string) (list string) string)))
-    (and (if type (member (ess-token-type token) type) t)
-         (if string (member (ess-token-value token) string) t))))
-
-(defun ess-refined-token= (token type &optional string)
-  (ess-token= (ess-refine-token token) type string))
-
-(defun ess-token-after= (type &optional string)
-  (ess-token= (ess-token-after) type string))
-
-(defun ess-token-before= (type &optional string)
-  (ess-token= (ess-token-before) type string))
-
-(defun ess-token-open-delimiter-p (token)
-  (string= (ess-char-syntax (ess-token-type token)) "("))
-
-(defun ess-token-close-delimiter-p (token)
-  (string= (ess-char-syntax (ess-token-type token)) ")"))
-
-(defun ess-token-delimiter-p (token)
-  (or (ess-token-open-delimiter-p token)
-      (ess-token-close-delimiter-p token)))
-
-(defun ess-token-operator-p (token &optional strict)
-  (and (or (member (ess-token-type token) ess-r-operators-list)
-           (string= (ess-token-type token) "%infix%"))
-       (or (null strict)
-           (not (ess-refined-token= token "param-assign")))))
-
-(defun ess-token-keyword-p (token)
-  (member (ess-token-type token) ess-r-keywords-list))
-
-
-;;*;; Point predicates
-
-(defun ess-inside-call-p (&optional call)
-  "Return non-nil if point is in a function or indexing call."
-  (let ((containing-sexp (or (bound-and-true-p containing-sexp)
-                             (ess-containing-sexp-position))))
-    (save-excursion
-      (and (prog1 (ess-goto-char containing-sexp)
-             (ess-climb-chained-delims))
-           (save-excursion
-             (forward-char)
-             (ess-up-list))
-           (or (ess-behind-call-opening-p "(")
-               (looking-at "\\["))
-           (ess-inside-call-name-p call)))))
-
-(defun ess-inside-continuation-p ()
-  (unless (or (looking-at ",")
-              (ess-behind-call-opening-p "[[(]"))
-    (or (save-excursion
-          (ess-jump-object)
-          (and (not (ess-ahead-param-assign-p))
-               (ess-behind-operator-p)))
-        (save-excursion
-          (ess-climb-object)
-          (ess-climb-operator)
-          (and (ess-behind-operator-p)
-               (not (ess-ahead-param-assign-p)))))))
-
-(defun ess-inside-call-name-p (&optional call)
-  (save-excursion
-    (ess-climb-call-name call)))
-
-(defun ess-inside-prefixed-block-p (&optional call)
-  "Return non-nil if point is in a prefixed block.
-Prefixed blocks refer to the blocks following function
-declarations, control flow statements, etc.
-
-If CALL is not nil, check if the prefix corresponds to CALL. If
-nil, return the prefix."
-  (save-excursion
-    (ess-escape-prefixed-block call)))
-
-\f
-;;*;; Syntactic Travellers and Predicates
-
-;;;*;;; Blanks, Characters, Comments and Delimiters
-
-(defun ess-skip-blanks-backward (&optional newlines)
-  "Skip blanks and newlines backward, taking end-of-line comments into account."
-  (ess-any ((ess-skip-blanks-backward-1))
-           ((when newlines
-              (ess-while (and (not (bobp))
-                              (= (point) (line-beginning-position)))
-                (forward-line -1)
-                (goto-char (ess-code-end-position))
-                (ess-skip-blanks-backward-1))))))
-
-(defun ess-skip-blanks-backward-1 ()
-  (and (not (bobp))
-       (/= 0 (skip-syntax-backward " "))))
-
-(defun ess-skip-blanks-forward (&optional newlines)
-  "Skip blanks and newlines forward, taking end-of-line comments into account."
-  (ess-any ((/= 0 (skip-syntax-forward " ")))
-           ((ess-while (and newlines
-                            (= (point) (ess-code-end-position))
-                            (when (ess-save-excursion-when-nil
-                                    ;; Handles corner cases such as point being on last line
-                                    (let ((orig-point (point)))
-                                      (forward-line)
-                                      (back-to-indentation)
-                                      (> (point) orig-point)))
-                              (skip-chars-forward " \t")
-                              t))))))
-
-(defun ess-jump-char (char)
-  (ess-save-excursion-when-nil
-    (ess-skip-blanks-forward t)
-    (when (looking-at char)
-      (goto-char (match-end 0)))))
-
-(defun ess-escape-comment ()
-  (when (ess-inside-comment-p)
-    (prog1 (comment-beginning)
-     (skip-chars-backward "#+[ \t]*"))))
-
-(defun ess-ahead-closing-p ()
-  (memq (char-before) '(?\] ?\} ?\))))
-
-(defun ess-ahead-boundary-p ()
-  (looking-back "[][ \t\n(){},]" (1- (point))))
-
-(defun ess-escape-string ()
-  (and (nth 3 (syntax-ppss))
-       (ess-goto-char (nth 8 (syntax-ppss)))))
-
-(defun ess-climb-paired-delims (&optional type token)
-  (ess-save-excursion-when-nil
-    (let ((token (or token (ess-token-before))))
-      (goto-char (ess-token-end token))
-      (when (if type
-                (ess-token= token type)
-              (ess-token-delimiter-p token))
-        (and (ess-backward-sexp)
-             (ess-token-after))))))
-
-(defun ess-jump-paired-delims (&optional type token)
-  (ess-save-excursion-when-nil
-    (let ((token (or token (ess-token-after))))
-      (goto-char (ess-token-start token))
-      (when (if type
-                (ess-token= token type)
-              (ess-token-delimiter-p token))
-        (and (ess-forward-sexp)
-             (ess-token-before))))))
-
-\f
-;;;*;;; Blocks
-
-(defun ess-block-opening-p ()
-  (save-excursion
-    (cond
-     ((looking-at "{"))
-     ;; Opening parenthesis not attached to a function opens up a
-     ;; block too. Only pick up those that are last on their line
-     ((ess-behind-block-paren-p)))))
-
-(defun ess-block-closing-p ()
-  (save-excursion
-    (cond
-     ((looking-at "}"))
-     ((looking-at ")")
-      (forward-char)
-      (backward-sexp)
-      (not (looking-back
-            (concat ess-r-name-pattern "[[:blank:]]*")
-            (line-beginning-position)))))))
-
-(defun ess-block-p ()
-  (or (save-excursion
-        (when containing-sexp
-          (goto-char containing-sexp)
-          (ess-block-opening-p)))
-      (ess-unbraced-block-p)))
-
-;; Parenthesised expressions
-(defun ess-behind-block-paren-p ()
-  (and (looking-at "(")
-       (not (ess-ahead-attached-name-p))))
-
-(defun ess-climb-block (&optional ignore-ifelse)
-  (ess-save-excursion-when-nil
-    (cond
-     ((and (not ignore-ifelse)
-           (ess-climb-if-else 'to-start)))
-     ((and (eq (char-before) ?\})
-           (prog2
-               (forward-char -1)
-               (ess-up-list -1)
-             (ess-climb-block-prefix)))))))
-
-(defvar ess-prefixed-block-patterns
-  (mapcar (lambda (fun) (concat fun "[ \t\n]*("))
-          '("function" "if" "for" "while")))
-
-(defun ess-behind-prefixed-block-p (&optional call)
-  (if call
-      (looking-at (concat call "[ \t]*("))
-    (cl-some #'looking-at ess-prefixed-block-patterns)))
-
-(defun ess-unbraced-block-p (&optional ignore-ifelse)
-  "This indicates whether point is in front of an unbraced
-prefixed block following a control flow statement. Returns
-position of the control flow function (if, for, while, etc)."
-  (save-excursion
-    (and (ess-backward-sexp)
-         (or (and (looking-at "else\\b")
-                  (not ignore-ifelse))
-             (and (looking-at "(")
-                  (ess-backward-sexp)
-                  (cl-some #'looking-at ess-prefixed-block-patterns)
-                  (if ignore-ifelse
-                      (not (looking-at "if\\b"))
-                    t)))
-         (point))))
-
-(defun ess-climb-block-prefix (&optional call ignore-ifelse)
-  "Climb the prefix of a prefixed block.
-Prefixed blocks refer to the blocks following function
-declarations, control flow statements, etc.
-
-Should be called either in front of a naked block or in front
-of the curly brackets of a braced block.
-
-If CALL not nil, check if the prefix corresponds to CALL. If nil,
-return the prefix."
-  (ess-save-excursion-when-nil
-    (or (and (not ignore-ifelse)
-             (prog1 (and (ess-climb-if-else-call)
-                         (or (null call)
-                             (looking-at call)))
-               (when (ess-token-after= "else")
-                 (ess-climb-token "}"))))
-        (let ((pos (ess-unbraced-block-p ignore-ifelse)))
-          (and (ess-goto-char pos)
-               (if call
-                   (looking-at call)
-                 (cond ((looking-at "function")
-                        "function")
-                       ((looking-at "for")
-                        "for")
-                       ((looking-at "if")
-                        "if")
-                       ((looking-at "else")
-                        "else"))))))))
-
-(defun ess-escape-prefixed-block (&optional call)
-  "Climb outside of a prefixed block."
-  (let ((containing-sexp (or (bound-and-true-p containing-sexp)
-                             (ess-containing-sexp-position))))
-    (or (ess-save-excursion-when-nil
-          (and (ess-goto-char containing-sexp)
-               (looking-at "{")
-               (ess-climb-block-prefix call)))
-        (ess-escape-unbraced-block call))))
-
-(defun ess-escape-unbraced-block (&optional call)
-  (ess-save-excursion-when-nil
-    (while (and (not (ess-unbraced-block-p))
-                (or (ess-escape-continuations)
-                    (ess-escape-call))))
-    (ess-climb-block-prefix call)))
-
-(defun ess-jump-block ()
-  (cond
-   ;; if-else blocks
-   ((ess-jump-if-else))
-   ;; Prefixed blocks such as `function() {}'
-   ((ess-behind-prefixed-block-p)
-    (ess-jump-prefixed-block))
-   ;; Naked blocks
-   ((and (or (looking-at "{")
-             (ess-behind-block-paren-p))
-         (ess-forward-sexp)))))
-
-(defun ess-jump-prefixed-block (&optional call)
-  (ess-save-excursion-when-nil
-    (when (ess-behind-prefixed-block-p call)
-      (ess-forward-sexp 2)
-      (ess-skip-blanks-forward t)
-      (if (looking-at "{")
-          (ess-forward-sexp)
-        (prog1 (ess-jump-expression)
-          (ess-jump-continuations))))))
-
-\f
-;;;*;;; Calls
-
-(defun ess-call-closing-p ()
-  (save-excursion
-    (when (cond ((looking-at ")")
-                 (ess-up-list -1))
-                ((looking-at "]")
-                 (when (ess-up-list -1)
-                   (prog1 t (ess-climb-chained-delims)))))
-      (ess-ahead-attached-name-p))))
-
-(defun ess-behind-call-opening-p (pattern)
-  (and (looking-at pattern)
-       (ess-ahead-attached-name-p)))
-
-;; Should be called just before the opening brace
-(defun ess-ahead-attached-name-p ()
-  (save-excursion
-    (ess-climb-object)))
-
-(defun ess-ahead-param-assign-p ()
-  "Return non-nil if looking at a function argument.
-To be called just before the `=' sign."
-  (ess-refined-token= (ess-token-before) "param-assign"))
-
-(defun ess-behind-arg-p ()
-  (save-excursion
-    (ess-jump-arg)))
-
-(defun ess-behind-parameter-p ()
-  (save-excursion
-    (ess-jump-parameter)))
-
-(defun ess-jump-parameter ()
-  (ess-save-excursion-when-nil
-    (and (ess-jump-name)
-         (when (looking-at "[ \t]*=\\([^=]\\)")
-           (goto-char (match-beginning 1))
-           (ess-skip-blanks-forward)
-           t))))
-
-(defun ess-jump-arg ()
-  (ess-save-excursion-when-nil
-    (ess-skip-blanks-forward t)
-    (ess-any ((ess-jump-parameter))
-             ((ess-jump-expression))
-             ((ess-jump-continuations)))))
-
-(defun ess-arg-bounds ()
-  "Should be called in front of the argument."
-  (save-excursion
-    (let ((beg (point)))
-      (and (ess-jump-arg)
-           (list beg (point))))))
-
-(defun ess-climb-call (&optional call)
-  "Climb functions (e.g. ggplot) and parenthesised expressions."
-  (or (ess-while (ess-save-excursion-when-nil
-                   (ess-climb-name)
-                   (and (ess-climb-chained-delims ?\])
-                        ;; (ess-climb-expression)
-                        (if (eq (char-before) ?\))
-                            (ess-climb-call)
-                          (ess-climb-name))
-                        )))
-      (ess-save-excursion-when-nil
-        (when (and (memq (char-before) '(?\] ?\) ?\}))
-                   (ess-backward-sexp))
-          (if call
-              (and (ess-climb-name)
-                   (looking-at call)))
-          (prog1 t
-            (ess-climb-name))))))
-
-(defun ess-climb-call-name (&optional call)
-  (ess-save-excursion-when-nil
-    (ess-jump-name)
-    (ess-skip-blanks-forward)
-    (and (ess-behind-call-opening-p "[[(]")
-         (ess-climb-name)
-         (or (null call)
-             (looking-at call)))))
-
-(defun ess-step-to-first-arg ()
-  (let ((containing-sexp (ess-containing-sexp-position)))
-    (cond ((ess-inside-call-p)
-           (goto-char containing-sexp)
-           (forward-char)
-           t)
-          ((ess-inside-call-name-p)
-           (ess-jump-name)
-           (ess-skip-blanks-forward)
-           (forward-char)
-           t))))
-
-(defun ess-jump-to-next-arg ()
-  (and (ess-jump-arg)
-       (prog1 (ess-jump-char ",")
-         (ess-skip-blanks-forward t))))
-
-(defun ess-jump-call ()
-  (ess-save-excursion-when-nil
-    (or (and (ess-jump-object)
-             (cond ((eq (char-before) ?\)))
-                   ((looking-at "\\[")
-                    (ess-jump-chained-brackets))
-                   ((looking-at "(")
-                    (ess-forward-sexp))))
-        (and (looking-at "[ \t]*(")
-             (ess-forward-sexp)))))
-
-(defun ess-behind-call-p ()
-  (save-excursion
-    (ess-jump-object)
-    (ess-skip-blanks-forward)
-    (looking-at "[[(]")))
-
-(defun ess-climb-chained-delims (&optional delim)
-  "Should be called with point between delims, e.g. `]|['."
-  (setq delim (if delim
-                  (list delim)
-                '(?\] ?\))))
-  (ess-while (ess-save-excursion-when-nil
-               (when (memq (char-before) delim)
-                 (ess-backward-sexp)))))
-
-(defun ess-jump-chained-brackets ()
-  (ess-while (ess-save-excursion-when-nil
-               (when (eq (char-after) ?\[)
-                 (ess-forward-sexp)))))
-
-(defun ess-escape-call (&optional call)
-  (let ((containing-sexp (ess-containing-sexp-position)))
-    (if (ess-inside-call-p)
-        (ess-save-excursion-when-nil
-          (goto-char containing-sexp)
-          (ess-climb-chained-delims)
-          (and (ess-climb-name)
-               (or (null call)
-                   (looking-at call))))
-      ;; At top level or inside a block, check if point is on the
-      ;; function name.
-      (ess-save-excursion-when-nil
-        (let ((orig-pos (point)))
-          (and (ess-jump-name)
-               (looking-at "[[(]")
-               (ess-climb-name)
-               (or (null call)
-                   (looking-at call))
-               (/= (point) orig-pos)))))))
-
-(defun ess-escape-calls ()
-  (ess-while (ess-escape-call)))
-
-(defun ess-jump-inside-call ()
-  (ess-save-excursion-when-nil
-    (when (ess-jump-name)
-      (ess-skip-blanks-forward)
-      (when (looking-at "(")
-        (forward-char)
-        t))))
-
-(defun ess-args-bounds (&optional marker)
-  (let ((containing-sexp (ess-containing-sexp-position)))
-    (when (ess-inside-call-p)
-      (save-excursion
-        (let ((beg (1+ containing-sexp))
-              (call-beg (ess-at-containing-sexp
-                          (ess-climb-name)
-                          (point))))
-          ;; (ess-up-list) can't find its way when point is on a
-          ;; backquoted name, so start from `beg'.
-          (and (goto-char beg)
-               (ess-up-list)
-               (prog1 t
-                 (forward-char -1))
-               (let ((end (if marker
-                              (point-marker)
-                            (point))))
-                 (list beg end call-beg))))))))
-
-(defun ess-args-alist ()
-  "Return all arguments as an alist with cars set to argument
-names and cdrs set to the expressions given as argument. Both
-cars and cdrs are returned as strings."
-  (save-excursion
-    (when (ess-step-to-first-arg)
-      (let (args current-arg)
-        (while (and (setq current-arg (ess-cons-arg))
-                    (setq args (nconc args (list current-arg)))
-                    (ess-jump-to-next-arg)))
-        args))))
-
-(defun ess-cons-arg ()
-  "Return a cons cell of the current argument with car set to the
-parameter name (nil if not specified) and cdr set to the argument
-expression."
-  (save-excursion
-    (ess-skip-blanks-forward t)
-    (let ((param (when (ess-behind-parameter-p)
-                   (buffer-substring-no-properties
-                    (point)
-                    (prog2
-                        (ess-jump-name)
-                        (point)
-                      (ess-jump-char "=")
-                      (ess-skip-blanks-forward)))))
-          (arg (buffer-substring-no-properties
-                (point)
-                (progn
-                  (ess-jump-arg)
-                  (point)))))
-      (cons param arg))))
-
-\f
-;;;*;;; Statements
-
-(defun ess-behind-operator-p (&optional strict)
-  (ess-token-operator-p (ess-token-after) strict))
-
-(defun ess-ahead-operator-p (&optional strict)
-  (ess-token-operator-p (ess-token-before) strict))
-
-(defun ess-climb-lhs (&optional no-fun-arg climb-line)
-  (ess-save-excursion-when-nil
-    (let ((start-line (line-number-at-pos)))
-      (ess-climb-operator)
-      (when (and (or climb-line (equal (line-number-at-pos) start-line))
-                 (ess-behind-definition-op-p no-fun-arg))
-        (prog1 t
-          (ess-climb-expression))))))
-
-(defun ess-jump-lhs ()
-  (ess-save-excursion-when-nil
-    (and (ess-jump-name)
-         (ess-behind-definition-op-p)
-         (ess-jump-operator))))
-
-(defun ess-climb-operator ()
-  (when (ess-token-operator-p (ess-token-before))
-    (prog1 (ess-climb-token)
-      (ess-skip-blanks-backward))))
-
-;; Currently doesn't check that the operator is not binary
-(defun ess-climb-unary-operator ()
-  (ess-save-excursion-when-nil
-    (let ((token (ess-climb-token)))
-      (member (ess-token-type token) '("+" "-" "!" "?" "~")))))
-
-;; Currently returns t if we climbed lines, nil otherwise.
-(defun ess-climb-continuations (&optional cascade ignore-ifelse)
-  (let* ((start-line (line-number-at-pos))
-         (state (list :start-line start-line
-                      :last-line start-line
-                      :moved 0
-                      :last-pos (point)
-                      :prev-point nil
-                      :def-op nil
-                      :expr nil)))
-    (when (ess-while (and (<= (plist-get state :moved) 1)
-                          (or (ess-save-excursion-when-nil
-                               (and (ess-climb-operator)
-                                    (ess-climb-continuations--update-state state cascade 'op)
-                                    (ess-climb-expression ignore-ifelse)))
-                              (ess-climb-unary-operator))
-                          (/= (plist-get state :last-pos) (point)))
-                     (ess-climb-continuations--update-state state cascade nil)
-                     (plist-put state :last-pos (point)))
-      (when (and (plist-get state :prev-point)
-                 (or (= (plist-get state :moved) 3)
-                     (not (plist-get state :expr))))
-        (goto-char (plist-get state :prev-point)))
-      (if (plist-get state :def-op)
-          'def-op
-        (< (line-number-at-pos) (plist-get state :start-line))))))
-
-(defun ess-climb-continuations--update-state (state cascade &optional op)
-  ;; Climbing multi-line expressions should not count as moving up
-  (when op
-    (plist-put state :expr (ess-ahead-closing-p)))
-  (let ((cur-line (line-number-at-pos)))
-    (when (and (plist-get state :last-line)
-               (< cur-line (plist-get state :last-line))
-               (or cascade (not (plist-get state :expr))))
-      (plist-put state :moved (1+ (plist-get state :moved)))
-      (plist-put state :last-line cur-line)))
-  ;; Don't update counter after climbing operator or climbing too high
-  (when (and (not op)
-             (<= (plist-get state :moved) 1))
-    (plist-put state :prev-point (point)))
-  (when (and (ess-behind-definition-op-p)
-             (<= (plist-get state :moved) 1))
-    (plist-put state :def-op t))
-  t)
-
-(defun ess-jump-operator ()
-  (when (ess-behind-operator-p)
-    (ess-jump-token)
-    (ess-skip-blanks-forward t)
-    t))
-
-(defun ess-jump-continuation ()
-  (and (ess-jump-operator)
-       (ess-jump-expression)))
-
-(defun ess-jump-continuations ()
-  (let (last-pos)
-    (when (ess-while (and (or (null last-pos)
-                              (/= (point) last-pos))
-                          (setq last-pos (point))
-                          (ess-jump-continuation)))
-      ;; In calls, operators can start on newlines
-      (let ((start-line (line-number-at-pos)))
-        (when (ess-save-excursion-when-nil
-                (and (ess-inside-call-p)
-                     (ess-skip-blanks-forward t)
-                     (/= (line-number-at-pos) start-line)
-                     (ess-behind-operator-p)))
-          (ess-jump-continuations)))
-      t)))
-
-(defun ess-ahead-continuation-p (&optional or-parameter)
-  (or (ess-token-operator-p (ess-token-before) (not or-parameter))
-      (save-excursion
-        (ess-climb-block-prefix))
-      (ess-token-after= "else")
-      (save-excursion
-        (ess-climb-if-else-call))))
-
-(defun ess-token-definition-op-p (token strict)
-  (and (ess-token= token '("<-" "<<-" ":=" "~" "="))
-       (if strict
-           (not (ess-refined-token= token "param-assign"))
-         t)))
-
-(defun ess-behind-definition-op-p (&optional strict)
-  (ess-token-definition-op-p (ess-token-after) strict))
-
-(defun ess-ahead-definition-op-p (&optional strict)
-  (ess-token-definition-op-p (ess-token-before) strict))
-
-(defun ess-behind-assignment-op-p ()
-  (let ((token (ess-token-after)))
-    (and (ess-token= token '("<-" "="))
-         (not (ess-refined-token= token "param-assign")))))
-
-(defun ess-escape-continuations ()
-  (ess-any ((unless (ess-ahead-boundary-p)
-              (ess-climb-expression)))
-           ((ess-while (ess-climb-continuations)))))
-
-(defun ess-continuations-bounds (&optional marker)
-  (save-excursion
-    (let ((beg (progn
-                 (ess-escape-continuations)
-                 (point))))
-      (when beg
-        (ess-jump-expression)
-        (ess-jump-continuations)
-        (let ((end (if marker
-                       (point-marker)
-                     (point))))
-          (list beg end))))))
-
-(defun ess-climb-to-top-level ()
-  (while (ess-goto-char (ess-containing-sexp-position)))
-  (ess-escape-continuations))
-
-\f
-;;;*;;; Statements: Control Flow
-
-(defun ess-climb-if-else-call (&optional multi-line)
-  "Climb if, else, and if else calls."
-  (ess-save-excursion-when-nil
-    (cond ((ess-climb-paired-delims ")")
-           (when (ess-climb-token "if")
-             ;; Check for `else if'
-             (prog1 t
-               (ess-save-excursion-when-nil
-                 (let ((orig-line (line-number-at-pos)))
-                   (and (ess-climb-token "else")
-                        (or multi-line
-                            (eq orig-line (line-number-at-pos)))))))))
-          ((ess-climb-token "else")))))
-
-
-(defun ess-climb-if-else-body (&optional from-else)
-  (cond
-   ;; Climb braced body
-   ((ess-save-excursion-when-nil
-      (and (when (progn (ess-skip-blanks-backward t)
-                        (eq (char-before) ?\}))
-             (prog1 t (forward-char -1)))
-           (ess-up-list -1))))
-   ;; Climb unbraced body
-   ((when from-else
-      (ess-save-excursion-when-nil
-        (ess-skip-blanks-backward t)
-        (prog1 (ess-climb-expression 'ignore-ifelse)
-          (or (ess-climb-continuations nil 'ignore-ifelse)
-              (ess-climb-block-prefix nil 'ignore-ifelse))))))))
-
-(defun ess-climb-if-else (&optional to-start)
-  "Climb horizontal as well as vertical if-else chains, with or
-without curly braces."
-  ;; Don't climb if we're atop the current chain of if-else
-  (unless (ess-token-after= "if")
-    (ess-save-excursion-when-nil
-      (let ((from-else (ess-token-after= "else")))
-        (when (and (ess-climb-if-else-body from-else)
-                   (ess-climb-if-else-call to-start))
-          ;; If we start from a final else and climb to another else, we
-          ;; are in the wrong chain of if-else. In that case,
-          ;; climb-recurse to the top of the current chain and climb
-          ;; again to step in the outer chain.
-          (when (save-excursion (and from-else
-                                     (ess-jump-token "else")
-                                     (not (ess-jump-token "if"))))
-            (ess-climb-if-else 'to-start)
-            (ess-climb-continuations)
-            (ess-climb-block-prefix nil 'ignore-ifelse)
-            (ess-climb-if-else-call nil))
-          (ess-maybe-climb-broken-else)
-          (when to-start
-            (ess-climb-if-else to-start))
-          t)))))
-
-;; Broken else: if \n else
-(defun ess-maybe-climb-broken-else (&optional same-line)
-  (ess-save-excursion-when-nil
-    ;; Don't record current line if not needed (expensive operation)
-    (let ((cur-line (when same-line (line-number-at-pos))))
-      (and (ess-climb-token "else")
-           (if same-line
-               (= cur-line (line-number-at-pos))
-             t)))))
-
-(defun ess-skip-curly-backward ()
-  (re-search-backward "}[ \t]*" (line-beginning-position) t))
-
-(defun ess-jump-if-else ()
-  (let (from)
-    (ess-while (ess-save-excursion-when-nil
-                 (ess-skip-blanks-forward t)
-                 (cond
-                  ((and (not (eq from 'if))
-                        (ess-jump-if)
-                        (setq from 'if)))
-                  ((looking-at "else")
-                   (ess-forward-sexp)
-                   (or (ess-jump-if)
-                       (progn
-                         (ess-skip-blanks-forward t)
-                         (ess-jump-expression)))
-                   (setq from 'else))
-                  (t
-                   nil))))))
-
-(defun ess-jump-if ()
-  (ess-save-excursion-when-nil
-    (ess-skip-blanks-forward t)
-    (and (looking-at "if[ \t\n]*(")
-         (ess-forward-sexp 2)
-         (progn
-           (ess-skip-blanks-forward t)
-           (ess-jump-expression)))))
-
-\f
-;;;*;;; Function Declarations
-
-(defun ess-behind-defun-p ()
-  (or (looking-at "function[ \t]*(")
-      (ess-behind-enclosed-defun-p)))
-
-(defun ess-behind-enclosed-defun-p ()
-  (save-excursion
-    (and (ess-behind-call-p)
-         (ess-jump-inside-call)
-         (cl-some (lambda (arg)
-                    (string-match "^function\\b"
-                                  (cdr arg)))
-                  (ess-args-alist)))))
-
-\f
-;;;*;;; Names / Objects / Expressions
-
-;; Should  climb any names, including backquoted ones or those
-;; containing `@' or `$'. Difficult to achieve with regexps, but
-;; skipping chars is faster anyway.
-(defun ess-climb-object ()
-  (ess-save-excursion-when-nil
-    (let (climbed)
-      (ess-skip-blanks-backward)
-      ;; Backquoted names can contain any character
-      (if (and (memq (char-before) '(?` ?\" ?\'))
-               (ess-backward-sexp))
-          (setq climbed t)
-        (while (cl-some (apply-partially '/= 0)
-                        `(,(skip-syntax-backward "w_")
-                          ,(skip-chars-backward "\"'")))
-          (setq climbed t)))
-      ;; Recurse if we find an indexing char
-      (let ((tok (ess-token-before)))
-        (when (member (ess-token-type tok) '("$" "@" "::" ":::"))
-          (goto-char (ess-token-start tok))
-          (ess-climb-object)))
-      climbed)))
-
-;; Todo: split name and object climbing
-(defun ess-climb-name ()
-  (ess-climb-object))
-
-;; This jumps both object names and atomic objects like strings or
-;; numbers.
-(defun ess-jump-object ()
-  (cond
-   ;; Jump over object names
-   ((ess-jump-name))
-   ;; Jump over strings))
-   ((ess-save-excursion-when-nil
-      (skip-chars-forward " \t")
-      (memq (char-after) '(?\" ?\')))
-    (ess-forward-sexp))))
-
-(defun ess-jump-name ()
-  (ess-save-excursion-when-nil
-    (let (climbed)
-      (skip-chars-forward " \t")
-      ;; Jump over backquoted names
-      (cond ((and (eq (char-after) ?`)
-                  (looking-back ess-r-symbol-pattern
-                                (1- (point))))
-             (forward-char)
-             (setq climbed t))
-            ((eq (char-after) ?`)
-             (forward-char)
-             (when (ess-while (not (memq (char-after) '(?` ?\C-J)))
-                     (forward-char))
-               (setq climbed t)
-               (forward-char)))
-            ;; Jump over regular names
-            ((when (/= 0 (skip-syntax-forward "w_"))
-               ;; Maybe point was inside backticks
-               (when (eq (char-after) ?`)
-                 (forward-char))
-               (setq climbed t))))
-      climbed)))
-
-(defun ess-climb-expression (&optional ignore-ifelse)
-  (ess-save-excursion-when-nil
-    (or (ess-climb-block ignore-ifelse)
-        (ess-climb-call)
-        (ess-climb-object))))
-
-(defun ess-jump-expression ()
-  (or (ess-jump-block)
-      (ess-jump-call)
-      (ess-jump-object)))
-
-(provide 'ess-r-syntax)
-
-;;; ess-r-syntax.el ends here
diff --git a/elpa/ess-20251212.937/ess-r-xref.el b/elpa/ess-20251212.937/ess-r-xref.el
deleted file mode 100644 (file)
index 474cf90..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-;;; ess-r-xref.el --- An xref backend for R. -*- lexical-binding: t -*-
-
-;; Copyright (C) 2018-2020 Free Software Foundation, Inc.
-;; Author: Aaron Jacobs
-;; Created: 21 January 2018
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; This file contains an xref backend for `ess-r-mode'.
-
-;;; Code:
-
-(require 'xref)
-(require 'ess-inf)
-(require 'ess-r-package)
-(require 'ess-tracebug)
-(eval-when-compile
-  (require 'subr-x))
-
-;; Silence the byte compiler. OK because this file is only loaded by ess-r-mode.
-(declare-function inferior-ess-r-force "ess-r-mode")
-
-
-(defvar ess-r-xref-pkg-sources nil
-  "Alist of R package->directory associations.
-Each element is a cons cell (PACKAGE . DIRECTORY). This variable
-is used as a cache of package->directory associations, but could
-be used by the users for a more refined control of package
-locations than `ess-r-package-library-paths'.")
-
-(defun ess-r-xref-backend ()
-  "An `xref-backend-functions' implementation for `ess-r-mode'.
-R's xref backend searches for `ess-r-package-library-paths' when
-srcrefs point to temporary locations."
-  'ess-r)
-
-(cl-defmethod xref-backend-identifier-at-point ((_backend (eql ess-r)))
-  (when-let ((sym (ess-symbol-at-point)))
-    (symbol-name sym)))
-
-(cl-defmethod xref-backend-definitions ((_backend (eql ess-r)) symbol)
-  (when-let ((xref (ess-r-xref--xref symbol)))
-    (list xref)))
-
-(cl-defmethod xref-backend-apropos ((_backend (eql ess-r)))
-  ;; Not yet supported.
-  nil)
-
-(cl-defmethod xref-backend-identifier-completion-table ((_backend (eql ess-r)))
-  (inferior-ess-r-force)
-  (ess-get-words-from-vector--foreground ".ess_all_functions()\n"))
-
-(defun ess-r-xref--srcref (symbol)
-  (inferior-ess-r-force)
-  ;; Look for `symbol' inside the package namespace
-  (let* ((pkg (ess-r-package-name))
-         (pkg (if pkg
-                  (concat "\"" pkg "\"")
-                "NULL")))
-    (with-current-buffer (ess-command (format ".ess_srcref(\"%s\", %s)\n" symbol pkg))
-      (goto-char (point-min))
-      (if (re-search-forward "Error" nil t)
-          (progn (message "R srcref lookup failed:\n%s" (buffer-string))
-                 (sit-for 1)
-                 nil)
-        (when (re-search-forward "(" nil 'noerror)
-          (goto-char (match-beginning 0))
-          (read (current-buffer)))))))
-
-(defun ess-r-xref--pkg-srcfile (symbol src-file &optional default-pkg)
-  "Search the R package containing symbol SYMBOL for file SRC-FILE.
-DEFAULT-PKG is the name of the package where presumably SYMBOL is located."
-  (let* ((pkgs (delq nil
-                     (delete-dups
-                      (or (cons default-pkg
-                                (ess-get-words-from-vector (format ".ess_fn_pkg(\"%s\")\n" symbol)))
-                          (user-error "Can't find package for symbol %s" symbol)))))
-         (lib-dirs (cond ((stringp ess-r-package-library-paths)
-                          (list ess-r-package-library-paths))
-                         ((listp ess-r-package-library-paths)
-                          ess-r-package-library-paths)
-                         (t (user-error "Invalid value of `ess-r-package-library-paths'"))))
-         (loc (or (cl-loop for pkg in pkgs
-                           for dir = (assoc-default pkg ess-r-xref-pkg-sources)
-                           when (and dir (file-exists-p dir)) return (cons pkg dir))
-                  (cl-some (lambda (dir)
-                             (cl-loop for pkg in pkgs
-                                      for path = (expand-file-name pkg dir)
-                                      when (file-exists-p path) return (cons pkg path)))
-                           lib-dirs)))
-         (file (when loc (expand-file-name src-file (cdr loc)))))
-    (when file
-      (unless (file-readable-p file)
-        (error "Can't read %s" file))
-      ;; Cache package's source directory.
-      (unless (assoc (car loc) ess-r-xref-pkg-sources)
-        (push loc ess-r-xref-pkg-sources))
-      file)))
-
-(defun ess-r-xref--xref (symbol)
-  "Create an xref for the source file reference of R symbol SYMBOL."
-  (when-let ((ref (ess-r-xref--srcref symbol)))
-    (let ((file (nth 0 ref))
-          (line (nth 1 ref))
-          (col  (nth 2 ref)))
-      (or
-       ;; 1) Result of ESS evaluation
-       (let* ((ess-ref (gethash file ess--srcrefs))
-              (ess-buff (when ess-ref (ess--dbg-find-buffer (car ess-ref)))))
-         (when ess-buff
-           ;; FIXME: this breaks when eval is on larger spans than function
-           (xref-make symbol (xref-make-buffer-location ess-buff (nth 2 ess-ref)))))
-       ;; 2) Real file from R proc working directory
-       (unless (file-name-absolute-p file)
-         (let ((file (expand-file-name file (ess-get-process-variable 'default-directory))))
-           (when (file-readable-p file)
-             (xref-make symbol (xref-make-file-location file line col)))))
-       ;; 3) Real file from the R's working directory
-       (unless (file-name-absolute-p file)
-         (when-let ((wdir (car (ess-get-words-from-vector ess-getwd-command))))
-           (let ((file (expand-file-name file wdir)))
-             (when (file-readable-p file)
-               (xref-make symbol (xref-make-file-location file line col))))))
-       ;; 4) Real file location from the current directory
-       (when (file-readable-p file)
-         (xref-make symbol (xref-make-file-location file line col)))
-       ;; 5) Temporary sources - truncate and locate in ess-r-package-library-paths
-       (when (string-match "/\\([^/]+\\)/\\(R/.*\\)$" file)
-         (when-let ((pkg-file (ess-r-xref--pkg-srcfile
-                               symbol (match-string 2 file) (match-string 1 file))))
-           (xref-make symbol (xref-make-file-location
-                              (expand-file-name pkg-file) line col))))))))
-
-(provide 'ess-r-xref)
-
-;;; ess-r-xref.el ends here
diff --git a/elpa/ess-20251212.937/ess-rd.el b/elpa/ess-20251212.937/ess-rd.el
deleted file mode 100644 (file)
index 937c30c..0000000
+++ /dev/null
@@ -1,491 +0,0 @@
-;; ess-rd.el --- Support for editing R documentation (Rd) source  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1997-2025 Free Software Foundation, Inc.
-;; Author: KH <Kurt.HornikNOSPAMci.tuwien.ac.at>
-;; Created: 25 July 1997
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-;;
-
-;;; Code:
-(eval-when-compile
-  (require 'subr-x))
-
-(require 'ess-help)
-(require 'ess-inf)
-;; Silence the byte compiler, see TODO below; can we remove these?
-(defvar ess-help-r-sec-regex)
-(defvar ess-help-r-sec-keys-alist)
-(defvar ess-r-customize-alist)
-
-(defcustom Rd-mode-hook nil
-  "Hook to be run when Rd mode is entered."
-  :type 'hook
-  :group 'ess-R
-  :group 'ess-hooks)
-
-(define-abbrev-table 'Rd-mode-skeleton-abbrev-table
-  '(("`ag" "\\arguments" nil :system t)
-    ("`al" "\\alias" nil :system t)
-    ("`au" "\\author" nil :system t)
-    ("`bf" "\\bold" nil :system t)
-    ;; not (yet) "bibcitep" "bibcitet" "bibshow" "bibinfo"
-    ("`co" "\\code" nil :system t)
-    ("`de" "\\describe" nil :system t)
-    ("`dn" "\\description" nil :system t)
-    ("`dt" "\\details" nil :system t)
-    ("`em" "\\emph" nil :system t)
-    ("`en" "\\enumerate" nil :system t)
-    ("`ex" "\\examples" nil :system t)
-    ("`fi" "\\file" nil :system t)
-    ("`fo" "\\format" nil :system t)
-    ("`it" "\\item" nil :system t)
-    ("`iz" "\\itemize" nil :system t)
-    ("`kw" "\\keyword" nil :system t)
-    ("`li" "\\link" nil :system t)
-    ("`me" "\\method" nil :system t)
-    ("`ma" "\\manual" nil :system t)
-    ("`na" "\\name" nil :system t)
-    ("`no" "\\note" nil :system t)
-    ("`re" "\\references" nil :system t)
-    ("`sa" "\\seealso" nil :system t)
-    ("`se" "\\section" nil :system t)
-    ("`so" "\\source" nil :system t)
-    ("`ss" "\\subsection" nil :system t)
-    ("`sy" "\\synopsis" nil :system t)
-    ("`ta" "\\tabular" nil :system t)
-    ("`ti" "\\title" nil :system t)
-    ("`us" "\\usage" nil :system t)
-    ("`va" "\\value" nil :system t))
-  "Abbrev table for R documentation keywords.
-All Rd mode abbrevs start with a grave accent (`)."
-  :case-fixed t)
-
-(define-abbrev-table 'Rd-mode-abbrev-table ()
-  "Abbrev table for Rd mode."
-  :parents (list Rd-mode-skeleton-abbrev-table))
-
-(defvar Rd-mode-syntax-table
-  (let ((tab (copy-syntax-table text-mode-syntax-table)))
-    (modify-syntax-entry ?\\ "\\" tab)
-    (modify-syntax-entry ?\{ "(}" tab)
-    (modify-syntax-entry ?\} "){" tab)
-    ;; Nice for editing, not for parsing ...
-    (modify-syntax-entry ?\( "()" tab)
-    (modify-syntax-entry ?\) ")(" tab)
-    (modify-syntax-entry ?\[ "(]" tab)
-    (modify-syntax-entry ?\] ")[" tab)
-    ;; To get strings right
-    ;; (modify-syntax-entry ?\' "\"" Rd-mode-syntax-table)
-    (modify-syntax-entry ?\" "\"" tab)
-    ;; To make abbrevs starting with a grave accent work ...
-    (modify-syntax-entry ?\` "w" tab)
-    ;; Comments
-    (modify-syntax-entry ?\% "<" tab)
-    (modify-syntax-entry ?\n ">" tab)
-    tab)
-  "Syntax table for `Rd-mode'.")
-
-(defvar Rd-mode-parse-syntax-table
-  (let ((tab (copy-syntax-table Rd-mode-syntax-table)))
-    ;; To make parse-partial-sexps do the thing we want for computing
-    ;; indentations
-    (modify-syntax-entry ?\( "_" tab)
-    (modify-syntax-entry ?\) "_" tab)
-    (modify-syntax-entry ?\[ "_" tab)
-    (modify-syntax-entry ?\] "_" tab)
-    tab)
-  "Syntax table for parsing Rd mode.")
-
-(defvar Rd-section-names
-  '("Rdversion" "arguments" "alias" "author" "concept" "describe" "description"
-    "details" "docType" "encoding" "enumerate" "examples" "format"
-    "itemize" "keyword" "name" "note" "preformatted" "references"
-    "seealso" "section" "source" "subsection" "synopsis"
-    "tabular" "title" "usage"
-    "value"))
-
-(defvar Rd-keywords ; to be highlighted in Rd-mode
-  '(
-    ;; the next two lines: only valid in R <= 2.8.1
-    ;; commented out on 2011-01-14 for ESS version 5.13:
-    ;; "Alpha" "Gamma" "alpha" "beta" "epsilon" "lambda" "mu" "pi" "sigma"
-    ;; "ge" "le" "left" "right"
-    ;;
-    "RdOpts" "R" "S3method" "S4method" "Sexpr"
-    "abbr" "acronym"
-    "bold" "cite" "code" "command" "cr" "dQuote" "deqn" "dfn" "dontdiff" "dontrun"
-    "dontshow" "donttest" "dots" "email" "emph" "enc" "env" "eqn" "figure" "file"
-    "href"
-    "ifelse" "if"
-    "item" "kbd" "ldots" "linkS4class" "link" "method"
-    "manual"
-    "newcommand" "option" "out"
-    "pkg" "sQuote" "renewcommand"
-    "samp" "strong" "tab" "url" "var" "verb"
-    ;; System macros (from <R>/share/Rd/macros/system.Rd ):
-    "bibcitep" "bibcitet" "bibshow" "bibinfo"
-    "CRANpkg" "PR" "sspace" "doi"
-    "I" ; should we?
-    "LaTeX"
-    "proglang"
-    "packageTitle" "packageDescription" "packageAuthor"
-    "packageMaintainer" "packageDESCRIPTION" "packageIndices"
-    ))
-
-(defvar Rd-font-lock-keywords
-  (list
-   (cons
-    (concat "\\\\\\("
-            (mapconcat #'identity Rd-section-names "\\|")
-            "\\>\\)")
-    'font-lock-constant-face) ; Rd-bold-face
-   (cons
-    (concat "\\\\\\("
-            (mapconcat #'identity Rd-keywords "\\|")
-            "\\>\\)")
-    'font-lock-keyword-face)
-   '("^#\\(ifn?def\\)\\s-+\\(\\sw+\\)"
-     (1 font-lock-builtin-face)
-     (2 font-lock-variable-name-face nil t))
-   '("^#\\(endif\\)" 1 font-lock-builtin-face))
-  "Additional Rd expressions to highlight.")
-
-(defvar Rd-indent-level 2
-  "Indentation of Rd code with respect to containing blocks.")
-
-(defvar Rd-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map "\t" #'indent-according-to-mode)
-    (define-key map "\C-j" #'reindent-then-newline-and-indent)
-    (define-key map "\C-m" #'reindent-then-newline-and-indent)
-    (define-key map "\C-c\C-p" #'Rd-preview-help)
-    (define-key map "\C-c\C-j" #'Rd-mode-insert-item)
-    (define-key map "\C-c\C-e" #'Rd-mode-insert-skeleton)
-    (define-key map "\C-c\C-d" #'Rd-mode-insert-data-skeleton)
-    (define-key map "\C-c\C-f" #'Rd-font)
-    (define-key map "\C-c\C-s" #'Rd-mode-insert-section)
-    (define-key map "\C-c\C-n" #'ess-eval-line-visibly-and-step)
-    (define-key map "\C-c\C-r" #'ess-eval-region)
-    (define-key map "\C-c\C-c" #'ess-eval-region-or-function-or-paragraph-and-step)
-    (define-key map "\C-\M-x"  #'ess-eval-region-or-function-or-paragraph)
-    (define-key map "\C-c\C-v" #'ess-display-help-on-object)
-    (define-key map "\C-c\C-w" #'ess-switch-process)
-    (define-key map "\C-c\C-y" #'ess-switch-to-ESS)
-    (define-key map "\C-c\C-z" #'ess-switch-to-end-of-ESS)
-    map)
-  "Keymap used in Rd mode.")
-
-(defvar Rd-mode-menu
-  (list "Rd"
-        ["Markup [word]"                Rd-font t]
-        ["Insert Item"                  Rd-mode-insert-item t]
-        ["Insert Section"               Rd-mode-insert-section t]
-        ["Insert Skeleton"              Rd-mode-insert-skeleton t]
-        ["Insert Data Skeleton"         Rd-mode-insert-data-skeleton t]
-        "-"
-        ["Preview"                      Rd-preview-help t]
-        "-"
-        ["Eval Line"                    ess-eval-line-visibly-and-step t]
-        ["Eval Region"                  ess-eval-region t]
-        ["Switch to ESS Process"        ess-switch-to-ESS t]
-        ["Switch the ESS Process"       ess-switch-process t]
-        ["Switch to end{ESS Pr}"        ess-switch-to-end-of-ESS t]
-        "-"
-        ["Toggle Abbrev Mode"           abbrev-mode t]
-        ["Toggle Auto-Fill Mode"        auto-fill-mode t]
-        "-"
-        ["Submit Bug Report"            ess-submit-bug-report t]
-        "-"
-        ["Describe Rd Mode"             describe-mode t])
-  "Menu used in Rd mode.")
-
-(defvar Rd-to-help-command "R CMD Rd2txt"
-  "Shell command for converting R documentation source to help text.")
-
-(defvar Rd-font-list
-  '((?\C-b "\\bold{"    "}")
-    (?\C-c "\\code{"    "}")
-    (?\C-e "\\emph{"    "}")
-    (?\C-l "\\link{"    "}")
-    (?l "\\code{\\link{" "}}")
-    (?\C-m "\\email{"   "}")
-    (?\C-q "\\eqn{"     "}")
-    (?\C-u "\\url{"     "}")
-    )
-  "List of \"fonts\" used by `Rd-font'.
-Each entry is a list. The first element is the key to activate
-the font. The second element is the string to insert before
-point, and the third element is the string to insert after
-point.")
-
-
-;;;###autoload
-(define-derived-mode Rd-mode text-mode "Rd"
-  "Major mode for editing R documentation source files.
-
-Type \\[list-abbrevs] to display the built-in abbrevs for Rd
-keywords.To automatically turn on the abbrev(iate) features, add
-the following to your Emacs configuration file:
-
-  (add-hook \\='Rd-mode-hook #\\='abbrev-mode)"
-  (setq ess-language "S" ess-dialect  "R")
-  (require 'ess-r-mode)
-  (ess-setq-vars-local ess-r-customize-alist)
-
-  (setq-local indent-line-function #'Rd-mode-indent-line)
-  (setq fill-column 72)
-  (setq-local comment-start-skip "\\s<+\\s-*")
-  (setq-local comment-start "% ")
-  (setq-local comment-end "")
-  (setq font-lock-defaults
-        '(Rd-font-lock-keywords nil nil))
-
-  ;; Here is a workaround for an Emacs bug related to indirect buffers and
-  ;; spurious lockfiles that rears its ugly head with .Rd files
-  ;; https://lists.gnu.org/archive/html/bug-gnu-emacs/2013-02/msg01368.html
-  ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=14328
-  (setq-local create-lockfiles nil)
-
-  (easy-menu-define Rd-mode-menu-map Rd-mode-map
-    "Menu keymap for Rd mode." Rd-mode-menu)
-
-  (turn-on-auto-fill))
-
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.Rd\\'" . Rd-mode))
-
-(defun Rd-describe-major-mode ()
-  "Describe the current major mode."
-  (declare (obsolete describe-mode "ESS 19.04"))
-  (describe-function major-mode))
-
-(defun Rd-mode-in-verbatim-p ()
-  "Return non-nil if in a usage, examples, or synopsis."
-  (let ((pos (point)))
-    (save-excursion
-      (if (and (re-search-backward
-                "\\\\\\(usage\\|examples\\|synopsis\\)" nil t)
-               (re-search-forward "\\s(" nil t))
-          (condition-case ()
-              (progn
-                (up-list 1)
-                (< pos (point)))
-            (error t))
-        nil))))
-
-(defun Rd-mode-in-preprocessor-line-p ()
-  "Return non-nil if in a preprocessor line."
-  (save-excursion
-    (beginning-of-line)
-    (looking-at "[ \t]*#\\(ifdef\\|endif\\)")))
-
-(defun Rd-mode-calculate-indent ()
-  "Return appropriate indentation for current line in Rd mode."
-  (save-excursion
-    (beginning-of-line)
-    (cond
-     ((Rd-mode-in-verbatim-p)
-      ;; Don't do anything in verbatims
-      nil)
-     ((Rd-mode-in-preprocessor-line-p)
-      ;; Indent to 0
-      0)
-     (t
-      (let ((p (progn
-                 (re-search-forward "[ \t]*\\s)*" (line-end-position) t)
-                 (point))))
-        (if (or (< (forward-line -1) 0)
-                (Rd-mode-in-verbatim-p))
-            0
-          (set-syntax-table Rd-mode-parse-syntax-table)
-          (while (and (or (looking-at "[ \t]*$")
-                          (Rd-mode-in-preprocessor-line-p))
-                      (not (bobp)))
-            (forward-line -1))
-          (re-search-forward "[ \t]*\\s)*" (line-end-position) t)
-          (prog1
-              (+ (current-indentation)
-                 (* (car (parse-partial-sexp (point) p))
-                    Rd-indent-level))
-            (set-syntax-table Rd-mode-syntax-table))))))))
-
-(defun Rd-mode-indent-line ()
-  "Indent current line as Rd source."
-  (when-let ((ic (Rd-mode-calculate-indent))
-             (rp (- (current-column) (current-indentation))))
-    (when (< ic 0)
-      (error "Unmatched parenthesis"))
-    (indent-line-to ic)
-    (when (> rp 0)
-      (move-to-column (+ ic rp)))))
-
-(defun Rd-mode-insert-item ()
-  "Insert \\item{ on a newline."
-  (interactive)
-  (reindent-then-newline-and-indent)
-  (insert "\\item{")
-  )
-
-(defun Rd-mode-insert-section ()
-  "Insert a section from `Rd-section-names'."
-  (interactive)
-  (let ((s (ess-completing-read
-            "Insert section: "
-            (mapcar (lambda (x) (cons x x)) Rd-section-names)
-            nil t)))
-    (if (string= s "")
-        (progn (insert "\\section{}{") (backward-char 2))
-      (insert (format "\\%s{" s)))))
-
-(defun Rd-mode-insert-skeleton ()
-  "Insert several empty Rd fields."
-  (interactive)
-  ;; Hmm: in theory this should be kept in sync with prompt()
-  ;; ---  maybe using prompt() [or promptClass()...] would be better anyway?!
-  (insert "\\name{}\n")
-  (insert "\\alias{}\n")
-  (insert "\\title{}\n")
-  (insert "\\description{\n}\n")
-  (insert "\\usage{\n}\n")
-  (insert "\\arguments{\n}\n")
-  (insert "\\value{\n}\n")
-  (insert "\\details{\n}\n")
-  (insert "\\references{\n}\n")
-  (insert "\\seealso{\n}\n")
-  (insert "\\examples{\n}\n")
-  (insert "\\author{}\n")
-  (insert "\\keyword{}\n"))
-
-(defun Rd-mode-insert-data-skeleton ()
-  "Insert several empty Rd fields."
-  (interactive)
-  ;; Hmm: in theory this should be kept in sync with prompt()
-  ;; ---  maybe using prompt() [or promptClass()...] would be better anyway?!
-  (insert "\\name{}\n")
-  (insert "\\docType{}\n")
-  (insert "\\alias{}\n")
-  (insert "\\title{}\n")
-  (insert "\\description{\n}\n")
-  (insert "\\usage{\n}\n")
-  (insert "\\format{\n}\n")
-  (insert "\\details{\n}\n")
-  (insert "\\source{}\n")
-  (insert "\\references{\n}\n")
-  (insert "\\examples{\n}\n")
-  (insert "\\keyword{datasets}\n"))
-
-
-;; This is an `easy' version of (defun TeX-font ..) in AUCtex's  tex.el ;
-;;  see TeX-font-list and also LaTeX-font-list in latex.el
-
-(defun Rd-font (what)
-  "Insert template for font command.
-WHAT determines the font to use, as specified by `Rd-font-list'."
-  (interactive "c")
-  ;;TeX had : (Rd-update-style)
-  (let* ((entry (assoc what Rd-font-list))
-         (before (nth 1 entry))
-         (after (nth 2 entry)))
-    (cond ((null entry) ;; help on possibilities :
-           (let ((help
-                  (concat
-                   "Rd Markup (available from C-c C-f):\n\n\t"
-                   "KEY          Rd-Markup\n\n"
-                   (mapconcat
-                    (lambda (entry)
-                      ;; A textual description of an ENTRY in TeX-font-list.
-                      (concat (format "%11s  "
-                                      (key-description
-                                       (char-to-string (nth 0 entry))))
-                              (format "%14s %-3s"
-                                      (nth 1 entry) (nth 2 entry))))
-                    Rd-font-list "\n"))))
-             (with-output-to-temp-buffer "*Help*"
-               (set-buffer "*Help*")
-               (insert help))))
-
-          ((region-active-p)
-           (save-excursion
-             (cond ((> (mark) (point))
-                    (insert before)
-                    (goto-char (mark))
-                    (insert after))
-                   (t
-                    (insert after)
-                    (goto-char (mark))
-                    (insert before)))))
-          (t
-           (insert before)
-           (save-excursion
-             (insert after))))))
-
-(defun Rd-preview-help (&optional via-shell)
-  "Preview the current Rd buffer contents as help.
-If the current buffer is not associated with a file, create a
-temporary one in variable `temporary-file-directory'."
-  (declare (advertised-calling-convention () "ESS 19.04"))
-  (interactive "P")                     ; If optional VIA-SHELL is set, using `Rd-to-help-command'.
-  (let ((file buffer-file-name)
-        (pbuf (get-buffer-create "R Help Preview"))
-        del-p)
-    (unless file
-      (setq file (make-temp-file "RD_" nil ".Rd"))
-      (write-region (point-min) (point-max) file)
-      (setq del-p t))
-
-    (if via-shell ;; FIXME eventually get rid of this option
-        ;; only method in ESS <= 14.09 -- calls "R" even if in "R-devel"; slower
-        (let ((shcmd (format "%s '%s'" Rd-to-help-command file)))
-          (set-buffer pbuf)
-          (erase-buffer)
-          (ess-write-to-dribble-buffer
-           (format "Rd-preview-help: (shell-command |%s| t)" shcmd))
-          (shell-command shcmd t))
-      ;; else directly:
-      (ess-force-buffer-current "R process to use: ")
-      (ess--foreground-command (format ".ess_Rd2txt(\"%s\")\n" file) pbuf)
-      (set-buffer pbuf))
-
-    ;; FIXME(2): once got rid of via-shell, consider
-    ;; (ess--flush-help-into-current-buffer file "tools::Rd2txt(\"%s\")\n")
-    ;; instead of all this :
-    (ess-setq-vars-local ess-r-customize-alist)
-    ;; mostly cut'n'paste from ess--flush-help* (see FIXME(2)):
-    (ess-help-underline)
-    (ess--help-major-mode)
-    ;; FIXME: Is this really needed?
-    (setq ess-help-sec-regex ess-help-r-sec-regex
-          ess-help-sec-keys-alist ess-help-r-sec-keys-alist)
-    (goto-char (point-min))
-    (set-buffer-modified-p 'nil)
-    (setq buffer-read-only t)
-    (setq truncate-lines nil)
-    (when del-p (delete-file file))
-    (unless (get-buffer-window pbuf 'visible)
-      (display-buffer pbuf t))))
-
-(define-obsolete-function-alias 'Rd-submit-bug-report #'ess-submit-bug-report "2018-08-16")
-
-(provide 'ess-rd)
-
-;;; ess-rd.el ends here
diff --git a/elpa/ess-20251212.937/ess-rdired.el b/elpa/ess-20251212.937/ess-rdired.el
deleted file mode 100644 (file)
index e025a5f..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-;;; ess-rdired.el --- prototype object browser for R, looks like dired mode.  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2002-2022 Free Software Foundation, Inc.
-;; Author: Stephen Eglen <stephenNOSPAManc.ed.ac.uk>
-;; Created: Thu 24 Oct 2002
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; This provides a dired-like buffer for R objects.  Instead of
-;; operating on files, we operate on R objects in the current
-;; environment.  Objects can be viewed, edited, deleted, plotted and
-;; so on.
-;; Do "M-x R" to start an R session, then create a few variables:
-;;
-;; s <- sin(seq(from=0, to=8*pi, length=100))
-;; x <- c(1, 4, 9)
-;; y <- rnorm(20)
-;; z <- TRUE
-
-;; Then in Emacs, do "M-x ess-rdired" and you should see the following in
-;; the buffer *R dired*:
-;; Name              Class    Length     Size
-;; s                  numeric    100        848 bytes
-;; x                  numeric    3          80 bytes
-;; y                  numeric    20         208 bytes
-;; z                  logical    1          56 bytes
-
-;; Type "?" in the buffer to see the documentation.  e.g. when the
-;; cursor is on the line for `s', type 'p' to plot it, or `v' to view
-;; its contents in a buffer.  Then type 'd' to delete it.
-
-;; How it works.
-
-;; Most of the hard work is done by the R routine .rdired.objects(),
-;; which, when called, produces the list of objects in a tidy format.
-;; This function is stored within the Lisp variable `ess-rdired-objects'.
-
-;; Todo - How to select alternative environments?  Currently only
-;; shows objects in the .GlobalEnv?  See BrowseEnv() in 1.6.x for way
-;; of browsing other environments.
-
-;; Todo - problem with fix -- have to wait for fix() command to return
-;; before *R* buffer can be used again.  This can get stuck, umm. not
-;; sure what is going wrong here.  Maybe add a hook to the temp buffer
-;; so that when buffer is killed, we send an instruction to R to
-;; update the value of the variable to the contents of the buffer.
-;; This way *R* doesn't have to wait.
-
-;; Todo - small bug in .rdired.objects -- if we have a variable called
-;; `my.x', its value is replaced by the value of my.x used in the
-;; sapply() calls within .rdired.objects().
-
-;;; Code:
-
-(require 'ess-inf)
-
-(eval-when-compile
-  (require 'subr-x))
-
-(defvar ess-rdired-objects ".ess.rdired()\n"
-  "Function to call within R to print information on objects.")
-
-(defvar ess-rdired-buffer "*R dired*"
-  "Name of buffer for displaying R objects.")
-
-(defvar ess-rdired-auto-update-timer nil
-  "The timer object for auto updates.")
-
-(defcustom ess-rdired-auto-update-interval 5
-  "Seconds between refreshes of the `ess-rdired' buffer."
-  :type '(choice (const :tag "No auto updates" nil) (integer :tag "Seconds"))
-  :group 'ess-R
-  :package-version '(ess . "19.04"))
-
-(defvar ess-rdired-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map "d" #'ess-rdired-delete)
-    (define-key map "x" #'ess-rdired-delete)
-    (define-key map "v" #'ess-rdired-view)
-    (define-key map "V" #'ess-rdired-View)
-    (define-key map "p" #'ess-rdired-plot)
-    (define-key map "y" #'ess-rdired-type)
-    (define-key map "\C-c\C-s" #'ess-rdired-switch-process)
-    (define-key map "\C-c\C-y" #'ess-switch-to-ESS)
-    (define-key map "\C-c\C-z" #'ess-switch-to-end-of-ESS)
-    map))
-
-(define-derived-mode ess-rdired-mode tabulated-list-mode "Rdired"
-  "Major mode for output from `ess-rdired'.
-`ess-rdired' provides a dired-like mode for R objects.  It shows the
-list of current objects in the current environment, one-per-line.  You
-can then examine these objects, plot them, and so on."
-  :group 'ess-R
-  (setq mode-name (concat "RDired " ess-local-process-name))
-  (setq tabulated-list-format
-        `[("Name" 18 t)
-          ("Class" 10 t)
-          ("Length" 10 ess-rdired--length-predicate)
-          ("Rows" 10 ess-rdired--rows-predicate)
-          ("Size" 10 ess-rdired--size-predicate)])
-  (add-hook 'tabulated-list-revert-hook #'ess-rdired-refresh nil t)
-  (when (and (not ess-rdired-auto-update-timer)
-             ess-rdired-auto-update-interval)
-    (setq ess-rdired-auto-update-timer
-          (run-at-time t ess-rdired-auto-update-interval #'ess-rdired-refresh)))
-  (add-hook 'kill-buffer-hook #'ess-rdired-cancel-auto-update-timer nil t)
-  (tabulated-list-init-header))
-
-;;;###autoload
-(defun ess-rdired ()
-  "Show R objects from the global environment in a separate buffer.
-You may interact with these objects, see `ess-rdired-mode' for
-details."
-  (interactive)
-  (unless (and (string= "R" ess-dialect)
-               ess-local-process-name)
-    (error "Not in an R buffer with attached process"))
-  (let ((proc ess-local-process-name))
-    (pop-to-buffer (get-buffer-create ess-rdired-buffer))
-    (setq ess-local-process-name proc)
-    (ess-rdired-mode)
-    (ess-rdired-refresh)))
-
-(defun ess-rdired-refresh ()
-  "Refresh the `ess-rdired' buffer."
-  (let* ((buff (get-buffer-create ess-rdired-buffer))
-         (proc-name (buffer-local-value 'ess-local-process-name buff))
-         (proc (get-process proc-name))
-         (out-buff (get-buffer-create " *ess-rdired-output*"))
-         text)
-    (when (and proc-name proc
-               (not (process-get proc 'busy)))
-      (ess--foreground-command ess-rdired-objects out-buff nil nil nil proc)
-      (with-current-buffer out-buff
-        (goto-char (point-min))
-        ;; Delete two lines. One filled with +'s from R's prompt
-        ;; printing, the other with the header info from the data.frame
-        (delete-region (point-min) (1+ (line-end-position 2)))
-        (setq text (split-string (buffer-string) "\n" t "\n"))
-        (erase-buffer))
-      (with-current-buffer buff
-        (setq tabulated-list-entries
-              (mapcar #'ess-rdired--tabulated-list-entries text))
-        (let ((entry (tabulated-list-get-id))
-              (col (current-column)))
-          (tabulated-list-print)
-          (while (not (equal entry (tabulated-list-get-id)))
-            (forward-line))
-          (move-to-column col))))))
-
-(defun ess-rdired-cancel-auto-update-timer ()
-  "Cancel the timer `ess-rdired-auto-update-timer'."
-  (setq ess-rdired-auto-update-timer
-        (cancel-timer ess-rdired-auto-update-timer)))
-
-(defun ess-rdired--tabulated-list-entries (text)
-  "Return a value suitable for `tabulated-list-entries' from TEXT."
-    (let (name class length rows size)
-    (if (not (string-match-p " +\"" text))
-        ;; Normal-world
-        (setq text (split-string text " " t)
-              name (nth 0 text)
-              text (cdr text))
-      ;; Else, someone has spaces in their variable names
-      (string-match "\"\\([^\"]+\\)" text)
-      (setq name (substring (match-string 0 text) 1)
-            text (split-string (substring text (1+ (match-end 0))) " " t)))
-    (setq class (nth 0 text)
-          length (nth 1 text)
-          rows (nth 2 text)
-          size (nth 3 text))
-    (list name
-          `[(,name
-             help-echo "mouse-2, RET: View this object"
-             action ess-rdired-view)
-            ,class
-            ,length
-            ,rows
-            ,size])))
-
-(defun ess-rdired-edit ()
-  "Edit the object at point."
-  (interactive)
-  (ess-command (concat "edit(" (tabulated-list-get-id) ")\n")))
-
-(defun ess-rdired-view (&optional _button)
-  "View the object at point."
-  (interactive)
-  (ess-execute (ess-rdired-get (tabulated-list-get-id))
-               nil "R view" ))
-
-(defun ess-rdired-get (name)
-  "Generate R code to get the value of the variable NAME.
-This is complicated because some variables might have spaces in their names.
-Otherwise, we could just pass the variable name directly to *R*."
-  (concat "get(" (ess-rdired-quote name) ")")
-  )
-
-(defun ess-rdired-quote (name)
-  "Quote NAME if not already quoted."
-  (if (equal (substring name 0 1) "\"")
-      name
-    (concat "\"" name "\"")))
-
-(defun ess-rdired-View ()
-  "View the object at point in its own buffer.
-Like `ess-rdired-view', but the object gets its own buffer name."
-  (interactive)
-  (let ((objname (tabulated-list-get-id)))
-    (ess-execute (ess-rdired-get objname)
-                 nil (concat "R view " objname ))))
-
-(defun ess-rdired-plot ()
-  "Plot the object on current line."
-  (interactive)
-  (let ((objname (tabulated-list-get-id)))
-    (ess-eval-linewise (format "plot(%s)" (ess-rdired-get objname)))))
-
-(defun ess-rdired-type ()
-  "Run the mode() on command at point."
-  (interactive)
-  (let ((objname (tabulated-list-get-id))
-        ;; create a temp buffer, and then show output in echo area
-        (tmpbuf (get-buffer-create "**ess-rdired-mode**")))
-    (if objname
-        (progn
-          (ess-command (concat "mode(" (ess-rdired-get objname) ")\n")
-                       tmpbuf )
-          (set-buffer tmpbuf)
-          (message "%s" (concat
-                         objname ": "
-                         (buffer-substring (+ 4 (point-min)) (1- (point-max)))))
-          (kill-buffer tmpbuf)))))
-
-(defalias 'ess-rdired-expunge #'ess-rdired-delete)
-
-(defun ess-rdired-delete ()
-  "Delete the object at point."
-  (interactive)
-  (let ((objname (tabulated-list-get-id)))
-    (when (yes-or-no-p (format "Really delete %s? " objname))
-      (ess-eval-linewise (format "rm(%s)" (ess-rdired-quote objname)) nil nil nil t)
-      (revert-buffer))))
-
-(defun ess-rdired-switch-process ()
-  "Switch to examine different *R* process.
-If you have multiple R processes running, e.g. *R*, *R:2*, *R:3*, you can
-use this command to choose which R process you would like to examine.
-After switching to a new process, the buffer is updated."
-  (interactive)
-  (ess-switch-process)
-  (ess-rdired))
-
-(defun ess-rdired--length-predicate (A B)
-  "Enable sorting by length in `ess-rdired' buffers.
-Return t if A's length is < than B's length."
-  (let ((lenA (aref (cadr A) 2))
-        (lenB (aref (cadr B) 2)))
-    (< (string-to-number lenA) (string-to-number lenB))))
-
-(defun ess-rdired--rows-predicate (A B)
-  "Enable sorting by rows in `ess-rdired' buffers.
-Return t if A's length is < than B's length."
-  (let ((lenA (aref (cadr A) 2))
-        (lenB (aref (cadr B) 2)))
-    (< (string-to-number lenA) (string-to-number lenB))))
-
-(defun ess-rdired--size-predicate (A B)
-  "Enable sorting by size in `ess-rdired' buffers.
-Return t if A's size is < than B's size."
-  (let ((lenA (aref (cadr A) 3))
-        (lenB (aref (cadr B) 3)))
-    (< (string-to-number lenA) (string-to-number lenB))))
-
-(define-obsolete-function-alias 'ess-rdired-quit #'quit-window "ESS 19.04")
-(define-obsolete-function-alias 'ess-rdired-next-line #'forward-to-indentation "ESS 19.04")
-(define-obsolete-function-alias 'ess-rdired-previous-line #'backward-to-indentation "ESS 19.04")
-(define-obsolete-function-alias 'ess-rdired-move-to-object #'back-to-indentation "ESS 19.04")
-
-(provide 'ess-rdired)
-
-;;; ess-rdired.el ends here
diff --git a/elpa/ess-20251212.937/ess-roxy.el b/elpa/ess-20251212.937/ess-roxy.el
deleted file mode 100644 (file)
index 00b172c..0000000
+++ /dev/null
@@ -1,1038 +0,0 @@
-;;; ess-roxy.el --- convenient editing of in-code roxygen documentation  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2009-2022 Free Software Foundation, Inc.
-;; Author: Henning Redestig <henning.red * go0glemail c-m>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; Lots of inspiration from doc-mode,
-;; https://nschum.de/src/emacs/doc-mode/
-;;
-;; Features::
-;;
-;; - basic highlighting
-;; - generating and updating templates from function definition and customized default template
-;;   - C-c C-o C-o :: update template
-;; - navigating and filling roxygen fields
-;;   - C-c TAB, M-q, C-a, ENTER, M-h :: advised tag completion, fill-paragraph,
-;;        ess-roxy-move-beginning-of-line, newline-and-indent
-;;   - C-c C-o n,p :: next, previous roxygen entry
-;;   - C-c C-o C-c :: Unroxygen region. Convenient for editing examples.
-;; - folding visibility using hs-minor-mode
-;;   - TAB :: advised ess-indent-command, hide entry if in roxygen doc.
-;; - preview
-;;   - C-c C-o C-r :: create a preview of the Rd file as generated
-;;     using roxygen
-;;   - C-c C-o C-t :: create a preview of the Rd HTML file as generated
-;;     using roxygen and the tools package
-;;   - C-c C-o t :: create a preview of the Rd text file
-;;
-;; Known issues:
-;;
-;; - hideshow mode does not work very well. In particular, if ordinary
-;;   comments precede a roxygen entry, then both will be hidden in the
-;;   same overlay from start and not unfoldable using TAB since the
-;;   roxygen prefix is not present. The planned solution is implement
-;;   a replacement for hideshow.
-;; - only limited functionality for S4 documentation.
-
-;;; Code:
-
-(require 'ess-utils)
-(require 'hideshow)
-(require 'outline)
-(eval-when-compile
-  (require 'cl-lib)
-  (require 'subr-x))
-(require 'ess-rd)
-(require 'ess-r-syntax)
-
-(defvar roxy-str)
-(defvar ess-r-mode-syntax-table)
-(declare-function ess-fill-args "ess-r-mode")
-(declare-function ess-fill-continuations "ess-r-mode")
-(declare-function inferior-ess-r-force "ess-r-mode")
-
-(defvar-local ess-roxy-re nil
-  "Regular expression to recognize roxygen blocks.")
-
-\f
-;;*;; Roxy Minor Mode
-
-(defvar ess-roxy-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "C-c C-o h") #'ess-roxy-hide-all)
-    (define-key map (kbd "C-c C-o n")   #'ess-roxy-next-entry)
-    (define-key map (kbd "C-c C-o p")   #'ess-roxy-previous-entry)
-    (define-key map (kbd "C-c C-o C-o") #'ess-roxy-update-entry)
-    (define-key map (kbd "C-c C-o C-r") #'ess-roxy-preview-Rd)
-    (define-key map (kbd "C-c C-o C-w") #'ess-roxy-preview-HTML)
-    (define-key map (kbd "C-c C-o C-t")   #'ess-roxy-preview-text)
-    (define-key map (kbd "C-c C-o C-c") #'ess-roxy-toggle-roxy-region)
-    (define-key map [remap back-to-indentation] #'ess-roxy-goto-end-of-roxy-comment)
-    (define-key map [remap newline] #'ess-roxy-newline)
-    (define-key map [remap newline-and-indent] #'ess-roxy-newline)
-    (define-key map [remap ess-indent-command] #'ess-roxy-ess-indent-command)
-    (define-key map [remap move-beginning-of-line] #'ess-roxy-move-beginning-of-line)
-    (define-key map [remap beginning-of-visual-line] #'ess-roxy-move-beginning-of-line)
-    map))
-
-(defvar ess-roxy-font-lock-keywords nil
-  "Cache set by `ess-roxy-generate-keywords'.
-Used to remove keywords added by function `ess-roxy-mode'.")
-
-(defun ess-roxy-generate-keywords ()
-  "Generate a list of keywords suitable for `font-lock-add-keywords'."
-  (setq-local ess-roxy-font-lock-keywords
-              `((,(concat ess-roxy-re " *\\([@\\]"
-                          (regexp-opt ess-roxy-tags-param t)
-                          "\\)\\>")
-                 (1 'font-lock-keyword-face prepend))
-                (,(concat ess-roxy-re " *\\(@"
-                          (regexp-opt '("param" "importFrom" "importClassesFrom"
-                                        "importMethodsFrom" "describeIn")
-                                      'words)
-                          "\\)\\(?:[ \t]+\\(\\(?:\\sw+,?\\)+\\)\\)")
-                 (1 'font-lock-keyword-face prepend)
-                 (3 'font-lock-variable-name-face prepend))
-                (,(concat "[@\\]" (regexp-opt ess-roxy-tags-noparam t) "\\>")
-                 (0 'font-lock-variable-name-face prepend))
-                (,(concat ess-roxy-re)
-                 (0 'bold prepend)))))
-
-(defvar ess-roxy-fold-examples nil
-  "Whether to fold `@examples' when opening a buffer.
-Use you regular key for `outline-show-entry' to reveal it.")
-
-;;;###autoload
-(define-minor-mode ess-roxy-mode
-  "Minor mode for editing ROxygen documentation."
-  :keymap ess-roxy-mode-map
-  (if ess-roxy-mode
-      ;; Turn on `ess-roxy-mode':
-      (progn
-        (setq-local ess-roxy-re (concat "^" (string-trim comment-start) "+'"))
-        (font-lock-add-keywords nil (ess-roxy-generate-keywords))
-        (add-hook 'completion-at-point-functions #'ess-roxy-complete-tag nil t)
-        ;; Hideshow Integration
-        (when ess-roxy-hide-show-p
-          (hs-minor-mode 1)
-          (when ess-roxy-start-hidden-p
-            (ess-roxy-hide-all)))
-        ;;  Outline Integration
-        (when ess-roxy-fold-examples
-          (ess-roxy-hide-all-examples))
-        ;; Autofill
-        (setq-local paragraph-start (concat "\\(" ess-roxy-re "\\)*" paragraph-start))
-        (setq-local paragraph-separate (concat "\\(" ess-roxy-re "\\)*" paragraph-separate))
-        (setq-local adaptive-fill-function #'ess-roxy-adaptive-fill-function)
-        ;; Hooks
-        (add-hook 'ess-presend-filter-functions #'ess-roxy-remove-roxy-re nil t))
-    ;; Turn off `ess-roxy-mode':
-    ;; Hideshow
-    (when (and ess-roxy-hide-show-p hs-minor-mode)
-      (hs-show-all)
-      (hs-minor-mode))
-    ;; Hooks
-    (remove-hook 'ess-presend-filter-functions #'ess-roxy-remove-roxy-re t)
-    (font-lock-remove-keywords nil ess-roxy-font-lock-keywords)
-    ;; (setq-local syntax-propertize-function nil)
-    ;; (setq-local font-lock-fontify-region-function nil)
-    ;; (setq-local font-lock-unfontify-region-function nil)
-    )
-  ;; Regardless of turning on or off we need to re-fontify the buffer:
-  (when font-lock-mode
-    (font-lock-flush)))
-
-
-\f
-;;*;; Outline Integration
-
-(defvar ess-roxy-outline-regexp "^#+' +@examples\\|^[^#]")
-
-(defun ess-roxy-substitute-outline-regexp (command)
-  (let ((outline-regexp (if (ess-roxy-entry-p "examples")
-                            ess-roxy-outline-regexp
-                          outline-regexp)))
-    (funcall command)))
-
-(declare-function outline-cycle "outline-magic")
-(defun ess-roxy-cycle-example ()
-  (interactive)
-  (unless (featurep 'outline-magic)
-    (error "Please install and load outline-magic"))
-  ;; Don't show children when cycling @examples
-  (let ((this-command 'outline-cycle-overview))
-    (ess-roxy-substitute-outline-regexp #'outline-cycle)))
-
-(defun ess-roxy-show-example ()
-  (interactive)
-  (ess-roxy-substitute-outline-regexp #'outline-show-entry))
-
-(defun ess-roxy-hide-example ()
-  (interactive)
-  (ess-roxy-substitute-outline-regexp #'outline-hide-entry))
-
-(defun ess-roxy-hide-all-examples ()
-  (interactive)
-  (save-excursion
-    (goto-char (point-min))
-    (while (re-search-forward "^#+' +@examples\\b" nil t)
-      ;; Handle edge cases
-      (when (ess-roxy-entry-p "examples")
-        (ess-roxy-hide-example)))))
-
-(substitute-key-definition #'outline-hide-entry
-                           #'ess-roxy-hide-example
-                           ess-roxy-mode-map outline-minor-mode-map)
-
-(substitute-key-definition #'outline-show-entry
-                           #'ess-roxy-show-example
-                           ess-roxy-mode-map outline-minor-mode-map)
-
-\f
-;;*;; Function definitions
-
-(defun ess-back-to-roxy ()
-  "Go to roxy prefix."
-  (end-of-line)
-  (re-search-backward (concat ess-roxy-re " ?") (line-beginning-position))
-  (goto-char (match-end 0)))
-
-(defun ess-roxy-beg-of-entry ()
-  "Get point number at start of current entry, 0 if not in entry."
-  (save-excursion
-    (let (beg)
-      (beginning-of-line)
-      (setq beg -1)
-      (if (not (ess-roxy-entry-p))
-          (setq beg 0)
-        (setq beg (point)))
-      (while (and (= (forward-line -1) 0) (ess-roxy-entry-p))
-        (setq beg (point)))
-      beg)))
-
-(defun ess-roxy-in-header-p ()
-  "True if point is the description / details field."
-  (save-excursion
-    (let ((res t)
-          (cont (ess-roxy-entry-p)))
-      (beginning-of-line)
-      (while cont
-        (if (looking-at (concat ess-roxy-re " *[@].+"))
-            (progn (setq res nil)
-                   (setq cont nil)))
-        (setq cont (and (= (forward-line -1) 0) (ess-roxy-entry-p)))
-        )res)))
-
-(defun ess-roxy-beg-of-field ()
-  "Get point number at beginning of current field, 0 if not in entry."
-  (save-excursion
-    (let (cont beg)
-      (beginning-of-line)
-      (setq beg 0)
-      (setq cont t)
-      (while (and (ess-roxy-entry-p) cont)
-        (setq beg (point))
-        (if (looking-at (concat ess-roxy-re " *[@].+"))
-            (setq cont nil))
-        (if (ess-roxy-in-header-p)
-            (if (looking-at (concat ess-roxy-re " *$"))
-                (progn
-                  (forward-line 1)
-                  (setq beg (point))
-                  (setq cont nil))))
-        (if cont (setq cont (= (forward-line -1) 0))))
-      beg)))
-
-(defun ess-roxy-end-of-entry ()
-  "Get point number at end of current entry, 0 if not in entry."
-  (save-excursion
-    (let ((end))
-      (end-of-line)
-      (setq end -1)
-      (if (not (ess-roxy-entry-p))
-          (setq end 0)
-        (setq end (point)))
-      (while (and (= (forward-line 1) 0) (ess-roxy-entry-p))
-        (end-of-line)
-        (setq end (point)))
-      end)))
-
-(defun ess-roxy-end-of-field ()
-  "Get point number at end of current field, 0 if not in entry."
-  (save-excursion
-    (let ((end nil)
-          (cont nil))
-      (setq end 0)
-      (if (ess-roxy-entry-p) (progn (end-of-line) (setq end (point))))
-      (beginning-of-line)
-      (forward-line 1)
-      (setq cont t)
-      (while (and (ess-roxy-entry-p) cont)
-        (save-excursion
-          (end-of-line)
-          (setq end (point)))
-        (if (or (and (ess-roxy-in-header-p)
-                     (looking-at (concat ess-roxy-re " *$")))
-                (looking-at (concat ess-roxy-re " *[@].+")))
-            (progn
-              (forward-line -1)
-              (end-of-line)
-              (setq end (point))
-              (setq cont nil)))
-        (if cont (setq cont (= (forward-line 1) 0))))
-      end)))
-
-(defun ess-roxy-entry-p (&optional field)
-  "Non-nil if point is in a roxy entry.
-FIELD allows checking for a specific field with
-`ess-roxy-current-field'."
-  (and ess-roxy-mode
-       (save-excursion
-         (beginning-of-line)
-         (looking-at-p ess-roxy-re))
-       (or (null field)
-           (string= (ess-roxy-current-field) field))))
-
-(defun ess-roxy-narrow-to-field ()
-  "Go to to the start of current field."
-  (interactive)
-  (let ((beg (ess-roxy-beg-of-field))
-        (end (ess-roxy-end-of-field)))
-    (narrow-to-region beg end)))
-
-(defun ess-roxy-extract-field ()
-  (let ((field (buffer-substring (ess-roxy-beg-of-entry)
-                                 (ess-roxy-end-of-entry)))
-        (prefix-re (ess-roxy-guess-str))
-        (roxy-re ess-roxy-re))
-    (with-temp-buffer
-      (setq ess-roxy-re roxy-re)
-      (insert field)
-      (goto-char (point-min))
-      (while (re-search-forward prefix-re (point-max) 'noerror)
-        (replace-match ""))
-      (buffer-substring (point-min) (point-max)))))
-
-(defun ess-roxy-adaptive-fill-function ()
-  "Return prefix for filling paragraph or nil if not determined."
-  (when (ess-roxy-entry-p)
-    (let ((roxy-str (car (split-string (ess-roxy-guess-str) "'"))))
-      (if (ess-roxy-in-header-p)
-          (save-excursion
-            (ess-back-to-roxy)
-            (re-search-forward "\\([ \t]*\\)" (line-end-position) t)
-            (concat roxy-str "' " (match-string 1)))
-        (concat roxy-str "' " (make-string ess-indent-offset ? ))))))
-
-(defun ess-roxy-current-field ()
-  "Return the name of the field at point."
-  (and (not (ess-roxy-in-header-p))
-       (save-excursion
-         (goto-char (ess-roxy-beg-of-field))
-         (if (re-search-forward (concat ess-roxy-re
-                                        "[ \t]+@\\([[:alpha:]]+\\)")
-                                (line-end-position) t)
-             (match-string-no-properties 1)))))
-
-(defun ess-roxy-maybe-indent-line ()
-  "Indent line when point is in a field, but not in its first line."
-  (when (and (not (ess-roxy-in-header-p))
-             (not (equal (ess-roxy-current-field) "examples"))
-             (save-excursion
-               (beginning-of-line)
-               (let ((line-n (count-lines 1 (point))))
-                 (goto-char (ess-roxy-beg-of-field))
-                 (not (equal line-n (count-lines 1 (point)))))))
-    (ess-back-to-roxy)
-    (delete-region (point) (progn (skip-chars-forward " \t") (point)))
-    (insert (make-string ess-indent-offset ? ))))
-
-(defun ess-roxy-goto-func-def ()
-  "Put point at start of function.
-Go to the beginning of the current one or below the current
-roxygen entry, error otherwise"
-  (if (ess-roxy-entry-p)
-      (progn
-        (ess-roxy-goto-end-of-entry)
-        (forward-line 1)
-        (beginning-of-line))
-    (unless (looking-at-p ess-function-pattern)
-      (beginning-of-defun))))
-
-(defun ess-roxy-get-args-list-from-def ()
-  "Get args list for current function."
-  (save-excursion
-    (ess-roxy-goto-func-def)
-    (let ((args (ess-roxy-get-function-args)))
-      (mapcar (lambda (x) (cons x '(""))) args))))
-
-(defun ess-roxy-insert-args (args &optional here)
-  "Insert an ARGS list to the end of the current roxygen entry.
-If HERE is supplied start inputting `here'. Finish at end of
-line."
-  (let* ((roxy-str (ess-roxy-guess-str))
-         arg-des)
-    (if (and here (< 1 here))
-        (goto-char here)
-      (ess-roxy-goto-end-of-entry)
-      (beginning-of-line)
-      (when (not (looking-at-p "="))
-        (end-of-line)))
-    (while (stringp (caar args))
-      (setq arg-des (pop args))
-      (unless (string= (car arg-des) "")
-        (insert (concat "\n" roxy-str " @param " (car arg-des) " "))
-        (insert
-         (ess-replace-in-string (concat (car (cdr arg-des))) "\n"
-                                (concat "\n" roxy-str)))
-        (when ess-roxy-fill-param-p
-          (fill-paragraph))))))
-
-(defun ess-roxy-merge-args (fun ent)
-  "Take two args lists (alists) and return their union.
-The result holds all keys from both FUN and ENT but no duplicates and
-association from ent are preferred over entries from fun. Also,
-drop entries from ent that are not in fun and are associated with
-the empty string."
-  (let ((res-arg nil)
-        (arg-des))
-    (while (stringp (caar fun))
-      (setq arg-des (pop fun))
-      (if (assoc (car arg-des) ent)
-          (setq res-arg
-                (cons (cons (car arg-des) (cdr (assoc (car arg-des) ent))) res-arg))
-        (setq res-arg (cons (cons (car arg-des) '("")) res-arg))))
-    (while (stringp (caar ent))
-      (setq arg-des (pop ent))
-      (if (and (not (assoc (car arg-des) res-arg)) (not (string= (car (cdr arg-des)) "")))
-          (setq res-arg (cons (cons (car arg-des) (cdr arg-des)) res-arg))))
-    (nreverse res-arg)))
-
-(defun ess-roxy-update-entry ()
-  "Update the entry at point or the entry above the current function.
-Add a template empty roxygen documentation if no roxygen entry is
-available. The template can be customized via the variable
-`ess-roxy-template-alist'. The parameter descriptions can are
-filled if `ess-roxy-fill-param-p' is non-nil."
-  (interactive)
-  (unless (derived-mode-p 'ess-r-mode)
-    (user-error "%s mode not yet supported" major-mode))
-  (save-excursion
-    (let* ((args-fun (ess-roxy-get-args-list-from-def))
-           (args-ent (ess-roxy-get-args-list-from-entry))
-           (args (ess-roxy-merge-args args-fun args-ent))
-           (roxy-str (ess-roxy-guess-str))
-           (line-break "")
-           template tag-def)
-      (ess-roxy-goto-func-def)
-      (when (not (= (forward-line -1) 0))
-        (insert "\n")
-        (forward-line -1))
-      (when (and (not (looking-at "^\n")) (not (ess-roxy-entry-p)))
-        (end-of-line)
-        (insert "\n"))
-      (if (ess-roxy-entry-p)
-          (ess-roxy-insert-args args (1- (ess-roxy-delete-args)))
-        (setq template (copy-sequence ess-roxy-template-alist))
-        (while (stringp (caar template))
-          (setq tag-def (pop template))
-          (if (string= (car tag-def) "param")
-              (ess-roxy-insert-args args (point))
-            (if (string= (car tag-def) "description")
-                (insert (concat line-break roxy-str " "
-                                (cdr tag-def) "\n" roxy-str))
-              (if (string= (car tag-def) "details")
-                  (insert (concat line-break roxy-str " " (cdr tag-def)))
-                (insert (concat line-break roxy-str " @"
-                                (car tag-def) " " (cdr tag-def))))))
-          (setq line-break "\n"))))))
-
-(defun ess-roxy-goto-end-of-entry ()
-  "Put point at the bottom of the current entry or above the function at point.
-Return t if the point is left in a roxygen entry, otherwise nil.
-Error if point is not in function or roxygen entry."
-  (when (not (ess-roxy-entry-p))
-    (beginning-of-defun)
-    (forward-line -1))
-  (if (ess-roxy-entry-p)
-      (progn (goto-char (ess-roxy-end-of-entry))
-             t)
-    (forward-line)
-    nil)
-  (ess-roxy-entry-p))
-
-(defun ess-roxy-goto-beg-of-entry ()
-  "Put point at the top of the entry at point or above the function at point.
-Return t if the point is left in a roxygen
-entry, otherwise nil. Error if point is not in function or
-roxygen entry."
-  (if (not (ess-roxy-entry-p))
-      (progn
-        (goto-char (nth 0 (end-of-defun)))
-        (forward-line -1)))
-  (if (ess-roxy-entry-p)
-      (progn
-        (goto-char (ess-roxy-beg-of-entry))
-        t)
-    (forward-line) nil))
-
-(defun ess-roxy-delete-args ()
-  "Remove all args from the entry at point or above the function at point.
-Return 0 if no deletions were made other wise the point at where
-the last deletion ended"
-  (save-excursion
-    (let* ((cont t)
-           (field-beg 0)
-           entry-beg entry-end field-end)
-      (ess-roxy-goto-end-of-entry)
-      (setq entry-beg (ess-roxy-beg-of-entry))
-      (setq entry-end (ess-roxy-end-of-entry))
-      (goto-char entry-end)
-      (beginning-of-line)
-      (while (and (<= entry-beg (point)) (> entry-beg 0) cont)
-        (if (looking-at
-             (concat ess-roxy-re " *@param"))
-            (progn
-              (setq field-beg (ess-roxy-beg-of-field))
-              (setq field-end (ess-roxy-end-of-field))
-              (delete-region field-beg (+ field-end 1))))
-        (setq cont nil)
-        (if (= (forward-line -1) 0)
-            (setq cont t)))
-      field-beg)))
-
-(defun ess-roxy-get-args-list-from-entry ()
-  "Fill an args list from the entry above the function where the point is."
-  (save-excursion
-    (let* (args entry-beg field-beg field-end args-text arg-name desc)
-      (if (ess-roxy-goto-end-of-entry)
-          (progn
-            (setq roxy-str (ess-roxy-guess-str))
-            (beginning-of-line)
-            (setq entry-beg (ess-roxy-beg-of-entry))
-            (while (and (< entry-beg (point)) (> entry-beg 0))
-              (if (looking-at
-                   (concat ess-roxy-re " *@param"))
-                  (progn
-                    (setq field-beg (ess-roxy-beg-of-field))
-                    (setq field-end (ess-roxy-end-of-field))
-                    (setq args-text (buffer-substring-no-properties
-                                     field-beg field-end))
-                    (setq args-text
-                          (ess-replace-in-string args-text roxy-str ""))
-                    (setq args-text
-                          (ess-replace-in-string
-                           args-text "[[:space:]]*@param *" ""))
-                    ;; (setq args-text
-                    ;;    (ess-replace-in-string args-text "\n" ""))
-                    (string-match "[^[:space:]]*" args-text)
-                    (setq arg-name (match-string 0 args-text))
-                    (setq desc (replace-regexp-in-string
-                                (concat "^" (regexp-quote arg-name) " *") "" args-text))
-                    (setq args (cons (list (concat arg-name)
-                                           (concat desc))
-                                     args))))
-              (forward-line -1))
-            args)
-        nil))))
-
-(defun ess-roxy-toggle-roxy-region (beg end)
-  "Toggle prefix roxygen string from BEG to END.
-Add the prefix if missing, remove if found. BEG and END default
-to the region, if active, and otherwise the entire line. This is
-convenient for editing example fields."
-  (interactive "r")
-  (unless (and beg end)
-    (setq beg (line-beginning-position)
-          end (line-end-position)))
-  (ess-roxy-roxy-region beg end (ess-roxy-entry-p)))
-
-(defun ess-roxy-roxy-region (beg end &optional on)
-  (save-excursion
-    (let (RE to-string
-             (roxy-str (ess-roxy-guess-str)))
-      (narrow-to-region beg (- end 1))
-      (if on
-          (progn (setq RE (concat ess-roxy-re " +?"))
-                 (setq to-string ""))
-        (setq RE "^")
-        (setq to-string (concat roxy-str " ")))
-      (goto-char beg)
-      (while (re-search-forward RE (point-max) 'noerror)
-        (replace-match to-string))
-      (widen))))
-
-(defun ess-roxy-preview ()
-  "Generate documentation for roxygen entry at point.
-Use a connected R session (starting one if necessary) and
-`ess-roxy-package' to generate the Rd code for the entry at
-point. Place it in a buffer and return that buffer."
-  (unless (derived-mode-p 'ess-r-mode)
-    (user-error "Preview only supported in R buffers, try `ess-r-devtools-document-package' instead"))
-  (let* ((beg (ess-roxy-beg-of-entry))
-         (tmpf (make-temp-file "ess-roxy"))
-         (roxy-buf (get-buffer-create " *RoxygenPreview*"))
-         (R-old-roxy
-          (concat
-           "..results <- roxygen2:::roc_process(rd_roclet(), parse.files(P), \"\");"
-           "cat(vapply(..results, function(x) roxygen2:::rd_out_cache$compute(x, format(x)), character(1)), \"\\n\")" ))
-         (R-new-roxy
-          (concat
-           "..results <- roc_proc_text(rd_roclet(), readChar(P, file.info(P)$size));"
-           "cat(vapply(..results, format, character(1)), \"\\n\")" ))
-         (out-rd-roclet
-          (cond ((string= "roxygen" ess-roxy-package)
-                 "make.Rd2.roclet()$parse")
-                ;; must not line break strings to avoid getting +s in the output
-                ((string= "roxygen2" ess-roxy-package)
-                 (concat "(function(P) { if(packageVersion('roxygen2') < '3.0.0') {"
-                         R-old-roxy "} else {" R-new-roxy "} })"))
-                (t (error "Need to hard code the roclet output call for roxygen package '%s'"
-                          ess-roxy-package)))))
-    (when (= beg 0)
-      (error "Point is not in a Roxygen entry"))
-    (save-excursion
-      (goto-char (ess-roxy-end-of-entry))
-      (forward-line 1)
-      (if (end-of-defun)
-          (append-to-file beg (point) tmpf)
-        (while (and (forward-line 1)
-                    (not (looking-at-p "^$"))
-                    (not (eobp))
-                    (not (looking-at-p ess-roxy-re))))
-        (append-to-file beg (point) tmpf))
-      (inferior-ess-r-force)
-      (ess-force-buffer-current)
-      (unless (ess-boolean-command (concat "print(suppressWarnings(require(" ess-roxy-package
-                                           ", quietly=TRUE)))\n"))
-        (error (concat "Failed to load the " ess-roxy-package " package; "
-                       "in R, try  install.packages(\"" ess-roxy-package "\")")))
-      (ess-command (concat out-rd-roclet "(\"" tmpf "\")\n") roxy-buf)
-      (with-current-buffer roxy-buf
-        ;; Kill characters up to % in case we missed stripping prompts
-        ;; or +'s:
-        (goto-char (point-min))
-        (when (re-search-forward "%" (line-end-position) t)
-          (backward-char)
-          (delete-region (line-beginning-position) (point)))))
-    (delete-file tmpf)
-    roxy-buf))
-
-(defun ess-roxy-preview-HTML (&optional visit-instead-of-browse)
-  "Use a (possibly newly) connected R session and the roxygen package to
-generate a HTML page for the roxygen entry at point and open that
-buffer in a browser.  Visit the HTML file instead of showing it in
-a browser if `visit-instead-of-browse' is non-nil."
-  (interactive "P")
-  (let* ((roxy-buf (ess-roxy-preview))
-         (rd-tmp-file (make-temp-file "ess-roxy-" nil ".Rd"))
-         (html-tmp-file (make-temp-file "ess-roxy-" nil ".html"))
-         (rd-to-html (concat "Rd2HTML(\"" rd-tmp-file "\",\""
-                             html-tmp-file "\", stages=c(\"render\"))"))
-         )
-    (with-current-buffer roxy-buf
-      (set-visited-file-name rd-tmp-file)
-      (save-buffer)
-      (kill-buffer roxy-buf))
-    (ess-force-buffer-current)
-    (ess-command "print(suppressWarnings(require(tools, quietly=TRUE)))\n")
-    (if visit-instead-of-browse
-        (progn
-          (ess-command (concat rd-to-html "\n"))
-          (find-file html-tmp-file))
-      (ess-command (concat "browseURL(" rd-to-html ")\n")))))
-
-(defun ess-roxy-preview-text ()
-  "Use the connected R session and the roxygen package to
-generate the text help page of the roxygen entry at point."
-  (interactive)
-  (with-current-buffer (ess-roxy-preview)
-    (Rd-preview-help)))
-
-(defun ess-roxy-preview-Rd (&optional name-file)
-  "Preview Rd for the roxygen entry at point.
-Use the connected R session and the roxygen package to
-generate the Rd code for the roxygen entry at point. If called
-with a non-nil NAME-FILE (\\[universal-argument]),
-also set the visited file name of the created buffer to
-facilitate saving that file."
-  (interactive "P")
-  (let ((roxy-buf (ess-roxy-preview)))
-    (pop-to-buffer roxy-buf)
-    (if name-file
-        (save-excursion
-          (goto-char 1)
-          (search-forward-regexp "name{\\(.+\\)}")
-          (set-visited-file-name (concat (match-string 1) ".Rd"))))
-    (Rd-mode)
-    ;; why should the following be needed here? [[currently has no effect !!]]
-    ;; usually in a *.Rd file fontification happens automatically
-    (font-lock-ensure)))
-
-
-(defun ess-roxy-guess-str (&optional not-here)
-  "Guess the prefix used in the current roxygen block.
-If NOT-HERE is non-nil, guess the prefix for nearest roxygen
-block before the point."
-  (save-excursion
-    (if (ess-roxy-entry-p)
-        (progn
-          (goto-char (line-beginning-position))
-          (search-forward-regexp ess-roxy-re))
-      (if not-here
-          (search-backward-regexp ess-roxy-re)))
-    (if (or not-here (ess-roxy-entry-p))
-        (match-string 0)
-      (if (derived-mode-p 'ess-r-mode)
-          ess-roxy-str
-        (concat (string-trim comment-start) "'")))))
-
-(defun ess-roxy-hide-block ()
-  "Hide current roxygen comment block."
-  (interactive)
-  (save-excursion
-    (let ((end-of-entry (ess-roxy-end-of-entry))
-          (beg-of-entry (ess-roxy-beg-of-entry)))
-      (hs-hide-block-at-point nil (list beg-of-entry end-of-entry)))))
-
-(defun ess-roxy-toggle-hiding ()
-  "Toggle hiding/showing of a block.
-See `hs-show-block' and `ess-roxy-hide-block'."
-  (interactive)
-  (hs-life-goes-on
-   (if (hs-overlay-at (line-end-position))
-       (hs-show-block)
-     (ess-roxy-hide-block))))
-
-(defun ess-roxy-show-all ()
-  "Hide all Roxygen entries in current buffer."
-  (interactive)
-  (ess-roxy-hide-all t))
-
-(defun ess-roxy-hide-all (&optional show)
-  "Hide all Roxygen entries in current buffer."
-  (interactive)
-  (when (not ess-roxy-hide-show-p)
-    (user-error "First enable hide-show with `ess-roxy-hide-show-p'"))
-  (hs-life-goes-on
-   (save-excursion
-     (goto-char (point-min))
-     (while (re-search-forward (concat ess-roxy-re) (point-max) t 1)
-       (let ((end-of-entry (ess-roxy-end-of-entry)))
-         (if show
-             (hs-show-block)
-           (ess-roxy-hide-block))
-         (goto-char end-of-entry)
-         (forward-line 1))))))
-
-(defun ess-roxy-previous-entry ()
-  "Go to beginning of previous Roxygen entry."
-  (interactive)
-  (if (ess-roxy-entry-p)
-      (progn
-        (goto-char (ess-roxy-beg-of-entry))
-        (forward-line -1)))
-  (search-backward-regexp ess-roxy-re (point-min) t 1)
-  (goto-char (ess-roxy-beg-of-entry)))
-
-(defun ess-roxy-next-entry ()
-  "Go to beginning of next Roxygen entry."
-  (interactive)
-  (if (ess-roxy-entry-p)
-      (progn
-        (goto-char (ess-roxy-end-of-entry))
-        (forward-line 1)))
-  (search-forward-regexp ess-roxy-re (point-max) t 1)
-  (goto-char (ess-roxy-beg-of-entry)))
-
-(defun ess-roxy-get-function-args ()
-  "Return the arguments specified for the current function as a list of strings.
-Assumes point is at the beginning of the function."
-  (save-excursion
-    (let ((args-txt
-           (buffer-substring-no-properties
-            (progn
-              (search-forward-regexp "\\([=,-]+ *function *\\|^\s*function\\)" nil nil 1)
-              (+ (point) 1))
-            (progn
-              (ess-roxy-match-paren)
-              (point)))))
-      (setq args-txt (replace-regexp-in-string "#+[^\"']*\n" "" args-txt))
-      (setq args-txt (replace-regexp-in-string "([^)]+)" "" args-txt))
-      (setq args-txt (replace-regexp-in-string "=[^,]+" "" args-txt))
-      (setq args-txt (replace-regexp-in-string "[ \t\n]+" "" args-txt))
-      (split-string args-txt ","))))
-
-(defun ess-roxy-match-paren ()
-  "Go to the matching parenthesis."
-  (cond ((looking-at "\\s\(") (forward-list 1) (backward-char 1))
-        ((looking-at "\\s\)") (forward-char 1) (backward-list 1))))
-
-(defun ess-roxy-complete-tag ()
-  "Complete the tag at point."
-  (let ((bounds (ess-bounds-of-symbol)))
-    (when (and bounds
-               (save-excursion
-                 (goto-char (car bounds))
-                 (eq (following-char) ?@)))
-      (list (1+ (car bounds)) (cdr bounds)
-            (append ess-roxy-tags-noparam ess-roxy-tags-param)))))
-
-(defun ess-roxy-tag-completion ()
-  "Completion data for Emacs >= 24."
-  (when (save-excursion (re-search-backward "@\\<\\(\\w*\\)" (line-beginning-position) t))
-    (let ((beg (match-beginning 1))
-          (end (match-end 1)))
-      (when (and end (= end (point)))
-        (list beg end (append ess-roxy-tags-noparam ess-roxy-tags-param) :exclusive 'no)))))
-
-(defun ess-roxy-remove-roxy-re (string)
-  "Remove `ess-roxy-str' from STRING before sending to R process.
-Useful for sending code from example section. This function is
-placed in `ess-presend-filter-functions'."
-  ;; In the future we might want to detect chunks between markdown
-  ;; fences and strip everything that comes before `@examples`
-  (if (ess-roxy--all-prefixed string)
-      (replace-regexp-in-string (concat ess-roxy-re "\\s-*") "" string)
-    string))
-
-(defun ess-roxy--all-prefixed (string)
-  (let ((ess-roxy-re-lexical ess-roxy-re))
-    (with-temp-buffer
-      (insert string)
-      (goto-char 0)
-      (while (and (looking-at-p ess-roxy-re-lexical)
-                  (re-search-forward "\n" nil t)))
-      (looking-at-p ess-roxy-re-lexical))))
-
-(defun ess-roxy-find-par-end (stop-point &rest stoppers)
-  (mapc #'(lambda (stopper)
-            (when (and (> stop-point (point))
-                       (save-excursion
-                         (re-search-forward stopper stop-point t)))
-              (setq stop-point (match-beginning 0))))
-        stoppers)
-  (save-excursion
-    (goto-char stop-point)
-    (line-end-position 0)))
-
-\f
-;;*;; Advices
-(defmacro ess-roxy-with-filling-context (examples &rest body)
-  "Setup context (e.g. `comment-start') for filling roxygen BODY.
-EXAMPLES should be non-nil if filling an example block."
-  (declare (indent 2) (debug (&rest form)))
-  `(let ((comment-start (concat ess-roxy-re "[ \t]+#"))
-         (comment-start-skip (concat ess-roxy-re "[ \t]+# *"))
-         (comment-use-syntax nil)
-         (adaptive-fill-first-line-regexp (concat ess-roxy-re "[ \t]*"))
-         (paragraph-start (concat "\\(" ess-roxy-re "\\(" paragraph-start
-                                  "\\|[ \t]*@" "\\)" "\\)\\|\\(" paragraph-start "\\)"))
-         (temp-table (if ,examples
-                         (make-syntax-table ess-r-mode-syntax-table)
-                       Rd-mode-syntax-table)))
-     (when ,examples
-       ;; Prevent the roxy prefix to be interpreted as comment or string
-       ;; starter
-       (modify-syntax-entry ?# "w" temp-table)
-       (modify-syntax-entry ?' "w" temp-table))
-     ;; Neutralize (comment-normalize-vars) because it modifies the
-     ;; comment-start regexp in such a way that paragraph filling of
-     ;; comments in @examples fields does not work
-     (cl-letf (((symbol-function 'comment-normalize-vars) #'ignore))
-       (with-syntax-table temp-table
-         ,@body))))
-
-(defun ess-roxy-ess-indent-command (&optional whole-exp)
-  "Hide this block if we are at the beginning of the line.
-Else call `ess-indent-command'."
-  (interactive "P")
-  (if (and (bolp) (ess-roxy-entry-p) ess-roxy-hide-show-p)
-      (progn (ess-roxy-toggle-hiding))
-    (ess-indent-command whole-exp)))
-
-(defun ess--roxy-fill-block (fun &optional args)
-  "Fill a roxygen block.
-FUN should be a filling function and ARGS gets passed to it."
-  (let* ((saved-pos (point))
-         (par-start (save-excursion
-                      (if (save-excursion
-                            (and (backward-paragraph)
-                                 (forward-paragraph)
-                                 (<= (point) saved-pos)))
-                          (line-beginning-position)
-                        (progn (backward-paragraph) (point)))))
-         (par-end (ess-roxy-find-par-end
-                   (save-excursion
-                     (forward-paragraph)
-                     (point))
-                   (concat ess-roxy-re "[ \t]*@examples\\b") "^[^#]")))
-    ;; Refill the whole structural paragraph sequentially, field by
-    ;; field, stopping at @examples
-    (ess-roxy-with-filling-context nil
-        (save-excursion
-          (save-restriction
-            (narrow-to-region par-start par-end)
-            (goto-char (point-min))
-            (while (< (point) (point-max))
-              (ess-roxy-maybe-indent-line)
-              (apply fun args)
-              (forward-paragraph)))))))
-
-(defun ess-r--fill-paragraph (orig-fun &rest args)
-  "ESS fill paragraph for R mode.
-Overrides `fill-paragraph' which is ORIG-FUN when necessary and
-passes ARGS to it."
-  (cond
-   ;; Regular case
-   ((not (derived-mode-p 'ess-r-mode))
-    (apply orig-fun args))
-   ;; Filling of code comments in @examples roxy field
-   ((and (ess-roxy-entry-p)
-         (save-excursion
-           (ess-roxy-goto-end-of-roxy-comment)
-           (looking-at "#")))
-    (ess-roxy-with-filling-context t
-        (apply orig-fun args)))
-   ((and (not (ess-roxy-entry-p))
-         (ess-inside-comment-p))
-    (apply orig-fun args))
-   ;; Filling of call arguments with point on call name
-   ((and ess-fill-calls
-         (ess-inside-call-name-p))
-    (save-excursion
-      (skip-chars-forward "^([")
-      (forward-char)
-      (ess-fill-args)))
-   ;; Filling of continuations
-   ((and ess-fill-continuations
-         (ess-inside-continuation-p))
-    (ess-fill-continuations))
-   ;; Filling of call arguments
-   ((and ess-fill-calls
-         (ess-inside-call-p))
-    (ess-fill-args))
-   ;; Filling of roxy blocks
-   ((ess-roxy-entry-p)
-    (ess--roxy-fill-block orig-fun args))
-   (t
-    (apply orig-fun args))))
-(advice-add 'fill-paragraph :around #'ess-r--fill-paragraph)
-
-(defun ess-roxy-move-beginning-of-line (arg)
-  "Move point to the beginning of the current line or roxygen comment.
-If not in a roxygen comment, call `move-beginning-of-line', which
-see for ARG. If in a roxygen field, leave point at the end of a
-roxygen comment. If already there, move to the beginning of the
-line."
-  (interactive "^p")
-  (if (ess-roxy-entry-p)
-      (let ((pos (point)))
-        (ess-roxy-goto-end-of-roxy-comment)
-        (when (eql (point) pos)
-          (move-beginning-of-line nil)))
-    (move-beginning-of-line arg)))
-
-(defun ess-roxy-goto-end-of-roxy-comment ()
-  "Leave point at the end of a roxygen comment.
-If not in a roxygen entry, call `back-to-indentation'."
-  (interactive)
-  (if (ess-roxy-entry-p)
-      (progn
-        (end-of-line)
-        (re-search-backward (concat ess-roxy-re " *")
-                            (line-beginning-position) t)
-        (goto-char (match-end 0)))
-    (back-to-indentation)))
-
-(defun ess-roxy-indent-new-comment-line ()
-  (if (not (ess-roxy-entry-p))
-      (indent-new-comment-line)
-    (ess-roxy-indent-on-newline)))
-
-(define-obsolete-function-alias 'ess-roxy-newline-and-indent
-  #'ess-roxy-newline "ESS 19.04")
-(defun ess-roxy-newline ()
-  "Start a newline and insert the roxygen prefix.
-Only do this if in a roxygen block and
-`ess-roxy-insert-prefix-on-newline' is non-nil."
-  (interactive)
-  (if (and (ess-roxy-entry-p)
-           ess-roxy-insert-prefix-on-newline)
-      (ess-roxy-indent-on-newline)
-    (newline nil t)))
-
-(defun ess-roxy-indent-on-newline ()
-  "Insert a newline in a roxygen field."
-  (cond
-   ;; Point at beginning of first line of entry; do nothing
-   ((= (point) (ess-roxy-beg-of-entry))
-    (newline-and-indent))
-   ;; Otherwise: skip over roxy comment string if necessary and then
-   ;; newline and then inset new roxy comment string
-   (t
-    (let ((point-after-roxy-string
-           (save-excursion (forward-line 0)
-                           (ess-back-to-roxy)
-                           (point))))
-      (goto-char (max (point) point-after-roxy-string)))
-    (newline-and-indent)
-    (insert (concat (ess-roxy-guess-str t) " ")))))
-
-(defun ess-roxy-cpp-fill-paragraph (&rest _args)
-  "Advice for `c-fill-paragraph' that accounts for roxygen comments."
-  (cond
-   ;; Fill roxy @example's.
-   ((ess-roxy-entry-p "examples")
-    (ess--roxy-fill-block 'fill-paragraph) nil)
-   ;; Fill roxy entries.
-   ((ess-roxy-entry-p)
-    (ess--roxy-fill-block 'fill-paragraph) nil)
-   ;; Return t to signal to go on to `c-fill-paragraph'.
-   (t t)))
-
-(advice-add 'c-fill-paragraph :before-while #'ess-roxy-cpp-fill-paragraph)
-
-(defun ess-roxy-enable-in-cpp ()
-  "Enable `ess-roxy-mode' in C++ buffers in R packages."
-  (when (and (fboundp 'ess-r-package-project)
-             (ess-r-package-project))
-    (ess-roxy-mode)))
-
-(with-eval-after-load "cc-mode"
-  (add-hook 'c++-mode-hook #'ess-roxy-enable-in-cpp))
-
-(defun ess-roxy--region-p (beg end)
-  (when ess-roxy-re
-    (save-excursion
-      (goto-char beg)
-      (catch 'ess-r-not-roxy
-        (while (< (point) end)
-          (unless (looking-at-p ess-roxy-re)
-            (throw 'ess-r-not-roxy nil))
-          (forward-line))
-        t))))
-
-(provide 'ess-roxy)
-
-;;; ess-roxy.el ends here
diff --git a/elpa/ess-20251212.937/ess-s-lang.el b/elpa/ess-20251212.937/ess-s-lang.el
deleted file mode 100644 (file)
index c02f960..0000000
+++ /dev/null
@@ -1,526 +0,0 @@
-;;; ess-s-lang.el --- Support for editing S source code  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1989-2022 Free Software Foundation, Inc.
-;; Author: A.J. Rossini <rossiniNOSPAMbiostat.washington.edu>
-;; Created: 26 Aug 1997
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; Code for general editing S source code (specializes to S, S+, R).
-
-;;; Code:
-
-(require 'ess-mode)
-(require 'ess-help)
-(require 'ess-inf)
-
-(declare-function speedbar-add-supported-extension "speedbar" (extension))
-
-\f ; Configuration variables
-
-(defvar S-syntax-table
-  (let ((S-syntax-table (make-syntax-table)))
-    (modify-syntax-entry ?\\ "\\" S-syntax-table)
-    (modify-syntax-entry ?+  "."  S-syntax-table)
-    (modify-syntax-entry ?-  "."  S-syntax-table)
-    (modify-syntax-entry ?=  "."  S-syntax-table)
-    (modify-syntax-entry ?%  "."  S-syntax-table)
-    (modify-syntax-entry ?<  "."  S-syntax-table)
-    (modify-syntax-entry ?>  "."  S-syntax-table)
-    (modify-syntax-entry ?&  "."  S-syntax-table)
-    (modify-syntax-entry ?|  "."  S-syntax-table)
-    (modify-syntax-entry ?\' "\"" S-syntax-table)
-    (modify-syntax-entry ?\" "\"" S-syntax-table)
-    (modify-syntax-entry ?#  "<"  S-syntax-table) ; open comment
-    (modify-syntax-entry ?\n ">"  S-syntax-table) ; close comment
-    ;;(modify-syntax-entry ?.  "w"  S-syntax-table) ; "." used in S obj names
-    (modify-syntax-entry ?.  "_"  S-syntax-table) ; see above/below,
-                                        ; plus consider separation.
-    (modify-syntax-entry ?$  "_"  S-syntax-table); foo$comp = 1 symbol(completion)
-    (modify-syntax-entry ?@  "_"  S-syntax-table); foo@slot = 1 symbol(completion)
-    (modify-syntax-entry ?_  "_"  S-syntax-table)
-    (modify-syntax-entry ?:  "_"  S-syntax-table)
-    (modify-syntax-entry ?*  "."  S-syntax-table)
-    (modify-syntax-entry ?<  "."  S-syntax-table)
-    (modify-syntax-entry ?>  "."  S-syntax-table)
-    (modify-syntax-entry ?/  "."  S-syntax-table)
-    S-syntax-table)
-  "Syntax table for S code."
-  )
-
-(defvar S-editing-alist
-  '((paragraph-start              . (concat "\\s-*$\\|" page-delimiter))
-    (paragraph-separate           . (concat "\\s-*$\\|" page-delimiter))
-    (paragraph-ignore-fill-prefix . t)
-    ;;(comment-indent-function  . 'S-comment-indent)
-    ;;(ess-comment-indent           . 'S-comment-indent)
-    ;;(ess-calculate-indent           . 'ess-calculate-indent)
-    ;;(ess-keep-dump-files          . 'ask)
-    ;; For Changelog add, require ' ' before <- : "attr<-" is a function name :
-    (add-log-current-defun-header-regexp . "^\\(.+\\)\\s-+<-[ \t\n]*function"))
-  "General options for S and S+ source files.")
-
-(defvar inferior-S-language-start
-  '(concat "options("
-           "STERM='"    ess-STERM  "'"
-           ", str.dendrogram.last=\"'\""
-           (if ess-editor (concat ", editor='" ess-editor "'"))
-           (if ess-pager  (concat ", pager='"  ess-pager  "', help.pager='"  ess-pager  "'"))
-           ", show.error.locations=TRUE"
-           ")")
-  "S language expression for startup -- default for all S dialects.")
-
-(defconst S-common-cust-alist
-  '((ess-language                  . "S")
-    (inferior-ess-exit-command     . "q()\n")
-    (inferior-ess-language-start   . (eval inferior-S-language-start))
-    (comint-use-prompt-regexp      . t)  ;;use fields if nil
-    (comint-process-echoes        . t)
-    ;; these prompt are the same for all S-languages As long as custom prompt
-    ;; ends in inferior-ess-primary-prompt everything should work as expected.
-    (inferior-ess-primary-prompt   . "> ")
-    ;; (inferior-ess-secondary-prompt . "[+:] ") ;; catch Selection: and alike
-    (inferior-ess-secondary-prompt . "+ ") ;; catch Selection: and alike
-    (comment-start                . "#")
-    (comment-add                  . 1)
-    (comment-start-skip           . "#+ *")
-    (comment-use-syntax           . t)  ; see log for bug report 2013-06-07
-    (comment-column               . 40)
-    (ess-no-skip-regexp           . (concat "^ *@\\|" (default-value 'ess-no-skip-regexp)))
-    ;; inferior-ess-prompt is used by comint for navigation, only if
-    ;; comint-use-prompt-regexp is t; (transcript-mode also relies on this regexp)
-    (inferior-ess-prompt           . inferior-S-prompt)
-    (ess-getwd-command          . "getwd()\n")
-    (ess-setwd-command          . "setwd('%s')\n")
-    (ess-funargs-command        . ".ess_funargs(\"%s\")\n")
-    (fill-nobreak-predicate     . 'ess-inside-string-p)
-    (ess-execute-screen-options-command . "options(width=%d, length=99999)\n")
-    (font-lock-defaults           . '(ess-build-font-lock-keywords
-                                      nil nil ((?\. . "w") (?\_ . "w")))))
-  "S-language common settings for all <dialect>-customize-alist.")
-
-(defconst S+common-cust-alist
-  (append
-   '((ess-suffix                . "S")
-     (ess-help-sec-regex        . ess-help-S+-sec-regex)
-     (ess-help-sec-keys-alist   . ess-help-S+sec-keys-alist)
-     (ess-change-sp-regexp      . ess-S+-change-sp-regexp)
-     (ess-function-pattern      . ess-s-function-pattern)
-     (ess-function-template     . " <- \n#\nfunction()\n{\n\n}\n")
-     (ess-dump-filename-template . (replace-regexp-in-string
-                                    "S$" ess-suffix ; in the one from custom:
-                                    ess-dump-filename-template-proto))
-     (ess-traceback-command     . "traceback()\n")
-     (ess-mode-editing-alist    . S-editing-alist)
-
-     (ess-dumped-missing-re
-      . "\\(\\(<-\\|=\\)\nDumped\n\\'\\)\\|\\(\\(<-\\|=\\)\\(\\s \\|\n\\)*\\'\\)")
-     (ess-syntax-error-re
-      . "\\(Syntax error: .*\\) at line \\([0-9]*\\), file \\(.*\\)$")
-     (inferior-ess-objects-command  . inferior-Splus-objects-command)
-     (ess-describe-object-at-point-commands . 'ess-S-describe-object-at-point-commands)
-     (ess-editor . S-editor)
-     (ess-pager  . S-pager))
-   S-common-cust-alist)
-  "Common settings for all S+<*>-customize-alist."
-  )
-
-;;; Changes from S to S-PLUS 3.x.  (standard S3 should be in ess-s-lang!).
-
-(defconst ess-help-S+sec-keys-alist
-  '((?a . "ARGUMENTS:")
-    (?b . "BACKGROUND:")
-    (?B . "BUGS:")
-    (?d . "DESCRIPTION:")
-    (?D . "DETAILS:")
-    (?e . "EXAMPLES:")
-    (?n . "NOTE:")
-    (?O . "OPTIONAL ARGUMENTS:")
-    (?R . "REQUIRED ARGUMENTS:")
-    (?r . "REFERENCES:")
-    (?s . "SEE ALSO:")
-    (?S . "SIDE EFFECTS:")
-    (?u . "USAGE:")
-    (?v . "VALUE:"))
-  "Alist of (key . string) pairs for use in section searching.")
-;;; `key' indicates the keystroke to use to search for the section heading
-;;; `string' in an S help file. `string' is used as part of a
-;;; regexp-search, and so specials should be quoted.
-
-;; S ver.3 (NOT S-Plus)
-(defconst ess-help-S3-sec-keys-alist
-  '((?a . "ARGUMENTS:")
-    (?b . "BACKGROUND:")
-    (?B . "BUGS:")
-    (?d . "DESCRIPTION:")
-    (?D . "DETAILS:")
-    (?e . "EXAMPLES:")
-    (?n . "NOTE:")
-    (?r . "REFERENCES:")
-    (?s . "SEE ALSO:")
-    (?S . "SIDE EFFECTS:")
-    (?u . "USAGE:")
-    (?v . "VALUE:"))
-  "Help section keys for S ver.3.")
-
-;; S ver.4 (NOT S-Plus)
-(defconst ess-help-S4-sec-keys-alist
-  '((?a . "ARGUMENTS:")
-    (?b . "BACKGROUND:")
-    (?B . "BUGS:")
-    (?d . "DESCRIPTION:")
-    (?D . "DETAILS:")
-    (?e . "EXAMPLES:")
-    (?n . "NOTE:")
-    (?r . "REFERENCES:")
-    (?s . "SEE ALSO:")
-    (?S . "SIDE EFFECTS:")
-    (?u . "USAGE:")
-    (?v . "VALUE:"))
-  "Help section keys for S4.")
-
-
-(defconst ess-help-S+-sec-regex "^[A-Z.]+:$"
-  "Reg(ular) Ex(pression) of section headers in help file.")
-
-\f ; Function Definitions
-
-(defun S-comment-indent ()
-  "Indentation for S comments."
-  (if (or (looking-at "###")
-          (and (looking-at "#!") (= 1 (line-number-at-pos))))
-      (current-column)
-    (if (looking-at "##")
-        (let ((tem (when ;; FIXME ess-calculate-indent is R specific
-                       (fboundp 'ess-calculate-indent)
-                     (ess-calculate-indent))))
-          (if (listp tem) (car tem) tem))
-      (skip-chars-backward " \t")
-      (max (if (bolp) 0 (1+ (current-column)))
-           comment-column))))
-
-;;*;; S/R  Pretty-Editing
-
-(defun ess-fix-comments (&optional dont-query verbose)
-  "Fix buffer so that single-line comments start with at least '##',
-and ensure space before subsequent text."
-  (interactive "P")
-  (ess-replace-regexp-dump-to-src "#\\([A-Za-z0-9]\\)" "# \\1" nil verbose)
-  (ess-replace-regexp-dump-to-src "^\\([ \t]*#\\)\\([^#]\\)"
-                                  "\\1#\\2" dont-query verbose))
-
-(defun ess-dump-to-src (&optional dont-query verbose)
-  "Make the change in an S - dump() file to improve human readability.
-Optional arguments DONT-QUERY and VERBOSE are passed to
-`ess-replace-regexp-dump-to-src'."
-  (interactive "P")
-  (ess-replace-regexp-dump-to-src  "^\"\\([a-z.][a-z.0-9]*\\)\" *<-\n"
-                                   "\n\\1 <- "
-                                   dont-query verbose))
-
-(defun ess-num-var-round (&optional dont-query verbose)
-  "Round endings like 000000 and 99999.
-Optional argument DONT-QUERY means do not query.
-Optional argument VERBOSE gives more verbose output."
-  (interactive "P")
-  (save-excursion
-    (goto-char (point-min))
-    (let ((num 0)
-          (str "")
-          (rgxp "000000+[1-9]?[1-9]?\\>")
-          (to   ""))
-      (if dont-query
-          (ess-rep-regexp     rgxp to nil nil verbose)
-        (query-replace-regexp rgxp to nil))
-      (while (< num 9)
-        (setq str (concat (int-to-string num) "999999+[0-8]*"))
-        (if (and (numberp verbose) (> verbose 1))
-            (message (format "\nregexp: '%s'" str)))
-        (goto-char (point-min))
-        (ess-rep-regexp str (int-to-string (1+ num))
-                        'fixedcase 'literal verbose)
-        (setq num (1+ num))))))
-
-(defun ess-fix-dot (before-chars &optional dont-query verbose)
-  "Remove trailing decimal '.' (\"dot\"), before BEFORE-CHARS.
-Optional argument DONT-QUERY and VERBOSE get passed to
-`ess-replace-regexp-dump-to-src'."
-  ;; typically, before-chars =  "]:" or more
-  (ess-replace-regexp-dump-to-src
-   (concat "\\([0-9]\\)\\.\\( *[" before-chars "]\\)")
-   ;;           111      ^
-   "\\1\\2" dont-query verbose))
-
-(defun ess-fix-dot-1 (&optional do-query verbose)
-  "Remove trailing decimal '.' (\"dot\"), before ':' or ']', i.e.,
-in cases where it's ugly and nonsense.  DO-QUERY(prefix) asks before replacing."
-  (interactive "P")
-  (ess-fix-dot "]:" (not do-query) verbose))
-
-(defun ess-fix-dot-more (&optional dont-query verbose)
-  "Remove trailing decimal '.' (\"dot\", typically from S+) in more cases
-than `ess-fix-dot-1'."
-  (interactive "P")
-  (ess-fix-dot-1 nil verbose)
-  (ess-fix-dot ",)" dont-query verbose))
-
-(defun ess-fix-EQ-assign (&optional dont-query verbose not-all)
-  "Replace \"=\" by \"<-\" in places where it `might make sense', e.g.,
-for function assignments and lines not ending in \",\".
-Be *careful* for list()s of functions and when argument not-all is
-nil (as by default) !"
-  ;;TODO: "in the few places we can be very sure.."
-  ;;---- is hard in general: local functions: ok; but functions in
-  ;;  list(a = function(x) abs(x), b= function(y) bound(y))  *NOT* ok!
-  (interactive "P")
-  (ess-replace-regexp-dump-to-src
-   "^\\( *[a-z.][_a-z.0-9]*\\) *= *\\(function *(\\)"
-   "\\1 <- \\2" dont-query verbose)
-  (unless not-all
-    ;; "too" aggressive {proposing to replace function argument specs}:
-    (ess-replace-regexp-dump-to-src ;; all those *not* ending in ","
-     ;; including  Mat[ i, ] = ...,
-     ;; but not `names(x) = "..."' for that is "confused" with plot(x=x,..)
-     "^\\( *[a-z.][][, \"_a-z.0-9]*\\) *= *\\([a-z.0-9({]\\(.*[^,]\\)? *$\\)"
-     "\\1 <- \\2" nil ;; always query - often has many "false positives"
-     verbose)))
-
-;;; All of the above three :
-(defun ess-MM-fix-src (&optional dont-query verbose)
-  "Clean up ess-source code which has been produced by dump(..), and other
-code typically produced by other tools.  Produces more readable code,
-and one that is well formatted in Emacs ess-mode."
-  (interactive "P")
-  ;; each of the following does a save-excursion:
-  (ess-dump-to-src dont-query)
-  (ess-fix-comments dont-query)
-  (ess-num-var-round dont-query verbose)
-  (ess-fix-dot-more dont-query verbose)
-  (ess-fix-EQ-assign dont-query verbose 'not-all))
-
-(defun ess-fix-miscellaneous (&optional from verbose)
-  "Fix Miscellaneous S/R `ill-formation's from current \\[point].
-Particularly use \"<-\"and put spaces around operators."
-  (interactive "d\nP"); Defaults: point and prefix (C-u)
-  ;; activate by (setq ess-verbose t)
-  (ess-if-verbose-write
-   (format "ess-fix-misc begin (from = %s, verbose = %s)\n" from verbose))
-  (save-excursion
-
-    (when (and (string= ess-dialect "R")
-               (fboundp 'ess-r-fix-T-F))
-      (ess-r-fix-T-F from (not verbose)))
-
-    ;; activate by (setq ess-verbose t)
-    (ess-if-verbose-write "ess-fix-misc: after fix-T-F\n");___D___
-
-    ;; former C and matlab programmers leave trailing  ";" :
-    ;; (goto-char from) (ess-rep-regexp "; *$" "" nil 'literal verbose)
-    ;; (ess-if-verbose-write "ess-fix-misc: after trailing ';'\n");___D___
-    (goto-char from) (ess-rep-regexp ";\\( *\\)#" "\\1#" nil nil verbose)
-    (ess-if-verbose-write "ess-fix-misc: after ';' before #\n");___D___
-
-    ;;from R 1.9.x "_" is valid in names; here assume no initial / trailing '_'
-    ;; BUG: The following changes "beta_ " or " _abc"
-    ;; (goto-char from) (ess-rep-regexp " +_ *" " <- " nil 'literal verbose)
-    ;; (goto-char from) (ess-rep-regexp   "_ +" " <- " nil 'literal verbose)
-
-    (ess-if-verbose-write "ess-fix-misc: before 'around \"<-\"' :\n");___D___
-    ;; ensure space around  "<-"  ---- but only replace if necessary:
-    (goto-char from)
-    (ess-rep-regexp "\\([^< \t\n]\\)\\(<<?-\\)" "\\1 \\2" nil nil verbose)
-    (goto-char from)(ess-rep-regexp "<-\\([^ \t\n]\\)" "<- \\1" nil nil verbose)
-    ;; ensure space around  "<" (not in "<-","<=","<<-")  and ">" (not ">=") :
-    (goto-char from);; --> " <", care with "->":
-    (ess-rep-regexp "\\([^-< \t\n]\\)\\([<>]\\)" "\\1 \\2" nil nil verbose)
-    ;; ">" -> "> " , for "<", don't split "<-" nor "<<-":
-    (goto-char from)
-    (ess-rep-regexp "\\(>=?\\)\\([^= \t\n]\\)" "\\1 \\2" nil nil verbose)
-    (goto-char from)
-    (ess-rep-regexp "\\(<=?\\)\\([^-<= \t\n]\\)" "\\1 \\2" nil nil t)
-
-    (ess-if-verbose-write "ess-fix-misc: before \"=\" \"==\" .. :\n");___D___
-    ;; -- ensure space around "=", "==", "!=" :
-    (goto-char from) ;; --> " ="
-    (ess-rep-regexp "\\([^=!<> ]\\)\\([=!]?\\)=" "\\1 \\2=" nil nil verbose)
-    (goto-char from) (ess-rep-regexp "=\\([^= ]\\)" "= \\1" nil nil verbose)
-
-    (goto-char from) ;; add a space between "{" and surrounding ..char:
-    (ess-rep-regexp "{\\([.A-Za-z()]\\)" "{ \\1" 'fix nil verbose)
-    (ess-rep-regexp "\\([()]\\){" "\\1 {" 'fix nil verbose)
-    (goto-char from) ;; add a space between "}" and a preceding wordchar:
-    (ess-rep-regexp "\\([A-Za-z0-9()]\\)}" "\\1 }" 'fix nil verbose)
-    (ess-space-around "else" from verbose)
-
-    (ess-if-verbose-write "ess-fix-misc: after \"{ ... }\" :\n");___D___
-    (goto-char from) ;; add a space inside "){"
-    (ess-rep-regexp "){" ") {" 'fix nil verbose)
-
-    ;; add a newline and indent before a "}"
-    ;; --- IFF there's NO "{" or "#" AND some NON-white text on the same line:
-    ;;D (if verbose (message "\t R-fix-misc..: Hard.. '}'"))
-    (goto-char from)
-    (ess-rep-regexp "^\\([^#{\n]*[^#{ \t\n]+[ \t]*\\)}[ \t]*$"
-                    "\\1\n}" 'fix nil verbose)
-    (ess-if-verbose-write "ess-fix-misc __end__\n");___D___
-    ))
-
-(defun ess-cycle-assign ()
-  "Cycle between assignment symbols in `ess-assign-list'.
-On consecutive calls, replace the assignment symbol before point
-with the next symbol from that list. This function sets the last
-keypress to repeat it, so if it is bound to \"C-c C-=\" pressing
-\"=\" again cycles to the next assignment."
-  (interactive)
-  (if (eq last-command this-command)
-      (let ((slist ess-assign-list)
-            str)
-        ;; The or statements in the setq allow cycling past the end of
-        ;; ess-assign-list.
-        (while (and (setq str (or (car slist) (car ess-assign-list))
-                          slist (or (cdr slist) ess-assign-list))
-                    (not (and (re-search-backward str
-                                                  (- (point) (length str)) t)
-                              (not (replace-match (car slist))))))))
-    (delete-horizontal-space)
-    (insert (car ess-assign-list)))
-  (set-transient-map
-   (let ((map (make-sparse-keymap))
-         (key (format "%c" (event-basic-type last-input-event))))
-     (define-key map (kbd key) #'ess-cycle-assign)
-     map)))
-
-(defun ess-insert-assign (arg)
-  "Insert the first element of `ess-assign-list' unless in string or comment.
-If the character before point is the first element of
-`ess-assign-list', replace it with the last character typed.
-
-If `ess-language' is not \"S\", call `self-insert-command' with ARG."
-  (interactive "p")
-  (if (string= ess-language "S")
-      (let* ((assign (car ess-assign-list))
-             (event (event-basic-type last-input-event))
-             (char (ignore-errors (format "%c" event))))
-        (cond ((and char (ess-inside-string-or-comment-p))
-               (insert char))
-              ((re-search-backward assign (- (point) (length assign)) t)
-               (if (and char (numberp event))
-                   (replace-match char t t)
-                 (replace-match "")))
-              (t (delete-horizontal-space) 
-                 (insert assign))))
-    (funcall #'self-insert-command arg)))
-
-;; In case people had this in their config don't cause errors:
-(define-obsolete-function-alias 'ess-smart-S-assign #'ess-insert-assign "ESS 18.10")
-(define-obsolete-function-alias 'ess-disable-smart-S-assign #'ignore "ESS 18.10")
-
-(defun ess-add-MM-keys ()
-  "Define MM's user keys."
-  (declare (obsolete "Setup your own keybindings." "ESS 19.04"))
-  (define-key inferior-ess-mode-map "\C-cw" #'ess-execute-screen-options)
-  (define-key ess-mode-map          [?\M--] #'ess-insert-assign)
-  (define-key inferior-ess-mode-map [?\M--] #'ess-insert-assign))
-
-(defun ess-dump-args-and-go (Sfunc)
-  "Dump the function name, with arguments, to a buffer for editing.
-
-Currently, this needs to:
-   1. set the buffer to the right mode, with the right settings
-   2. format the statement,
-   3. c/function/Sfunc/
-and I need to relearn Emacs lisp (but I had to, anyway."
-  (declare (obsolete 'ess-execute "ESS 19.04"))
-  (interactive "sFunction ? ")
-  (let* ((buffname "ess-complete.R"))
-    (ess-execute (format "args(%s)" Sfunc) t buffname)
-    (pop-to-buffer (concat "*" buffname "*"))
-    (while (search-forward "function" nil t)
-      (replace-match Sfunc nil t))
-    (when (fboundp 'ess-r-mode)
-      (ess-r-mode))))
-
-;;; S imenu support
-
-;; don't use syntax classes, bad for etags
-(defvar ess-imenu-S-generic-expression
-  '(("Functions" "^\\([^ \t\n]+\\)[ \t\n]*\\(?:<-\\|=\\)[ \t\n]*function[ ]*(" 1)
-    ("Classes" "^.*setClass(\\(.*\\)," 1)
-    ("Coercions" "^.*setAs(\\([^,]+,[^,]*\\)," 1) ; show from and to
-    ("Generics" "^.*setGeneric(\\([^,]*\\)," 1)
-    ("Methods" "^.*set\\(Group\\|Replace\\)?Method(\\([^,]+,[^,]*\\)" 2)
-    ("Package" "^.*\\(library\\|require\\)(\\([^)]*\\)" 2)
-    ("Data" "^\\(.+\\)[ \t\n]-*\\(?:<-\\|=\\)[ \t\n]*\\(read\\|.*data\\.frame\\).*(" 1))
-  "Imenu generic expression for S modes.
-See `imenu-generic-expression'.")
-
-(defun ess-imenu-S (&optional _arg)
-  "S Language Imenu support for ESS.
-ARG is ignored."
-  (declare (obsolete "It is set automatically in major modes" "ESS 19.04"))
-  (imenu-add-to-menubar "Imenu-S"))
-
-
-\f ;;; Speedbar stuff.
-
-(eval-after-load "speedbar"
-  '(progn
-     (speedbar-add-supported-extension ".R")
-     (speedbar-add-supported-extension ".S")
-     (speedbar-add-supported-extension ".s")
-     (speedbar-add-supported-extension ".q")))
-
-(cl-defmethod ess-help-get-topics (proc &context (ess-dialect "R"))
-  "Return a list of current S help topics associated with process PROC.
-If `sp-for-help-changed?' process variable is non-nil or
-`ess-help-topics-list' is nil, (re)-populate the latter and
-return it.  Otherwise, return `ess-help-topics-list'."
-  (with-ess-process-buffer nil
-    (cond
-     ;; (Re)generate the list of topics
-     ((or (not ess-help-topics-list)
-          (ess-process-get 'sp-for-help-changed?))
-      (ess-process-put 'sp-for-help-changed? nil)
-      (setq ess-help-topics-list
-            (delete-dups
-             (append (ess-get-object-list proc 'exclude-1st)
-                     (ess-get-help-files-list)
-                     (ess-get-help-aliases-list)))))
-     (t
-      ess-help-topics-list))))
-
-(cl-defmethod ess-help--reset-cache-override (&context (ess-dialect "R"))
-  (ess-command ".ess.getHelpAliases(reset = TRUE)\n"
-               nil nil nil nil nil nil ess-help--aliases-timeout))
-
-(define-obsolete-function-alias 'ess-toggle-S-assign-key #'ignore "ESS 18.10")
-(define-obsolete-function-alias 'ess-smart-underscore #'ess-insert-assign "ESS 18.10")
-(define-obsolete-function-alias 'ess-insert-S-assign #'ess-insert-assign "ESS 18.10")
-
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.[Ss]t\\'" . S-transcript-mode))
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.Sout\\'" . S-transcript-mode))
-
-(provide 'ess-s-lang)
-
-;;; ess-s-lang.el ends here
diff --git a/elpa/ess-20251212.937/ess-sas-a.el b/elpa/ess-20251212.937/ess-sas-a.el
deleted file mode 100644 (file)
index 2ae5a19..0000000
+++ /dev/null
@@ -1,1443 +0,0 @@
-;;; ess-sas-a.el --- clean-room implementation of many SAS-mode features  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1997-2022 Free Software Foundation, Inc.
-;; Author: Rodney A. Sparapani
-;; Maintainer: ESS-coreNOSPAMr-project.org
-;; Created: 17 November 1999
-;; Keywords: languages
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Code:
-
-(require 'ess-mode)
-(require 'ess-utils)
-;; 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]?\\|[pP][nN][gG]\\)"
-  "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-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"))))
-
-  "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)))
-
-;; whether the image libraries are configured is what is important here
-        (if (and (string-match "JPEG" system-configuration-features)
-                 (string-match "[.][jJ][pP][eE]?[gG]" ess-tmp-graph))
-            (find-file ess-tmp-graph)
-         (if (and (string-match "PNG" system-configuration-features)
-                  (string-match "[.][pP][nN][gG]" ess-tmp-graph))
-             (find-file ess-tmp-graph)
-        ;; ;;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="
-                        "\\|NOTE: Import cancelled.  Output dataset .* already exists."
-                       "\\|NOTE: Export cancelled.  Output file"
-                        "\\|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-revert-wisely)
-  (set-visited-file-name (concat (buffer-name) ".rtf"))
-  (when 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"))
-  (when 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\\|\f\\|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)
-  (when arg
-    ;; TODO: Why is this set up this way?
-    (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)))
-
-(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 receive: " 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 receive: " 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
diff --git a/elpa/ess-20251212.937/ess-sas-d.el b/elpa/ess-20251212.937/ess-sas-d.el
deleted file mode 100644 (file)
index 5cf147b..0000000
+++ /dev/null
@@ -1,332 +0,0 @@
-;;; ess-sas-d.el --- SAS customization  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1997-2022 Free Software Foundation, Inc.
-;; Author: Richard M. Heiberger <rmhNOSPAMtemple.edu>
-;; Created: 20 Aug 1997
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; This file defines all the SAS customizations for ESS behaviors.  See
-;; ess-sas-l and ess-sas-a for the underlying general modifications.
-
-;;; Code:
-
-(require 'shell)
-(require 'ess-sas-l)
-
-(defcustom SAS-mode-hook nil
-  "Hook to run when entering SAS mode."
-  :type 'hook
-  :group 'ess-sas)
-
-(defvar inferior-SAS-args "-stdio -linesize 80 -noovp -nosyntaxcheck"
-  "Arguments to use for starting SAS.")
-
-(defvar inferior-SAS-args-temp nil
-  "Hack variable, needed for args preprocessing.
-Better logic needed!  (see 2 uses, in this file).")
-
-(defvar SAS-mode-syntax-table
-  (let ((tab (make-syntax-table)))
-    (modify-syntax-entry ?\\ "."  tab)  ;; backslash is punctuation
-    (modify-syntax-entry ?+  "."  tab)
-    (modify-syntax-entry ?-  "."  tab)
-    (modify-syntax-entry ?=  "."  tab)
-    (modify-syntax-entry ?%  "w"  tab)
-    (modify-syntax-entry ?<  "."  tab)
-    (modify-syntax-entry ?>  "."  tab)
-    (modify-syntax-entry ?&  "w"  tab)
-    (modify-syntax-entry ?|  "."  tab)
-    (modify-syntax-entry ?\' "\"" tab)
-    (modify-syntax-entry ?*  ". 23"  tab) ; comment character
-    (modify-syntax-entry ?\; "."  tab)
-    (modify-syntax-entry ?_  "w"  tab)
-    (modify-syntax-entry ?<  "."  tab)
-    (modify-syntax-entry ?>  "."  tab)
-    (modify-syntax-entry ?/  ". 14"  tab) ; comment character
-    (modify-syntax-entry ?.  "w"  tab)
-    tab)
-  "Syntax table for `SAS-mode'.")
-
-(defun ess-SAS-pre-run-hook (temp-ess-dialect)
-  "Set up log and list files for interactive SAS."
-
-  (let* ((ess-shell-buffer-name-flag (get-buffer "*shell*"))
-         ess-shell-buffer-name
-         ;; isn't pretty yet.
-         ;;  ess-local-process-name is defined after this function.
-         ;;  it needs to be defined prior to this function.
-         (tmp-procname (let ((ntry 0)
-                             (done nil))
-                         ;; find a non-existent process
-                         (while (not done)
-                           (setq ntry (1+ ntry)
-                                 done (not
-                                       (get-process (ess-proc-name
-                                                     ntry
-                                                     temp-ess-dialect)))))
-                         (ess-proc-name ntry temp-ess-dialect)))
-         ;; Following was tmp-local-process-name.  Stolen from inferior-ess
-         (ess-sas-lst-bufname (concat "*" tmp-procname ".lst*"))
-         (ess-sas-log-bufname (concat "*" tmp-procname ".log*"))
-         (explicit-shell-file-name "/bin/sh")
-         inferior-SAS-redirect-args
-         ess-sas-lst
-         ess-sas-log)
-
-    (ess-write-to-dribble-buffer
-     (format "(ess-SAS-pre-run-hook 1): ess-lang=%s, ess-dialect=%s, temp-dialect=%s, buf=%s \n"
-             ess-language
-             ess-dialect
-             temp-ess-dialect
-             (current-buffer)))
-    ;; If someone is running a *shell* buffer, rename it to avoid
-    ;; inadvertent nuking.
-    (if ess-shell-buffer-name-flag
-        (with-current-buffer "*shell*"
-          (setq ess-shell-buffer-name
-                (rename-buffer "*ess-shell-regular*" t))))
-
-    ;; Construct the LST buffer for output
-    (if (get-buffer ess-sas-lst-bufname)
-        nil
-      (with-current-buffer (shell)
-        (accept-process-output (get-buffer-process (current-buffer)) 0.2)
-        (sleep-for 2)           ; need to wait, else working too fast!
-        (setq ess-sas-lst (ess-insert-accept "tty"))
-        (SAS-listing-mode)
-        (shell-mode)
-        (ess-listing-minor-mode t)
-        (rename-buffer ess-sas-lst-bufname t)))
-
-    ;; Construct the LOG buffer for output
-    (if (get-buffer  ess-sas-log-bufname)
-        nil
-      (with-current-buffer (shell)
-        (accept-process-output (get-buffer-process (current-buffer)) 0.2)
-        (sleep-for 2)           ; need to wait, else working too fast!
-        (setq ess-sas-log (ess-insert-accept "tty"))
-                                        ;(SAS-log-mode)
-        (shell-mode)
-        (ess-transcript-minor-mode t)
-        (rename-buffer ess-sas-log-bufname t)))
-
-    (setq inferior-SAS-redirect-args (concat " "
-                                             ess-sas-lst
-                                             " "
-                                             ess-sas-log
-                                             " ")
-          inferior-SAS-args-temp (concat inferior-SAS-redirect-args
-                                         inferior-SAS-args))
-
-    ;; Restore the *shell* buffer
-    (if ess-shell-buffer-name-flag
-        (with-current-buffer ess-shell-buffer-name
-          (rename-buffer "*shell*")))
-
-    (delete-other-windows)
-    (split-window-vertically)
-    (split-window-vertically)
-    (switch-to-buffer (nth 2 (buffer-list)))
-    (other-window 2)
-    (switch-to-buffer ess-sas-log-bufname)
-    (split-window-vertically)
-    (other-window 1)
-    (switch-to-buffer ess-sas-lst-bufname)
-    (other-window 2)
-
-    ;;workaround
-    (setq inferior-SAS-program
-          (concat (file-name-as-directory ess-etc-directory)
-                  "ess-sas-sh-command"))
-    (setq inferior-ess-program inferior-SAS-program)))
-
-(defun ess-insert-accept (command)
-  "Submit command to process, get next line."
-  (interactive)
-  (goto-char (point-max))
-  (insert command)
-  (comint-send-input)
-  (accept-process-output (get-buffer-process (current-buffer)) 0.2)
-  (forward-line -1)
-  (let* ((beg (point))
-         (ess-tty-name (progn (end-of-line) (buffer-substring beg (point)))))
-    (goto-char (point-max))
-    ess-tty-name))
-
-
-(defvar SAS-customize-alist
-  '((ess-local-customize-alist     . SAS-customize-alist)
-    (ess-language                  . "SAS")
-    (ess-dialect                   . "SAS")
-    (inferior-ess-program          . inferior-SAS-program)
-    (ess-help-sec-regex            . "^[A-Z. ---]+:$")
-    (ess-help-sec-keys-alist       . " ")
-    (ess-object-name-db-file       . "ess-sas-namedb.el")
-    (inferior-ess-objects-command  . "objects(%d)");;FIXME
-    (inferior-ess-help-command     . "help(\"%s\",pager=\"cat\",window=F)\n");;FIXME
-    (inferior-ess-exit-command     . "endsas;\n")
-    (ess-loop-timeout              .  500000 )
-    (inferior-ess-primary-prompt   . "^")
-    (inferior-ess-secondary-prompt . "^")
-    (comint-use-prompt-regexp      . t)
-    (inferior-ess-start-args       . inferior-SAS-args-temp)
-    ;; (ess-pre-run-hook              . 'ess-SAS-pre-run-hook)
-    ;; (ess-local-process-name        . nil)
-    )
-  "Variables to customize for SAS")
-
-;;; The functions of interest (mode, inferior mode)
-
-;;;###autoload
-(define-derived-mode SAS-mode ess-mode "[SAS]"
-  "Major mode for editing SAS source.  See `ess-mode' for more help."
-  :group 'ess-sas
-  (ess-setq-vars-local SAS-customize-alist)
-  (setq ess-local-customize-alist SAS-customize-alist)
-  (setq-local sentence-end ";[\t\n */]*")
-  (setq-local paragraph-start "^[ \t]*$")
-  (setq-local paragraph-separate "^[ \t]*$")
-  (setq-local paragraph-ignore-fill-prefix t)
-  (setq-local adaptive-fill-mode nil)
-  (setq-local indent-line-function #'sas-indent-line)
-  (setq-local comment-start "/*")
-  (setq-local comment-start-skip "/[*]")
-  (setq-local comment-end "*/")
-  (setq-local comment-end-skip "[*]/")
-  (setq-local comment-column 40)
-  (setq-local ess-local-process-name nil)
-  (setq-local tab-stop-list ess-sas-tab-stop-list)
-  (setq-local font-lock-keywords-case-fold-search t)
-  ;; Local map settings, AFTER initialization (only if not yet defined)
-  (unless sas-mode-local-map
-    (setq sas-mode-local-map (copy-keymap (current-local-map)))
-    (ess-sas-edit-keys-set ess-sas-edit-keys-toggle)
-    (if ess-sas-local-unix-keys (ess-sas-local-unix-keys))
-    (if ess-sas-local-pc-keys (ess-sas-local-pc-keys))
-    (if ess-sas-global-unix-keys (ess-sas-global-unix-keys))
-    (if ess-sas-global-pc-keys (ess-sas-global-pc-keys)))
-  (define-key sas-mode-local-map ";" #'ess-electric-run-semicolon)
-  (define-key sas-mode-local-map (kbd "\C-c\C-w") #'ess-multi-frame-SAS)
-  ;; this is a mess
-  ;; interactive and batch commands share sas-mode-local-map,
-  ;; but the associated commands are very different
-  ;; what would be better is two maps like
-  ;; sas-batch-mode-local-map and sas-interactive-mode-local-map
-  ;; or smart function definitions that would do the appropriate
-  ;; thing for either batch or interactive sessions
-  ;; however, neither of these solutions are planned
-  ;; therefore, no key definitions can be shared between
-  ;; batch and interactive at this time, hence the lines that
-  ;; are commented below:  uncomment at your own risk
-  ;;  (define-key sas-mode-local-map "\C-c\C-p" 'ess-sas-file-path)
-  ;;  (define-key sas-mode-local-map "\C-c\C-b" 'ess-sas-submit)
-  ;;  (define-key sas-mode-local-map "\C-c\C-r" 'ess-sas-submit-region)
-  ;;  (define-key sas-mode-local-map "\C-c\C-x" 'ess-sas-goto-log)
-  ;;  (define-key sas-mode-local-map "\C-c\C-y" 'ess-sas-goto-lst)
-
-  (use-local-map sas-mode-local-map)
-
-  (setq font-lock-defaults
-        ;; KEYWORDS KEYWORDS-ONLY CASE-FOLD .....
-        '(SAS-mode-font-lock-defaults nil t)))
-
-
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.[Ss][Aa][Ss]\\'" . SAS-mode))
-
-;; rmh Jul 10 2003
-(defun ess-electric-run-semicolon (arg)
-  "Insert character.
-If the line contains \"run;\" or \"quit;\" and nothing else then
-indent line."
-  (interactive "P")
-  (if ess-sas-edit-keys-toggle
-      (insert ";")
-    (if (and (not arg)
-             (eolp)
-             (save-excursion
-               (skip-chars-backward " \t")
-               (backward-word 1)
-               (and (looking-at "run\\|quit")
-                    (progn
-                      (skip-chars-backward " \t")
-                      (bolp)))))
-        (progn
-          (insert last-command-event)
-          (funcall indent-line-function)
-          (save-excursion
-            (delete-char -1))))
-    (self-insert-command (prefix-numeric-value arg))))
-
-(defun SAS-menu ()
-  "Start SAS from the menu."
-  (interactive)
-  (if ess-microsoft-p
-      ;; replace with other choices for starting SAS?
-      (error "SAS cannot be started this way in ESS on Windows.")
-    (SAS)))
-
-(defun SAS ()
-  "Call \\='SAS\\=', from SAS Institute."
-  (interactive)
-  (let* ((temp-dialect "SAS")) ;(cdr (rassoc ess-dialect SAS-customize-alist))))
-    (ess-write-to-dribble-buffer
-     (format "(SAS): ess-dial=%s, temp-dial=%s\n"
-             ess-dialect
-             temp-dialect))
-    (ess-SAS-pre-run-hook temp-dialect)
-    (setq ess-eval-visibly-p nil)
-    ;; FIXME: `inferior-SAS-args' is defined from
-    ;; `inferior-SAS-args-temp' in `ess-SAS-pre-run-hook'
-    (let ((inf-buf (inferior-ess nil SAS-customize-alist)))
-      (with-current-buffer inf-buf
-        (use-local-map sas-mode-local-map))
-      inf-buf)))
-
-(defun ess-multi-frame-SAS ()
-  "Put running SAS buffers into separate frames.
-Load this function M-x load-file essx-sas.el RET.
-Then find-file myfile.sas.  If myfile.sas is already in a buffer, kill-buffer
-it and then find-file it again.
-Place the cursor in a myfile.sas buffer.  Run SAS with M-x SAS,
-Return the cursor to the myfile.sas buffer,
-then enter C-c C-w to put *SAS* *SAS.log* *SAS.lst* buffers into
-their own frames."
-  (interactive)
-  (delete-other-windows)
-  (with-current-buffer "*SAS*"
-    (make-frame))
-  (with-current-buffer "*SAS.log*"
-    (make-frame))
-  (with-current-buffer "*SAS.lst*"
-    (make-frame)))
-
-(defun ess-num-or-zero (arg)
-  "If a number, then return that number, otherwise return 0."
-  (or (and (numberp arg) arg) 0))
-
-\f ; Provide package
-
-(provide 'ess-sas-d)
-
-;;; ess-sas-d.el ends here
diff --git a/elpa/ess-20251212.937/ess-sas-l.el b/elpa/ess-20251212.937/ess-sas-l.el
deleted file mode 100644 (file)
index 97e51ce..0000000
+++ /dev/null
@@ -1,1754 +0,0 @@
-;;; ess-sas-l.el --- SAS customization  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1997-2022 Free Software Foundation, Inc.
-;; Authors: Richard M. Heiberger
-;;          A.J. Rossini
-;;          Rodney Sparapani
-;; Created: 20 Aug 1997
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; This is based upon Version 1.4 of SAS mode:
-
-
-;;;    sas-mode:  indent, run etc, SAS programs.
-;;;  Author:   Tom Cook
-;;;            Dept. of Biostatistics
-;;;            University of Wisconsin - Madison
-;;;            Madison, WI 53706
-;;;            cookNOSPAMbiostat.wisc.edu
-;;;
-;;;  Acknowledgements:
-;;;  Menu code for XEmacs/Lucid emacs and startup mods
-;;;  contributed by arossiniNOSPAMbiostats.hmc.psu.edu
-;;;
-;;; Last change: 2/1/95
-;;; Last change: 01/15/02
-
-;;; Code:
-
-(require 'ess-mode)
-(require 'ess-sas-a)
-
-(declare-function SAS-mode "ess-sas-d")
-
-(put 'ess-transcript-minor-mode 'permanent-local t)
-(or (assq 'ess-transcript-minor-mode minor-mode-alist)
-    (setq minor-mode-alist
-          (append minor-mode-alist
-                  (list '(ess-transcript-minor-mode " ESStr")))))
-
-(put 'ess-listing-minor-mode 'permanent-local t)
-(or (assq 'ess-listing-minor-mode minor-mode-alist)
-    (setq minor-mode-alist
-          (append minor-mode-alist
-                  (list '(ess-listing-minor-mode " ESSlst")))))
-
-(defun ess-transcript-minor-mode (&optional arg)
-  "Toggle Ess-Transcript minor mode.
-With arg, turn Ess-Transcript minor mode on if arg is positive, off
-otherwise.  See the command `ess-transcript-mode' for more information
-on this mode."
-  (interactive "P")
-  (setq ess-transcript-minor-mode
-        (if (null arg) (not ess-transcript-minor-mode)
-          (> (prefix-numeric-value arg) 0)))
-  (force-mode-line-update)
-  (setq mode-line-process
-        '(" [" ess-local-process-name "]")))
-
-(defun ess-listing-minor-mode (&optional arg)
-  "Toggle Ess-Listing minor mode.
-With arg, turn Ess-Listing minor mode on if arg is positive, off
-otherwise.  Ess-Listing mode is used solely to place an indicator on
-the mode line."
-  (interactive "P")
-  (setq ess-listing-minor-mode
-        (if (null arg) (not ess-listing-minor-mode)
-          (> (prefix-numeric-value arg) 0)))
-  (force-mode-line-update)
-  (setq mode-line-process
-        '(" [" ess-local-process-name "]")))
-        
-(defcustom ess-automatic-sas-log-or-lst-mode t
-  "Automatically turn on `SAS-log-mode' and `SAS-listing-mode' when enabled."
-  :type 'boolean
-  :group 'ess-sas)
-
-(defun ess-SAS-log-mode-p ()
-  "Return t when when a SAS log file is detected.
-A SAS log is defined as having:
-
-1. The first line matches \"^1[ \t]*The SAS System\"
-2. The file name ends in .log.
-"
-  (and ess-automatic-sas-log-or-lst-mode
-       (save-excursion
-         (goto-char (point-min))
-         (looking-at "1[ \t]*The SAS System"))
-       (if (buffer-file-name)
-           (string-match ".log$" (buffer-file-name))
-         t)))
-
-(defun ess-SAS-listing-mode-p ()
-  "Return t when SAS listing file is detected.
-A .lst file is a SAS listing file when:
-
-1. The file name ends in .lst
-2. The corresponding log file exists and is a SAS log file.
-"
-  (when ess-automatic-sas-log-or-lst-mode
-    (let* ((bfn (buffer-file-name))
-           (log (and bfn
-                     (string-match-p "\\.lst$" bfn)
-                     (replace-regexp-in-string "\\.lst$" ".log" bfn))))
-      (and log
-           (file-exists-p log)
-           (with-temp-buffer
-             (insert-file-contents log nil 0 200)
-             (goto-char (point-min))
-             (looking-at "1[ \t]*The SAS System"))))))
-
-(add-to-list 'magic-mode-alist
-             '(ess-SAS-log-mode-p . SAS-log-mode))
-(add-to-list 'magic-mode-alist
-             '(ess-SAS-listing-mode-p . SAS-listing-mode))
-
-(define-derived-mode SAS-log-mode SAS-mode "ESS[LOG]"
-  "`ess-transcript-mode' for SAS."
-  :group 'ess-sas
-  (ess-transcript-minor-mode 1)
-  (setq buffer-read-only t) ;; to protect the buffer.
-  (buffer-disable-undo))
-
-(defvar sas-mode-local-map nil "contains modified local keymap for SAS")
-(define-derived-mode SAS-listing-mode special-mode "ESS[LST]"
-  "Fundamental mode with `ess-listing-minor-mode' and read-only."
-  :keymap sas-mode-local-map
-  :group 'ess-sas
-  (ess-listing-minor-mode 1)
-  (buffer-disable-undo))
-
-(defalias 'sas-log-mode        #'SAS-log-mode)
-(defalias 'SAS-transcript-mode #'SAS-log-mode)
-(defalias 'sas-transcript-mode #'SAS-log-mode)
-(defalias 'sas-mode #'SAS-mode)
-(defalias 'sas-listing-mode    #'SAS-listing-mode)
-
-(defcustom  sas-indent-width 4
-  "Amount to indent sas statements."
-  :group 'ess-sas
-  :type  'integer)
-
-(defcustom sas-indent-ignore-comment "\\*"
-  "Comments that start with this regular expression are ignored in indentation."
-  :group 'ess-sas
-  :type  'string)
-
-(defcustom sas-require-confirmation t
-  "Require confirmation when revisiting a modified sas-output file."
-  :group 'ess-sas
-  :type  'boolean)
-
-(defcustom sas-pre-run-hook nil
-  "Hook to execute prior to running SAS via `submit-sas'."
-  :group 'ess-sas
-  :type  'hook)
-
-(defcustom sas-notify t
-  "Beep and display message when job is done."
-  :group 'ess-sas
-  :type  'boolean)
-
-(defcustom sas-error-notify t
-  "If `sas-notify' t, indicate errors in log file upon completion."
-  :group 'ess-sas
-  :type  'boolean)
-
-(defcustom sas-get-options nil
-  "Options to be passed to SAS in sas-get-dataset."
-  :group 'ess-sas
-  :type '(choice (const nil) string))
-
-(defcustom sas-get-options-history nil
-  "History list of Options passed to SAS in sas-get-dataset."
-  :type '(choice (const nil)
-                 (string))
-  :group 'ess-sas)
-
-(defcustom sas-page-number-max-line 3
-  "Number of lines from the page break, to search for the page
-number."
-  :group 'ess-sas
-  :type  'integer)
-
-(defcustom sas-notify-popup nil
-  "If this and `sas-notify' are t), popup a window when SAS job ends."
-  :group 'ess-sas
-  :type  'boolean)
-
-(defcustom sas-tmp-libname "_tmp_"
-  "Libname to use for sas-get-dataset."
-  :group 'ess-sas
-  :type  'string)
-
-(defcustom sas-file-name nil
-  "The name of the current sas file."
-  :group 'ess-sas
-  :type '(choice (const nil) file))
-
-;; The next two are ``the inside of [...] in a regexp'' to be used in
-;; (skip-chars-(for|back)ward SAS-..-chars)
-(defcustom sas-white-chars " \t\n\f"
-  "This does NOT escape blanks (RMH, 2000/03/20)."
-  :group 'ess-sas
-  :type  'string)
-
-(defcustom sas-comment-chars (concat sas-white-chars ";")
-  "Doc?"
-  :group 'ess-sas
-  :type  'string)
-
-(defcustom ess-sas-run-regexp-opt t
-  "If you do not want to run regexp-opt, then set to nil."
-  :group 'ess-sas
-  :type 'boolean)
-
-(defvar sas-buffer-name nil)
-(defvar sas-file-root nil)
-(defvar sas-submitable nil)
-(defvar sas-dataset nil)
-
-(defvar SAS-mode-font-lock-defaults
-  (if ess-sas-run-regexp-opt
-      (list
-       ;; .log NOTE: messages
-       (cons "^NOTE [0-9]+-[0-9]+: Line generated by the invoked macro"
-             font-lock-comment-face)
-       (cons "^NOTE: .*$"                          font-lock-comment-face)
-       (cons "^      [^ @].*[.]$"                   font-lock-comment-face)
-       (cons "^      [a-z].*[a-z][ ]?$"            font-lock-comment-face)
-       (cons "^      Engine:[ ]+V.+$"              font-lock-comment-face)
-       (cons "^      Physical Name:[ ]+.+$"        font-lock-comment-face)
-       (cons "^      \\(cpu\\|real\\) time[ ]+[0-9].*$"
-             font-lock-comment-face)
-       (cons "^      decimal may be shifted by the"
-             font-lock-comment-face)
-       (cons "^NOTE: The infile "                  font-lock-comment-face)
-       (cons "^NOTE: 1 record was read from the infile "
-             font-lock-comment-face)
-       (cons "^NOTE: [1-9][0-9]* records were read from the infile "
-             font-lock-comment-face)
-       (cons "^      Filename=.*,$"                font-lock-comment-face)
-       (cons "^      File Name=.*,$"               font-lock-comment-face)
-       (cons "^      File $"                       font-lock-comment-face)
-       (cons "^      Name=.*,$"                    font-lock-comment-face)
-       (cons "^      File List=("                  font-lock-comment-face)
-       (cons "^      List=("                       font-lock-comment-face)
-       (cons "^      Owner Name=.*,$"              font-lock-comment-face)
-       (cons "^      Access Permission=.*,$"       font-lock-comment-face)
-       (cons "^      Last Modified=.*,?$"          font-lock-comment-face)
-       (cons "^      File Size (bytes)=[0-9]+$"    font-lock-comment-face)
-       (cons "^      Pipe command="                font-lock-comment-face)
-       (cons "^NOTE: The file "                    font-lock-comment-face)
-       (cons "^NOTE: 1 record was written to the file "
-             font-lock-comment-face)
-       (cons "^NOTE: [1-9][0-9]* records were written to the file "
-             font-lock-comment-face)
-       (cons "^NOTE: PROC LOGISTIC is modeling the probability that"
-             font-lock-comment-face)
-       (cons "^NOTE: PROC GENMOD is modeling the probability that"
-             font-lock-comment-face)
-       (cons "^1[ ]+The SAS System.*$"             font-lock-comment-face)
-       (cons "^\014.*$"                            font-lock-comment-face)
-       (cons "[*][*][*] ANNOTATE macros are now available [*][*][*]"
-             font-lock-comment-face)
-       (cons "For further information on ANNOTATE macros, enter,"
-             font-lock-comment-face)
-       ;; (cons "^SAS/STAT 9.3_M1, SAS/ETS 9.3_M1, SAS/OR 9.3_M1"
-       ;;       font-lock-comment-face)
-       (cons "\\(or \\)?%HELPANO.*$"
-             font-lock-comment-face)
-       (cons "^Local Variables:$"                  font-lock-comment-face)
-       (cons "^End:$"                              font-lock-comment-face)
-       (cons "^MPRINT([_A-Z0-9]+)"                 font-lock-comment-face)
-
-       ;; .log ERROR: messages
-                                        ;     (cons "^ERROR\\( [0-9]+-[1-9][0-9][0-9]\\)?: .*$"
-       (cons "^ERROR\\( [0-9]+-[0-9]+\\)?: .*$"
-             font-lock-keyword-face)
-                                        ;       ERROR:
-       (cons "^       [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
-             font-lock-keyword-face)
-                                        ;       ERROR #-###:
-       (cons "^             [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
-             font-lock-keyword-face)
-                                        ;       ERROR ##-###:
-       (cons "^              [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
-             font-lock-keyword-face)
-                                        ;       ERROR ###-###:
-       (cons "^               [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
-             font-lock-keyword-face)
-       (cons "^              a format name."       font-lock-keyword-face)
-       (cons "^       where a numeric operand is required. The condition was: "
-             font-lock-keyword-face)
-       (cons "[ ][_]+$"                            font-lock-keyword-face)
-
-       ;; .log WARNING: messages
-                                        ;(cons "^WARNING\\( [0-9]+-[1-9][0-9][0-9]\\)?: .*$"
-       (cons "^WARNING\\( [0-9]+-[0-9]+\\)?: .*$"
-             font-lock-function-name-face)
-                                        ;       WARNING:
-       (cons "^         [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
-             font-lock-function-name-face)
-                                        ;       WARNING #-###:
-       (cons "^               [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
-             font-lock-function-name-face)
-                                        ;       WARNING ##-###:
-       (cons "^                [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
-             font-lock-function-name-face)
-                                        ;       WARNING ###-###:
-       (cons "^                 [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
-             font-lock-function-name-face)
-
-       ;; SAS comments
-       ;; /* */ style handled by grammar above
-       (cons "\\(^[0-9]*\\|[:;!]\\)[ \t]*%?\\*[^;/][^;]*;"
-             font-lock-comment-face)
-
-                                        ; these over-rides need to come before the more general declarations
-       (cons "\\<and("      font-lock-function-name-face)
-       (cons "\\<data="     font-lock-keyword-face)
-       (cons "\\<in:("      font-lock-function-name-face)
-       (cons "\\<index("    font-lock-function-name-face)
-       (cons "\\<input("    font-lock-function-name-face)
-       (cons "\\<libname("  font-lock-function-name-face)
-       (cons "\\<not("      font-lock-function-name-face)
-       (cons "\\<or("       font-lock-function-name-face)
-       (cons "\\<put("      font-lock-function-name-face)
-       (cons "\\<sum("      font-lock-function-name-face)
-
-                                        ; other idiosyncratic keywords
-                                        ;(cons "key="      font-lock-keyword-face)
-                                        ;(cons "/unique"   font-lock-keyword-face)
-
-       ;; SAS execution blocks: DATA, %MACRO/%MEND, %DO/%END, etc.
-       (cons (regexp-opt '(
-                           "data" "start" "return" ;"proc"
-                           "%macro" "%mend"
-                           "%do" "%to" "%by" "%end"
-                           "%goto" "%go to"
-                           "%if" "%then" "%else"
-                           "%global" "%inc" "%include" "%input" "%local" "%let" "%put" "%sysexec"
-                           ) 'words) font-lock-constant-face)
-
-       ;; SAS execution blocks that must be followed by a semi-colon
-       (cons (concat "\\<"
-                     (regexp-opt
-                      '(
-                        "run;" "quit;" "endsas;" "finish;"
-                        "cards;" "cards4;" "datalines;" "datalines4;" "lines;" "lines4;"
-                        )))
-             font-lock-constant-face)
-
-       ;; SAS statements that must be followed by a semi-colon
-       (cons (concat "\\<"
-                     (regexp-opt
-                      '(
-                        "end;" "list;" "lostcard;" "page;" "stop;" ;"return;" 
-                        )))
-             font-lock-keyword-face)
-
-       ;; SAS statements that must be followed by an equal sign
-       (cons (concat "\\<"
-                     (regexp-opt
-                      '(
-                        "compress=" "in=" "out=" "sortedby="
-                        )))
-             font-lock-keyword-face)
-
-;;;    ;; SAS procedure names
-       (cons (concat "\\<proc[ ]+"
-                     (regexp-opt '(
-"access" "aceclus" "adaptivereg" "aggregation" "anom" "anova" "append" "appsrv" "arima" "assess" "astore" "authlib" "autoreg"
-"bchoice" "bglimm" "binning" "bnet" "bom" "boolrule" "boxplot" "build"
-"calendar" "calis" "callrfc" "cancorr" "candisc" "capability" "cardinality" "carima" "cas" "casutil" "catalog" "catmod" "causalgraph" "causalmed" "causaltrt" "ccdm" "ccopula" "cesm" "chart" "cimport" "clp" "cluster" "cntselect" "compare" "compile" "computab" "contents" "convert" "copula" "copy" "corr" "correlation" "corresp" "countreg" "cpanel" "cpm" "cport" "cqlim" "cspatialreg" "cusum" "cv2view"
-"datasets" "datasource" "datekeys" "db2ext" "db2util" "dbcstab" "dbf" "dbload" "delete" "dfil" "dif" "discrim" "display" "distance" "dmsrvadm" "dmsrvdatasvc" "dmsrvprocesssvc" "document" "download" "dqloclst" "dqmatch" "dqscheme" "ds2" "dstods2" "dtree"
-"ecm" "entropy" "esm" "expand" "explode" "export"
-"factex" "factmac" "factor" "fastclus" "fastknn" "fcmp" "fedsql" "fism" "fmm" "fmtc2itm" "fontreg" "forest" "format" "forms" "freq" "freqtab" "fsbrowse" "fsedit" "fsletter" "fslist" "fsview"
-"g3d" "g3grid" "ga" "gam" "gammod" "gampl" "gamselect" "ganno" "gantt" "gareabar" "gbarline" "gchart" "gcontour" "gdevice" "gee" "genmod" "genselect" "geocode" "gfont" "ginside" "gis" "gkpi" "glimmix" "glm" "glmmod" "glmpower" "glmselect" "gmap" "gmm" "goptions" "gplot" "gproject" "gradar" "gradboost" "greduce" "gremove" "greplay" "groovy" "gslide" "gtile" "gvarclus"
-"hadoop" "hdmd" "hmm" "hp4score" "hpbin" "hpbnet" "hpboolrule" "hpcandisc" "hpcdm" "hpclus" "hpcopula" "hpcorr" "hpcountreg" "hpdecide" "hpdmdb" "hpds2" "hpexport" "hpf" "hpfarimaspec" "hpfdiagnose" "hpfengine" "hpfesmspec" "hpfevents" "hpfexmspec" "hpfidmspec" "hpfmm" "hpforest" "hpfreconcile" "hpfrepository" "hpfselect" "hpftemprecon" "hpfucmspec" "hpgenselect" "hpimpute" "hplmixed" "hplogistic" "hpmixed" "hpneural" "hpnlmod" "hppanel" "hppls" "hpprincomp" "hpqlim" "hpquantselect" "hpreduce" "hpreg" "hprisk" "hpsample" "hpseverity" "hpsplit" "hpsummary" "hpsvm" "hptmine" "hptmscore" "http"
-"ica" "iclifetest" "icphreg" "iml" "import" "imstat" "imxfer" "inbreed" "infomaps" "iomoperate" "irt" "ishikawa" "items"
-"javainfo" "json"
-"kclus" "kde" "kpca" "krige2d"
-"lasr" "lattice" "lifereg" "lifetest" "lmixed" "loan" "localedata" "loess" "logistic" "logselect" "lua"
-"macontrol" "mapimport" "mbanalysis" "mbc" "mcmc" "mdc" "mddb" "mds" "mdsummary" "means" "metadata" "metalib" "metaoperate" "mi" "mianalyze" "migrate" "mixed" "modeclus" "model" "modelmatrix" "mtlearn" "multtest" "mvpdiagnose" "mvpmodel" "mvpmonitor" "mwpca"
-"nested" "netdraw" "network" "nlin" "nlmixed" "nlmod" "nmf" "nnet" "npar1way"
-"odslist" "odstable" "odstext" "olap" "olapcontents" "olapoperate" "operate" "optex" "optgraph" "options" "optload" "optlp" "optlso" "optmilp" "optmodel" "optnet" "optnetwork" "optqp" "optsave" "orthoreg"
-"panel" "pareto" "partition" "pca" "pdlreg" "pds" "pdscopy" "phreg" "phselect" "plan" "plm" "plot" "pls" "plsmod" "pm" "pmenu" "power" "presenv" "princomp" "prinqual" "print" "printto" "probit" "proto" "prtdef" "prtexp" "psmatch" "pwencode"
-"qdevice" "qlim" "qtrselect" "quantlife" "quantreg" "quantselect" "quest"
-"rank" "rareevents" "rdc" "rdpool" "rdsec" "recommend" "reg" "registry" "regselect" "release" "reliability" "report" "risk" "rmstreg" "robustreg" "rpca" "rsreg"
-"s3" "sandwich" "scaproc" "score" "scoreaccel" "semisuplearn" "seqdesign" "seqtest" "server" "severity" "sevselect" "sgdesign" "sgmap" "sgpanel" "sgpie" "sgplot" "sgrender" "sgscatter" "shewhart" "sim2d" "similarity" "simlin" "simnormal" "simsystem" "smcalib" "smproject" "smscore" "smselect" "smspec" "soap" "sort" "source" "sparseml" "spatialreg" "spc" "spdo" "spectra" "spp" "sql" "sqoop" "ssm" "standard" "statespace" "stdize" "stdrate" "stepdisc" "stp" "stream" "summary" "surveyfreq" "surveyimpute" "surveylogistic" "surveymeans" "surveyphreg" "surveyreg" "surveyselect" "svdd" "svmachine" "syslin"
-"tabulate" "tapecopy" "tapelabel" "textmine" "timedata" "timeid" "timeplot" "timeseries" "tmodel" "tmscore" "tpspline" "transpose" "transreg" "trantab" "tree" "treesplit" "tscsreg" "tsinfo" "tsmodel" "tsne" "tsreconcile" "ttest"
-"ucm" "univariate" "upload"
-"varclus" "varcomp" "varimpute" "variogram" "varmax" "varreduce" "vasmp"
-"x11" "x12" "x13" "xsl"
-                                   ) 'words)) font-lock-constant-face)
-
-                                        ;       (cons (concat
-                                        ;             "\\<"
-                                        ;             "do[ \t]*" (regexp-opt '("over" "until" "while") t) "?"
-                                        ;             "\\>")
-                                        ;            font-lock-keyword-face)
-                                        ;
-       ;; SAS base and SAS/Graph statements
-       (cons (concat ;"\\<"
-              (regexp-opt
-               '(
-                 "do" "to" "by" "goto" ; "go"
-                 "abort" "and" "array" "assess" "attrib"
-                 "baseline" "bayes" "between" "bivar" "block" "bubble" "bubble2"
-                 "change" "choro" "class" "contains" "contrast"
-                 "delete" "display" "dm" "donut" "drop"
-                 "else" "error" "exchange" "exclude"
-                 "fcs" "file" "filename" "format" "freq"
-                 "footnote" "footnote1" "footnote2" "footnote3" "footnote4" "footnote5"
-                 "footnote6" "footnote7" "footnote8" "footnote9" "footnote10"
-                 "goptions" "grid" ; "ge" "gt"
-                 "hazardratio" "hbar" "hbar3d"
-                 "id" "if" "index" "infile" "informat" "input" ; "is" rarely used, but common false pos.
-                 "keep"
-                 "label" "length" "libname" "like" "link" "lsmeans" ; "le" "lt"
-                 "manova" "means" "merge" "missing" "model" "modify"
-                 "not" "null" ; "ne" "note"
-                 "ods" "options" "output" "otherwise" ; "or"
-                 "pageby" "parms" "pie" "pie3d" "plot" "plot2" "prism" "put"
-                 "random" "rename" "repeated" "retain"
-                 "same" "save" "scatter" "select" "set" "skip" "star" "strata" "sum" "sumby" "surface"
-                 "table" "tables" "test" "then" "time"
-                 "title" "title1" "title2" "title3" "title4" "title5"
-                 "title6" "title7" "title8" "title9" "title10"
-                 "univar" "update"
-                 "value" "var" "vbar" "vbar3d"
-                 "weight" "where" "window" "with"
-                                        ; "x"
-                 ) 'words)) ;"\\>")
-             font-lock-keyword-face)
-
-       ;; SAS/GRAPH statements not handled above
-       (cons (concat "\\<"
-                     (regexp-opt
-                      '("axis" "legend" "pattern" "symbol")) "\\([1-9][0-9]?\\)?"
-                      "\\>")
-             font-lock-keyword-face)
-
-       ;; SAS functions and SAS macro functions
-       (cons "%[a-z_][a-z_0-9]*[(;]"                  font-lock-function-name-face)
-                                        ;(cons "\\<call[ \t]+[a-z]+("                   font-lock-function-name-face)
-
-       (cons (concat ;"\\<"
-              (regexp-opt
-               '(
-;; SAS functions found in sashelp.vfunc where fncprod='X'
-                 "abs" "arcos" "arsin" "atan"
-                 "betainv" "byte"
-                 "call execute" "call label" "call module" "call modulei"
-                 "call poke" "call ranbin" "call rancau" "call ranexp"
-                 "call rangam" "call rannor" "call ranpoi" "call rantbl"
-                 "call rantri" "call ranuni" "call rxchange" "call rxfree"
-                 "call rxsubstr" "call set" "call streaminit" "call symput" "call system"
-                 "cdf" "ceil" "cinv" "collate" "compress" "convx" "convxp" "cos" "cosh" "css" "cv"
-                 "daccdb" "daccdbsl" "daccsl" "daccsyd" "dacctab"
-                 "depdb" "depdbsl" "depsl" "depsyd" "deptab"
-                 "date" "datejul" "datepart" "datetime" "day" "dhms" "dif" "digamma" "dim"
-                 "erf" "erfc" "exp"
-                 "finv" "fipname" "fipnamel" "fipstate" "floor" "fuzz"
-                 "gaminv" "gamma"
-                 "hbound" "hms" "hour"
-                 "in" "index" "indexc" "input" "int" "intck" "intnx" "intrr" "irr"
-                 "juldate"
-                 "kurtosis"
-                 "lag" "lbound" "left" "length" "lgamma" "log" "log10" "log2"
-                 "logcdf" "logpdf" "logsdf"
-                 "max" "mdy" "mean" "min" "minute" "mod" "month" "mort"
-                 "n" "netpv" "nmiss" "normal" "npv"
-                 "ordinal"
-                 "pdf"
-                 "probbeta" "probbnml" "probchi" "probf" "probgam" "probhypr" "probit" "probnegb" "probnorm" "probt"
-                 "poisson" "put"
-                 "qtr" "quantile"
-                 "rand" "range" "rank" "repeat" "reverse" "right" "round" "rxmatch" "rxparse"
-                 "ranbin" "rancau" "ranexp" "rangam" "rannor" "ranpoi" "rantbl" "rantri" "ranuni"
-                 "saving" "scan" "sdf" "second" "sign" "sin" "sinh" "sqrt" "squantile"
-                 "std" "stderr" "stfips" "stname" "stnamel" "substr" "sum" "symget"
-                 "tan" "tanh" "time" "timepart" "tinv" "today" "translate" "trigamma" "trim" "trunc"
-                 "uniform" "until" "upcase" "uss"
-                 "var" "verify"
-                 "weekday" "when" "while"
-                 "year" "yyq"
-                 "zipfips" "zipname" "zipnamel" "zipstate"
-
-;;;    ;; SAS/IML functions 
-                 "all" "allcomb" "allperm" "any" "apply" "armasim"
-                 "bin" "blankstr" "block" "branks" "bspline" "btran" "byte"
-                 "char" "choose" "col" "colvec" "concat" "contents" "convexit" "corr" "corr2cov" 
-                 "countmiss" "countn" "countunique" "cov" "cov2corr" "covlag" "cshape" "cusum"
-                 "cuprod" "cv" "cvexhull" 
-                 "datasets" "design" "designf" "det" "diag" "dimension" "distance" "do" "duration" 
-                 "echelon" "eigval" "eigvec" "expmatrix" "expandgrid" 
-                 "fft" "fftc" "forward" "froot" "full"
-                 "gasetup" "geomean" "ginv" 
-                 "hadamard" "half" "hankel" "harmean" "hdir" "hermite" "homogen"
-                 "i" "ifft" "ifftc" "importtablefromr" "insert" "inv" "invupdt" "isempty" "isskipped"
-                 "j" "jroot" 
-                 "kurtosis" 
-                 "lambertw" "listgetallnames" "listgetitem" "listgetname" "listgetsubitem" "listindex"
-                 "listlen" "loc" "logabsdet" 
-                 "mad" "magic" "mahalanobis" "moduleic" "modulein" 
-                 "name" "ncol" "nrow" "ndx2sub" "nleng" "norm" "num" 
-                 "opscal" "orpol"
-                 "parentname" "palette" "polyroot" "prod" "product" "pv"
-                 "quartile" 
-                 "rancomb" "randdirichlet" "randfun" "randmultinomial" "randmvt" "randnormal" "randwishart"
-                 "ranperk" "ranperm" "ranktie" "rates" "ratio" "remove" "repeat" "root" "row" 
-                 "rowcat" "rowcatc" "rowvec" "rsubstr" 
-                 "sample" "setdif" "shape" "shapecol" "skewness" "solve" "sparse" "splinev" "spot" 
-                 "sqrsym" "sqrvech" "ssq" "standard" "storage" "sub2ndx" "sweep" "symsqr"
-                 "t" "tablecreate" "tablecreatefromdataset" "tablegetvardata" "tablegetvarformat"
-                 "tablegetvarindex" "tablegetvarinformat" "tablegetvarlabel" "tablegetvarname"
-                 "tablegetvartype" "tableisexistingvar" "tableisvarnumeric" "tfhilbert" "tfpwv"
-                 "tfstft" "tfwindow" "toeplitz" "trace" "trisolv" "type" 
-                 "union" "unique" "uniqueby" 
-                 "value" "vecdiag" "vech" 
-                 "xmult" "xsect"
-                 "yield"
-                 
-;;;    ;; SAS functions introduced in Technical Report P-222
-                 "airy"
-                 "band" "blshift" "brshift" "bnot" "bor" "bxor"
-                 "cnonct" "compbl"
-                 "dairy" "dequote"
-                 "fnonct"
-                 "ibessel" "indexw" "inputc" "inputn"
-                 "jbessel"
-                 "lowcase"
-                 "putc" "putn"
-                 "quote"
-                 "resolve"
-                 "soundex" "sysprod"
-                 "tnonct" "tranwrd" "trimn"
-
-;;;    ;; SCL functions that are known to work with SAS macro function %sysfunc
-                 "attrc" "attrn"
-                 "cexist" "close"
-                 "dclose" "dnum" "dopen" "dread"
-                 "exist"
-                 "fclose" "fetchobs" "fileexist" "finfo" "fopen" "fput" "fwrite"
-                 "getoption" "getvarc" "getvarn"
-                 "libname" "libref"
-                 "open" "optgetn" "optsetn"
-                 "pathname"
-                 "sysmsg"
-                 "varfmt" "varlabel" "varnum" "vartype"
-                 ) 'words) ;"\\>"
-              "("); "[ \t]*(")
-             font-lock-function-name-face)
-       )
-    (list
-     ;; .log NOTE: messages
-     (cons "^NOTE: .*$"                         font-lock-constant-face)
-
-     ;; .log ERROR: messages
-     (cons "^ERROR: .*$"                        font-lock-keyword-face)
-
-     ;; .log WARNING: messages
-     (cons "^WARNING: .*$"                      font-lock-function-name-face)
-
-     ;; SAS comments
-     ;; /* */ handled by grammar above
-     ;;  (list "/\\*.*\\*/"                      0  font-lock-comment-face t)
-     (cons "\\(^[0-9]*\\|;\\)[ \t]*\\(%?\\*\\|comment\\).*\\(;\\|$\\)" font-lock-comment-face)
-
-     ;; SAS execution blocks, DATA/RUN, PROC/RUN, SAS Macro Statements
-     (cons "\\<%do[ \t]*\\(%until\\|%while\\)?\\>"
-           font-lock-constant-face)
-     ;;(cons (concat "\\(^[0-9]*\\|;\\)[ \t]*"
-     ;;"%\\(end\\|global\\|local\\|m\\(acro\\|end\\)\\)"
-     ;;"\\>")                               font-lock-constant-face)
-     (cons "\\<%\\(end\\|global\\|local\\|m\\(acro\\|end\\)\\)\\>"
-           font-lock-constant-face)
-
-     (cons (concat "\\(^[0-9]*\\|;\\|):\\|%then\\|%else\\)[ \t]*"
-                   "\\(data\\|endsas\\|finish\\|quit\\|run\\|start\\)[ \t\n;]")
-           font-lock-constant-face)
-     (cons (concat "\\(^[0-9]*\\|;\\|):\\|%then\\|%else\\)[ \t]*"
-                   ;;"proc[ \t]+[a-z][a-z_0-9]+")        font-lock-constant-face)
-                   "proc[ \t]+"
-                   ;;SAS/Base, SAS/Graph, SAS/FSP and common add-ons
-                   "\\(append"
-                   "\\|b\\(genmod\\|lifereg\\|phreg\\)"
-                   "\\|c\\(a\\(lendar\\|talog\\)\\|port\\|o\\(mpare\\|ntents\\|py\\|rr\\)\\)"
-                   "\\|d\\(atasets\\|bcstab\\|isplay\\)\\|ex\\(plode\\|port\\)"
-                   "\\|f\\(orm\\(at\\|s\\)\\|req\\|s\\(browse\\|edit\\|l\\(etter\\|ist\\)\\|view\\)\\)"
-                   "\\|g?\\(chart\\|p\\(lot\\|rint\\)\\)"
-                   "\\|g\\(anno\\|contour\\|device\\|font\\|\\(key\\)?map\\|options\\|project"
-                   "\\|re\\(duce\\|move\\|play\\)\\|slide\\|testit\\|3\\(d\\|grid\\)\\)"
-                   "\\|\\(map\\|[cg]\\)?import\\|i\\(ml\\|nsight\\)"
-                   "\\|means\\|options\\|p\\(menu\\|rintto\\)"
-                   "\\|r\\(ank\\|e\\(gistry\\|port\\)\\)"
-                   "\\|s\\(ort\\|ql\\|tandard\\|ummary\\)"
-                   "\\|t\\(abulate\\|emplate\\|imeplot\\|ran\\(spose\\|tab\\)\\)\\|univariate"
-                   ;;SAS/Stat and SAS/ETS
-                   "\\|a\\(ceclus\\|nova\\|rima\\|utoreg\\)\\|boxplot"
-                   "\\|c\\(a\\(lis\\|n\\(corr\\|disc\\)\\|tmod\\)\\|itibase\\|luster\\|o\\(mputab\\|rresp\\)\\)"
-                   "\\|discrim\\|expand\\|f\\(a\\(ctor\\|stclus\\)\\|orecast\\|req\\)"
-                   "\\|g\\(enmod\\|l\\(immix\\|m\\(mod\\|power\\|select\\)?\\)\\)\\|inbreed\\|k\\(de\\|rige2d\\)"
-                   "\\|l\\(attice\\|ife\\(reg\\|test\\)\\|o\\(ess\\|gistic\\)\\)"
-                   "\\|m\\(ds\\|ixed\\|o\\(de\\(clus\\|l\\)\\|rtgage\\)\\|ulttest\\)"
-                   "\\|n\\(ested\\|l\\(in\\|mixed\\)\\|par1way\\)\\|orthoreg"
-                   "\\|p\\(dlreg\\|hreg\\|l\\(an\\|s\\)\\|ower\\|r\\(in\\(comp\\|qual\\)\\|obit\\)\\)\\|r\\(sr\\)?eg"
-                   "\\|s\\(core\\|im\\(2d\\|lin\\)\\|pectra\\|t\\(atespace\\|dize\\|epdisc\\)\\|urvey\\(means\\|reg\\|select\\)\\|yslin\\)"
-                   "\\|t\\(phreg\\|pspline\\|r\\(ansreg\\|ee\\)\\|test\\)"
-                   "\\|var\\(clus\\|comp\\|iogram\\)\\|x11"
-                   "\\)")        font-lock-constant-face)
-
-     ;;(cons (concat "\\(^[0-9]*\\|;\\|%then\\|%else\\)[ \t]*"
-     ;;"\\(%\\(go[ \t]*to\\|i\\(f\\|n\\(clude\\|put\\)\\)\\|let\\|put\\|sysexec\\)\\)"
-     ;;"\\>")                               font-lock-constant-face)
-     (cons "\\<%\\(go[ \t]*to\\|i\\(f\\|n\\(clude\\|put\\)\\)\\|let\\|put\\|sysexec\\)\\>"
-           font-lock-constant-face)
-
-     (cons "\\<%\\(by\\|else\\|t\\(o\\|hen\\)\\)\\>"
-           font-lock-constant-face)
-
-     ;; SAS dataset options/PROC statements followed by an equal sign/left parentheses
-
-     (cons (concat
-            "[ \t(,]"
-            "\\(attrib\\|by\\|compress\\|d\\(ata\\|rop\\)\\|f\\(irstobs\\|ormat\\)"
-            "\\|i\\(d\\|f\\|n\\)\\|ke\\(ep\\|y\\)\\|l\\(abel\\|ength\\)"
-            "\\|o\\(bs\\|rder\\|ut\\)\\|rename\\|s\\(ortedby\\|plit\\)"
-            "\\|var\\|where\\)"
-            "[ \t]*=")
-           font-lock-keyword-face)
-     (cons "\\<\\(in\\(:\\|dex[ \t]*=\\)?\\|until\\|wh\\(en\\|ile\\)\\)[ \t]*("
-           font-lock-keyword-face)
-
-     ;; SAS statements
-     (cons (concat
-            "\\(^[0-9]*\\|):\\|[;,]\\|then\\|else\\)[ \t]*"
-            "\\(a\\(bort\\|rray\\|ttrib\\)\\|b\\(ayes\\|y\\)"
-            "\\|c\\(hange\\|lass\\|ontrast\\)"
-            "\\|d\\(elete\\|isplay\\|m\\|o\\([ \t]+\\(data\\|over\\)\\)?\\|rop\\)"
-            "\\|e\\(rror\\|stimate\\|xc\\(hange\\|lude\\)\\)"
-            "\\|f\\(ile\\(name\\)?\\|o\\(otnote\\(10?\\|[2-9]\\)?\\|rmat\\)\\|req\\)"
-            "\\|go\\([ \t]*to\\|ptions\\)"
-            "\\|hazardratio\\|[hv]bar\\(3d\\)?"
-            "\\|i\\(d\\|f\\|n\\(dex\\|f\\(ile\\|ormat\\)\\|put\\|value\\)\\)"
-            "\\|keep\\|l\\(abel\\|ength\\|i\\(bname\\|nk\\|st\\)\\|smeans\\)"
-            "\\|m\\(anova\\|e\\(ans\\|rge\\)\\|issing\\|od\\(el\\|ify\\)\\)\\|note"
-            "\\|o\\(ds\\|ptions\\|therwise\\|utput\\)\\|p\\(arms\\|lot2?\\|ut\\)"
-            "\\|r\\(andom\\|e\\(name\\|peated\\|tain\\)\\)"
-            "\\|s\\(ave\\|e\\(lect\\|t\\)\\|kip\\|trata\\|um\\(by\\)?\\)"
-            "\\|t\\(ables?\\|i\\(me\\|tle\\(10?\\|[2-9]\\)?\\)\\)\\|update"
-            "\\|va\\(lue\\|r\\)\\|w\\(eight\\|here\\|i\\(ndow\\|th\\)\\)"
-
-            ;; IML statements that are not also SAS statements
-            "\\|append\\|c\\(lose\\(file\\)?\\|reate\\)\\|edit\\|f\\(ind\\|orce\\|ree\\)"
-            "\\|insert\\|load\\|mattrib\\|p\\(a[ru]se\\|rint\\|urge\\)"
-            "\\|re\\(move\\|peat\\|place\\|set\\|sume\\)"
-            "\\|s\\(et\\(in\\|out\\)\\|how\\|ort\\|tore\\|ummary\\)\\|use\\)?"
-
-            "\\>")                                  font-lock-keyword-face)
-
-
-
-     ;;  (cons "\\<\\(\\(then\\|else\\)[ \t]*\\)?\\(do\\([ \t]*over\\)?\\|else\\)\\>"
-     ;;                                             font-lock-keyword-face)
-
-     ;; SAS statements that must be followed by a semi-colon
-     (cons (concat
-            "\\(^[0-9]*\\|):\\|[;,]\\|then\\|else\\)[ \t]*"
-            "\\(cards4?\\|datalines\\|end\\|l\\(ostcard\\)\\|page\\|stop\\)?"
-            "[ \t]*;")                      font-lock-keyword-face)
-
-     ;; SAS/GRAPH statements not handled above
-     (cons (concat
-            "\\(^[0-9]*\\|):\\|[;,]\\)[ \t]*"
-            "\\(axis\\|legend\\|pattern\\|symbol\\)"
-            "\\([1-9][0-9]?\\)?\\>")        font-lock-keyword-face)
-
-     ;; SAS Datastep functions and SAS macro functions
-                                        ;(cons "%[a-z_][a-z_0-9]*[ \t]*[(;]"
-     ;; SAS macro functions occasionally defined with no arguments
-     ;; which means they can be followed by any character that can
-     ;; separate tokens, however, they are most likely to be followed
-     ;; by operat-ions/ors
-     (cons "%[a-z_][a-z_0-9]*[- \t();,+*/=<>]"
-           font-lock-function-name-face)
-     (cons "\\<call[ \t]+[a-z_][a-z_0-9]*[ \t]*("
-           font-lock-function-name-face)
-
-     (cons (concat
-            "\\<"
-            "\\(a\\(bs\\|r\\(cos\\|sin\\)\\|tan\\)\\|b\\(etainv\\|yte\\)"
-            "\\|c\\(eil\\|inv\\|o\\(llate\\|mpress\\|sh?\\)\\|ss\\|v\\)"
-            "\\|dacc\\(db\\(\\|sl\\)\\|s\\(l\\|yd\\)\\|tab\\)"
-            "\\|dep\\(db\\(\\|sl\\)\\|s\\(l\\|yd\\)\\|tab\\)"
-            "\\|d\\(a\\(te\\(\\|jul\\|part\\|time\\)\\|y\\)\\|hms\\|i\\(f[0-9]*\\|m\\|gamma\\)\\)"
-            "\\|e\\(rfc?\\|xp\\)"
-            "\\|f\\(i\\(nv\\|p\\(namel?\\|state\\)\\)\\|loor\\|uzz\\)\\|gam\\(inv\\|ma\\)"
-            "\\|h\\(bound\\|ms\\|our\\)\\|i\\(n\\(dexc?\\|put\\|t\\(\\|ck\\|nx\\|rr\\)\\)\\|rr\\)"
-            "\\|juldate\\|kurtosis\\|l\\(ag[0-9]*\\|bound\\|e\\(ft\\|ngth\\)\\|gamma\\|og\\(\\|10\\|2\\)\\)"
-            "\\|m\\(ax\\|dy\\|ean\\|in\\(\\|ute\\)\\|o\\(d\\|nth\\|rt\\)\\)"
-            "\\|n\\(\\|etpv\\|miss\\|o\\(rmal\\|t\\)\\|pv\\)"
-            "\\|prob\\([ft]\\|b\\(eta\\|nml\\)\\|chi\\|gam\\|hypr\\|it\\|n\\(egb\\|orm\\)\\)"
-            "\\|ordinal\\|p\\(oisson\\|ut\\)\\|qtr\\|r\\(e\\(peat\\|verse\\)\\|ight\\|ound\\)"
-            "\\|ran\\(bin\\|cau\\|exp\\|g\\(am\\|e\\)\\|k\\|nor\\|poi\\|t\\(bl\\|ri\\)\\|uni\\)"
-            "\\|s\\(aving\\|can\\|econd\\|i\\(gn\\|nh?\\)\\|qrt\\|t\\(d\\(\\|err\\)\\|fips\\|namel?\\)\\|u\\(bstr\\|m\\)\\|ymget\\)"
-            "\\|t\\(anh?\\|i\\(me\\(\\|part\\)\\|nv\\)\\|oday\\|r\\(anslate\\|i\\(gamma\\|m\\)\\|unc\\)\\)"
-            "\\|u\\(niform\\|pcase\\|ss\\)\\|v\\(ar\\|erify\\)"
-            "\\|weekday\\|y\\(ear\\|yq\\)\\|zip\\(fips\\|namel?\\|state\\)"
-
-;;;    ;; SAS functions introduced in Technical Report P-222
-
-            "\\|airy\\|b\\(and\\|lshift\\|not\\|or\\|rshift\\|xor\\)"
-            "\\|c\\(nonct\\|ompbl\\)\\|d\\(airy\\|equote\\)\\|fnonct\\|tnonct"
-            "\\|i\\(bessel\\|n\\(dexw\\|put[cn]\\)\\)\\|jbessel\\|put[cn]"
-            "\\|lowcase\\|quote\\|resolve\\|s\\(oundex\\|ysprod\\)\\|tr\\(anwrd\\|imn\\)"
-
-;;;    ;; IML functions that are not also Datastep functions
-            "\\|a\\(ll\\|ny\\|pply\\|rmasim\\)\\|b\\(lock\\|ranks\\|tran\\)"
-            "\\|c\\(har\\|hoose\\|on\\(cat\\|tents\\|vexit\\|vmod\\)\\|ovlag\\|shape\\|usum\\|vexhull\\)"
-            "\\|d\\(atasets\\|esignf?\\|et\\|iag\\|o\\|uration\\)"
-            "\\|e\\(chelon\\|igv\\(al\\|ec\\)\\)\\|f\\(ft\\|orward\\)\\|ginv"
-            "\\|h\\(alf\\|ankel\\|dir\\|ermite\\|omogen\\)"
-            "\\|i\\(\\|fft\\|nsert\\|nv\\(updt\\)?\\)\\|j\\(\\|root\\)\\|loc\\|mad"
-            "\\|n\\(ame\\|col\\|leng\\|row\\|um\\)\\|o\\(pscal\\|rpol\\)"
-            "\\|p\\(olyroot\\|roduct\\|v\\)\\|r\\(anktie\\|ates\\|atio\\|emove\\|eturn\\|oot\\|owcatc?\\)"
-            "\\|s\\(etdif\\|hape\\|olve\\|plinev\\|pot\\|qrsym\\|ssq\\|torage\\|weep\\|ymsqr\\)"
-            "\\|t\\(\\|eigv\\(al\\|ec\\)\\|oeplitz\\|race\\|risolv\\|ype\\)"
-            "\\|uni\\(on\\|que\\)\\|v\\(alue\\|ecdiag\\)\\|x\\(mult\\|sect\\)\\|yield"
-
-;;;    ;; SCL functions that are known to work with SAS macro function %sysfunc
-
-            "\\|attr[cn]\\|c\\(exist\\|lose\\)\\|d\\(close\\|num\\|open\\|read\\)"
-            "\\|exist\\|f\\(close\\|etchobs\\|i\\(leexist\\|nfo\\)\\|open\\|put\\|write\\)"
-            "\\|get\\(option\\|var[cn]\\)\\|lib\\(name\\|ref\\)\\|op\\(en\\|t\\(getn\\|setn\\)\\)"
-            "\\|pathname\\|sysmsg\\|var\\(fmt\\|l\\(abel\\|en\\)\\|n\\(ame\\|um\\)\\|type\\)\\)"
-            "[ \t]*(")                      font-lock-function-name-face)
-     ))
-  "Font Lock regexs for SAS.")
-
-(defun beginning-of-sas-statement (arg &optional comstart)
-  "Move point to beginning of current sas statement."
-  (interactive "P")
-  (let ((pos (point))
-        )
-    (if (search-forward ";" nil 1) (forward-char -1))
-    (re-search-backward ";[ \n*/]*$" (point-min) 1 arg)
-    (skip-chars-forward sas-comment-chars)
-    (if comstart nil
-      (if (looking-at "\\*/")
-          (progn (forward-char 2)
-                 (skip-chars-forward sas-comment-chars)))
-      (while (looking-at "/\\*")
-        (if (not (search-forward "*/" pos t 1)) ;;(;; (point-max) 1 1)
-            (forward-char 2))
-        (skip-chars-forward sas-white-chars)))))
-
-(defun sas-indent-line ()
-  "Indent function for SAS mode."
-  (interactive)
-  (let (indent prev-end
-               (pos (- (point-max) (point)))
-               (case-fold-search t)
-               (cur-ind (current-indentation))
-               (comment-col (sas-comment-start-col))) ;; 2/1/95 TDC
-    (save-excursion
-      (cond ((progn
-               (back-to-indentation)
-               (or (bobp)
-                   (looking-at
-                    "data[ ;]\\|proc[ ;]\\|run[ ;]\\|quit[ ;]\\|endsas[ ;]\\|g?options[ ;]\\|%macro[ ;]\\|%mend[ ;]")))
-             ;;  Case where current statement is DATA, PROC, etc...
-             (setq prev-end (point))
-             (goto-char (point-min))
-             ;;  Added 6/27/94
-             ;;  May get fooled if %MACRO, %DO, etc embedded in comments
-             (setq indent
-                   (+ (* (- (sas-how-many "^[ \t]*%macro\\|[ \t]+%do"
-                                          prev-end)
-                            (sas-how-many "^[ \t]*%mend\\|%end" prev-end))
-                         sas-indent-width) comment-col)))  ;; 2/1/95 TDC
-            ;;  Case where current line begins with sas-indent-ignore-comment
-            ;; added 6/27/94  to leave "* ;" comments alone.
-            ((progn
-               (back-to-indentation)
-               (and (not (looking-at "\\*/"))
-                    (looking-at (concat sas-indent-ignore-comment "\\|/\\*"))))
-             (setq indent (current-indentation)))
-            ;;  Case where current statement not DATA, PROC etc...
-            (t (beginning-of-line 1)
-               (skip-chars-backward sas-white-chars)
-               (if (bobp) nil
-                 (backward-char 1))
-               (cond
-                ((looking-at ";")       ;  modified 1/31/95
-                 (setq indent (sas-next-statement-indentation)))
-                ((save-excursion;; added 4/28/94 to properly check
-                   (if (bobp) () (backward-char 1));; for end of comment
-                   (setq prev-end (point))
-                   (looking-at "\\*/"));;  improved 1/31/95
-                 (save-excursion
-                   (search-backward "*/"
-                                    (point-min) 1 1); comment start is first /*
-                   (search-forward "/*"
-                                   prev-end 1 1)    ; after previous */
-                   (backward-char 2)                ; 2/1/95 TDC
-                   (skip-chars-backward sas-white-chars)
-                   (setq indent
-                         (if (bobp) 0
-                           (if (looking-at ";")
-                               (sas-next-statement-indentation)
-                             ;;(+ (current-indentation) sas-indent-width)
-                             (current-indentation))))))
-
-                ;; added 6/27/94 to leave "* ;" comments alone
-                ((save-excursion
-                   (progn
-                     (beginning-of-sas-statement 1 t)
-                     (and (not (looking-at "\\*/"))
-                          (looking-at sas-indent-ignore-comment))))
-                 (setq indent cur-ind))
-                ((progn
-                   (beginning-of-sas-statement 1)
-                   (bobp));; added 4/13/94
-                 (setq indent sas-indent-width));; so the first line works
-                ((save-excursion
-                   (beginning-of-sas-statement 2)
-                   (looking-at "cards4?;\\|datalines4?;\\|lines4?;"))
-                 (setq indent (current-indentation))) ; So cards keep indentation.
-                (t
-                 (if (progn
-                       (save-excursion
-                         (beginning-of-line 1)
-                         (skip-chars-backward sas-white-chars)
-                         (if (bobp) nil (backward-char 1))
-                         (or (looking-at ";")
-                             (bobp) (backward-char 1) (looking-at "\\*/"))))
-                     (setq indent (+ (current-indentation) sas-indent-width))
-                   (setq indent (current-indentation))))))))
-    (save-excursion
-      (let (beg end)
-        (back-to-indentation)
-        (setq end (point))
-        (beginning-of-line 1)
-        (setq beg (point))
-        (delete-region beg end)
-        (indent-to indent)))
-    (if (> (- (point-max) pos) (point))
-        (goto-char (- (point-max) pos)))))
-
-
-;;(defun sas-indent-region (start end)
-;;  "Indent a region of SAS code."
-;;  (interactive "r")
-;;  (save-excursion
-;;    (let ((endmark (copy-marker end)))
-;;      (goto-char start)
-;;      (and (bolp) (not (eolp))
-;;         (sas-indent-line))
-;;      (indent-sexp endmark)
-;;      (set-marker endmark nil))))
-
-
-(defun indent-sas-statement (arg)
-  "Indent all continuation lines sas-indent-width spaces from first
-line of statement."
-  (interactive "p")
-  (let (end)
-    (save-excursion
-      (if (> arg 0)
-          (while (and (> arg 0) (search-forward ";" (point-max) 1 1))
-            (setq end (point))
-            (if (bobp) nil (backward-char 1))
-            (beginning-of-sas-statement 1)
-            (forward-char 1)
-            (indent-region (point)
-                           end
-                           (+ (current-column) (1- sas-indent-width)))
-            (search-forward ";" (point-max) 1 1)
-            (setq arg (1- arg)))))))
-
-;; added 9/31/94
-(defun sas-next-statement-indentation ()
-  "Returns the correct indentation of the next sas statement.
-The current version assumes that point is at the end of the statement.
-This will (hopefully) be fixed in later versions."
-  (if (bobp) 0
-    (save-excursion
-      (let ((prev-end (point)))
-        (beginning-of-sas-statement 1)
-        (while (and (not (bobp))
-                    (not (looking-at "\\*/"))
-                    (looking-at sas-indent-ignore-comment))
-          (skip-chars-backward sas-white-chars)
-          (if (bobp) nil
-            (backward-char 1))
-          (setq prev-end (point))
-          (beginning-of-sas-statement 1 t))
-        (if (or
-             (looking-at
-              (concat "data[ \n\t;]\\|"
-                      (regexp-opt '("cards;" "cards4;" "datalines;" "datalines4;" "lines;" "lines4;"))
-                      "\\|proc[ \n\t]\\|%?do[ \n\t;]\\|%macro[ \n\t]\\|/\\*"))
-             (save-excursion
-               (re-search-forward
-                "\\b%?then\\>[ \n\t]*\\b%?do\\>\\|\\b%?else\\>[ \n\t]*\\b%?do\\>"
-                prev-end 1 1))) ; fixed 1/30/95 to avoid being fooled by
-                                        ; variable names starting with "do"
-            (+ (current-indentation) sas-indent-width)
-          (if (looking-at "%?end[ ;\n]\\|%mend[ ;\n]\\|\\*/")
-              (max (- (current-indentation) sas-indent-width) 0)
-            (current-indentation)))))))
-
-;; added 2/1/95
-(defun sas-comment-start-col ()
-  "If the current line is inside a /* */ comment, returns column in which the
-opening /* appears.  returns 0 otherwise."
-  (let ((pos (point)))
-    (save-excursion
-      (if (and (search-backward "*/" (point-min) 1 1)
-               (search-forward "/*" pos 1 1))
-          (current-indentation)
-        0))))
-
-
-;;  Created 6/27/94 to verify that RUN; statements match PROC and DATA
-;;  statements.  Useful since indentation my be goofy w/o "RUN;"
-(defun sas-check-run-statements ()
-  "Check to see that \"run\" statements are matched with proc, data statements."
-  (interactive)
-  (let (pos
-        (ok t)
-        (eob-ok t))
-    (save-excursion
-      (beginning-of-line)
-      (while ok
-        (if (re-search-forward
-             "\\(^[ \t]*run[ ;]\\)\\|\\(^[ \t]*proc \\|^[ \t]*data[ ;]\\)"
-             nil 1)
-            (if (match-beginning 2)
-                (if (re-search-forward
-                     "\\(^[ \t]*run[ ;]\\)\\|\\(^[ \t]*proc \\|^[ \t]*data[ ;]\\)"
-                     nil t)
-                    (progn (setq pos (point))
-                           (setq ok (match-beginning 1)))
-                  (setq eob-ok nil pos (point-max))))
-          (setq ok nil)))
-      (setq ok (eobp)))
-    (if (and ok eob-ok) (message "Run statements match")
-      (goto-char pos)
-      (beep)
-      (message "Missing Run Statement."))))
-
-(defun sas-fix-life-tables ()
-  "Remove censored and duplicate observations from life tables generated by
-Proc Lifetest.  Operates on current region.  A major space saver if there is
-heavy censoring."
-  (interactive)
-  (if buffer-read-only (setq buffer-read-only nil))
-  (goto-char (point-min))
-  (while (re-search-forward "^.*[ ]+[.][ ]+[.][ ]+[.][ ]+.*$" nil t)
-    (replace-match "" nil nil)))
-                                        ;  (save-excursion
-                                        ;    (shell-command-on-region
-                                        ;     start end
-                                        ;     "sed '/[ ][.][ ]/d'" t)))
-;;"sed \"\\?          *\\.          *\\.          *\\.    ?d\"" t)))
-;;(vip-goto-line 1)
-;;(setq ex-g-flag nil
-;;ex-g-variant nil)
-;;(vip-ex "1,$g/           \\.           \\.           \\.    /d")))
-
-(defun sas-fix-page-numbers (offset &optional page-num)
-  "Fix number of current page in sas output files after editing.  Add
-OFFSET to actual page number."
-  (interactive "P")
-  (if (not offset) (setq offset 0))
-  (if (not page-num) (setq page-num (sas-page-number)))
-  (save-excursion
-    (if (/= (preceding-char) ?\C-l) (backward-page 1))
-    (let (end len mstart mend)
-      (save-excursion
-        (forward-line sas-page-number-max-line)
-        (setq end (point)))
-      (if (re-search-forward
-           "\\(^[0-9]+[ ]\\)\\|\\([ ][0-9]+$\\)"
-           end t)
-          (progn (setq len (- (match-end 0) (match-beginning 0))
-                       mstart (match-beginning 0)
-                       mend (match-end 0))
-                 (delete-region mstart mend)
-                 (if (eolp)
-                     (insert (format
-                              (concat "%" len "d") (+ page-num offset)))
-                   (insert (substring
-                            (concat (+ (sas-page-number) offset) "      ")
-                            0 len))))))))
-
-(defun sas-page-fix (start)
-  "Fix page numbers in sas output from point to end of file.
-If START is given this will be the number for the current page."
-  (interactive "P")
-  (let (offset (pnum (sas-page-number)))
-    (if (not start) (setq offset 0)
-      (setq offset (- start pnum)))
-    (while (not (eobp))
-      (sas-fix-page-numbers offset pnum)
-      (setq pnum (1+ pnum))
-      (forward-page 1))))
-
-(defun fix-page-breaks ()
-  "Fix page breaks in SAS 6 print files."
-  (interactive)
-  (save-excursion
-    (goto-char (point-min))
-    (if (looking-at "\f") (delete-char 1))
-                                        ;(replace-regexp "^\\(.+\\)\f" "\\1\n\f\n")
-    (while (re-search-forward "^\\(.+\\)\f" nil t)
-      (replace-match "\\1\n\f\n" nil nil))
-    (goto-char (point-min))
-                                        ;(replace-regexp "^\f\\(.+\\)" "\f\n\\1")
-    (while (re-search-forward "^\f\\(.+\\)" nil t)
-      (replace-match "\f\n\\1" nil nil))
-                                        ;    (goto-char (point-min))
-                                        ;(replace-regexp " $" "")
-                                        ;(while (re-search-forward "$" nil t)
-                                        ;     (replace-match "" nil nil))
-    (goto-char (point-min))
-                                        ;(replace-regexp " \\([^\\$]+\\)" "\n\\1")
-    (while (re-search-forward " \\([^\\$]+\\)" nil t)
-      (replace-match "\n\\1" nil nil))
-    (goto-char (point-max))
-    (if (not (bobp))
-        (progn (backward-char 1)
-               (if (not (looking-at "\n"))
-                   (progn (forward-char 1) (open-line 1)))))))
-
-(defun sas-page-number ()
-  ;; like what-page except it returns an integer page number
-  "Return page number of point in current buffer."
-  (let ((opoint (point))) (save-excursion
-                            (goto-char (point-min))
-                            (1+ (sas-how-many page-delimiter opoint)))))
-
-(defun sas-how-many (regexp &optional end)
-  ;; a copy of `how-many' which returns an integer
-  ;; rather than a message
-  "Return number of matches for REGEXP following point."
-  (let ((count 0) opoint)
-    (save-excursion
-      (while (and (not (eobp))
-                  (progn (setq opoint (point))
-                         (re-search-forward regexp end t)))
-        (if (= opoint (point))
-            (forward-char 1)
-          (setq count (1+ count))))
-      count)))
-
-(defun beginning-of-sas-proc ()
-  "Move point to beginning of sas proc, macro or data step."
-  (interactive)
-  (let ((case-fold-search t))
-    (forward-char -1)
-    (while (not (or (looking-at "data\\|proc\\|%macro")
-                    (bobp)))
-      (re-search-backward "proc\\|data\\|%macro" (point-min) 1)
-      (beginning-of-sas-statement 1))))
-
-(defun next-sas-proc (arg)
-  "Move point to beginning of next sas proc."
-  (interactive "P")
-  (let ((case-fold-search t))
-    (forward-char 1)
-    (if (re-search-forward
-         "^[ \t]*\\(data[ ;]\\|proc[ ;]\\|endsas[ ;]\\|g?options[ ;]\\|%macro[ ;]\\)"
-         nil t arg)
-        (beginning-of-sas-statement 1)
-      (forward-char -1))))
-
-(defun set-sas-file-name ()
-  "Stores the name of the current sas file."
-  (let ((name (buffer-file-name)))
-    (cond ((not name))
-          ((string-match (substring name -4 nil)
-                         "\\.sas\\|\\.lst\\|\\.log")
-
-           (setq sas-file-name (substring name 0 (- (length name) 4)))
-           (setq sas-buffer-name (buffer-name))
-           (setq sas-file-root (substring sas-buffer-name 0
-                                          (- (length sas-buffer-name) 4))))
-          (t (message "This file does not have a standard suffix")))))
-
-;;  created 6/27/94
-(defun sas-set-alternate-file-name (name)
-  "Stores the NAME of an alternate sas file.
-When this file is submitted with `submit-sas', the alternate file will
-be submitted instead.  `sas-submitable' is automatically sets to t."
-  (interactive "f")
-  (cond ((string-match (substring name -4 nil)
-                       "\\.sas\\|\\.lst\\|\\.log")
-         (setq sas-file-name (substring name 0 (- (length name) 4)))
-         (setq sas-submitable t))
-        (t (message "This file does not have a standard suffix"))))
-
-(defun switch-to-sas-source ()
-  "Switches to sas source file associated with the current file."
-  (interactive)
-  (switch-to-sas-file "sas"))
-
-(defun switch-to-sas-lst ()
-  "Switches to sas source file associated with the current file."
-  (interactive)
-  (switch-to-sas-file "lst"))
-
-(defun switch-to-sas-log ()
-  "Switches to sas source file associated with the current file."
-  (interactive)
-  (switch-to-sas-file "log"))
-
-(defun switch-to-sas-source-other-window ()
-  "Switches to sas source file associated with the current file."
-  (interactive)
-  (switch-to-sas-file-other-window "sas"))
-
-(defun switch-to-sas-lst-other-window ()
-  "Switches to sas source file associated with the current file."
-  (interactive)
-  (switch-to-sas-file-other-window "lst"))
-
-(defun switch-to-sas-log-other-window ()
-  "Switches to sas source file associated with the current file."
-  (interactive)
-  (switch-to-sas-file-other-window "log"))
-
-;;(defun switch-to-sas-file (suff &optional revert silent)
-;;  "Switches to sas \"SUFF\" file associated with the current file"
-;;  (let* ((sfile sas-file-name)
-;;       (buf (get-file-buffer (concat sfile "." suff)))
-;;       (sas-require-confirmation
-;;           (and sas-require-confirmation (not revert))))
-;;     (if (or sas-require-confirmation (string-equal suff "sas") (not buf))
-;;         (find-file (concat sfile "." suff))
-;;       (progn (switch-to-buffer buf)
-;;              (if (not (verify-visited-file-modtime (current-buffer)))
-;;                  (progn (revert-buffer t t)
-;;                         (if (not silent)
-;;                             (message "File has changed on disk.  Buffer automatically updated."))))))
-;;     (setq sas-file-name sfile))
-;;   (if (string-equal suff "sas")
-;;       (if (not (string-equal major-mode "sas-mode"))
-;;           (sas-mode))
-;;     (if (not (string-equal major-mode "sasl-mode"))
-;;         (sasl-mode))))
-;;
-;;(defun switch-to-sas-file-other-window (suff)
-;;  "Switches to sas \"SUFF\" file associated with the current file"
-;;  (let* ((sfile sas-file-name)
-;;       (buf (get-file-buffer (concat sfile "." suff))))
-;;    (if (or sas-require-confirmation (string-equal suff "sas") (not buf))
-;;      (find-file-other-window (concat sfile "." suff))
-;;      (progn (switch-to-buffer-other-window buf)
-;;           (if (not (verify-visited-file-modtime (current-buffer)))
-;;               (progn (revert-buffer t t)
-;;                      (message "File has changed on disk.  Buffer automatically updated.")))))
-;;    (setq sas-file-name sfile))
-;;  (if (string-equal suff "sas")
-;;      (if (not (string-equal major-mode "sas-mode"))
-;;        ;;(sas-mode)
-;;        )
-;;    (if (not (string-equal major-mode "sasl-mode"))
-;;      ;;(sasl-mode)
-;;      )))
-
-(defun switch-to-sas-file (suff)
-  "Switches to sas \"SUFF\" file associated with the current file."
-  (switch-to-buffer (set-sas-file-buffer suff)))
-
-(defun switch-to-sas-file-other-window (suff)
-  "Switches to sas \"SUFF\" file associated with the current file."
-  (switch-to-buffer-other-window (set-sas-file-buffer suff)))
-
-;;  The following was created 6/7/94 to handle buffers without messing up
-;;  windows.
-
-(defun set-sas-file-buffer (suff &optional revert silent)
-  "Sets current buffer to sas \"SUFF\" file associated with the current file."
-  (let* ((sfile sas-file-name)
-         (buf (get-file-buffer (concat sfile "." suff)))
-         (sas-require-confirmation
-          (and sas-require-confirmation (not revert))))
-    (if (or sas-require-confirmation (string-equal suff "sas") (not buf))
-        (set-buffer (find-file-noselect (concat sfile "." suff)))
-      (progn (set-buffer buf)
-             (if (not (verify-visited-file-modtime (current-buffer)))
-                 (progn (revert-buffer t t)
-                        (if (not silent)
-                            (message "File has changed on disk.  Buffer automatically updated."))))))
-    (setq sas-file-name sfile))
-  ;;(if (string-equal suff "sas")
-  ;; (if (not (string-equal major-mode "sas-mode")) (sas-mode))
-  ;; (if (not (string-equal major-mode "sasl-mode"))(sasl-mode))
-  (current-buffer))
-
-(defun switch-to-sas-process-buffer ()
-  "Switch to sas-process-buffer."
-  (interactive)
-  (let (buf proc-name)
-    (setq proc-name (concat "SAS" sas-file-name)
-          buf (concat "*" proc-name "*"))
-    (switch-to-buffer-other-window buf)))
-
-(defun submit-sas ()
-  ;; 6/17/94  added sas-submitable local variable.
-  "Submit SAS file as shell command."
-  (interactive)
-  (if ;; can file be run, or is it only for inclusion?
-      (or sas-submitable
-          (progn
-            (beep)
-            (y-or-n-p
-             (format
-              "Submission is disabled for this file.  Submit it anyway? "))))
-      (progn
-        ;; if buffer name has changed, tell user
-        (if (or
-             (string-equal sas-buffer-name (buffer-name))
-             (not
-              (y-or-n-p
-               (format
-                "The name of this buffer has changed.  Submit the new file? "))))
-            (setq sas-buffer-name (buffer-name))
-          (set-sas-file-name))
-        (let ((sas-file sas-file-name)
-              (sas-root sas-file-root)
-              ;;(sas-buf  sas-buffer-name)
-              proc-name
-              buf)
-
-          ;; Save buffer to SAS the right file :-).
-          (if (buffer-modified-p)
-              (if (y-or-n-p (format "Buffer %s is modified. Save it? "
-                                    (buffer-name)))
-                  (save-buffer)))
-          (setq proc-name (concat "SAS" sas-file)
-                buf (concat "*" proc-name "*"))
-          (if (get-buffer buf)
-              (save-window-excursion (switch-to-buffer buf)
-                                     (erase-buffer)
-                                     (setq default-directory
-                                           (file-name-directory sas-file))))
-
-          (run-hooks 'sas-pre-run-hook)  ;; added 8/24/94
-          (message "----  Submitting SAS job   ----")
-          ;; (switch-to-buffer buf)
-          (make-comint proc-name
-                       sas-program     ;added sas-program 4/29/94
-                       nil
-                       sas-root)
-          (save-window-excursion
-            (switch-to-buffer buf)
-            (setq sas-file-name sas-file)
-            (bury-buffer buf))
-
-          (message "----  SAS job submitted  ----   ")
-
-          (if sas-notify;;  added 4/7/94
-              (set-process-sentinel (get-process proc-name) #'sas-sentinel)
-            (display-buffer buf t))))
-    (message "----  File not submitted  ----")))
-
-;; 5/2/94 Modified sas-sentinel to check for errors in log file upon
-;; completion.
-(defun sas-sentinel (proc arg);; created 4/7/94
-  "Notify user that SAS run is done."
-  (beep)
-  ;;(if (string-equal arg "finished\n")
-  (save-excursion
-    (let (msg buf win (sbuf (concat "*" (process-name proc) "*")))
-      (setq msg
-            (format "SAS %s %s"
-                    (substring arg 0 -1)
-                    (if sas-error-notify
-                        ;;(save-window-excursion
-                        (progn
-                          (set-buffer sbuf)
-                          (setq buf (set-sas-file-buffer "log" t t))
-                          (goto-char (point-min))
-                          (setq win (get-buffer-window buf))
-                          (save-window-excursion
-                            (if win
-                                (progn
-                                  (select-window win)
-                                  (if (re-search-forward "^ERROR" nil t)
-                                      " (See .log file for errors)"
-                                    ""))
-                              (switch-to-buffer buf)
-                              (if (re-search-forward "^ERROR" nil t)
-                                  " (See .log file for errors)"
-                                ""))))
-                      "")))
-      (set-buffer sbuf)
-      (goto-char (point-max))
-      (insert msg)
-      (bury-buffer (get-buffer sbuf))
-      ;;(if (and sas-notify-popup window-system)
-      ;;    (x-popup-dialog t
-      ;;                (list "SAS Menu" (cons msg  nil) )))
-      ;;(if (not (minibuffer-window-active-p)) (princ msg))
-      (princ msg))))
-
-;; 5/2/94 Modified run-sas-on-region to separate log and output buffers.
-;;
-;;(defun run-sas-on-region (start end append &optional buffer)
-;;  "Submit region to SAS"
-;;  (interactive "r\nP")
-;;  (message "----  Running SAS  ----")
-;;  (let ((sfile sas-file-name)
-;;        (shell-file-name "/bin/sh")
-;;        serror buff)
-;;    (setq buffer (or buffer "*SAS output*"))
-;;    (save-excursion
-;;      (shell-command-on-region
-;;       start end;; added sas-program
-;;       (concat sas-program " -nonews -stdio 2> /tmp/_temp_.log" nil))
-;;      (get-buffer-create "*SAS Log*")
-;;      (save-window-excursion
-;;        (switch-to-buffer "*SAS Log*")
-;;        (erase-buffer)
-;;        (insert-file-contents "/tmp/_temp_.log")
-;;        (delete-file "/tmp/_temp_.log")
-;;        (setq serror (re-search-forward "^ERROR" nil t))
-;;        (if serror () (bury-buffer)))
-;;      (setq buff (get-buffer-create buffer))
-;;      (save-window-excursion
-;;        (switch-to-buffer buff)
-;;        (setq sas-file-name sfile)
-;;        (if append
-;;            (progn
-;;              (end-of-buffer)
-;;              (insert "\f\n"))
-;;          (erase-buffer))
-;;        (if (get-buffer "*Shell Command Output*")
-;;            (progn (insert-buffer "*Shell Command Output*")
-;;                   (kill-buffer "*Shell Command Output*"))
-;;          (insert "SAS completed with no output."))
-;;        (if append () (sasl-mode))
-;;        (message "----  SAS Complete ----")))
-;;    (if (not serror)
-;;        (switch-to-buffer-other-window  buff)
-;;      (switch-to-buffer-other-window "*SAS Log*")
-;;      (goto-char serror)
-;;      (beep)
-;;      (message "Error found in log file.")
-;;      )))
-
-(defun switch-to-dataset-log-buffer ()
-  "Switch to log buffer for run-sas-on-region."
-  (interactive)
-  (switch-to-buffer-other-window "*SAS Log*"))
-
-(defun switch-to-dataset-source-buffer ()
-  "Switch to source buffer for run-sas-on-region."
-  (interactive)
-  (switch-to-buffer-other-window (format " *sas-tmp-%s*" sas-dataset)))
-
-;;(defun sas-get-dataset (filename &optional arg opts-p append buffer vars)
-;;  "Run proc contents and proc print on SAS dataset.  Automatically prompts
-;;for SAS options to use.  Default options are defined by the variable
-;;`sas-get-options'.  Output may be updated from within output buffer with
-;;C-cr if dataset changes.  Also, the source code which generates the output
-;;may be edited with C-cs.  Typing C-cr within the output buffer reexecutes
-;;the (modified) source code."
-;;  (interactive "fName of SAS dataset (file name):")
-;;  (let ((file (file-name-nondirectory filename))
-;;        (dir (file-name-directory filename))
-;;        (opts sas-get-options)
-;;        (minibuffer-history sas-get-options-history)
-;;        buf); fsize)
-;;    (setq buffer (or buffer (concat "*" file "*")))
-;;    (setq opts (if opts-p opts (read-string "SAS options: " opts)))
-;;    (setq sas-get-options-history minibuffer-history)
-;;    (cond ((string-match (substring file -6 nil) "\\.ssd01")
-;;      (setq file (substring file 0 (- (length file) 6))))
-;;    (t (error "This file is not a SAS dataset.")))
-;;    (setq buf (format " *sas-tmp-%s*" file))
-;;    (get-buffer-create buf)
-;;    (save-window-excursion
-;;      (switch-to-buffer buf)
-;;      (erase-buffer)
-;;      (setq default-directory dir)
-;;      (if opts
-;;          (insert (format "options  %s ;\n" opts)))
-;;      (insert (format "title \"Contents of SAS dataset `%s'\" ;\n" file))
-;;      (insert (format "libname %s '%s' ;\n" sas-tmp-libname dir))
-;;      (if (not (equal arg 1))
-;;               (insert (format "proc contents data = %s.%s ;\n" sas-tmp-libname file)))
-;;      (if (equal arg 2) ()
-;;        (insert (format "proc print data = %s.%s ;\n" sas-tmp-libname file))
-;;        (if vars (insert (format "  var %s ;\n" vars))))
-;;      (run-sas-on-region (point-min) (point-max) append
-;;                         buffer)
-;;      (get-buffer buffer)
-;;      (if append () (sasd-mode))  ;; added 5/5/94
-;;      (setq sas-dataset file))
-;;    (if (get-buffer-window buffer t)
-;;        (raise-frame (window-frame (get-buffer-window buffer t)))
-;;    (display-buffer buffer (not append)))
-;;    ))
-
-;;(defun revert-sas-dataset ()
-;;  "Revert current sas dataset from disk version"
-;;  (interactive)
-;;  (let* ((file sas-dataset)
-;;        (buf (format " *sas-tmp-%s*" file))
-;;        (pos (point)))
-;;      (save-window-excursion
-;;        (switch-to-buffer buf)
-;;        (run-sas-on-region (point-min) (point-max) nil
-;;                           (concat "*" file ".ssd01*"))
-;;        )
-;;      (goto-char pos)  ;; added 6/9/94
-;;    (sasd-mode)  ;; added 5/5/94
-;;    (setq sas-dataset file)))
-
-(defun sas-insert-local-variables ()  ;; created 6/17/94
-  "Add local variables code to end of sas source file."
-  (interactive)
-  (save-excursion
-    (if (re-search-forward "\\* *Local Variables: *;" nil t)
-        ()
-      (goto-char (point-max))
-      (insert "
-
-**  Local Variables:  ;
-**  End:  ;
-page ;
-"))))
-
-\f
-;;  variables section
-(defvar sas-dir-mode-map nil)
-(defvar-local sas-directory-name nil
-  "Name of directory associated with this buffer.")
-(defvar-local sas-dir-buf-end nil)
-(defvar-local sas-sorted-by-num nil)
-;; user variables
-\f
-;; keymaps etc...
-
-(if sas-dir-mode-map ()
-  (setq sas-dir-mode-map (make-sparse-keymap))
-  (define-key sas-dir-mode-map "m" #'sas-mark-item)
-  (define-key sas-dir-mode-map "u" #'sas-unmark-item)
-  (define-key sas-dir-mode-map " " #'sas-next-line)
-  (define-key sas-dir-mode-map "\C-n" #'sas-next-line)
-  (define-key sas-dir-mode-map "\C-p" #'sas-prev-line)
-  (define-key sas-dir-mode-map "\177" #'sas-prev-line-undo)
-  (define-key sas-dir-mode-map "\C-b" #'sas-backward-page-narrow)
-  (define-key sas-dir-mode-map "\C-v" #'sas-forward-page-narrow)
-  (define-key sas-dir-mode-map "\C-m" #'sas-goto-dataset)
-  (define-key sas-dir-mode-map "t" #'sas-dir-goto-page)
-  (define-key sas-dir-mode-map "q" #'bury-buffer)
-  (define-key sas-dir-mode-map "1" #'digit-argument)
-  (define-key sas-dir-mode-map "2" #'digit-argument)
-  (define-key sas-dir-mode-map "3" #'digit-argument)
-  (define-key sas-dir-mode-map "4" #'digit-argument)
-  (define-key sas-dir-mode-map "5" #'digit-argument)
-  (define-key sas-dir-mode-map "6" #'digit-argument)
-  (define-key sas-dir-mode-map "7" #'digit-argument)
-  (define-key sas-dir-mode-map "8" #'digit-argument)
-  (define-key sas-dir-mode-map "9" #'digit-argument)
-  (define-key sas-dir-mode-map [menu-bar sas run]
-    '("Submit File " . submit-sas))
-  )
-
-(define-derived-mode sas-dir-mode special-mode "SAS"
-  "Major mode for managing sas files."
-  :group 'ess-sas
-  (setq sas-directory-name (expand-file-name default-directory)))
-
-
-;;(defun sas-make-library (directory &optional update)
-;;  "Create a buffer with the names of all sas datasets from DIRECTORY."
-;;  (interactive "DDirectory Name: ")
-;;  (let ((dir (expand-file-name directory)) buf out cont pos)
-;;    (setq buf (format " *sas-tmp-%s*" dir))
-;;    (setq out (concat "*SAS-dir-" dir))
-;;    (setq cont (concat "*SAS-cont-" dir))
-;;    (get-buffer-create buf)
-;;    (if (get-buffer out)
-;;        (if update
-;;            (progn
-;;              (set-buffer out)
-;;              (setq buffer-read-only nil)))
-;;      (setq update t))
-;;    (pop-to-buffer out)
-;;    (setq default-directory dir)
-;;    (setq pos (point))
-;;    (if update
-;;        (progn
-;;          (save-window-excursion
-;;            (set-buffer buf)
-;;            (erase-buffer)
-;;            (setq default-directory dir)
-;;            (insert "options linesize=70 pagesize=1000 ;\n")
-;;            (insert (format "title \"Contents of SAS directory `%s'\" ;\n"
-;;                            dir))
-;;            (insert (format "libname %s '%s' ;\n" sas-tmp-libname dir))
-;;            (insert (format "proc contents data = %s._all_ directory details memtype=data ;\n" sas-tmp-libname))
-;;            (run-sas-on-region (point-min) (point-max) nil
-;;                               out)
-;;            (set-buffer out)
-;;            (goto-char (point-min))
-;;            (if (= (sas-how-many page-delimiter (point-max)) 0)
-;;                (let ((buffer-read-only nil))
-;;                  (erase-buffer)
-;;                  (insert "There are no SAS datasets in this directory")
-;;                  (pop-to-buffer out))
-;;              (save-excursion
-;;                (set-buffer (get-buffer-create cont))
-;;                (setq buffer-read-only t)
-;;                (let ((buffer-read-only nil))
-;;                  (erase-buffer)
-;;                  (insert-buffer out)
-;;                  (delete-region (point-min)
-;;                                 (or (re-search-forward page-delimiter nil t)
-;;                                     (point-min)))
-;;                  (sas-page-fix 1)
-;;                  (goto-char (point-min))
-;;                  (sas-dir-mode)
-;;                  (sas-narrow-to-page)))
-;;              (if (re-search-forward page-delimiter nil t)
-;;                  (delete-region (progn (beginning-of-line) (point))
-;;                                 (point-max)))
-;;              (sas-insert-set-properties (point-min) (point-max))
-;;              )
-;;            (switch-to-buffer out t)
-;;            (goto-char (point-min))
-;;            (sas-dir-mode)
-;;            (setq sas-dir-buf-end (point-max)))
-;;          (goto-char pos)
-;;          (sas-move-to-filename (point-max))))))
-
-
-(defun sas-move-to-filename (&optional eol)
-  (or eol (setq eol (progn (end-of-line) (point))))
-  (beginning-of-line)
-  (if (re-search-forward "\\(^ *[0-9]+ *<*\\)[^:0-9\n]" eol t)
-      (goto-char (match-end 1))))
-
-(defun sas-next-line (arg)
-  "Move down one line."
-  (interactive "p")
-  (forward-line arg)
-  (sas-move-to-filename (point-max)))
-;;(and (< (point) sas-dir-buf-end)
-;;(forward-line arg)
-;;(sas-move-to-filename sas-dir-buf-end)))
-
-(defun sas-prev-line (&optional _arg)
-  "Move up one line."
-  (interactive)
-  (beginning-of-line)
-  (re-search-backward "^ *[0-9]+ *<*[^:0-9\n]" (point-min) t)
-  (sas-move-to-filename sas-dir-buf-end))
-
-(defun sas-insert-set-properties (beg end)
-  (save-excursion
-    (goto-char beg)
-    (while (< (point) end)
-      (if (sas-move-to-filename)
-          (put-text-property (point)
-                             (+ 8 (point))
-                             'mouse-face 'highlight))
-      (forward-line 1))))
-
-(defun sas-get-filename ()
-  "Return name of dataset on current line."
-  (interactive)
-  (save-excursion
-    (if (string-equal "*SAS-dir" (substring (buffer-name) 0 8))
-        (sas-move-to-filename)
-      (goto-char (point-min))
-      (re-search-forward "Data Set Name: [^.]*\\."))
-    (expand-file-name
-     (downcase (concat sas-directory-name
-                       (buffer-substring
-                        (point)
-                        (save-excursion
-                          (skip-chars-forward "A-Z0-9_")
-                          (point))) ".ssd01")))))
-
-(defun sas-get-file-number ()
-  "Return name of dataset on current line."
-  (interactive)
-  (if (sas-move-to-filename)
-      (progn (forward-word -1)
-             (re-search-forward "[0-9]*")
-             (string-to-number
-              (buffer-substring (match-beginning 0)
-                                (match-end 0))))))
-
-(defun sas-goto-page (arg)
-  "Goto top of page ARG.  If no ARG, then goto top of file."
-  (interactive "P")
-  (goto-char 1)
-  (if arg
-      (if (> arg 1)
-          (progn
-            (re-search-forward page-delimiter (point-max) 1 (1- arg)))))
-  (skip-chars-forward sas-white-chars); was " \f\n" till 5.1.13
-  (recenter 1))
-
-(defun forward-page-top-of-window (arg)
-  "Move forward to page boundary and leave first line at top of window.
-With arg, repeat, or go back if negative. A page boundary is any line
-whose beginning matches the regexp `page-delimiter'."
-  (interactive "p")
-  (forward-page arg)
-  (recenter 0))
-
-(defun backward-page-top-of-window (arg)
-  "Move backward to page boundary and leave first line at top of window.
-With arg, repeat, or go back if negative. A page boundary is any line
-whose beginning matches the regexp `page-delimiter'."
-  (interactive "p")
-  (forward-page (- arg))
-  (recenter 0))
-
-(defun sas-narrow-to-page ()
-  (save-excursion
-    (let* ((min (point-min))
-           (max (point-max)))
-      ;;(omin (point-min))
-      ;;(omax (point-max)))
-      (if (or (bolp) (beginning-of-line)
-              (looking-at page-delimiter))
-          (forward-char 1)
-        (forward-page -1))
-      (setq min (point))
-      (forward-page 1)
-      (beginning-of-line)
-      (setq max (point))
-      (narrow-to-region min max))))
-
-(defun sas-forward-page-narrow (arg)
-  "Move forward to page boundary and narrow to page.
-With arg, repeat, or go back if negative. A page boundary is any line
-whose beginning matches the regexp `page-delimiter'."
-  (interactive "p")
-  (widen)
-  (forward-page arg)
-  (sas-narrow-to-page)
-  (goto-char (point-min)))
-
-(defun sas-backward-page-narrow (arg)
-  "Move backward to page boundary and narrow to page.
-With arg, repeat, or go back if negative. A page boundary is any line
-whose beginning matches the regexp `page-delimiter'."
-  (interactive "p")
-  (goto-char (point-min))
-  (widen)
-  (forward-page (- arg))
-  (sas-narrow-to-page))
-
-(defun sas-goto-dataset (&optional page)
-  (interactive)
-  (and sas-directory-name
-       (let ((page (or page (sas-get-file-number))))
-         ;;(dir sas-directory-name))
-         (if page
-             (progn
-               (switch-to-buffer-other-window
-                (concat "*SAS-cont-" sas-directory-name))
-               (widen)
-               (sas-goto-page page)
-               (sas-narrow-to-page)
-               (goto-char (point-min)))))))
-
-
-(defun sas-dir-goto-page (page)
-  (interactive "p")
-  (widen)
-  (sas-goto-page page)
-  (sas-narrow-to-page))
-
-(defun sas-mark-item (&optional next)
-  (interactive)
-  (sas-move-to-filename)
-  (beginning-of-line)
-  (let ((buffer-read-only nil))
-    (if (re-search-forward "^\\( *[0-9]+ *\\) \\([A-Z][A-Z_0-9]*\\) "
-                           (save-excursion (end-of-line) (point)) t)
-        (replace-match "\\1<\\2>")))
-  (or next (sas-next-line 1)))
-
-(defun sas-unmark-item ()
-  (interactive)
-  (save-excursion
-    (beginning-of-line)
-    (let ((buffer-read-only nil))
-      (if (re-search-forward "^\\( *[0-9]+ *\\)<\\([A-Z][A-Z_0-9]*\\)>"
-                             (save-excursion (end-of-line) (point)) t)
-          (replace-match "\\1 \\2 ")))))
-
-(defun sas-prev-line-undo (arg)
-  (interactive "p")
-  (sas-prev-line arg)
-  (sas-unmark-item)
-  (sas-move-to-filename))
-
-(defun sas-create-var-string ()
-  (and (string-equal "*SAS-cont" (substring (buffer-name) 0 9))
-       (let (str)
-         (goto-char (point-min))
-         (while
-             (re-search-forward "^\\( *[0-9]+ *\\)<\\([A-Z][A-Z_0-9]*\\)>"
-                                nil t)
-           (setq str (concat str " " (buffer-substring (match-beginning 2)
-                                                       (match-end 2)))))
-         str)))
-
-
-(defun ess-imenu-SAS (&optional _arg)
-  "SAS language Imenu support for ESS."
-  (interactive)
-  (setq imenu-generic-expression
-        '( (nil "[ \t\n=]\\([[:alpha:]_][[:alnum:]_]*[.][[:alpha:]_][[:alnum:]_]*\\)[ ,()\t\n;]" 1)))
-  (imenu-add-to-menubar "SAS Datasets"))
-
-(provide 'ess-sas-l)
-
-;;; ess-sas-l.el ends here
diff --git a/elpa/ess-20251212.937/ess-site.el b/elpa/ess-20251212.937/ess-site.el
deleted file mode 100644 (file)
index c298086..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-;;; ess-site.el --- user customization of ESS  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1993-2020 Free Software Foundation, Inc.
-;; Author: David Smith <D.M.SmithNOSPAMlancaster.ac.uk>
-;; Created: 12 Nov 1993
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; Load path, autoloads, and major modes
-;; ========================================
-;;
-;; This file defines all the site-specific customizations for ESS. It should be
-;; edited on a per-site basis. users who wish to use ESS should add the path to
-;; ess-site to their `load-path' and require it:
-;;
-;;    (add-to-list 'load-path "/path/to/ess/lisp-directory");;
-;;    (require 'ess-site)
-;;
-;; For most users the variable ess-lisp-directory will automatically be set
-;; correctly. If you are working with an old Emacs, one in which file-truename
-;; is not defined, then you might need to change the value of ess-lisp-directory
-;; to the directory which is to contain the file ess-site.elc. This is probably
-;; the current directory, or the value of LISPDIR if it was set in the Makefile.
-;;
-;; Debug startup: (setq ess-show-load-messages t)
-
-;;; Code:
-
-(when load-file-name
-  ;; Modify this if ess-site.el is not in the ./lisp/ directory
-  (defvar ess-lisp-directory (file-name-directory load-file-name)
-    "Directory containing ess-site.el(c) and other ESS Lisp files.")
-  (add-to-list 'load-path (directory-file-name ess-lisp-directory)))
-
-;;; Loading popular dialects (they should become optional in the future)
-
-(require 'ess-r-mode)
-(require 'essd-els) ;; ess-remote
-(require 'ess-sas-d)
-(require 'ess-bugs-d)
-(require 'ess-jags-d)
-(require 'ess-toolbar)
-
-(provide 'ess-site)
-
-;;; ess-site.el ends here
diff --git a/elpa/ess-20251212.937/ess-sp6-d.el b/elpa/ess-20251212.937/ess-sp6-d.el
deleted file mode 100644 (file)
index 087c7ca..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-;;; ess-sp6-d.el --- S-Plus 6 & 7 & 8  customization  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2001-2022 Free Software Foundation, Inc.
-;; Author: A.J. Rossini <rossiniNOSPAMu.washington.edu>
-;; Created: 2001/02/06
-;; Maintainer: ESS Core Team <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; AJR copied S+5 to be S+6.
-;; AJR copied S4 to be S+5.
-;; DB contributed the changes from ess-sp3-d.el to
-;; ess-s4-d.el. (removed the old ugly approach).
-;; This file defines Sp5 customizations for ess-mode.  Lots of thanks
-;; to RMH and JMC for code and suggestions
-;; Thanks to MM for making this sensible.
-
-;;; Code:
-
-(require 'ess-mode)
-(require 'ess-inf)
-(require 'ess-s-lang)
-(require 'ess-trns)
-
-
-;; You now need to make sure you've defined if you are running 5.0 or 5.1.
-;; Lots of things are broken between them, GRR...
-
-(defun S+-directory-p (directory)
-  "Splus 5++ directories have a .Data directory and a __Meta directory within."
-  (and directory
-       (file-directory-p (concat directory ".Data"))
-       (file-directory-p (concat directory ".Data/__Meta"))))
-
-(defvar S+-directory-function #'inferior-ess-default-directory)
-
-(defvaralias 'S+6-setup-directory-function 'S+-setup-directory-function)
-(defvar S+-setup-directory-function
-  (lambda (startdir)
-    (when (and startdir (S+-directory-p startdir))
-      (setenv "S_WORK"
-              (if (getenv "S_WORK")
-                  (concat startdir ":" (getenv "S_WORK"))
-                ;;(message "adding %s to S_WORK" startdir)
-                startdir)))))
-
-
-
-(defvaralias 'S+6-customize-alist 'S+-customize-alist)
-(defvar S+-customize-alist
-  (append
-   '((ess-local-customize-alist        . S+-customize-alist)
-     (ess-dialect                      . S+-dialect-name)
-     (ess-function-pattern             . ess-r-function-pattern)
-
-     (ess-object-name-db-file          . "ess-sp6-namedb.el")
-     (inferior-ess-program             . inferior-S+-program)
-     (inferior-ess-help-command        . "help(\"%s\", pager=\"slynx -dump\", window=FALSE)\n")
-     (inferior-ess-search-list-command . "searchPaths()\n")
-
-     (ess-startup-directory-function   . S+-directory-function)
-     (ess-STERM                        . "iESS"))
-   S+common-cust-alist)
-
-  "Variables to customize for S+.")
-
-(defvar ess-S+-post-run-hook nil
-  "Functions run in process buffer after the initialization of S+
-  process.")
-
-(defvar ess-S+--injected-code
-  ".ess_funargs <- function(funname){
-  ## funname <- deparse(substitute(object))
-  fun <- try(eval(parse(text=funname)), silent = TRUE)
-  if(is.function(fun)) {
-    special <- grepl('[:$@[]', funname)
-    args <- args(fun)
-    fmls <- formals(args)
-    fmls.names <- names(fmls)
-    fmls <- gsub('\\\"', '\\\\\\\"', as.character(fmls), fixed = TRUE)
-    args.alist <- sprintf(\"'(%s)\", paste(\"(\\\"\", fmls.names, \"\\\" . \\\"\", fmls, \"\\\")\", sep = '', collapse = ' '))
-    ## envname <- environmentName(environment(fun))
-    envname <-  if (special) '' else 'S+'
-    cat(sprintf('(list \\\"%s\\\" %s )\\n', envname, args.alist))
-  }
-}
-")
-
-(defalias 'S+6 #'S+)
-(defun S+ (&optional _proc-name)
-  "Call `Splus6', based on S version 4, from Bell Labs.
-New way to do it."
-  (interactive)
-  (ess-write-to-dribble-buffer
-   (format "\n(S+): ess-dialect=%s, buf=%s\n" ess-dialect (current-buffer)))
-  (let ((inf-buf (inferior-ess nil S+-customize-alist)))
-    (ess-command ess-S+--injected-code)
-    (when inferior-ess-language-start
-      (ess-eval-linewise inferior-ess-language-start))
-    (with-current-buffer inf-buf
-      (run-mode-hooks 'ess-S+-post-run-hook))
-    inf-buf))
-
-
-(defalias 'S+6-mode #'S+-mode)
-;;;###autoload
-(defun S+-mode (&optional _proc-name)
-  "Major mode for editing S+ source.  See `ess-mode' for more help."
-  (interactive)
-  (setq-local ess-local-customize-alist S+-customize-alist)
-  (ess-mode)
-  (if (fboundp 'ess-add-toolbar) (ess-add-toolbar))
-  (setq imenu-generic-expression ess-imenu-S-generic-expression)
-  (when ess-imenu-use-S (imenu-add-to-menubar "Imenu-S")))
-
-(defalias 'S+6-transcript-mode #'S+-transcript-mode)
-(define-derived-mode S+-transcript-mode ess-transcript-mode "ESS S Transcript"
-  "S-PLUS 6 transcript mode."
-  :syntax-table S-syntax-table
-  :group 'ess-S)
-
-(defvar ess-s-versions '("Splus")
-  "List of partial strings for versions of S 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 S is made available.  For example, if the
-file \"Splus7\" is found and this variable includes the string
-\"Splus\", a function called `M-x Splus7' will be available to run that
-version of S.
-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'.
-Set this variable to nil to disable searching for other versions
-of S using this method.
-If you set this variable, you need to restart Emacs (and set this variable
-before ess-site is loaded) for it to take effect.")
-(define-obsolete-variable-alias
-  'ess-s-versions-created 'ess-s-created-runners "ESS 18.10")
-(defvar ess-s-created-runners)
-(defun ess-s-define-runners ()
-  "Generate functions for starting other versions of S.
-See `ess-s-versions' for strings that determine which functions are created.
-It assumes these versions of S can be run as a substitute for Splus6.
-
-This function returns the list of functions, if any, that were
-created.  The functions will normally be placed on the menubar upon
-ESS initialization."
-  (when ess-s-versions
-    (let ((versions
-           (delete-dups
-            (mapcar #'file-name-nondirectory
-                    (apply #'nconc
-                           (mapcar #'ess-find-exec-completions
-                                   ess-s-versions))))))
-      ;; Iterate over each string in VERSIONS, creating a new defun
-      ;; each time.
-      (setq ess-s-created-runners
-            (mapc (lambda (v) (ess-define-runner v "S")) versions))
-      ;; Add to menu
-      (when ess-s-created-runners
-        ;; new-menu will be a list of 3-vectors, of the form:
-        ;; ["R-1.8.1" R-1.8.1 t]
-        (let ((new-menu (mapcar (lambda (x) (vector x (intern x) t))
-                                ess-s-created-runners)))
-          (easy-menu-add-item ess-mode-menu '("Start Process")
-                              (cons "Other" new-menu)))))))
-;; Define the runners
-(ess-s-define-runners)
-(define-obsolete-function-alias
-  'ess-s-versions-create #'ess-s-define-runners "ESS 18.10")
-
-
-
-\f ; Provide package
-
-(provide 'ess-sp6-d)
-
-;;; ess-sp6-d.el ends here
diff --git a/elpa/ess-20251212.937/ess-toolbar.el b/elpa/ess-20251212.937/ess-toolbar.el
deleted file mode 100644 (file)
index b6d1207..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-;;; ess-toolbar.el --- Support for a toolbar in ESS.  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1997-2020 Free Software Foundation, Inc.
-;; Author: Stephen Eglen
-;; Created: 2004-05-06
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; This code adds a toolbar to ESS modes for editing R and S code.
-;; Support can be added for other modes (e.g. STATA), just ask!
-;;
-;; This code is experimental. It has been tested only on Linux
-;; machines.  All feedback appreciated.
-;;
-;; 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.  See also the documentation for ess-toolbar-items
-;; if you wish to change its value.
-
-;;; Technical issues.
-
-;; 2009-03-16: toolbar code in Emacs 23 has changed slightly to 22,
-;; and presumably once Emacs 22 is no longer supported, this code can
-;; be cleaned up a bit (i.e. no need to set load-path.)
-
-;;; Code:
-
-(require 'ess-mode)
-
-(defgroup ess-toolbar nil
-  "ESS: toolbar support."
-  :group 'ess
-  :link '(emacs-commentary-link :tag "Commentary" "ess-toolbar.el")
-  :prefix "ess-")
-
-(defcustom ess-use-toolbar
-  (and (fboundp 'display-images-p) (display-images-p))
-  "Non-nil means ESS should support the toolbar."
-  :type 'boolean)
-
-
-(defcustom ess-toolbar-own-icons nil
-  "Non-nil means that we only put our toolbar entries in ESS.
-Otherwise we get standard toolbar as well as ESS entries.
-The standard toolbar items are copied from the default toolbar."
-  :type 'boolean)
-
-(defcustom ess-toolbar-global nil
-  "*Non-nil means that the ESS toolbar is available in all Emacs buffers.
-Otherwise, the ESS toolbar is present only in R/S mode buffers.
-For beginners, this is probably better set to a non-nil value."
-  :type 'boolean)
-
-(defcustom ess-toolbar-items
-  '( (R   "startr")
-     ;;(S   "spluslogo" "Start S process")
-     (S   "splus_letter_small")
-     (ess-eval-line-and-step   "rline")
-     (ess-eval-region   "rregion")
-     (ess-eval-function-or-paragraph-and-step "rregion")
-     (ess-load-file   "rbuffer")
-     (ess-eval-function   "rfunction")
-     (ess-switch-to-ESS   "switch_ess"))
-  "Items to be added to the ESS toolbar.
-Each list element has two items:
-1. the name of the function to run
-2. the icon to be used (without .xpm extension)
-
-General toolbar items are also added to the ESS toolbar
-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."
-  :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"))))
-
-(defvar ess-icon-directory
-  (expand-file-name "icons" ess-etc-directory)
-  "*Location for ESS icons.
-This variable should be set automatically by the ESS install process.
-Icons should be found in ESS/etc/icons/ directory.
-If `ess-icon-directory' is invalid, please report a bug.")
-
-(unless (file-directory-p ess-icon-directory)
-  (ess-write-to-dribble-buffer
-   "`ess-icon-directory' does not exist; using `ess-etc-directory'.\n")
-  (setq ess-icon-directory ess-etc-directory))
-
-(defvar ess-toolbar nil
-  "Toolbar items to be added to ESS editing buffers.")
-
-(defun ess-make-toolbar ()
-  "Make the ESS toolbar."
-  ;; 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.
-  (when (boundp 'tool-bar-map)
-    (setq ess-toolbar
-          (if (or ess-toolbar-own-icons (null tool-bar-map))
-              (make-sparse-keymap)
-            (copy-keymap tool-bar-map)))
-    (let ((tool-bar-map ess-toolbar)
-          (load-path (list ess-icon-directory)))
-      ;; in Emacs 22, icons are found by examining load-path, bound here
-      ;; whereas Emacs 23 seems to want them in image-load-path, set at the
-      ;; bottom of this file.
-      (mapc #'ess-add-icon ess-toolbar-items))))
-
-(defun ess-add-icon (x)
-  "Add an ESS item to the Emacs toolbar.
-X should be a list, see `ess-toolbar-items' for the format."
-  ;; By using tool-bar-add-item-from-menu instead of tool-bar-add-item
-  ;; we get the tooltips "for free" from ess-mode-map.
-  (tool-bar-add-item-from-menu (car x) (cadr x) ess-mode-map))
-
-(defun ess-add-toolbar ()
-  "Add the ESS toolbar to a particular mode.
-The toolbar is added iff `ess-toolbar-global' is nil, else the toolbar
-is added globally when ess-toolbar.el is loaded."
-  (when (and ess-toolbar (not ess-toolbar-global))
-    (setq-local tool-bar-map ess-toolbar)))
-
-;; Make the toolbars.  Each toolbar is hopefully made only when this file
-;; is loaded; we don't need it to be remade every time.
-(if ess-use-toolbar
-    (progn
-      (ess-make-toolbar)
-      ;; After making the toolbar, if ESS toolbar is needed globally,
-      ;; add it here.
-      (if ess-toolbar-global
-          (setq tool-bar-map ess-toolbar)
-        (ess-write-to-dribble-buffer "Creating global Emacs toolbar"))
-
-      ;; Check for toolbar support - needed iff ess-use-toolbar is non-nil.
-      (or
-       ;; Emacs support for images:
-       (and (fboundp 'display-images-p) (display-images-p))
-       ;; if above tests failed, give a warning.
-       (progn
-         (message "Toolbar support for ESS not available in this Emacs.")
-         ;; Not sure if we want to delay startup of ESS.
-         ;;(sit-for 2)
-         ))
-      ))
-
-;; Following needed for Emacs 23, not Emacs 22
-(when (boundp 'image-load-path)
-  (add-to-list 'image-load-path ess-icon-directory))
-
-(provide 'ess-toolbar)
-
-;;; ess-toolbar.el ends here
diff --git a/elpa/ess-20251212.937/ess-tracebug.el b/elpa/ess-20251212.937/ess-tracebug.el
deleted file mode 100644 (file)
index 36ee08e..0000000
+++ /dev/null
@@ -1,2870 +0,0 @@
-;; ess-tracebug.el --- Tracing and debugging facilities for ESS.  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2011-2025 Free Software Foundation, Inc.
-;; Author: Vitalie Spinu
-;; Maintainer: Vitalie Spinu
-;; Created: Oct 14 14:15:22 2010
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;;  Ess-tracebug is a package for interactive debugging of R code from
-;;  ESS and provides such features as:
-;;  - visual debugging
-;;  - browser, recover and conditional  breakpoints
-;;  - watch window and loggers
-;;  - on the fly  debug/undebug of R functions and methods
-;;  - highlighting of error source references and easy error navigation
-;;  - interactive traceback.
-;;
-;;  For a complete description please see the documentation in the ESS
-;;  manual.
-
-;;; Code:
-
-(eval-and-compile
-  (when (< emacs-major-version 26)
-    (require 'cl))
-  (require 'cl-lib)
-  (require 'tramp)
-  (require 'subr-x)
-  (require 'ess-utils))
-(require 'comint)
-(require 'compile)
-(require 'ring)
-
-
-(defvar text-scale-mode-amount)
-(autoload 'text-scale-mode              "face-remap" "[autoload]" nil)
-
-;; Silence the byte compiler. This is OK here because this file is
-;; only loaded from ess-inf and has no autoloads.
-;; TODO: This is a LOT. Can we move some of this around?
-(defvar ess--dbg-del-empty-p)
-(defvar inferior-ess-mode-map)
-(defvar ess-mode-map)
-(defvar ess--inhibit-presend-hooks)
-
-(declare-function ess--accumulation-buffer "ess-inf")
-(declare-function ess--if-verbose-write-process-state "ess-inf")
-(declare-function ess--run-presend-hooks "ess-inf")
-(declare-function ess-boolean-command "ess-inf")
-(declare-function ess-build-eval-command "ess-inf")
-(declare-function ess-build-load-command "ess-inf")
-(declare-function ess-command "ess-inf")
-(declare-function ess-dirs "ess-inf")
-(declare-function ess-eval-region--normalise-region "ess-inf" )
-(declare-function ess-force-buffer-current "ess-inf")
-(declare-function ess-get-process "ess-inf")
-(declare-function ess-get-process-variable "ess-inf")
-(declare-function ess-get-words-from-vector "ess-inf")
-(declare-function ess-get-words-from-vector--foreground "ess-inf")
-(declare-function ess-process-get "ess-inf")
-(declare-function ess-process-live-p "ess-inf")
-(declare-function ess-process-put "ess-inf")
-(declare-function ess-send-string "ess-inf")
-(declare-function ess-switch-process "ess-inf" ())
-(declare-function ess-switch-to-ESS "ess-inf")
-(declare-function ess-switch-to-end-of-ESS "ess-inf" ())
-(declare-function ess-wait-for-process "ess-inf")
-(declare-function inferior-ess--set-status "ess-inf")
-(declare-function inferior-ess-output-filter "ess-inf")
-(declare-function inferior-ess-run-callback "ess-inf")
-
-(declare-function ess-helpobjs-at-point--read-obj "ess-help")
-(declare-function ess-r-get-evaluation-env "ess-r-mode")
-(declare-function ess-roxy--region-p "ess-roxy")
-
-(declare-function ess-r-package--all-source-dirs "ess-r-package")
-(declare-function ess-r-package-name "ess-r-package")
-(declare-function ess-r-package-source-dirs "ess-r-package")
-
-
-;; Do not require tramp at runtime. It is expensive to load. Instead,
-;; guard calls with (require 'tramp) and silence the byte compiler
-;; here.
-(declare-function tramp-dissect-file-name "tramp")
-(declare-function tramp-get-remote-tmpdir "tramp")
-;; The following declares can be removed once we drop Emacs 25
-(declare-function tramp-file-name-hop "tramp")
-(declare-function tramp-file-name-host "tramp")
-(declare-function tramp-file-name-localname "tramp")
-(declare-function tramp-file-name-method "tramp")
-(declare-function tramp-file-name-user "tramp")
-
-
-(defgroup ess-tracebug nil
-  "Error navigation and debugging for ESS.
-Currently only R is supported."
-  :link '(emacs-library-link :tag "Source Lisp File" "ess-tracebug.el")
-  :group 'ess)
-
-(defvar ess-tracebug-indicator " TB"
-  "String to be displayed in mode-line alongside the process name.
-Indicates that ess-tracebug-mode is turned on.")
-
-(defvar ess-watch-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map "k" #'ess-watch-kill)
-    ;; (define-key ess-watch-mode-map "u" #'ess-watch-undelete)
-    ;; editing requires a little more work.
-    (define-key map "a" #'ess-watch-add)
-    (define-key map "i" #'ess-watch-insert)
-    (define-key map "e" #'ess-watch-edit-expression)
-    (define-key map "r" #'ess-watch-rename)
-    (define-key map "q" #'ess-watch-quit)
-    (define-key map "u" #'ess-watch-move-up)
-    (define-key map "U" #'ess-watch-move-down)
-    (define-key map "d" #'ess-watch-move-down)
-    (define-key map "n" #'ess-watch-next-block)
-    (define-key map "p" #'ess-watch-previous-block)
-    ;; R mode keybindings.
-    (define-key map "\C-c\C-s" #'ess-switch-process)
-    (define-key map "\C-c\C-y" #'ess-switch-to-ESS)
-    (define-key map "\C-c\C-z" #'ess-switch-to-end-of-ESS)
-    map)
-  "Keymap for `ess-watch-mode'.")
-
-
-(defcustom ess-tracebug-prefix nil
-  "Key to be used as prefix for all `ess-tracebug' commands.
-Set this to a key combination you don't use often, like:
-
- (setq ess-tracebug-prefix \"\\M-t\")
-
-The postfix keys are defined in `ess-tracebug-map':
-\\{ess-tracebug-map}"
-  :type '(choice (const nil) (string))
-  :group 'ess-tracebug)
-
-(defcustom ess-tracebug-search-path nil
-  "List of directories to search for source files.
-Elements should be directory names, not file names of directories."
-  :type '(choice (const :tag "Unset" nil)
-                 (repeat :tag "Directory list" (string :tag "Directory")))
-  :group 'ess-debug)
-
-(defvar ess-watch-buffer "*R watch*"
-  "Name of the watch buffer.")
-
-(defcustom ess-watch-height-threshold nil
-  "Minimum height for splitting *R* window sensibly to make space for watch window.
-See `split-height-threshold' for a detailed description.
-
-If nil, the value of `split-height-threshold' is used."
-  :group 'ess-debug
-  :type '(choice (const nil) (integer)))
-
-(defcustom ess-watch-width-threshold nil
-  "Minimum width for splitting *R* window sensibly to make space for watch window.
-See `split-width-threshold' for a detailed description.
-
-If nil, the value of `split-width-threshold' is used."
-  :group 'ess-debug
-  :type '(choice (const nil) (integer)))
-
-(defcustom  ess-watch-scale-amount -1
-  "The number of steps to scale the watch font down (up).
-Each step scales the height of the default face in the watch
-window by the variable `text-scale-mode-step' (a negative number
-of steps decreases the height by the same amount)"
-  :group 'ess-debug
-  :type 'integer)
-
-(defvar-local ess-watch-current-block-overlay nil
-  "The overlay for currently selected block in the R watch buffer .")
-
-(defcustom ess-inject-source 'function-and-buffer
-  "Control the source injection into evaluated code.
-
-If t,  always inject source reference.
-If function,  inject only for functions,
-If function-and-buffer, inject for functions and whole buffer (the default),
-If nil, never inject.
-
-When tracebug is active (the default), ESS instructs the
-subprocess to keep the source code references.
-
-If this variable is t, you won't be able to execute blocks which
-don't form a valid R expression. That is, if your expression
-spreads multiple paragraphs, and you call
-\\[ess-eval-region-or-function-or-paragraph-and-step] on first
-paragraph, R will report an error."
-  :group 'ess-tracebug
-  :type '(choice (const nil) (const function) (const function-and-buffer) (const t)))
-
-(defcustom ess-tracebug-enter-hook nil
-  "List of functions to call on entry to `ess-tracebug' mode.
-Use `add-hook' to insert append your functions to this list."
-  :group 'ess-tracebug
-  :type 'hook)
-
-(defcustom ess-tracebug-exit-hook nil
-  "List of functions to call on exit of `ess-tracebug' mode.
-Use `add-hook' to insert append your functions to this list."
-  :group 'ess-tracebug
-  :type 'hook)
-
-(defvaralias 'ess-tracebug-map 'ess-dev-map)
-
-(defvar ess--tracebug-eval-index 0
-  "This is used by to track source references in evaluation with source.
-For example, each time `ess-eval-function' is called the evaluated
-region is marked.  When debugger enters the code it displays
-this reference number. Ess-debug finds this number in the
-referenced buffer.")
-
-;; these vars are org variables that store the src block locations
-(defvar org-edit-src-beg-marker nil)
-(defvar org-babel-current-src-block-location nil
-  "Marker pointing to the src block currently being executed.
-This may also point to a call line or an inline code block.  If
-multiple blocks are being executed (e.g., in chained execution
-through use of the :var header argument) this marker points to
-the outer-most code block.")
-
-;; hash to store source references of the form: tmpname -> (filename . src_start)
-(defvar ess--srcrefs (make-hash-table :test 'equal :size 100))
-
-(defvar ess-tracebug-original-buffer-marker nil
-  "Marker pointing to the beginning of original source code.
-If non-nil, tracebug will insert the source references based on
-this location instead of the current buffer. This is useful for
-applications, like org-babel,  that call ess evaluation functions
-from temporary buffers.")
-
-(defun ess-tracebug-p ()
-  "Return non-nil if tracebug is running."
-  (ess-process-get 'tracebug))
-
-(defun ess-make-source-refd-command (beg end visibly process)
-  "Saves a region to a temporary file in order to add source references.
-BEG and END delimit the region. Returns a string containing an
-inferior process command for loading the temporary file.  This
-command conforms to VISIBLY."
-  (let* ((filename buffer-file-name)
-         (proc-dir (ess-get-process-variable 'default-directory))
-         (remote (when (file-remote-p proc-dir)
-                   (require 'tramp)
-                   ;; should this be done in process buffer?
-                   (tramp-dissect-file-name proc-dir)))
-         (orig-marker (or ess-tracebug-original-buffer-marker
-                          org-edit-src-beg-marker
-                          org-babel-current-src-block-location))
-         orig-beg)
-    (setq ess--tracebug-eval-index (1+ ess--tracebug-eval-index))
-    (goto-char beg)
-    (skip-chars-forward " \t\n")
-    (setq beg (point))
-    (goto-char end)
-    (skip-chars-backward " \t\n")
-    (setq end (point)
-          orig-beg beg)
-
-    ;; Delete all old temp files
-    (when (and (not (ess-process-get 'busy))
-               (< 1 (float-time
-                     (time-subtract (current-time)
-                                    (ess-process-get 'last-eval)))))
-      (dolist (f (ess-process-get 'temp-source-files))
-        (and (file-exists-p f)
-             (delete-file f)))
-      (ess-process-put 'temp-source-files nil))
-
-    (when (markerp orig-marker)
-      (setq filename (buffer-file-name (marker-buffer orig-marker)))
-      (setq orig-beg (+ beg (marker-position orig-marker))))
-
-    (let ((tmpfile
-           (expand-file-name (make-temp-name
-                              (concat (file-name-nondirectory
-                                       (or filename "unknown")) "!"))
-                             (if remote
-                                 (tramp-get-remote-tmpdir remote)
-                               temporary-file-directory))))
-
-      (ess-process-put 'temp-source-files
-                       (cons tmpfile (ess-process-get 'temp-source-files)))
-
-      (when remote
-        ;; Get local name (should this be done in process buffer?)
-        (setq tmpfile (with-parsed-tramp-file-name tmpfile nil localname)))
-
-      (if (not filename)
-          (puthash tmpfile (list nil ess--tracebug-eval-index nil) ess--srcrefs)
-        (puthash tmpfile (list filename ess--tracebug-eval-index orig-beg) ess--srcrefs)
-        (puthash (file-name-nondirectory tmpfile) ; R sometimes strips dirs
-                 (list filename ess--tracebug-eval-index orig-beg) ess--srcrefs)
-        (with-silent-modifications
-          (put-text-property beg end 'tb-index ess--tracebug-eval-index)))
-      (let ((string (ess-process-buffer-substring process beg end)))
-        (or
-         ;; Sending string to subprocess is considerably faster than tramp file
-         ;; transfer. So, give priority to `ess-eval-command' if available
-         (ess-build-eval-command string visibly t tmpfile)
-         ;; When no `ess-eval-command' available, use `ess-load-command'
-         (progn
-           (write-region beg end tmpfile nil 'silent)
-           (ess-build-load-command tmpfile visibly t)))))))
-
-(defun ess-process-buffer-substring (process start end)
-  (ess--run-presend-hooks process (buffer-substring-no-properties start end)))
-
-;; Declare globally so that the bytecode compiler let-binds it
-;; properly
-(defvar-local ess-r-evaluation-env nil)
-
-(defun ess-tracebug-send-region (process start end &optional visibly message type)
-  "Send region to process adding source references as specified
-by `ess-inject-source' variable."
-  ;; Disable evaluation env if we're sending a roxy region. This is
-  ;; not the ideal place to do this.
-  (let* ((se (ess-eval-region--normalise-region start end))
-         (start (car se))
-         (end (cdr se))
-         (ess-r-evaluation-env (unless (ess-roxy--region-p start end)
-                                 (ess-r-get-evaluation-env)))
-         (inject-p  (cond ((eq type 'function)
-                           ess-inject-source)
-                          ((eq type 'buffer)
-                           (or (eq ess-inject-source t)
-                               (eq ess-inject-source 'function-and-buffer)))
-                          ((eq ess-inject-source t))
-                          ;; We need to always inject with namespaced
-                          ;; evaluation (FIXME: not right place for
-                          ;; this).
-                          (ess-r-evaluation-env)))
-         (ess--dbg-del-empty-p (unless inject-p ess--dbg-del-empty-p))
-         (string (if inject-p
-                     (ess-make-source-refd-command start end visibly process)
-                   (ess-process-buffer-substring process start end)))
-         (message (if (fboundp ess-build-eval-message-function)
-                      (funcall ess-build-eval-message-function message)
-                    message)))
-    ;; Don't run the presend hooks twice.
-    (let ((ess--inhibit-presend-hooks t))
-      (process-put process :eval-visibly visibly)
-      ;; Visible evaluation is not nice when sourcing temporary files. You get
-      ;; .ess.eval(*code*) instead of *code*.
-      (setq visibly (unless inject-p visibly))
-      (ess-send-string process string visibly message))))
-
-(defun ess-tracebug-send-function (proc start end &optional visibly message)
-  "Like `ess-tracebug-send-region' but with tweaks for functions."
-  (ess-tracebug-send-region proc start end visibly message 'function))
-
-;; * Input Ring:
-
-;; i   . Goto input event marker forwards     . `ess-debug-goto-input-event-marker'
-;; I   . Goto input event marker backwards    . `ess-debug-goto-input-event-marker'
-
-
-(defun ess-tracebug-show-help ()
-  "Show help for `ess-tracebug'."
-  (interactive)
-  (if (fboundp 'describe-keymap)
-      (describe-keymap 'ess-tracebug-map)
-    (info "(ess) ESS tracebug")))
-
-(defun ess-tracebug--propertize (dummy bitmap face &optional string )
-  "If `window-system' propertize DUMMY with fringe BITMAP and FACE.
-Otherwise, propertize line-prefix and margin with STRING and FACE"
-  (unless string
-    (setq string dummy))
-  (if window-system
-      (propertize dummy 'display (list 'left-fringe bitmap face))
-    (propertize dummy
-                'display (list '(margin left-margin)
-                               (propertize string
-                                           'font-lock-face face
-                                           'face face)))))
-
-
-(defun ess-tracebug (&optional arg)
-  "Toggle `ess-tracebug' mode.
-With ARG, turn `ess-tracebug' mode on if and only if ARG is
-positive.
-
-This mode adds to ESS the interactive debugging, breakpoint and
-error navigation functionality.  Strictly speaking `ess-tracebug'
-is not a minor mode. It integrates globally into ESS and iESS.
-
-Note: Currently, `ess-tracebug' does not detect some of R's debug
-related messages in non-English locales. To set your R messages
-to English add the following line to your .Rprofile init file:
-
-   Sys.setlocale(\"LC_MESSAGES\", \"C\")
-
-
-See `ess-tracebug-help' for the overview of ess-tracebug functionality."
-
-  ;; Note: The functionality in ess-tracebug is divided on conceptual
-  ;; grounds in tracing and debugging and could be
-  ;; activated/deactivate separately with `ess--tb-start' and
-  ;; `ess-debug-start' respectively.
-
-  (interactive "P")
-  (ess-force-buffer-current "R process to activate tracebug in: ")
-  (with-current-buffer (process-buffer (get-process ess-local-process-name))
-    (when (equal ess-dialect "R")
-      (setq arg
-            (if arg
-                (prefix-numeric-value arg)
-              (if (ess-process-get 'tracebug) -1 1)))
-      (if (> arg 0)
-          (unless (ess-process-get 'tracebug) ;; only if not already active
-            (ess--tb-start)
-            (ess-debug-start)
-            ;; (dolist (bf (buffer-list))
-            ;;   (with-current-buffer bf
-            ;;     (when (and (eq major-mode 'ess-mode)
-            ;;                (equal ess-dialect "R"))
-            ;;       (ess-bp-recreate-all))))
-            ;; watch functionality
-            (if ess-tracebug-prefix
-                (let ((comm (key-binding ess-tracebug-prefix)))
-                  ;; (message "ess-tracebug-prefix will be removed in future versions. Electric debug keys are now on [C-c] and [C-c C-t] maps.")
-                  ;; (sit-for 1)
-                  (when (commandp comm)
-                    (define-key ess-tracebug-map ess-tracebug-prefix comm))
-                  (define-key ess-mode-map ess-tracebug-prefix ess-tracebug-map)
-                  (define-key inferior-ess-mode-map ess-tracebug-prefix ess-tracebug-map)
-                  (define-key ess-watch-mode-map ess-tracebug-prefix ess-tracebug-map)))
-            (run-hooks 'ess-tracebug-enter-hook)
-            (ess-process-put 'tracebug t)
-            (message "ess-tracebug mode enabled"))
-        (when (ess-process-get 'tracebug) ;;only when active
-          (ess-process-put  'tracebug nil)
-          ;; unset the map
-          (when ess-tracebug-prefix
-            (define-key ess-mode-map ess-tracebug-prefix nil)
-            (define-key inferior-ess-mode-map ess-tracebug-prefix nil))
-          (ess--tb-stop)
-          (ess-debug-stop)
-          (run-hooks 'ess-tracebug-exit-hook)
-          (message "ess-tracebug mode disabled"))))))
-
-(defalias 'ess-toggle-tracebug #'ess-tracebug)
-
-
-;;;_* TRACEBACK
-
-;; (defface ess--tb-last-input-face
-;;   '((((class grayscale)
-;;       (background light)) (:background "DimGray"))
-;;     (((class grayscale)
-;;       (background dark))  (:background "LightGray"))
-;;     (((class color) (background light) (min-colors 88))
-;;      (:overline "medium blue" ))
-;;     (((class color) (background dark) (min-colors 88))
-;;      (:overline "deep sky blue" ))
-;;     (((background light))  (:weight bold))
-;;     (((background dark)) (:weight bold))
-;;     )
-;;   "Face to highlight currently debugged line."
-;;   :group 'ess-tracebug )
-
-(defface ess-tracebug-last-input-fringe-face
-  '((((background light) (min-colors 88)) (:foreground "medium blue" :overline "medium blue"))
-    (((background dark) (min-colors 88))  (:foreground "deep sky blue" :overline "deep sky blue"))
-    (((background light) (min-colors 8))  (:foreground "blue"))
-    (((background dark) (min-colors 8))  (:foreground "cyan")))
-  "Face for fringe bitmap for last-input position."
-  :group 'ess-tracebug)
-
-(if (fboundp 'define-fringe-bitmap)
-    (define-fringe-bitmap 'last-input-arrow
-      [#b00011111
-       #b00010000
-       #b00010000
-       #b00010000
-       #b00010000
-       #b00010000
-       #b00010000
-       #b00010000
-       #b00010000
-       #b00010000
-       #b11010111
-       #b01111100
-       #b00111000
-       #b00010000] nil nil 'top))
-
-
-(defvar ess--tb-last-input (make-marker)
-  "Marker pointing to the last user input position in iESS buffer.
-This is the place where `ess--tb-last-input-overlay' is moved.
-Local in iESS buffers with `ess-tracebug' mode enabled.")
-
-(defvar ess--tb-last-input-overlay nil
-  "Overlay to highlight the position of last input in iESS buffer.
-Local in iESS buffers.")
-
-(defvar-local ess--busy-count 0
-  "Used to compute the busy indicator.")
-
-;; (unless (boundp 'ess--busy-slash)
-;; (defvar ess--busy-slash '(32 ?\u2014 92 47))
-;; (setq ess--busy-slash (mapcar (lambda (el) (format " %c " el))
-;;                               ess--busy-slash))
-;; )
-
-
-(defvar ess--busy-slash '("   " " - " " \\ " " / "))
-(defvar ess--busy-B '("   " " B " "   "))
-(defvar ess--busy-stars '("      " "      " " *    " " **   " " ***  " " **** "))
-(defvar ess--busy-vbars '("      " "      " " |    " " ||   " " |||  " " |||| "))
-
-(defcustom ess-busy-strings ess--busy-slash
-  "List of strings to replace in turn for busy indication.
-The first element of the list is used as an indicator of the
-process being ready (i.e. not busy). Implemented lists that you
-can use `ess--busy-slash', `ess--busy-B',`ess--busy-stars',
-`ess--busy-vbars'"
-  :group 'ess
-  :type '(repeat string))
-
-(defvar ess--busy-timer nil
-  "Timer used for busy process indication.")
-
-(defcustom inferior-ess-fix-misaligned-output nil
-  "If non-nil, try to correct misaligned process output."
-  :group 'ess-tracebug
-  :type 'boolean)
-
-(defcustom inferior-ess-replace-long+ t
-  "Determines if ESS replaces long + sequences in output.
-If \\='strip, remove all such instances.  Otherwise, if non-nil, `+
-+ + + ' containing 3 or more + is replaced by
-`ess-long+replacement'.
-This variable can be process-local but not buffer-local."
-  :group 'ess-tracebug
-  :type '(choice (const :tag "No replacement" nil)
-                 (const :tag "Replace all" strip)
-                 (const :tag "Replace 3 or more +" t)))
-
-(defvar ess-long+replacement ". + "
-  "Replacement used for long + prompt.
-Please don't customize this or other prompt related variables.
-ESS internal code assumes default R prompts.")
-
-(defmacro ess-copy-key (from-map to-map fun)
-  `(define-key ,to-map
-     (car (where-is-internal ,fun  ,from-map))
-     ,fun))
-
-;;;_ + traceback functions
-(defun ess--tb-make-last-input-overlay (beg end)
-  "Create an overlay to indicate the last input position."
-  (let   ((ove (make-overlay beg end)))
-    (overlay-put ove 'before-string
-                 (ess-tracebug--propertize "!"  'last-input-arrow 'ess-tracebug-last-input-fringe-face))
-    ;; (overlay-put ove 'face  'ess--tb-last-input-face)
-    (overlay-put ove 'evaporate t)
-    ove))
-
-
-(defun ess--tb-start ()
-  "Start traceback session."
-  (with-current-buffer (process-buffer (get-process ess-local-process-name))
-    (unless ess-error-regexp-alist
-      (error "Can not activate the traceback for %s dialect" ess-dialect))
-    (setq-local compilation-error-regexp-alist ess-error-regexp-alist)
-    (let (compilation-mode-font-lock-keywords)
-      (compilation-setup t))
-    (setq next-error-function #'ess-tracebug-next-error-function)
-    ;; new locals
-    (make-local-variable 'ess--tb-last-input)
-    (make-local-variable 'ess--tb-last-input-overlay)
-    (make-local-variable 'compilation-search-path)
-    (setq compilation-search-path ess-tracebug-search-path) ;; TODO: make this dialect specific
-    (ess-tracebug--set-left-margin)
-    (save-excursion
-      (goto-char comint-last-input-start)
-      (setq ess--tb-last-input (point))
-      (setq ess--tb-last-input-overlay
-            (ess--tb-make-last-input-overlay
-             (line-beginning-position) (line-end-position))))
-    ;; busy timer
-    (setq mode-line-buffer-identification
-          (list (car (propertized-buffer-identification "%3b"))
-                `(:eval  (nth ess--busy-count ess-busy-strings)))) ;; 'face 'mode-line-buffer-id))))
-    (make-local-variable 'ess--busy-timer)
-    (setq ess--busy-timer
-          (run-with-timer 2 .5 (ess--make-busy-timer-function (get-buffer-process (current-buffer)))))
-    (add-hook 'kill-buffer-hook (lambda () (when ess--busy-timer (cancel-timer ess--busy-timer))))
-    (add-hook 'comint-input-filter-functions #'ess-tracebug-set-last-input nil 'local)
-
-    ;; redefine
-    ;; TODO: all this part should go (partially gone now)
-    (advice-add 'ess-parse-errors :override #'next-error)))
-
-(defun ess--tb-stop ()
-  "Stop ess traceback session in the current ess process."
-  (with-current-buffer (process-buffer (get-process ess-current-process-name))
-    ;; restore original definitions
-    (when (equal ess-dialect "R")
-      (advice-remove 'ess-parse-errors #'next-error))
-    (if (local-variable-p 'ess--tb-last-input-overlay)
-        (delete-overlay ess--tb-last-input-overlay))
-    (kill-local-variable 'ess--tb-last-input-overlay)
-    (kill-local-variable 'ess--tb-last-input)
-    (font-lock-remove-keywords nil (compilation-mode-font-lock-keywords))
-    (font-lock-ensure)
-    (kill-local-variable 'compilation-error-regexp-alist)
-    (kill-local-variable 'compilation-search-path)
-    (cancel-timer ess--busy-timer)
-    (remove-hook 'comint-input-filter-functions #'ess-tracebug-set-last-input 'local)
-    (setq mode-line-buffer-identification (propertized-buffer-identification "%12b"))))
-
-(defvar ess--dbg-forward-ring (make-ring 10)
-  "Ring of markers to the positions of user inputs when the
-debugger or traceback events are initiated. It is used in
-`ess--dbg-goto-input-point'.")
-
-(defvar ess--dbg-backward-ring (make-ring 10)
-  "Ring of markers for the positions from `ess--dbg-goto-input-point'.
-Marks the position from which it was called. See also
-`ess--dbg-goto-debug-point'")
-
-;; (setq ess-R--tb-regexp-alist '(R R2 R3 R-recover))
-;;(pop compilation-error-regexp-alist-alist)
-
-(defun ess-show-traceback ()
-  "Display R traceback and last error message.
-Pop up a compilation/grep/occur like buffer. Usual global key
-bindings are available (\\[next-error] and \\[previous-error])
-for `next-error' and `previous-error' respectively.
-
-You can bind `no-select' versions of this commands:
-\(define-key compilation-minor-mode-map [(?n)] #\\='next-error-no-select)
-\(define-key compilation-minor-mode-map [(?p)] #\\='previous-error-no-select)"
-  (interactive)
-  (cl-assert ess-traceback-command nil
-             "Not implemented for dialect %s" ess-dialect)
-  (ring-insert ess--dbg-forward-ring (point-marker))
-  (ess-force-buffer-current "R process to use: ")
-  (let ((trbuf (get-buffer-create "*ess-traceback*"))
-        (lproc-name ess-local-process-name)
-        (alist ess-mode-editing-alist)
-        (cmd ess-traceback-command)
-        (inhibit-read-only t))
-    (setq next-error-last-buffer trbuf)
-    (with-current-buffer trbuf
-      (setq ess-local-process-name lproc-name)
-      (ess-command cmd trbuf)
-      (goto-char (point-min))
-      ;; fixme: this is R specific check
-      (cl-assert (not (re-search-forward "No traceback available" nil t)) nil
-                 "No traceback available")
-      (ess-dirs)
-      (when (boundp 'ess-r-error-regexp-alist)
-        (setq-local compilation-error-regexp-alist ess-r-error-regexp-alist))
-      (setq-local compilation-search-path ess-tracebug-search-path)
-      (ess-setq-vars-local alist)
-      (font-lock-refresh-defaults)
-      (compilation-minor-mode 1)
-      (setq next-error-function #'ess-tracebug-next-error-function)
-      (setq buffer-read-only t)
-      (pop-to-buffer trbuf))))
-
-(defvar ess-call-stack-command nil)
-(defun ess-show-call-stack ()
-  "Display current call stack.
-Also see `ess-show-traceback'"
-  (interactive)
-  (let ((ess-traceback-command ess-call-stack-command))
-    (ess-show-traceback)))
-
-(defalias 'ess-show-R-traceback #'ess-show-traceback)
-
-(defun ess--tb-next-error-goto-process-marker ()
-  ;; assumes current buffer is the process buffer with compilation enabled
-  ;; used in ess-tracebug-next-error-function
-                                        ;  (with-current-buffer (process-buffer (get-process ess-local-process-name)) ; already in comint buffer .. no need
-  (comint-goto-process-mark)
-  (set-window-point (get-buffer-window) (point))  ;moves the cursor
-  ;; FIXME: Should jump to current-debug-position,  but messes the things if in recover
-  ;; (when (ess-debug-is-active)
-  ;;   (ess-debug-goto-current-debug-position)
-  ;;   )
-  )
-
-(defun ess-tracebug-next-error-function (n &optional reset)
-  "Advance to the next error message and visits the file.
-This is the value of `next-error-function' in iESS buffers."
-  ;; Modified version of `compilation-next-error-function'.
-  (interactive "p")
-  (if reset  (goto-char (point-max)))
-  (let* (;; (columns compilation-error-screen-columns) ; buffer's local value
-         ;; (proc (or (get-buffer-process (current-buffer))
-         ;;                         (error "Current buffer has no process")))
-         (pbuff-p (get-buffer-process (current-buffer)))
-         (n (or n 1))
-         (beg-pos  ; from where the search for next error starts
-          (if (and pbuff-p
-                   (>= n 0)
-                   (comint-after-pmark-p))
-              ess--tb-last-input
-            (point)))
-         (at-error t)
-         (msg
-          (condition-case nil
-              (compilation-next-error n nil beg-pos)
-            (error
-             (when pbuff-p
-               (ess--tb-next-error-goto-process-marker))
-             (if (< n 0)
-                 (message "Before first reference")
-               (message "Beyond last reference"));(error-message-string err))
-             (setq at-error nil))))
-         (msg (if (or (not pbuff-p)
-                      (eq n 0)
-                      (> (point) ess--tb-last-input))
-                  msg
-                (ess--tb-next-error-goto-process-marker)
-                (message "Beyond last-input marker")
-                (setq at-error nil)))
-         (marker (point-marker))
-         loc)
-    (when at-error
-      (setq compilation-current-error (point-marker)
-            overlay-arrow-position (if (bolp)
-                                       compilation-current-error
-                                     (copy-marker (line-beginning-position)))
-            loc (if (fboundp 'compilation--message->loc)
-                    (compilation--message->loc msg)
-                  (car msg)))
-      (let* ((file (caar (nth 2 loc)))
-             (col (car loc))
-             (line (cadr loc))
-             (mkrs (ess--dbg-create-ref-marker file line col)))
-        (if mkrs
-            ;; is this really needed? Shall we go directly to the location?
-            (compilation-goto-locus marker (car mkrs) (cadr mkrs))
-          (message "Reference to '%s' not found" file))))))
-
-
-(defun inferior-ess-move-last-input-overlay ()
-  "Move the overlay to the point."
-  (let ((pbol (line-beginning-position)))
-    (move-overlay ess--tb-last-input-overlay
-                  pbol (max (- (point) 2) (+ pbol 2)))))
-
-
-;;;_* DEBUGGER
-(defgroup ess-debug nil
-  "Debugging for ESS"
-  :link '(emacs-library-link :tag "Source Lisp File" "ess-tracebug.el")
-  :group 'ess-tracebug
-  :prefix "ess-debug-")
-
-(defcustom  ess-debug-error-action-alist
-  '(( ""   "NONE"       "NULL" )
-    ( " r" "RECOVER"    "utils::recover")
-    ( " t" "TRACEBACK"  "base::traceback"))
-  "Alist of `on-error' actions.
-Toggled with `ess-debug-toggle-error-action'.  Each element must
-have the form (DISP SYMB ACTION) where DISP is the string to be
-displayed in the mode line when the action is in place. SYMB is
-the symbolic name of an action. ACTION is the string giving the
-actual expression to be assigned to `error' user option. See R's
-help ?options for more details."
-  :type '(alist :key-type string
-                :value-type (group string string))
-  :group 'ess-debug)
-
-(defvar ess--dbg-output-buf-prefix " *ess.dbg"
-  "The prefix of the buffer name the R debug output is directed to."  )
-
-(defvar-local ess--dbg-current-ref (make-marker)
-  "Current debug reference in *ess.dbg* buffers (a marker).")
-
-(defvar-local ess--dbg-last-ref-marker (make-marker)
-  "Last debug reference in *ess.dbg* buffer (a marker).")
-
-(defvar-local ess--dbg-buf-p nil
-  "This is t in ess.dbg buffers.")
-
-;; (defcustom ess--dbg-auto-single-key-p t
-;;   "If t entering the debug state triggers single-key mode.
-;; Set it to nil if you want to trigger single-key mode manually
-;; with the `ess-tracebug-prefix' key.
-;; ")
-
-(defvar ess--dbg-current-debug-position (make-marker)
-  "Marker to the current debugged line.
-It always point to the beginning of the currently debugged line
-and is used by overlay-arrow.
-In no-windowed Emacs an `overlay-arrow' is displayed at this position.")
-
-(unless  window-system
-  (add-to-list 'overlay-arrow-variable-list 'ess--dbg-current-debug-position))
-
-(defface ess-debug-current-debug-line-face
-  '((default (:inherit highlight)))
-  "Face used to highlight currently debugged line."
-  :group 'ess-debug)
-
-
-(defvar  ess--dbg-current-debug-overlay
-  (let ((overlay (make-overlay (point) (point))))
-    (overlay-put overlay 'face  'ess-debug-current-debug-line-face)
-    (overlay-put overlay 'evaporate t)
-    overlay)
-  ;; should be global variable!!
-  "The overlay for currently debugged line.")
-
-
-(defcustom ess-debug-blink-interval .2
-  "Time in seconds to blink the background of the debug line.
-Currently two events are defined `ref-not-found' and `same-ref'.
-Blinking colors for these events can be customized by
-corresponding faces."
-  :group 'ess-debug
-  :type 'float)
-
-(defface ess-debug-blink-ref-not-found-face
-  '((((class grayscale) (background light)) (:background "DimGray"))
-    (((class grayscale) (background dark))  (:background "LightGray"))
-    (((class color) (background light) (min-colors 88)) (:background "IndianRed4"))
-    (((class color) (background dark) (min-colors 88))  (:background "dark red"))
-    (((background light) (min-colors 8))  (:foreground "red"))
-    (((background dark) (min-colors 8))  (:foreground "red")))
-  "Face used to blink currently debugged line's background
- when the reference file is not found. See also `ess-debug-ask-for-file'"
-  :group 'ess-debug )
-
-(defface ess-debug-blink-same-ref-face
-  '((((class grayscale) (background light)) (:background "DimGray"))
-    (((class grayscale) (background dark))  (:background "LightGray"))
-    (((class color) (background light) (min-colors 88)) (:background "steel blue"))
-    (((class color) (background dark) (min-colors 88))  (:background "midnight blue"))
-    (((background light) (min-colors 8))  (:foreground "blue"))
-    (((background dark) (min-colors 8))  (:foreground "cyan")))
-  "Face used to highlight currently debugged line when new debug
-reference is the same as the preceding one. It is highlighted for
-`ess-debug-blink-interval' seconds."
-  :group 'ess-debug )
-
-(defcustom ess-debug-ask-for-file nil
-  "If non nil, ask for file if the current debug reference is not found.
-
-If nil, the currently debugged line is highlighted for
-`ess-debug-blink-interval' seconds."
-  :group 'ess-debug
-  :type 'boolean)
-
-(defcustom ess-debug-skip-first-call t
-  "If non-nil, skip first debugger call.
-
-In R first call doesn't contain source references and is skipped
-by default."
-  :group 'ess-debug
-  :type 'boolean)
-
-(defvar ess-electric-selection-map
-  (let (ess-electric-selection-map)
-    (define-prefix-command 'ess-electric-selection-map)
-    ;; command-c and command-Q are not always working reliably
-    (define-key ess-electric-selection-map "\M-N" #'ess-debug-command-continue)
-    (define-key ess-electric-selection-map "\M-C" #'ess-debug-command-continue)
-    (define-key ess-electric-selection-map "\M-Q" #'ess-debug-command-quit)
-    (define-key ess-electric-selection-map "0" #'ess-debug-command-digit)
-    (define-key ess-electric-selection-map "1" #'ess-debug-command-digit)
-    (define-key ess-electric-selection-map "2" #'ess-debug-command-digit)
-    (define-key ess-electric-selection-map "3" #'ess-debug-command-digit)
-    (define-key ess-electric-selection-map "4" #'ess-debug-command-digit)
-    (define-key ess-electric-selection-map "5" #'ess-debug-command-digit)
-    (define-key ess-electric-selection-map "6" #'ess-debug-command-digit)
-    (define-key ess-electric-selection-map "7" #'ess-debug-command-digit)
-    (define-key ess-electric-selection-map "8" #'ess-debug-command-digit)
-    (define-key ess-electric-selection-map "9" #'ess-debug-command-digit)
-    (define-key ess-electric-selection-map "?" #'ess-tracebug-show-help)
-    ess-electric-selection-map)
-  "Keymap used to define commands for single key input mode.
-This commands are triggered by `ess-electric-selection' .
-
-\\{ess-electric-selection-map}")
-
-;;;_ + debug functions
-(defun ess-debug-set-error-action (spec)
-  "Set the on-error action.
-The SPEC should be one of the components of
-`ess-debug-error-action-alist'."
-  (let ((proc (get-process ess-local-process-name)))
-    (if spec
-        (with-current-buffer (process-buffer proc)
-          (process-put proc 'on-error-action (car spec))
-          (ess-command (format "options(error= %s )\n" (nth 2 spec))))
-      (error "Unknown action"))))
-
-(defun ess-debug-toggle-error-action ()
-  "Toggle the `on-error' action.
-The action list is in `ess-debug-error-action-alist'."
-  (interactive)
-  (ess-force-buffer-current)
-  (let* ((ev last-command-event)
-         (com-char  (event-basic-type ev))
-         (cur-action (or (ess-process-get 'on-error-action) ""))
-         actions act)
-    (setq actions
-          (cdr (member (assoc cur-action ess-debug-error-action-alist)
-                       ess-debug-error-action-alist)))
-    (unless actions
-      (setq actions ess-debug-error-action-alist))
-    (setq act (pop actions))
-    (ess-debug-set-error-action act)
-    (message "On-error action set to: %s"
-             (propertize (cadr act) 'face 'font-lock-function-name-face))
-    (while  (eq (event-basic-type (setq ev (read-event))) com-char)
-      (unless actions
-        (setq actions ess-debug-error-action-alist))
-      (setq act (pop actions))
-      (ess-debug-set-error-action act)
-      (force-mode-line-update)
-      (message "On-error action set to: %s"
-               (propertize (cadr act) 'face 'font-lock-function-name-face)))
-    (push ev unread-command-events)))
-
-(defun ess--dbg-activate-overlays ()
-  "Initialize active debug line overlays."
-  (move-overlay ess--dbg-current-debug-overlay
-                (line-beginning-position) (1+ (line-end-position)))
-  ;; used by overlay-arrow functionality on no-X,  should be bol
-  (move-marker ess--dbg-current-debug-position (line-beginning-position)))
-
-(defun ess--dbg-deactivate-overlays ()
-  "Delete debugger markers and overlays.
-Overlay arrow remains to indicate the last debug position."
-  (delete-overlay ess--dbg-current-debug-overlay)
-  (set-marker ess--dbg-current-debug-position nil))
-
-
-;;;_ + Work Flow
-(defun ess-debug-goto-input-event-marker ()
-  "Jump to the point where the last debugger/traceback etc event occurred.
-
-   Mainly useful during/after debugging, to jump to the place
-from where the code was initially executed.  This is an
-electric-command, which means that after the command is triggered a
-single key event is enough to navigate through the input-event-S-ring.
-If the key-event which triggered the command is Shift modified
-the input-event-S-ring is traversed backwards.
-
-The input-event-S-ring is a virtual object which consists of two
-rings `ess--dbg-forward-ring' and `ess--dbg-backward-ring' which
-are joint at their tops.
-
-See the more info at https://code.google.com/p/ess-tracebug/#Work-Flow"
-  (interactive)
-  (let* ((ev last-command-event)
-         (com-char  (event-basic-type ev))
-         (ring-el 0)
-         input-point)
-    (if (memq 'shift (event-modifiers ev))
-        (setq input-point (ring-ref ess--dbg-backward-ring 0))
-      (ring-insert ess--dbg-backward-ring (point-marker)) ;; insert in backward ring ;;TODO: check if the marker to this (close by?) position is already in the ring
-      (setq input-point (ring-ref ess--dbg-forward-ring 0)))
-    (when (marker-buffer input-point) ;; TODO: give a message here if buff is not found
-      (pop-to-buffer-same-window (marker-buffer input-point))
-      (when (marker-position input-point)
-        (goto-char (marker-position input-point))))
-    (while  (eq (event-basic-type  (event-basic-type (setq ev (read-event)))) com-char)
-      (if (memq 'shift (event-modifiers ev))
-          (setq ring-el (1- ring-el))
-        (setq ring-el (1+ ring-el)))
-      (if (< ring-el 0)
-          (setq input-point (ring-ref ess--dbg-backward-ring (- ring-el)))  ;; get it from backward-ring
-        ;; get it from forward-ring
-        (setq input-point (ring-ref ess--dbg-forward-ring ring-el)) )
-      (when (marker-buffer input-point)
-        (pop-to-buffer-same-window (marker-buffer input-point))
-        (when (marker-position input-point)
-          (goto-char (marker-position input-point)))))
-    (push ev unread-command-events)))
-
-(defun ess-debug-goto-debug-point ()
-  "Return to the debugging position.
-Jump to markers stored in `ess--dbg-backward-ring'. If debug
-session is active, first jump to current debug line.
-
-This is an electric-command. Shift triggers the opposite traverse
-of the ring."
-  (interactive)
-  (let* ((debug-point (ring-ref ess--dbg-backward-ring 0))
-         (ev last-command-event)
-         (com-char  (event-basic-type ev))
-         (ring-el 0))
-    (if (ess--dbg-is-active-p)
-        (progn
-          (pop-to-buffer-same-window (marker-buffer ess--dbg-current-debug-position))
-          (goto-char (marker-position ess--dbg-current-debug-position ))
-          (back-to-indentation))
-      (pop-to-buffer-same-window (marker-buffer debug-point))
-      (goto-char (marker-position debug-point)))
-    (while  (eq (event-basic-type (setq ev (read-event))) com-char)
-      (if (memq 'shift (event-modifiers ev))
-          (setq ring-el (1- ring-el))
-        (setq ring-el (1+ ring-el)))
-      (setq debug-point (ring-ref ess--dbg-backward-ring ring-el))
-      (when (marker-buffer debug-point)
-        (pop-to-buffer-same-window (marker-buffer debug-point))
-        (when (marker-position debug-point)
-          (goto-char (marker-position debug-point)))))
-    (push ev unread-command-events)))
-
-(defun ess-debug-insert-in-forward-ring ()
-  "Insert `point-marker' into the forward-ring."
-  (interactive)
-  (ring-insert ess--dbg-forward-ring (point-marker))
-  (message "Point inserted into the forward-ring"))
-
-(defvar ess-debug-indicator " DB"
-  "String to be displayed in mode-line alongside the process name.
-Indicates that ess-debug-mode is turned on. When the debugger is
-in active state this string is shown in upper case and
-highlighted.")
-
-(defvar-local ess--dbg-mode-line-debug
-  '(:eval (let ((proc (get-process ess-local-process-name)))
-            (if (and proc (process-get proc 'dbg-active))
-                (let ((str ess-debug-indicator))
-                  (ess-debug-minor-mode 1) ; activate the keymap
-                  (put-text-property 1 (length str)
-                                     'face '(:foreground "white" :background "red")
-                                     str)
-                  str)
-              (ess-debug-minor-mode -1)
-              ""))))
-(put 'ess--dbg-mode-line-debug 'risky-local-variable t)
-
-(defvar-local ess--dbg-mode-line-error-action
-  '(:eval (or (and (ess-process-live-p)
-                   (ess-process-get 'on-error-action))
-              "")))
-(put 'ess--dbg-mode-line-error-action 'risky-local-variable t)
-
-(defun ess--dbg-remove-empty-lines (string)
-  "Remove empty lines from STRING (which interfere with evals) during debug.
-This function is placed in `ess-presend-filter-functions'."
-  (if (and ess--dbg-del-empty-p (ess-process-get 'dbg-active))
-      (replace-regexp-in-string "\n\\s *$" "" string)
-    string))
-
-
-(defun ess-debug-start ()
-  "Start the debug session.
-Add to ESS the interactive debugging functionality, breakpoints,
-watch and loggers.  Integrates into ESS and iESS modes by binding
-`ess-tracebug-map' to `ess-tracebug-prefix' in
-`ess-mode-map' and `inferior-ess-mode-map' respectively."
-  (interactive)
-  (let ((dbuff (get-buffer-create (concat ess--dbg-output-buf-prefix "." ess-current-process-name "*"))) ;TODO: make dbuff a string!
-        (proc (ess-get-process ess-local-process-name))
-        (lpn ess-local-process-name))
-    (process-put proc 'dbg-buffer dbuff); buffer were the look up takes place
-    (process-put proc 'dbg-active nil)  ; t if the process is in active debug state.
-                                        ; Active debug states are usually those, in which prompt start with Browser[d]>
-    (set-process-filter proc #'inferior-ess-tracebug-output-filter)
-    (with-current-buffer (process-buffer proc)
-      (unless (equal ess-dialect "R")
-        (error "Can not activate the debugger for %s dialect" ess-dialect))
-      (add-to-list 'ess--mode-line-process-indicator 'ess--dbg-mode-line-debug t)
-      (add-to-list 'ess--mode-line-process-indicator 'ess--dbg-mode-line-error-action t)
-
-      (add-hook 'ess-presend-filter-functions #'ess--dbg-remove-empty-lines nil 'local))
-    (with-current-buffer dbuff
-      (setq ess-local-process-name lpn)
-      (buffer-disable-undo)
-      ;; (setq buffer-read-only nil)
-      (make-local-variable 'overlay-arrow-position) ;; indicator for next-error functionality in the *ess.dbg*,  useful??
-      (goto-char (point-max))
-      (setq ess--dbg-buf-p t  ;; true if in  *ess.dbg* buffer
-            ess--dbg-current-ref (point-marker)  ;; used by goto-error functionality
-            ess--dbg-last-ref-marker (point-marker)  ;; gives marker to reference of the last debugged line
-            )
-      ;;      (beginning-of-line)
-      ;; (setq buffer-read-only t)
-      )))
-
-(defun ess-debug-stop ()
-  "End the debug session.
-Kill the *ess.dbg.[R_name]* buffer."
-  ;;; process plist is not removed, TODO?low priority
-  (interactive)
-  (let ((proc (get-process ess-current-process-name))) ;;local?
-    (with-current-buffer (process-buffer proc)
-      (if (member ess-dialect '("XLS" "SAS" "STA"))
-          (error "Can not deactivate the debugger for %s dialect" ess-dialect))
-      (delq 'ess--dbg-mode-line-debug ess--mode-line-process-indicator)
-      (delq 'ess--dbg-mode-line-error-action ess--mode-line-process-indicator)
-      (remove-hook 'ess-presend-filter-functions #'ess--dbg-remove-empty-lines 'local))
-    (set-process-filter proc #'inferior-ess-output-filter)
-    (kill-buffer (process-get proc 'dbg-buffer))
-    (process-put proc 'dbg-buffer nil)
-    (process-put proc 'dbg-active nil)
-    ;; (when (buffer-live-p ess--dbg-buffer)
-    ;;   ;; (with-current-buffer ess--dbg-buffer
-    ;;   ;;   (set-buffer-modified-p nil)
-    ;;   ;;   )
-    ;;   (kill-buffer ess--dbg-buffer)
-    ;;   )
-    ))
-
-
-(defun ess--make-busy-timer-function (process)
-  "Display the spinner of prompt if PROCESS is busy."
-  `(lambda ()
-     (let ((pb ,process))
-       (when (eq (process-status pb) 'run) ;; only when the process is alive
-         (with-current-buffer (process-buffer pb)
-           (if (not (process-get pb 'busy)) ;; if ready
-               (when (> ess--busy-count 0)
-                 (setq ess--busy-count 0)
-                 (force-mode-line-update)
-                 (redisplay))
-             (setq ess--busy-count (1+ (mod  ess--busy-count  (1- (length ess-busy-strings)))))
-             (force-mode-line-update)
-             (redisplay)))))))
-
-;; (ess--make-busy-prompt-function (get-process "R"))
-
-(defun ess--dbg-is-active-p ()
-  "Return t if the current R process is in active debugging state."
-  (and (ess-process-live-p)
-       (ess-process-get  'dbg-active)))
-
-(defun ess--dbg-is-recover-p ()
-  "Return t if the current R process is in active debugging state."
-  (and (ess-process-live-p)
-       (ess-process-get  'is-recover)))
-
-(defun ess-debug-active-p (&optional proc)
-  (and (ess-process-live-p proc)
-       (or (ess-process-get 'dbg-active proc)
-           (ess-process-get 'is-recover proc))))
-
-(defvar ess--dbg-regexp-reference "debug \\w+ +\\(.+\\)#\\([0-9]+\\):")
-(defvar ess--dbg-regexp-jump "debug \\w+ ") ;; debug at ,debug bei ,etc
-(defvar ess--dbg-regexp-skip
-  ;; don't anchor to bol; secondary prompt can occur before (anything else?)
-  ;; "\\(\\(?:Called from: \\)\\|\\(?:debugging in: \\)\\|\\(?:#[0-9]*: +recover()\\)\\)")
-  "\\(\\(?:Called from: \\)\\|\\(?:#[0-9]*: +recover()\\)\\)")
-
-(defvar ess--dbg-regexp-no-skip
-  ;; exceptions for first skip (magrittr)
-  "debug_pipe")
-
-(defvar ess--dbg-regexp-debug  "\\(\\(?:Browse[][0-9]+\\)\\|\\(?:debug: \\)\\)")
-(defvar ess--dbg-regexp-selection "\\(Selection: \\'\\)")
-(defvar ess--dbg-regexp-input (concat ess--dbg-regexp-debug "\\|"
-                                      ess--dbg-regexp-selection))
-
-(defvar ess--suppress-next-output? nil)
-
-
-\f
-;;; MPI
-
-;; http://jkorpela.fi/chars/c0.html
-;; https://en.wikipedia.org/wiki/ANSI_escape_code#Escape_sequences
-(defvar ess-mpi-message-start-delimiter "\e_")
-(defvar ess-mpi-message-field-separator "\1e")
-(defvar ess-mpi-message-end-delimiter "\e\\")
-
-(define-obsolete-variable-alias 'ess-mpi-alist 'ess-mpi-handlers "ESS 19.04")
-(defvar ess-mpi-handlers
-  '(("message" . ess-mpi:message)
-    ("error"   . ess-mpi:error)
-    ("eval"    . ess-mpi:eval)
-    ("y-or-n"  . ess-mpi:y-or-n))
-  "Alist of the MPI handlers.
-Each element is of the form (TYPE . HANDLER), where TYPE is the
-message type and HANDLER is a function (symbol) to be called on
-the payload list of each message.")
-
-(defun ess-mpi:message (msg)
-  (message "%s" msg))
-
-(defun ess-mpi:error (msg)
-  (error "MPI error: %s" msg))
-
-(defun ess-mpi:eval (str &optional callback)
-  "Read STR and evaluate as Emacs expression.
-If present, the CALLBACK string is passed through `format' with
-returned value from EXPR and then sent to the subprocess."
-  (let ((result (eval (read str) t)))
-    (when callback
-      (ess-send-string (ess-get-process) (format callback result)))))
-
-(defun ess-mpi:y-or-n (prompt callback)
-  "Ask `y-or-n-p' with PROMPT.
-The CALLBACK string is passed through `format' with returned
-value from EXPR and then sent to the subprocess."
-  (let ((result (y-or-n-p prompt)))
-    (when callback
-      (let ((result (if result "TRUE" "FALSE")))
-        (ess-send-string (ess-get-process) (format callback result))))))
-
-(defun ess-mpi-convert (el)
-  (cond
-   ((string= el "nil") nil)
-   ((string= el "t") t)
-   (t el)))
-
-(defun ess-mpi-handle-messages (buf)
-  "Handle all mpi messages in BUF and delete them.
-The MPI message has the form \\^[TYPE\\^^FIELD...\\^] where TYPE is the
-type of the messages on which handlers in `ess-mpi-handlers' are
-dispatched, \\^C are ASCII control chars, and FIELDs are strings.
-Return `:incomplete' if BUF ends with an incomplete message."
-  (let ((obuf (current-buffer))
-        (out nil))
-    (with-current-buffer buf
-      (goto-char (point-min))
-      ;; This should be smarter because Emacs might cut it in the middle of the
-      ;; message. In practice this almost never happen because we are
-      ;; accumulating output into the cache buffer.
-      (while (search-forward ess-mpi-message-start-delimiter nil t)
-        (let ((mbeg0 (match-beginning 0))
-              (mbeg (match-end 0)))
-          (if (search-forward ess-mpi-message-end-delimiter nil t)
-              (let* ((mend (match-beginning 0))
-                     (mend0 (match-end 0))
-                     (msg (buffer-substring mbeg mend))
-                     (payload (mapcar #'ess-mpi-convert
-                                      (split-string msg ess-mpi-message-field-separator)))
-                     (head (pop payload))
-                     (handler (cdr (assoc head ess-mpi-handlers))))
-                (unwind-protect
-                    (if handler
-                        (with-current-buffer obuf
-                          (apply handler payload))
-                      (error "No handler defined for MPI message '%s" head))
-                  (goto-char mbeg0)
-                  (delete-region mbeg0 mend0)))
-            (setq out :incomplete))))
-      out)))
-
-(defun ess--replace-long+-in-prompt (proc prompt is-final)
-  "Replace long + + + in PROMPT based on `inferior-ess-replace-long+' value.
-If IS-FINAL means that PROMPT occurs at the end of the process
-chunk. If non-nil, special care is taken not to drop last '+'
-value as it might be a continuation prompt."
-  ;; see #576 for interesting input examples
-  (let ((len (length prompt))
-        (inferior-ess-replace-long+ (buffer-local-value
-                                     'inferior-ess-replace-long+
-                                     (process-buffer proc))))
-    (if (or (null inferior-ess-replace-long+)
-            (< len 2))
-        prompt
-      (let ((last+ (eq (elt prompt (- len 2)) ?+)))
-        (cond
-         ((eq inferior-ess-replace-long+ 'strip)
-          (if (and last+ is-final)
-              "+ "
-            "> "))
-         ((eq inferior-ess-replace-long+ t)
-          (let ((prompt (replace-regexp-in-string "\\(\\+ \\)\\{2\\}\\(\\+ \\)+"
-                                                  ess-long+replacement prompt)))
-            (if (and last+ (not is-final))
-                ;; append > for aesthetic reasons
-                (concat prompt "> ")
-              prompt)))
-         (t (error "Invalid values of `inferior-ess-replace-long+'")))))))
-
-(defun ess--offset-output (prev-prompt str)
-  "Add suitable offset to STR given the preceding PREV-PROMPT.
-Do nothing if `inferior-ess-fix-misaligned-output' is nil."
-  (if (and inferior-ess-fix-misaligned-output prev-prompt)
-      (let ((len (length prev-prompt)))
-        ;; prompts have at least 2 chars
-        (if (eq (elt prev-prompt (- len 2)) ?+)
-            ;; when last + append > for aesthetic reasons
-            (concat "> \n" str)
-          (if (eq (elt str 0) ?\n)
-              ;; don't insert empty lines
-              str
-            (concat "\n" str))))
-    str))
-
-(defun ess--flush-accumulated-output (proc)
-  "Flush accumulated output of PROC into its output buffer.
-Insertion happens chunk by chunk. A chunk is a region between two
-prompts."
-  (let* ((abuf (ess--accumulation-buffer proc))
-         (pbuf (process-buffer proc))
-         (visibly (process-get proc :eval-visibly))
-         (nowait (eq visibly 'nowait))
-         (flush-timer (process-get proc 'flush-timer)))
-    (when (> (buffer-size abuf) 0)
-      (when (timerp flush-timer)
-        (cancel-timer flush-timer))
-      (if (eq (buffer-local-value 'major-mode pbuf) 'fundamental-mode)
-          ;; FIXME: this cannot be, ess-command changes the filter
-          ;; Just in case if we are in *ess-command* buffer; restart the timer.
-          (process-put proc 'flush-timer
-                       (run-at-time .02 nil #'ess--flush-accumulated-output proc))
-        ;; Incomplete mpi should hardly happen. Only on those rare occasions
-        ;; when an mpi is issued after a long task and split by the Emacs input
-        ;; handler, or mpi printing itself takes very long.
-        (unless (eq :incomplete (ess-mpi-handle-messages abuf))
-          (with-current-buffer abuf
-            ;; Uncomment this line when debugging. This pops up the
-            ;; accumulation buffer and causes point to follow
-            ;; automatically as the parsing progresses.
-            ;; (pop-to-buffer (current-buffer))
-            (goto-char (point-min))
-            (let ((case-fold-search nil))
-              (when (re-search-forward "Error\\(:\\| +in\\)" nil t)
-                (unless (get-buffer-window pbuf 'visible)
-                  (setq next-error-last-buffer pbuf)
-                  (display-buffer pbuf nil t))))
-            (goto-char (point-min))
-            ;; First long + + in the output mirrors the sent input by the user and
-            ;; is unnecessary in nowait case. A single + can be a continuation in
-            ;; the REPL, thus we check if there is an extra output after the + .
-            (when nowait
-              (when (looking-at "\\([+>] \\)\\{2,\\}\n?")
-                (goto-char (match-end 0))
-                (when (eq (point) (point-max))
-                  ;; if this is the last prompt in the output back-up one prompt
-                  ;; (cannot happen after \n)
-                  (backward-char 2))))
-            (let ((do-clean (not (eq visibly t)))
-                  (pos2 (point))
-                  (pos1 (point))
-                  (tpos nil)
-                  (prompt nil)
-                  (regexp (if nowait
-                              ;; we cannot disambiguate printed input fields and
-                              ;; prompts in output in this case; match 2+ pluses or
-                              ;; > and 2+ spaces
-                              "\\(^\\([+>] \\)\\{2,\\}\\)\\|\\(> \\) +"
-                            "^\\([+>] \\)+"))
-                  (prev-prompt (process-get proc 'prev-prompt)))
-              (while (re-search-forward regexp nil t)
-                (setq pos1 (match-beginning 0)
-                      tpos (if nowait
-                               (or (match-end 1) (match-end 3))
-                             (match-end 0)))
-                (when (> pos1 pos2)
-                  (let ((str (buffer-substring pos2 pos1)))
-                    (comint-output-filter proc (ess--offset-output prev-prompt str))))
-                (setq pos2 tpos)
-                (setq prompt (let ((prompt (buffer-substring pos1 pos2)))
-                               (if do-clean
-                                   (ess--replace-long+-in-prompt proc prompt (eq pos2 (point-max)))
-                                 prompt)))
-                ;; Cannot bypass this trivial call to comint-output-filter because
-                ;; external tools could rely on prompts (org-babel [#598] for
-                ;; example). Setting dummy regexp in order to avoid comint erasing
-                ;; this prompt which contrasts to how we output prompts in all
-                ;; other cases.
-                (with-current-buffer pbuf
-                  (let ((comint-prompt-regexp "^$"))
-                    (comint-output-filter proc prompt)))
-                (setq prev-prompt (and do-clean prompt)
-                      pos1 pos2))
-              ;; insert last chunk if any
-              (unless (eq pos1 (point-max))
-                (let ((str (buffer-substring-no-properties pos1 (point-max))))
-                  (comint-output-filter proc (ess--offset-output prev-prompt str))
-                  (setq prev-prompt nil)))
-              (process-put proc 'prev-prompt prev-prompt)
-              (process-put proc 'flush-time (and (process-get proc 'busy)
-                                                 (float-time)))
-              (erase-buffer))))))))
-
-(defun inferior-ess-tracebug-output-filter (proc string)
-  "Standard output filter for the inferior ESS process.
-When `ess-debug' is active, this is the filter. Call
-`inferior-ess-output-filter'. Check for debug
-reg-expressions (see `ess--dbg-regexp-debug',...), when found
-puts iESS in the debugging state. If in debugging state, mirrors
-the output into *ess.dbg* buffer."
-  (let* ((is-iess (or (derived-mode-p 'ess-watch-mode)
-                      (derived-mode-p 'inferior-ess-mode)))
-         (pbuf (process-buffer proc))
-         (abuf (ess--accumulation-buffer proc))
-         (dbuff (process-get proc 'dbg-buffer))
-         (wbuff (get-buffer ess-watch-buffer))
-         (was-in-dbg (process-get proc 'dbg-active))
-         (was-in-recover (process-get proc 'is-recover))
-         (input-point (point-marker))
-         (match-jump (string-match ess--dbg-regexp-jump string))
-         (match-input (string-match ess--dbg-regexp-input string))
-         (match-selection (and match-input
-                               (match-string 2 string))) ;; Selection:
-         (match-skip (and ess-debug-skip-first-call
-                          (string-match ess--dbg-regexp-skip string)
-                          (not (string-match ess--dbg-regexp-no-skip string))))
-         (match-dbg (or match-skip (and match-input (not match-selection))))
-         (is-ready (inferior-ess--set-status proc string))
-         (new-time (float-time))
-         (last-time (process-get proc 'flush-time))
-         (flush-timer (process-get proc 'flush-timer)))
-
-    ;; current-buffer is still the user's input buffer here
-    (ess--if-verbose-write-process-state proc string "tracebug-filter")
-    (inferior-ess-run-callback proc string)
-    (process-put proc 'is-recover match-selection)
-
-    (if (or (process-get proc 'suppress-next-output?)
-            ess--suppress-next-output?)
-
-        ;; works only for suppressing short output, enough for now (for callbacks)
-        (process-put proc 'suppress-next-output? nil)
-
-      (with-current-buffer abuf
-        (goto-char (point-max))
-        (insert string))
-
-      ;; cancel the timer each time we enter this filter
-      (when (timerp flush-timer)
-        (cancel-timer flush-timer)
-        (process-put proc 'flush-timer nil))
-
-      (unless last-time ;; don't flush for the first time
-        (setq last-time new-time)
-        (process-put proc 'flush-time new-time))
-
-      ;; flush periodically
-      (let ((fast-flush (or is-ready
-                            ;; for the sake of ess-eval-linewise
-                            (process-get proc 'sec-prompt))))
-        (if (or
-             ;; theoretically we should flush asynchronously in all cases but
-             ;; somewhat unexpectedly it introduces much more randomness during
-             ;; batch testing. TODO: flush directly for now and either remove or
-             ;; improve on the next refactoring iteration
-             fast-flush
-             (> (- new-time last-time) .5)
-             (bound-and-true-p edebug-mode)
-             ;; the flush is not getting called if the third party call
-             ;; accept-process-output in a loop (e.g. org-babel-execute-src-block)
-             (bound-and-true-p org-babel-current-src-block-location))
-            (ess--flush-accumulated-output proc)
-          ;; Setup new flush timer. Ideally also for fast-flush case in order to
-          ;; avoid detecting intermediate prompts as end-of-output prompts.
-          (let ((timeout (if fast-flush .01 .2)))
-            (process-put proc 'flush-timer
-                         (run-at-time timeout nil #'ess--flush-accumulated-output proc))))))
-
-    ;; WATCH
-    (when (and is-ready wbuff) ;; refresh only if the process is ready and wbuff exists, (not only in the debugger!!)
-      (ess-watch-refresh-buffer-visibly wbuff))
-
-    ;; JUMP to line if debug expression was matched
-    (when match-jump
-      (with-current-buffer dbuff              ;; insert string in *ess.dbg* buffer
-        (goto-char (point-max))
-        (insert (concat "|-" string "-|")))
-      (ess--dbg-goto-last-ref-and-mark dbuff is-iess))
-
-    ;; (with-current-buffer dbuff ;; un-comment to see the value of STRING just before debugger exists
-    ;;   (let ((inhibit-read-only t))
-    ;;     (goto-char (point-max))
-    ;;     (insert (concat " ---\n " string "\n ---"))
-    ;;     ))
-
-    ;; SKIP if needed
-    (when (and match-skip (not was-in-recover))
-      (process-send-string proc  "n\n"))
-
-    ;; EXIT the debugger
-    (when (and was-in-dbg
-               (not (or match-jump match-dbg))
-               (or is-ready match-selection))
-      (ess--dbg-deactivate-overlays)
-      (process-put proc 'dbg-active nil)
-      ;; (message "|<-- exited debugging -->|")
-      (when wbuff
-        (ess-watch-refresh-buffer-visibly wbuff)))
-
-    ;; ACTIVATE the debugger if entered for the first time
-    (when (and (not was-in-dbg)
-               (not match-selection)
-               (or match-jump match-dbg))
-      (unless is-iess
-        (ring-insert ess--dbg-forward-ring input-point))
-      (process-put proc 'dbg-active t)
-      (message
-       (ess--debug-keys-message-string))
-      (unless match-jump
-        ;; no source reference, simply show the inferior
-        (display-buffer pbuf)))
-
-    (when (and match-selection (not is-iess)) ;(and (not was-in-recover) match-selection)
-      (ess-electric-selection t))))
-
-
-(defvar ess-debug-minor-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "M-C") #'ess-debug-command-continue)
-    (define-key map [(control meta ?C)] #'ess-debug-command-continue-multi)
-    (define-key map (kbd "M-N") #'ess-debug-command-next)
-    (define-key map (kbd "M-S") #'ess-debug-command-step)
-    (define-key map (kbd "M-W") #'ess-debug-command-where)
-    (define-key map (kbd "M-F") #'ess-debug-command-finish)
-    (define-key map (kbd "M-H") #'ess-debug-command-help)
-    (define-key map (kbd "M-R") #'ess-debug-command-resume)
-    (define-key map [(control meta ?N)] #'ess-debug-command-next-multi)
-    (define-key map (kbd "M-Q") #'ess-debug-command-quit)
-    (define-key map (kbd "M-U") #'ess-debug-command-up)
-    map)
-  "Keymap active when ESS process is in debugging state.
-\\{ess-debug-minor-mode-map}")
-
-
-(define-minor-mode ess-debug-minor-mode
-  "Minor mode activated when ESS process is in debugging state."
-  :lighter nil
-  :keymap ess-debug-minor-mode-map)
-
-(defun ess--dbg-goto-last-ref-and-mark (dbuff &optional other-window)
-  "Open the most recent debug reference and set the necessary marks and overlays.
-It's called from `inferior-ess-tracebug-output-filter'. DBUFF
-must be the *ess.dbg* buffer associated with the process. If
-OTHER-WINDOW is non nil, attempt to open the location in a
-different window."
-  (let (t-debug-position ref)
-    (with-current-buffer dbuff
-      (setq ref (ess--dbg-get-next-ref -1 (point-max) ess--dbg-last-ref-marker
-                                       ess--dbg-regexp-reference)) ; sets point at the end of found ref
-      (when ref
-        (move-marker ess--dbg-last-ref-marker (line-end-position))
-        ;; each new step repositions the current-ref!
-        (move-marker ess--dbg-current-ref ess--dbg-last-ref-marker)))
-    (when ref
-      (let ((buf (apply #'ess--dbg-goto-ref other-window ref)))
-        (if buf
-            ;; if referenced buffer has been found, put overlays:
-            (with-current-buffer buf
-              (setq t-debug-position (copy-marker (line-beginning-position)))
-              (if (equal t-debug-position ess--dbg-current-debug-position)
-                  (progn ;; highlights the overlay for ess--dbg-blink-interval seconds
-                    (overlay-put ess--dbg-current-debug-overlay 'face 'ess--dbg-blink-same-ref-face)
-                    (run-with-timer ess-debug-blink-interval nil
-                                    (lambda ()
-                                      (overlay-put ess--dbg-current-debug-overlay 'face 'ess-debug-current-debug-line-face))))
-                ;; else
-                (ess--dbg-activate-overlays)))
-          ;;else, buffer is not found: highlight and give the corresponding message
-          (overlay-put ess--dbg-current-debug-overlay 'face 'ess--dbg-blink-ref-not-found-face)
-          (run-with-timer ess-debug-blink-interval nil
-                          (lambda ()
-                            (overlay-put ess--dbg-current-debug-overlay 'face 'ess-debug-current-debug-line-face)))
-          (message "Reference %s not found" (car ref)))))))
-
-(defun ess--dbg-goto-ref (other-window file line &optional col)
-  "Opens the reference given by FILE, LINE and COL.
-Try to open in a different window if OTHER-WINDOW is nil.  Return
-the buffer if found, or nil otherwise be found.
-`ess--dbg-find-buffer' is used to find the FILE and open the
-associated buffer. If FILE is nil return nil."
-  (let ((mrk (car (ess--dbg-create-ref-marker file line col)))
-        (lpn ess-local-process-name))
-    (when mrk
-      (let ((buf (marker-buffer mrk)))
-       (if (not other-window)
-           (pop-to-buffer-same-window buf)
-         (let ((this-frame (window-frame (get-buffer-window (current-buffer)))))
-           (display-buffer buf)
-           ;; simple save-frame-excursion
-           (unless (eq this-frame (window-frame (get-buffer-window buf t)))
-             (ess-select-frame-set-input-focus this-frame))))
-       ;; set or re-set to lpn as this is the process with debug session on
-       (with-current-buffer buf
-         (setq ess-local-process-name lpn)
-         (goto-char mrk)
-          (set-window-point (get-buffer-window buf) mrk))
-       buf))))
-
-;; temporary, hopefully org folks implement something similar
-(defvar org-babel-tangled-file nil)
-(declare-function org-babel-tangle-jump-to-org "ob-tangle.el")
-
-(defun ess--dbg-create-ref-marker (file line &optional col)
-  "Create markers to the reference given by FILE, LINE and COL.
-Return list of two markers MK-start and MK-end. MK-start is the
-position of error. Mk-end is the end of the line where error
-occurred. If buffer associated with FILE is not found, or line is
-nil, or TB-INDEX is not found return nil."
-  (if (stringp line) (setq line (string-to-number line)))
-  (if (stringp col) (setq col (string-to-number col)))
-  (let* ((srcref (gethash file ess--srcrefs))
-         (file (replace-regexp-in-string "^\n" "" ;; hack for gnu regexp
-                                         (or (car srcref) file)))
-         (tb-index (cadr srcref))
-         (buffer (ess--dbg-find-buffer file))
-         pos)
-    (when (and buffer line)
-      (save-excursion
-        (with-current-buffer buffer
-          (save-restriction
-            (widen) ;; how does this behave in narrowed buffers? tothink:
-            (goto-char 1)
-            (setq pos (point))
-            (when tb-index
-              (while (and (not (eq tb-index (get-text-property pos 'tb-index)))
-                          (setq pos (next-single-property-change pos 'tb-index)))))
-            (unless pos
-              ;; use beg position if index not found
-              (setq pos (nth 2 srcref)))
-            (when pos
-              (goto-char pos)
-              (forward-line (1- line))
-              (if col
-                  (goto-char (+ (line-beginning-position) col))
-                (back-to-indentation))
-              (when (bound-and-true-p org-babel-tangled-file)
-                (org-babel-tangle-jump-to-org))
-              (list (point-marker) (copy-marker (line-end-position))))))))))
-
-(defvar ess-r-package-library-paths)
-(defun ess--dbg-find-buffer (filename)
-  "Find a buffer for file FILENAME.
-If FILENAME is not found at all, ask the user where to find it if
-`ess--dbg-ask-for-file' is non-nil.  Search the directories in
-`ess-tracebug-search-path' and `ess-r-package-library-paths'."
-  (let ((dirs (append
-               (ess-r-package-source-dirs)
-               ess-r-package-library-paths
-               (cl-loop for d in (append ess-tracebug-search-path)
-                        append (ess-r-package--all-source-dirs d))))
-        (filematch (format "%s\\'" filename))
-        buffer name)
-    (setq dirs (delq nil (cons (with-ess-process-buffer t default-directory) dirs)))
-    ;; 1. The file name is absolute.  Use its explicit directory as
-    ;; the first in the search path, and strip it from FILENAME.
-    (when (and (null  buffer)
-               (file-name-absolute-p filename))
-      (setq filename (abbreviate-file-name (expand-file-name filename))
-            dirs (cons (file-name-directory filename) dirs)
-            filename (file-name-nondirectory filename)))
-    (or
-     ;; 2. Search the path.
-     (while (and (null buffer) dirs)
-       (let ((thisdir (pop dirs)))
-         (setq name (expand-file-name filename thisdir)
-               buffer (and (file-exists-p name)
-                           (find-file-noselect name)))))
-     buffer
-
-     ;; 3. search already open buffers for match (associated file might not even exist yet)
-     (cl-dolist (bf (buffer-list))
-       (with-current-buffer  bf
-         (when (and buffer-file-name
-                    (string-match filematch buffer-file-name))
-           (setq buffer bf)
-           (cl-return))))
-     buffer
-
-     ;; 4. Ask for file if not found (tothink: maybe remove this part?)
-     (when ess-debug-ask-for-file
-       (save-excursion            ;This save-excursion is probably not right.
-         (let* ((pop-up-windows t)
-                (name (read-file-name
-                       (format "Find next line in (default %s): "  filename)
-                       nil filename t nil))
-                (origname name))
-           (cond
-            ((not (file-exists-p name))
-             (message "Cannot find file `%s'" name)
-             (ding) (sit-for 2))
-            ((and (file-directory-p name)
-                  (not (file-exists-p
-                        (setq name (expand-file-name filename name)))))
-             (message "No `%s' in directory %s" filename origname)
-             (ding) (sit-for 2))
-            (t
-             (setq buffer (find-file-noselect name)))))))
-     buffer)))
-
-(defun ess--dbg-get-next-ref (n &optional pt BOUND REG nF nL nC)
-  "Move point to the next reference in the *ess.dbg* buffer.
-
-Must be called from *ess.dbg* buffer.
-It returns the reference in the form (file line col) /all strings/ ,
-or NIL if not found .  Prefix arg N says how many error messages
-to move forwards (or backwards, if negative).  Optional arg PT,
-if non-nil, specifies the value of point to start looking for the
-next message, default to (point).  BOUND is the limiting position
-of the search.  REG is the regular expression to search with.  nF
-- sub-expression of REG giving the `file'; defaults to 1.  nL -
-giving the `line'; defaults to 2.  nC - sub-expr giving the
-`column'; defaults to 3."
-  (unless ess--dbg-buf-p
-    (error "Not in *ess.dbg* buffer"))
-  (setq nF (or nF 1)
-        nL (or nL 2)
-        nC (or nC 3))
-  (or pt (setq pt (point)))
-  ;; (message "ess--dbg-last-ref-marker%s vs  pt%s vs point-max%s" ess--dbg-last-ref-marker pt (point-max))
-  (goto-char pt)
-  (if (search-forward-regexp REG BOUND t n)
-      (list (match-string nF) (match-string-no-properties nL) (match-string-no-properties nC))
-    nil))
-
-(defun ess--debug-keys-message-string (&optional map)
-  (let ((overriding-local-map (or map ess-debug-minor-mode-map)))
-    (substitute-command-keys
-     (mapconcat #'identity
-                '("(\\[ess-debug-command-continue])cont"
-                  "(\\[ess-debug-command-continue-multi])cont-multi"
-                  "(\\[ess-debug-command-next])next"
-                  "(\\[ess-debug-command-next-multi])next-multi"
-                  "(\\[ess-debug-command-up])up"
-                  "(\\[ess-debug-command-quit])quit")
-                " "))))
-
-(defun ess-electric-selection (&optional wait)
-  "Call commands defined in `ess-electric-selection-map'.
-Single-key input commands are those, which once executed do not
-require the prefix command for subsequent invocation.
-
-If WAIT is t, wait for next input and ignore the keystroke which
-triggered the command."
-  (interactive)
-  (ess--execute-electric-command ess-electric-selection-map
-                                 "Selection: " wait
-                                 (not (ess-process-get 'is-recover))))
-
-(defun ess-debug-command-digit (&optional ev)
-  "Digit commands in selection mode.
-If supplied, EV must be a proper key event or a string representing the digit."
-  (interactive)
-  (ess-force-buffer-current)
-  (unless (ess--dbg-is-recover-p)
-    (error "Recover is not active"))
-  (unless ev
-    (setq ev last-command-event))
-  (let* ((ev-char (if (stringp ev)
-                      ev
-                    (char-to-string (event-basic-type ev))))
-         (proc (get-process ess-current-process-name))
-         (mark-pos (marker-position (process-mark proc)))
-         (comint-prompt-read-only nil)
-         prompt  depth)
-    (with-current-buffer (process-buffer proc)
-      (goto-char mark-pos)
-      (save-excursion
-        (when (re-search-backward "\\(?: \\|^\\)\\([0-9]+\\):[^\t]+Selection:" ess--tb-last-input t)
-          (setq depth (string-to-number (match-string 1)))
-          (when (> depth 9)
-            (setq ev-char (ess-completing-read "Selection" (mapcar #'number-to-string
-                                                                   (number-sequence depth 0 -1))
-                                               nil t ev-char nil)))))
-      (setq prompt (delete-and-extract-region (line-beginning-position) mark-pos))
-      (insert (concat  prompt ev-char "\n"))
-      (ess-send-string proc ev-char)
-      (move-marker (process-mark proc) (max-char)))))
-
-(defun ess-debug-command-next ()
-  "Step next in debug mode.
-Equivalent to `n' at the R prompt."
-  (interactive)
-  (ess-force-buffer-current)
-  (unless (ess--dbg-is-active-p)
-    (error "Debugger is not active"))
-  (if (ess--dbg-is-recover-p)
-      (ess-send-string (ess-get-process) "0")
-    (ess-send-string (ess-get-process) "n")))
-
-(defun ess-debug-command-step ()
-      "Step into in debug mode.
-Equivalent to `s' at the R prompt."
-       (interactive)
-  (ess-force-buffer-current)
-  (unless (ess--dbg-is-active-p)
-    (error "Debugger is not active"))
-  (if (ess--dbg-is-recover-p)
-      (ess-send-string (ess-get-process) "0")
-    (ess-send-string (ess-get-process) "s")))
-
-(defun ess-debug-command-finish ()
-  "Step next in debug mode.
-Equivalent to `f' at the R prompt."
-  (interactive)
-  (ess-force-buffer-current)
-  (unless (ess--dbg-is-active-p)
-    (error "Debugger is not active"))
-  (if (ess--dbg-is-recover-p)
-      (progn (ess-send-string (ess-get-process) "0")
-       (ess-send-string (ess-get-process) "f"))
-    (ess-send-string (ess-get-process) "f")))
-
-
-(defun ess-debug-command-resume ()
-  "Step next in debug mode.
-Equivalent to `f' at the R prompt."
-  (interactive)
-  (ess-force-buffer-current)
-  (unless (ess--dbg-is-active-p)
-    (error "Debugger is not active"))
-  (if (ess--dbg-is-recover-p)
-      (progn (ess-send-string (ess-get-process) "0")
-       (ess-send-string (ess-get-process) "r"))
-    (ess-send-string (ess-get-process) "r")))
-
-(defun ess-debug-command-where ()
-  "Step next in debug mode.
-Equivalent to `where' at the R prompt."
-  (interactive)
-  (ess-force-buffer-current)
-  (unless (ess--dbg-is-active-p)
-    (error "Debugger is not active"))
-    (ess-send-string (ess-get-process) "where"))
-
-
-(defun ess-debug-command-help ()
-  "Step next in debug mode.
-Equivalent to `where' at the R prompt."
-  (interactive)
-  (ess-force-buffer-current)
-  (unless (ess--dbg-is-active-p)
-    (error "Debugger is not active"))
-    (ess-send-string (ess-get-process) "help"))
-
-(defun ess-debug-command-next-multi (&optional N)
-  "Ask for N and step (n) N times in debug mode."
-  (interactive)
-  (ess-force-buffer-current)
-  (unless (ess--dbg-is-active-p)
-    (error "Debugger is not active"))
-  (let ((N (or N (read-number "Number of steps: " 10)))
-        (ess--suppress-next-output? t))
-    (while (and (ess--dbg-is-active-p) (> N 0))
-      (ess-debug-command-next)
-      (ess-wait-for-process)
-      (setq N (1- N))))
-  (ess-debug-command-next))
-
-(defun ess-debug-command-continue-multi (&optional N)
-  "Ask for N, and continue (c) N times in debug mode."
-  (interactive)
-  (ess-force-buffer-current)
-  (unless (ess--dbg-is-active-p)
-    (error "Debugger is not active"))
-  (let ((N (or N (read-number "Number of continuations: " 10)))
-        (ess--suppress-next-output? t))
-    (while (and (ess--dbg-is-active-p) (> N 1))
-      (ess-debug-command-continue)
-      (ess-wait-for-process)
-      (setq N (1- N))))
-  (ess-debug-command-continue))
-
-(defun ess-debug-command-up ()
-  "Step up one call frame.."
-  (interactive)
-  (ess-force-buffer-current)
-  (unless (ess--dbg-is-active-p)
-    (error "Debugger is not active"))
-  (let ((up-cmd "try(browserSetDebug(), silent=T)\nc\n"))
-    (ess-send-string (ess-get-process) up-cmd)))
-
-;; (defun ess-debug-previous-error (&optional ev)
-;;   "Go to previous reference during the debug process.
-;; R doesn't support step backwards. This command just takes you  through
-;; debug history."
-;;   (interactive)
-;;   (previous-error))
-
-(defun ess-debug-command-quit ()
-  "Quits the browser/debug in R process.
-Equivalent of `Q' at the R prompt."
-  (interactive)
-  (ess-force-buffer-current)
-  (cond ((ess--dbg-is-recover-p)
-         (ess-send-string (ess-get-process) "0" t))
-        ;; if recover is called in a loop the following stalls Emacs
-        ;; (ess-wait-for-process proc nil 0.05)
-        ((ess--dbg-is-active-p)
-         (ess-send-string (ess-get-process) "Q" t))
-        (t
-         (error "Debugger is not active"))))
-
-(defun ess-debug-command-continue ()
-  "Continue the code execution.
-Equivalent of `c' at the R prompt."
-  (interactive)
-  (ess-force-buffer-current)
-  (cond ((ess--dbg-is-recover-p)
-         (ess-send-string (ess-get-process) "0"))
-        ((ess--dbg-is-active-p)
-         (ess-send-string (ess-get-process) "c"))
-        (t
-         (error "Debugger is not active"))))
-
-(defun ess-tracebug-set-last-input (&rest _args)
-  "Move `ess--tb-last-input' marker to the process mark.
-ARGS are ignored to allow using this function in process hooks."
-  (let* ((last-input-process (get-process ess-local-process-name))
-         (last-input-mark (copy-marker (process-mark last-input-process))))
-    (with-current-buffer (process-buffer last-input-process)
-      (when (local-variable-p 'ess--tb-last-input) ;; TB might not be active in all processes
-        (save-excursion
-          (setq ess--tb-last-input last-input-mark)
-          (goto-char last-input-mark)
-          (inferior-ess-move-last-input-overlay))))))
-
-;;;_ + BREAKPOINTS
-
-(defface ess-bp-fringe-inactive-face
-  '((((class color) (background light) (min-colors 88)) (:foreground "DimGray"))
-    (((class color) (background dark) (min-colors 88))  (:foreground "LightGray"))
-    (((background light) (min-colors 8))  (:foreground "blue"))
-    (((background dark) (min-colors 8))  (:foreground "cyan")))
-  "Face used to highlight inactive breakpoints."
-  :group 'ess-debug)
-
-(defface ess-bp-fringe-logger-face
-  '((((class color) (background light) (min-colors 88)) (:foreground "dark red"))
-    (((class color) (background dark) (min-colors 88))  (:foreground "tomato1"))
-    (((background light) (min-colors 8))  (:foreground "blue"))
-    (((background dark) (min-colors 8))  (:foreground "cyan")))
-  "Face used to highlight loggers."
-  :group 'ess-debug)
-
-(defface ess-bp-fringe-browser-face
-  '((((class color) (background light) (min-colors 88)) (:foreground "medium blue"))
-    (((class color) (background dark) (min-colors 88))  (:foreground "deep sky blue"))
-    (((background light) (min-colors 8))  (:foreground "blue"))
-    (((background dark) (min-colors 8))  (:foreground "cyan")))
-  "Face used to highlight `browser' breakpoints."
-  :group 'ess-debug)
-
-(defface ess-bp-fringe-recover-face
-  '((((class color) (background light) (min-colors 88)) (:foreground "dark magenta"))
-    (((class color) (background dark) (min-colors 88))  (:foreground "magenta"))
-    (((background light) (min-colors 8))  (:foreground "magenta"))
-    (((background dark) (min-colors 8))  (:foreground "magenta")))
-  "Face used to highlight `recover' breakpoints fringe."
-  :group 'ess-debug)
-
-(defun ess--bp-pipe-block-p ()
-  (save-excursion
-    (let ((inhibit-field-text-motion t))
-      (forward-line -1)
-      (end-of-line)
-      (looking-back "%>%[ \t]*" (line-beginning-position)))))
-
-(defun ess--bp-pipe-native-block-p ()
-  (save-excursion
-    (let ((inhibit-field-text-motion t))
-      (forward-line -1)
-      (end-of-line)
-      (looking-back "|>[ \t]*" (line-beginning-position)))))
-
-(defvar ess--bp-identifier 1)
-(defcustom ess-bp-type-spec-alist
-  '((pipe    ".ess_pipe_browser() %%>%%" "B %>%\n" filled-square ess-bp-fringe-browser-face ess--bp-pipe-block-p)
-    (pipe-native ".ess_pipe_browser() |>" "B |>\n" filled-square ess-bp-fringe-browser-face ess--bp-pipe-native-block-p)
-    (browser "browser(expr=is.null(.ESSBP.[[%s]]));" "B>\n" filled-square  ess-bp-fringe-browser-face)
-    (recover "recover()" "R>\n"   filled-square  ess-bp-fringe-recover-face))
-  "List of lists of breakpoint types.
-Each sublist  has five elements:
-1- symbol giving the name of specification
-2- R expression to be inserted (%s is substituted with unique identifier).
-3- string to be displayed instead of the expression
-4- fringe bitmap to use
-5- face for fringe and displayed string
-6- optional, a function which should return nil if this BP
-   doesn't apply to current context."
-  :group 'ess-debug
-  :type '(alist :key-type symbol
-                ;; FIXME: What's this `group'?  The values looks like strings!
-                ;; FIXME: The docstring talks about a 6th element (function)
-                ;; but it's missing here.
-                :value-type (group string string symbol face)))
-
-(defcustom ess-bp-inactive-spec
-  '(inactive     "##"    filled-square  ess-bp-fringe-inactive-face)
-  "List giving the inactive breakpoint specifications."
-  ;; List format is identical to that of the elements of
-  ;; `ess-bp-type-spec-alist' except that the second element giving
-  ;; the R expression is meaningless here." ;;fixme: second element is missing make it nil for consistency with all other specs
-  :group 'ess-debug
-  :type '(alist :key-type symbol
-                :value-type (group string string symbol face)))
-
-(defcustom ess-bp-conditional-spec
-  '(conditional     "browser(expr={%s})"  "CB[ %s ]>\n"  question-mark  ess-bp-fringe-browser-face)
-  "List giving the conditional breakpoint specifications.
-List format is identical to that of the elements of
-`ess-bp-type-spec-alist'.  User is asked for the conditional
-expression to be replaced instead of %s in the second and third
-elements of the specifications."
-  :group 'ess-debug
-  :type '(alist :key-type symbol
-                :value-type (group string string symbol face)))
-
-(defcustom ess-bp-logger-spec
-  '(logger     ".ess_log_eval('%s')"  "L[ \"%s\" ]>\n"  hollow-square  ess-bp-fringe-logger-face)
-  "List giving the loggers specifications.
-List format is identical to that of `ess-bp-type-spec-alist'."
-  :group 'ess-debug
-  :type '(alist :key-type symbol
-                :value-type (group string string symbol face)))
-
-
-(defun ess-bp-get-bp-specs (type &optional condition no-error)
-  "Get specs for TYPE."
-  (let ((spec-alist (cond
-                     ((eq type 'conditional)
-                      (let ((tl (copy-sequence  ess-bp-conditional-spec)))
-                        (when (eq (length condition) 0)
-                          (setq condition "TRUE"))
-                        (setcar (cdr tl) (format (cadr tl) condition))
-                        (setcar (cddr tl) (format (caddr tl) condition))
-                        (list tl)))
-                     ((eq type 'logger)
-                      (let ((tl (copy-sequence ess-bp-logger-spec)))
-                        (when (eq (length condition) 0)
-                          (setq condition "watchLog"))
-                        (setcar (cdr tl) (format (cadr tl) condition))
-                        (setcar (cddr tl) (format (caddr tl) condition))
-                        (list tl)))
-                     (t (copy-sequence ess-bp-type-spec-alist)))))
-    (or (assoc type spec-alist)
-        (if no-error
-            nil
-          (error "Undefined breakpoint type %s" type)))))
-
-(defun ess-bp-create (type &optional condition no-error)
-  "Set breakpoint for the current line.
-Returns the beginning position of the hidden text."
-  (let* ((bp-specs (ess-bp-get-bp-specs type condition no-error))
-         (init-pos (point-marker))
-         (fringe-bitmap (nth 3 bp-specs))
-         (fringe-face (nth 4 bp-specs))
-         (displ-string (nth 2 bp-specs))
-         (bp-id (format "\"@%s@\""
-                        (setq ess--bp-identifier (1+ ess--bp-identifier))))
-         (bp-command (concat  (format (nth 1 bp-specs) bp-id)
-                              "##:ess-bp-end:##\n"))
-         (dummy-string (format "##:ess-bp-start::%s@%s:##\n"  (car bp-specs) condition))
-         insertion-pos)
-    (when bp-specs
-      (set-marker init-pos (1+ init-pos))
-      (setq displ-string (propertize displ-string
-                                     'face fringe-face
-                                     'font-lock-face fringe-face))
-      (setq bp-command (propertize bp-command
-                                   'ess-bp t
-                                   'bp-id bp-id
-                                   'bp-active t
-                                   'cursor-intangible 'ess-bp
-                                   'rear-nonsticky '(cursor-intangible ess-bp bp-type)
-                                   'bp-type type
-                                   'bp-substring 'command
-                                   'display displ-string))
-      (setq dummy-string (propertize
-                          (ess-tracebug--propertize dummy-string fringe-bitmap fringe-face "*")
-                          'ess-bp t
-                          'cursor-intangible 'ess-bp
-                          'bp-type type
-                          'bp-substring 'dummy))
-      (ess-tracebug--set-left-margin)
-      (back-to-indentation)
-      (setq insertion-pos (point) )
-      (insert (concat   dummy-string bp-command))
-      (indent-for-tab-command)
-      (goto-char (1- init-pos))  ;; sort of save-excursion
-      insertion-pos)))
-
-(defun ess-bp-recreate-all ()
-  "Internal function to recreate all bp."
-  (save-excursion
-    (save-restriction
-      (with-silent-modifications
-        (cursor-intangible-mode)
-        (widen)
-        (goto-char (point-min))
-        (while (re-search-forward
-                "\\(##:ess-bp-start::\\(.*\\):##\n\\)\\(.+##:ess-bp-end:##\n\\)" nil t)
-          (let ((dum-beg (match-beginning 1))
-                (dum-end (match-end 1))
-                (comm-beg (match-beginning 3))
-                (comm-end (match-end 3))
-                (type (match-string 2))
-                (bp-command (match-string 3))
-                bp-id dum-props condition)
-            (when (string-match "^\\(\\w+\\)@\\(.*\\)\\'" type)
-              (setq condition (match-string 2 type))
-              (setq type (match-string 1 type)))
-            (setq bp-id
-                  (if (string-match "\"@[0-9]+@\"" bp-command)
-                      (match-string 0 bp-command)
-                    (setq ess--bp-identifier (1+ ess--bp-identifier))))
-            (setq type (intern type))
-            (let* ((bp-specs (ess-bp-get-bp-specs  type condition t))
-                   (displ-string (nth 2 bp-specs))
-                   (fringe-face (nth 4 bp-specs))
-                   (fringe-bitmap (nth 3 bp-specs)))
-              (when bp-specs
-                (setq displ-string (propertize displ-string
-                                               'face fringe-face
-                                               'font-lock-face fringe-face))
-                (add-text-properties comm-beg comm-end
-                                     (list 'ess-bp t
-                                           'bp-id bp-id
-                                           'cursor-intangible 'ess-bp
-                                           'rear-nonsticky '(cursor-intangible ess-bp bp-type)
-                                           'bp-type type
-                                           'bp-substring 'command
-                                           'display displ-string))
-                (setq dum-props
-                      (if window-system
-                          (list 'display (list 'left-fringe fringe-bitmap fringe-face))
-                        (list 'display (list '(margin left-margin)
-                                             (propertize "dummy"
-                                                         'font-lock-face fringe-face
-                                                         'face fringe-face)))))
-                (add-text-properties dum-beg dum-end
-                                     (append dum-props
-                                             (list 'ess-bp t
-                                                   'cursor-intangible 'ess-bp
-                                                   'bp-type type
-                                                   'bp-substring 'dummy)))
-                ;; (when comment-beg
-                ;;   (add-text-properties comment-beg comment-end
-                ;;                        (list 'ess-bp t
-                ;;                              'bp-id bp-id
-                ;;                              'cursor-intangible 'ess-bp
-                ;;                              'display (propertize (nth 1 ess-bp-inactive-spec) 'face fringe-face)
-                ;;                              'bp-type type
-                ;;                              'bp-substring 'comment)))
-                ))))))))
-
-(add-hook 'ess-r-mode-hook #'ess-bp-recreate-all)
-
-
-(defun ess-bp-get-bp-position-nearby ()
-  "Get nearby break points.
-Return the cons (beg . end) of breakpoint limit points closest to
-the current position. Only currently visible region of the buffer
-is searched. This command is intended for use in interactive
-commands like `ess-bp-toggle-state' and `ess-bp-kill'. Use
-`ess-bp-previous-position' in programs."
-  (interactive)
-  (let*  ((pos-end (if (get-char-property (1- (point)) 'ess-bp)
-                       (point)
-                     (previous-single-property-change (point) 'ess-bp nil (window-start))))
-          (pos-start (if (get-char-property (point) 'ess-bp) ;;check for bobp
-                         (point)
-                       (next-single-property-change (point) 'ess-bp nil (window-end))))
-          dist-up dist-down)
-    (unless (eq pos-end (window-start))
-      (setq dist-up (- (line-number-at-pos (point))
-                       (line-number-at-pos pos-end))))
-    (unless (eq pos-start (window-end))
-      (setq dist-down (- (line-number-at-pos pos-start)
-                         (line-number-at-pos (point)))))
-    (if (and dist-up dist-down)
-        (if (< dist-up dist-down)
-            (cons (previous-single-property-change pos-end 'ess-bp nil (window-start)) pos-end)
-          (cons pos-start (next-single-property-change pos-start 'ess-bp nil (window-end))))
-      (if dist-up
-          (cons (previous-single-property-change pos-end 'ess-bp nil (window-start)) pos-end)
-        (if dist-down
-            (cons pos-start (next-single-property-change pos-start 'ess-bp nil (window-end))))))))
-
-
-(defun ess-bp-previous-position ()
-  "Get previous breakpoints.
-Return the cons (beg . end) of breakpoint limit points closest
-to the current position, nil if not found."
-  (let* ( (pos-end (if (get-char-property (1- (point)) 'ess-bp)
-                       (point)
-                     (previous-single-property-change (point) 'ess-bp ))))
-    (if pos-end
-        (cons (previous-single-property-change pos-end 'ess-bp) pos-end))))
-
-(defun ess-bp-set ()
-  "Set a breakpoint."
-  (interactive)
-  (let* ((pos (ess-bp-get-bp-position-nearby))
-         (same-line (and pos
-                         (<=  (line-beginning-position) (cdr pos))
-                         (>= (line-end-position) (car pos))))
-         (types ess-bp-type-spec-alist)
-         (ev last-command-event)
-         (com-char  (event-basic-type ev))
-         bp-type)
-    (when same-line
-      ;; set bp-type to next type in types
-      (setq bp-type (get-text-property (car pos) 'bp-type))
-      (setq types (cdr (member (assq bp-type types) types))) ; nil if bp-type is last in the list
-      (when (null types)
-        (setq types ess-bp-type-spec-alist))
-      (ess-bp-kill)
-      (indent-for-tab-command))
-    ;; skip contextual bps
-    (while (and (nth 5 (car types))
-                (not (funcall (nth 5 (car types)))))
-      (pop types))
-    (setq bp-type (pop types))
-    (ess-bp-create (car bp-type))
-    (while  (eq (event-basic-type (setq ev (read-event (format "'%c' to cycle" com-char))))
-                com-char)
-      (if (null types) (setq types ess-bp-type-spec-alist))
-      (ess-bp-kill)
-      ;; skip contextual bps
-      (while (and (nth 5 (car types))
-                  (not (funcall (nth 5 (car types)))))
-        (pop types))
-      (setq bp-type (pop types))
-      (ess-bp-create (car bp-type))
-      (indent-for-tab-command))
-    (push ev unread-command-events)))
-
-
-(defun ess-bp-set-conditional (condition)
-  (interactive "sBreakpoint condition: ")
-  (ess-bp-create 'conditional condition)
-  (indent-for-tab-command))
-
-(defun ess-bp-set-logger (name)
-  (interactive "sLogger name : ")
-  (ess-bp-create 'logger name)
-  (indent-for-tab-command))
-
-(defun ess-bp-kill (&optional interactive?)
-  "Remove the breakpoint nearby."
-  (interactive "p")
-  (let ((pos (ess-bp-get-bp-position-nearby))
-        (init-pos (make-marker)))
-    (if (null pos)
-        (if interactive? (message "No breakpoints nearby"))
-      (if (eq (point) (line-end-position))
-          (goto-char (1- (point)))) ;; work-around for issue  3
-      (set-marker init-pos  (point))
-      (goto-char (car pos))
-      (delete-region (car pos) (cdr pos))
-      (indent-for-tab-command)
-      (goto-char init-pos)
-      (if (eq (point) (line-end-position)) (forward-char)))))
-
-(defun ess-bp-kill-all nil
-  "Delete all breakpoints in current buffer."
-  (interactive)
-  (let ((count 0)
-        (init-pos (make-marker))
-        pos)
-    (set-marker init-pos (1+ (point)))
-    (save-excursion   ;; needed if error
-      (goto-char (point-max))
-      (while (setq pos (ess-bp-previous-position))
-        (goto-char (car pos))
-        (delete-region (car pos) (cdr pos))
-        (indent-for-tab-command)
-        (setq count (1+ count)))
-      (if (eq count 1)
-          (message "Killed 1 breakpoint")
-        (message "Killed %d breakpoint(s)" count)))
-    (goto-char (1- init-pos))))
-
-
-(defun ess-bp-toggle-state ()
-  "Toggle the breakpoint between active and inactive states.
-
-For standard breakpoints, the effect of this command is
-immediate, that is you don't need to source your code and it
-works even in the process of debugging.
-
-For loggers, recover and conditional breakpoints this command
-just comments the breakpoint in the source file.
-
-If there is no active R session, this command triggers an error."
-  (interactive)
-  (unless (and ess-local-process-name
-               (get-process ess-local-process-name))
-    (error "No R session in this buffer"))
-  (save-excursion
-    (let ((pos (ess-bp-get-bp-position-nearby))
-          (fringe-face (nth 3 ess-bp-inactive-spec))
-          (cursor-sensor-inhibit 'ess-bp-toggle-state)
-          bp-id bp-specs beg-pos-command)
-      (if (null pos)
-          (message "No breakpoints in the visible region")
-        (goto-char (car pos))
-        (setq beg-pos-command (previous-single-property-change
-                               (cdr pos) 'bp-substring nil (car pos))
-              bp-id (get-char-property beg-pos-command 'bp-id))
-        (goto-char beg-pos-command)
-        (if (get-char-property beg-pos-command 'bp-active)
-            (progn
-              (put-text-property  (car pos) beg-pos-command ;; dummy display change
-                                  'display (list 'left-fringe (nth 2 ess-bp-inactive-spec) fringe-face))
-              (put-text-property beg-pos-command (cdr pos)
-                                 'bp-active nil)
-              (ess-command (format ".ESSBP.[[%s]] <- TRUE\n" bp-id)))
-          (setq bp-specs (assoc (get-text-property (point) 'bp-type) ess-bp-type-spec-alist))
-          (put-text-property beg-pos-command (cdr pos)
-                             'bp-active t)
-          (put-text-property  (car pos) beg-pos-command
-                              'display (list 'left-fringe (nth 3 bp-specs) (nth 4 bp-specs)))
-          (ess-command (format ".ESSBP.[[%s]] <- NULL\n" bp-id))
-          ;; (insert (propertize "##"
-          ;;                     'ess-bp t
-          ;;                     'cursor-intangible 'ess-bp
-          ;;                     'display (propertize (nth 1 ess-bp-inactive-spec) 'face fringe-face)
-          ;;                     'bp-type (get-char-property (point) 'bp-type)
-          ;;                     'bp-substring 'comment))
-          )))))
-
-
-(defun ess-bp-make-visible ()
-  "Make bp text visible."
-  (interactive)
-  (let ((pos (ess-bp-get-bp-position-nearby)))
-    (set-text-properties (car pos) (cdr pos) (list 'display nil))))
-
-
-
-(defun ess-bp-next nil
-  "Goto next breakpoint."
-  (interactive)
-  (when-let* ((bp-pos (next-single-property-change (point) 'ess-bp)))
-    (save-excursion
-      (goto-char bp-pos)
-      (when (get-text-property (1- (point)) 'ess-bp)
-        (setq bp-pos (next-single-property-change bp-pos 'ess-bp))))
-    (if bp-pos
-        (goto-char bp-pos)
-      (message "No breakpoints found"))))
-
-
-(defun ess-bp-previous nil
-  "Goto previous breakpoint."
-  (interactive)
-  (if-let* ((bp-pos (previous-single-property-change (point) 'ess-bp)))
-      (goto-char (or (previous-single-property-change bp-pos 'ess-bp)
-                     bp-pos))
-    (message "No breakpoints before the point found")))
-
-;;;_ + WATCH
-
-(defvar ess-watch-command
-  ;; assumes that every expression is a structure of length 1 as returned by parse.
-  ".ess_watch_eval()\n")
-
-(if (fboundp 'define-fringe-bitmap) ;;not clear to me why is this not bound in SSH session? - :TODO check
-    (define-fringe-bitmap 'current-watch-bar
-      [#b00001100] nil nil '(top t)))
-
-(defun ess-tracebug--set-left-margin ()
-  "Set the margin on non-X displays."
-  (unless window-system
-    (when (= left-margin-width 0)
-      (setq left-margin-width 1)
-      (set-window-buffer (selected-window) (current-buffer)))))
-
-(define-derived-mode ess-watch-mode special-mode "ESS watch"
-  "Major mode in `ess-watch' window."
-  :group 'ess-tracebug
-  (let ((cur-block (max 1 (ess-watch-block-at-point)))
-        (dummy-string
-         (ess-tracebug--propertize "|" 'current-watch-bar 'font-lock-keyword-face)))
-    (ess-tracebug--set-left-margin)
-    (setq-local revert-buffer-function #'ess-watch-revert-buffer)
-    (turn-on-font-lock)
-    (setq ess-watch-current-block-overlay
-          (make-overlay (point-min) (point-max)))
-    (overlay-put ess-watch-current-block-overlay 'line-prefix dummy-string)
-    (overlay-put ess-watch-current-block-overlay 'face 'ess-watch-current-block-face)
-    (ess-watch-set-current cur-block) ;;
-    (require 'face-remap)
-    ;; scale the font
-    (setq text-scale-mode-amount ess-watch-scale-amount)
-    (text-scale-mode)))
-
-(defun ess-watch ()
-  "Run `ess-watch-mode' on R objects.
-This is the trigger function.  See documentation of
-`ess-watch-mode' for more information."
-  (interactive)
-  (ess-force-buffer-current)
-  (let ((wbuf (get-buffer-create ess-watch-buffer))
-        (pname ess-local-process-name))
-    (pop-to-buffer wbuf
-                   ;; not strongly dedicated
-                   '(nil . ((dedicated . 1))))
-    (setq ess-local-process-name pname)
-    (ess-watch-mode)
-    ;; evals the ess-command and displays the buffer if not visible
-    (ess-watch-refresh-buffer-visibly wbuf)))
-
-
-(defun ess-watch-refresh-buffer-visibly (wbuf &optional sleep no-prompt-check)
-  "Eval `ess-watch-command' and direct the output into the WBUF.
-Call `ess-watch-buffer-show' to make the buffer visible, without
-selecting it. SLEEP and NO-PROMPT-CHECK get passed to `ess-command'.
-
-This function is used for refreshing the watch window after each step during
-the debugging."
-  ;; assumes that the ess-watch-mode is on!!
-  ;; particularly ess-watch-current-block-overlay is installed
-  (ess-watch-buffer-show wbuf) ;; if visible do nothing
-  (let ((pname ess-local-process-name)) ;; watch might be used from different dialects, need to reset
-    (with-current-buffer wbuf
-      (let ((curr-block (max 1 (ess-watch-block-at-point))) ;;can be 0 if
-            (inhibit-read-only t))
-        (when pname
-          (setq ess-local-process-name pname))
-        (ess-command  ess-watch-command wbuf sleep no-prompt-check)
-        ;; delete the ++++++> line  ;; not very reliable but works fine so far.
-        (goto-char (point-min))
-        (delete-region (line-beginning-position) (+ 1 (line-end-position)))
-        (ess-watch-set-current curr-block)
-        (set-window-point (get-buffer-window wbuf) (point))))))
-
-(defun ess-watch-buffer-show (buffer-or-name)
-  "Make watch buffer BUFFER-OR-NAME visible, and position accordingly.
-If already visible, do nothing.
-
-Currently the only positioning rule implemented is to split the R
-process window in half.  The behavior is controlled by
-`split-window-sensibly' with parameters `split-height-threshold'
-and `split-width-threshold' replaced by
-`ess-watch-height-threshold' and `ess-watch-width-threshold'
-respectively."
-  (interactive)
-  (unless (get-buffer-window ess-watch-buffer 'visible)
-    (save-selected-window
-      (ess-switch-to-ESS t)
-      (let* ((split-width-threshold (or ess-watch-width-threshold
-                                        split-width-threshold))
-             (split-height-threshold (or ess-watch-height-threshold
-                                         split-height-threshold))
-             (win (split-window-sensibly (selected-window))))
-        (if win
-            (set-window-buffer win buffer-or-name)
-          (display-buffer buffer-or-name) ;; resort to usual mechanism if could not split
-          )))))
-
-
-(defun ess-watch-revert-buffer (_ignore _noconfirm)
-  "Update the watch buffer.
-Arguments IGNORE and NOCONFIRM currently not used."
-  (ess-watch)
-  (message "Watch reverted"))
-
-
-(defface ess-watch-current-block-face
-  '((default (:inherit highlight)))
-  "Face used to highlight current watch block."
-  :group 'ess-debug)
-
-(defvar  ess-watch-start-block "@----"  ;; fixme: make defcustom and modify the injected command correspondingly
-  "String indicating the beginning of a block in watch buffer."
-  ;; :group 'ess-debug
-  ;; :type 'string
-  )
-
-(defvar ess-watch-start-expression "@---:"
-  "String indicating the beginning of an R expression in watch buffer."
-  ;; :group 'ess-debug
-  ;; :type 'string
-  )
-
-(defun ess-watch-block-limits-at-point ()
-  "Return start and end positions of the watch block."
-  (interactive)
-  (save-excursion
-    (let ((curr (point))
-          start-pos end-pos)
-      (end-of-line)
-      (setq start-pos
-            (if (re-search-backward ess-watch-start-block nil t )
-                (point)
-              (point-min)))
-      (goto-char curr)
-      (beginning-of-line)
-      (setq end-pos
-            (if (re-search-forward ess-watch-start-block nil t)
-                (match-beginning 0)
-              (point-max)))
-      (list start-pos end-pos))))
-
-(defun ess-watch-block-at-point ()
-  "Return the current block's order count, 0 if no block was found."
-  (save-excursion
-    (let ((cur-point (point))
-          (count 0))
-      (goto-char (point-min))
-      (while (re-search-forward ess-watch-start-block cur-point t)
-        (setq count (1+ count)))
-      count)))
-
-(defun ess-watch-set-current (nr)
-  "Move the overlay over the block with count NR in current watch buffer."
-  (goto-char (point-min))
-  (re-search-forward ess-watch-start-expression nil t nr)
-  (goto-char (match-end 0))
-  (apply #'move-overlay ess-watch-current-block-overlay (ess-watch-block-limits-at-point)))
-
-
-(defun ess-watch--make-alist ()
-  "Create an alist of expressions from the current watch buffer.
-Each element of assoc list is of the form (pos name expr) where
-pos is an unique integer identifying watch blocks by position,
-name is a string giving the name of expression block, expr is a
-string giving the actual R expression."
-  (interactive)
-  (save-excursion
-    (let* ((reg-name (concat "^" ess-watch-start-block " *\\(\\S-*\\).*$"))
-           (reg-expr (concat "^" ess-watch-start-expression "\\s-*\\(.*\\)$"))
-           (reg-all (concat "\\(" reg-name "\\)\n\\(" reg-expr "\\)"))
-           (pos 0) wal name expr)
-      (goto-char (point-min))
-      (while (re-search-forward reg-all nil t)
-        (setq pos  (+ 1 pos))
-        (setq name (match-string-no-properties 2))
-        (setq expr (match-string-no-properties 4))
-        (if (not (eq (string-to-number name) 0))  ;;if number of any kind set the name to ""
-            (setq name ""))
-        (setq wal
-              (append wal (list (list pos name expr)))))
-      wal)))
-
-(defun ess-watch--parse-assoc (al)
-  "Return a string command ready to be passed to R process.
-The command is of the form `assign(\".ess_watch_expressions\",
-list(a = parse(expr_a), b= parse(expr_b)), envir = .GlobalEnv)'.
-AL is an association list as return by `ess-watch--make-alist'"
-  (concat ".ess_watch_assign_expressions(list("
-          (mapconcat (lambda (el)
-                       (if (> (length  (cadr el) ) 0)
-                           (concat "`" (cadr el) "` = parse(text = '" (caddr el) "')")
-                         (concat "parse(text = '" (caddr el) "')")))
-                     al ", ")
-          "))\n"))
-
-(defun ess-watch--install-.ess_watch_expressions ()
-  ;; used whenever watches are added/deleted/modified from the watch
-  ;; buffer. this is the only way  to insert expressions into
-  ;; .ess_watch_expressions object in R. Assumes R watch being the current
-  ;; buffer, otherwise will most likely install empty list.
-  (interactive)
-  (process-send-string (ess-get-process ess-current-process-name)
-                       (ess-watch--parse-assoc (ess-watch--make-alist)))
-  ;;TODO: delete the prompt at the end of proc buffer TODO: defun ess-send-string!!
-  (sleep-for 0.05)  ;; need here, if ess-command is used immediately after,  for some weird reason the process buffer will not be changed
-  )
-
-
-(defun ess-watch-quit ()
-  "Quit (kill) the watch buffer.
-If watch buffer exists, it is displayed during the debug
-process. The only way to avoid the display, is to kill the
-buffer."
-  (interactive)
-  (kill-buffer) ;; dedicated, window is deleted unless not the only one
-  )
-
-;;;_  + MOTION
-(defun ess-watch-next-block (&optional n)
-  "Move the overlay over the next block.
-Optional N if supplied gives the number of steps forward `backward-char'."
-  (interactive "P")
-  (setq n (prefix-numeric-value n))
-  (goto-char (overlay-end ess-watch-current-block-overlay))
-  (unless (re-search-forward ess-watch-start-expression nil t n)
-    (goto-char (point-min)) ;;circular but always moves to start!
-    (re-search-forward ess-watch-start-expression nil t 1))
-  (apply #'move-overlay ess-watch-current-block-overlay (ess-watch-block-limits-at-point)))
-
-(defun ess-watch-previous-block (&optional n)
-  "Move the overlay over the previous block.
-Optional N if supplied gives the number of backward steps."
-  (interactive "P")
-  (setq n (prefix-numeric-value n))
-  (goto-char (overlay-start ess-watch-current-block-overlay))
-  (unless (re-search-backward ess-watch-start-expression nil t n)
-    (goto-char (point-max)) ;;circular but always moves to last!
-    (re-search-backward ess-watch-start-expression nil t 1))
-  (goto-char (match-end 0))
-  (apply #'move-overlay ess-watch-current-block-overlay (ess-watch-block-limits-at-point)))
-
-;;;_  + BLOCK MANIPULATION and EDITING
-(defun ess-watch-rename ()
-  "Rename the currently selected watch block."
-  (interactive)
-  (end-of-line)
-  (unless (re-search-backward ess-watch-start-block nil t)
-    (error "Can not find a watch block"))
-  (let ((reg-name (concat ess-watch-start-block " *\\(\\S-*\\).*$"))
-        name start end)
-    ;; (reg-expr (concat "^" ess-watch-start-expression "\\s-*\\(.*\\)$"))
-    ;; (reg-all (concat "\\(" reg-name "\\)\n\\(" reg-expr "\\)"))
-    ;; (pos 0) wal name expr)
-    (unless (re-search-forward reg-name (line-end-position) t)
-      (error "Can not find the name substring in the current watch block "))
-    (setq name (match-string-no-properties 1))
-    (setq start (match-beginning 1))
-    (setq end (match-end 1))
-    (goto-char start)
-    ;; TODO: highlight the name in R-watch here
-    (setq name (read-string (concat "New name (" name "): ") nil nil name) )
-    (setq buffer-read-only nil)
-    (delete-region start end)
-    (insert name)
-    (setq buffer-read-only t)
-    (ess-watch--install-.ess_watch_expressions)
-    (ess-watch-refresh-buffer-visibly (current-buffer))))
-
-(defun ess-watch-edit-expression ()
-  "Edit in the minibuffer the R expression from the current watch block."
-  (interactive)
-  (end-of-line)
-  (unless (re-search-backward ess-watch-start-block nil 1)
-    (error "Can not find a watch block"))
-  (let ((reg-expr (concat ess-watch-start-expression " *\\(.*\\)$"))
-        expr start end)
-    (unless (re-search-forward reg-expr nil t)
-      (error "Can not find an expression string in the watch block"))
-    (setq expr (match-string-no-properties 1))
-    (setq start (match-beginning 1))
-    (setq end (match-end 1))
-    (goto-char start)
-    ;; TODO: highlight the name in R-watch here
-    (setq expr (read-string  "New expression: " expr nil expr) )
-    (setq buffer-read-only nil)
-    (delete-region start end)
-    (insert expr)
-    (setq buffer-read-only t)
-    (ess-watch--install-.ess_watch_expressions)
-    (ess-watch-refresh-buffer-visibly (current-buffer))))
-
-(defun ess-watch-add ()
-  "Ask for new R expression and append to the current list of watch expressions."
-  (interactive)
-  (let (nr expr name)
-    (goto-char (point-max))
-    (setq nr (number-to-string (1+ (ess-watch-block-at-point))))
-    (setq name nr)
-    ;; (setq name (read-string (concat "Name (" nr "):") nil nil nr ))  ;;this one is quite annoying and not really needed than for logging
-    (setq expr (read-string "New expression: " nil nil "\"Empty watch!\""))
-    (setq buffer-read-only nil)
-    (insert (concat "\n" ess-watch-start-block " " name " -@\n" ess-watch-start-expression " " expr "\n"))
-    (setq buffer-read-only t)
-    (ess-watch--install-.ess_watch_expressions)))
-
-(defun ess-watch-insert ()
-  "Ask for new R expression and name and insert it in front of current watch block."
-  (interactive)
-  (let (nr expr name)
-    (setq nr (number-to-string (ess-watch-block-at-point)))
-    (setq name nr)
-    ;; (setq name (read-string (concat "Name (" nr "):") nil nil nr ))
-    (setq expr (read-string "New expression: " nil nil "\"Empty watch!\""))
-    (re-search-backward ess-watch-start-block nil 1) ;;point-min if not found
-    (setq buffer-read-only nil)
-    (insert (concat "\n" ess-watch-start-block " " name " -@\n" ess-watch-start-expression " " expr "\n"))
-    (setq buffer-read-only t)
-    (ess-watch--install-.ess_watch_expressions)))
-
-(defun ess-watch-move-up ()
-  "Move the current block up."
-  (interactive)
-  (let ((nr (ess-watch-block-at-point))
-        wbl)
-    (when (> nr 1)
-      (setq buffer-read-only nil)
-      (setq wbl (apply #'delete-and-extract-region  (ess-watch-block-limits-at-point)))
-      (re-search-backward ess-watch-start-block nil t 1) ;; current block was deleted, point is at the end of previous block
-      (insert wbl)
-      (ess-watch--install-.ess_watch_expressions)
-      (setq buffer-read-only t))))
-
-
-(defun ess-watch-move-down ()
-  "Move the current block down."
-  (interactive)
-  (let ((nr (ess-watch-block-at-point))
-        (nr-all (save-excursion (goto-char (point-max))
-                                (ess-watch-block-at-point)))
-        wbl)
-    (when (< nr nr-all)
-      (setq buffer-read-only nil)
-      (setq wbl (apply #'delete-and-extract-region  (ess-watch-block-limits-at-point)))
-      (end-of-line)
-      (when (re-search-forward ess-watch-start-block nil t 1) ;; current block was deleted, point is at the end of previous block or point-max
-        (goto-char (match-beginning 0)))
-      (insert wbl)
-      (ess-watch--install-.ess_watch_expressions)
-      (setq buffer-read-only t))))
-
-(defun ess-watch-kill ()
-  "Kill the current block."
-  (interactive)
-  (setq buffer-read-only nil)
-  (apply #'delete-region (ess-watch-block-limits-at-point))
-  (ess-watch--install-.ess_watch_expressions))
-
-;;;_ + Debug/Undebug at point
-(defun ess--dbg-get-signatures (method)
-  "Get signatures for the method METHOD."
-  (let ((tbuffer (get-buffer-create " *ess-command-output*")); initial space: disable-undo
-        signatures)
-    (save-excursion
-      (ess-if-verbose-write (format "ess-get-signatures*(%s).. " method))
-      (ess-command (concat "showMethods(\"" method "\")\n") tbuffer)
-      (message "%s" ess-local-process-name)
-      (message "%s" ess-current-process-name)
-      (ess-if-verbose-write " [ok] ..\n")
-      (set-buffer tbuffer)
-      (goto-char (point-min))
-      (if (not (re-search-forward "Function:" nil t))
-          (progn (ess-if-verbose-write "not seeing \"Function:\".. \n")
-                 (error (buffer-string))
-                 ;; (error "Cannot trace  method '%s' (Is it a primitive method which you have already traced?)" method)
-                 )
-        ;; (setq curr-point (point))
-        ;; (while (re-search-forward ", " nil t) ;replace all ", " with  ":" for better readability in completion buffers??
-        ;;   (replace-match ":"))
-        ;; (goto-char curr-point)
-        (while (re-search-forward "^.+$" nil t)
-          (setq signatures (cons (match-string-no-properties 0) signatures))))
-                                        ;      (kill-buffer tbuffer)
-      )
-    signatures))
-
-
-(defun ess-debug-flag-for-debugging ()
-  "Set the debugging flag on a function.
-Ask the user for a function and if it turns to be generic, ask
-for signature and trace it with browser tracer."
-  (interactive)
-  (ess-force-buffer-current "Process to use: ")
-  (let* ((tbuffer (get-buffer-create " *ess-command-output*")) ;; output buffer name is hard-coded in ess-inf.el
-         (pkg (ess-r-package-name))
-         (all-functions (ess-get-words-from-vector--foreground
-                         (if pkg
-                             (format ".ess_all_functions(c('%s'))\n" pkg)
-                           ".ess_all_functions()\n")))
-         (obj-at-point (ess-helpobjs-at-point--read-obj))
-         (default (and
-                   obj-at-point
-                   (let* ((reg (regexp-quote obj-at-point))
-                          (matches (cl-loop for el in all-functions
-                                            if (string-match reg el) collect el)))
-                     (car (sort matches (lambda (a b) (< (length a) (length b))))))))
-         (ufunc (ess-completing-read "Debug" all-functions
-                                     nil nil nil nil (or default obj-at-point)))
-         signature)
-    ;; FIXME: Most of the following logic should be in R
-    (if (ess-boolean-command (format "as.character(isGeneric('%s'))\n" ufunc))
-
-        ;; it's S4 generic:
-        (save-excursion
-          ;; ask for exact signature
-          (setq signature
-                (ess-completing-read (concat "Method for generic '" ufunc "'")
-                                     (ess--dbg-get-signatures ufunc) ;signal an error if not found
-                                     nil t nil nil "*default*"))
-          (if (equal signature "*default*")
-              ;;debug, the default ufunc
-              (ess-command (format "trace('%s', tracer = browser)\n" ufunc) tbuffer)
-            (ess-command (format "trace('%s', tracer = browser, signature = c('%s'))\n" ufunc signature) tbuffer))
-          (with-current-buffer tbuffer
-            ;; give appropriate message or error
-            (message "%s" (buffer-substring-no-properties (point-min) (point-max)))))
-
-      ;;else, not an S4 generic
-      (when (ess-boolean-command (format "as.character(.knownS3Generics['%s'])\n" ufunc))
-        ;; it's S3 generic:
-        (setq all-functions
-              (ess-get-words-from-vector
-               (format "local({gens<-methods('%s');as.character(gens[attr(gens, 'info')$visible])})\n" ufunc)))
-        (setq all-functions
-              ;; cannot debug non-visible methods
-              (delq nil (mapcar (lambda (el)
-                                  (if (not (char-equal ?* (aref el (1- (length el))))) el))
-                                all-functions)))
-        (setq ufunc (ess-completing-read (format "Method for S3 generic '%s'" ufunc)
-                                         (cons ufunc all-functions) nil t)))
-      (ess-command (format ".ess_dbg_flag_for_debuging('%s')\n" ufunc)))))
-
-
-(defun ess-debug-unflag-for-debugging ()
-  "Prompt for the debugged/traced function or method and undebug/untrace it."
-  (interactive)
-  (let ((tbuffer (get-buffer-create " *ess-command-output*")); initial space: disable-undo\
-        (debugged (ess-get-words-from-vector
-                   (if nil ;; FIXME: was checking `ess-developer-packages`
-                       (format ".ess_dbg_getTracedAndDebugged(c('%s'))\n"
-                               (mapconcat 'identity ess-developer-packages "', '"))
-                     ".ess_dbg_getTracedAndDebugged()\n")))
-        out-message fun def-val)
-    ;; (prin1 debugged)
-    (if (eq (length debugged) 0)
-        (setq out-message "No debugged or traced functions/methods found")
-      (setq def-val (if (eq (length debugged) 1)
-                        (car debugged)
-                      "*ALL*"))
-      (setq fun (ess-completing-read "Undebug" debugged nil t nil nil def-val))
-      (if (equal fun "*ALL*" )
-          (ess-command (concat ".ess_dbg_UndebugALL(c(\""
-                               (mapconcat #'identity debugged "\", \"")
-                               "\"))\n")
-                       tbuffer)
-        (ess-command (format ".ess_dbg_UntraceOrUndebug(\"%s\")\n" fun) tbuffer))
-      (with-current-buffer  tbuffer
-        (if (= (point-max) 1) ;; not reliable TODO:
-            (setq out-message (format  "Undebugged '%s' " fun))
-          (setq out-message (buffer-substring-no-properties (point-min) (point-max))) ;; untrace info or warning, or error occurred
-          )))
-    (message "%s" out-message)))
-
-;;;_ * Kludges and Fixes
-;;; delete-char and delete-backward-car do not delete whole intangible text
-(defun ess--tracebug-delete-char (n &rest _)
-  "When deleting an intangible char, delete the whole intangible region.
-Only do this when N is 1"
-  (when (and (ess-derived-mode-p)
-             (= n 1)
-             (get-text-property (point) 'cursor-intangible))
-    (kill-region (point) (or (next-single-property-change (point) 'cursor-intangible)
-                             (point-max)))
-    (indent-according-to-mode)))
-
-(advice-add 'delete-char :before-until #'ess--tracebug-delete-char)
-
-(defun ess--tracebug-delete-backward-char (n &rest _)
-  "When deleting an intangible char, delete the whole intangible region.
-Only do this when called interactively and N is 1"
-  (when (and (ess-derived-mode-p)
-             (= n 1)
-             (> (point) (point-min))
-             (get-text-property (1- (point)) 'cursor-intangible))
-    (kill-region (or (previous-single-property-change (point) 'cursor-intangible)
-                     (point-min))
-                 (point))))
-
-(advice-add 'delete-backward-char :before-until #'ess--tracebug-delete-backward-char)
-
-(provide 'ess-tracebug)
-
-;;; ess-tracebug.el ends here
diff --git a/elpa/ess-20251212.937/ess-trns.el b/elpa/ess-20251212.937/ess-trns.el
deleted file mode 100644 (file)
index 42a62e9..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-;;; ess-trns.el --- Support for manipulating S transcript files  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1989-2020 Free Software Foundation, Inc.
-;; Author: David Smith <dsmithNOSPAMstats.adelaide.edu.au>
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; Code for dealing with ESS transcripts.
-
-;;; Code:
-
-\f ; Requires and autoloads
-
-(require 'ess-mode)
-(require 'ess-inf)
-(require 'comint)
-
-(declare-function ess-display-help-on-object "ess-help" (object &optional command))
-
-\f ; ess-transcript-mode
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;; In this section:
-;;;;
-;;;; * The major mode ess-transcript-mode
-;;;; * Commands for ess-transcript-mode
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defcustom ess-transcript-mode-hook nil
-  "Hook for customizing ESS transcript mode."
-  :group 'ess-hooks
-  :type 'hook)
-
-;;*;; Major mode definition
-(defvar ess-transcript-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map "\C-c\C-s" #'ess-switch-process)
-    (define-key map "\C-c\C-r" #'ess-eval-region)
-    (define-key map "\C-c\M-r" #'ess-eval-region-and-go)
-    (define-key map "\C-c\C-k" #'ess-force-buffer-current)
-    (define-key map "\C-c\C-q" #'ess-quit)
-    (define-key map "\C-c\C-j" #'ess-transcript-send-command)
-    (define-key map "\C-c\M-j" #'ess-transcript-send-command-and-move)
-    (define-key map "\M-\C-a"  #'ess-goto-end-of-function-or-para)
-    (define-key map "\M-\C-e"  #'ess-goto-end-of-function-or-para)
-    (define-key map "\C-c\C-y" #'ess-switch-to-ESS)
-    (define-key map "\C-c\C-z" #'ess-switch-to-end-of-ESS)
-    (define-key map "\C-c\C-v" #'ess-display-help-on-object)
-    (define-key map "\C-c\C-d" #'ess-dump-object-into-edit-buffer)
-    (define-key map "\C-a"     #'comint-bol)
-    (define-key map "\M-\t"    #'comint-replace-by-expanded-filename)
-    (define-key map "\M-?"     #'comint-dynamic-list-completions)
-    (define-key map "\C-c\C-k" #'ess-request-a-process)
-    (define-key map "{"        #'skeleton-pair-insert-maybe)
-    (define-key map "}"        #'skeleton-pair-insert-maybe)
-    (define-key map "\e\C-h"   #'ess-mark-function-or-para)
-    (define-key map "\e\C-q"   #'ess-indent-exp)
-    (define-key map "\t"       #'ess-indent-command)
-    (define-key map "\C-c\C-p" #'comint-previous-prompt)
-    (define-key map "\C-c\C-n" #'comint-next-prompt)
-    (define-key map "\r"       #'ess-transcript-send-command-and-move)
-    (define-key map "\M-\r"    #'ess-transcript-send-command)
-    (define-key map "\C-c\r"   #'ess-transcript-copy-command)
-    (define-key map "\C-c\C-w" #'ess-transcript-DO-clean-region)
-    (define-key map "\C-c\M-c" #'ess-transcript-clean-buffer)
-    map)
-  "Keymap for `ess-transcript-mode'.")
-
-(easy-menu-define
-  ess-transcript-mode-menu ess-transcript-mode-map
-  "Menu for use in S transcript mode."
-  '("ESS-trans"
-    ["Describe"         describe-mode                   t]
-    ["About"           (ess-goto-info "Transcript Mode") t]
-    ["Send bug report"  ess-submit-bug-report           t]
-    "------"
-    ["Mark cmd group"   mark-paragraph          t]
-    ["Previous prompt"  comint-previous-prompt  t]
-    ["Next prompt"      comint-next-prompt      t]
-    "------"
-    ["Send and move" ess-transcript-send-command-and-move t]
-    ["Copy command"  ess-transcript-copy-command       t]
-    ["Send command"  ess-transcript-send-command       t]
-    ["Clean Region"  ess-transcript-DO-clean-region    t]
-    ["Clean Whole Buffer" ess-transcript-clean-buffer  t]
-    ["Switch S process" ess-switch-process             t]
-    ))
-
-;;;###autoload
-(define-derived-mode ess-transcript-mode ess-mode "ESS Transcript"
-  "Major mode for transcript files.
-
-Type \\[ess-transcript-send-command] to send a command in the
-transcript to the current inferior process. \\[ess-transcript-copy-command]
-copies the command but does not execute it, allowing you to edit it in
-the process buffer first.
-
-Type \\[ess-transcript-clean-region] to delete all outputs and prompts
-in the region, leaving only the commands."
-  :group 'ess
-  (setq buffer-read-only t
-        ess-local-process-name nil
-        mode-line-process '(" [" ess-local-process-name "]"))
-  ;; TODO: Set this more normally in various major modes
-  (unless inferior-ess-prompt ;; For S languages it is set in custom-alist
-    (setq inferior-ess-prompt
-          ;; Do not anchor to bol with `^'
-          (concat "\\("
-                  inferior-ess-primary-prompt
-                  "\\|"
-                  inferior-ess-secondary-prompt
-                  "\\)")))
-  (setq-local paragraph-start (concat "^" inferior-ess-prompt "\\|^\^L"))
-  (setq-local paragraph-separate "^\^L")
-  (setq-local comint-use-prompt-regexp t)
-  (setq-local comint-prompt-regexp (concat "^" inferior-ess-prompt))
-  (setq font-lock-defaults '(ess-build-font-lock-keywords
-                             nil nil ((?\. . "w") (?\_ . "w") (?' . ".")))))
-
-;;*;; Commands used in S transcript mode
-
-(defun ess-transcript-send-command ()
-  "Send the command at point in the transcript to the ESS process.
-The line should begin with a prompt.  The ESS process buffer is displayed if it
-is not already."
-  (interactive)
-  (let* ((proc (or ess-local-process-name
-                   (ess-request-a-process "Evaluate into which process? " t)))
-         (ess-buf (ess-get-process-buffer proc)))
-    (setq ess-local-process-name proc)
-    (if (get-buffer-window ess-buf) nil
-      (display-buffer ess-buf t))
-    (let ((input (inferior-ess-get-old-input)))
-      (with-current-buffer ess-buf
-        (goto-char (point-max))
-        (ess-eval-linewise input)))))
-
-(defun ess-transcript-send-command-and-move ()
-  "Send the command on this line, and move point to the next command."
-  (interactive)
-  (let* ((proc (or ess-local-process-name
-                   (ess-request-a-process "Evaluate into which process? " t)))
-         (ess-buf (ess-get-process-buffer proc)))
-    (setq ess-local-process-name proc)
-    (if (get-buffer-window ess-buf) nil
-      (display-buffer ess-buf t))
-    (let ((input (inferior-ess-get-old-input)))
-      (with-current-buffer ess-buf
-        (goto-char (point-max))
-        (ess-eval-linewise input nil nil nil 1))))
-  (comint-next-prompt 1))
-
-(defun ess-transcript-copy-command ()
-  "Copy the command at point to the command line of the ESS process."
-  (interactive)
-  (let* ((proc (or ess-local-process-name
-                   (ess-request-a-process "Evaluate into which process? " t)))
-         (ess-buf (process-buffer (get-process proc)))
-         (input (inferior-ess-get-old-input)))
-    (setq ess-local-process-name proc)
-    (if (get-buffer-window ess-buf) nil
-      (display-buffer ess-buf t))
-    (with-current-buffer ess-buf
-      (goto-char (point-max))
-      (insert input)))
-  (ess-switch-to-end-of-ESS))
-
-(defun ess-transcript-clean-region (beg end even-if-read-only)
-  "Strip the transcript in the region, leaving only (R/S/Lsp/..) commands.
-Deletes any lines not beginning with a prompt, and then removes the
-prompt from those lines that remain.  Prefix argument means to
-clean even if the buffer is \\[read-only]."
-  (interactive "r\nP")
-  (unless inferior-ess-prompt
-    (error "Cannot clean ESS transcript region in this mode!
- That only works in ess-transcript-mode or inferior-ess-mode ('*R*' etc)."
-           ;; Maybe call ess-clean-region-in-new-transcript ?"))
-           ))
-  (let ((do-toggle (and buffer-read-only even-if-read-only))
-        (ess-prompt-rx (if inferior-ess-secondary-prompt
-                           (concat "^\\(\\("
-                                   inferior-ess-prompt
-                                   "\\)\\|\\("
-                                   inferior-ess-secondary-prompt
-                                   "\\)\\)")
-                         (concat "^" inferior-ess-prompt))))
-    (save-excursion
-      (if do-toggle (setq buffer-read-only nil))
-      (save-restriction
-        (deactivate-mark)
-        (narrow-to-region beg end)
-        (goto-char (point-min))
-        (delete-non-matching-lines ess-prompt-rx)
-        (goto-char (point-min))
-        ;; (replace-regexp  *  * ) :
-        (while (re-search-forward ess-prompt-rx nil t)
-          (replace-match "" nil nil)))
-
-      (if do-toggle (setq buffer-read-only t)))))
-
-(defun ess-transcript-DO-clean-region (beg end)
-  "Clean the current via \\[ess-transcript-clean-region] even if the buffer is read-only."
-  (interactive "r")
-  (ess-transcript-clean-region beg end 'In-ANY-case))
-
-(defun ess-transcript-clean-buffer ()
-  "Cleanup the whole buffer.
-Use point-min/max to obey `narrow-to-region'."
-  (interactive)
-  (ess-transcript-clean-region (point-min) (point-max) 'In-ANY-case))
-
-(provide 'ess-trns)
-
-;;; ess-trns.el ends here
diff --git a/elpa/ess-20251212.937/ess-utils.el b/elpa/ess-20251212.937/ess-utils.el
deleted file mode 100644 (file)
index 24cf280..0000000
+++ /dev/null
@@ -1,1144 +0,0 @@
-;;; ess-utils.el --- General Emacs utility functions used by ESS  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1998-2022 Free Software Foundation, Inc.
-;; Author: Martin Maechler <maechlerNOSPAMstat.math.ethz.ch>
-;; Created: 9 Sept 1998
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-;; Various utilities for ESS.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'comint)
-(require 'project)
-(eval-when-compile
-  (require 'tramp))
-;; The only ESS file this file should depend on is ess-custom.el
-(require 'ess-custom)
-
-(defvar ac-modes)
-(declare-function ess-eval-linewise "ess-inf" (text &optional invisibly eob even-empty wait-last-prompt sleep-sec wait-sec))
-(declare-function color-lighten-name "color" (name percent))
-(declare-function tramp-dissect-file-name "tramp" (name &optional nodefault))
-;; The following declares can be removed once we drop Emacs 25
-(declare-function tramp-file-name-method "tramp")
-(declare-function tramp-file-name-user "tramp")
-(declare-function tramp-file-name-host "tramp")
-(declare-function tramp-file-name-localname "tramp")
-(declare-function tramp-file-name-hop "tramp")
-
-\f
-;;*;; elisp tools
-
-(defun ess-next-code-line (&optional arg skip-to-eob)
-  "Move ARG lines of code forward (backward if ARG is negative).
-If `ess-eval-empty' is non-nil, skip past all empty and comment
-lines. ARG is 1 by default. If ARG is 0 only comments are skipped
-forward. Don't skip the last empty and comment lines in the
-buffer unless SKIP-TO-EOB is non-nil. On success, return 0.
-Otherwise go as far as possible and return -1."
-  (interactive "p")
-  (if (or ess-eval-empty
-          (and (fboundp 'ess-roxy-entry-p)
-               (ess-roxy-entry-p)))
-      (forward-line arg)
-    (setq arg (or arg 1))
-    (beginning-of-line)
-    (let ((pos (point))
-          (inc (if (>= arg 0) 1 -1))
-          (cnt (if (= arg 0) 1 arg))
-          (out 0))
-      ;; when orig-arg == 0, we skip only comments
-      (while (and (/= cnt 0) (= out 0))
-        (unless (= arg 0)
-          (setq out (forward-line inc)))     ; out==0 means success
-        (comment-beginning)
-        (beginning-of-line)
-        (forward-comment (* inc (buffer-size))) ;; as suggested in info file
-        (if (or skip-to-eob
-                (not (looking-at ess-no-skip-regexp))) ;; don't go to eob or whatever
-            (setq cnt (- cnt inc))
-          (goto-char pos)
-          (setq cnt 0)
-          (forward-line inc)) ;; stop at next empty line
-        (setq pos (point)))
-      (goto-char pos)
-      out)))
-
-(defun ess-goto-line (line)
-  "Go to LINE in the widened buffer."
-  (save-restriction
-    (widen)
-    (goto-char (point-min))
-    (forward-line (1- line))))
-
-(defun ess-skip-thing (thing)
-  "Leave point at the end of THING.
-THING can be \\='function, \\='paragraph, or \\='line."
-  (cond
-   ((eql thing 'line) (goto-char (line-end-position)))
-   ((eql thing 'paragraph) (forward-paragraph))
-   ((eql thing 'function) (end-of-defun) (skip-chars-backward " \t\n"))))
-
-(defun ess-search-except (regexp &optional except backward)
-  "Search for a REGEXP and store as match 1.
-Optionally ignore strings that match EXCEPT. If BACKWARD is
-non-nil, search backward."
-  (let ((continue t) (exit nil))
-    (while continue
-      (if (or (and backward (search-backward-regexp regexp nil t))
-              (and (not backward) (search-forward-regexp regexp nil t)))
-          (progn
-            (setq exit (match-string 1))
-            (setq continue (and except (string-match except exit)))
-            (if continue (setq exit nil)))
-        ;;else
-        (setq continue nil)))
-    exit))
-
-(defun ess-save-and-set-local-variables ()
-  "If buffer was modified, save file and set Local Variables if defined.
-Return t if buffer was modified, nil otherwise."
-  (let ((ess-temp-return-value (buffer-modified-p)))
-    (save-buffer)
-    (hack-local-variables)
-    ess-temp-return-value))
-
-(defun ess-get-file-or-buffer (file-or-buffer)
-  "Return FILE-OR-BUFFER if it is a buffer.
-Otherwise return the buffer associated with the file which must
-be qualified by it's path; if the buffer does not exist, return
-nil."
-  (declare (side-effect-free t)
-           (obsolete nil "ESS 19.04"))
-  (if (bufferp file-or-buffer)
-      file-or-buffer
-    (find-buffer-visiting file-or-buffer)))
-
-(defun ess-file-content (file)
-  "Return the content of FILE as string."
-  (if (file-exists-p file)
-      (with-temp-buffer
-        (insert-file-contents-literally file)
-        (buffer-string))
-    (error "File '%s' does not exist" file)))
-
-(defun ess-uniq (list predicate)
-  "Uniquify LIST, stably, deleting elements using PREDICATE.
-Return the list with subsequent duplicate items removed by side effects.
-PREDICATE is called with an element of LIST and a list of elements from LIST,
-and should return the list of elements with occurrences of the element removed.
-This function will work even if LIST is unsorted.  See also `delete-dups'."
-  (declare (obsolete 'delete-dups "ESS 19.04"))
-  (let ((list list))
-    (while list
-      (setq list (setcdr list (funcall predicate (car list) (cdr list))))))
-  list)
-
-(define-obsolete-function-alias 'ess-uniq-list #'delete-dups "ESS 19.04")
-
-(defalias 'ess-flatten-list
-  ;; `flatten-tree' is a function in Emacs 27
-  (if (fboundp 'flatten-tree)
-      'flatten-tree
-    (lambda (list)
-      "Take the arguments and flatten them into one long LIST.
-Drops `nil' entries."
-      ;; Taken from lpr.el
-      ;; `lpr-flatten-list' is defined here (copied from "message.el" and
-      ;; enhanced to handle dotted pairs as well) until we can get some
-      ;; sensible autoloads, or `flatten-list' gets put somewhere decent.
-      (ess-flatten-list-1 list))))
-
-(defun ess-flatten-list-1 (list)
-  "Internal helper for `ess-flatten-list', which see for LIST."
-  (cond
-   ((null list) (list))
-   ((consp list)
-    (append (ess-flatten-list-1 (car list))
-            (ess-flatten-list-1 (cdr list))))
-   (t (list list))))
-
-(define-obsolete-function-alias 'ess-delete-blank-lines
-  #'delete-blank-lines "ESS 19.04")
-
-(define-obsolete-function-alias 'ess-line-to-list-of-words #'split-string "ESS 19.04")
-
-(defmacro ess--exit-protect (body &rest exit)
-  "Run EXIT when BODY exits early.
-Unlike `unwind-protect', the unwind forms only run in case of
-early exits. Unlike `condition-case', they run inconditionally,
-no matter the reason for exiting early (e.g. error or quit)."
-  (declare
-   (indent 1)
-   (debug (form &rest form)))
-  `(let ((--early-exit t))
-     (unwind-protect
-         (prog1 ,body (setq --early-exit nil))
-       (when --early-exit
-         ,@exit))))
-
-\f
-;;*;; System
-
-(defun ess-revert-wisely ()
-  "Revert from disk if file and buffer last modification times are different."
-  (interactive)
-  ;; whether or not a revert is needed, force load local variables
-  ;; for example, suppose that you change the local variables and then
-  ;; save the file, a revert is unneeded, but a force load is
-  (hack-local-variables)
-  (unless (verify-visited-file-modtime (current-buffer))
-    (progn
-      (let ((ess-temp-store-point (point)))
-        (revert-buffer t t)
-        (goto-char ess-temp-store-point))
-      t)))
-
-(define-obsolete-function-alias 'ess-find-exec #'ess-find-exec-completions "ESS 19.04")
-(defun ess-find-exec-completions (root)
-  "Given the ROOT of an executable file name, find all possible completions.
-Search for the executables in the variable `exec-path'."
-  (let (executables)
-    (dolist (dir exec-path)
-      (when (and (> (length dir) 0)
-                 (file-accessible-directory-p dir))
-        ;; the first test above excludes "" from exec-path, which can be
-        ;; problematic with Tramp.
-        (dolist (f (file-name-all-completions root dir))
-          (setq f (expand-file-name f dir))
-          (when (and (file-executable-p f)
-                     (not (backup-file-name-p f))
-                     (not (file-directory-p f)))
-            (push f executables)))))
-    executables))
-
-(defun ess-drop-non-directories (file-strings)
-  "Drop all entries in FILE-STRINGS that do not \"look like\" directories."
-  (ess-flatten-list (mapcar #'file-name-directory file-strings)))
-
-(defun ess--parent-dir (path n)
-  "Return Nth parent of PATH."
-  (let ((opath path))
-    (while (and path (> n 0))
-      (setq path (file-name-directory (directory-file-name opath)))
-      (if (equal path opath)
-          (setq path nil)
-        (setq opath path
-              n (1- n))))
-    path))
-
-\f
-;;*;; Interaction with inferiors
-
-(defmacro ess-when-new-input (time-var &rest body)
-  "BODY is evaluate only if the value of process variable TIME-VAR
-is bigger than the time of the last user input (stored in
-`last-eval' process variable). TIME-VAR is the name of the
-process variable which holds the access time. See the code for
-`ess-synchronize-dirs' and `ess-cache-search-list'.
-
-Returns nil when no current process, or process is busy, or
-time-var > last-eval. Otherwise, execute BODY and return the last
-value.
-
-If BODY is executed, set process variable TIME-VAR
-to (current-time).
-
-Variable  *proc*  is bound  to  the  current process  during  the
-evaluation of BODY.
-
-Should be used in `ess-idle-timer-functions' which call the
-process to avoid excessive requests."
-  (declare (indent 1) (debug t))
-  `(with-ess-process-buffer 'no-error
-     (let ((le (process-get *proc* 'last-eval))
-           (tv (process-get *proc* ',time-var)))
-       (when (and (or (null tv) (null le) (time-less-p tv le))
-                  (not (process-get *proc* 'busy)))
-         (let ((out (progn ,@body)))
-           (process-put *proc* ',time-var (current-time))
-           out)))))
-
-(defmacro with-ess-process-buffer (no-error &rest body)
-  "Execute BODY in the process buffer of `ess-current-process-name'.
-If NO-ERROR is t don't trigger error when there is not current
-process. Symbol *proc* is bound to the current process during the
-evaluation of BODY."
-  (declare (indent 1) (debug t))
-  `(let ((*proc* (and ess-local-process-name (get-process ess-local-process-name))))
-     (if *proc*
-         (with-current-buffer (process-buffer *proc*)
-           ,@body)
-       (unless ,no-error
-         (error "No current ESS process")))))
-
-\f
-;;*;; Emacs Integration
-
-(defun ess-derived-mode-p ()
-  "Non-nil if the current major mode is an ESS major mode."
-  (or (derived-mode-p 'ess-mode)
-      (derived-mode-p 'ess-julia-mode)))
-
-(defun ess--generate-eval-visibly-submenu (_menu)
-  '(["yes" (lambda () (interactive) (setq ess-eval-visibly t))
-     :style radio :enable t :selected (eq ess-eval-visibly t)]
-    ["nowait" (lambda () (interactive) (setq ess-eval-visibly 'nowait))
-     :style radio :enable t :selected (eq ess-eval-visibly 'nowait) ]
-    ["no" (lambda () (interactive) (setq ess-eval-visibly nil))
-     :style radio :enable t :selected (eq ess-eval-visibly nil) ]))
-
-;; Font Lock
-
-(defun ess--fl-keywords-values ()
-  "Return a cons (STANDARD-VALUE . CUSTOM-VALUE) of `ess-font-lock-keywords'."
-  (let ((sym ess-font-lock-keywords))
-    (if (and (symbolp sym)
-             (custom-variable-p sym))
-        (cons
-         (eval (car (get sym 'standard-value)) t)
-         (symbol-value sym))
-      (error "`ess-font-lock-keywords' must be a symbol of a custom variable"))))
-
-(defun ess--extract-fl-keywords ()
-  (let ((values (ess--fl-keywords-values)))
-    (mapcar (lambda (kv)
-              (let ((cust-kv (assoc (car kv) (cdr values))))
-                (when cust-kv
-                  (setcdr kv (cdr cust-kv))))
-              kv)
-            (copy-alist (car values)))))
-
-(defun ess-build-font-lock-keywords ()
-  "Retrieve `font-lock-keywords' from ess-[dialect]-font-lock-keywords.
-Merge the customized values of that variable on top of the
-standard values and return the new list. For this to work,
-`ess-font-lock-keywords' should be a name of the
-ess-[dialect]-font-lock-keywords variable."
-  (delq nil
-        (mapcar (lambda (c)
-                  (when (cdr c)
-                    (symbol-value (car c))))
-                (ess--extract-fl-keywords))))
-
-(defun ess-font-lock-toggle-keyword (keyword)
-  "Toggle KEYWORD font-lock."
-  (interactive
-   (list (intern (ess-completing-read
-                  "Keyword to toggle"
-                  (mapcar (lambda (el) (symbol-name (car el)))
-                          (car (ess--fl-keywords-values)))
-                  nil t))))
-  (let* ((values (ess--fl-keywords-values))
-         (kwd (cond
-               ;; already in custom values
-               ((assoc keyword (cdr values)))
-               ;; if keyword is not already in custom values (can happen if
-               ;; we add new keywords but the user has the old value saved in
-               ;; .emacs-custom.el)
-               ((let ((kwd (assoc keyword (car values)))
-                      (sym ess-font-lock-keywords))
-                  (when kwd
-                    (set sym (cons kwd (symbol-value sym)))
-                    kwd)))
-               (t (error "Invalid keyword %s" keyword)))))
-    (setcdr kwd (not (cdr kwd)))
-    (let ((mode major-mode)
-          (dialect ess-dialect))
-      ;; refresh font-lock defaults in all relevant buffers
-      (mapc (lambda (b)
-              (with-current-buffer b
-                (when (and (eq major-mode mode)
-                           (eq ess-dialect dialect))
-                  (font-lock-refresh-defaults))))
-            (buffer-list)))))
-
-(defun ess--generate-font-lock-submenu (_menu)
-  "Generate ESS font-lock submenu."
-  (append (mapcar (lambda (el)
-                    `[,(symbol-name (car el))
-                      (lambda () (interactive)
-                        (ess-font-lock-toggle-keyword ',(car el)))
-                      :style toggle
-                      :enable t
-                      :selected ,(cdr el)])
-                  (ess--extract-fl-keywords))
-          (list "-----"
-                ["Save to custom"
-                 (lambda () (interactive)
-                   (customize-save-variable ess-font-lock-keywords
-                                            (ess--extract-fl-keywords)))
-                 t])))
-
-(declare-function untrace-function "trace" ())
-(defvar ess--is-tracing nil)
-
-;;;###autoload
-(define-minor-mode ess-elisp-trace-mode
-  "Toggle tracing of ess-prefixed functions.
-Tracing is useful for debugging background ESS behaviour. When
-enabled, all functions prefixed in `ess-' and `inferior-ess' are
-instrumented with `trace-function'. Tracing is turned off by
-calling `untrace-function' on these functions."
-  :global t
-  :group 'ess
-  (let ((fns (append (all-completions "ess-" obarray)
-                     (all-completions "inferior-ess-" obarray)
-                     (list "update-ess-process-name-list"
-                           "forward-ess-r-expr"
-                           "forward-ess-r-sexp"
-                           "backward-ess-r-expr"
-                           "backward-ess-r-sexp"
-                           "company-ess-julia-objects"
-                           "run-ess-r"
-                           "run-ess-r-newest")))
-        (do (symbol-function (if ess-elisp-trace-mode
-                                 #'untrace-function
-                               #'trace-function))))
-    (dolist (fn fns)
-      (when (symbol-function (intern fn))
-        (funcall do (intern fn))))))
-
-\f
-;;*;; External modes
-
-;; Define these here for the byte compiler since ido dynamically
-;; let-binds them:
-(defvar ido-choice-list)
-(defvar ido-context-switch-command)
-(defvar ido-directory-too-big)
-(defvar ido-directory-nonreadable)
-(defvar ido-current-directory)
-(defvar ido-enable-flex-matching)
-(declare-function ido-choose-completion-string "ido")
-(declare-function ido-minibuffer-setup "ido")
-(declare-function ido-read-internal "ido" (item prompt hist &optional default require-match initial))
-
-(defun ess-completing-read (prompt collection &optional predicate
-                                   require-match initial-input hist def)
-  "Read a string in the minibuffer, with completion.
-Use `ido-completing-read' if IDO interface is present, or fall
-back on classical `completing-read' otherwise. Meaning of PROMPT,
-COLLECTION, PREDICATE, REQUIRE-MATCH, INITIAL-INPUT, HIST, and
-DEF is as in `completing-read'. PROMPT is automatically suffixed
-with ': ' and (default %s) when needed. If HIST is nil use
-`ess--completing-hist' as history. See also `ess-use-ido'."
-  (let ((use-ido (and ess-use-ido (require 'ido nil t))))
-    (setq hist (or hist 'ess--completing-hist))
-    (when (and def (not use-ido)) ;; ido places in front and highlights the default
-      (setq prompt (format "%s(default %s)" prompt def)))
-    (setq prompt (concat prompt ": "))
-    (if use-ido
-        (let ((reset-ido (and use-ido (not ido-mode))) ;people not using ido but having it)
-              (ido-current-directory nil)
-              (ido-directory-nonreadable nil)
-              (ido-directory-too-big nil)
-              (ido-context-switch-command 'ignore)
-              (ido-enable-flex-matching ess-ido-flex-matching) ;it's fast and useful, may be get into options
-              (ido-choice-list (copy-sequence collection)) ;ido removes the match (reported)
-              sel)
-          (unwind-protect
-              (progn
-                (add-hook 'minibuffer-setup-hook #'ido-minibuffer-setup)
-                (add-hook 'choose-completion-string-functions #'ido-choose-completion-string)
-                (setq sel (ido-read-internal 'list prompt hist def require-match initial-input))
-                (when hist  ;; ido does not push into hist the whole match if C-SPC or RET is used (reported)
-                  (unless (string= sel (car (symbol-value hist)))
-                    (set hist (cons sel  (symbol-value hist))))))
-            (when reset-ido
-              (remove-hook 'minibuffer-setup-hook #'ido-minibuffer-setup)
-              (remove-hook 'choose-completion-string-functions #'ido-choose-completion-string)))
-          sel)
-      ;; else usual completion
-      (completing-read prompt collection predicate require-match initial-input hist def))))
-
-(defun ess--setup-auto-complete (sources &optional inferior)
-  "Setup auto-complete depending on user settings.
-SOURCES gets added to `ac-sources', INFERIOR should be t for
-inferior buffers."
-  ;; auto-complete
-  (when (and (boundp 'ac-sources)
-             (if inferior
-                 (eq ess-use-auto-complete t)
-               ess-use-auto-complete))
-    (add-to-list 'ac-modes major-mode)
-    ;; files should be in front; ugly, but needed
-    (setq ac-sources
-          (delq 'ac-source-filename ac-sources))
-    (mapc (lambda (el) (add-to-list 'ac-sources el))
-          sources)
-    (add-to-list 'ac-sources 'ac-source-filename)))
-
-(defun ess--setup-company (sources &optional inferior)
-  "Setup company depending on user settings.
-SOURCES gets added to `company-backends', and when t, INFERIOR
-specifies inferior buffers."
-  ;; company
-  (when (and (boundp 'company-backends)
-             (if inferior
-                 (eq ess-use-company t)
-               ess-use-company))
-    (setq-local company-backends
-                (cl-copy-list (append sources company-backends)))
-    (delq 'company-capf company-backends)))
-
-(defun ess--setup-eldoc (fun)
-  "Setup support for eldoc.
-FUN is the function to return data for eldoc."
-  (when ess-use-eldoc
-    (if (not (boundp 'eldoc-documentation-functions))
-        ;; older versions of Eldoc included in Emacs 27 and previous
-        (add-function :before-until (local 'eldoc-documentation-function)
-                      fun)
-      ;; new eldoc, in Emacs 28+
-      (add-hook 'eldoc-documentation-functions fun nil t)
-      ;; Eldoc is on GNU ELPA so you can have new eldoc + Emacs 27.1
-      ;; or older, see bug#1130 and Emacs bug # 47388 for why we have
-      ;; to do this
-      (when (and (fboundp 'eldoc-documentation-default)
-                 (function-equal #'ignore eldoc-documentation-function))
-        (setq-local eldoc-documentation-function #'eldoc-documentation-default)))))
-
-(defmacro ess--execute-electric-command (map &optional prompt wait exit-form &rest args)
-  "Execute keys defined in MAP till a key is pressed which is not in MAP.
-Single-key input commands are those that once executed do not
-require the prefix command for subsequent invocation. Return the
-value of the lastly executed command. PROMPT is passed to
-`read-event'.
-
-If WAIT is t, wait for next input and ignore the keystroke which
-triggered the command.
-
-Each command in map should accept one at least one argument, the
-most recent event (as read by `read-event'). ARGS are the
-supplementary arguments passed to the commands.
-
-EXIT-FORM should be supplied for a more refined control of the
-read-even loop. The loop is exited when EXIT-FORM evaluates to
-t. See examples in the tracebug code."
-  ;;VS[09-06-2013]: check: it seems that set-temporary-overlay-map is designed
-  ;;for this type of things; see also repeat.el package.
-  `(let* ((ev last-command-event)
-          (command (lookup-key ,map (vector ev)))
-          out exit )
-     (if (not (or ,wait command))
-         (message "%s is undefined" (key-description (this-command-keys)))
-       (unless ,wait
-         (setq out (and command (funcall command ev ,@args))))
-       (while (and (not exit)
-                   (setq command
-                         (lookup-key ,map
-                                     (vector (setq ev (read-event ,prompt))))))
-         (setq out (funcall command ev ,@args))
-         (sleep-for .01)
-         (setq exit ,exit-form))
-       (unless exit ;; push only if an event triggered the exit
-         (push ev unread-command-events))
-       out)))
-
-(cl-defgeneric ess-build-tags-command ()
-  "Command passed to generate tags.
-If nil, `ess-build-tags-for-directory' uses the mode's imenu
-expression. Otherwise, it should be a string with two %s
-formats: one for directory and another for the output file."
-  nil)
-
-\f
-;;*;; Emacs itself
-
-(defun ess-yank-cleaned-commands ()
-  "Yank and strip the code, leaving only (R/S/Lsp/..) commands.
-Deletes any lines not beginning with a prompt, and then removes
-the prompt from those lines that remain. Invoke this command with
-\\[universal-argument] \\[universal-argument] \\<ess-mode-map>\\[yank]."
-  (setq yank-window-start (window-start))
-  (let ((beg (point)))
-    (push-mark beg)
-    (setq this-command t)
-    (insert-for-yank (current-kill 0))
-    (when (and (require 'ess-trns) (fboundp 'ess-transcript-clean-region))
-      (ess-transcript-clean-region beg (point) nil))
-    (if (eq (point) beg)
-        (message "No commands found"))
-    (if (eq this-command t)
-        (setq this-command 'yank))))
-
-(defun ess-yank (&optional arg)
-  "Variant of `yank' that optionally extracts commands from transcripts.
-When called with double prefix ARG (\\[universal-argument]
-\\[universal-argument]), calls `ess-transcript-clean-region'
-before yanking. See `ess-yank-cleaned-commands'."
-  (interactive "*P")
-  (if (equal '(16) arg)
-      (ess-yank-cleaned-commands)
-    (let* ((remapped (command-remapping 'yank (point)))
-           (command (cond ((eq remapped 'ess-yank) 'yank)
-                          ((null remapped) 'yank)
-                          (t remapped))))
-      (funcall command arg))))
-
-(put 'ess-yank 'delete-selection 'yank)
-
-(defun ess-build-tags-for-directory (dir tagfile)
-  "Ask for directory and tag file and build tags for current dialect.
-If the current language defines `ess-build-tags-command' use it
-and ask the subprocess to build the tags. Otherwise use imenu
-regexp and call find .. | etags .. in a shell command. You must
-have `find' and `etags' programs installed.
-
-Use M-. to navigate to a tag. \\[visit-tags-table] to
-append/replace the currently used tag table.
-
-If prefix is given, force tag generation based on imenu. Might be
-useful when different language files are also present in the
-directory (.cpp, .c etc)."
-  (interactive "DDirectory to tag:
-GTags file (default TAGS): ")
-  (when (or (eq (length (file-name-nondirectory tagfile)) 0)
-            (file-directory-p tagfile))
-    (setq tagfile (concat (file-name-as-directory tagfile) "TAGS")))
-  ;; Emacs find-tags doesn't play well with remote TAG files :(
-  (when (file-remote-p tagfile)
-    (require 'tramp)
-    (setq tagfile (with-parsed-tramp-file-name tagfile foo foo-localname)))
-  (when (file-remote-p dir)
-    (require 'tramp)
-    (setq dir (with-parsed-tramp-file-name dir foo foo-localname)))
-  (if (and (ess-build-tags-command) (null current-prefix-arg))
-      (ess-eval-linewise (format (ess-build-tags-command) dir tagfile))
-    ;; else generate from imenu
-    (unless imenu-generic-expression
-      (error "No ess-tag-command found, and no imenu-generic-expression defined"))
-    (let* ((find-cmd
-            (format "find %s -type f -size 1M \\( -regex \".*\\.\\(cpp\\|jl\\|[RsrSch]\\(nw\\)?\\)$\" \\)" dir))
-           (regs (delq nil (mapcar (lambda (l)
-                                     (if (string-match "'" (cadr l))
-                                         nil ;; remove for time being
-                                       (format "/%s/\\%d/"
-                                               (replace-regexp-in-string "/" "\\/" (nth 1 l) t)
-                                               (nth 2 l))))
-                                   imenu-generic-expression)))
-           (tags-cmd (format "etags -o %s --regex='%s' -" tagfile
-                             (mapconcat #'identity regs "' --regex='"))))
-      (message "Building tags: %s" tagfile)
-      (when (= 0 (shell-command (format "%s | %s" find-cmd tags-cmd)))
-        (message "Building tags .. ok!")))))
-
-\f
-;;*;; UI
-
-(defvar ess-current-region-overlay
-  (let ((overlay (make-overlay (point) (point))))
-    (overlay-put overlay 'face  'highlight)
-    overlay)
-  "The overlay for highlighting currently evaluated region or line.")
-
-(defun ess-blink-region (start end)
-  "Blink from START to END depending on option `ess-blink-region'."
-  (when ess-blink-region
-    (move-overlay ess-current-region-overlay start end)
-    (run-with-timer ess-blink-delay nil
-                    (lambda ()
-                      (delete-overlay ess-current-region-overlay)))))
-
-(defun ess-deactivate-mark ()
-  "Deactivate the mark, if active.
-If `evil-mode' is on, switch to `evil-normal-state'."
-  (if (and (bound-and-true-p evil-mode)
-           (fboundp 'evil-visual-state-p)
-           (evil-visual-state-p))
-      (when (fboundp 'evil-normal-state)
-        (evil-normal-state))
-    (when mark-active
-      (deactivate-mark))))
-
-;; SJE: 2009-01-30 -- this contribution from
-;; Erik Iverson <iversonNOSPAMbiostat.wisc.edu>
-
-(defun ess-tooltip-show-at-point (text xo yo)
-  "Show a tooltip displaying TEXT at (around) point.
-XO and YO are x- and y-offsets for the toolbar from point."
-  (let (
-        (fx (frame-parameter nil 'left))
-        (fy (frame-parameter nil 'top))
-        (fw (frame-pixel-width))
-        (fh (frame-pixel-height))
-        frame-left frame-top my-x-offset my-y-offset)
-    ;; The following comment was found before code looking much like that
-    ;; of frame-left and frame-top below in the file
-    ;; tooltip-help.el. I include it here for acknowledgment, and I did observe
-    ;; the same behavior with the Emacs window maximized under Windows XP.
-
-    ;; -----original comment--------
-    ;; handles the case where (frame-parameter nil 'top) or
-    ;; (frame-parameter nil 'left) return something like (+ -4).
-    ;; This was the case where e.g. Emacs window is maximized, at
-    ;; least on Windows XP. The handling code is "shamelessly
-    ;; stolen" from cedet/speedbar/dframe.el
-    ;; (contributed by Andrey Grigoriev)
-    (setq frame-left (if (not (consp fx))
-                         fx
-                       (if (eq (car fx) '-)
-                           (- (display-pixel-width) (car (cdr fx)) fw)
-                         (car (cdr fx)))))
-    (setq frame-top (if (not (consp fy))
-                        fy
-                      (if (eq (car fy) '-)
-                          (- (display-pixel-height) (car (cdr fy)) fh)
-                        (car (cdr fy)))))
-    ;; calculate the offset from point, use xo and yo to adjust to preference
-    (setq my-x-offset (+ (car(window-inside-pixel-edges))
-                         (car(posn-x-y (posn-at-point)))
-                         frame-left xo))
-    (setq my-y-offset (+ (cadr(window-inside-pixel-edges))
-                         (cdr(posn-x-y (posn-at-point)))
-                         frame-top yo))
-    (let ((tooltip-frame-parameters
-           (cons (cons 'top my-y-offset)
-                 (cons (cons 'left my-x-offset)
-                       tooltip-frame-parameters))))
-      (tooltip-show text))))
-
-(defun ess-select-frame-set-input-focus (frame)
-  "Select FRAME, raise it, and set input focus, if possible.
-Copied almost verbatim from gnus-utils.el (but with test for mac added)."
-  ;; The function `select-frame-set-input-focus' won't set
-  ;; the input focus under Emacs 21.2 and X window system.
-  ;;((fboundp 'select-frame-set-input-focus)
-  ;; (defalias 'gnus-select-frame-set-input-focus
-  ;;   'select-frame-set-input-focus)
-  ;; (select-frame-set-input-focus frame))
-  (raise-frame frame)
-  (select-frame frame)
-  (cond ((and
-          (memq window-system '(x mac))
-          (fboundp 'x-focus-frame))
-         (x-focus-frame frame))
-        ((and (eq window-system 'w32)
-              ;; silence byte compiler warnings about w32-fns
-              (fboundp 'w32-focus-frame))
-         (w32-focus-frame frame)))
-  (when focus-follows-mouse
-    (set-mouse-position frame (1- (frame-width frame)) 0)))
-
-(define-obsolete-function-alias 'ess-do-auto-fill #'do-auto-fill "ESS 19.04")
-
-\f
-;;*;; Syntax
-
-(defun ess-containing-sexp-position ()
-  "Return the `cadr' of `syntax-ppss'."
-  (cadr (syntax-ppss)))
-
-(defun ess-code-end-position ()
-  "Like (line-end-position) but stops at comments."
-  (save-excursion
-    (goto-char (1+ (line-end-position)))
-    (forward-comment -1)
-    (point)))
-
-;; FIXME: The following function pattern stuff is specific to R but is
-;; used throughout ESS
-(defvar ess-r-set-function-start
-  ;; [MGAR].. <=>  {setMethod(), set[Group]Generic(), setAs(), setReplaceMethod()}
-  ;; see also set-S4-exp in ess-r-function-pattern below
-  "^set[MGAR][GMa-z]+\\s-?(")
-
-(defvar ess-function-pattern nil ; in R set to ess-r-function-pattern
-  "Regexp to match the beginning of a function in S buffers.")
-
-(defvar ess-r-symbol-pattern
-  "\\(\\sw\\|\\s_\\)"
-  "The regular expression for matching an R symbol.")
-
-(defvar ess-r-name-pattern
-  (concat "\\(" ess-r-symbol-pattern "+\\|\\(`\\).+`\\)")
-  "The regular expression for matching a R name.")
-
-(defvar ess--r-s-function-pattern
-  (let* ((Q     "\\s\"")                    ; quote
-         (Sym-0 "\\(\\sw\\|\\s_\\)")        ; symbol
-         (Symb (concat Sym-0 "+"))
-         (xSymb "[^ \t\n\"']+") ;; (concat "\\[?\\[?" Sym-0 "*")); symbol / [ / [[ / [symbol / [[symbol
-         ;; FIXME: allow '%foo%' but only when quoted; don't allow [_0-9] at beg.
-         (space "\\(\\s-\\|\n\\)*")         ; white space
-
-         (S7-method (concat "method(" Symb "," space
-                            "\\(list(\\(" Symb ",?" space "\\)+)\\|" Symb
-                            "\\))"))
-
-         (part-1 (concat
-                  "\\(" ;;--------outer Either-------
-                  "\\(\\("          ; EITHER
-                  Q xSymb Q         ; any function name between quotes
-                  "\\)\\|\\("
-                  Symb ; (beginning of name) + ess-r-symbol-pattern
-                  "\\)\\|\\("       ; Add S7 method as a valid function name
-                  S7-method
-                  "\\)\\)"))        ; END EITHER OR
-
-         (set-S4-exp
-          (concat
-           "^set\\(As\\|Method\\|Generic\\|GroupGeneric\\|ReplaceMethod\\)(" ; S4 ...
-           Q xSymb Q "," space
-           ;; and now often `` signature(......), : ''
-           ".*" ;; <<< FIXME ???
-           ))
-
-         (part-2 (concat
-                  "\\|" ;;--------outer Or ---------
-                  set-S4-exp
-                  "\\)" ;;--------end outer Either/Or-------
-
-                  "\\(" space "\\s<.*\\s>\\)*"      ; whitespace, comment
-                  ;; FIXME: in principle we should skip 'definition *= *' here
-                  space "\\(function\\|\\\\\\)\\s-*(" ; whitespace, function keyword, parenthesis
-                  )))
-    `(,part-1 ,part-2))
-  "Partial regex for matching functions.
-
-Placeholder for use in constructing `ess-r-function-pattern' and
-`ess-s-function-pattern'.")
-
-(defvar ess-r-function-pattern
-  (concat (car ess--r-s-function-pattern)
-          "\\s-*\\(<-\\|=\\)" ; whitespace, assign
-          (nth 1 ess--r-s-function-pattern))
-  "The regular expression for matching the beginning of an R function.")
-
-(defvar ess-s-function-pattern
-  (concat (car ess--r-s-function-pattern)
-          "\\s-*\\(<-\\|_\\|=\\)" ; whitespace, assign (incl. "_")
-          (nth 1 ess--r-s-function-pattern))
-  "The regular expression for matching the beginning of an S function.")
-
-(defvar ess--fn-name-start-cache nil)
-
-(defun ess--fn-name-start ()
-  "Return (FN-NAME . START-POS).
-FN-NAME is a function name located before the pointer. START-POS
-is the position where FN-NAME starts. Store this cons in variable
-`ess--fn-name-start-cache'."
-  (save-excursion
-    (save-restriction
-      (let* ((proc (get-buffer-process (current-buffer)))
-             (mark (and proc (process-mark proc))))
-        (if (and mark (>= (point) mark))
-            (narrow-to-region mark (point)))
-        (and (fboundp 'ess-noweb-narrow-to-chunk)
-             (bound-and-true-p ess-noweb-mode)
-             (ess-noweb-narrow-to-chunk))
-        (unless (ess-inside-string-p)
-          (setq ess--fn-name-start-cache
-                (condition-case nil ;; check if it is inside a function
-                    (progn
-                      ;; for the sake of big buffers, look only 1000 chars back
-                      (narrow-to-region (max (point-min) (- (point) 1000)) (point))
-                      (up-list -1)
-                      (while (not (looking-at "("))
-                        (up-list -1))
-                      (let ((funname (symbol-name (ess-symbol-at-point))))
-                        (when (and funname
-                                   (not (member funname ess-S-non-functions)))
-                          (cons funname (- (point) (length funname))))))
-                  (error nil))))))))
-
-(defun ess-symbol-at-point ()
-  "Like `symbol-at-point' but consider fully qualified names.
-Fully qualified names include accessor symbols (like aaa$bbb and
-aaa@bbb in R)."
-  (with-syntax-table (or ess-mode-completion-syntax-table
-                         (syntax-table))
-    (symbol-at-point)))
-
-(defun ess-bounds-of-symbol ()
-  "Get bounds of symbol at point.
-Intended for completion."
-  (let ((bounds (with-syntax-table (or ess-mode-completion-syntax-table
-                                       (syntax-table))
-                  (bounds-of-thing-at-point 'symbol))))
-    (and bounds
-         (not (save-excursion
-                (goto-char (car bounds))
-                (looking-at "/\\|[.0-9]")))
-         bounds)))
-
-(defun ess-symbol-start ()
-  "Get initial position for objects completion.
-Symbols are fully qualified names that include accessor
-symbols (like aaa$bbb and aaa@bbb in R)."
-  (car (ess-bounds-of-symbol)))
-
-(defun ess-arg-start ()
-  "Get initial position for args completion."
-  (when (not (ess-inside-string-p))
-    (when (ess--fn-name-start)
-      (if (looking-back "[(,]+[ \t\n]*" nil)
-          (point)
-        (ess-symbol-start)))))
-
-(defun ess-inside-string-p (&optional pos)
-  "Return non-nil if POS is inside string.
-POS defaults to `point'."
-  (let ((pos (or pos (point))))
-    (nth 3 (syntax-ppss pos))))
-
-(defun ess-inside-comment-p (&optional pos)
-  "Return non-nil if POS is inside string.
-POS defaults to `point'."
-  (let ((pos (or pos (point))))
-    (nth 4 (syntax-ppss pos))))
-
-(defun ess-inside-string-or-comment-p (&optional pos)
-  "Return non-nil if POS is inside a string or comment.
-POS defaults to `point'."
-  (or (ess-inside-string-p pos)
-      (ess-inside-comment-p pos)))
-
-(defun ess-inside-brackets-p (&optional pos curly?)
-  "Return t if position POS is inside brackets.
-POS defaults to point if no value is given. If CURLY?? is non nil
-also return t if inside curly brackets."
-  (save-excursion
-    (let ((ppss (syntax-ppss pos))
-          (r nil))
-      (while (and (> (nth 0 ppss) 0)
-                  (not r))
-        (goto-char (nth 1 ppss))
-        (when (or (char-equal ?\[ (char-after))
-                  (and curly?
-                       (char-equal ?\{ (char-after))))
-          (setq r t))
-        (setq ppss (syntax-ppss)))
-      r)))
-
-\f
-;;*;; String manipulation
-
-(defun ess-quote-special-chars (string)
-  "Quote special characters in STRING."
-  (replace-regexp-in-string
-   "\"" "\\\\\\&"
-   (replace-regexp-in-string ;; replace backslashes
-    "\\\\" "\\\\" string nil t)))
-
-(defun ess-rep-regexp (regexp to-string &optional fixedcase literal verbose)
-  "Instead of (replace-regexp..) -- do NOT replace in strings or comments.
-If FIXEDCASE is non-nil, do *not* alter case of replacement text.
-If LITERAL   is non-nil, do *not* treat `\\' as special.
-If VERBOSE   is non-nil, (message ..) about replacements."
-  (let ((case-fold-search (and case-fold-search
-                               (not fixedcase))); t  <==> ignore case in search
-        (ppt (point)); previous point
-        (p))
-    (while (and (setq p (re-search-forward regexp nil t))
-                (< ppt p))
-      (setq ppt p)
-      (cond ((not (ess-inside-string-or-comment-p (1- p)))
-             (if verbose
-                 (let ((beg (match-beginning 0)))
-                   (message "buffer in (match-beg.,p)=(%d,%d) is '%s'"
-                            beg p (buffer-substring beg p))))
-             (replace-match to-string fixedcase literal))))))
-
-(defun ess-replace-regexp-dump-to-src (regexp to-string &optional dont-query verbose)
-  "Replace REGEXP matches from beginning of buffer with TO-STRING.
-If DONT-QUERY is non-nil, call `ess-rep-regexp' else call
-`query-replace-regexp'. VERBOSE can be passed to `ess-rep-regexp'."
-  (save-excursion
-    (goto-char (point-min))
-    (if dont-query
-        (ess-rep-regexp     regexp to-string nil nil verbose)
-      (query-replace-regexp regexp to-string nil))))
-
-(defun ess-space-around (word &optional from verbose)
-  "Replace-regexp .. ensuring space around all occurrences of WORD.
-Start at from FROM, which defaults to point."
-  (interactive "d\nP"); Defaults: point and prefix (C-u)
-  (save-excursion
-    (goto-char from)
-    (ess-rep-regexp (concat "\\([^ \t\n]\\)\\(\\<" word "\\>\\)")
-                    "\\1 \\2" nil nil verbose)
-    (goto-char from)
-    (ess-rep-regexp (concat "\\(\\<" word "\\>\\)\\([^ \t\n]\\)")
-                    "\\1 \\2" nil nil verbose)))
-
-(defun ess-time-string (&optional clock)
-  "Return a string for use as a timestamp, like \"13 Mar 1992\".
-Include hr:min if CLOCK is non-nil. Redefine to taste."
-  (declare (obsolete format-time-string "ESS 19.04"))
-  (format-time-string (concat "%e %b %Y" (if clock ", %H:%M"))))
-
-(defun ess-replace-in-string (str regexp newtext &optional literal)
-  "Replace all matches in STR for REGEXP with NEWTEXT string.
-Optional LITERAL non-nil means do a literal replacement.
-Otherwise treat \\ in NEWTEXT string as special:
-  \\& means substitute original matched text,
-  \\N means substitute match for \(...\) number N,
-  \\\\ means insert one \\."
-  (if (not (stringp str))
-      (error "(replace-in-string): First argument must be a string: %s" str))
-  (if (stringp newtext)
-      nil
-    (error "(replace-in-string): 3rd arg must be a string: %s"
-           newtext))
-  (let ((rtn-str "")
-        (start 0)
-        (special)
-        match prev-start)
-    (while (setq match (string-match regexp str start))
-      (setq prev-start start
-            start (match-end 0)
-            rtn-str
-            (concat
-             rtn-str
-             (substring str prev-start match)
-             (cond (literal newtext)
-                   (t (mapconcat
-                       (function
-                        (lambda (c)
-                          (if special
-                              (progn
-                                (setq special nil)
-                                (cond ((eq c ?\\) "\\")
-                                      ((eq c ?&)
-                                       (substring str
-                                                  (match-beginning 0)
-                                                  (match-end 0)))
-                                      ((and (>= c ?0) (<= c ?9))
-                                       (if (> c (+ ?0 (length
-                                                       (match-data))))
-                                           ;; Invalid match num
-                                           (error "(replace-in-string) Invalid match num: %c" c)
-                                         (setq c (- c ?0))
-                                         (substring str
-                                                    (match-beginning c)
-                                                    (match-end c))))
-                                      (t (char-to-string c))))
-                            (if (eq c ?\\) (progn (setq special t) nil)
-                              (char-to-string c)))))
-                       newtext ""))))))
-    (concat rtn-str (substring str start))))
-
-(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
-binary files!")
-
-;;; MM: Newer Emacsen now have  delete-trailing-whitespace
-;;; --  but no customization like  nuke-trailing-whitespace-p ..
-(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
-`ess-nuke-trailing-whitespace-p' is nil, this function is
-disabled. If t, unreservedly strip trailing whitespace. If not
-nil and not t, query for each instance."
-  (interactive)
-  (let ((bname (buffer-name)))
-    (cond ((or
-            (string= major-mode "rmail-mode")
-            (string= bname "RMAIL")
-            nil)); do nothing..
-          (t
-           (and (not buffer-read-only)
-                ess-nuke-trailing-whitespace-p
-                (save-match-data
-                  (save-excursion
-                    (save-restriction
-                      (widen)
-                      (goto-char (point-min))
-                      (cond ((eq ess-nuke-trailing-whitespace-p t)
-                             (while (re-search-forward "[ \t]+$" (point-max) t)
-                               (delete-region (match-beginning 0)
-                                              (match-end 0))))
-                            (t
-                             (query-replace-regexp "[ \t]+$" "")))))))))
-    ;; always return nil, in case this is on write-file-hooks.
-    nil))
-
-(defun ess--strip-final-newlines (string)
-  (replace-regexp-in-string "\n+$" "" string))
-
-\f
-;;*;; Debugging tools
-
-(defun ess-write-to-dribble-buffer (text)
-  "Write TEXT to `ess-dribble-buffer'."
-  (when (or ess-verbose ess-write-to-dribble)
-    (with-current-buffer (get-buffer-create ess-dribble-buffer)
-      (goto-char (point-max))
-      (insert-before-markers text))))
-
-(defun ess-if-verbose-write (text)
-  "Write TEXT to `ess-dribble-buffer' only if `ess-verbose' is non-nil."
-  (when ess-verbose (ess-write-to-dribble-buffer text)))
-
-(defun ess-kill-last-line ()
-  (save-excursion
-    (goto-char (point-max))
-    (forward-line -1)
-    (delete-region (line-end-position) (point-max))))
-
-(defun ess-sleep ()
-  "Put Emacs to sleep for `ess-sleep-for-shell' seconds (floats work)."
-  (sleep-for ess-sleep-for-shell))
-
-(defun ess-setq-vars-local (alist &optional buf)
-  "Set language variables from ALIST, in buffer BUF, if desired."
-  (when buf (set-buffer buf))
-  (mapc (lambda (pair)
-          (make-local-variable (car pair))
-          (set (car pair) (eval (cdr pair) t))
-          (when (bound-and-true-p ess--make-local-vars-permanent)
-            (put (car pair) 'permanent-local t))) ;; hack for Rnw
-        alist))
-
-(defmacro ess--alist (vars)
-  "Build a self-named alist from VARS.
-VARS must be a list of symbols."
-  (declare (debug 0))
-  `(list ,@(mapcar (lambda (var) `(cons ',var ,var)) vars)))
-
-(defvar ess-error-regexp   "^\\(Syntax error: .*\\) at line \\([0-9]*\\), file \\(.*\\)$"
-  "Regexp to search for errors.")
-
-(define-obsolete-function-alias 'ess-beginning-of-function #'beginning-of-defun "ESS 19.04")
-(define-obsolete-function-alias 'ess-end-of-function #'end-of-defun "ESS 19.04")
-
-(with-no-warnings
-  (defalias 'ess--project-root
-    ;; TODO: Remove once we drop support for Emacs 27
-    (if (and (fboundp 'project-root)
-             ;; Issues caused unless we confirm `project-roots' is obsolete, see bug#1052
-             (get 'project-roots 'byte-obsolete-info))
-        'project-root
-      (lambda (project) "See `project-roots'."
-        (car (project-roots project))))))
-
-(provide 'ess-utils)
-
-;;; ess-utils.el ends here
diff --git a/elpa/ess-20251212.937/ess.el b/elpa/ess-20251212.937/ess.el
deleted file mode 100644 (file)
index f021802..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-;;; ess.el --- Emacs Speaks Statistics  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1997-2025 Free Software Foundation, Inc.
-
-;; Author: David Smith <dsmithNOSPAMstats.adelaide.edu.au>
-;;         A.J. Rossini <blindglobeNOSPAMgmail.com>
-;;         Richard M. Heiberger <rmhNOSPAMtemple.edu>
-;;         Kurt Hornik <Kurt.HornikNOSPAMR-project.org>
-;;         Martin Maechler <maechlerNOSPAMstat.math.ethz.ch>
-;;         Rodney A. Sparapani <rsparapaNOSPAMmcw.edu>
-;;         Stephen Eglen <stephenNOSPAMgnu.org>
-;;         Sebastian P. Luque <spluqueNOSPAMgmail.com>
-;;         Henning Redestig <henning.redNOSPAMgooglemail.com>
-;;         Vitalie Spinu <spinuvitNOSPAMgmail.com>
-;;         Lionel Henry <lionel.hryNOSPAMgmail.com>
-;;         J. Alexander Branham <alex.branhamNOSPAMgmail.com>
-;;
-;; Maintainer: ESS Core Team <ESS-coreNOSPAMr-project.org>
-;; Created: 7 Jan 1994
-;; Package-Version: 20251212.937
-;; Package-Revision: e39ca8fa7fce
-;; URL: https://ess.r-project.org/
-;; Package-Requires: ((emacs "25.1"))
-;; ESSR-Version: 1.8
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-;;
-;; Emacs Speaks Statistics (ESS) is a package designed to support editing of
-;; scripts and interaction with various statistical analysis programs such as R,
-;; S-Plus, SAS, Stata and OpenBUGS/JAGS. For more details please visit ESS home
-;; page at https://ess.r-project.org/
-
-;;; Code:
-
-(require 'ess-utils)
-(require 'cl-generic)
-(require 'lisp-mnt)
-(defvar reporter-prompt-for-summary-p)
-
-\f
-;; Versions
-
-(defconst ess-version (eval-when-compile
-                        (lm-version (or (and (boundp 'load-true-file-name)
-                                             load-true-file-name)
-                                        load-file-name
-                                        buffer-file-name)))
-  "Version of ESS currently loaded.")
-
-(defconst essr-version (eval-when-compile
-                         (lm-with-file (or (and (boundp 'load-true-file-name)
-                                                load-true-file-name)
-                                           load-file-name
-                                           buffer-file-name)
-                           (lm-header "ESSR-Version")))
-  "Version of ESSR package.")
-
-(defvar ess-revision nil
-  "The revision and date of ESS.
-Is set  by \\[ess-version-string].")
-
-;;;###autoload
-(defun ess-version ()
-  "Return a string with ESS version information."
-  (interactive)
-  (message (format "ess-version: %s (loaded from %s)"
-                   (ess-version-string)
-                   (file-name-directory ess-lisp-directory))))
-
-(defun ess-version-string ()
-  (let* ((ess-dir (file-name-directory ess-lisp-directory)) ; if(<from source>) the top-level 'ess/'
-         (is-release (file-exists-p (concat ess-etc-directory ".IS.RELEASE")))
-         (rel-string (if is-release "Released "))
-         (git-ref-fn (concat ess-dir ".git/HEAD"))
-         (git-ref (when (file-exists-p git-ref-fn)
-                    (with-current-buffer (find-file-noselect git-ref-fn)
-                      (goto-char (point-min))
-                      (when (re-search-forward "ref: \\(.*\\)\n" nil t)
-                        (match-string 1)))))
-         (git-fname (if git-ref
-                        (concat ess-dir ".git/" git-ref)
-                      ;; For release
-                      (concat ess-etc-directory "git-ref")))
-         (git-rev (when (file-exists-p git-fname)
-                    (with-current-buffer (find-file-noselect git-fname)
-                      (goto-char (point-min))
-                      (concat "git: "(buffer-substring
-                                      (point-min) (line-end-position))))))
-         (elpa-fname (concat ess-dir "ess-pkg.el"))
-         (elpa-rev (when (file-exists-p elpa-fname)
-                     ;; Get it from ELPA dir name, (probably won't work if installed manually)
-                     (concat "elpa: "
-                             (replace-regexp-in-string "ess-" ""
-                                                       (file-name-nondirectory
-                                                        (substring ess-dir 1 -1)))))))
-    ;; Set the "global" ess-revision:
-    (setq ess-revision (format "%s%s%s"
-                               (or rel-string "")
-                               (or git-rev "")
-                               (or elpa-rev "")))
-    (when (string= ess-revision "")
-      (setq ess-revision "<unknown>"))
-    (concat ess-version " [" ess-revision "]")))
-
-\f
-;;; Bug Reporting
-
-;;;###autoload
-(defun ess-submit-bug-report ()
-  "Submit a bug report to the ESS maintainers."
-  (interactive)
-  (let ((reporter-prompt-for-summary-p 't))
-    (reporter-submit-bug-report
-     "ess-helpNOSPAMr-project.org"
-     (concat "ess-mode " (ess-version-string))
-     (list 'ess-language
-           'ess-dialect
-           'ess-ask-for-ess-directory
-           'ess-ask-about-transfile
-           'default-directory
-           'ess-keep-dump-files
-           'ess-source-directory
-           'ess-use-ido
-           'ess-use-eldoc
-           'ess-use-tracebug
-           'ess-use-auto-complete
-           'ess-use-company
-           'ess-eval-visibly-p
-           'ess-can-eval-in-background
-           'ess-local-process-name)
-     nil
-     (lambda ()
-       ;;(goto-char (point-max))
-       (rfc822-goto-eoh)
-       (forward-line 1)
-       (insert "\n\n-------------------------------------------------------------\n")
-       (insert "This bug report will be sent to the ESS _help_ email list\n")
-       (insert ">>> _INSTEAD_ we strongly recommend you open an issue for this\n")
-       (insert "    at  https://github.com/emacs-ess/ESS/issues .\n\n")
-       (insert "If you still prefer to use the ESS help email, press C-c C-c to send your message.\n")
-       (insert "-------------------------------------------------------------\n\n")
-       (insert (with-current-buffer ess-dribble-buffer
-                 (goto-char (point-max))
-                 (forward-line -100)
-                 (buffer-substring-no-properties (point) (point-max))))))))
-
-
-\f
-;;; Timer
-
-(defcustom ess-idle-timer-interval 1
-  "Number of seconds to wait before running function in `ess-idle-timer-functions'."
-  :type '(integer)
-  :group 'ess)
-
-(defvar ess-idle-timer-functions nil
-  "A list of functions to run each `ess-idle-timer-interval' idle seconds.
-If your function calls the process, you better use
-`ess-when-new-input' to wrap your call. If you call the
-subprocess please respect `ess-can-eval-in-background' variable.
-
-These functions are run with `run-hooks'. Use `add-hook' to add
-symbols to this variable.
-
-Most likely you will need a local hook. Then you should specify
-the LOCAL argument to `add-hook' and initialize it in
-`ess-mode-hook' or `ess-post-run-hook', or one of the more
-specialized hooks `ess-r-post-run-hook',`ess-stata-post-run-hook'
-etc.")
-
-(defun ess--idle-timer-function nil
-  "Internal function executed by `ess--idle-timer'."
-  (run-hooks 'ess-idle-timer-functions))
-
-(require 'timer)
-(defvar ess--idle-timer
-  (run-with-idle-timer ess-idle-timer-interval 'repeat
-                       #'ess--idle-timer-function)
-  "Timer used to run `ess-idle-timer-functions'.")
-
-\f
-;;; Dispatch on ess-dialect
-;; Inspired by major-mode specializer in cl-generic.el
-
-;; FIXME: Implement a notion of derived dialects. major-mode specializer cannot
-;; be used here as we need same dialect in different major-modes.
-
-;; Two parts:
-;; 1) first define a specializer (ess-dialect= DIALECT) to match symbols
-;;    representing ess dialects.
-;; 2) then define a context-rewriter so you can write
-;;   `&context (ess-dialect "R")` rather than
-;;   `&context (ess-dialect (ess-dialect= "R"))`.
-
-(cl-generic-define-generalizer ess--generic-dialect-generalizer
-  95
-  (lambda (name &rest _) `(if (stringp ,name) (intern ,name)
-                            (if (symbolp ,name) ,name)))
-  (lambda (tag &rest _) `((ess-dialect= ,tag))))
-
-(cl-defmethod cl-generic-generalizers ((_specializer (head ess-dialect=)))
-  "Support for (ess-dialect DIALECT) context specializer."
-  (list ess--generic-dialect-generalizer))
-
-(cl-generic-define-context-rewriter ess-dialect (dialect)
-  `(ess-dialect (ess-dialect= ,(if (stringp dialect)
-                                   (intern dialect)
-                                 dialect))))
-
-;; (cl-defgeneric ess-print-dialect ()
-;;   (error "unknown dialect %s" ess-dialect))
-;; (cl-defmethod ess-print-dialect (&context (ess-dialect "R"))
-;;   (message "dialect: R"))
-;; (cl-defmethod ess-print-dialect (&context (ess-dialect "julia"))
-;;   (message "dialect: julia"))
-
-(provide 'ess)
-
-;;; ess.el ends here
diff --git a/elpa/ess-20251212.937/ess.info b/elpa/ess-20251212.937/ess.info
deleted file mode 100644 (file)
index 0aee6e8..0000000
+++ /dev/null
@@ -1,5209 +0,0 @@
-This is ess.info, produced by makeinfo version 6.8 from ess.texi.
-
-INFO-DIR-SECTION Emacs
-START-INFO-DIR-ENTRY
-* ESS: (ess). Emacs Speaks Statistics (R/S/S+, SAS, BUGS/JAGS and Stata).
-END-INFO-DIR-ENTRY
-
-ESS -- Emacs Speaks Statistics
-******************************
-
-\1f
-File: ess.info,  Node: Top,  Next: Introduction,  Up: (dir)
-
-ESS: Emacs Speaks Statistics
-****************************
-
-ESS version 25.01.0
-
-     by  A.J. Rossini,
-         R.M. Heiberger,
-         K. Hornik,
-         M. Maechler,
-         R.A. Sparapani,
-         S.J. Eglen,
-         S.P. Luque,
-         H. Redestig,
-         V. Spinu,
-         L. Henry,
-     and J.A. Branham.
-
-     Emacs Speaks Statistics (ESS) provides an intelligent, consistent
-     interface between the user and the software.  ESS interfaces with
-     R, SAS, S-PLUS, BUGS/JAGS and other statistical analysis packages
-     on GNU/Linux, other Unix-like systems such as macOS, and Microsoft
-     Windows.  ESS is itself a package within the Emacs text editor and
-     uses Emacs features to streamline the creation and use of
-     statistical software.  ESS knows the syntax and grammar of
-     statistical analysis packages and provides consistent display and
-     editing features based on that knowledge.  ESS assists in
-     interactive and batch execution of statements written in these
-     statistical analysis languages.
-
-   The source and documentation of ESS 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.
-
-   ESS 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 in
-the file COPYING in the same directory as this file for more details.
-
-* Menu:
-
-* Introduction::                Overview of features provided by this package
-* Installation::                Installing ESS on your system
-* Interactive ESS::             Interacting with statistical programs
-* Entering commands::           Interacting with the ESS process
-* Evaluating code::             Sending code to the ESS process
-* Transcript Mode::             Manipulating saved transcript files
-* Editing objects::             How to create/edit objects and functions
-* Help::                        Reading help files
-* Completion::                  Various completion mechanisms
-* Developing with ESS::         Tools for package development and debugging
-* Extras::                      Other ESS features for the S family
-* ESS for R::                   Overview of ESS features for the S family
-* ESS for SAS::
-* ESS for BUGS::
-* ESS for JAGS::
-* Mailing lists/bug reports::   How to get assistance with ESS
-* Customization::               Customizing ESS
-* Indices::
-
-\1f
-File: ess.info,  Node: Introduction,  Next: Installation,  Prev: Top,  Up: Top
-
-1 Introduction to ESS
-*********************
-
-ESS provides a generic interface, through Emacs, to statistical
-packages.  It currently supports R (and the rest of the S family), SAS,
-BUGS/JAGS, Stata, and Julia with the level of support roughly in that
-order.
-
-   Throughout this manual, _Emacs_ refers to _GNU Emacs_ by the Free
-Software Foundation.  Although previous versions of ESS supported other
-Emacsen, current versions only support GNU Emacs.
-
-   There are two main ways of interacting with ESS: through "regular"
-modes or "inferior" modes.  Regular modes act like normal Emacs major
-modes.  ESS major modes are displayed in the mode-line in the format
-'ESS[dialect]', where 'dialect' can take values such as 'R', 'SAS', or
-'S'.
-
-   ESS also provides easy access to an "inferior process," which is an
-Emacs buffer associated with a running process.  This can be an R
-session, for example.  These inferior processes are referred to as
-inferior ESS ('iESS'), and are shown in the modeline by 'iESS
-[dialect]'.
-
-   Currently, the documentation contains many references to ''R'' where
-actually any supported (statistics) language is meant, i.e., 'R' could
-also mean 'S' or 'SAS.'
-
-   For exclusively interactive users of R, ESS provides a number of
-features to make life easier.  There is an easy to use command history
-mechanism, including a quick prefix-search history.  To reduce typing,
-command-line completion is provided for all R objects and "hot keys" are
-provided for common R function calls.  Help files are easily accessible,
-and a paging mechanism is provided to view them.  Finally, an incidental
-(but very useful) side-effect of ESS is that a transcript of your
-session is kept for later saving or editing.
-
-   No special knowledge of Emacs is necessary when using R interactively
-under ESS.
-
-   For those that use R in the typical edit-test-revise cycle when
-writing R functions, ESS provides for editing of R functions in Emacs
-buffers.  Unlike the typical use of R where the editor is restarted
-every time an object is edited, ESS uses the current Emacs session for
-editing.  In practical terms, this means that you can edit more than one
-function at once, and that the ESS process is still available for use
-while editing.  Error checking is performed on functions loaded back
-into R, and a mechanism to jump directly to the error is provided.  ESS
-also provides for maintaining text versions of your R functions in
-specified source directories.
-
-* Menu:
-
-* Features::                    Why should I use ESS?
-* New features::
-* Credits::                     Authors of and contributors to ESS
-* Manual::                      How to read this manual
-
-\1f
-File: ess.info,  Node: Features,  Next: New features,  Up: Introduction
-
-1.1 Why should I use ESS?
-=========================
-
-Statistical packages are powerful software systems for manipulating and
-analyzing data, but their user interfaces often leave something to be
-desired: they offer weak editor functionality and they differ among
-themselves so markedly that you have to re-learn how to do those things
-for each package.  ESS is a package which is designed to make editing
-and interacting with statistical packages more uniform, user-friendly
-and give you the power of Emacs as well.
-
-   Additionally, both Emacs and ESS (and R) are free software designed
-to give users full control over their computer.  For more on what this
-means, visit <https://www.gnu.org/philosophy/free-sw.html>.
-
-* Menu:
-
-* Current Features::
-
-\1f
-File: ess.info,  Node: Current Features,  Up: Features
-
-1.1.1 Features Overview
------------------------
-
-   * Languages Supported:
-        * S family (R, S, and S+ AKA S-PLUS)
-        * SAS
-        * BUGS/JAGS
-        * Stata
-        * Julia
-   * Editing source code (S family, SAS, BUGS/JAGS, Stata, Julia)
-        * Syntactic indentation and highlighting of source code
-        * Partial evaluation of code
-        * Loading and error-checking of code
-        * Source code revision maintenance
-        * Batch execution (SAS, BUGS/JAGS)
-        * Use of imenu to provide links to appropriate functions
-   * Interacting with the process (S family, SAS, Stata, Julia)
-        * Command-line editing
-        * Searchable Command history
-        * Command-line completion of S family object names and file
-          names
-        * Quick access to object lists and search lists
-        * Transcript recording
-        * Interface to the help system
-   * Transcript manipulation (S family, Stata)
-        * Recording and saving transcript files
-        * Manipulating and editing saved transcripts
-        * Re-evaluating commands from transcript files
-   * Interaction with Help Pages and other Documentation (R)
-        * Fast Navigation
-        * Sending Examples to running ESS process.
-        * Fast Transfer to Further Help Pages
-   * Help File Editing (R)
-        * Syntactic indentation and highlighting of source code.
-        * Sending Examples to running ESS process.
-        * Previewing
-
-   For source code buffers, ESS offers several features:
-
-   * Support for multiple indentation styles R code *Note Indenting::.
-
-   * Facilities for loading and error-checking source files, including a
-     keystroke to jump straight to the position of an error in a source
-     file.  *Note Error Checking::.
-
-   * Source code revision maintenance, which allows you to keep historic
-     versions of R source files.  *Note Source Files::.
-
-   * Facilities for evaluating R code such as portions of source files,
-     or line-by-line evaluation of files (useful for debugging).  *Note
-     Evaluating code::.
-
-   ESS also provides features that make it easier to interact with
-inferior ESS (iESS) process (a connection between your buffer and the
-statistical package which is waiting for you to input commands).  These
-include:
-
-   * Command-line editing for fixing mistakes in commands before they
-     are entered.  *Note Command-line editing::.
-
-   * Searchable command history for recalling previously-submitted
-     commands.  *Note Command History::.
-
-   * Command-line completion of both object and file names for quick
-     entry.  *Note Completion::.
-
-   * Hot-keys for quick entry of commonly-used commands in 'R' such as
-     'objects()', and 'search()'.  *Note Hot keys::.
-
-   * Transcript recording for a complete record of all the actions in an
-     R session.  *Note Transcript::.
-
-   * Interface to the help system, with a specialized mode for viewing R
-     help files.  *Note Help::.
-
-   * Object editing.  ESS allows you to edit more than one function
-     simultaneously in dedicated Emacs buffers.  The ESS process may
-     continue to be used while functions are being edited.  *Note Edit
-     buffer::.
-
-   Finally, ESS provides features for re-submitting commands from saved
-transcript files, including:
-
-   * Evaluation of previously entered commands, stripping away
-     unnecessary prompts.  *Note Transcript resubmit::.
-
-\1f
-File: ess.info,  Node: New features,  Next: Credits,  Prev: Features,  Up: Introduction
-
-1.2 New features in ESS
-=======================
-
-Changes and New Features in 25.01.0:
-
-   * polymode: In our transition from literate libraries (such as noweb
-     documented below with respect to 19.04), we now recommend the
-     polymode packages as a more suitable replacement.  Furthermore, we
-     suggest the related polymodes including poly-noweb, poly-markdown
-     and poly-R (installed in that order).  The package polymode itself,
-     as well as the polymodes packages, are all on MELPA rather than
-     ELPA. Therefore, you need to add MELPA to the list of installation
-     archives as follows.  '(add-to-list 'package-archives
-     '("melpa-stable" . "https://stable.melpa.org/packages/"))' for 'M-x
-     package-install'
-
-   * ESS[R]: The shorthand notation for lambda functions and the
-     question mark are now fontified as keywords.  Contributed by Maxime
-     Pettinger.
-
-   * ESS[SAS]: Developed new comprehensive lists of PROCs and functions
-     for syntax highlighting.  See 'etc/proc.sas' and 'etc/func.sas'.
-
-   Changes and New Features in 24.01.1:
-
-   * Revert a bug introduced with the 'ess-request-a-process' change
-
-   Changes and New Features in 24.01.0:
-
-   * fix docstring warnings in ess-custom
-
-   * :package-version is now set to "VERSION" in ess-custom.  By make
-     this is replaced with "24.01.0" (or similar).
-
-   * Better "collaboration" with org-mode.  Now 'ess-request-a-process'
-     obeys 'ess-gen-proc-buffer-name-function', thanks to Ihor
-     Radchenko.
-
-   Changes and New Features in 19.04 (unreleased):
-
-   * ESS[R]: When a background command is interrupted with C-g, ESS now
-     asks the user if they want to disable background evaluations
-     altogether.  This is a resiliency measure against cases where
-     background evals cause cascading errors or hangs.
-
-   * ESS[R]: Background commands now propagate errors to Emacs.
-
-   * ESS[R]: Background commands can now be disabled by process instad
-     of globally.  For instance when a process has failed to initialize
-     properly, background evals are disabled for that particular process
-     to avoid cascading errors.  Other processes may still use
-     background commands.
-
-   * ESS[R]: ESSR commands are now more robust when ESSR is not in
-     scope.  This can happen when using 'browser()' in an environment
-     that doesn't inherit from the search path.
-
-   * ESS[R]: Unexpected exits are now detected during startup.  In that
-     case an error is thrown with advice about how to recover.
-
-   * ESS[R]: 'options(width = )' is now set on startup based on the
-     width of the inferior window.
-
-   * ESS[R]: Add support for R projects and start R by default in the
-     project folder.
-
-   * ESS[R]: Backticked symbols in the process buffer are no longer
-     fontified as strings.
-
-   * ESS[R]: 'ess-command' now runs R code in a sandboxed environment.
-     Use '.ess.environment()' to inspect the current environment.
-
-   * ESS[R]: Added support for new syntax in R 4.0 and R 4.1.  This
-     concerns raw strings, lambda functions, and the pipe operator.
-
-   * ESS[R]: Highlight error locations in rlang style backtraces
-
-   * ESS[R]: Fixed issue that caused ESS-help to hang when usage blocks
-     include R comments (#1025).  Fix contributed by Bill Evans.
-
-   * ESS: New 'ess-elisp-trace-mode' minor mode.  Toggle it to start or
-     stop tracing all 'ess'-prefixed functions with 'trace-function'.
-     Tracing is useful for debugging background ESS behaviour.
-
-   * ESS[R]: 'ess-get-help-aliases-list' now caches the aliases on the R
-     side.  This should speed up help lookup when the search path has
-     changed and the aliases are read again.
-
-   * ESS: 'ess-command' now uses a default timeout of 30 seconds.  It
-     should normally be avoided with long-running tasks because it
-     causes Emacs to block while the command is running.  If the timeout
-     is reached, an error is thrown.  An interrupt is also sent to the
-     process in case of early exit.
-
-     This is a behaviour change: you will now have to explicitly opt in
-     blocking the whole Emacs UI for more than 30 seconds by supplying a
-     larger timeout (use 'most-positive-fixnum' for infinity).
-
-   * ESS: 'ess-wait-for-process' now returns nil if a timeout is
-     reached.
-
-   * ESS: 'ess-get-words-from-vector' gains a 'timeout' argument.
-
-   * ESS[R]: Fixed performance issue with argument completions.  The
-     help summary for the argument is no longer displayed in the echo
-     area.  This fixes delays and hangs (#1062).
-
-   * ESS[R]: 'ess-command' is now more robust and resilient to hangs and
-     custom prompts (#1043).  It also strips continuation prompts ('+'
-     prompts) automatically and reliably (#1116).
-
-   * ESS[R]: 'ess-command' now handles sinked consoles correctly.
-
-   * ESS[R]: 'ess-command' no longer changes '.Last.value'.  As a
-     result, background tasks like completions no longer affect the last
-     value binding (#1058).
-
-   * ESS[R]: Namespaced evaluation is disable in roxygen examples
-     (#1026).  Part of this change is that namespaced evaluation has
-     become a buffer-local rather than process-local setting (#1046).
-     This makes it possible to disable namespaced evaluation in specific
-     buffers or contexts.
-
-   * iESS: Inferior processes can now properly reuse frames (#987).
-     Fixed issue that caused the current buffer to be incorrectly
-     displayed in the new frame when 'display-buffer' is set to pop up
-     frames.
-
-   * ESS[R]: Better support for tramp.  Fixed package evaluation on
-     remote servers with Tramp (#950); process reloading (#1001); and an
-     evaluation issue (#1024).  These fixes were contributed by David
-     Pritchard.
-
-   * ESS[R]: Automatic offsetting of R process output is now disabled by
-     default because it produces undesirable output in some situations.
-     To re-enable, set 'inferior-ess-fix-misaligned-output' to t.
-
-   * ESS[R]: Improved 'xref' lookup ('M-.').  Function locations are now
-     always detected for package libraries listed in
-     'ess-r-package-library-paths'.
-
-   * ESS[R]: Evaluated lines starting with the Roxygen prefix are now
-     always stripped from the prefix, so they can be sent to the process
-     easily.  Previously, this was only the case inside the 'examples'
-     field.  Since roxygen is switching to R markdown, it becomes useful
-     to evaluate chunks of R outside examples.
-
-   * stata support is now obsolete since we were unable to elicit FSF
-     paperwork from some of the original authors: see the lisp/obsolete
-     sub-directory on the ESS github repo
-
-   * 'ess-set-working-directory' no longer changes the active directory
-     (as defined by the buffer-local variable 'default-directory') of
-     the buffer where the command is called.  Instead, the active
-     directory of the inferior buffer is updated to the new working
-     directory.
-
-   * The default of ess-eval-visibly is now ''nowait'.  With this change
-     you should no longer experience freezes while evaluating code.
-
-   * ESS[R]: There is a new menu entry for reloading the R process.  It
-     is otherwise bound to 'C-c C-e C-r'.  Reloading now reuses the same
-     process name and start arguments that were used to start the
-     process.
-
-   * iESS: Process runners now return the inferior buffer.  Note that
-     callers of inferior runners should not assume that the current
-     buffer has been set to the inferior buffer.  Instead, use
-     'with-current-buffer' with the return value of the inferior.
-
-   * iESS[SAS]: The SAS keymap was only set in iESS buffers called
-     '*SAS*'.  This is now fixed.
-
-   * ESS[R]: Fixed longstanding indentation issues involving '::' and
-     ':::' operators.
-
-   * Implement a more reliable check for the process busy state.
-     Background actions such as completion and directory synchronization
-     should not block the process and should not cause printing of the
-     extraneous output to the interpreter.
-
-   * Activate 'goto-address-mode' for url and email highlighting in
-     inferior buffers.
-
-   * 'smart-underscore' and 'ess-smart-S-assign-key' have been removed.
-     Users who liked the previous behavior (i.e.  underscore inserting
-     "<-") should bind 'ess-insert-assign' to the underscore in their
-     Emacs initialization file.  For example, '(define-key
-     ess-r-mode-map "_" #'ess-insert-assign)' and '(define-key
-     inferior-ess-r-mode-map "_" #'ess-insert-assign)' will activate it
-     in all ESS R buffers.
-
-   * ESS major modes are now defined using 'define-derived-mode'.  This
-     makes ESS major modes respect modern conventions such as having
-     <language>-mode-hook and <language>-mode-map.  Users are encouraged
-     to place customizations under the appropriate mode.
-
-   * New option ess-auto-width controls setting the width option on
-     window changes.  Users can change it to 'frame, 'window, or an
-     integer.  See the documentation for details.
-     'ess-auto-width-visible' controls visibility.
-
-   * ESS now respects 'display-buffer-alist'.  Users can now use
-     'display-buffer-alist' to manage how and where windows appear.  For
-     more information and examples, see *Note (ess)Controlling buffer
-     display::.
-
-   * 'ess-roxy-mode' can now be enabled in non-R buffers.  This is
-     primarily intended to support roxygen documentation for cpp
-     buffers.  Preview functionality is not supported outside R buffers.
-
-   * ESS[R]: DESCRIPTION files now open in 'conf-colon-mode'.
-
-   * 'ess-style' now has effects when set as a file or directory local
-     variable.
-
-   * 'ess-default-style' is now obsolete, use 'ess-style' instead.
-
-   * Options for 'ess-gen-proc-buffer-name-function' have been renamed.
-     ess-gen-proc-buffer-name:projectile-or-simple was renamed to
-     ess-gen-proc-buffer-name:project-or-simple and
-     ess-gen-proc-buffer-name:projectile-or-directory was renamed to
-     ess-gen-proc-buffer-name:project-or-directory.  As the name
-     suggests, these now rely on project.el (included with Emacs) rather
-     than projectile.el, which is a third-party package.
-
-   * Eldoc fully honors 'eldoc-echo-area-use-multiline-p'
-
-   * ESS[R]: 'ess-r-rhub-check-package' gained new 'RECOMMENDED'.
-
-   * ESS[R]: devtools commands ask about saving modified buffers before
-     running.  Users can disable the questioning with
-     'ess-save-silently'.
-
-   * ESS[R] help pages now provide links to other help topics.  This is
-     similar with what you would see with, for example
-     'options(help_type = ``html'')' but works with the plain-text
-     version as well.  This only works with 'options(useFancyQuotes =
-     TRUE)' (the default).
-
-   * 'ess-rdired' buffers now derive from tabulated-list-mode.  They
-     should look better and be a bit faster overall.  The size column
-     now displays object sizes in bytes.
-
-   * 'ess-rdired' buffers now auto-update.  The frequency is governed by
-     the new option 'ess-rdired-auto-update-interval'.
-
-   * ESS[R]: 'electric-layout-mode' is now supported.  This
-     automatically inserts a newline after an opening curly brace in R
-     buffers.  To enable it, customize 'ess-r-mode-hook'.
-
-   * ESS[R]: imenu now supports assignment with the equals sign.
-
-   * ESS[Rd]: Rd no longer writes abbrevs to user's abbrev file.
-
-   * ESS removed support for many unused languages.  This includes old
-     versions of S+, ARC, OMG, VST, and XLS.
-
-   * ess-r-runner-prefixes was modified to find R-4 and later.
-
-   * ESS no longer activates eldoc if the user has disabled
-     global-eldoc-mode.
-
-   The following have been made obsolete or removed, see their
-documentation for more detail:
-
-   * Libraries for literate data analysis are obsolete and not loaded by
-     default.  This includes 'ess-noweb', 'ess-swv', and related
-     functionality like 'Rnw-mode'.  Users are encouraged to switch to
-     one of several other packages that deal with these modes.  For
-     example, polymode <https://github.com/polymode/poly-R/>,
-     <https://polymode.github.io/>, or markdown-mode with edit-indirect
-     <https://jblevins.org/projects/markdown-mode>.
-
-   * Support for 'auto-complete' is obsolete.  The 'auto-complete'
-     package is unmaintained and so ESS support is now obsolete.  Users
-     are encouraged to switch to 'company-mode' instead.
-
-   * User options for controlling display of buffers.  This includes
-     'ess-show-buffer-action', 'inferior-ess-same-window',
-     'inferior-ess-own-frame', and 'inferior-ess-frame-alist'.  See
-     above about ESS respecting 'display-buffer-alist'.
-
-   * Variables 'ess-tab-always-indent' and 'ess-tab-complete-in-script'.
-     Use the Emacs-wide setting of 'tab-always-indent' instead.
-
-   * 'inferior-ess-*-start-file' variables.  All modes except Stata did
-     not respect customization of this variable.  In order to load a
-     file on startup, you should put a function on
-     'ess-*-post-run-hook'.
-
-   Bug Fixes in 18.10.3:
-   * More 'Makefile' fixes, notably installing '*.el's.
-
-   Bug Fixes in 18.10.2:
-   * ESS[R] Fix namespace evaluation in non-installed packages.
-     Evaluation is directed into GlobalEnv as originally intended.
-   * 'Makefile' fixes, notably for 'make install' and including full
-     docs in the tarballs.
-
-   Bug Fixes in 18.10.1:
-   * New functions 'ess-eval-line-visibly-and-step' ('C-c C-n' and
-     'ess-eval-region-or-line-visibly-and-step' ('C-RET') which behave
-     as the old versions of 'ess-eval-line-and-step' and
-     'ess-eval-region-or-line-and-step'.
-
-   Changes and New Features in 18.10:
-
-   * This is the last release to support Emacs older than 25.1.  Going
-     forward, only GNU Emacs 25.1 and newer will be supported.  Soon
-     after this release, support for older Emacs versions will be
-     dropped from the git master branch.  Note that MELPA uses the git
-     master branch to produce ESS snapshots, so if you are using Emacs <
-     25.1 from MELPA and are unable to upgrade, you should switch to
-     MELPA-stable.
-
-   * ESS now displays the language dialect in the mode-line.  So, for
-     example, R buffers will now show ESS[R] rather than ESS[S].
-
-   * The ESS manual has been updated and revised.
-
-   * The ESS initialization process has been further streamlined.  If
-     you update the autoloads (which installation from 'package-install'
-     does), you should not need to '(require 'ess-site)' at all, as
-     autoloads should automatically load ESS when it is needed (e.g.
-     the first time an R buffer is opened).  In order to defer loading
-     your ESS config, you may want to do something like
-     '(with-require-after-load "ess" <ess-config-here>)' in your Emacs
-     init file.  Users of the popular 'use-package' Emacs package can
-     now do '(use-package ess :defer t)' to take advantage of this
-     behavior.  For more information on this feature, see *Note
-     (ess)Activating and Loading ESS::.
-
-   * ESS now respects Emacs conventions for keybindings.  This means
-     that The 'C-c [letter]' bindings have been removed.  This affects
-     'C-c h', which was bound to 'ess-eval-line-and-step-invisibly' in
-     'sas-mode-local-map'; 'C-c f', which was bound to
-     'ess-insert-function-outline' in 'ess-add-MM-keys'; and 'C-c h',
-     which was bound to 'ess-handy-commands' in 'Rd-mode-map',
-     'ess-noweb-minor-mode-map', and 'ess-help-mode-map'
-
-   * Functions 'ess-eval-line-and-step' and
-     'ess-eval-region-or-line-and-step' now behave consistently with
-     other evaluation function inside a package.
-
-   * ESS[R]: 'ess-r-package-use-dir' now works with any mode.  This sets
-     the working directory to the root of the current package including
-     for example C or C++ files within '/src').
-
-   * ESS[R]: Long + + prompts in the inferior no longer offset output.
-
-   * ESS[R]: New option 'strip' for 'inferior-ess-replace-long+'.  This
-     strips the entire + + sequence.
-
-   * ESS modes now inherit from 'prog-mode'.  In the next release, ESS
-     modes will use 'define-derived-mode' so that each mode will have
-     (for example) its own hooks and keymaps.
-
-   * ESS[R]: Supports flymake in R buffers for Emacs 26 and newer.
-     Users need to install the 'lintr' package to use it.  Customizable
-     options include 'ess-use-flymake', 'ess-r-flymake-linters', and
-     'ess-r-flymake-lintr-cache'.
-
-   * ESS[R]: Gained support for xref in Emacs 25+ *Note (emacs)Xref::.
-
-   * ESS[R]: The startup screen is cleaner.  It also displays the
-     startup directory with an explicit 'setwd()'.
-
-   * ESS[R]: Changing the working directory is now always reflected in
-     the process buffer.
-
-   * ESS[R]: 'Makevars' files open with 'makefile-mode'.
-
-   * New variable 'ess-write-to-dribble'.  This allows users to disable
-     the dribble ('*ESS*') buffer if they wish.
-
-   * All of the '*-program-name' variables have been renamed to
-     '*-program'.  Users who previously customized e.g.
-     'inferior-ess-R-program-name' will need to update their
-     customization to 'inferior-ess-R-program'.  These variables are
-     treated as risky variables.
-
-   * 'ess-smart-S-assign' was renamed to 'ess-insert-assign'.  It
-     provides similar functionality but for any keybinding, not just
-     '_'.  For instance if you bind it to ';', repeated invocations
-     cycle through between assignment and inserting ';'.
-
-   * 'C-c C-=' is now bound to 'ess-cycle-assign' by default.  See the
-     documentation for details.  New user customization option
-     'ess-assign-list' controls which assignment operators are cycled.
-
-   * ESS[R] In remote sessions, the ESSR package is now fetched from
-     GitHub.
-
-   * Commands that send the region to the inferior process now deal with
-     rectangular regions.  See the documentation of 'ess-eval-region'
-     for details.  This only works on Emacs 25.1 and newer.
-
-   * ESS[R]: Improvements to interacting with iESS in non-R files.
-     Interaction with inferior process in non-R files within packages
-     (for instance C or C++ files) has been improved.  This is a work in
-     progress.
-
-   * ESS[R]: Changing the working directory is now always reflected in
-     the process buffer.
-
-   * ESS[JAGS]: *.jog and *.jmd files no longer automatically open in
-     JAGS mode.
-
-   Many improvements to fontification:
-
-   * Improved customization for faces.  ESS now provides custom faces
-     for (nearly) all faces used and places face customization options
-     into their own group.  Users can customize these options using 'M-x
-     customize-group RET ess-faces'.
-
-   * Many new keywords were added to 'ess-R-keywords' and
-     'ess-R-modifiers'.  See the documentation for details.
-
-   * ESS[R]: 'in' is now only fontified when inside a 'for' construct.
-     This avoids spurious fontification, especially in the output buffer
-     where 'in' is a common English word.
-
-   * ESS: Font-lock keywords are now generated lazily.  That means you
-     can now add or remove keywords from variables like 'ess-R-keywords'
-     in your Emacs configuration file after loading ESS (i.e.  in the
-     ':config' section for 'use-package' users).
-
-   * ESS[R]: Fontification of roxygen '@param' keywords now supports
-     comma-separated parameters.
-
-   * ESS[R]: Certain keywords are only fontified if followed by a
-     parenthesis.  Function-like keywords such as 'if ()' or 'stop()'
-     are no longer fontified as keyword if not followed by an opening
-     parenthesis.  The same holds for search path modifiers like
-     'library()' or 'require()'.
-
-   * ESS[R]: Fixed fontification toggling.  Especially certain syntactic
-     elements such as '%op%' operators and backquoted function
-     definitions.
-
-   * ESS[R]: 'ess-font-lock-toggle-keyword' can be called interactively.
-     This command asks with completion for a font-lock group to toggle.
-     This functionality is equivalent to the font-lock menu.
-
-   Notable bug fixes:
-
-   * 'prettify-symbols-mode' no longer breaks indentation.  This is
-     accomplished by having the pretty symbols occupy the same number of
-     characters as their non-pretty cousins.  You may customize the new
-     variable 'ess-r-prettify-symbols' to control this behavior.
-
-   * ESS: Inferior process buffers are now always displayed on startup.
-     Additionally, they don't hang Emacs on failures.
-
-   Obsolete libraries, functions, and variables:
-
-   * The 'ess-r-args.el' library has been obsoleted and will be removed
-     in the next release.  Use 'eldoc-mode' instead, which is on by
-     default.
-
-   * Functions and options dealing with the smart assign key are
-     obsolete.  The following functions have been made obsolete and will
-     be removed in the next release of ESS: 'ess-smart-S-assign',
-     'ess-toggle-S-assign', 'ess-toggle-S-assign-key',
-     'ess-disable-smart-S-assign'.
-
-     The variable 'ess-smart-S-assign-key' is now deprecated and will be
-     removed in the next release.  If you would like to continue using
-     '_' for inserting assign in future releases, please bind
-     'ess-insert-assign' in 'ess-mode-map' the normal way.
-
-   * ESS[S]: Variable 'ess-s-versions-list' is obsolete and ignored.
-     Use 'ess-s-versions' instead.  You may pass arguments by starting
-     the inferior process with the universal argument.
-
-   Changes and New Features in 17.11:
-
-   * The ESS initialization process has been streamlined.  You can now
-     load the R and Stata modes independently from the rest of ESS. Just
-     put '(require 'ess-r-mode)' or '(require 'ess-stata-mode)' in your
-     init file.  This is for experienced Emacs users as this requires
-     setting up autoloads for '.R' files manually.  We will keep
-     maintaining 'ess-site' for easy loading of all ESS features.
-
-   * Reloading and quitting the process is now more robust.  If no
-     process is attached, ESS now switches automatically to one
-     (prompting you for selection if there are several running).
-     Reloading and quitting will now work during a debug session or when
-     R is prompting for input (for instance after a crash).  Finally,
-     the window configuration is saved and restored after reloading to
-     prevent the buffer of the new process from capturing the cursor.
-
-   * ESS[R]: New command 'ess-r-package-use-dir'.  It sets the working
-     directory of the current process to the current package directory.
-
-   * ESS[R] Lookup for references in inferior buffers has been improved.
-     New variable 'ess-r-package-source-roots' contains package
-     sub-directories which are searched recursively during the file
-     lookup point.  Directories in 'ess-tracebug-search-path' are now
-     also searched recursively.
-
-   * ESS[R] Namespaced evaluation is now automatically enabled only in
-     the 'R/' directory.  This way ESS will not attempt to update
-     function definitions from a package if you are working from e.g.  a
-     test file.
-
-   Changes and New Features in 16.10:
-
-   * ESS[R]: Syntax highlighting is now more consistent.  Backquoted
-     names are not fontified as strings (since they really are
-     identifiers).  Furthermore they are now correctly recognized when
-     they are function definitions or function calls.
-   * ESS[R]: Backquoted names and '%op%' operators are recognized as
-     sexp.  This is useful for code navigation, e.g.  with 'C-M-f' and
-     'C-M-b'.
-   * ESS[R]: Integration of outline mode with roxygen examples fields.
-     You can use outline mode's code folding commands to fold the
-     examples field.  This is especially nice to use with well
-     documented packages with long examples set.  Set
-     'ess-roxy-fold-examples' to non-nil to automatically fold the
-     examples field when you open a buffer.
-   * ESS[R]: New experimental feature: syntax highlighting in roxygen
-     examples fields.  This is turned off by default.  Set
-     'ess-roxy-fontify-examples' to non-nil to try it out.
-   * ESS[R]: New package development command 'ess-r-devtools-ask' bound
-     to 'C-c C-w C-a'.  It asks with completion for any devtools command
-     that takes 'pkg' as argument.
-   * ESS[R]: New command 'C-c C-e C-r' to reload the inferior process.
-     Currently only implemented for R. The R method runs
-     'inferior-ess-r-reload-hook' on reloading.
-   * ESS[R]: 'ess-r-package-mode' is now activated in non-file buffers
-     as well.
-
-   Bug fixes in 16.10:
-   * ESS[R]: Fix broken (un)flagging for debugging inside packages
-   * ESS[R]: Fixes (and improvements) in Package development
-   * ESS[R]: Completion no longer produces '...=' inside 'list( )'.
-   * ESS[R]: Better debugging and tracing in packages.
-   * ESS[R]: Better detection of symbols at point.
-   * ESS[R]: No more spurious warnings on deletion of temporary files.
-   * ESS[julia]: help and completion work (better)
-   * ESS[julia]: available via 'ess-remote'
-
-   Changes and New Features in 16.04:
-
-   * ESS[R]: 'developer' functionality has been refactored.  The new
-     user interface consists of a single command
-     'ess-r-set-evaluation-env' bound by default to 'C-c C-t C-s'.  Once
-     an evaluation environment has been set with, all subsequent ESS
-     evaluation will source the code into that environment.  By default,
-     for file within R packages the evaluation environment is set to the
-     package environment.  Set 'ess-r-package-auto-set-evaluation-env'
-     to 'nil' to disable this.
-   * ESS[R]: New 'ess-r-package-mode' This development mode provides
-     features to make package development easier.  Currently, most of
-     the commands are based on the 'devtools' packages and are
-     accessible with 'C-c C-w' prefix.  See the documentation of
-     'ess-r-package-mode' function for all available commands.  With
-     'C-u' prefix each command asks for extra arguments to the
-     underlying devtools function.  This mode is automatically enabled
-     in all files within R packages and is indicated with '[pkg:NAME]'
-     in the mode-line.
-   * ESS[R]: Help lookup has been improved.  It is now possible to get
-     help for namespaced objects such as pkg::foobar.  Furthermore, ESS
-     recognizes more reliably when you change 'options('html_type')'.
-   * ESS[R]: New specialized breakpoints for debugging magrittr pipes
-   * ESS: ESS now implements a simple message passing interface to
-     communicate between ESS and inferior process.
-
-   Bug fixes in 16.04:
-   * ESS[R]: Roxygen blocks with backtics are now correctly filled
-   * ESS[R]: Don't skip breakpoints in magrittr's 'debug_pipe'
-   * ESS[R]: Error highlighting now understands 'testthat' type errors
-   * ESS[Julia]: Added getwd and setwd generic commands
-
-\1f
-File: ess.info,  Node: Credits,  Next: Manual,  Prev: New features,  Up: Introduction
-
-1.3 Authors of and contributors to ESS
-======================================
-
-The ESS environment is built on the open-source projects of many
-contributors, dating back to 1989 where Doug Bates and Ed Kademan wrote
-S-mode to edit S and Splus files in GNU Emacs.  Frank Ritter and Mike
-Meyer added features, creating version 2.  Meyer and David Smith made
-further contributions, creating version 3.  For version 4, David Smith
-provided significant enhancements to allow for powerful process
-interaction.
-
-   John Sall wrote GNU Emacs macros for SAS source code around 1990.
-Tom Cook added functions to submit jobs, review listing and log files,
-and produce basic views of a dataset, thus creating a SAS-mode which was
-distributed in 1994.
-
-   In 1994, A.J. Rossini extended S-mode to support XEmacs.  Together
-with extensions written by Martin Maechler, this became version 4.7 and
-supported S, Splus, and R. In 1995, Rossini extended SAS-mode to work
-with XEmacs.
-
-   In 1997, Rossini merged S-mode and SAS-mode into a single Emacs
-package for statistical programming; the product of this marriage was
-called ESS version 5.  Richard M. Heiberger designed the inferior mode
-for interactive SAS and SAS-mode was further integrated into ESS. Thomas
-Lumley's Stata mode, written around 1996, was also folded into ESS. More
-changes were made to support additional statistical languages,
-particularly XLispStat.
-
-   ESS initially worked only with Unix statistics packages that used
-standard-input and standard-output for both the command-line interface
-and batch processing.  ESS could not communicate with statistical
-packages that did not use this protocol.  This changed in 1998 when
-Brian Ripley demonstrated use of the Windows Dynamic Data Exchange (DDE)
-protocol with ESS. Heiberger then used DDE to provide interactive
-interfaces for Windows versions of Splus.  In 1999, Rodney A. Sparapani
-and Heiberger implemented SAS batch for ESS relying on files, rather
-than standard-input/standard-output, for Unix, Windows and Mac.  In
-2001, Sparapani added BUGS batch file processing to ESS for Unix and
-Windows.
-
-   * The multiple process code, and the idea for
-     'ess-eval-line-and-next-line' are by Rod Ball.
-
-   * Thanks to Doug Bates for many useful suggestions.
-
-   * Thanks to Martin Maechler for reporting and fixing bugs, providing
-     many useful comments and suggestions, and for maintaining the ESS
-     mailing lists.
-
-   * Thanks to Frank Ritter for updates, particularly the menu code, and
-     invaluable comments on the manual.
-
-   * Thanks to Ken'ichi Shibayama for his excellent indenting code, and
-     many comments and suggestions.
-
-   * Thanks to Aki Vehtari for adding interactive BUGS support.
-
-   * Thanks to Brendan Halpin for bug-fixes and updates to Stata-mode.
-
-   * Last, but definitely not least, thanks to the many ESS users and
-     contributors to the ESS mailing lists.
-
-   _ESS_ is being developed and currently maintained by
-
-   * A.J. Rossini (mailto:blindglobeNOSPAMgmail.com)
-   * Richard M. Heiberger (mailto:rmhNOSPAMtemple.edu)
-   * Kurt Hornik (mailto:Kurt.HornikNOSPAMR-project.org)
-   * Martin Maechler (mailto:maechlerNOSPAMstat.math.ethz.ch)
-   * Rodney A. Sparapani (mailto:rsparapaNOSPAMmcw.edu)
-   * Stephen Eglen (mailto:stephenNOSPAMgnu.org)
-   * Sebastian P. Luque (mailto:spluqueNOSPAMgmail.com)
-   * Henning Redestig (mailto:henning.redNOSPAMgooglemail.com)
-   * Vitalie Spinu (mailto:spinuvitNOSPAMgmail.com)
-   * Lionel Henry (mailto:lionel.hryNOSPAMgmail.com)
-   * J. Alexander Branham (mailto:alex.branhamNOSPAMgmail.com)
-
-\1f
-File: ess.info,  Node: Manual,  Prev: Credits,  Up: Introduction
-
-1.4 How to read this manual
-===========================
-
-If you need to install ESS, read *note Installation:: for details on
-what needs to be done before proceeding to the next chapter.  This
-section describes some of the basics of using Emacs.  If you are already
-familiar with basic Emacs functionality, skip this section.  You may
-also want to use the Emacs tutorial, accessible via 'C-h t'.
-
-   In this manual we use the standard notation used by Emacs for
-describing the keystrokes used to invoke certain commands.  'C-<chr>'
-means hold the CONTROL key while typing the character <chr>.  'M-<chr>'
-means hold the META key (usually ALT) down while typing <chr>.  If there
-is no META, EDIT or ALT key, instead press and release the ESC key and
-then type <chr>.
-
-   All ESS commands can be invoked by typing 'M-x command'.  Most of the
-useful commands are bound to keystrokes for ease of use.  Also, the most
-popular commands are also available through the Emacs menubar, and a
-small subset are provided on the toolbar.  Where possible, keybindings
-are similar to other modes in Emacs to strive for a consistent user
-interface within Emacs, regardless of the details of which programming
-language is being edited, or process being run.
-
-   Some commands, such as 'M-x R' can accept an optional 'prefix'
-argument.  To specify the prefix argument, you would type 'C-u' before
-giving the command.  For example, if you type 'C-u M-x R', you will be
-asked for command line options that you wish to invoke the R process
-with.
-
-   Emacs is a 'self-documenting' text editor.  This applies to ESS in
-two ways.  First, some documentation about each ESS command can be
-obtained by typing 'C-h f'.  For example, if you type 'C-h f
-ess-eval-region', documentation for that command will appear in a
-separate *Help* buffer.  Second, 'C-h m' pops up a complete list of
-keybindings available in each ESS mode and brief description of that
-mode.
-
-   Emacs is a versatile editor written in both C and a dialect of Lisp
-known as Elisp.  ESS is written in Elisp and benefits from the flexible
-nature of lisp.  In particular, many aspects of ESS behaviour can be
-changed by suitable customization of Lisp variables.  This manual
-mentions some of the most frequent variables.  A full list of them
-however is available by using the Custom facility within Emacs.  Type
-'M-x customize-group RET ess RET' to get started.  *note Customization::
-provides details of common user variables you can change to customize
-ESS to your taste, but it is recommended that you defer this section
-until you are more familiar with ESS.
-
-\1f
-File: ess.info,  Node: Installation,  Next: Interactive ESS,  Prev: Introduction,  Up: Top
-
-2 Installing ESS on your system
-*******************************
-
-ESS supports GNU Emacs versions 25.1 and newer.
-
-   ESS is most likely to work with current/recent versions of the
-following statistical packages: R/S-PLUS, SAS, Stata, OpenBUGS and JAGS.
-
-   To build the PDF documentation, you will need a version of TeX Live
-or texinfo that includes texi2dvi.
-
-   There are two main methods used for installing ESS. You may install
-from a third-party repository or from source code.  Once you install it,
-you must also activate or load ESS in each Emacs session, though
-installation from a third-party repository likely takes care of that for
-you.  See *note Activating and Loading ESS:: for more details.
-
-* Menu:
-
-* Installing from a third-party repository::
-* Installing from source::
-* Activating and Loading ESS::
-* Check Installation::
-
-\1f
-File: ess.info,  Node: Installing from a third-party repository,  Next: Installing from source
-
-2.1 Installing from a third-party repository
-============================================
-
-ESS is packaged by many third party repositories.  Many GNU/Linux
-distributions package it, usually with the name "emacs-ess" or similar.
-
-   ESS is also available through Milkypostman’s Emacs Lisp Package
-Archive (MELPA), a popular repository for Emacs packages.  Instructions
-on how to do so are found on MELPA's website (https://melpa.org/).
-MELPA also hosts MELPA-stable with stable ESS builds.  You may choose
-between MELPA with the latest and greatest features (and bugs) or
-MELPA-stable, which may lag a bit behind but should be more stable.
-
-   After installing, users should make sure ESS is activated or loaded
-in each Emacs session.  See *note Activating and Loading ESS::.
-Depending on install method, this may be taken care of automatically.
-
-\1f
-File: ess.info,  Node: Installing from source,  Next: Activating and Loading ESS,  Prev: Installing from a third-party repository
-
-2.2 Installing from source
-==========================
-
-Stable versions of ESS are available at the ESS web page
-(https://ess.r-project.org) as a .tgz file or .zip file.  ESS releases
-are GPG-signed, you should check the signature by downloading the
-accompanying '.sig' file and doing:
-
-     gpg --verify ess-18.10.tgz.sig
-
-   Alternatively, you may download the git repository.  ESS is currently
-hosted on GitHub: <https://github.com/emacs-ess/ESS>.  'git clone
-https://github.com/emacs-ess/ESS.git' will download it to a new
-directory 'ESS' in the current working directory.
-
-   We will refer to the location of the ESS source files as
-'/path/to/ESS/' hereafter.
-
-   After installing, users should make sure they activate or load ESS in
-each Emacs session, see *note Activating and Loading ESS::
-
-   Optionally, compile Elisp files, build the documentation, and the
-autoloads:
-     cd /path/to/ESS/
-     make
-   Without this step the documentation, reference card, and autoloads
-will not be available.  Uncompiled ESS will also run slower.
-
-   Optionally, you may make ESS available to all users of a machine by
-installing it site-wide.  To do so, run 'make install'.  You might need
-administrative privileges:
-
-     make install
-
-   The files are installed into '/usr/share/emacs' directory.  For this
-step to run correctly on macOS, you will need to adjust the 'PREFIX'
-path in 'Makeconf'.  The necessary code and instructions are commented
-in that file.
-
-\1f
-File: ess.info,  Node: Activating and Loading ESS,  Next: Check Installation,  Prev: Installing from source
-
-2.3 Activating and Loading ESS
-==============================
-
-After installing ESS, you must activate or load it each Emacs session.
-ESS can be autoloaded, and if you used a third-party repository (such as
-your Linux distribution or MELPA) to install, you can likely skip this
-section and proceed directly to *note Check Installation::
-
-   Otherwise, you may need to add the path to ESS to 'load-path' with:
-
-     (add-to-list 'load-path "/path/to/ESS/lisp")
-
-   You then need to decide whether to take advantage of deferred loading
-(which will result in a faster Emacs startup time) or require ESS when
-Emacs is loaded.  To autoload ESS when needed (note that if installed
-from source, you must have run 'make'):
-
-     (load "ess-autoloads")
-
-   To require ESS on startup, you can either put
-
-     (require 'ess-site)
-
-   or
-
-     (require 'ess-r-mode)
-
-   In your configuration file, depending on whether you want all ESS
-features or only R related features.
-
-\1f
-File: ess.info,  Node: Check Installation,  Prev: Activating and Loading ESS
-
-2.4 Check Installation
-======================
-
-Restart Emacs and check that ESS was loaded from a correct location with
-'M-x ess-version'.
-
-\1f
-File: ess.info,  Node: Interactive ESS,  Next: Entering commands,  Prev: Installation,  Up: Top
-
-3 Interacting with statistical programs
-***************************************
-
-As well as using ESS to edit your source files for statistical programs,
-you can use ESS to run these statistical programs.  In this chapter, we
-mostly will refer by example to running R from within Emacs.  The Emacs
-convention is to name such processes running under its control as
-'inferior processes'.  Some users find this terminology confusing; you
-may prefer to think of these as 'interactive processes.'  Either way, we
-use the term 'iESS' to refer to the Emacs mode used to interact with
-statistical programs.
-
-* Menu:
-
-* Starting up::
-* Multiple ESS processes::
-* ESS processes on Remote Computers::
-* Customizing startup::
-* Controlling buffer display::
-
-\1f
-File: ess.info,  Node: Starting up,  Next: Multiple ESS processes,  Up: Interactive ESS
-
-3.1 Starting an ESS process
-===========================
-
-To start an inferior R session on GNU/Linux, macOS, or Windows using the
-Cygwin bash shell, simply type 'M-x R RET'.  To start an R session on
-Windows when you use the MSDOS/powershell shell, simply type 'M-x
-S+6-msdos RET'.  R will then (by default) ask the question
-
-     R starting data directory?
-
-Enter the name of the directory you wish to have as the working
-directory (that is, the directory you wish to have 'getwd()' return if
-using R).
-
-   You will then be popped into a buffer named '*R*' which will be used
-for interacting with the ESS process, and you can start entering
-commands.
-
-\1f
-File: ess.info,  Node: Multiple ESS processes,  Next: ESS processes on Remote Computers,  Prev: Starting up,  Up: Interactive ESS
-
-3.2 Running more than one ESS process
-=====================================
-
-ESS allows you to run more than one iESS process simultaneously in the
-same session.  Each process has a name and a number; the initial process
-(process 1) is simply named 'R'.  If you call 'M-x R' again without
-killing the first R process, ESS will start a second R process with the
-name 'R:2'.  To have the first buffer named 'R:1', customize the option
-'ess-plain-first-buffername'.  With a prefix argument, 'C-u M-x R'
-allows for the specification of command line options.
-
- -- User Option: ess-plain-first-buffername
-     If non-'nil', name the first iESS process [R]. Otherwise, name it
-     [R:1].
-
-   You can switch to any active ESS process with the command 'M-x
-ess-request-a-process'.  Just enter the name of the process you require;
-completion is provided over the names of all running processes.  This is
-a good command to consider binding to a global key.
-
-\1f
-File: ess.info,  Node: ESS processes on Remote Computers,  Next: Customizing startup,  Prev: Multiple ESS processes,  Up: Interactive ESS
-
-3.3 ESS processes on Remote Computers
-=====================================
-
-3.3.1 ESS and TRAMP
--------------------
-
-ESS works with processes on remote computers as easily as with processes
-on the local machine.  The recommended way to access a statistical
-program on remote computer is to start it with *Note (tramp)Top::.
-
-   Start an ssh session using TRAMP with 'C-x C-f /ssh:user@host: RET'.
-Tramp should open a dired buffer in your remote home directory.  Now
-call your favorite ESS process ('R', 'Julia', 'stata' etc) as you would
-usually do on local machine: 'M-x R'.
-
-   Alternatively you can start your process normally ('M-x R').  When
-asked for starting directory, simply type '/ssh:user@host: RET'.  The R
-process will be started on the remote machine.
-
-   To simplify the process even further create a "config" file in your
-'.ssh/' folder and add an account.  For example if you use amazon EC2,
-it might look like following:
-
-   Host amazon
-      Hostname ec2-54-215-203-181.us-west-1.compute.amazonaws.com
-      User ubuntu
-      IdentityFile ~/.ssh/my_amazon_key.pem
-      ForwardX11 yes
-
-   With this configuration '/ssh:amazon:' is enough to start a
-connection.  The ForwardX11 is needed if you want to see the R graphic
-device showing on the current machine
-
-3.3.2 ESS-remote
-----------------
-
-TRAMP is the recommended way of starting a remote session.  The other
-way to start a remote ESS connection is through 'ess-remote'.
-
-  1. Start a new shell, telnet or ssh buffer and connect to the remote
-     computer (e.g.  use, 'M-x shell', 'M-x telnet' or 'M-x ssh'; ssh.el
-     is available at
-     <https://www.splode.com/~friedman/software/emacs-lisp/src/ssh.el>).
-
-  2. Start the ESS process on the remote machine, for example with one
-     of the commands 'R', 'Splus', or 'sas -stdio'.
-
-  3. Start 'M-x ess-remote'.  You will be prompted for a program name
-     with completion.  Choose one.  Your process is now known to ESS.
-     All the usual ESS commands ('C-c C-n' and its relatives) now work
-     with the R language processes.  For SAS you need to use a different
-     command 'C-c i' (that is a regular 'i', not a 'C-i') to send lines
-     from your 'myfile.sas' to the remote SAS process.  'C-c i' sends
-     lines over invisibly.  With ess-remote you get teletype
-     behavior--the data input, the log, and the listing all appear in
-     the same buffer.  To make this work, you need to end every PROC and
-     DATA step with a "RUN;" statement.  The "RUN;" statement is what
-     tells SAS that it should process the preceding input statements.
-
-  4. Graphics (interactive) on the remote machine.  If you run X11
-     (*Note X11::, X Windows) on both the local and remote machines then
-     you should be able to display the graphs locally by setting the
-     'DISPLAY' environment variable appropriately.  Windows users can
-     download 'xfree86' from cygwin.
-
-  5. Graphics (static) on the remote machine.  If you don't run the X
-     window system on the local machine, then you can write graphics to
-     a file on the remote machine, and display the file in a graphics
-     viewer on the local machine.  Most statistical software can write
-     one or more of postscript, GIF, or JPEG files.  Depending on the
-     versions of Emacs and the operating system that you are running,
-     Emacs itself may display '.gif' and '.jpg' files.  Otherwise, a
-     graphics file viewer will be needed.  Ghostscript/ghostview may be
-     downloaded to display '.ps' and '.eps' files.  Viewers for GIF and
-     JPEG are usually included with operating systems.  *Note
-     ESS(SAS)--Function keys for batch processing::, for more
-     information on using the F12 key for displaying graphics files with
-     SAS.
-
-   Should you or a colleague inadvertently start a statistical process
-in an ordinary '*shell*' buffer, the 'ess-remote' command can be used to
-convert it to an ESS buffer and allow you to use the ESS commands with
-it.
-
-\1f
-File: ess.info,  Node: Customizing startup,  Next: Controlling buffer display,  Prev: ESS processes on Remote Computers,  Up: Interactive ESS
-
-3.4 Changing the startup actions
-================================
-
-If you do not wish ESS to prompt for a starting directory when starting
-a new process, set the variable 'ess-ask-for-ess-directory' to 'nil'.
-In this case, the starting directory will be set using one of the
-following methods:
-
-  1. If the variable 'ess-directory-function' stores the name of a
-     function, the value returned by this function is used.  The default
-     for this variable is nil.
-
-  2. Otherwise, if the variable 'ess-directory' stores the name of a
-     directory (ending in a slash), this value is used.  The default for
-     this variable is nil.
-
-  3. Otherwise, the working directory of the current buffer is used.
-
-   If 'ess-ask-for-ess-directory' has a non-'nil' value (as it does by
-default) then the value determined by the above rules provides the
-default when prompting for the starting directory.  Incidentally,
-'ess-directory' is an ideal variable to set in 'ess-pre-run-hook'.
-
-   You may also customize 'ess-post-run-hook' and the dialect-specific
-'ess-*-post-run-hook' variables.  For example, you may want to use
-'ess-load-file' to load a file when ESS starts R:
-
-     (add-hook 'ess-r-post-run-hook (lambda () (ess-load-file "foo.R")))
-
-   If you like to keep a record of your R actions, set the variable
-'ess-ask-about-transfile' to 't', and you will be asked for a filename
-for the transcript before the ESS process starts.
-
- -- User Option: ess-ask-about-transfile
-     If non-'nil', ask for a file name in which to save the session
-     transcript.
-
-   Enter the name of a file in which to save the transcript at the
-prompt.  If the file doesn't exist it will be created (for R, you likely
-want it to end in '.Rout').  If the file already exists the transcript
-will be appended to the file.  (Note: if you don't set this variable but
-you still want to save the transcript, you can still do it later --
-*note Saving transcripts::.)
-
-   Once these questions are answered (if they are asked at all) the
-inferior process itself is started.  If you need to pass any arguments
-to this program, they may be specified in the variable
-'inferior-S_PROGRAM_NAME-args'.  For example, if 'inferior-ess-program'
-is '"R"' then the variable to set is 'inferior-R-args'.  It is not
-normally necessary to pass arguments to the iESS program; in particular
-do not pass the '-e' option to 'Splus', since ESS provides its own
-command history mechanism.
-
-   ESS can set the width option of inferior processes automatically when
-the window configuration changes.  To do so, set 'ess-auto-width' to a
-non-nil value.  By default, the change will not be shown in the inferior
-buffer.  If you want it to be shown, set 'ess-auto-width-visible' to a
-non-nil value.
-
-\1f
-File: ess.info,  Node: Controlling buffer display,  Prev: Customizing startup,  Up: Interactive ESS
-
-3.5 Controlling buffer display
-==============================
-
-Users can control how buffers are displayed by customizing
-'display-buffer-alist', *Note (emacs)Window Choice::.  This section
-provides examples of how to achieve certain setups.
-
-   Users coming from RStudio may want the R process to appear at the
-bottom left of the frame, help buffers to appear at the bottom right,
-and ess-rdired buffers at the top right.  To achieve that, you could
-this.  Note that the order matters; '*R Dired*' would match '*R' if it
-came before in the alist.
-
-     (setq display-buffer-alist
-           `(("^\\*R Dired"
-              (display-buffer-reuse-window display-buffer-in-side-window)
-              (side . right)
-              (slot . -1)
-              (window-width . 0.33)
-              (reusable-frames . nil))
-             ("^\\*R"
-              (display-buffer-reuse-window display-buffer-at-bottom)
-              (window-width . 0.5)
-              (reusable-frames . nil))
-             ("^\\*Help"
-              (display-buffer-reuse-window display-buffer-in-side-window)
-              (side . right)
-              (slot . 1)
-              (window-width . 0.33)
-              (reusable-frames . nil))))
-
-   Some users prefer working with multiple frames where one frame has
-the source code and the other frame has the inferior process.  To
-achieve this, use this example.  For a detailed description of
-'reusable-frames', see *Note (elisp)Buffer Display Action Alists::.
-
-     (setq display-buffer-alist
-           '(("^\\*R"
-              (display-buffer-reuse-window display-buffer-pop-up-frame)
-              (reusable-frames . 0))))
-
-   Some users may want the process window to be dedicated to the process
-so that other buffers are not shown on top of that window.  *Note
-(elisp)Dedicated Windows::.  For example, this prevents help buffers
-from being displayed in the window showing the inferior R process.
-
-     (setq display-buffer-alist
-           '(("^\\*R"
-              nil
-              (dedicated . t))))
-
-   By default, ESS usually prefers splitting the frame into multiple
-windows so that you can work with both the R script and the R REPL
-visible at once.  If you want to override this behavior so that the
-script buffer and the process buffer share the same window, you can do
-so like this:
-
-     (setq display-buffer-alist
-           '(("^\\*R" . ((display-buffer-same-window) (inhibit-same-window . nil)))
-             ("\\.R$" . ((display-buffer-same-window) (inhibit-same-window . nil)))))
-
-\1f
-File: ess.info,  Node: Entering commands,  Next: Evaluating code,  Prev: Interactive ESS,  Up: Top
-
-4 Interacting with the ESS process
-**********************************
-
-The primary function of the ESS package is to provide an easy-to-use
-front end to the R interpreter.  This is achieved by running the R
-process from within an Emacs buffer, called hereafter _inferior_ buffer,
-which has an active 'inferior-ess-mode'.  The features of inferior R
-mode are similar to those provided by the standard Emacs shell mode
-(*note (emacs)Shell Mode::).  Command-line completion of R objects and a
-number of 'hot keys' for commonly-used R commands are also provided for
-ease of typing.
-
-* Menu:
-
-* Command-line editing::        Entering commands and fixing mistakes
-* Transcript::                  Manipulating the transcript
-* Command History::             Command History
-* History expansion::           References to historical commands
-* Hot keys::                    Hot keys for common commands
-* Statistical Process running in ESS?::
-* Emacsclient::                 Using emacsclient
-* Other::                       Other commands provided by inferior-ESS
-
-\1f
-File: ess.info,  Node: Command-line editing,  Next: Transcript,  Up: Entering commands
-
-4.1 Entering commands and fixing mistakes
-=========================================
-
-Sending a command to the ESS process is as simple as typing it in and
-pressing the <RETURN> key:
-
- -- Command: inferior-ess-send-input
-     'RET' Send the command on the current line to the ESS process.
-
-   If you make a typing error before pressing 'RET' all the usual Emacs
-editing commands are available to correct it (*note Basic:
-(emacs)Basic.).  Once the command has been corrected you can press
-<RETURN> (even if the cursor is not at the end of the line) to send the
-corrected command to the ESS process.
-
-   Emacs provides some other commands which are useful for fixing
-mistakes:
-
-'C-c C-w'
-     'backward-kill-word' Deletes the previous word (such as an object
-     name) on the command line.
-
-'C-c C-u'
-     'comint-kill-input' Deletes everything from the prompt to point.
-     Use this to abandon a command you have not yet sent to the ESS
-     process.
-
-'C-a'
-     'comint-bol' Move to the beginning of the line, and then skip
-     forwards past the prompt, if any.
-
-   *Note (emacs)Shell Mode::, for other commands relevant to entering
-input.
-
-\1f
-File: ess.info,  Node: Transcript,  Next: Command History,  Prev: Command-line editing,  Up: Entering commands
-
-4.2 Manipulating the transcript
-===============================
-
-Most of the time, the cursor spends its time at the bottom of the ESS
-process buffer, entering commands.  However all the input and output
-from the current (and previous) ESS sessions is stored in the process
-buffer (we call this the transcript) and often we want to move back up
-through the buffer, to look at the output from previous commands for
-example.
-
-   Within the process buffer, a paragraph is defined as the prompt, the
-command after the prompt, and the output from the command.  Thus 'M-{'
-and 'M-}' move you backwards and forwards, respectively, through
-commands in the transcript.  A particularly useful command is 'M-h'
-('mark-paragraph') which will allow you to mark a command and its entire
-output (for deletion, perhaps).  For more information about paragraph
-commands, *note Paragraphs: (emacs)Paragraphs.
-
-   If an ESS process finishes and you restart it in the same process
-buffer, the output from the new ESS process appears after the output
-from the first ESS process separated by a form-feed ('^L') character.
-Thus pages in the ESS process buffer correspond to ESS sessions.  Thus,
-for example, you may use 'C-x [' and 'C-x ]' to move backward and
-forwards through ESS sessions in a single ESS process buffer.  For more
-information about page commands, *note Pages: (emacs)Pages.
-
-* Menu:
-
-* Last command::                Manipulating the output from the last command
-* Process buffer motion::       Viewing older commands
-* Transcript resubmit::         Re-submitting commands from the transcript
-* Saving transcripts::          Keeping a record of your R session
-
-\1f
-File: ess.info,  Node: Last command,  Next: Process buffer motion,  Up: Transcript
-
-4.2.1 Manipulating the output from the last command
----------------------------------------------------
-
-Viewing the output of the command you have just entered is a common
-occurrence and ESS provides a number of facilities for doing this.
-Whenever a command produces output, it is possible that the window will
-scroll, leaving the next prompt near the middle of the window.  The
-first part of the command output may have scrolled off the top of the
-window, even though the entire output would fit in the window if the
-prompt were near the bottom of the window.  If this happens, you can use
-the following comint commands:
-
-   'comint-show-maximum-output' to move to the end of the buffer, and
-place cursor on bottom line of window to make more of the last output
-visible.  To make this happen automatically for all inputs, set the
-variable 'comint-scroll-to-bottom-on-input' to 't' or ''this'.  If the
-first part of the output is still not visible, use 'C-c C-r'
-('comint-show-output'), which moves cursor to the previous command line
-and places it at the top of the window.
-
-   Finally, if you want to discard the last command output altogether,
-use 'C-c C-o' ('comint-delete-output'), which deletes everything from
-the last command to the current prompt.  Use this command judiciously to
-keep your transcript to a more manageable size.
-
-\1f
-File: ess.info,  Node: Process buffer motion,  Next: Transcript resubmit,  Prev: Last command,  Up: Transcript
-
-4.2.2 Viewing older commands
-----------------------------
-
-If you want to view the output from more historic commands than the
-previous command, commands are also provided to move backwards and
-forwards through previously entered commands in the process buffer:
-
-'C-c C-p'
-     'comint-previous-prompt' Moves point to the preceding prompt in the
-     process buffer.
-
-'C-c C-n'
-     'comint-next-prompt' Moves point to the next prompt in the process
-     buffer.
-
-Note that these two commands are analogous to 'C-p' and 'C-n' but apply
-to command lines rather than text lines.  And just like 'C-p' and 'C-n',
-passing a prefix argument to these commands means to move to the ARG'th
-next (or previous) command.  (These commands are also discussed in *note
-Shell History Copying: (emacs)Shell History Copying.)
-
-   There are also two similar commands (not bound to any keys by
-default) which move to preceding or succeeding commands, but which first
-prompt for a regular expression (*note Syntax of Regular Expression:
-(emacs)Regexps.), and then moves to the next (previous) command matching
-the pattern.
-
-'comint-backward-matching-input regexp arg'
-'comint-forward-matching-input regexp arg'
-     Search backward (forward) through the transcript buffer for the
-     ARG'th previous (next) command matching REGEXP.  ARG is the prefix
-     argument; REGEXP is prompted for in the minibuffer.
-
-\1f
-File: ess.info,  Node: Transcript resubmit,  Next: Saving transcripts,  Prev: Process buffer motion,  Up: Transcript
-
-4.2.3 Re-submitting commands from the transcript
-------------------------------------------------
-
-When moving through the transcript, you may wish to re-execute some of
-the commands you find there.  ESS provides commands to do this; these
-commands may be used whenever the cursor is within a command line in the
-transcript (if the cursor is within some command _output_, an error is
-signaled).  Note all commands involve the <RETURN> key.
-
-'RET'
-     'inferior-ess-send-input' *Note Command-line editing::.
-
-'C-c RET'
-     'comint-copy-old-input' Copy the command under the cursor to the
-     current command line, but don't execute it.  Leaves the cursor on
-     the command line so that the copied command may be edited.
-
-   When the cursor is not after the current prompt, the <RETURN> key has
-a slightly different behavior than usual.  Pressing 'RET' on any line
-containing a command that you entered (i.e.  a line beginning with a
-prompt) sends that command to the ESS process once again.  If you wish
-to edit the command before executing it, use 'C-c RET' instead; it
-copies the command to the current prompt but does not execute it,
-allowing you to edit it before (re)submitting it.
-
-   These commands work even if the current line is a continuation line
-(i.e.  the prompt is '+' instead of '>') -- in this case all the lines
-that form the multi-line command are concatenated together and the
-resulting command is sent to the ESS process (currently this is the only
-way to resubmit a multi-line command to the ESS process in one go).  If
-the current line does not begin with a prompt, an error is signalled.
-This feature, coupled with the command-based motion commands described
-above, could be used as a primitive history mechanism.  ESS provides a
-more sophisticated mechanism, however, which is described in *note
-Command History::.
-
-\1f
-File: ess.info,  Node: Saving transcripts,  Prev: Transcript resubmit,  Up: Transcript
-
-4.2.4 Keeping a record of your R session
-----------------------------------------
-
-To keep a record of your R session in a disk file, use the Emacs command
-'C-x C-w' ('write-file') to attach a file to the ESS process buffer.
-The name of the process buffer will (probably) change to the name of the
-file, but this is not a problem.  You can still use R as usual; just
-remember to save the file before you quit Emacs with 'C-x C-s'.  You can
-make ESS prompt you for a filename in which to save the transcript every
-time you start R by setting the variable 'ess-ask-about-transfile' to
-'t'; *Note Customizing startup::.  For R files, naming transcript files
-'*.Rout' puts them in a special mode (ESS transcript mode -- *note
-Transcript Mode::) for editing transcript files which is automatically
-selected for files with this suffix.
-
-   R transcripts can get very large, so some judicious editing is
-appropriate if you are saving it in a file.  Use 'C-c C-o' whenever a
-command produces excessively long output (printing large arrays, for
-example).  Delete erroneous commands (and the resulting error messages
-or other output) by moving to the command (or its output) and typing
-'M-h C-w'.  Also, remember that 'C-c C-x' (and other hot keys) may be
-used for commands whose output you do not wish to appear in the
-transcript.  These suggestions are appropriate even if you are not
-saving your transcript to disk, since the larger the transcript, the
-more memory your Emacs process will use on the host machine.
-
-   You can use 'ess-transcript-clean-region' to strip output from a
-transcript, leaving only source code suitable for inclusion in files
-'source()'-able from R. *note Transcript Mode: Clean.
-
-\1f
-File: ess.info,  Node: Command History,  Next: History expansion,  Prev: Transcript,  Up: Entering commands
-
-4.3 Command History
-===================
-
-ESS provides easy-to-use facilities for re-executing or editing previous
-commands.  An input history of the last few commands is maintained (by
-default the last 500 commands are stored, although this can be changed
-by setting the variable 'comint-input-ring-size' in
-'inferior-ess-mode-hook'.)  The simplest history commands simply select
-the next and previous commands in the input history:
-
-'M-p'
-     'comint-previous-input' Select the previous command in the input
-     history.
-
-'M-n'
-     'comint-next-input' Select the next command in the input history.
-
-For example, pressing 'M-p' once will re-enter the last command into the
-process buffer after the prompt but does not send it to the ESS process,
-thus allowing editing or correction of the command before the ESS
-process sees it.  Once corrections have been made, press 'RET' to send
-the edited command to the ESS process.
-
-   If you want to select a particular command from the history by
-matching it against a regular expression (*note Syntax of Regular
-Expression: (emacs)Regexps.), to search for a particular variable name
-for example, these commands are also available:
-
-'M-r'
-     'comint-history-isearch-backward-regexp' Prompt for a regular
-     expression, and search backwards through the input history for a
-     command matching the expression.
-
-A common type of search is to find the last command that began with a
-particular sequence of characters; the following two commands provide an
-easy way to do this:
-
-'C-c M-r'
-     'comint-previous-matching-input-from-input' Select the previous
-     command in the history which matches the string typed so far.
-
-'C-c M-s'
-     'comint-next-matching-input-from-input' Select the next command in
-     the history which matches the string typed so far.
-
-Instead of prompting for a regular expression to match against, as they
-instead select commands starting with those characters already entered.
-For instance, if you wanted to re-execute the last 'attach()' command,
-you may only need to type 'att' and then 'C-c M-r' and 'RET'.
-
-   *Note Shell History Ring: (emacs)Shell Ring, for a more detailed
-discussion of the history mechanism, and do experiment with the 'In/Out'
-menu to explore the possibilities.
-
-   Many ESS users like to have even easier access to these, and
-recommend adding something like
-       (eval-after-load "comint"
-        '(progn
-           (define-key comint-mode-map [up]
-             'comint-previous-matching-input-from-input)
-           (define-key comint-mode-map [down]
-             'comint-next-matching-input-from-input)
-
-           ;; also recommended for ESS use --
-           (setq comint-move-point-for-output 'others)
-           ;; somewhat extreme, almost disabling writing in *R*, *shell* buffers above prompt:
-           (setq comint-scroll-to-bottom-on-input 'this)
-           ))
-   to your Emacs configuration file, where the last two settings are
-typically desirable for the situation where you work with a script (for
-example, 'code.R') and send code chunks to the process buffer (e.g.
-'*R*').  Note however that these settings influence all 'comint'-using
-Emacs modes, not just the ESS ones, and for that reason, these
-customization cannot be part of 'ESS' itself.
-
-* Menu:
-
-* Saving History::
-
-\1f
-File: ess.info,  Node: Saving History,  Up: Command History
-
-4.3.1 Saving the command history
---------------------------------
-
-The 'ess-history-file' variable, which is 't' by default, together with
-'ess-history-directory', governs if and where the command history is
-saved and restored between sessions.  By default,
-'ess-history-directory' is 'nil', and the command history will be stored
-(as a file) in the same directory as the iESS process.
-
-   ESS users may work exclusively with script files rather than in a
-iESS session, and may not want to save any history files.  To do so:
-
-       (setq ess-history-file nil)
-
-or if you prefer only one global command history file:
-
-       (setq ess-history-directory "~/.R/")
-
-in your Emacs configuration file.
-
-\1f
-File: ess.info,  Node: History expansion,  Next: Hot keys,  Prev: Command History,  Up: Entering commands
-
-4.4 References to historical commands
-=====================================
-
-Instead of searching through the command history using the command
-described in the previous section, you can alternatively refer to a
-historical command directly using a notation very similar to that used
-in 'csh'.  History references are introduced by a '!' or '^' character
-and have meanings as follows:
-
-'!!'
-     The immediately previous command
-
-'!-N'
-     The Nth previous command
-
-'!text'
-     The last command beginning with the string 'text'
-
-'!?text'
-     The last command containing the string 'text'
-
-   In addition, you may follow the reference with a "word designator" to
-select particular "words" of the input.  A word is defined as a sequence
-of characters separated by whitespace.  (You can modify this definition
-by setting the value of 'comint-delimiter-argument-list' to a list of
-characters that are allowed to separate words and themselves form
-words.)  Words are numbered beginning with zero.  The word designator
-usually begins with a ':' (colon) character; however it may be omitted
-if the word reference begins with a '^', '$', '*' or '-'.  If the word
-is to be selected from the previous command, the second '!' character
-can be omitted from the event specification.  For instance, '!!:1' and
-'!:1' both refer to the first word of the previous command, while '!!$'
-and '!$' both refer to the last word in the previous command.  The
-format of word designators is as follows:
-
-'0'
-     The zeroth word (i.e.  the first one on the command line)
-
-'N'
-     The Nth word, where N is a number
-
-'^'
-     The first word (i.e.  the second one on the command line)
-
-'$'
-     The last word
-
-'X-Y'
-     A range of words; '-Y' abbreviates '0-Y'
-
-'*'
-     All the words except the zeroth word, or nothing if the command had
-     just one word (the zeroth)
-
-'X*'
-     Abbreviates X-$
-
-'X-'
-     Like 'X*', but omitting the last word
-
-   In addition, you may surround the entire reference except for the
-first '!' by braces to allow it to be followed by other (non-whitespace)
-characters (which will be appended to the expanded reference).
-
-   Finally, ESS also provides quick substitution; a reference like
-'^old^new^' means "the last command, but with the first occurrence of
-the string 'old' replaced with the string 'new'" (the last '^' is
-optional).  Similarly, '^old^' means "the last command, with the first
-occurrence of the string 'old' deleted" (again, the last '^' is
-optional).
-
-   To convert a history reference as described above to an input
-suitable for R, you need to "expand" the history reference, using the
-<TAB> key.  For this to work, the cursor must be preceded by a space
-(otherwise it would try to complete an object name) and not be within a
-string (otherwise it would try to complete a filename).  So to expand
-the history reference, type 'SPC TAB'.  This will convert the history
-reference into an R command from the history, which you can then edit or
-press <RET> to execute.
-
-   For example, to execute the last command that referenced the variable
-'data', type '!?data SPC TAB RET'.
-
-\1f
-File: ess.info,  Node: Hot keys,  Next: Statistical Process running in ESS?,  Prev: History expansion,  Up: Entering commands
-
-4.5 Hot keys for common commands
-================================
-
-ESS provides a number of commands for executing the commonly used
-functions.  These commands below are basically information-gaining
-commands (such as 'objects()' or 'search()') which tend to clutter up
-your transcript and for this reason some of the hot keys display their
-output in a temporary buffer instead of the process buffer by default.
-This behavior is controlled by the following option:
-
- -- User Option: ess-execute-in-process-buffer
-     If non-'nil', means that these commands will produce their output
-     in the process buffer instead.
-
-   In any case, passing a prefix argument to the commands (with 'C-u')
-will reverse the meaning of 'ess-execute-in-process-buffer' for that
-command.  In other words, the output will be displayed in the process
-buffer if it usually goes to a temporary buffer, and vice-versa.  These
-are the hot keys that behave in this way:
-
- -- Command: ess-execute-objects POSN
-     'C-c C-x' Sends the 'objects()' command to the ESS process.  A
-     prefix argument specifies the position on the search list (use a
-     negative argument to toggle 'ess-execute-in-process-buffer' as
-     well).  This is a quick way to see what objects are in your working
-     directory.  A prefix argument of 2 or more means get objects for
-     that position.  A negative prefix argument POSN gets the objects
-     for that position, as well as toggling
-     'ess-execute-in-process-buffer'.
-
- -- Command: ess-execute-search INVERT
-     'C-c C-s' Sends the 'inferior-ess-search-list-command' command to
-     the 'ess-language' process; 'search()' in R. Prefix INVERT toggles
-     'ess-execute-in-process-buffer'.
-
-   'ess-execute' may seem pointless when you could just type the command
-in anyway, but it proves useful for 'spot' calculations which would
-otherwise clutter your transcript, or for evaluating an expression while
-partway through entering a command.  You can also use this command to
-generate new hot keys using the Emacs keyboard macro facilities; *note
-Keyboard Macros: (emacs)Keyboard Macros.
-
-   The following hot keys do not use 'ess-execute-in-process-buffer' to
-decide where to display the output -- they either always display in the
-process buffer or in a separate buffer, as indicated:
-
- -- Command: ess-load-file FILENAME
-     'C-c M-l' Prompts for a file (FILENAME) to load into the ESS
-     process using 'source()'.  If there is an error during loading, you
-     can jump to the error in the file with the following function.
-
- -- Command: ess-parse-errors ARG RESET
-     Visits next 'next-error' message and corresponding source code.  If
-     all the error messages parsed so far have been processed already,
-     the message buffer is checked for new ones.  A prefix ARG specifies
-     how many error messages to move; negative means move back to
-     previous error messages.  Just 'C-u' as a prefix means reparse the
-     error message buffer and start at the first error.  The RESET
-     argument specifies restarting from the beginning.
-
-     *Note Error Checking::, for more details.
-
- -- Command: ess-display-help-on-object OBJECT COMMAND
-     'C-c C-v' Pops up a help buffer for an R object or function.  If
-     COMMAND is supplied, it is used instead of
-     'inferior-ess-help-command'.  See *note Help:: for more details.
-
- -- Command: ess-quit
-     'C-c C-q' Issue an exiting command to the inferior process,
-     additionally also running 'ess-cleanup' for disposing of any
-     temporary buffers (such as help buffers and edit buffers) that may
-     have been created.  Use this command when you have finished your R
-     session instead of simply quitting at the inferior process prompt,
-     otherwise you will need to issue the command 'ess-cleanup'
-     explicitly to make sure that all the files that need to be saved
-     have been saved, and that all the temporary buffers have been
-     killed.
-
-\1f
-File: ess.info,  Node: Statistical Process running in ESS?,  Next: Emacsclient,  Prev: Hot keys,  Up: Entering commands
-
-4.6 Is the Statistical Process running under ESS?
-=================================================
-
-For the R languages (R, S, S-Plus) ESS sets an option in the current
-process that programs in the language can check to determine the
-environment in which they are currently running.
-
-   ESS sets 'options(STERM="iESS")' for R language processes running in
-an inferior 'iESS[S]' or 'iESS[R]' buffer.
-
-   ESS sets 'options(STERM="ddeESS")' for independent S-Plus for Windows
-processes running in the GUI and communicating with ESS via the DDE
-(Microsoft Dynamic Data Exchange) protocol through a 'ddeESS[S]' buffer.
-
-   Other values of 'options()$STERM' that we recommend are:
-
-   * 'length': Fixed length xterm or telnet window.
-   * 'scrollable': Unlimited length xterm or telnet window.
-   * 'server': S-Plus Stat Server.
-   * 'BATCH': BATCH.
-   * 'Rgui': R GUI.
-   * 'Commands': S-Plus GUI without DDE interface to ESS.
-
-   Additional values may be recommended in the future as new interaction
-protocols are created.  Unlike the values 'iESS' and 'ddeESS', ESS can't
-set these other values since the R language program is not under the
-control of ESS.
-
-\1f
-File: ess.info,  Node: Emacsclient,  Next: Other,  Prev: Statistical Process running in ESS?,  Up: Entering commands
-
-4.7 Using emacsclient
-=====================
-
-When starting R or S under Unix, ESS sets
-'options(editor="emacsclient")'.  Under Microsoft Windows, it will use
-gnuclient.exe rather than emacsclient, but the same principal applies.
-Within your R session, if you have a function called 'iterator', typing
-'fix(iterator)', will show that function in a temporary Emacs buffer.
-You can then correct the function.  When you kill the buffer, the
-definition of the function is updated.  Using 'edit()' rather than
-'fix()' means that the function is not updated.  Finally, the R function
-'page(x)' will also show a text representation of the object 'x' in a
-temporary Emacs buffer.
-
-\1f
-File: ess.info,  Node: Other,  Prev: Emacsclient,  Up: Entering commands
-
-4.8 Other commands provided by inferior-ESS
-===========================================
-
-The following commands are also available in the process buffer:
-
- -- Command: comint-interrupt-subjob
-     'C-c C-c' Sends a Control-C signal to the iESS process.  This has
-     the effect of aborting the current command.
-
- -- Command: ess-switch-to-inferior-or-script-buffer TOGGLE-EOB
-     'C-c C-z' When in process buffer, return to the most recent script
-     buffer.  When in a script buffer pop to the associated process
-     buffer.  Consecutive presses of 'C-z' switch between the script and
-     process buffers.
-
-     If TOGGLE-EOB is given, the value of
-     'ess-switch-to-end-of-proc-buffer' is toggled.
-
- -- User Option: ess-switch-to-end-of-proc-buffer
-     If non-'nil', 'ess-switch-to-inferior-or-script-buffer' goes to end
-     of process buffer.
-
-   Other commands available in iESS modes are discussed in *note
-(emacs)Shell Mode::.
-
-\1f
-File: ess.info,  Node: Evaluating code,  Next: Transcript Mode,  Prev: Entering commands,  Up: Top
-
-5 Sending code to the ESS process
-*********************************
-
-Other commands are also available for evaluating portions of code in the
-R process.  These commands cause the selected code to be evaluated
-directly by the ESS process as if you had typed them in at the command
-line; the 'source()' function is not used.  You may choose whether both
-the commands and their output appear in the process buffer (as if you
-had typed in the commands yourself) or if the output alone is echoed.
-The behavior is controlled by the variable:
-
- -- User Option: ess-eval-visibly
-     Non-'nil' means 'ess-eval-*' commands display commands and output
-     in the process buffer.  A value of 't' blocks Emacs while R is
-     busy.  A value of 'nowait' does not block Emacs but printing may be
-     slightly off.
-
-   Passing a prefix ('C-u') (in Elisp terms, the argument VIS) to any of
-the following commands, however, reverses the meaning of
-'ess-eval-visibly' for that command only -- for example 'C-u C-c C-j'
-evaluates the current line without showing the input in the iESS buffer.
-The default value of 'ess-eval-visibly' ('t') means that ESS calls block
-Emacs until they finish.  This may be undesirable, especially if
-commands take long to finish.  Users who want input to be displayed and
-Emacs not to be blocked can set 'ess-eval-visibly' to ''nowait'.  This
-sends the input to the iESS buffer but does not wait for the process to
-finish, ensuring Emacs is not blocked.
-
-   Primary commands for evaluating code are:
-
- -- Command: ess-eval-region-or-line-and-step VIS
-     'C-<RET>' Sends the highlighted region or current line and step to
-     next line of code.
-
- -- Command: ess-eval-region-or-function-or-paragraph VIS
-     'C-M-x' Sends the current selected region or function or paragraph.
-
- -- Command: ess-eval-region-or-function-or-paragraph-and-step VIS
-     'C-c C-c' Like 'ess-eval-region-or-function-or-paragraph' but steps
-     to next line of code.
-
-   Other, not so often used, evaluation commands are:
-
- -- Command: ess-eval-line VIS
-     'C-c C-j' Sends the current line to the ESS process.
-
- -- Command: ess-eval-line-and-go VIS
-     'C-c M-j' Like 'ess-eval-line' but additionally switches point to
-     the ESS process.
-
- -- Command: ess-eval-function VIS NO-ERROR
-     'C-c C-f' Sends the function containing point to the ESS process.
-
- -- Command: ess-eval-function-and-go VIS
-     'C-c M-f' Like 'ess-eval-function' but additionally switches point
-     to the ESS process.
-
- -- Command: ess-eval-region START END TOGGLE MESSAGE
-     'C-c C-r' Sends the current region to the ESS process.
-
- -- Command: ess-eval-region-and-go START END VIS
-     'C-c M-r' Like 'ess-eval-region' but additionally switches point to
-     the ESS process.
-
- -- Command: ess-eval-buffer VIS
-     'C-c C-b' Sends the current buffer to the ESS process.
-
- -- Command: ess-eval-buffer-and-go VIS
-     'C-c M-b' Like 'ess-eval-buffer' but additionally switches point to
-     the ESS process.
-
-   All the above 'ess-eval-*' commands are useful for evaluating small
-amounts of code and observing the results in the process buffer for
-debugging purposes, or for generating transcripts from source files.
-When editing R functions, it is generally preferable to use 'C-c C-l' to
-update the function's value.  In particular, 'ess-eval-buffer' is now
-largely obsolete.
-
-   A useful way to work is to divide the frame into two windows; one
-containing the source code and the other containing the process buffer.
-If you wish to make the process buffer scroll automatically when the
-output reaches the bottom of the window, you will need to set the
-variable 'comint-move-point-for-output' to ''others' or 't'.
-
-\1f
-File: ess.info,  Node: Transcript Mode,  Next: Editing objects,  Prev: Evaluating code,  Up: Top
-
-6 Manipulating saved transcript files
-*************************************
-
-Inferior R mode records the transcript (the list of all commands
-executed, and their output) in the process buffer, which can be saved as
-a "transcript file", which should normally have the suffix '.Rout'.  The
-most obvious use for a transcript file is as a static record of the
-actions you have performed in a particular R session.  Sometimes,
-however, you may wish to re-execute commands recorded in the transcript
-file by submitting them to a running ESS process.  This is what
-Transcript Mode is for.
-
-   If you load file a with the suffix '.Rout' into Emacs, it is placed
-in R Transcript Mode.  Transcript Mode is similar to inferior R mode
-(*note Entering commands::): paragraphs are defined as a command and its
-output, and you can move though commands either with the paragraph
-commands or with 'C-c C-p' and 'C-c C-n'.
-
-* Menu:
-
-* Resubmit::                    Resubmitting commands from the transcript file
-* Clean::                       Cleaning transcript files
-
-\1f
-File: ess.info,  Node: Resubmit,  Next: Clean,  Up: Transcript Mode
-
-6.1 Resubmitting commands from the transcript file
-==================================================
-
-Three commands are provided to re-submit command lines from the
-transcript file to a running ESS process.  They are:
-
- -- Command: ess-transcript-send-command
-     'M-RET' Sends the current command line to the ESS process, and
-     execute it.
-
- -- Command: ess-transcript-copy-command
-     'C-c RET' Copy the current command to the ESS process, and switch
-     to it (ready to edit the copied command).
-
- -- Command: ess-transcript-send-command-and-move
-     'RET' Sends the current command to the ESS process, and move to the
-     next command line.  This command is useful for submitting a series
-     of commands.
-
-Note that the first two commands are similar to those on the same keys
-in inferior R Mode.  In all three cases, the commands should be executed
-when the cursor is on a command line in the transcript; the prompt is
-automatically removed before the command is submitted.
-
-\1f
-File: ess.info,  Node: Clean,  Prev: Resubmit,  Up: Transcript Mode
-
-6.2 Cleaning transcript files
-=============================
-
-Yet another use for transcript files is to extract the command lines for
-inclusion in an R source file or function.  Transcript mode provides one
-command which does just this:
-
- -- Command: ess-transcript-clean-region BEG END EVEN-IF-READ-ONLY
-     'C-c C-w' Strip the transcript in the region (given by BEG and
-     END), leaving only commands.  Deletes any lines not beginning with
-     a prompt, and then removes the prompt from those lines that remain.
-     Prefix argument EVEN-IF-READ-ONLY means to clean even if the buffer
-     is read-only.  Don't forget to remove any erroneous commands first!
-
-The remaining command lines may then be copied to a source file or edit
-buffer for inclusion in a function definition, or may be evaluated
-directly (*note Evaluating code::) using the code evaluation commands
-from R mode, also available in R Transcript Mode.
-
-\1f
-File: ess.info,  Node: Editing objects,  Next: Help,  Prev: Transcript Mode,  Up: Top
-
-7 Editing objects and functions
-*******************************
-
-ESS provides facilities for editing R objects within your Emacs session.
-Most editing is performed on R functions, although in theory you may
-edit datasets as well.  Edit buffers are always associated with files,
-although you may choose to make these files temporary if you wish.
-Alternatively, you may make use of a simple yet powerful mechanism for
-maintaining backups of text representations of R functions.
-Error-checking is performed when R code is loaded into the ESS process.
-
-* Menu:
-
-* Edit buffer::                 Edit objects in a specialized buffer
-* Loading::                     Loading source files into the ESS process
-* Error Checking::              Detecting errors in source files
-* Indenting::                   Indenting and formatting S code
-* Other edit buffer commands::  Commands for motion, completion and more
-* Source Files::                Maintaining R source files
-* Source Directories::          Names and locations of dump files
-
-\1f
-File: ess.info,  Node: Edit buffer,  Next: Loading,  Up: Editing objects
-
-7.1 Creating or modifying R objects
-===================================
-
-To edit an object, type
-
- -- Command: ess-dump-object-into-edit-buffer OBJECT
-     'C-c C-e C-d' Edit an object in its own edit buffer.
-
-   from within the iESS process buffer ('*R*').  You will then be
-prompted for an object to edit: you may either type in the name of an
-existing object (for which completion is available using the 'TAB' key),
-or you may enter the name of a new object.  A buffer will be created
-containing the text representation of the requested object or, if you
-entered the name of a non-existent object at the prompt and the variable
-'ess-function-template' is non-'nil', you will be presented with a
-template defined by that variable, which defaults to a skeleton function
-construct.
-
-   You may then edit the function as required.  The edit buffer
-generated by 'ess-dump-object-into-edit-buffer' is placed in the 'ESS'
-major mode which provides a number of commands to facilitate editing R
-source code.  Commands are provided to intelligently indent R code,
-evaluate portions of R code and to move around R code constructs.
-
-   Note: when you dump a file with 'C-c C-e C-d', ESS first checks to
-see whether there already exists an edit buffer containing that object
-and, if so, pops you directly to that buffer.  If not, ESS next checks
-whether there is a file in the appropriate place with the appropriate
-name (*note Source Files::) and if so, reads in that file.  You can use
-this facility to return to an object you were editing in a previous
-session (and which possibly was never loaded to the R session).
-Finally, if both these tests fail, the ESS process is consulted and a
-'dump()' command issued.  If you want to force ESS to ask the ESS
-process for the object's definition (say, to reformat an unmodified
-buffer or to revert back to R's idea of the object's definition) pass a
-prefix argument to 'ess-dump-object-into-edit-buffer' by typing 'C-u C-c
-C-e C-d'.
-
-\1f
-File: ess.info,  Node: Loading,  Next: Error Checking,  Prev: Edit buffer,  Up: Editing objects
-
-7.2 Loading source files into the ESS process
-=============================================
-
-The best way to get information -- particularly function definitions --
-into R is to load them in as source file, using R's 'source' function.
-You have already seen how to create source files using 'C-c C-e C-d';
-ESS provides a complementary command for loading source files (even
-files not created with ESS!) into the ESS process, namely
-'ess-load-file' ('C-c M-l').  *note Hot keys::.
-
-After typing 'C-c M-l' you will prompt for the name of the file to load
-into R; usually this is the current buffer's file which is the default
-value (selected by simply pressing 'RET' at the prompt).  You will be
-asked to save the buffer first if it has been modified (this happens
-automatically if the buffer was generated with 'C-c C-e C-d').  The file
-will then be loaded, and if it loads successfully you will be returned
-to the ESS process.
-
-\1f
-File: ess.info,  Node: Error Checking,  Next: Indenting,  Prev: Loading,  Up: Editing objects
-
-7.3 Detecting errors in source files
-====================================
-
-If any errors occur when loading a file with 'C-c C-l', ESS will inform
-you of this fact.  In this case, you can jump directly to the line in
-the source file which caused the error by typing 'C-c `'
-('ess-parse-errors').  You will be returned to the offending file
-(loading it into a buffer if necessary) with point at the line S
-reported as containing the error.  You may then correct the error, and
-reload the file.  Note that none of the commands in an R source file
-will take effect if any part of the file contains errors.
-
-   Sometimes the error is not caused by a syntax error (loading a
-non-existent file for example).  In this case typing 'C-c `' will simply
-display a buffer containing S's error message.  You can force this
-behavior (and avoid jumping to the file when there _is_ a syntax error)
-by passing a prefix argument to 'ess-parse-errors' with 'C-u C-c `'.
-
-\1f
-File: ess.info,  Node: Indenting,  Next: Other edit buffer commands,  Prev: Error Checking,  Up: Editing objects
-
-7.4 Indenting and formatting R code
-===================================
-
-ESS provides a sophisticated mechanism for indenting R source code.
-Compound statements (delimited by '{' and '}') are indented relative to
-their enclosing block.  In addition, the braces have been electrified to
-automatically indent to the correct position when inserted, and
-optionally insert a newline at the appropriate place as well.  Lines
-which continue an incomplete expression are indented relative to the
-first line of the expression.  Function definitions, 'if' statements,
-calls to 'expression()' and loop constructs are all recognized and
-indented appropriately.  User variables are provided to control the
-amount of indentation in each case, and there are also a number of
-predefined indentation styles to choose from.
-
-   Comments are also handled specially by ESS, using an idea borrowed
-from the Emacs-Lisp indentation style.  By default, comments beginning
-with '###' are aligned to the beginning of the line.  Comments beginning
-with '##' are aligned to the current level of indentation for the block
-containing the comment.  Finally, comments beginning with '#' are
-aligned to a column on the right (the 40th column by default, but this
-value is controlled by the variable 'comment-column',) or just after the
-expression on the line containing the comment if it extends beyond the
-indentation column.  You turn off the default behavior by adding the
-line '(setq ess-indent-with-fancy-comments nil)' to your '.emacs' file.
-
-   ESS also supports roxygen2 entries which is R documentation
-maintained in the source code as comments *Note roxygen2::.
-
-   The indentation commands provided by ESS are:
-
- -- Command: ess-indent-or-complete
-     'TAB' Indents the current line as R code.
-
-     Try to indent first, and if code is already properly indented,
-     complete instead.  In ess-mode, only tries completion if
-     'tab-always-indent' is ''complete'.  See also
-     'ess-first-tab-never-complete'.
-
- -- User Option: ess-first-tab-never-complete
-     If non-'nil', 'TAB' never tries to complete in ess-mode.  The
-     default ''symbol' does not try to complete if the next char is a
-     valid symbol constituent.  There are more options, see the help
-     ('C-h v').
-
- -- Command: ess-indent-exp
-     'TAB' Indents each line in the R (compound) expression which
-     follows point.  Very useful for beautifying your R code.
-
- -- Command: ess-electric-brace
-     '{' '}' The braces automatically indent to the correct position
-     when typed.
-
-   The following Emacs command are also helpful:
-
-'RET'
-'LFD'
-     'newline-and-indent' Insert a newline, and indent the next line.
-     (Note that most keyboards nowadays do not have a <LINEFEED> key,
-     but <RET> and 'C-j' are equivalent.)
-
-'M-;'
-     'indent-dwim' Call the comment command you want (Do What I Mean).
-
-* Menu:
-
-* Styles:: Changing styles for indentation and alignment
-
-\1f
-File: ess.info,  Node: Styles,  Up: Indenting
-
-7.4.1 Changing styles for code indentation and alignment
---------------------------------------------------------
-
-The combined value of twelve variables (4 of three groups
-'ess-indent-*', 'ess-offset-*' and 'ess-align-*') that control
-indentation are collectively termed a style.  ESS provides several
-styles covering the common styles of indentation: 'DEFAULT', 'OWN',
-'GNU', 'BSD', 'K&R', 'C++', 'RRR', 'RRR+', 'Rstudio', 'Rstudio-', and
-'CLB'.  The variable 'ess-style-alist' lists the value of each
-indentation variable per style (and its documentation contains more).
-
- -- Command: ess-set-style
-     'C-c C-e C-s' (or 'C-c C-e s') sets the formatting style in this
-     buffer to be one of the predefined styles, see above.  The
-     'DEFAULT' style uses the default values for the indenting
-     variables; The 'OWN' style allows you to use your own private
-     values of the indentation variable, see below.
-
- -- User Option: ess-style
-     The style to use.  See the variable 'ess-style-alist' for how these
-     groups (DEFAULT, OWN, GNU, RRR, ...) map onto different settings
-     for variables.  You can set this in your Emacs configuration file:
-
-          (setq ess-style 'C++)
-
- -- User Option: ess-style-alist
-     Predefined formatting styles for ESS code.  Values for all groups,
-     except OWN, are fixed.  To change the value of variables in the OWN
-     group, customize the variable 'ess-own-style-list'.  The default
-     style in use is controlled by 'ess-style'.
-
-   The styles 'DEFAULT' and 'OWN' are initially identical.  If you wish
-to edit some of the default values, set 'ess-style' to ''OWN' and change
-'ess-own-style-list'.  *Note Customization::, for convenient ways to set
-both these variables.
-
-   If you prefer not to use the customization facility, you can change
-individual indentation variables within a hook, for example:
-
-     (defun myindent-ess-hook ()
-       (setq ess-indent-level 4))
-     (add-hook 'ess-mode-hook 'myindent-ess-hook)
-
-   In the rare case that you'd like to add an entire new indentation
-style of your own, copy the definition of 'ess-own-style-list' to a new
-variable and ensure that the last line of the ':set' declaration calls
-'ess-add-style' with a unique name for your style (e.g.  ''MINE').
-Finally, add '(setq ess-style 'MINE)' to use your new style.
-
-\1f
-File: ess.info,  Node: Other edit buffer commands,  Next: Source Files,  Prev: Indenting,  Up: Editing objects
-
-7.5 Commands for motion, completion and more
-============================================
-
-A number of commands are provided to move across function definitions in
-the edit buffer:
-
- -- Command: ess-goto-beginning-of-function-or-para
-     'ESC C-a' aka 'C-M-a' If inside a function go to the beginning of
-     it, otherwise go to the beginning of paragraph.
-
- -- Command: ess-goto-end-of-function-or-para
-     'ESC C-e' aka 'C-M-e' Move point to the end of the function
-     containing point.
-
- -- Command: ess-mark-function
-     'ESC C-h' aka 'C-M-h' Place point at the beginning of the R
-     function containing point, and mark at the end.
-
-Don't forget the usual Emacs commands for moving over balanced
-expressions and parentheses: *Note Lists and Sexps: (Emacs)Lists.
-
-   Completion is provided in the edit buffer in a similar fashion to the
-process buffer: <TAB> first indents, and if there is nothing to indent,
-completes the object or file name; 'M-?' lists file completions.  See
-*Note Completion::, for more.
-
-   Finally, 'C-c C-z' ('ess-switch-to-inferior-or-script-buffer')
-returns you to the 'iESS' process buffer, if done from a script buffer,
-placing point at the end of the buffer.  If this is done from the 'iESS'
-process buffer, point is taken to the script buffer.
-
-   In addition many commands available in the process buffer are also
-available in the script buffer.  You can still read help files with 'C-c
-C-v', edit another function with 'C-c C-e C-d' and of course 'C-c C-l'
-can be used to load a source file into R.
-
-\1f
-File: ess.info,  Node: Source Files,  Next: Source Directories,  Prev: Other edit buffer commands,  Up: Editing objects
-
-7.6 Maintaining R source files
-==============================
-
-Every edit buffer in ESS is associated with a "dump file" on disk.  Dump
-files are created whenever you type 'C-c C-e C-d'
-('ess-dump-object-into-edit-buffer'), and may either be deleted after
-use, or kept as a backup file or as a means of keeping several versions
-of an R function.
-
- -- User Option: ess-delete-dump-files
-     If non-'nil', dump files created with C-c C-e C-d are deleted
-     immediately after they are created by the ess-process.
-
-   Since immediately after R dumps an object's definition to a disk file
-the source code on disk corresponds exactly to R's idea of the object's
-definition, the disk file isn't needed; deleting it now has the
-advantage that if you _don't_ modify the file (say, because you just
-wanted to look at the definition of one of the standard R functions) the
-source dump file won't be left around when you kill the buffer.  Note
-that this variable only applies to files generated with R's 'dump'
-function; it doesn't apply to source files which already exist.  The
-default value is 't'.
-
- -- User Option: ess-keep-dump-files
-     Variable controlling whether to delete dump files after a
-     successful load.  If 'nil': always delete.  If 'ask', confirm to
-     delete.  If 'check', confirm to delete, except for files created
-     with 'ess-dump-object-into-edit-buffer'.  Anything else, never
-     delete.  This variable only affects the behaviour of
-     'ess-load-file'.  Dump files are never deleted if an error occurs
-     during the load.
-
-   After an object has been successfully (without error) loaded back
-into R with 'C-c C-l', the disk file again corresponds exactly (well,
-almost -- see below) to R's record of the object's definition, and so
-some people prefer to delete the disk file rather than unnecessarily use
-up space.  This option allows you to do just that.
-
-   If the value of 'ess-keep-dump-files' is 't', dump files are never
-deleted after they are loaded.  Thus you can maintain a complete text
-record of the functions you have edited within ESS. Backup files are
-kept as usual, and so by using the Emacs numbered backup facility --
-*note Single or Numbered Backups: (emacs)Backup Names, you can keep a
-historic record of function definitions.  Another possibility is to
-maintain the files with a version-control system such as git *Note
-Version Control: (emacs)Version Control.  As long as a dump file exists
-in the appropriate place for a particular object, editing that object
-with 'C-c C-e C-d' finds that file for editing (unless a prefix argument
-is given) -- the ESS process is not consulted.  Thus you can keep
-comments _outside_ the function definition as a means of documentation
-that does not clutter the R object itself.  Another useful feature is
-that you may format the code in any fashion you please without R
-re-indenting the code every time you edit it.  These features are
-particularly useful for project-based work.
-
-   If the value of 'ess-keep-dump-files' is nil, the dump file is always
-silently deleted after a successful load with 'C-c C-l'.  While this is
-useful for files that were created with 'C-c C-e C-d' it also applies to
-any other file you load (say, a source file of function definitions),
-and so can be dangerous to use unless you are careful.  Note that since
-'ess-keep-dump-files' is buffer-local, you can make sure particular
-files are not deleted by setting it to 't' in the Local Variables
-section of the file *Note Local Variables in Files: (emacs)File
-Variables.
-
-   A safer option is to set 'ess-keep-dump-files' to 'ask'; this means
-that ESS will always ask for confirmation before deleting the file.
-Since this can get annoying if you always want to delete dump files
-created with 'C-c C-e C-d', but not any other files, setting
-'ess-keep-dump-files' to 'check' (the default value) will silently
-delete dump files created with 'C-c C-e C-d' in the current Emacs
-session, but query for any other file.  Note that in any case you will
-only be asked for confirmation once per file, and your answer is
-remembered for the rest of the Emacs session.
-
-   Note that in all cases, if an error (such as a syntax error) is
-detected while loading the file with 'C-c C-l', the dump file is _never_
-deleted.  This is so that you can edit the file in a new Emacs session
-if you happen to quit Emacs before correcting the error.
-
-   Dump buffers are always autosaved, regardless of the value of
-'ess-keep-dump-files'.
-
-\1f
-File: ess.info,  Node: Source Directories,  Prev: Source Files,  Up: Editing objects
-
-7.7 Names and locations of dump files
-=====================================
-
-Every dump file should be given a unique file name, usually the dumped
-object name with some additions.
-
- -- User Option: ess-dump-filename-template
-     Template for filenames of dumped objects.  '%s' is replaced by the
-     object name.
-
-By default, dump file names are the user name, followed by '.' and the
-object and ending with '.R'.  Thus if user 'joe' dumps the object
-'myfun' the dump file will have name 'joe.myfun.R'.  The username part
-is included to avoid clashes when dumping into a publicly-writable
-directory, such as '/tmp'; you may wish to remove this part if you are
-dumping into a directory owned by you.
-
-   You may also specify the directory in which dump files are written:
-
- -- User Option: ess-source-directory
-     Directory name (ending in a slash) where R dump files are to be
-     written.
-
-   By default, dump files are always written to '/tmp', which is fine
-when 'ess-keep-dump-files' is 'nil'.  If you are keeping dump files,
-then you will probably want to keep them somewhere in your home
-directory, say '~/R-source'.  This could be achieved by including the
-following line in your Emacs configuration file:
-     (setq ess-source-directory (expand-file-name "~/R-source/"))
-
-   If you would prefer to keep your dump files in separate directories
-depending on the value of some variable, ESS provides a facility for
-this also.  By setting 'ess-source-directory' to a lambda expression
-which evaluates to a directory name, you have a great deal of
-flexibility in selecting the directory for a particular source file to
-appear in.  The lambda expression is evaluated with the process buffer
-as the current buffer and so you can use the variables local to that
-buffer to make your choice.  For example, the following expression
-causes source files to be saved in the subdirectory 'Src' of the
-directory the ESS process was run in.
-
-     (setq ess-source-directory
-           (lambda ()
-              (concat ess-directory "Src/")))
-
-('ess-directory' is a buffer-local variable in process buffers which
-records the directory the ESS process was run from.)  This is useful if
-you keep your dump files and you often edit objects with the same name
-in different ESS processes.  Alternatively, if you often change your R
-working directory during an R session, you may like to keep dump files
-in some subdirectory of the directory pointed to by the first element of
-the current search list.  This way you can edit objects of the same name
-in different directories during the one R session:
-     (setq ess-source-directory
-        (lambda ()
-            (file-name-as-directory
-             (expand-file-name (concat
-                                (car ess-search-list)
-                                "/.Src")))))
-
-   If the directory generated by the lambda function does not exist but
-can be created, you will be asked whether you wish to create the
-directory.  If you choose not to, or the directory cannot be created,
-you will not be able to edit functions.
-
-\1f
-File: ess.info,  Node: Help,  Next: Completion,  Prev: Editing objects,  Up: Top
-
-8 Reading help files
-********************
-
-ESS provides an easy-to-use facility for reading R help files from
-within Emacs.  From within the ESS process buffer or any ESS edit
-buffer, typing 'C-c C-v' ('ess-display-help-on-object') will prompt you
-for the name of an object for which you would like documentation.
-Completion is provided over all objects which have help files.
-
-   If the requested object has documentation, you will be popped into a
-buffer (named '*help(OBJ-NAME)*') containing the help file.  This buffer
-is placed in a special ESS help mode which disables the usual editing
-commands but which provides a number of keys for paging through the help
-file.
-
-   Help commands:
-
-'?'
-     'ess-describe-help-mode' Pops up a help buffer with a list of the
-     commands available in R help mode.
-
-'h'
-     'ess-display-help-on-object' Pop up a help buffer for a different
-     object.
-
-   Paging commands:
-
-'DEL'
-     'scroll-down-command' Move one screen backwards through the help
-     file.
-
-'SPC'
-     'scroll-up-command' Move one screen forwards through the help file.
-
-'>'
-'<'
-     'end/beginning-of-buffer' Move to the end or beginning of the help
-     file, respectively.
-
-   Section-based motion commands:
-
-'n'
-'p'
-     'ess-skip-to-previous-section' and 'ess-skip-to-next-section' Move
-     to the next and previous section header in the help file,
-     respectively.  A section header consists of a number of capitalized
-     words, followed by a colon.
-
-   In addition, the 's' key followed by one of the following letters
-will jump to a particular section in the help file.  Note that the exact
-headings available and capitalization scheme may vary across languages.
-
-   You may use 's ?' to get the current list of active key bindings.
-
-'a'
-     Arguments:
-
-'b'
-     Background:
-
-'B'
-     Bugs:
-
-'d'
-     Description:
-
-'D'
-     Details:
-
-'e'
-     Examples:
-
-'n'
-     Note:
-
-'O'
-     Optional Arguments:
-
-'R'
-     Required Arguments:
-
-'r'
-     References:
-
-'s'
-     See Also:
-
-'S'
-     Side Effects:
-
-'u'
-     Usage:
-
-'v'
-     Value:
-
-'?'
-     Pops up a help buffer with a list of the defined section motion
-     keys.
-
-   Evaluation:
-
-'l'
-     'ess-eval-line-and-step' Evaluates the current line in the ESS
-     process, and moves to the next line.  Useful for running examples
-     in help files.
-
-'r'
-     'ess-eval-region' Send the contents of the current region to the
-     ESS process.  Useful for running examples in help files.
-
-   Quit commands:
-
-'q'
-     'ess-help-quit' Return to previously selected buffer, and bury the
-     help buffer.
-
-'k'
-     'kill-buffer' Return to previously selected buffer, and kills the
-     help buffer.
-
-'x'
-     'ess-kill-buffer-and-go' Return to the ESS process, killing this
-     help buffer.
-
-   Miscellaneous:
-
-'i'
-     'ess-display-index' Prompt for a package and display it's help
-     index.
-
-'v'
-     'ess-display-vignettes' Display all available vignettes.
-
-'w'
-     'ess-display-help-in-browser' Display current help page with the
-     web browser.
-
-'/'
-     'isearch-forward' Same as 'C-s'.
-
-   In addition, all of the ESS commands available in the edit buffers
-are also available in R help mode (*note Edit buffer::).  Of course, the
-usual (non-editing) Emacs commands are available, and for convenience
-the digits and <-> act as prefix arguments.
-
-   If a help buffer already exists for an object for which help is
-requested, that buffer is popped to immediately; the ESS process is not
-consulted at all.  If the contents of the help file have changed, you
-either need to kill the help buffer first, or pass a prefix argument
-(with 'C-u') to 'ess-display-help-on-object'.
-
-   Help buffers are marked as temporary buffers in ESS, and are deleted
-when 'ess-quit' or 'ess-cleanup' are called.
-
-   Help buffers normally appear in another window within the current
-frame.  If you wish help buffers to appear in their own frame (either
-one per help buffer, or one for all help buffers), you can customize the
-variable 'ess-help-own-frame'.
-
-   Help buffers are displayed by calling the function
-'ess-display-help'.  You can customize where these buffers are displayed
-by adding an entry in 'display-buffer-alist'; for examples, see *Note
-(ess)Controlling buffer display::.  Or by customizing the options
-'ess-help-own-frame', 'ess-help-frame-alist', and
-'ess-display-buffer-reuse-frame'.
-
-\1f
-File: ess.info,  Node: Completion,  Next: Developing with ESS,  Prev: Help,  Up: Top
-
-9 Completion
-************
-
-* Menu:
-
-* Object names::
-* Function arguments::
-* Minibuffer completion::
-* Company::
-* Icicles::
-
-\1f
-File: ess.info,  Node: Object names,  Next: Function arguments,  Up: Completion
-
-9.1 Completion of object names
-==============================
-
-The <TAB> key is for completion.  The value of the variable
-'ess-first-tab-never-complete' controls when completion is allowed to
-occur.  In 'ess-mode' <TAB> first tries to indent, and if there is
-nothing to indent, complete the object name instead.
-
-'TAB'
-     'comint-dynamic-complete' Complete the R object name or filename
-     before point.
-
-   When the cursor is just after a partially-completed object name,
-pressing <TAB> provides completion in a similar fashion to the rest of
-Emacs.  ESS maintains a list of all objects known to R at any given
-time, which basically consists of all objects (functions and datasets)
-in every attached directory listed by the 'search()' command along with
-the component objects of attached data frames
-
-   For example, consider three functions 'binomplot()', 'binom.test()'
-and 'binomial()'.  Typing 'bin TAB' will insert the characters 'om',
-completing the longest prefix ('binom') which distinguishes these three
-commands.  Pressing 'TAB' once more provides a list of the three
-commands which have this prefix, allowing you to add more characters
-(say, '.') which specify the function you desire.  After entering more
-characters pressing 'TAB' yet again will complete the object name up to
-uniqueness, etc.  If you just wish to see what completions exist without
-adding any extra characters, type 'M-?'.
-
- -- Command: ess-complete-object-name
-     'M-?' List all possible completions of the object name at point.
-
-   ESS also provides completion over the components of named lists and
-environments (after '$'), S4 classes slots (after @), package and
-namespace objects (after :: and :::).
-
-   Completion is also provided over file names, which is particularly
-useful when using R functions such as 'get()' or 'scan()' which require
-fully expanded file names.
-
-   In the iESS buffer, if the cursor is not in a string and does not
-follow a (partial) object name, the <TAB> key has a third use: it
-expands history references.  *Note History expansion::.
-
-   Efficiency in completion is gained by maintaining a cache of objects
-currently known to R; when a new object becomes available or is deleted,
-only one component of the cache corresponding to the associated
-directory needs to be refreshed.  If ESS ever becomes confused about
-what objects are available for completion (such as when if refuses to
-complete an object you *know* is there), the command 'M-x ess-resynch'
-forces the _entire_ cache to be refreshed, which should fix the problem.
-
-\1f
-File: ess.info,  Node: Function arguments,  Next: Minibuffer completion,  Prev: Object names,  Up: Completion
-
-9.2 Completion of function arguments
-====================================
-
-When inside a function call (i.e.  following ''(''), 'TAB' completion
-also provides function arguments.  If function is a generic, completion
-will provide all the arguments of 'S3' methods known to 'R'.
-
-   In R versions newer than 2.14.1, ESS uses R's built-in completion
-engine and will honor its settings.  You may read about them by issuing
-'?rc.options' at the prompt.  For example, to have the equals sign for
-function arguments contain spaces on both sides (e.g.  'lm(for)'
-suggests 'formula = ' rather than 'formula='), you can adjust
-'funarg.suffix':
-
-     utils::rc.options(funarg.suffix = " = ")
-
-   A related functionality is *Note ESS ElDoc::, which displays function
-arguments in the echo area whenever the point is inside a function call.
-
-\1f
-File: ess.info,  Node: Minibuffer completion,  Next: Company,  Prev: Function arguments,  Up: Completion
-
-9.3 Minibuffer completion
-=========================
-
-ESS uses 'IDO' mechanism (part of default Emacs) for minibuffer
-completion if the 'ido' package is available and the value of
-'ess-use-ido' it 't' (the default).  The completion command
-'ess-completing-read' falls back on classic 'completion-read' interface
-if this feature is not available for whatever reason.
-
-\1f
-File: ess.info,  Node: Company,  Next: Icicles,  Prev: Minibuffer completion,  Up: Completion
-
-9.4 Company
-===========
-
-Another popular package for completion is company, short for complete
-anything.  ESS provides support for company out-of-the-box.  To disable
-company support, set 'ess-use-company' to 'nil'.  You can set it to
-''script-only' to only activate company in R scripts.
-
-\1f
-File: ess.info,  Node: Icicles,  Prev: Company,  Up: Completion
-
-9.5 Icicles
-===========
-
-Another option for comprehensively handling completion in Emacs is via
-Icicles (<https://www.emacswiki.org/emacs/Icicles>).  It allows users to
-have completions shown temporarily in the standard '*Completions*'
-buffer, and interactively select completion candidates using several
-methods.  As of version 2013.04.04, Icicles provides support for
-completion in ESS. Please consult Icicles documentation, which is easily
-accessible via 'customize-group Icicles', for more details on
-installation and customization options.
-
-   Once installed, Icicles can be activated by evaluating):
-
-     (require 'icicles)
-     (icy-mode 1)
-
-   Icicles can be toggled by typing 'M-x icy'.
-
-   When Icicles is on, 'TAB' offers completion, provided the conditions
-determined by 'ess-first-tab-never-complete' allow it.  Typing 'M-TAB'
-will attempt completion regardless.  Typing 'M-?' in 'ESS' or 'iESS'
-modes brings up the relevant completion candidates from which to choose.
-Minibuffer input filters the available candidates.  Use 'TAB' for prefix
-completion or 'S-TAB' for substring or regexp completion.  Use 'S-SPC'
-to match an additional pattern (repeatable).  You can cycle among the
-matching candidates, choosing with 'RET' or 'mouse-2'.
-
-\1f
-File: ess.info,  Node: Developing with ESS,  Next: Extras,  Prev: Completion,  Up: Top
-
-10 Developing with ESS
-**********************
-
-ESS provides several tools to help you with the development of your R
-packages:
-
-* Menu:
-
-* ESS tracebug::                Visual debugging, breakpoints, tracing, watch etc.
-* Editing documentation::       Tools to edit R documentation
-* Namespaced Evaluation::               Develop your packages on the fly
-
-\1f
-File: ess.info,  Node: ESS tracebug,  Next: Editing documentation,  Up: Developing with ESS
-
-10.1 ESS tracebug
-=================
-
-* Menu:
-
-* Getting started with tracebug:: Quick tutorial
-
-ESS 'tracebug' offers visual debugging, interactive error navigation,
-interactive backtrace, breakpoint manipulation, control over R error
-actions, watch window and interactive flagging/unflagging of functions
-for debugging.
-
-   'ess-tracebug' is on by default.  You can toggle it on and off with
-'M-x' 'ess-tracebug'.  To disable startup activation of 'ess-tracebug'
-set 'ess-use-tracebug' to nil.
-
-   Tracebug functionality can be found on 'ess-dev-map', bound to 'C-c
-C-t'.  Additionally, when subprocess is in a debugging state
-'ess-debug-minor-mode' is active and the following additional shortcuts
-are available:
-
-* Interactive Debugging (`ess-debug-minor-mode-map'):
-
- M-C   . Continue                  . `ess-debug-command-continue'
- M-C-C . Continue multi            . `ess-debug-command-continue-multi'
- M-N   . Next step                 . `ess-debug-command-next'
- M-C-N . Next step multi           . `ess-debug-command-next-multi'
- M-U   . Up frame                  . `ess-debug-command-up'
- M-Q   . Quit debugging            . `ess-debug-command-quit'
-
-
-   These are all the tracebug commands defined in 'ess-dev-map' ('C-c
-C-t ?' to show this table):
-
-
-* Breakpoints (`ess-dev-map'):
-
- b   . Set BP (repeat to cycle BP type) . `ess-bp-set'
- B   . Set conditional BP               . `ess-bp-set-conditional'
- k   . Kill BP                          . `ess-bp-kil'
- K   . Kill all BPs                     . `ess-bp-kill-all'
- o   . Toggle BP state                  . `ess-bp-toggle-state'
- l   . Set logger BP                    . `ess-bp-set-logger'
- n   . Goto next BP                     . `ess-bp-next'
- p   . Goto previous BP                 . `ess-bp-previous'
-
-  (C- prefixed equivalents are also defined)
-
-* Debugging (`ess-dev-map'):
- `   . Show traceback                       . `ess-show-traceback' (also on C-c `)
- ~   . Show callstack                       . `ess-show-call-stack' (also on C-c ~)
- e   . Toggle error action (repeat to cycle). `ess-debug-toggle-error-action'
- d   . Flag for debugging                   . `ess-debug-flag-for-debugging'
- u   . Unflag for debugging                 . `ess-debug-unflag-for-debugging'
- w   . Watch window                         . `ess-watch'
-
-  (C- prefixed equivalents are also defined)
-
-* Navigation to errors (general Emacs functionality):
-
- C-x `, M-g n   . `next-error'
- M-g p          . `previous-error'
-
-* Misc:
-
-?   . Show this help           . `ess-tracebug-show-help'
-
-
-   To configure how electric watch window splits the display see
-'ess-watch-width-threshold' and 'ess-watch-height-threshold' variables.
-
-   _Note:_ Currently, ess-tracebug does not detect some of R's debug
-related messages in non-English locales.  To set your R messages to
-English add the following line to your .Rprofile init file:
-
-   Sys.setlocale("LC_MESSAGES", "C")
-
-\1f
-File: ess.info,  Node: Getting started with tracebug,  Up: ESS tracebug
-
-10.1.1 Getting started with tracebug
-------------------------------------
-
-Consider a buffer with the following function:
-
-test <- function(x){
-  mean(x),
-}
-
-   Evaluating the function (e.g.  'C-c C-c') results in an error about
-an unexpected comma.  You can use 'next-error' (bound by default to 'C-x
-`', 'M-g n', and 'M-g M-n') to jump to the place where the error
-occurred.  Alternatively, use the mouse to click on the error to jump to
-where it occurred.
-
-   Correct the error by deleting the comma.  Now put point on 'mean' and
-set the breakpoint using 'C-c C-t b' ('ess-bp-set') and reevaluate the
-function.  Jump to the inferior buffer (possibly using 'C-c C-z') and
-evaluate 'test(1:10)'.  An interactive debug process starts, stopping at
-the breakpoint we just specified.  Here you can debug your function
-(what is 'x' at this point?).  Use 'M-N' to continue.
-
-   Let's replace our test function with one slightly more complicated:
-
-test <- function(x){
-  x <- x + 1
-  y <- mean(x)
-  x <- ifelse(x > 5, x, x - 100)
-  list(x, y)
-}
-
-   Try setting multiple breakpoints.  You can unset a breakpoint by
-killing it with 'C-c C-t k'.  You can set conditional breakpoints too.
-Try setting one by placing point on the line 'x <- x + 1' and doing 'C-c
-C-t B'.  ESS will ask for the condition.  Let's set it to
-'!is.numeric(x)'.  After re-evaluating 'test', try calling 'test(1:100)'
-and 'test('foo')'.
-
-   You can remove all breakpoints with 'C-c C-t K'.
-
-   You can flag a function for debugging (similar to calling
-'debug(test)' at R's prompt) by doing 'C-c C-t d'.  Try this yourself by
-putting point over 'test' and doing 'C-c C-t d'.
-
-   If an error occurs, you can get the complete call stack by doing 'C-c
-`' or 'C-c C-t `' ('ess-show-traceback').
-
-   Tracebug also offers a watch window where you can watch values of
-objects.  Open it with 'C-c C-t w' ('ess-watch').  Initially you aren't
-watching anything.  Add something with 'a' (e.g.  'a test').  The watch
-window displays what the object is at any given time and automatically
-updates.  Quit the watch window with 'q'.
-
-\1f
-File: ess.info,  Node: Editing documentation,  Next: Namespaced Evaluation,  Prev: ESS tracebug,  Up: Developing with ESS
-
-10.2 Editing documentation
-==========================
-
-ESS provides two ways of writing documentation for R objects.  Either
-using the standard R documentation system or using in-source
-documentation written as structured comment fields for use with the
-roxygen2 package.
-
-* Menu:
-
-* R documentation files::       Edit objects in a specialized buffer
-* roxygen2::                     Loading source files into the ESS process
-
-\1f
-File: ess.info,  Node: R documentation files,  Next: roxygen2,  Up: Editing documentation
-
-10.2.1 Editing R documentation (Rd) files
------------------------------------------
-
-R objects are documented in files written in the "R documentation"
-("Rd"), a simple markup language closely resembling (La)TeX, which can
-be processed into a variety of formats, including LaTeX, HTML, and plain
-text.  Rd format is described in section "Rd format" of the "Writing R
-Extensions" manual in the R distribution.  ESS has several features that
-facilitate editing Rd files.
-
-   Visiting an Rd file as characterized by its extension 'Rd' will
-activate Rd Mode, which provides several facilities for making editing R
-documentation files more convenient, by helping with indentation,
-insertions, even doing some of the typing for you (with Abbrev Mode),
-and by showing Rd keywords, strings, etc. in different faces (with Font
-Lock Mode).
-
-   In Rd mode, the following special Emacs commands can be used in
-addition to the standard Emacs commands.
-
-'C-h m'
-     Describe the features of Rd mode.
-
-'LFD'
-'RET'
-     Reindent the current line, insert a newline and indent the new line
-     ('reindent-then-newline-and-indent').  An abbrev before point is
-     expanded if 'abbrev-mode' is non-'nil'.
-
-'TAB'
-     Indent current line based on its contents and on previous lines.
-     ('indent-according-to-mode').
-
-'C-c C-e'
-     Insert a "skeleton" with Rd markup for at least all mandatory
-     entries in Rd files ('Rd-mode-insert-skeleton').  Note that many
-     users might prefer to use the R function 'prompt' on an existing R
-     object to generate a non-empty Rd "shell" documenting the object
-     (which already has all information filled in which can be obtained
-     from the object).
-
-'C-c C-f'
-     Insert "font" specifiers for some of the Rd markup commands markup
-     available for emphasizing or quoting text, including markup for
-     URLs and email addresses ('Rd-font').  'C-c C-f' is only a prefix;
-     see e.g. 'C-c C-f TAB' for the available bindings.  Note that
-     currently, not all of the Rd text markup as described in section
-     "Marking text" of "Writing R Extensions" can be accessed via 'C-c
-     C-f'.
-
-'C-c C-j'
-     Insert a suitably indented '\item{' on the next line
-     ('Rd-mode-insert-item').
-
-'C-c C-p'
-     Preview a plain text version ("help file", *note Help::) generated
-     from the Rd file ('Rd-preview-help').
-
-   In addition, when editing Rd files one can interact with a running R
-process in a similar way as when editing R language files.  For example,
-'C-c C-v' provides access to on-line help, and 'C-c C-n' sends the
-current line to the R process for evaluation.  This interaction is
-particularly useful when editing the examples in the Rd file.  See 'C-h
-m' for all available commands.
-
-   Rd mode also provides access to abbreviations for most of the Rd
-markup commands.  Type 'M-x list-abbrevs' with Abbrev mode turned on to
-list all available abbrevs.  Note that all Rd abbrevs start with a grave
-accent.
-
-   Rd mode can be customized via the following variables.
-
- -- User Option: Rd-mode-hook
-     Hook to be run when Rd mode is entered.
-
- -- User Option: Rd-indent-level
-     The indentation of Rd code with respect to containing blocks.
-     Default is 2.
-
- -- User Option: Rd-to-help-command
-     The shell command used for converting Rd source to help text.
-     Default is 'R CMD Rd2txt'.
-
-   To automatically turn on the abbrev and font-lock features of Rd
-mode, add the following lines to one of your Emacs startup files:
-
-     (add-hook 'Rd-mode-hook
-               (lambda ()
-                (abbrev-mode 1)
-                (font-lock-mode 1)))
-
-\1f
-File: ess.info,  Node: roxygen2,  Prev: R documentation files,  Up: Editing documentation
-
-10.2.2 Editing roxygen2 documentation
--------------------------------------
-
-The roxygen2 R package makes it possible to keep the intended contents
-for Rd files as structured comments in the R source files.  roxygen2 can
-then parse R files and generate appropriate Rd files from these
-comments, fill the usage fields as well as updating 'NAMESPACE' files.
-See the roxygen2 documentation found via <https://roxygen2.r-lib.org>
-for more information on its usage.  An example of an roxygen2 entry for
-a simple R function can look like this:
-
-     ##' Description of the function
-     ##'
-     ##' Further details about this function
-     ##' @title A title
-     ##' @param me all parameters must be listed and documented
-     ##' @return Description of the return value
-     ##' @author The author
-     myfun <- function(me)
-       cat("Hello", me, "\n")
-   The entry is immediately preceding the object to document and all
-lines start with the roxygen2 prefix string, in this case '##''.  ESS
-provides support to edit these documentation entries by providing line
-filling, navigation, template generation etc.  Syntax highlighting is
-provided.
-
-   roxygen2 is customized by the variables in the customization group
-"Ess Roxy".  Customizations include the roxygen2 prefix, use of folding
-to toggle visibility of roxygen2 entries and the roxygen2 template.
-
-   All ESS roxygen2 support is defined in 'ess-roxy.el' which is loaded
-by default in ESS. The following special Emacs commands are provided.
-
- -- Command: ess-roxy-update-entry
-     'C-c C-o C-o' Generate a roxygen2 template or update the parameter
-     list in roxygen2 entry at point (or above the function at the
-     point).  Documented parameters that are not in the function are
-     placed last in the list, parameters that are not documented and not
-     in the definition are dropped.  Parameter descriptions are filled
-     if 'ess-roxy-fill-param-p' is non-nil.
-
- -- Command: ess-roxy-toggle-roxy-region BEG END
-     'C-c C-o C-c' Toggle the presence of the leading roxygen2 string on
-     all lines in the marked region (between BEG and END.  Convenient
-     for transferring text to roxygen2 entries and to evaluate example
-     fields.
-
- -- Command: ess-roxy-preview-Rd NAME-FILE
-     'C-c C-o C-r' Use the attached R process to parse the entry at
-     point to obtain the Rd code.  Convenient for previewing and
-     checking syntax.  When used with the prefix argument NAME-FILE,
-     i.e.  'C-u C-c C-e C-r', place the content in a buffer associated
-     with a Rd file with the same name as the documentation.  Requires
-     the roxygen2 package to be installed.
-
- -- Command: ess-roxy-preview-HTML VISIT-INSTEAD-OF-OPEN
-     'C-c C-o C-t' Use the attached R process to parse the entry at to
-     generate HTML for the entry and open it in a browser.  When used
-     with the prefix argument VISIT-INSTEAD-OF-OPEN, i.e.  'C-u C-c C-e
-     C-t', visit the generated HTML file instead.  Requires the roxygen2
-     and tools packages to be installed.
-
- -- Command: ess-roxy-previous-entry
-     'C-c C-o p' Go to start of the roxygen2 entry above point.
-
- -- Command: ess-roxy-next-entry
-     'C-c C-o n' Go to end of the roxygen2 entry above point.
-
- -- Command: ess-roxy-hide-all
-     'C-c C-o C-h' Use the hideshow mode to fold away the visibility of
-     all roxygen2 entries.  Hide-show support must be enabled for this
-     binding to get defined.
-
-   ESS also advises the following standard editing functions in order to
-make roxygen2 editing more intuitive:
-
-'TAB'
-     'ess-R-complete-object-name' Complete roxygen2 tag at point.  E.g.
-     doing 'TAB' when the point is at the end of '@par' completes to
-     '@param'.
-
-'M-h'
-     'mark-paragraph' If the transient mark mode is active, place mark
-     and point at start end end of the field at point and activate the
-     mark.
-
-'TAB'
-     'ess-indent-command' If hide-show support is enabled, fold away the
-     visibility of the roxygen2 entry at point.
-
-'M-q'
-     'fill-paragraph' Fill the roxygen2 field at point.
-
-'C-a'
-     'ess-roxy-move-beginning-of-line' Move to the point directly to the
-     right of the roxygen2 start string.  If already there, move to the
-     beginning of the line.
-
-'RET'
-     'newline-and-indent' Insert a new line and the roxygen2 prefix
-     string.
-
-\1f
-File: ess.info,  Node: Namespaced Evaluation,  Prev: Editing documentation,  Up: Developing with ESS
-
-10.3 Namespaced Evaluation
-==========================
-
-In non package files evaluation commands, *Note Evaluating code::, send
-portions of the current buffer environment ('R_GlobalEnv'.  When
-developing packages, ESS sends code to the corresponding package
-namespace and (for visible objects) into package environment (visible on
-search path).  All objects that are assigned are displayed in the
-minibuffer alongside the environment in which they are assigned.
-
-   Here is a short overview of how namespace and package environments
-work in R. All objects defined in a package 'foo' are stored in an
-environment called 'namespace:foo'.  Parent environment of
-'namespace:foo' is an environment 'imports:foo' which contains copies of
-all objects from other packages which 'foo' imports.  Parent environment
-of 'imports:foo' is the 'namespace:base'.  Parent environment of
-'namespace:base' is .GlobalEnv.  Thus functions and methods stored in
-'namespace:foo' see all the objects in .GlobalEnv unless shadowed by
-objects in 'imports:foo', 'namespace:base', or 'namespace:foo' itself.
-There is another environment associated with 'foo' - 'package:foo'.
-This environment stores *copies* of exported objects from
-'namespace:foo' and is placed on the search() path, i.e.  if 'foo' is
-loaded and if you start with .GlobalEnv and iteratively call
-parent.env() you will get eventually to 'package:foo'.  Thus all methods
-and functions defined in .GlobalEnv can "see" objects in 'package:foo'
-environment.  See also
-<https://cran.r-project.org/doc/manuals/R-ints.html#Namespaces>.
-
-   Occasionally you want to evaluate into a package from a non-package
-file, or the other way around, evaluate into 'GlobalEnv' from inside a
-package.  In such cases 'C-c C-t C-s' is your friend.
-
- -- Command: ess-r-set-evaluation-env ARG
-     'C-c C-t C-s' Set or unset the current evaluation environment (a
-     package).
-
-\1f
-File: ess.info,  Node: Extras,  Next: ESS for R,  Prev: Developing with ESS,  Up: Top
-
-11 Other ESS features and tools
-*******************************
-
-ESS has a few extra features, which didn't fit anywhere else.
-* Menu:
-
-* ESS ElDoc::                   Display function arguments in minibuffer
-* ESS Flymake::                 On-the-fly syntax checking
-* Handy commands::              Usefully commands at your fingertips
-* Highlighting::                Syntactic highlighting of buffers
-* Parens::                      Parenthesis matching
-* Graphics::                    Using graphics with ESS
-* Imenu::                       Support for Imenu in ESS
-* Outline::                     Use outline-minor-mode in R scripts
-* Toolbar::                     Support for toolbar in ESS
-* Xref::                        Xref
-* Rdired::                      Directory editor for R objects
-* Package listing::             R object/package management and help utilities
-* Org::                         Interaction with Org mode
-* Sweave and AUCTeX::           Support for Sweave in ESS and AUCTeX
-
-\1f
-File: ess.info,  Node: ESS ElDoc,  Next: ESS Flymake,  Up: Extras
-
-11.1 ElDoc
-==========
-
-In 'ElDoc' mode, the echo area displays function's arguments at point.
-ElDoc is active by default in 'ess-mode' and 'inferior-ess-mode'
-buffers.  To activate it only in 'ess-mode' buffers, place the following
-into your init file:
-
-     (setq ess-use-eldoc 'script-only)
-
- -- User Option: ess-use-eldoc
-     If 't', activate eldoc in ess-mode and inferior-ess-mode buffers.
-     If ''script-only' activate in ess-mode buffers only.  Set
-     'ess-use-eldoc' to 'nil' to stop using 'ElDoc' altogether.
-
- -- User Option: ess-eldoc-show-on-symbol
-     This variable controls whether the help is shown only inside
-     function calls.  If set to 't', 'ElDoc' shows help string whenever
-     the point is on a symbol, otherwise (the default), shows only when
-     the point is in a function call, i.e.  after ''(''.
-
- -- User Option: ess-eldoc-abbreviation-style
-     The variable determines how the doc string should be abbreviated to
-     fit into minibuffer.  Posible values are 'nil', 'mild', 'normal',
-     'strong' and 'aggressive'.  Please see the documentation of the
-     variable for more details.  The default filter is 'normal'.
-
-   Ess-eldoc also honors the value of 'eldoc-echo-area-use-multiline-p',
-which if set to 'nil', will cause the truncation of doc string
-indifferent of the value of 'ess-eldoc-abbreviation-style'.  This way
-you can combine different filter levels with the truncation.
-
-\1f
-File: ess.info,  Node: ESS Flymake,  Next: Handy commands,  Prev: ESS ElDoc,  Up: Extras
-
-11.2 Flymake
-============
-
-The minor mode 'flymake-mode' provides on-the-fly syntax checking.  ESS
-provides support for flymake in R-mode in Emacs versions 26 and newer.
-It is enabled by default, to disable it you may set 'ess-use-flymake' to
-'nil'.  In order to use it, you may need to install the 'lintr' R
-package, available from CRAN.
-
- -- User Option: ess-use-flymake
-     When non-nil, use flymake.  If ''process', only use flymake when
-     the buffer has an inferior process running.
-
- -- User Option: ess-r-flymake-linters
-     This variable describes the linters to use.  It can either be a
-     string with an R expression to be used as-is or a list of strings
-     where each element is passed to 'lintr::with_defaults'.  See the
-     help page for 'lintr::default_linters' for information on available
-     linters and their defaults.
-
- -- User Option: ess-r-flymake-lintr-cache
-     When 't' (the default), lintr uses a cache.  Change to 'nil' to
-     disable lintr's caching mechanism.
-
-\1f
-File: ess.info,  Node: Handy commands,  Next: Highlighting,  Prev: ESS Flymake,  Up: Extras
-
-11.3 Handy commands
-===================
-
- -- Command: ess-handy-commands
-     Request and execute a command from 'ess-handy-commands' list.
-
- -- User Option: ess-handy-commands
-     An alist of custom ESS commands available for call by
-     'ess-handy-commands' and 'ess-smart-comma' function.
-
-     Currently contains:
-
-     change-directory
-          'ess-change-directory'
-     help-index
-          'ess-display-index'
-     help-object
-          'ess-display-help-on-object'
-     vignettes
-          'ess-display-vignettes'
-     objects[ls]
-          'ess-execute-objects'
-     search
-          'ess-execute-search'
-     set-width
-          'ess-execute-screen-options'
-     install.packages
-          'ess-install.packages'
-     library
-          'ess-library'
-     setRepos
-          'ess-setRepositories'
-     sos
-          'ess-sos'
-
-   Handy commands: 'ess-library', 'ess-install.packages', etc - ask for
-item with completion and execute the correspond command.  'ess-sos' is a
-interface to 'findFn' function in package 'sos'.  If package 'sos' is
-not found, ask user for interactive install.
-
-\1f
-File: ess.info,  Node: Highlighting,  Next: Parens,  Prev: Handy commands,  Up: Extras
-
-11.4 Syntactic highlighting of buffers
-======================================
-
-ESS provides Font-Lock (*note Using Multiple Typefaces: (emacs)Faces.)
-patterns for inferior R Mode, S Mode, and R Transcript Mode buffers.
-
-   The font-lock patterns are defined by the following variables, which
-you may modify if desired:
-
- -- User Option: inferior-R-font-lock-keywords
-     Font-lock patterns for inferior *R* processes.  (There is a
-     corresponding 'inferior-S-font-lock-keywords' for *S* processes.)
-     The default value highlights prompts, inputs, assignments, output
-     messages, vector and matrix labels, and literals such as 'NA' and
-     'TRUE'.
-
- -- User Option: ess-R-font-lock-keywords
-     Font-lock patterns for ESS R programming mode.  (There is a
-     corresponding 'ess-S-font-lock-keywords' for S buffers.)  The
-     default value highlights function names, literals, assignments,
-     source functions and reserved words.
-
-\1f
-File: ess.info,  Node: Parens,  Next: Graphics,  Prev: Highlighting,  Up: Extras
-
-11.5 Parenthesis matching
-=========================
-
-Emacs has facilities for highlighting the parenthesis matching the
-parenthesis at point.  This feature is very useful when trying to
-examine which parentheses match each other.  This highlighting also
-indicates when parentheses are not matching.  You may activate it
-putting this in your Emacs configuration file:
-
-     (show-paren-mode)
-
-\1f
-File: ess.info,  Node: Graphics,  Next: Imenu,  Prev: Parens,  Up: Extras
-
-11.6 Using graphics with ESS
-============================
-
-One of the main features of R is its ability to generate high-resolution
-graphics plots.  When using R in a windowing environment, no additional
-configuration is necessary; plots will be shown in a new (non-Emacs)
-window.
-
-   If not using a windowing environment or S, ESS provides a number of
-features for dealing with such plots.
-
-* Menu:
-
-* printer::                     The printer() graphics driver
-* X11::                         The X11() (and other X Windows based) driver
-* winjava::                     Java Graphics Device
-
-\1f
-File: ess.info,  Node: printer,  Next: X11,  Up: Graphics
-
-11.6.1 Using ESS with the 'printer()' driver
---------------------------------------------
-
-This is the simplest (and least desirable) method of using graphics
-within ESS. S's 'printer()' device driver produces crude character based
-plots which can be contained within the ESS process buffer itself.  To
-start using character graphics, issue the S command
-     printer(width=79)
-   (the 'width=79' argument prevents Emacs line-wrapping at column 80 on
-an 80-column terminal.  Use a different value for a terminal with a
-different number of columns.)  Plotting commands do not generate
-graphics immediately, but are stored until the 'show()' command is
-issued, which displays the current figure.
-
-\1f
-File: ess.info,  Node: X11,  Next: winjava,  Prev: printer,  Up: Graphics
-
-11.6.2 Using ESS with windowing devices
----------------------------------------
-
-Of course, the ideal way to use graphics with ESS is to use a windowing
-system.  Under X Windows, or X11, this requires that the DISPLAY
-environment variable be appropriately set.
-
-\1f
-File: ess.info,  Node: winjava,  Prev: X11,  Up: Graphics
-
-11.6.3 Java Graphics Device
----------------------------
-
-S+6.1 and newer on Windows contains a java library that supports
-graphics.  Send the commands:
-
-     library(winjava)
-     java.graph()
-
-to start the graphics driver.  This allows you to use ESS for both
-interaction and graphics within S-PLUS. (Thanks to Tim Hesterberg for
-this information.)
-
-\1f
-File: ess.info,  Node: Imenu,  Next: Outline,  Prev: Graphics,  Up: Extras
-
-11.7 Imenu
-==========
-
-Imenu is an Emacs tool for providing mode-specific buffer indexes.  In
-some of the ESS editing modes (currently SAS and R), support for Imenu
-is provided.  For example, in R mode buffers, the menubar should display
-an item called "Imenu-R". Within this menubar you will then be offered
-bookmarks to particular parts of your source file (such as the starting
-point of each function definition).
-
-   Imenu works by searching your buffer for lines that match what ESS
-thinks is the beginning of a suitable entry, for example the beginning
-of a function definition.  To examine the regular expression that ESS
-uses, check the value of 'imenu-generic-expression'.  This value is set
-by various ESS variables such as 'ess-imenu-S-generic-expression'.
-
-\1f
-File: ess.info,  Node: Outline,  Next: Toolbar,  Prev: Imenu,  Up: Extras
-
-11.8 Outline navigation
-=======================
-
-R editing buffers integrate with 'outline-minor-mode'.  When you toggle
-the minor mode (for example via 'M-x outline-minor-mode' or by adding it
-to 'ess-r-mode-hook'), ESS assigns 'ess-r-outline-level' to
-'outline-level' and installs 'ess-r-outline-regexp' so that comment
-headings drive folding.  Lines that begin with one or more '#', followed
-by text and a trailing marker of '----', '====', or '####', are treated
-as outline headings.  This matches the section markers convention
-adopted by RStudio.
-
-     # Setup ----
-     ## Data ----
-     ### Models ====
-     #### Helpers ####
-
-   The number of leading '#' characters sets the outline depth.  Use
-standard Outline commands (such as 'C-c  C-t') to cycle visibility once
-the minor mode is active.  To enable Outlining automatically, add it to
-the R mode hook:
-
-     (add-hook 'ess-r-mode-hook #'outline-minor-mode)
-
- -- User Option: ess-r-outline-regexp
-     Regular expression used by ESS to recognise outline headings in R
-     buffers.  The default matches the RStudio-style sections shown
-     above, but you can customise it if you prefer a different comment
-     convention.
-
-\1f
-File: ess.info,  Node: Toolbar,  Next: Xref,  Prev: Outline,  Up: Extras
-
-11.9 Toolbar
-============
-
-The R and S editing modes have support for a toolbar.  This toolbar
-provides icons to act as shortcuts for starting new S/R processes, or
-for evaluating regions of your source buffers.  The toolbar should be
-present if your Emacs can display images.  *Note Customization::, for
-ways to change the toolbar.
-
-\1f
-File: ess.info,  Node: Xref,  Next: Rdired,  Prev: Toolbar,  Up: Extras
-
-11.10 Xref
-==========
-
-Xref is an Emacs interface that supports finding "identifiers," usually
-function definitions in ESS's view.  ESS ships with support for Xref in
-Emacs versions 25.1 and higher.  For how to use this feature, see *Note
-(emacs)Xref::.
-
-\1f
-File: ess.info,  Node: Rdired,  Next: Package listing,  Prev: Xref,  Up: Extras
-
-11.11 Rdired
-============
-
-Ess-rdired provides a dired-like buffer for viewing, editing and
-plotting objects in your current R session.  If you are used to using
-the dired (directory editor) facility in Emacs, this mode gives you
-similar functionality for R objects.
-
-   Start an R session with 'M-x R' and then store a few variables, such
-as:
-
-     s <- sin(seq(from=0, to=8*pi, length=100))
-     x <- c(1, 4, 9)
-     y <- rnorm(20)
-     z <- TRUE
-
-   Then use 'M-x ess-rdired' to create a buffer listing the objects in
-your current environment and display it in a new window:
-                 mode length
-       s      numeric    100
-       x      numeric      3
-       y      numeric     20
-       z      logical      1
-
-   Type 'C-h m' or '?' to get a list of the keybindings for this mode.
-For example, with your point on the line of a variable, 'p' will plot
-the object, 'v' will view it, and 'd' will mark the object for deletion
-('x' will actually perform the deletion).
-
-\1f
-File: ess.info,  Node: Package listing,  Next: Org,  Prev: Rdired,  Up: Extras
-
-11.12 Package listing
-=====================
-
-ESS[R] provides several commands to list and manage packages and objects
-under the 'C-c C-.' keymap:
-
- -- Command: ess-r-package-list-local-packages
-     'C-c C-. l' List all packages in all available libraries.
-
- -- Command: ess-r-package-list-available-packages
-     'C-c C-. r' List available packages from repositories listed by
-     'getOptions(``repos'')' in the current R session.
-
- -- Command: ess-r-package-update-packages LIB REPOS
-     'C-c C-. u' Update packages in a particular library LIB and
-     repository REPOS.
-
- -- Command: ess-rutils-rm-all
-     'C-c C-. m' Remove all R objects.
-
- -- Command: ess-rutils-load-workspace
-     'C-c C-. w' Load a workspace file into R.
-
- -- Command: ess-rutils-save-workspace
-     'C-c C-. s' Save a workspace file.
-
- -- Command: ess-change-directory
-     'C-c C-. d' Change the working directory for the current R session.
-
- -- Command: ess-rutils-html-docs
-     'C-c C-. H' Use 'browse-url' to navigate R html documentation.
-
-   Functions for listing objects and packages ('ess-rutils-local-pkgs',
-'ess-rutils-repos-pkgs', and 'ess-rutils-objs') show results in a
-separate buffer and window, in 'ess-rutils-mode', providing useful key
-bindings in this mode (type '?' in this buffer for a description).
-
-\1f
-File: ess.info,  Node: Org,  Next: Sweave and AUCTeX,  Prev: Package listing,  Up: Extras
-
-11.13 Interaction with Org mode
-===============================
-
-Org-mode (<https://orgmode.org>) now supports reproducible research and
-literate programming in many languages (including R) - see chapter 15 of
-the Org manual
-(<https://orgmode.org/org.html#Working-with-Source-Code>).  For ESS
-users, this offers a document-based work environment within which to
-embed ESS usage.  R code lives in code blocks of an Org document, from
-which it can be edited in ess-mode, evaluated, extracted ("tangled") to
-pure code files.  The code can also be exported ("woven") with the
-surrounding text to several formats including HTML and LaTeX. Results of
-evaluation including figures can be captured in the Org document, and
-data can be passed from the Org document (e.g.  from a table) to the ESS
-R process.  (This section contributed by Dan Davison and Eric Schulte.)
-
-\1f
-File: ess.info,  Node: Sweave and AUCTeX,  Prev: Org,  Up: Extras
-
-11.14 Support for Sweave in ESS and AUCTeX
-==========================================
-
-Libraries for literate data analysis are obsolete and not loaded by
-default.  This includes 'ess-noweb', 'ess-swv', and related
-functionality like 'Rnw-mode'.  Users are encouraged to switch to one of
-several other packages that deal with these modes.  For example,
-polymode <https://github.com/polymode/poly-R/>,
-<https://polymode.github.io/>, or markdown-mode with edit-indirect
-<https://jblevins.org/projects/markdown-mode>.
-
-   ESS provides support for writing and processing Sweave
-(<https://leisch.userweb.mwn.de/Sweave/>), building up on Emacs'
-ess-noweb-mode for literate programming.  When working on an Sweave
-document, the following key bindings are available:
-
- -- Command: ess-swv-weave CHOOSE
-     'M-n s' Run Sweave on the current .Rnw file.  If CHOOSE is
-     non-'nil', offer a menu of available weavers.
-
- -- Command: ess-swv-latex
-     'M-n l' Run LaTeX after Sweave'ing.
-
- -- Command: ess-swv-PS
-     'M-n p' Generate and display a postscript file after LaTeX'ing.
-
- -- Command: ess-swv-PDF PDFLATEX-CMD
-     'M-n P' Generate and display a PDF file after LaTeX'ing.  Optional
-     argument PDFLATEX-CMD is the command to use, which by default, is
-     the command used to generate the PDF file is the first element of
-     'ess-swv-pdflatex-commands'.
-
- -- User Option: ess-swv-pdflatex-commands
-     Commands used by 'ess-swv-PDF' to run a version of pdflatex; the
-     first entry is the default command.
-
-   Sweave'ing with 'ess-swv-weave' starts an inferior-ESS process, if
-one is not available.  Other commands are available from the 'Sweaving,
-Tangling, ...' submenu of the Noweb menu.
-
-   AUCTeX (<https://www.gnu.org/software/auctex>) users may prefer to
-set the variable 'ess-swv-plug-into-AUCTeX-p' (available from the "ESS
-Sweave" customization group) to t.  Alternatively, the same can be
-achieved by activating the entry "AUCTeX Interface" from the 'Sweaving,
-Tangling, ...' submenu, which toggles this variable on or off.  When the
-interface is activated, new entries for Sweave'ing and LaTeX'ing
-thereafter are available from AUCTeX's "Command" menu.  Sweave'ing can,
-thus, be done by 'C-c C-c Sweave RET' without an inferior-ESS process.
-Similarly, LaTeX'ing can be done by 'C-c C-c LaTeXSweave RET'.  In both
-cases, the process can be monitored with 'C-c C-l'
-('TeX-recenter-output-buffer').  Open the viewer with 'C-c C-v'
-('TeX-view'), as usual in AUCTeX.
-
-\1f
-File: ess.info,  Node: ESS for R,  Next: ESS for SAS,  Prev: Extras,  Up: Top
-
-12 Overview of ESS features for the S family
-********************************************
-
-* Menu:
-
-* ESS(R)--Editing files::
-* iESS(R)--Inferior ESS processes::
-* Philosophies for using ESS(R)::
-* Example ESS usage::
-
-\1f
-File: ess.info,  Node: ESS(R)--Editing files,  Next: iESS(R)--Inferior ESS processes,  Up: ESS for R
-
-12.1 ESS[R]-Editing files
-=========================
-
-ESS[R] mode should be automatically turned on when visiting a file
-ending with an R or S suffix (*.R, *.S, *.s, etc), which enables the
-features discussed previously.  Alternatively, type 'M-x R-mode' to put
-the current buffer into R mode.  However, one will have to start up an
-inferior process to take advantage of the interactive features.
-
-\1f
-File: ess.info,  Node: iESS(R)--Inferior ESS processes,  Next: Philosophies for using ESS(R),  Prev: ESS(R)--Editing files,  Up: ESS for R
-
-12.2 iESS[R]-Inferior ESS processes
-===================================
-
-To start up iESS mode for R, use:
-        M-x R
-        M-x S+3
-        M-x S4
-        M-x S+5
-        M-x S+6
-
-(for R, S-PLUS 3.x, S4, S+5, S+6 or S+7, respectively.  This assumes
-that you have access to each).
-
-   In the case that you wish to pass command line arguments to the
-starting R process, call it with the universal prefix.  To set command
-line arguments that apply to all future iESS sessions, set the variable
-'inferior-R-args'.
-
-   Note that R has some extremely useful command line arguments.  For
-example, '--vanilla' will ensure R starts up without loading in any init
-files.
-
-   If you have other versions of R or S available on the system, ESS is
-also able to start those versions.  How this exactly works depend on
-which OS you are using (details below).  The general principle,
-regardless of OS, is that ESS searches the paths listed in the variable
-'exec-path' for R binaries.  If ESS cannot find your R binaries, on Unix
-you can change the Unix environment variable 'PATH', as this variable is
-used to set 'exec-path'.
-
-   R on GNU/Linux systems and other Unix-like systems (macOS): If you
-have "R-3.6.3" on your 'exec-path', it can be started using 'M-x
-R-3.6.3'.  By default, ESS will find versions of R beginning "R-1",
-"R-2", ..., "R-7", "R-devel", or "R-patched".  If your versions of R are
-called other names, consider renaming them with a symbolic link or
-change the variable 'ess-r-runners-prefixes'.  To see which functions
-have been created for starting different versions of R, type 'M-x R-'
-and then hit [Tab].  These other versions of R can also be started from
-the "ESS->Start Process->Other" menu.
-
-   R on Windows systems: If you have "rw1081" on your 'exec-path', it
-can be started using 'M-x rw1081'.  By default, ESS will find versions
-of R located in directories parallel to the version of R in your 'PATH'.
-If your versions of R are called other names, you will need to change
-the variable 'ess-rterm-versions'.  To see which functions have been
-created for starting different versions of R, type 'M-x rw' and then hit
-[Tab].  These other versions of R can also be started from the
-"ESS->Start Process->Other" menu.
-
-   Once ESS has found these extra versions of R, it will then create a
-new function, called 'M-x run-ess-r-newest', which will call the newest
-version of R that it found.  (ESS examines the date in the first line of
-information from 'R --version' to determine which is newest.)
-
-\1f
-File: ess.info,  Node: Philosophies for using ESS(R),  Next: Example ESS usage,  Prev: iESS(R)--Inferior ESS processes,  Up: ESS for R
-
-12.3 Philosophies for using ESS[R]
-==================================
-
-There are two philosophies for using ESS. Most modern best practices
-prefer the first.  ESS is configured for the first, and this is what the
-manual focuses on.
-
-   1: The source code is real.  Objects are realizations of the source
-code.  Source for EVERY user modified object is placed in a particular
-directory or directories, for later editing and retrieval.
-
-   2: R objects are real.  Source code is a temporary realization of the
-objects.  Dumped buffers should not be saved.
-_We_strongly_discourage_this_approach_.  However, if you insist, add the
-following lines to your Emacs configuration file:
-     (setq ess-keep-dump-files nil)
-     (setq ess-delete-dump-files t)
-     (setq ess-mode-silently-save nil)
-
-\1f
-File: ess.info,  Node: Example ESS usage,  Prev: Philosophies for using ESS(R),  Up: ESS for R
-
-12.4 Example ESS usage
-======================
-
-Comments as to what should be happening are prefixed by "##".
-
-         ### Data Analysis Example
-
-         ## Open the file you want with
-         C-x C-f myfile.R
-
-         ## Edit as appropriate, then start and switch to an *R*
-         process buffer with
-         C-c C-z
-
-         ## A new buffer *R* will appear. R will have been started
-         ## in this buffer. The buffer is in iESS [R] mode.
-
-         ## Return to the script
-         C-z (or C-c C-z if you have pressed other keys in between)
-
-         ## Send current region (if active), or function, or paragraph at
-         point with
-         C-M-x
-
-         ## Send current region or function or paragraph and step with
-         C-c C-c
-
-         ## Send current line with
-         C-RET
-
-         ## or load the entire buffer with
-         C-c C-l
-
-         ## Save the revised myfile.R with
-         C-x C-s.
-
-         ## Save the entire *R* interaction buffer with
-         C-x C-s.
-
-         ## Search for documentation with
-         C-c C-d
-
-         ## Investigate available ESS commands with
-         C-c C-h
-
-         ## You will be prompted for a file name. The recommended name is
-         ## myfile.Rout. With this suffix, the file will be opened in
-         ## ess-transcript.
-
-
-\1f
-File: ess.info,  Node: ESS for SAS,  Next: ESS for BUGS,  Prev: ESS for R,  Up: Top
-
-13 ESS for SAS
-**************
-
-* Menu:
-
-* ESS(SAS)--Design philosophy::
-* ESS(SAS)--Editing files::
-* ESS(SAS)--TAB key::
-* ESS(SAS)--Batch SAS processes::
-* ESS(SAS)--Function keys for batch processing::
-* iESS(SAS)--Interactive SAS processes::
-* iESS(SAS)--Common problems::
-* ESS(SAS)--Graphics::
-* ESS(SAS)--Windows::
-ESS[SAS] was designed for use with SAS.  It is descended from emacs
-macros developed by John Sall for editing SAS programs and 'SAS-mode' by
-Tom Cook.  Those editing features and new advanced features are part of
-ESS[SAS].  The user interface of ESS[SAS] has similarities with ESS[S]
-and the SAS Display Manager.
-
-\1f
-File: ess.info,  Node: ESS(SAS)--Design philosophy,  Next: ESS(SAS)--Editing files,  Up: ESS for SAS
-
-13.1 ESS[SAS]-Design philosophy
-===============================
-
-ESS[SAS] was designed to aid the user in writing and maintaining SAS
-programs, such as 'FOO.sas'.  Both interactive and batch submission of
-SAS programs is supported.
-
-   ESS[SAS] was written with two primary goals.
-  1. The emacs text editor provides a powerful and flexible development
-     environment for programming languages.  These features are a boon
-     to all programmers and, with the help of ESS[SAS], to SAS users as
-     well.
-  2. Although a departure from SAS Display Manager, ESS[SAS] provides
-     similar key definitions to give novice ESS[SAS] users a head start.
-     Also, inconvenient SAS Display Manager features, like remote
-     submission and syntax highlighting, are provided transparently;
-     appealing to advanced ESS[SAS] users.
-
-\1f
-File: ess.info,  Node: ESS(SAS)--Editing files,  Next: ESS(SAS)--TAB key,  Prev: ESS(SAS)--Design philosophy,  Up: ESS for SAS
-
-13.2 ESS[SAS]-Editing files
-===========================
-
-ESS[SAS] is the mode for editing SAS language files.  This mode handles:
-
-   * proper indenting, generated by both <TAB> and <RET>.
-   * color and font choices based on syntax.
-   * ability to save and submit the file you are working on as a batch
-     SAS process with a single keypress and to continue editing while it
-     is runs in the background.
-   * capability of killing the batch SAS process through the '*shell*'
-     buffer or allow the SAS process to keep on running after you exit
-     emacs.
-   * single keypress navigation of '.sas', '.log' and '.lst' files
-     ('.log' and '.lst' files are refreshed with each keypress).
-   * ability to send the contents of an entire buffer, a highlighted
-     region, or a single line to an interactive SAS process.
-   * ability to switch between processes which would be the target of
-     the buffer (for the above).
-
-   ESS[SAS] is automatically turned on when editing a file with a '.sas'
-suffix (or other extension, if specified via 'auto-mode-alist').  The
-function keys can be enabled to use the same function keys that the SAS
-Display Manager does.  The interactive capabilities of ESS require you
-to start an inferior SAS process with 'M-x SAS' (*Note
-iESS(SAS)--Interactive SAS processes::.)
-
-   At this writing, the indenting and syntax highlighting are generally
-correct.  Known issues: for multiple line '*' or '%*' comments, only the
-first line is highlighted; for '.log' files, only the first line of a
-'NOTE:', 'WARNING:' or 'ERROR:' message is highlighted; unmatched
-single/double quotes in 'CARDS' data lines are *NOT* ignored; in an
-iterative 'DO' statement, 'TO' and 'BY' are not highlighted.
-
-\1f
-File: ess.info,  Node: ESS(SAS)--TAB key,  Next: ESS(SAS)--Batch SAS processes,  Prev: ESS(SAS)--Editing files,  Up: ESS for SAS
-
-13.3 ESS[SAS]-<TAB> key
-=======================
-
-Two options.  The <TAB> key is bound by default to 'sas-indent-line'.
-This function is used to syntactically indent SAS code so 'PROC' and
-'RUN' are in the left margin, other statements are indented
-'sas-indent-width' spaces from the margin, continuation lines are
-indented 'sas-indent-width' spaces in from the beginning column of that
-statement.  This is the type of functionality that emacs provides in
-most programming language modes.  This functionality is activated by
-placing the following line in your initialization file prior to a
-'require'/'load':
-     (setq ess-sas-edit-keys-toggle nil)
-
-   ESS provides an alternate behavior for <TAB> that makes it behave as
-it does in SAS Display Manager, i.e.  move the cursor to the next stop.
-The alternate behavior also provides a "TAB" backwards, 'C-<TAB>', that
-moves the cursor to the stop to the left and deletes any characters
-between them.  This functionality is obtained by placing the following
-line in your initialization file prior to a 'require'/'load':
-     (setq ess-sas-edit-keys-toggle t)
-   Under the alternate behavior, <TAB> is bound to 'M-x tab-to-tab-stop'
-and the stops are defined by 'ess-sas-tab-stop-list'.
-
-\1f
-File: ess.info,  Node: ESS(SAS)--Batch SAS processes,  Next: ESS(SAS)--Function keys for batch processing,  Prev: ESS(SAS)--TAB key,  Up: ESS for SAS
-
-13.4 ESS[SAS]-Batch SAS processes
-=================================
-
-Submission of a SAS batch job is dependent on your environment.
-'ess-sas-submit-method' is determined by your operating system and your
-shell.  It defaults to ''sh' unless you are running Windows or Mac
-Classic.  Under Windows, it will default to ''sh' if you are using a
-UNIX-imitating shell; otherwise ''ms-dos' for an MS-DOS shell.  On
-macOS, it will default to ''sh', but under Mac Classic, it defaults to
-''apple-script'.  You will also set this to ''sh' if the SAS batch job
-needs to run on a remote machine rather than your local machine.  This
-works transparently if you are editing the remote file via ange-ftp/EFS
-or tramp.  Note that 'ess-sas-shell-buffer-remote-init' is a Local
-Variable that defaults to '"ssh"' which will be used to open the buffer
-on the remote host and it is assumed that no password is necessary, i.e.
-you are using 'ssh-agent'/'ssh-add' or the equivalent (see the
-discussion about Local Variables below if you need to change the
-default).
-
-   However, if you are editing the file locally and transferring it back
-and forth with Kermit, you need some additional steps.  First, start
-Kermit locally before remotely logging in.  Open a local copy of the
-file with the 'ess-kermit-prefix' character prepended (the default is
-'"#"').  Execute the command 'M-x ess-kermit-get' which automatically
-brings the contents of the remote file into your local copy.  If you
-transfer files with Kermit manually in a '*shell*' buffer, then note
-that the Kermit escape sequence is 'C-q C-\ c' rather than 'C-\ c' which
-it would be in an ordinary terminal application, i.e.  not in an emacs
-buffer.  Lastly, note that the remote Kermit command is specified by
-'ess-kermit-command'.
-
-   The command used by the 'SUBMIT' function key (<F3> or <F8>) to
-submit a batch SAS job, whether local or remote, is
-'ess-sas-submit-command' which defaults to 'sas-program'.  'sas-program'
-is '"invoke SAS using program file"' for Mac Classic and '"sas"'
-otherwise.  However, you may have to alter 'ess-sas-submit-command' for
-a particular program, so it is defined as buffer-local.  Conveniently,
-it can be set at the end of the program:
-     endsas;
-     Local variables:
-     ess-sas-submit-command: "sas8"
-     End:
-
-   The command line is also made of 'ess-sas-submit-pre-command',
-'ess-sas-submit-post-command' and 'ess-sas-submit-command-options' (the
-last of which is also buffer-local).  Here are some examples for your
-'~/.emacs' or '~/.emacs.d/init.el' file (you may also use
-'M-x customize-variable'):
-     ;'sh default
-     (setq ess-sas-submit-pre-command "nohup")
-     ;'sh default
-     (setq ess-sas-submit-post-command "-rsasuser &")
-     ;'sh example
-     (setq-default ess-sas-submit-command "/usr/local/sas/sas")
-     ;'ms-dos default
-     (setq ess-sas-submit-pre-command "start")
-     ;'ms-dos default
-     (setq ess-sas-submit-post-command "-rsasuser -icon")
-     ;Windows example
-     (setq-default ess-sas-submit-command "c:/progra~1/sas/sas.exe")
-     ;Windows example
-     (setq-default ess-sas-submit-command "c:\\progra~1\\sas\\sas.exe")
-
-   There is a built-in delay before a batch SAS job is submitted when
-using a UNIX-imitating shell under Windows.  This is necessary in many
-cases since the shell might not be ready to receive a command.  This
-delay is currently set high enough so as not to be a problem.  But,
-there may be cases when it needs to be set higher, or could be set much
-lower to speed things up.  You can over-ride the default in your
-'~/.emacs' or '~/.emacs.d/init.el' file by:
-     (setq ess-sleep-for 0.2)
-
-   For example, '(setq ess-sas-global-unix-keys t)' keys shown, '(setq
-ess-sas-global-pc-keys t)' in parentheses; ESS[SAS] function keys are
-presented in the next section.  Open the file you want to work with
-'C-x C-f foo.sas'.  'FOO.sas' will be in ESS[SAS] mode.  Edit as
-appropriate, then save and submit the batch SAS job.
-     <F3> (<F8>)
-   The job runs in the '*shell*' buffer while you continue to edit
-'FOO.sas'.  If 'ess-sas-submit-method' is ''sh', then the message buffer
-will display the shell notification when the job is complete.  The ''sh'
-setting also allows you to terminate the SAS batch job before it is
-finished.
-     <F8> (<F3>)
-   Terminating a SAS batch in the '*shell*' buffer.
-     kill PID
-   You may want to visit the '.log' (whether the job is still running or
-it is finished) and check for error messages.  The '.log' will be
-refreshed and you will be placed in it's buffer.  You will be taken to
-the first error message, if any.
-     <F5> (<F6>)
-   Goto the next error message, if any.
-     <F5> (<F6>)
-   Now, 'refresh' the '.lst' and go to it's buffer.
-     <F6> (<F7>)
-   If you wish to make changes, go to the '.sas' file with.
-     <F4> (<F5>)
-   Make your editing changes and submit again.
-     <F3> (<F8>)
-
-\1f
-File: ess.info,  Node: ESS(SAS)--Function keys for batch processing,  Next: iESS(SAS)--Interactive SAS processes,  Prev: ESS(SAS)--Batch SAS processes,  Up: ESS for SAS
-
-13.5 ESS[SAS]-Function keys for batch processing
-================================================
-
-The setup of function keys for SAS batch processing is unavoidably
-complex, but the usage of function keys is simple.  There are five
-distinct options:
-
-   Option 1 (default).  Function keys in ESS[SAS] are not bound to Elisp
-commands.  This is in accordance with the GNU Elisp Coding Standards
-(GECS) which do not allow function keys to be bound so that they are
-available to the user.
-
-   Options 2-5.  Since GECS does not allow function keys to be bound by
-modes, these keys are often unused.  So, ESS[SAS] provides users with
-the option of binding Elisp commands to these keys.  Users who are
-familiar with SAS will, most likely, want to duplicate the function key
-capabilities of the SAS Display Manager.  There are four options (noted
-in parentheses).
-
-  a. SAS Display Manager has different function key definitions for UNIX
-     (2, 4) and Windows (3, 5); ESS[SAS] can use either.
-  b. The ESS[SAS] function key definitions can be active in all buffers
-     (global: 4, 5) or limited (local: 2, 3) only to buffers with files
-     that are associated with ESS[SAS] as specified in your
-     'auto-mode-alist'.
-
-   The distinction between local and global is subtle.  If you want the
-ESS[SAS] definitions to work when you are in the '*shell*' buffer or
-when editing files other than the file extensions that ESS[SAS]
-recognizes, you will most likely want to use the global definitions.  If
-you want your function keys to understand SAS batch commands when you
-are editing SAS files, and to behave normally when editing other files,
-then you will choose the local definitions.  The option can be chosen by
-the person installing ESS for a site or by an individual.
-
-  a. For a site installation or an individual, place *ONLY ONE* of the
-     following lines in your initialization file prior to a
-     'require'/'load'.  ESS[SAS] function keys are available in ESS[SAS]
-     if you choose either 2 or 3 and in all modes if you choose 4 or 5:
-          ;;2; (setq ess-sas-local-unix-keys t)
-          ;;3; (setq ess-sas-local-pc-keys t)
-          ;;4; (setq ess-sas-global-unix-keys t)
-          ;;5; (setq ess-sas-global-pc-keys t)
-
-     The names '-unix-' and '-pc-' have nothing to do with the operating
-     system that you are running.  Rather, they mimic the definitions
-     that the SAS Display Manager uses by default on those platforms.
-
-  b. If your site installation has configured the keys contrary to your
-     liking, then you must call the appropriate function.
-           (load "ess-site") ;; local-unix-keys
-           (ess-sas-global-pc-keys)
-
-   Finally, we get to what the function keys actually do.  You may
-recognize some of the nicknames as SAS Display Manager commands (they
-are in all capitals).
-
-UNIX     PC       Nickname
-<F2>     <F2>     'refresh'
-                  revert the current buffer with the file of the same name if the file is
-                  newer than the buffer
-<F3>     <F8>     'SUBMIT'
-                  save the current '.sas' file (which is either the '.sas' file in the
-                  current buffer or the '.sas' file associated with the '.lst' or '.log'
-                  file in the current buffer) and submit the file as a batch SAS job
-<F4>     <F5>     'PROGRAM'
-                  switch buffer to '.sas' file
-<F5>     <F6>     'LOG'
-                  switch buffer to '.log' file, 'refresh' and goto next error message, if
-                  any
-<F6>     <F7>     'OUTPUT'
-                  switch buffer to '.lst' file and 'refresh'
-<F7>     <F4>     'filetype-1'
-                  switch buffer to 'filetype-1' (defaults to '.txt') file and 'refresh'
-<F8>     <F3>     'shell'
-                  switch buffer to '*shell*'
-<F9>     <F9>     'VIEWTABLE'
-                  open an interactive 'PROC FSEDIT' session on the SAS dataset near point
-<F10>    <F10>    toggle-log
-                  toggle ESS[SAS] for '.log' files; useful for certain debugging situations
-<F11>    <F11>    'filetype-2'
-                  switch buffer to 'filetype-2' (defaults to '.dat') file and 'refresh'
-<F12>    <F12>    viewgraph
-                  open a 'GSASFILE' near point for viewing either in emacs or with an
-                  external viewer
-'C-<F1>' 'C-<F1>' rtf-portrait
-                  create an MS RTF portrait file from the current buffer with a file
-                  extension of '.rtf'
-'C-<F2>' 'C-<F2>' rtf-landscape
-                  create an MS RTF landscape file from the current buffer with a file
-                  extension of '.rtf'
-'C-<F3>' 'C-<F8>' submit-region
-                  write region to 'ess-temp.sas' and submit
-'C-<F5>' 'C-<F6>' append-to-log
-                  append 'ess-temp.log' to the current '.log' file
-'C-<F6>' 'C-<F7>' append-to-output
-                  append 'ess-temp.lst' to the current '.lst' file
-'C-<F9>' 'C-<F9>' 'INSIGHT'
-                  open an interactive 'PROC INSIGHT' session on the SAS dataset near point
-'C-<F10>''C-<F10>'toggle-listing
-                  toggle ESS[SAS] for '.lst' files; useful for toggling read-only
-
-   'SUBMIT', 'PROGRAM', 'LOG' and 'OUTPUT' need no further explanation
-since they mimic the SAS Display Manager commands and related function
-key definitions.  However, six other keys have been provided for
-convenience and are described below.
-
-   'shell' switches you to the '*shell*' buffer where you can interact
-with your operating system.  This is especially helpful if you would
-like to kill a SAS batch job.  You can specify a different buffer name
-to associate with a SAS batch job (besides '*shell*') with the
-buffer-local variable 'ess-sas-shell-buffer'.  This allows you to have
-multiple buffers running SAS batch jobs on multiple local/remote
-computers that may rely on different methods specified by the
-buffer-local variable 'ess-sas-submit-method'.
-
-   <F2> performs the 'refresh' operation on the current buffer.
-'refresh' compares the buffer's last modified date/time with the file's
-last modified date/time and replaces the buffer with the file if the
-file is newer.  This is the same operation that is automatically
-performed when 'LOG', 'OUTPUT', 'filetype-1' or <F11> are pressed.
-
-   'filetype-1' switches you to a file with the same file name as your
-'.sas' file, but with a different extension ('.txt' by default) and
-performs 'refresh'.  You can over-ride the default extension; for
-example in your '~/.emacs' or '~/.emacs.d/init.el' file:
-     (setq ess-sas-suffix-1 "csv") ; for example
-
-   <F9> will prompt you for the name of a permanent SAS dataset near
-point to be opened for viewing by 'PROC FSEDIT'.  You can control the
-SAS batch command-line with 'ess-sas-data-view-submit-options'.  For
-controlling the SAS batch commands, you have the global variables
-'ess-sas-data-view-libname' and 'ess-sas-data-view-fsview-command' as
-well as the buffer-local variable 'ess-sas-data-view-fsview-statement'.
-If you have your SAS 'LIBNAME' defined in '~/autoexec.sas', then the
-defaults for these variables should be sufficient.
-
-   Similarly, 'C-<F9>' will prompt you for the name of a permanent SAS
-dataset near point to be opened for viewing by 'PROC INSIGHT'.  You can
-control the SAS batch command-line with
-'ess-sas-data-view-submit-options'.  For controlling the SAS batch
-commands, you have the global variables 'ess-sas-data-view-libname' and
-'ess-sas-data-view-insight-command' as well as the buffer-local variable
-'ess-sas-data-view-insight-statement'.
-
-   <F10> toggles ESS[SAS] mode for '.log' files which is off by default
-(technically, it is 'SAS-log-mode', but it looks the same).  The syntax
-highlighting can be helpful in certain debugging situations, but large
-'.log' files may take a long time to highlight.
-
-   <F11> is the same as 'filetype-1' except it is '.dat' by default.
-
-   <F12> will prompt you for the name of a 'GSASFILE' near the point in
-'.log' to be opened for viewing either with emacs or with an external
-viewer.  Depending on your version of emacs and the operating system you
-are using, emacs may support '.gif' and '.jpg' files internally.  You
-may need to change the following variables for your own situation.
-'ess-sas-graph-view-suffix-regexp' is a regular expression of supported
-file types defined via file name extensions.
-'ess-sas-graph-view-viewer-default' is the default external viewer for
-your platform.  'ess-sas-graph-view-viewer-alist' is an alist of
-exceptions to the default; i.e.  file types and their associated viewers
-which will be used rather than the default viewer.
-     (setq ess-sas-graph-view-suffix-regexp (concat "[.]\\([eE]?[pP][sS]\\|"
-     "[pP][dD][fF]\\|[gG][iI][fF]\\|[jJ][pP][eE]?[gG]\\|"
-     "[tT][iI][fF][fF]?\\)")) ;; default
-     (setq ess-sas-graph-view-viewer-default "kodakimg") ;; Windows default
-     (setq ess-sas-graph-view-viewer-default "sdtimage") ;; Solaris default
-     (setq ess-sas-graph-view-viewer-alist
-       '(("[eE]?[pP][sS]" . "gv") ("[pP][dD][fF]" . "gv")) ;; default w/ gv
-
-   'C-<F2>' produces US landscape by default, however, it can produce A4
-landscape (first line for "global" key mapping, second for "local"):
-     (global-set-key [(control f2)] 'ess-sas-rtf-a4-landscape)
-     (define-key sas-mode-local-map [(control f2)] 'ess-sas-rtf-a4-landscape)
-
-\1f
-File: ess.info,  Node: iESS(SAS)--Interactive SAS processes,  Next: iESS(SAS)--Common problems,  Prev: ESS(SAS)--Function keys for batch processing,  Up: ESS for SAS
-
-13.6 iESS[SAS]-Interactive SAS processes
-========================================
-
-Inferior ESS (iESS) is the method for interfacing with interactive
-statistical processes (programs).  iESS[SAS] is what is needed for
-interactive SAS programming.  iESS[SAS] works best with the SAS
-command-line option settings '"-stdio -linesize 80 -noovp
--nosyntaxcheck"' (the default of 'inferior-SAS-args').
-
-     '-stdio'
-                 required to make the redirection of stdio work
-     '-linesize 80'
-                 keeps output lines from folding on standard terminals
-     '-noovp'
-                 prevents error messages from printing 3 times
-     '-nosyntaxcheck'
-                 permits recovery after syntax errors
-
-   To start up iESS[SAS] mode, use:
-        M-x SAS
-
-   The '*SAS:1.log*' buffer in 'ESStr' mode corresponds to the file
-'FOO.log' in SAS batch usage and to the 'SAS: LOG' window in the SAS
-Display Manager.  All commands submitted to SAS, informative messages,
-warnings, and errors appear here.
-
-   The '*SAS:1.lst*' buffer in 'ESSlst' mode corresponds to the file
-'FOO.lst' in SAS batch usage and to the 'SAS: OUTPUT' window in the SAS
-Display Manager.  All printed output appears in this window.
-
-   The '*SAS:1*' buffer exists solely as a communications buffer.  The
-user should never use this buffer directly.  Files are edited in the
-'FOO.sas' buffer.  The 'C-c C-r' key in ESS[SAS] is the functional
-equivalent of bringing a file into the 'SAS: PROGRAM EDITOR' window
-followed by 'SUBMIT'.
-
-   For example, open the file you want to work with.
-     C-x C-f foo.sas
-   'FOO.sas' will be in ESS[SAS] mode.  Edit as appropriate, and then
-start up SAS with the cursor in the 'FOO.sas' buffer.
-     M-x SAS
-   Four buffers will appear on screen:
-Buffer         Mode              Description
-'FOO.sas'      'ESS[SAS]'        your source file
-'*SAS:1*'      'iESS[SAS:1]'     iESS communication buffer
-'*SAS:1.log*'  'Shell ESStr      SAS log information
-               []'
-'*SAS:1.lst*'  'Shell ESSlst     SAS listing information
-               []'
-   If you would prefer each of the four buffers to appear in its own
-individual frame, you can arrange for that.  Place the cursor in the
-buffer displaying 'FOO.sas'.  Enter the sequence 'C-c C-w'.  The cursor
-will normally be in buffer 'FOO.sas'.  If not, put it there and
-'C-x b FOO.sas'.
-
-   Send regions, lines, or the entire file contents to SAS (regions are
-most useful: a highlighted region will normally begin with the keywords
-'DATA' or 'PROC' and end with 'RUN;'), 'C-c C-r'.
-
-   Information appears in the log buffer, analysis results in the
-listing buffer.  In case of errors, make the corrections in the
-'FOO.sas' buffer and resubmit with another 'C-c C-r'.
-
-   At the end of the session you may save the log and listing buffers
-with the usual 'C-x C-s' commands.  You will be prompted for a file
-name.  Typically, the names 'FOO.log' and 'FOO.lst' will be used.  You
-will almost certainly want to edit the saved files before including them
-in a report.  The files are read-only by default.  You can make them
-writable by the emacs command 'C-x C-q'.
-
-   At the end of the session, the input file 'FOO.sas' will typically
-have been revised.  You can save it.  It can be used later as the
-beginning of another iESS[SAS] session.  It can also be used as a batch
-input file to SAS.
-
-   The '*SAS:1*' buffer is strictly for ESS use.  The user should never
-need to read it or write to it.  Refer to the '.lst' and '.log' buffers
-for monitoring output!
-
-   Troubleshooting: *Note iESS(SAS)--Common problems::.
-
-\1f
-File: ess.info,  Node: iESS(SAS)--Common problems,  Next: ESS(SAS)--Graphics,  Prev: iESS(SAS)--Interactive SAS processes,  Up: ESS for SAS
-
-13.7 iESS[SAS]-Common problems
-==============================
-
-  1. iESS[SAS] does not work on Windows.  In order to run SAS inside an
-     emacs buffer, it is necessary to start SAS with the '-stdio'
-     option.  SAS does not support the '-stdio' option on Windows.
-  2. If 'M-x SAS' gives errors upon startup, check the following:
-        * you are running Windows: see 1.
-        * 'ess-sas-sh-command' (from the ESS 'etc' directory) needs to
-          be executable; too check, type 'M-x dired'; if not, fix it as
-          follows, type 'M-:', then at the minibuffer prompt 'Eval:',
-          type '(set-file-modes "ess-sas-sh-command" 493)'.
-        * 'sas' isn't in your executable path; to verify, type 'M-:' and
-          at the minibuffer prompt 'Eval:', type '(executable-find
-          "sas")'
-  3. 'M-x SAS' starts SAS Display Manager.  Probably, the command 'sas'
-     on your system calls a shell script.  In that case you will need to
-     locate the real 'sas' executable and link to it.  You can execute
-     the UNIX command:
-          find / -name sas -print
-     Now place a soft link to the real 'sas' executable in your '~/bin'
-     directory, with for example
-          cd ~/bin
-          ln -s /usr/local/sas9/sas sas
-   Check your 'PATH' environment variable to confirm that '~/bin'
-appears before the directory in which the 'sas' shell script appears.
-
-\1f
-File: ess.info,  Node: ESS(SAS)--Graphics,  Next: ESS(SAS)--Windows,  Prev: iESS(SAS)--Common problems,  Up: ESS for SAS
-
-13.8 ESS[SAS]-Graphics
-======================
-
-Output from a SAS/GRAPH 'PROC' can be displayed in a SAS/GRAPH window
-for SAS batch on Windows or for both SAS batch and interactive with
-XWindows on UNIX.  If you need to create graphics files and view them
-with <F12>, then include the following (either in 'FOO.sas' or in
-'~/autoexec.sas'):
-     filename gsasfile 'graphics.ps';
-     goptions device=ps gsfname=gsasfile gsfmode=append;
-   'PROC PLOT' graphs can be viewed in the listing buffer.  You may wish
-to control the vertical spacing to allow the entire plot to be visible
-on screen, for example:
-     proc plot;
-         plot a*b / vpos=25;
-     run;
-
-\1f
-File: ess.info,  Node: ESS(SAS)--Windows,  Prev: ESS(SAS)--Graphics,  Up: ESS for SAS
-
-13.9 ESS[SAS]-Windows
-=====================
-
-   * iESS[SAS] does not work on Windows.  *Note iESS(SAS)--Common
-     problems::.
-
-   * ESS[SAS] mode for editing SAS language files works very well.
-     *Note ESS(SAS)--Editing files::.
-
-   * There are two execution options for SAS on Windows.  You can use
-     batch.  *Note ESS(SAS)--Batch SAS processes::.
-
-     Or you can mark regions with the mouse and submit the code with
-     'submit-region' or paste them into SAS Display Manager.
-
-\1f
-File: ess.info,  Node: ESS for BUGS,  Next: ESS for JAGS,  Prev: ESS for SAS,  Up: Top
-
-14 ESS for BUGS
-***************
-
-ESS[BUGS] provides 5 features.  First, BUGS syntax is described to allow
-for proper fontification of statements, distributions, functions,
-commands and comments in BUGS model files, command files and log files.
-Second, ESS creates templates for the command file from the model file
-so that a BUGS batch process can be defined by a single file.  Third,
-ESS provides a BUGS batch script that allows ESS to set BUGS batch
-parameters.  Fourth, key sequences are defined to create a command file
-and submit a BUGS batch process.  Lastly, interactive submission of BUGS
-commands is also supported.
-
-14.1 ESS[BUGS]-Model files
-==========================
-
-Model files with the '.bug' extension are edited in ESS[BUGS] mode.
-Three keys are bound for your use in ESS[BUGS], 'F2', 'C-c C-c' and '='.
-'F2' performs the same action as it does in ESS[SAS], *Note
-ESS(SAS)--Function keys for batch processing::.  'C-c C-c' performs the
-function 'ess-bugs-next-action' which you will use a lot.  Pressing it
-in an empty buffer for a model file will produce a template for you.
-'=' inserts the set operator, '<-'.
-
-14.2 ESS[BUGS]-Command files
-============================
-
-Files ending in '.bmd' are used for BUGS command files.  When you have
-finished editing your model file and press 'C-c C-c', a command file is
-created if one does not already exist.  When you are finished editing
-your command file, pressing 'C-c C-c' again will submit your command
-file as a batch job.
-
-14.3 ESS[BUGS]-Log files
-========================
-
-The '.bog' extension is used for BUGS log files.  The command line
-generated by ESS creates the '.bog' transcript file.
-
-\1f
-File: ess.info,  Node: ESS for JAGS,  Next: Mailing lists/bug reports,  Prev: ESS for BUGS,  Up: Top
-
-15 ESS for JAGS
-***************
-
-ESS[JAGS] provides 4 features.  First, JAGS syntax is described to allow
-for proper fontification of statements, distributions, functions,
-commands and comments in JAGS model files, command files and log files.
-Second, ESS creates templates for the command file from the model file
-so that a JAGS batch process can be defined by a single file.  Third,
-ESS provides a JAGS batch script that allows ESS to set JAGS batch
-parameters.  Fourth, key sequences are defined to create a command file
-and submit a JAGS batch process.
-
-15.1 ESS[JAGS]-Model files
-==========================
-
-Files with the '.jag' extension are edited in ESS[JAGS] mode.  Three
-keys are bound for your use in ESS[JAGS], 'F2', 'C-c C-c' and '='.  'F2'
-performs the same action as it does in ESS[SAS], *Note
-ESS(SAS)--Function keys for batch processing::.  'C-c C-c' performs the
-function 'ess-bugs-next-action' which you will use a lot.  Pressing it
-in an empty buffer for a model file will produce a template for you.
-'=' inserts the set operator, '<-'.
-
-   The first press of 'C-c C-c' will set up a template, including some
-necessary file-local variables in an empty buffer.  These variables are
-'ess-jags-chains', 'ess-jags-monitor', 'ess-jags-thin',
-'ess-jags-burnin' and 'ess-jags-update'; they appear in the 'Local
-Variables' section.  When you are finished editing your model file,
-pressing 'C-c C-c' will perform the necessary actions to build your
-command file for you.
-
-   The 'ess-jags-chains' variable is the number of chains that you want
-to initialize and sample from; defaults to 1.  The 'ess-jags-monitor'
-variable is a list of variables that you want monitored: encase each
-variable in double quotes.  When you press 'C-c C-c', the appropriate
-statements are created in the command file to monitor the list of
-variables.  By default, no variables are explicitly monitored which
-means JAGS will implicitly monitor all "default" variables.  The
-'ess-jags-thin' variable is the thinning parameter.  By default, the
-thinning parameter is set to 1, i.e.  no thinning.  The
-'ess-jags-burnin' variable is the number of initial samples to discard.
-By default, the burnin parameter is set to 10000.  The 'ess-jags-update'
-variable is the number of post-burnin samples to keep.  By default, the
-update parameter is set to 10000.  Both 'ess-jags-burnin' and
-'ess-jags-update' are multiplied by 'ess-jags-thin' since JAGS does not
-do it automatically.
-
-15.2 ESS[JAGS]-Command files
-============================
-
-Files ending in '.jmd' are for JAGS command files.  For your '.jmd'
-file, there is only one variable, 'ess-jags-command', in the 'Local
-Variables' section.  When you have finished editing your model file and
-press 'C-c C-c', a command file is created if one does not already
-exist.  When you are finished editing your command file, pressing 'C-c
-C-c' again will submit your command file as a batch job.  The
-'ess-jags-command' variable allows you to specify a different JAGS
-program to use to run your model; defaults to "jags".
-
-15.3 ESS[JAGS]-Log files
-========================
-
-The '.jog' extension is used for JAGS log files.  You may find 'F2'
-useful to refresh the '.jog' if the batch process over-writes or appends
-it.
-
-\1f
-File: ess.info,  Node: Mailing lists/bug reports,  Next: Customization,  Prev: ESS for JAGS,  Up: Top
-
-16 Bugs and Bug Reporting, Mailing Lists
-****************************************
-
-* Menu:
-
-* Bugs::
-* Reporting Bugs::
-* Mailing Lists::
-* Help with Emacs::
-
-\1f
-File: ess.info,  Node: Bugs,  Next: Reporting Bugs,  Up: Mailing lists/bug reports
-
-16.1 Bugs
-=========
-
-   * Commands like 'ess-display-help-on-object' and list completion
-     cannot be used while the user is entering a multi-line command.
-     The only real fix in this situation is to use another ESS process.
-
-   * The 'ess-eval-' commands can leave point in the ESS process buffer
-     in the wrong place when point is at the same position as the last
-     process output.  This proves difficult to fix, in general, as we
-     need to consider all _windows_ with 'window-point' at the right
-     place.
-
-   * It's possible to clear the modification flag (say, by saving the
-     buffer) with the edit buffer not having been loaded into S.
-
-   * Backup files can sometimes be left behind, even when
-     'ess-keep-dump-files' is 'nil'.
-
-   * Passing an incomplete S expression to 'ess-execute' causes ESS to
-     hang.
-
-   * The function-based commands don't always work as expected on
-     functions whose body is not a parenthesized or compound expression,
-     and don't even recognize anonymous functions (i.e.  functions not
-     assigned to any variable).
-
-   * Multi-line commands could be handled better by the command history
-     mechanism.
-
-   * Changes to the continuation prompt in R (e.g.  'options(continue =
-     " ")') are not automatically detected by ESS. Hence, for now, the
-     best thing is not to change the continuation prompt.  If you do
-     change the continuation prompt, you will need to change accordingly
-     the value of 'inferior-ess-secondary-prompt' in
-     'R-customize-alist'.
-
-\1f
-File: ess.info,  Node: Reporting Bugs,  Next: Mailing Lists,  Prev: Bugs,  Up: Mailing lists/bug reports
-
-16.2 Reporting Bugs
-===================
-
-Please post bug reports, suggestions etc.  on our github issue tracker
-(https://github.com/emacs-ess/ESS/issues); if not possible, e-mail them
-to <ESS-helpNOSPAMr-project.org>.
-
-   The easiest way to set this up, is within Emacs by typing
-
-   'M-x ess-submit-bug-report'
-
-   This also gives the maintainers valuable information about your
-installation which may help us to identify or even fix the bug.
-
-   If Emacs reports an error, backtraces can help us debug the problem.
-Type "M-x set-variable RET debug-on-error RET t RET". Then run the
-command that causes the error and you should see a *Backtrace* buffer
-containing debug information; send us that buffer.
-
-   Note that comments, suggestions, words of praise and large cash
-donations are also more than welcome.
-
-\1f
-File: ess.info,  Node: Mailing Lists,  Next: Help with Emacs,  Prev: Reporting Bugs,  Up: Mailing lists/bug reports
-
-16.3 Mailing Lists
-==================
-
-There is a mailing list for discussions and announcements relating to
-ESS. Join the list by sending an e-mail with "subscribe ess-help" (or
-"help") in the body to <ess-help-requestNOSPAMr-project.org>; contributions
-to the list may be mailed to <ess-helpNOSPAMr-project.org>.  Rest assured,
-this is a fairly low-volume mailing list.
-
-   The purposes of the mailing list include
-
-   * helping users of ESS to get along with it.
-   * discussing aspects of using ESS.
-   * suggestions for improvements.
-   * announcements of new releases of ESS.
-   * posting small patches to ESS.
-
-\1f
-File: ess.info,  Node: Help with Emacs,  Prev: Mailing Lists,  Up: Mailing lists/bug reports
-
-16.4 Help with Emacs
-====================
-
-Emacs is a complex editor with many abilities that we do not have space
-to describe here.  If you have problems with other features of Emacs
-(e.g.  printing), there are several sources to consult, including the
-Emacs FAQs (try 'M-x view-emacs-faq') and EmacsWiki
-(<https://www.emacswiki.org>).  Please consult them before asking on the
-mailing list about issues that are not specific to ESS.
-
-\1f
-File: ess.info,  Node: Customization,  Next: Indices,  Prev: Mailing lists/bug reports,  Up: Top
-
-Appendix A Customizing ESS
-**************************
-
-ESS can be easily customized to your taste simply by including the
-appropriate lines in your Emacs configuration file.  There are numerous
-variables which affect the behavior of ESS in certain situations which
-can be modified to your liking.  Keybindings may be set or changed to
-your preferences, and for per-buffer customizations hooks are also
-available.
-
-   Most of these variables can be viewed and set using the Custom
-facility within Emacs.  Type 'M-x customize-group RET ess RET' to see
-all the ESS variables that can be customized.  Variables are grouped by
-subject to make it easy to find related variables.
-
-\1f
-File: ess.info,  Node: Indices,  Prev: Customization,  Up: Top
-
-Indices
-*******
-
-* Menu:
-
-* Key index::
-* Function and program index::
-* Variable index::
-* Concept index::
-
-\1f
-File: ess.info,  Node: Key index,  Next: Function and program index,  Up: Indices
-
-Key index
-=========
-
-\0\b[index\0\b]
-* Menu:
-
-* ,:                                     Handy commands.       (line  6)
-* {:                                     Indenting.            (line 53)
-* }:                                     Indenting.            (line 53)
-* C-c C-. d:                             Package listing.      (line 30)
-* C-c C-. H:                             Package listing.      (line 33)
-* C-c C-. l:                             Package listing.      (line 10)
-* C-c C-. m:                             Package listing.      (line 21)
-* C-c C-. r:                             Package listing.      (line 13)
-* C-c C-. s:                             Package listing.      (line 27)
-* C-c C-. u:                             Package listing.      (line 17)
-* C-c C-. w:                             Package listing.      (line 24)
-* C-c C-b:                               Evaluating code.      (line 68)
-* C-c C-c:                               Other.                (line  9)
-* C-c C-c <1>:                           Evaluating code.      (line 41)
-* C-c C-e C-d:                           Edit buffer.          (line  9)
-* C-c C-e C-s:                           Styles.               (line 15)
-* C-c C-e s:                             Styles.               (line 15)
-* C-c C-f:                               Evaluating code.      (line 54)
-* C-c C-j:                               Evaluating code.      (line 47)
-* C-c C-o C-c:                           roxygen2.             (line 45)
-* C-c C-o C-h:                           roxygen2.             (line 72)
-* C-c C-o C-o:                           roxygen2.             (line 37)
-* C-c C-o C-r:                           roxygen2.             (line 51)
-* C-c C-o C-t:                           roxygen2.             (line 59)
-* C-c C-o n:                             roxygen2.             (line 69)
-* C-c C-o p:                             roxygen2.             (line 66)
-* C-c C-q:                               Hot keys.             (line 71)
-* C-C C-r:                               Evaluating code.      (line 61)
-* C-c C-s:                               Hot keys.             (line 34)
-* C-c C-t C-s:                           Namespaced Evaluation.
-                                                               (line 36)
-* C-c C-v:                               Hot keys.             (line 66)
-* C-c C-w:                               Clean.                (line 11)
-* C-c C-x:                               Hot keys.             (line 24)
-* C-c C-z:                               Other.                (line 13)
-* C-c M-b:                               Evaluating code.      (line 71)
-* C-c M-f:                               Evaluating code.      (line 57)
-* C-c M-j:                               Evaluating code.      (line 50)
-* C-c M-l:                               Hot keys.             (line 50)
-* C-c M-r:                               Evaluating code.      (line 64)
-* C-c RET:                               Resubmit.             (line 14)
-* C-c `:                                 Error Checking.       (line  9)
-* C-j:                                   Indenting.            (line 60)
-* C-M-a:                                 Other edit buffer commands.
-                                                               (line 10)
-* C-M-e:                                 Other edit buffer commands.
-                                                               (line 14)
-* C-M-h:                                 Other edit buffer commands.
-                                                               (line 18)
-* C-M-q:                                 Indenting.            (line 49)
-* C-M-x:                                 Evaluating code.      (line 38)
-* C-RET:                                 Evaluating code.      (line 34)
-* ESC C-a:                               Other edit buffer commands.
-                                                               (line 10)
-* ESC C-e:                               Other edit buffer commands.
-                                                               (line 14)
-* ESC C-h:                               Other edit buffer commands.
-                                                               (line 18)
-* ESC C-q:                               Indenting.            (line 49)
-* M-;:                                   Indenting.            (line 65)
-* M-?:                                   Object names.         (line 33)
-* M-C-q:                                 Indenting.            (line 49)
-* M-n l:                                 Sweave and AUCTeX.    (line 24)
-* M-n P:                                 Sweave and AUCTeX.    (line 30)
-* M-n s:                                 Sweave and AUCTeX.    (line 20)
-* M-RET:                                 Resubmit.             (line 10)
-* RET:                                   Command-line editing. (line 10)
-* RET <1>:                               Resubmit.             (line 18)
-* TAB:                                   Indenting.            (line 35)
-
-\1f
-File: ess.info,  Node: Function and program index,  Next: Variable index,  Prev: Key index,  Up: Indices
-
-Function and program index
-==========================
-
-\0\b[index\0\b]
-* Menu:
-
-* backward-kill-word:                    Command-line editing.
-                                                              (line  22)
-* comint-backward-matching-input:        Process buffer motion.
-                                                              (line  31)
-* comint-bol:                            Command-line editing.
-                                                              (line  31)
-* comint-copy-old-input:                 Transcript resubmit. (line  16)
-* comint-delete-output:                  Last command.        (line  24)
-* comint-dynamic-complete:               Object names.        (line  12)
-* comint-forward-matching-input:         Process buffer motion.
-                                                              (line  32)
-* comint-history-isearch-backward-regexp: Command History.    (line  32)
-* comint-interrupt-subjob:               Other.               (line   8)
-* comint-kill-input:                     Command-line editing.
-                                                              (line  26)
-* comint-next-input:                     Command History.     (line  18)
-* comint-next-matching-input-from-input: Command History.     (line  45)
-* comint-next-prompt:                    Process buffer motion.
-                                                              (line  15)
-* comint-previous-input:                 Command History.     (line  14)
-* comint-previous-matching-input-from-input: Command History. (line  41)
-* comint-previous-prompt:                Process buffer motion.
-                                                              (line  11)
-* comint-show-output:                    Last command.        (line  20)
-* dump():                                Edit buffer.         (line  35)
-* ess-change-directory:                  Package listing.     (line  29)
-* ess-cleanup:                           Hot keys.            (line  71)
-* ess-cleanup <1>:                       Help.                (line 170)
-* ess-complete-object-name:              Object names.        (line  32)
-* ess-describe-help-mode:                Help.                (line  21)
-* ess-display-help-on-object:            Hot keys.            (line  65)
-* ess-display-help-on-object <1>:        Help.                (line   8)
-* ess-display-help-on-object <2>:        Help.                (line  25)
-* ess-dump-object-into-edit-buffer:      Edit buffer.         (line   8)
-* ess-electric-brace:                    Indenting.           (line  52)
-* ess-eval-buffer:                       Evaluating code.     (line  67)
-* ess-eval-buffer-and-go:                Evaluating code.     (line  70)
-* ess-eval-function:                     Evaluating code.     (line  53)
-* ess-eval-function-and-go:              Evaluating code.     (line  56)
-* ess-eval-line:                         Evaluating code.     (line  46)
-* ess-eval-line-and-go:                  Evaluating code.     (line  49)
-* ess-eval-line-and-step:                Help.                (line 106)
-* ess-eval-region:                       Evaluating code.     (line  60)
-* ess-eval-region <1>:                   Help.                (line 111)
-* ess-eval-region-and-go:                Evaluating code.     (line  63)
-* ess-eval-region-or-function-or-paragraph: Evaluating code.  (line  37)
-* ess-eval-region-or-function-or-paragraph-and-step: Evaluating code.
-                                                              (line  40)
-* ess-eval-region-or-line-and-step:      Evaluating code.     (line  33)
-* ess-execute-objects:                   Hot keys.            (line  23)
-* ess-execute-search:                    Hot keys.            (line  33)
-* ess-goto-beginning-of-function-or-para: Other edit buffer commands.
-                                                              (line   9)
-* ess-goto-end-of-function-or-para:      Other edit buffer commands.
-                                                              (line  13)
-* ess-handy-commands:                    Handy commands.      (line   6)
-* ess-handy-commands <1>:                Handy commands.      (line   6)
-* ess-indent-command:                    roxygen2.            (line  90)
-* ess-indent-exp:                        Indenting.           (line  48)
-* ess-indent-or-complete:                Indenting.           (line  34)
-* ess-load-file:                         Hot keys.            (line  49)
-* ess-load-file <1>:                     Loading.             (line  11)
-* ess-mark-function:                     Other edit buffer commands.
-                                                              (line  17)
-* ess-parse-errors:                      Hot keys.            (line  54)
-* ess-parse-errors <1>:                  Error Checking.      (line   9)
-* ess-quit:                              Hot keys.            (line  70)
-* ess-quit <1>:                          Help.                (line 170)
-* ess-R-complete-object-name:            roxygen2.            (line  80)
-* ess-r-outline-level:                   Outline.             (line   6)
-* ess-r-package-list-available-packages: Package listing.     (line  12)
-* ess-r-package-list-local-packages:     Package listing.     (line   9)
-* ess-r-package-update-packages:         Package listing.     (line  16)
-* ess-r-set-evaluation-env:              Namespaced Evaluation.
-                                                              (line  35)
-* ess-remote:                            ESS processes on Remote Computers.
-                                                              (line   9)
-* ess-request-a-process:                 Multiple ESS processes.
-                                                              (line  18)
-* ess-resynch:                           Object names.        (line  52)
-* ess-roxy-hide-all:                     roxygen2.            (line  71)
-* ess-roxy-move-beginning-of-line:       roxygen2.            (line  97)
-* ess-roxy-next-entry:                   roxygen2.            (line  68)
-* ess-roxy-preview-HTML:                 roxygen2.            (line  58)
-* ess-roxy-preview-Rd:                   roxygen2.            (line  50)
-* ess-roxy-previous-entry:               roxygen2.            (line  65)
-* ess-roxy-toggle-roxy-region:           roxygen2.            (line  44)
-* ess-roxy-update-entry:                 roxygen2.            (line  36)
-* ess-rutils-html-docs:                  Package listing.     (line  32)
-* ess-rutils-load-workspace:             Package listing.     (line  23)
-* ess-rutils-rm-all:                     Package listing.     (line  20)
-* ess-rutils-save-workspace:             Package listing.     (line  26)
-* ess-set-style:                         Styles.              (line  14)
-* ess-skip-to-help-section:              Help.                (line  55)
-* ess-skip-to-next-section:              Help.                (line  46)
-* ess-skip-to-previous-section:          Help.                (line  46)
-* ess-smart-comma:                       Handy commands.      (line   6)
-* ess-submit-bug-report:                 Reporting Bugs.      (line   6)
-* ess-switch-to-end-of-ESS:              Help.                (line 117)
-* ess-switch-to-inferior-or-script-buffer: Other.             (line  12)
-* ess-swv-latex:                         Sweave and AUCTeX.   (line  23)
-* ess-swv-PDF:                           Sweave and AUCTeX.   (line  29)
-* ess-swv-PS:                            Sweave and AUCTeX.   (line  26)
-* ess-swv-weave:                         Sweave and AUCTeX.   (line  19)
-* ess-tracebug:                          ESS tracebug.        (line   6)
-* ess-transcript-clean-region:           Clean.               (line  10)
-* ess-transcript-copy-command:           Resubmit.            (line  13)
-* ess-transcript-send-command:           Resubmit.            (line   9)
-* ess-transcript-send-command-and-move:  Resubmit.            (line  17)
-* ess-use-ido, ess-completing-read:      Minibuffer completion.
-                                                              (line   6)
-* fill-paragraph:                        roxygen2.            (line  94)
-* getting started with tracebug:         Getting started with tracebug.
-                                                              (line   6)
-* inferior-ess-send-input:               Command-line editing.
-                                                              (line   9)
-* mark-paragraph:                        roxygen2.            (line  85)
-* newline-and-indent:                    roxygen2.            (line 102)
-* objects():                             Hot keys.            (line  24)
-* outline-minor-mode:                    Outline.             (line   6)
-* printer():                             printer.             (line  11)
-* q():                                   Hot keys.            (line  71)
-* R:                                     Starting up.         (line  11)
-* S:                                     Starting up.         (line  11)
-* search():                              Hot keys.            (line  34)
-* search() <1>:                          Object names.        (line  19)
-* source():                              Evaluating code.     (line  20)
-* source() <1>:                          Loading.             (line  11)
-* STERM:                                 Statistical Process running in ESS?.
-                                                              (line   6)
-
-\1f
-File: ess.info,  Node: Variable index,  Next: Concept index,  Prev: Function and program index,  Up: Indices
-
-Variable index
-==============
-
-\0\b[index\0\b]
-* Menu:
-
-* comint-delimiter-argument-list:        History expansion.    (line 28)
-* comint-input-ring-size:                Command History.      (line  9)
-* comment-column:                        Indenting.            (line 24)
-* ess-ask-about-transfile:               Customizing startup.  (line 36)
-* ess-ask-about-transfile <1>:           Saving transcripts.   (line 12)
-* ess-ask-for-ess-directory:             Customizing startup.  (line  7)
-* ess-ask-for-ess-directory <1>:         Customizing startup.  (line 21)
-* ess-auto-width:                        Customizing startup.  (line 56)
-* ess-auto-width-visible:                Customizing startup.  (line 56)
-* ess-delete-dump-files:                 Source Files.         (line 12)
-* ess-directory:                         Source Directories.   (line 48)
-* ess-dump-filename-template:            Source Directories.   (line  9)
-* ess-eldoc-abbreviation-style:          ESS ElDoc.            (line 24)
-* ess-eldoc-show-on-symbol:              ESS ElDoc.            (line 18)
-* ess-eval-visibly:                      Evaluating code.      (line 14)
-* ess-execute-in-process-buffer:         Hot keys.             (line 13)
-* ess-first-tab-never-complete:          Indenting.            (line 42)
-* ess-first-tab-never-complete <1>:      Object names.         (line  6)
-* ess-function-template:                 Edit buffer.          (line 17)
-* ess-handy-commands:                    Handy commands.       (line  6)
-* ess-handy-commands <1>:                Handy commands.       (line  9)
-* ess-indent-with-fancy-comments:        Indenting.            (line 28)
-* ess-keep-dump-files:                   Source Files.         (line 26)
-* ess-plain-first-buffername:            Multiple ESS processes.
-                                                               (line 14)
-* ess-post-run-hook:                     Customizing startup.  (line 26)
-* ess-pre-run-hook:                      Customizing startup.  (line 21)
-* ess-r-flymake-linters:                 ESS Flymake.          (line 16)
-* ess-r-flymake-lintr-cache:             ESS Flymake.          (line 23)
-* ess-R-font-lock-keywords:              Highlighting.         (line 19)
-* ess-r-outline-regexp:                  Outline.              (line  6)
-* ess-r-outline-regexp <1>:              Outline.              (line 27)
-* ess-search-list:                       Source Directories.   (line 62)
-* ess-source-directory:                  Source Directories.   (line 22)
-* ess-style:                             Styles.               (line 21)
-* ess-style-alist:                       Styles.               (line 28)
-* ess-switch-to-end-of-proc-buffer:      Other.                (line 21)
-* ess-swv-pdflatex-commands:             Sweave and AUCTeX.    (line 35)
-* ess-use-eldoc:                         ESS ElDoc.            (line 13)
-* ess-use-flymake:                       ESS Flymake.          (line 12)
-* iESS program arguments:                Customizing startup.  (line 48)
-* inferior-ess-program:                  Customizing startup.  (line 48)
-* inferior-R-font-lock-keywords:         Highlighting.         (line 12)
-* Rd-indent-level:                       R documentation files.
-                                                               (line 78)
-* Rd-mode-hook:                          R documentation files.
-                                                               (line 75)
-* Rd-to-help-command:                    R documentation files.
-                                                               (line 82)
-
-\1f
-File: ess.info,  Node: Concept index,  Prev: Variable index,  Up: Indices
-
-Concept Index
-=============
-
-\0\b[index\0\b]
-* Menu:
-
-* aborting R commands:                   Other.               (line   9)
-* aborting S commands:                   Other.               (line   9)
-* arguments to R program:                Customizing startup. (line  51)
-* arguments to S program:                Customizing startup. (line  51)
-* authors:                               Credits.             (line   6)
-* autosaving:                            Source Files.        (line  83)
-* bug reports:                           Reporting Bugs.      (line   6)
-* bugs:                                  Bugs.                (line   6)
-* changing ESS processes:                Multiple ESS processes.
-                                                              (line   6)
-* cleaning up:                           Hot keys.            (line  71)
-* code folding:                          Outline.             (line   6)
-* comint:                                Credits.             (line   6)
-* command history:                       Command History.     (line   6)
-* command line arguments:                iESS(R)--Inferior ESS processes.
-                                                              (line  16)
-* command-line completion:               Object names.        (line   6)
-* command-line editing:                  Command-line editing.
-                                                              (line   6)
-* commands:                              Entering commands.   (line   6)
-* comments:                              Source Files.        (line  41)
-* comments in R:                         Indenting.           (line  18)
-* company:                               Company.             (line   6)
-* completion in edit buffer:             Other edit buffer commands.
-                                                              (line  24)
-* completion of object names:            Object names.        (line   6)
-* completion on file names:              Object names.        (line  39)
-* completion on lists:                   Object names.        (line  37)
-* completion, when prompted for object names: Edit buffer.    (line  14)
-* creating new objects:                  Edit buffer.         (line  14)
-* credits:                               Credits.             (line   6)
-* customization:                         Customization.       (line   6)
-* data frames:                           Object names.        (line  20)
-* deleting output:                       Last command.        (line  24)
-* directories:                           Starting up.         (line  11)
-* dump file directories:                 Source Directories.  (line  20)
-* dump file names:                       Source Directories.  (line   6)
-* dump files:                            Edit buffer.         (line  27)
-* dump files <1>:                        Source Files.        (line  10)
-* echoing commands when evaluating:      Evaluating code.     (line  20)
-* edit buffer:                           Edit buffer.         (line   6)
-* editing commands:                      Command History.     (line   6)
-* editing functions:                     Editing objects.     (line   6)
-* editing transcripts:                   Saving transcripts.  (line  18)
-* ElDoc:                                 ESS ElDoc.           (line   6)
-* emacsclient:                           Emacsclient.         (line   6)
-* entering commands:                     Entering commands.   (line   6)
-* errors:                                Error Checking.      (line   6)
-* ESS commands blocking Emacs:           Evaluating code.     (line  20)
-* ess developer:                         Namespaced Evaluation.
-                                                              (line   6)
-* ESS process buffer:                    Starting up.         (line  17)
-* ESS process directory:                 Starting up.         (line  11)
-* ESS tracebug:                          ESS tracebug.        (line   6)
-* ESS-elsewhere:                         ESS processes on Remote Computers.
-                                                              (line   9)
-* ess-roxy:                              roxygen2.            (line   6)
-* evaluating code with echoed commands:  Evaluating code.     (line  20)
-* evaluating R expressions:              Evaluating code.     (line  31)
-* evaluating S expressions:              Evaluating code.     (line  31)
-* finding function definitions:          Xref.                (line   6)
-* flymake:                               ESS Flymake.         (line   6)
-* font-lock mode:                        Highlighting.        (line   7)
-* formatting source code:                Indenting.           (line  32)
-* graphics:                              Graphics.            (line   6)
-* Handy commands:                        Handy commands.      (line   6)
-* help files:                            Help.                (line   6)
-* highlighting:                          Highlighting.        (line   7)
-* historic backups:                      Source Files.        (line  41)
-* hot keys:                              Hot keys.            (line  43)
-* icicles:                               Icicles.             (line   6)
-* IDO completions:                       Minibuffer completion.
-                                                              (line   6)
-* indenting:                             Indenting.           (line  32)
-* installation:                          Installation.        (line   6)
-* interactive use of R:                  Introduction.        (line  31)
-* interactive use of S:                  Introduction.        (line  31)
-* interrupting R commands:               Other.               (line   9)
-* interrupting S commands:               Other.               (line   9)
-* introduction:                          Introduction.        (line   6)
-* keyboard short cuts:                   Hot keys.            (line  43)
-* killing temporary buffers:             Hot keys.            (line  71)
-* killing the ESS process:               Hot keys.            (line  71)
-* lists, completion on:                  Object names.        (line  37)
-* motion in transcript mode:             Transcript Mode.     (line  17)
-* multi-line commands, resubmitting:     Transcript resubmit. (line  33)
-* multiple ESS processes:                Multiple ESS processes.
-                                                              (line   6)
-* multiple inferior processes:           Multiple ESS processes.
-                                                              (line   6)
-* multiple interactive processes:        Multiple ESS processes.
-                                                              (line   6)
-* new objects, creating:                 Edit buffer.         (line  14)
-* objects:                               Hot keys.            (line  24)
-* outline-minor-mode:                    Outline.             (line   6)
-* pages in the process buffer:           Transcript.          (line  24)
-* paging commands in help buffers:       Help.                (line  28)
-* paragraphs in the process buffer:      Transcript.          (line  13)
-* parsing errors:                        Error Checking.      (line   6)
-* process buffer:                        Starting up.         (line  17)
-* process names:                         Multiple ESS processes.
-                                                              (line   8)
-* programming in R:                      Introduction.        (line  43)
-* programming in S:                      Introduction.        (line  43)
-* project work in R:                     Source Files.        (line  41)
-* project work in S:                     Source Files.        (line  41)
-* quitting from ESS:                     Hot keys.            (line  71)
-* re-executing commands:                 Command History.     (line   6)
-* reading long command outputs:          Last command.        (line  19)
-* remote Computers:                      ESS processes on Remote Computers.
-                                                              (line   9)
-* reverting function definitions:        Edit buffer.         (line  27)
-* roxy:                                  roxygen2.            (line   6)
-* roxygen2:                              roxygen2.            (line   6)
-* running R:                             Starting up.         (line   6)
-* running S:                             Starting up.         (line   6)
-* S+elsewhere:                           ESS processes on Remote Computers.
-                                                              (line   9)
-* search list:                           Hot keys.            (line  34)
-* search list <1>:                       Source Directories.  (line  55)
-* sending input:                         Entering commands.   (line   6)
-* Space in function argument completion: Function arguments.  (line  10)
-* starting directory:                    Starting up.         (line  11)
-* starting ESS:                          Starting up.         (line   6)
-* STERM:                                 Statistical Process running in ESS?.
-                                                              (line   6)
-* temporary buffers:                     Help.                (line 169)
-* temporary buffers, killing:            Hot keys.            (line  71)
-* tracebug tutorial:                     Getting started with tracebug.
-                                                              (line   6)
-* tramp support:                         ESS processes on Remote Computers.
-                                                              (line   9)
-* transcript:                            Transcript.          (line   9)
-* transcript file:                       Customizing startup. (line  40)
-* transcript file names:                 Saving transcripts.  (line  13)
-* transcript mode motion:                Transcript Mode.     (line  17)
-* transcripts of R sessions:             Introduction.        (line  38)
-* transcripts of S sessions:             Introduction.        (line  38)
-* using ESS interactively:               Introduction.        (line  31)
-* using R interactively:                 Introduction.        (line  31)
-* using S interactively:                 Introduction.        (line  31)
-* winjava:                               winjava.             (line   6)
-* working directory:                     Starting up.         (line  11)
-* working directory <1>:                 Source Directories.  (line  55)
-* X Windows:                             X11.                 (line   6)
-* xref:                                  Xref.                (line   6)
-
-
-\1f
-Tag Table:
-Node: Top\7f268
-Node: Introduction\7f2906
-Node: Features\7f5660
-Node: Current Features\7f6486
-Node: New features\7f9937
-Node: Credits\7f36694
-Node: Manual\7f40311
-Node: Installation\7f42977
-Node: Installing from a third-party repository\7f43914
-Node: Installing from source\7f44861
-Node: Activating and Loading ESS\7f46453
-Node: Check Installation\7f47527
-Node: Interactive ESS\7f47747
-Node: Starting up\7f48592
-Node: Multiple ESS processes\7f49336
-Node: ESS processes on Remote Computers\7f50417
-Node: Customizing startup\7f54520
-Node: Controlling buffer display\7f57410
-Node: Entering commands\7f60031
-Node: Command-line editing\7f61189
-Node: Transcript\7f62422
-Node: Last command\7f64191
-Node: Process buffer motion\7f65617
-Node: Transcript resubmit\7f67120
-Node: Saving transcripts\7f69085
-Node: Command History\7f70875
-Node: Saving History\7f74284
-Node: History expansion\7f75045
-Node: Hot keys\7f78256
-Node: Statistical Process running in ESS?\7f82326
-Node: Emacsclient\7f83605
-Node: Other\7f84397
-Node: Evaluating code\7f85416
-Node: Transcript Mode\7f89212
-Node: Resubmit\7f90365
-Node: Clean\7f91428
-Node: Editing objects\7f92424
-Node: Edit buffer\7f93542
-Node: Loading\7f95588
-Node: Error Checking\7f96615
-Node: Indenting\7f97664
-Node: Styles\7f100708
-Node: Other edit buffer commands\7f103082
-Node: Source Files\7f104738
-Node: Source Directories\7f109342
-Node: Help\7f112495
-Node: Completion\7f116941
-Node: Object names\7f117156
-Node: Function arguments\7f119790
-Node: Minibuffer completion\7f120733
-Node: Company\7f121207
-Node: Icicles\7f121594
-Node: Developing with ESS\7f122914
-Node: ESS tracebug\7f123360
-Node: Getting started with tracebug\7f126367
-Node: Editing documentation\7f128525
-Node: R documentation files\7f129077
-Node: roxygen2\7f132780
-Node: Namespaced Evaluation\7f137191
-Node: Extras\7f139189
-Node: ESS ElDoc\7f140281
-Node: ESS Flymake\7f141777
-Node: Handy commands\7f142871
-Node: Highlighting\7f144068
-Node: Parens\7f145103
-Node: Graphics\7f145579
-Node: printer\7f146250
-Node: X11\7f147006
-Node: winjava\7f147345
-Node: Imenu\7f147757
-Node: Outline\7f148604
-Node: Toolbar\7f149868
-Node: Xref\7f150278
-Node: Rdired\7f150608
-Node: Package listing\7f151671
-Node: Org\7f153055
-Node: Sweave and AUCTeX\7f154009
-Node: ESS for R\7f156561
-Node: ESS(R)--Editing files\7f156861
-Node: iESS(R)--Inferior ESS processes\7f157362
-Node: Philosophies for using ESS(R)\7f160017
-Node: Example ESS usage\7f160944
-Node: ESS for SAS\7f162349
-Node: ESS(SAS)--Design philosophy\7f163072
-Node: ESS(SAS)--Editing files\7f164005
-Node: ESS(SAS)--TAB key\7f165859
-Node: ESS(SAS)--Batch SAS processes\7f167225
-Node: ESS(SAS)--Function keys for batch processing\7f172253
-Node: iESS(SAS)--Interactive SAS processes\7f181740
-Node: iESS(SAS)--Common problems\7f185494
-Node: ESS(SAS)--Graphics\7f187018
-Node: ESS(SAS)--Windows\7f187801
-Node: ESS for BUGS\7f188379
-Node: ESS for JAGS\7f190135
-Node: Mailing lists/bug reports\7f193487
-Node: Bugs\7f193751
-Node: Reporting Bugs\7f195375
-Node: Mailing Lists\7f196290
-Node: Help with Emacs\7f197017
-Node: Customization\7f197549
-Node: Indices\7f198323
-Node: Key index\7f198498
-Node: Function and program index\7f203630
-Node: Variable index\7f213196
-Node: Concept index\7f216903
-\1f
-End Tag Table
-
-\1f
-Local Variables:
-coding: utf-8
-End:
diff --git a/elpa/ess-20251212.937/essd-els.el b/elpa/ess-20251212.937/essd-els.el
deleted file mode 100644 (file)
index 67040a2..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-;;; essd-els.el --- S-PLUS 3.x at another location customization  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1998-2022 Free Software Foundation, Inc.
-
-;; Author: Richard M. Heiberger <rmhNOSPAMtemple.edu>
-;; Created: December 1998
-;; Maintainer: ESS-core <ESS-core@r-project.org>
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; This file defines all the S-PLUS 3.x customizations for ess-mode.
-
-;;; Code:
-
-(require 'ess-r-mode)
-(require 'ess-sp6-d)
-(require 'ess-sas-d)
-(require 'ess-trns)
-(require 'ess-utils)
-(defvar ess-julia-customize-alist)
-
-;; Easily changeable in a user's .emacs
-(defvar S+elsewhere-dialect-name "S+6"
-  "Name of `dialect' for S-PLUS at another location.")
-
-(defvar S+elsewhere-start-args "-i"
-  "Arguments for `S+elsewhere-dialect-name'.")
-
-(defcustom inferior-ess-remote-pager nil
-  "Remote pager to use for reporting help files and similar things.
-The default value is nil."
-  :group 'ess-proc
-  :type '(choice (const nil) string))
-
-
-(defvar S+elsewhere-customize-alist
-  (append
-   '((ess-local-customize-alist         . S+elsewhere-customize-alist)
-     (ess-dialect                       . S+elsewhere-dialect-name)
-     (ess-object-name-db-file           . "ess-spelsewhere-namedb.el" )
-     (inferior-ess-program              . inferior-S-elsewhere-program)
-     (inferior-ess-help-command         . "help(\"%s\", pager=\"cat\", window=F)\n")
-     (ess-STERM  . "iESS")
-     )
-   S+common-cust-alist)
-  "Variables to customize for S+elsewhere.")
-
-(defun S+elsewhere (&optional _proc-name)
-  "Call \\='S-PLUS 3.x\\=', the \\='Real Thing\\='  from StatSci."
-  ;; git commit 104c4d7c56bc239ea245562763caa317bc3a1a84
-  (declare (obsolete ess-remote "2000"))
-  (ess-write-to-dribble-buffer
-   (format "\n(S+elsewhere): ess-dialect=%s, buf=%s\n" ess-dialect
-           (current-buffer)))
-  (let ((inf-buf (inferior-ess nil S+elsewhere-customize-alist)))
-    (when inferior-ess-language-start
-      (ess-eval-linewise inferior-ess-language-start))
-    inf-buf))
-
-(defun S+elsewhere-mode (&optional _proc-name)
-  "Major mode for editing S+3 source.  See `ess-mode' for more help."
-  (declare (obsolete ess-remote "2000"))
-  (setq-local ess-local-customize-alist S+elsewhere-customize-alist)
-  (ess-mode))
-
-;; This REALLY shouldn't need an editing mode.  Just a transcript and
-;; an inferior process handler.
-
-(defun ess-select-alist-dialect (&optional dialect)
-  "Query user for an ESS DIALECT and return the matching customize-alist."
-  (interactive)
-  (let* ((dialects '("R" "S+" "julia" "s3" "s4"
-                     "sp3" "sp4" "sqpe4" "sp5" "sqpe" "SAS"))
-         (dialect (or dialect
-                      (ess-completing-read "Dialect" dialects nil t))))
-    (cond
-     ((string= dialect "julia") (progn (require 'julia-mode)
-                                       ess-julia-customize-alist))
-     ((string= dialect "R")     ess-r-customize-alist)
-     ((string= dialect "SAS")   SAS-customize-alist)
-     (t                         S+elsewhere-customize-alist))))
-
-(defun ess-add-ess-process ()
-  "Execute this command from within a buffer running a process to add
-the process to `ess-process-name-alist' and to make it the
-`ess-current-process-name'.  This command will normally be run in a
-telnet buffer connected to another computer or in a shell or comint
-buffer on the local computer."
-  (interactive)
-  (let ((proc (get-buffer-process (buffer-name))))
-    (if (not proc)
-        (error "No process is associated with this buffer")
-      (set-process-filter proc #'inferior-ess-output-filter)
-      (setq ess-current-process-name (process-name proc))
-      (add-to-list 'ess-process-name-list
-                   (list ess-current-process-name)))))
-
-(defvar ess-remote nil
-  "Indicator, t in remote buffers.")
-
-;;;###autoload
-(defun ess-remote (&optional proc-name dialect)
-  "Execute this command from within a buffer running a process.
-It runs `ess-add-ess-process' to add the PROC-NAME to
-`ess-process-name-alist' and to make it the
-`ess-current-process-name'. It then prompts the user for an ESS
-language and sets the editing characteristics appropriately.
-
-To use this command, first start a process on a remote computer by
-manual use of telnet, rlogin, ssh, or some other protocol.  Start the
-relevant program (\"S\" or \"R\" or \"sas -stdio\") in that buffer.  Once
-you are talking to S or R or SAS, then do \\[ess-remote] to make
-the current buffer an inferior-ess buffer with the right behavior for
-the language you are currently working with.  With S and R, use C-c
-C-n to send lines over.  With SAS, use C-c i
-`ess-eval-line-and-step-invisibly' to send lines over invisibly.
-
-DIALECT is the desired ess-dialect. If nil, ask for dialect"
-
-  (interactive)
-  (ess-add-ess-process)
-  ;; Need to select a remote-customize-alist
-  (let ((customize-alist (ess-select-alist-dialect dialect)))
-    (ess-write-to-dribble-buffer
-     (format "\n(ESS-remote): ess-dialect=%s, buf=%s\n" ess-dialect
-             (current-buffer)))
-    (ess-setq-vars-local customize-alist)
-    (inferior-ess--set-major-mode ess-dialect)
-    (setq-local ess-remote t)
-    (setq ess-local-process-name (or proc-name ess-current-process-name))
-
-    (goto-char (point-max))
-
-    (when (equal ess-dialect "R")
-      ;; ugly fix for evn variable. What can we do :(
-      (ess-eval-linewise (format "options(pager='%s')\n"
-                                 (or inferior-ess-remote-pager inferior-ess-pager))
-                         nil nil nil 'wait)
-      (ess-r-load-ESSR))
-
-    (when (equal ess-dialect "S+")
-      (ess-command ess-S+--injected-code))
-
-    (when (equal ess-language "SAS")
-      (font-lock-mode 0)
-      (SAS-log-mode)
-      (shell-mode)
-      (setq buffer-read-only nil)
-      (font-lock-mode 1))
-
-    (ess-process-put 'funargs-cache (make-hash-table :test 'equal))
-    (ess-process-put 'funargs-pre-cache nil)
-    ;; auto-complete
-    (ess--setup-auto-complete ess-r-ac-sources t)
-    ;; company
-    (ess--setup-company ess-r-company-backends t)
-
-    (when inferior-ess-language-start
-      (ess-eval-linewise inferior-ess-language-start
-                         nil nil nil 'wait-prompt))))
-
-
-\f ; Provide package
-
-(provide 'essd-els)
-
-;;; essd-els.el ends here
diff --git a/elpa/ess-20251212.937/etc/ESSR.rds b/elpa/ess-20251212.937/etc/ESSR.rds
deleted file mode 100644 (file)
index 5203244..0000000
Binary files a/elpa/ess-20251212.937/etc/ESSR.rds and /dev/null differ
diff --git a/elpa/ess-20251212.937/etc/ESSR/BUILDESSR b/elpa/ess-20251212.937/etc/ESSR/BUILDESSR
deleted file mode 100755 (executable)
index 248d660..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env Rscript
-## -*- mode: R -*-
-## code to build ESSR environment.
-## Assume that current directory is etc/ESSR
-## run "./BUILDESSR" to create ../ESSR.rda
-
-## exactly as in inferior-ess-r-load-ESSR in ess-r-d.el
-source('./R/.load.R', local=TRUE)
-ESSR <- .ess.ESSR.load('./R/')
-saveRDS(ESSR, file = "../ESSR.rds")
diff --git a/elpa/ess-20251212.937/etc/ESSR/LOADREMOTE b/elpa/ess-20251212.937/etc/ESSR/LOADREMOTE
deleted file mode 100644 (file)
index 919ec33..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-## -*- mode: R -*-
-## loading code which is first sent to R on remote sessions
-local({
-    ver <- '%s' ## <- passed from elisp
-    root <- '~/.config/ESSR'
-    if(!file.exists(root))
-        dir.create(root, recursive = TRUE)
-    ## cannot use sprintf here
-    essr_file <- file.path(root, paste('ESSRv', ver, '.rds', sep = ''))
-    tryCatch({
-        if(!file.exists(essr_file)) {
-            url <- paste('https://github.com/emacs-ess/ESS/raw/ESSRv', ver, '/etc/ESSR.rds', sep = '')
-            utils::download.file(url, essr_file)
-        }
-        ESSR <- readRDS(essr_file)
-        ESSR[[".ess.Rversion"]] <- ESSR[[".ess.getRversion"]]()
-        attach(ESSR)
-        print(TRUE)
-    },
-    error = function(e) {
-      print(e)
-      print(FALSE)
-    })
-})
diff --git a/elpa/ess-20251212.937/etc/ESSR/R/.basic.R b/elpa/ess-20251212.937/etc/ESSR/R/.basic.R
deleted file mode 100644 (file)
index c7cba3b..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-#### Essential functionality needed by ESS
-
-## Should work on *all* versions of R.
-## Do not use _ in names, nor :: , nor 1L etc, as they
-## cannot be parsed in old R versions
-
-.ess.getRversion <- function() {
-    if(exists("getRversion", mode="function")) getRversion()
-    else paste(R.version$major, R.version$minor, sep=".")
-}
-
-## loading ESSR.rda might fail, so re-assign here:
-.ess.Rversion <- .ess.getRversion()
-
-.ess.R.has.utils <- (.ess.Rversion >= "1.9.0")
-.ess.utils.name <- paste("package",
-                         if(.ess.Rversion >= "1.9.0") "utils" else "base",
-                         sep = ":")
-
-## Instead of modern  utils::help use one that works in R 1.0.0:
-.ess.findFUN   <- get("find", .ess.utils.name)
-
-
-### HELP
-.ess.help <- function(..., help.type = getOption("help_type")) {
-    if (is.null(help.type)) {
-        help.type <- "text"
-    }
-
-    ## - get("help", ..) searching in global env works with devtools redefines
-    ## - Redefining to .ess.help this way is necessary because
-    ##   utils:::print.help_files_with_topic (used internally when there's
-    ##   more than one a package) uses the quoted call
-    ##   MM: don't understand; more specifically?
-    ..help <- function(...) {
-        do.call(get("help", envir = .GlobalEnv), list(...))
-    }
-
-    if (.ess.Rversion > "2.10") {
-        ## Abbreviating help_type to avoid underscore
-        if(!is.null(getOption("warnPartialMatchArgs"))) {
-            op <- options(warnPartialMatchArgs = FALSE); on.exit(options(op))
-        }
-        ..help(..., help = help.type)
-    } else {
-        ..help(..., htmlhelp = help.type == "html")
-    }
-}
-
-.ess.getHelpAliases <- local({
-    readrds <- if (.ess.Rversion >= '2.13.0') readRDS else .readRDS
-    aliasesCache <- new.env()
-
-    getAliases <- function(file) {
-        cached <- aliasesCache[[file]]
-        if (!is.null(cached))
-            return(cached)
-
-        aliases <- tryCatch(
-            error = function(...) NULL,
-            if (file.exists(file))
-                names(readrds(file))
-            else
-                NULL
-        )
-
-        aliasesCache[[file]] <- aliases
-        aliases
-    }
-
-    function(reset = FALSE) {
-        if (reset)
-            aliasesCache <<- new.env()
-
-        rdsFiles <- paste(searchpaths(), "/help/aliases.rds", sep = "")
-        unlist(lapply(rdsFiles, getAliases), use.names = FALSE)
-    }
-})
-
-.ess.helpLinks <- function(topic, package) {
-    tryCatch(
-        warning = function(...) NULL,
-        error = function(...) NULL, # needs R >= 2.13.0
-        {
-            ast <- .ess.fetchParsedRd(topic, package)
-            .ess.findLinks(ast)
-        }
-    )
-}
-
-.ess.fetchParsedRd <- function(topic, package) {
-    path <- utils:::index.search(topic, find.package(package))
-    utils:::.getHelpFile(path)
-}
-
-.ess.findLinks <- function(x) {
-    links <- NULL
-    findLinksRec <- function(x) {
-        if (.ess.isRdLink(x)) {
-            ## Ignore `pkg` for now
-            links <<- c(links, .ess.getRdLink(x)[[2]])
-        } else if (is.list(x)) {
-            for (elt in x)
-                findLinksRec(elt)
-        }
-    }
-
-    findLinksRec(x)
-    links
-}
-
-.ess.isRdLink <- function(x) {
-    identical(attr(x, "Rd_tag"), "\\link")
-}
-
-## From `tools:::get_link()`
-.ess.getRdLink <- function(x) {
-    pkg <- ""
-    dest <- paste(unlist(x), collapse = "")
-
-    opt <- attr(x, "Rd_option")
-    if (!is.null(opt)) {
-        if (grepl("^=", opt, perl = TRUE, useBytes = TRUE)) {
-            dest <- sub("^=", "", opt)
-        } else if (grepl(":", opt, perl = TRUE, useBytes = TRUE)) {
-           dest <- sub("^[^:]*:", "", opt)
-            pkg <- sub(":.*", "", opt)
-        } else {
-            pkg <- as.character(opt)
-        }
-    }
-
-    c(pkg, dest)
-}
-
-### SOURCING
-.ess.eval <- function(string, visibly = TRUE, output = FALSE,
-                      max.deparse.length = 300,
-                      file = tempfile("ESS"), local = NULL)
-{
-    if (is.null(local)) {
-        local <- if (.ess.Rversion > '2.13') parent.frame() else FALSE
-    }
-
-    ## create FILE, put string into it. Then source.
-    ## arguments are like in source and .ess.source
-    cat(string, file = file)
-    ## The following on.exit infloops in R 3.3.0
-    ## https://github.com/emacs-ess/ESS/issues/334
-    ## https://bugs.r-project.org/bugzilla/show_bug.cgi?id=16971
-    ## So we are cleaning it in .ess.source instead.
-    ## on.exit(file.remove(file))
-    .ess.source(file, visibly = visibly, output = output,
-                max.deparse.length = max.deparse.length,
-                local = local, fake.source = TRUE)
-}
-
-.ess.strip.error <- function(msg, srcfile) {
-    pattern <- paste(srcfile, ":[0-9]+:[0-9]+: ", sep = "")
-    sub(pattern, "", msg)
-}
-
-.ess.file.remove <- function(file){
-    if (base::file.exists(file)) base::file.remove(file)
-    else FALSE
-}
-
-.ess.source <- function(file, visibly = TRUE, output = FALSE,
-                        max.deparse.length = 300, local = NULL,
-                        fake.source = FALSE, keep.source = TRUE,
-                        message.prefix = "") {
-    if (is.null(local)) {
-        local <- if (.ess.Rversion > "2.13")
-            parent.frame()
-        else FALSE
-    }
-
-    ss <-
-        if (.ess.Rversion >= "3.4")
-            base::source
-        else if (.ess.Rversion >= "2.8")
-            function(..., spaced) base::source(...)
-        else function(..., spaced, keep.source) base::source(...)
-
-    on.exit({
-        if (fake.source)
-            .ess.file.remove(file)
-    })
-
-    out <- ss(file, echo = visibly, local = local, print.eval = output, spaced = FALSE,
-              max.deparse.length = max.deparse.length, keep.source = keep.source)
-
-    if(!fake.source)
-        cat(sprintf("%sSourced file %s\n", message.prefix, file))
-
-    ## Return value for org-babel
-    invisible(out$value)
-}
-
-if(.ess.Rversion < "1.8")
-    ## (works for "1.7.2"): bquote() was new in 1.8.0
-    bquote <- function(expr, where=parent.frame()){
-        unquote <- function(e)
-            if (is.pairlist(e)) as.pairlist(lapply(e, unquote))
-            else if (length(e) <= 1) e
-            else if (e[[1]] == as.name(".")) eval(e[[2]], where)
-            else as.call(lapply(e, unquote))
-
-        unquote(substitute(expr))
-    }
-
-.ess.command <- function(expr, sentinel) {
-    ## It is possible that the REPL is marked as non-busy when the
-    ## output is sinked because prompts are not sinked. In that case,
-    ## redirect the sinked output temporarily to ESS.
-    sinked <- !identical(stdout(), getConnection(1))
-    if (sinked)
-        sink(getConnection(1))
-
-    on.exit({
-        writeLines(paste(sentinel, "-END", sep = ""))
-        if (sinked)
-            sink(NULL)
-    })
-
-    writeLines(paste(sentinel, "-START", sep = ""))
-
-    .ess.environment.state$env <- parent.frame()
-    on.exit(.ess.environment.state$env <- NULL, add = TRUE)
-
-
-    ## Don't interrupt `browser()` sessions (#1081)
-    restart <- function(...) {
-        if (!is.null(findRestart("browser")))
-            invokeRestart("browser")
-    }
-
-    ## Should be an exiting handler to be able to catch
-    ## stack overflow errors
-    rethrow <- function(cnd) {
-        stop('\1e\1eESSR::ERROR \"', conditionMessage(cnd), '\"\1e\1e')
-    }
-
-    out <- tryCatch(
-        error = rethrow,
-        withCallingHandlers(
-            interrupt = restart,
-            withVisible(expr)
-        )
-    )
-
-    ## Print result manually because we can't rely on auto-print
-    ## without changing the last value
-    if (out$visible)
-        print(out$value)
-
-    ## Keep `.Last.value` stable
-    invisible(.Last.value)
-}
-
-.ess.environment.state <- new.env(parent = emptyenv())
-
-.ess.environment <- function() {
-    .ess.environment.state$env
-}
diff --git a/elpa/ess-20251212.937/etc/ESSR/R/.load.R b/elpa/ess-20251212.937/etc/ESSR/R/.load.R
deleted file mode 100644 (file)
index e6c0014..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-## This file is sourced when R starts and `load.ESSR` is called. See
-## inferior-ess-r-load-ESSR--local.
-## Do not use _ in names, nor :: as they cannot be parsed in old R versions
-
-## obtain the R version number as a string
-.ess.ESSR.get.rver <- function() {
-    if(exists("getRversion", mode="function")) getRversion()
-    else paste(R.version$major, R.version$minor, sep=".")
-}
-
-## load .base.R and all other files into ESSR environment; then attach ESSR
-.ess.ESSR.load <- function(dir) {
-
-    if (Sys.getenv("ESSR_TEST_LOAD_ERROR") != "")
-        stop('Loading failed with a nice message.')
-
-    Rver <- .ess.ESSR.get.rver()
-    ESSR <- .ess.ESSR.create.env(Rver)
-    .ess.ESSR.source.files(ESSR, dir, Rver)
-    .ess.ESSR.attach.env(ESSR, Rver)
-
-    ## BUILDESSR needs this:
-    invisible(ESSR)
-}
-
-.ess.ESSR.create.env <- function(Rver) {
-
-    ESSR <-
-        if (Rver <= "1.3.0") ## really old library() revert order a bit
-            attach(NULL, name = "ESSR")
-        else if(length(nn <- names(formals(new.env))) && any(nn == "parent"))
-            new.env(parent =
-                        if (Rver >= "1.9.0") getNamespace("utils")
-                        else .BaseNamespaceEnv)
-        else
-            new.env()
-
-    assign(".ess.Rversion", Rver, envir = ESSR)
-
-    ## updated by make !!
-    VERSION <- "1.8"
-    assign(".ess.ESSRversion", VERSION, envir = ESSR)
-
-    ESSR
-}
-
-## attempt to source the files in the ESSR directory and place the resulting R
-## objects into ESSR environment; the updated version of the environment is
-## returned
-.ess.ESSR.source.files <- function(ESSR, dir, Rver) {
-
-    .source <-
-        if(any("keep.source" == names(formals(sys.source))))
-            sys.source
-        else
-            function(..., keep.source) sys.source(...)
-
-    ## .basic.R:
-    try(.source(paste(dir,'/.basic.R', sep = ""), envir = ESSR, keep.source = FALSE))
-
-    ## all others try(*) as it will fail in old R
-    if (Rver > "1.3.0") { # no sense if very old R
-        for (f in dir(dir, pattern='\\.R$', full.names=TRUE))
-            try(.source(f, envir = ESSR, keep.source = FALSE))
-    }
-
-    ESSR
-}
-
-
-## attach the ESSR environment to the search path
-.ess.ESSR.attach.env <- function(ESSR, Rver) {
-    if (Rver >= "2.4.0")
-        attach(ESSR)
-    else if (Rver > "1.3.0") { # borrow from older library()
-        e <- attach(NULL, name = "ESSR")
-        .Internal(lib.fixup(ESSR, e))
-    } else { # if old R, use as in that old library():
-        .Internal(lib.fixup(ESSR, .GlobalEnv))
-    }
-}
-
-
-## copy any ESSR R objects in the global environment into a newly created ESSR
-## environment; then remove the original objects and attach ESSR
-.ess.collect.ESSR.objects <- function() {
-
-    Rver <- .ess.ESSR.get.rver()
-    ESSR <- .ess.ESSR.create.env(Rver)
-    essr.nms <- grep('\\.(ess|ESS)', ls(.GlobalEnv, all.names = TRUE), value = TRUE)
-    for (nm in essr.nms) {
-        assign(nm, get(nm, pos = .GlobalEnv), envir = ESSR)
-    }
-    .ess.ESSR.attach.env(ESSR, Rver)
-    rm(list = essr.nms, pos = .GlobalEnv)
-}
diff --git a/elpa/ess-20251212.937/etc/ESSR/R/completion.R b/elpa/ess-20251212.937/etc/ESSR/R/completion.R
deleted file mode 100644 (file)
index 50017df..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-## Do *NOT* use  1L -- it gives  parse errors in historical versions of R
-
-## Try a setup working in as old R as possible.
-## ===>
-##    1)  do not use "_" in names!   --- seems impossible for the Millenials ..
-##    2)  use our own simplified definition of  '::' and ':::' ?
-##
-if(!exists("local"))
-    local <- function(expr, envir = environment()) { invisible(eval(expr, envir=envir)) }
-
-##' Robust version of
-##'    utils:::.addFunctionInfo(c = c("recursive", "use.names")) #  needed only for R <= 3.y.z
-local({
-    U <- asNamespace("utils"); fn <- ".addFunctionInfo"
-    EX <- exists(fn, envir=U)
-    if(EX && is.function(FN <- get(fn, envir=U))) {
-        FN(c = c("recursive", "use.names")); ##dbg: cat("Calling utils:::",fn,"(c = ...)\n")
-    }
-})
-
-\f
-.ess_eval <- function(str, env = globalenv()) {
-    ## don't remove; really need eval(parse(  here!!
-    tryCatch(eval(parse(text=str), envir = env),
-             error=function(e) NULL) ## also works for special objects containing @:$ etc
-}
-
-.ess_nonull <- function(x, default = "") {
-    if (is.null(x)) default
-    else x
-}
-
-## not needed for completion;   called from  (ess-r-xref--srcref *) in  ../../../lisp/ess-r-xref.el
-.ess_srcref <- function(name, pkg) {
-    if (!is.null(pkg) && requireNamespace(pkg)) {
-        env <- asNamespace(pkg)
-    } else {
-        env <- globalenv()
-    }
-    fn <- .ess_eval(name, env)
-    if (is.null(fn)) {
-        objs <- utils::getAnywhere(name)$objs
-        for (fn in objs) {
-            if(is.function(fn))
-                break
-        }
-    }
-    out <- "()\n"
-    if (is.function(fn) && !is.null(utils::getSrcref(fn))) {
-        file <- utils::getSrcFilename(fn, full.names = TRUE)
-        if (file != "") {
-            line <- .ess_nonull(utils::getSrcLocation(fn, "line"  ), 1)
-            col  <- .ess_nonull(utils::getSrcLocation(fn, "column"), 1)
-            out <- sprintf("(\"%s\" %d %d)\n", file, line, col - 1)
-        }
-    }
-    cat(out)
-}
-
-\f
-.ess_fn_pkg <- function(fn_name) {
-    objs <- utils::getAnywhere(fn_name)
-    print(sub("(package|namespace):", "", objs$where))
-}
-
-.ess_funargs <- function(funname) {
-    if(.ess.Rversion > '2.14.1') {
-        ## temporarily disable JIT compilation and errors
-        comp <- compiler::enableJIT(0)
-        op <- options(error=NULL)
-        on.exit({ options(op); compiler::enableJIT(comp) })
-    }
-    fun <- .ess_eval(funname)
-    if(is.function(fun)) {
-        special <- grepl('[:$@[]', funname)
-        args <- if(!special){
-                    fundef <- paste(funname, '.default',sep='')
-                    do.call('argsAnywhere', list(fundef))
-                }
-
-        if(is.null(args))
-            args <- args(fun)
-        if(is.null(args))
-            args <- do.call('argsAnywhere', list(funname))
-
-        fmls <- formals(args)
-        fmls_names <- names(fmls)
-        fmls <- gsub('\"', '\\\"',
-                     gsub("\\", "\\\\", as.character(fmls), fixed = TRUE),
-                     fixed=TRUE)
-        args_alist <-
-            sprintf("'(%s)",
-                    paste("(\"", fmls_names, "\" . \"", fmls, "\")",
-                          sep = '', collapse = ' '))
-        allargs <-
-            if (special) fmls_names
-            else tryCatch(gsub(' ?= ?', '', utils:::functionArgs(funname, ''), fixed = FALSE),
-                          error=function(e) NULL)
-        allargs <- sprintf("'(\"%s\")",
-                           paste(allargs, collapse = '\" "'))
-        envname <-
-            if (is.primitive(fun)) "base"
-            else environmentName(environment(fun))
-        if (envname == "R_GlobalEnv") envname <- ""
-        cat(sprintf('(list \"%s\" %s %s)\n',
-                    envname, args_alist, allargs))
-    }
-}
-
-\f
-.ess_get_completions <- function(string, end, suffix = " = ") {
-    oldopts <- utils::rc.options(funarg.suffix = suffix)
-    on.exit(utils::rc.options(oldopts))
-    sett <- utils::rc.settings
-    oldDots <- sett()[["dots"]]
-    on.exit(sett(dots=oldDots), add=TRUE)
-    sett(dots = FALSE)
-    if(.ess.Rversion > '2.14.1') {
-        comp <- compiler::enableJIT(0)
-        op <- options(error=NULL)
-        on.exit({ options(op); compiler::enableJIT(comp)}, add = TRUE)
-    }
-    utils:::.assignLinebuffer(string)
-    utils:::.assignEnd(end)
-    utils:::.guessTokenFromLine()
-    utils:::.completeToken()
-    c(get('token', envir=utils:::.CompletionEnv),
-      utils:::.retrieveCompletions())
-}
-
-.ess_arg_help <- function(arg, func) {
-    op <- options(error=NULL)
-    on.exit(options(op))
-    fguess <-
-        if(is.null(func)) get('fguess', envir=utils:::.CompletionEnv)
-        else func
-    findArgHelp <- function(fun, arg){
-        file <- help(fun, try.all.packages=FALSE)[[1]]
-        hlp <- utils:::.getHelpFile(file)
-        id <- grep('arguments', tools:::RdTags(hlp), fixed=TRUE)
-        if(length(id)){
-            arg_section <- hlp[[id[[1]]]]
-            items <- grep('item', tools:::RdTags(arg_section), fixed=TRUE)
-            ## cat('items:', items, fill=TRUE)
-            if(length(items)){
-                arg_section <- arg_section[items]
-                args <- unlist(lapply(arg_section,
-                                      function(el) paste(unlist(el[[1]][[1]], TRUE, FALSE), collapse='')))
-                fits <- grep(arg, args, fixed=TRUE)
-                ## cat('args', args, 'fits', fill=TRUE)
-                if(length(fits))
-                    paste(unlist(arg_section[[fits[1]]][[2]], TRUE, FALSE), collapse='')
-            }
-        }
-    }
-    funcs <- c(fguess, tryCatch(methods(fguess),
-                                warning= function(w) NULL,
-                                error  = function(e) NULL))
-    if(length(funcs) > 1 && length(pos <- grep('default', funcs))) {
-        funcs <- c(funcs[[pos[[1]]]], funcs[-pos[[1]]])
-    }
-    i <- 1; found <- FALSE
-    out <- 'No help found'
-    while(i <= length(funcs) && is.null(out <-
-                                            tryCatch(findArgHelp(funcs[[i]], arg),
-                                                     warning=function(w) {NULL},
-                                                     error=function(e) {NULL})
-                                        ))
-        i <- i + 1
-    cat('\n\n', as.character(out), '\n')
-}
diff --git a/elpa/ess-20251212.937/etc/ESSR/R/debug.R b/elpa/ess-20251212.937/etc/ESSR/R/debug.R
deleted file mode 100644 (file)
index cb2580b..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-### BREAKPOINTS
-.ESSBP. <- new.env()
-
-### DEBUG/UNDEBUG
-.ess_find_funcs <- function(env) {
-    objs <- ls(envir = env, all.names = TRUE)
-    if (length(objs) > 0)
-        objs <- objs[sapply(objs, exists, envir = env,
-                            mode = 'function', inherits = FALSE)]
-    objs
-}
-
-.ess_all_functions <- function(packages = c(), env = NULL) {
-    if(is.null(env))
-        env <- parent.frame()
-    empty <- emptyenv()
-    coll <- list()
-    for(p in packages){
-        ## package might not be attached
-        try(
-        {
-            objNS <- .ess_find_funcs(asNamespace(p))
-            objPKG <- .ess_find_funcs(as.environment(paste0('package:', p)))
-            objNS <- setdiff(objNS, objPKG)
-            if(length(objPKG))
-                coll[[length(coll) + 1]] <- paste0(p, ':::', objNS)
-        }, silent = TRUE)
-    }
-    while(!identical(empty, env)){
-        coll[[length(coll) + 1]] <- .ess_find_funcs(env)
-        env <- parent.env(env)
-    }
-    grep('^\\.ess', unlist(coll, use.names = FALSE),
-         invert = TRUE, value = TRUE)
-}
-
-\f
-.ess_dbg_flag_for_debuging <- function(fname){
-    all <- utils::getAnywhere(fname)
-    if(length(all$obj) == 0){
-        msg <- sprintf("No functions names '%s' found", fname)
-    } else {
-        msg <- sprintf("Flagged '%s' for debugging", fname)
-        tryCatch(lapply(all$obj, debug),
-                 error = function(e){
-                     msg <- paste0("Error: ", e$message)
-                 })
-    }
-    cat(msg)
-    .ess_mpi_message(msg)
-}
-
-.ess_dbg_getTracedAndDebugged <- function()
-{
-    packages <- base::.packages()
-    tr_state <- tracingState(FALSE)
-    on.exit(tracingState(tr_state))
-    generics <- methods::getGenerics()
-    all_traced <- c()
-    for(i in seq_along(generics)){
-        genf <- methods::getGeneric(generics[[i]],
-                                    package=generics@package[[i]])
-        if(!is.null(genf)){ ## might happen !! v.2.13
-            menv <- methods::getMethodsForDispatch(genf)
-            traced <- unlist(eapply(menv, is, 'traceable', all.names=TRUE))
-            if(length(traced) && any(traced))
-                all_traced <- c(paste(generics[[i]],':',
-                                      names(traced)[traced],sep=''), all_traced)
-            tfn <- getFunction(generics[[i]], mustFind=FALSE, where = .GlobalEnv)
-            if(!is.null(tfn ) && is(tfn,  'traceable')) # if the default is traced,  it does not appear in the menv :()
-                all_traced <- c(generics[[i]], all_traced)
-        }
-    }
-    debugged_pkg <- unlist(lapply(packages, function(pkgname){
-        ns <- asNamespace(pkgname)
-        funcs <- .ess_find_funcs(ns)
-        dbged <- funcs[unlist(lapply(funcs,
-                                     function(f){
-                                         isdebugged(get(f, envir = ns, inherits = FALSE))
-                                     }))]
-        if(length(dbged))
-            paste0(pkgname, ':::`', dbged, '`')
-    }))
-    env <- parent.frame()
-    ## traced function don't appear here. Not really needed and would affect performance.
-    all <- .ess_all_functions(packages = packages, env = env)
-    which_deb <- lapply(all, function(nm){
-        ## if isdebugged is called with string it doess find
-        tryCatch(isdebugged(get(nm, envir = env)),
-                 error = function(e) FALSE)
-        ## try(eval(substitute(isdebugged(nm), list(nm = as.name(nm)))), silent = T)
-    })
-    debugged <- all[which(unlist(which_deb, recursive=FALSE, use.names=FALSE))]
-    unique(c(debugged_pkg, debugged, all_traced))
-}
-
-\f
-.ess_dbg_UntraceOrUndebug <- function(name, env = parent.frame()) {
-    tr_state <- tracingState(FALSE)
-    on.exit(tracingState(tr_state))
-    if( grepl('::', name) ){
-        ## foo:::bar name
-        eval(parse(text = sprintf('undebug(%s)', name)))
-    }else{
-        ## name is a name of a function to be undebugged or has a form
-        ## name:Class1#Class2#Class3 for traced methods
-        name <- strsplit(name, ':', fixed = TRUE)[[1]]
-        if( length(name)>1 ){
-            ## a method
-            fun <- name[[1]]
-            sig <- strsplit(paste(name[-1], collapse=''), '#', fixed=TRUE)[[1]]
-            untrace(fun, signature = sig)
-        }else{
-            ## function
-            if( is(getFunction(name, where = parent.frame()), 'traceable') )
-                untrace(name)
-            else if(grepl(":", name))
-                undebug(name)
-            else
-                undebug(get(name, envir = env))
-        }}
-}
-
-.ess_dbg_UndebugALL <- function(funcs)
-{
-    tr_state <- tracingState(FALSE)
-    on.exit(tracingState(tr_state))
-    env <- parent.frame()
-    invisible(lapply(funcs, function( nm ) {
-        ## ugly tryCatch, but there might be several names pointing to the
-        ## same function, like foo:::bar and bar. An alternative would be
-        ## to call .ess_dbg_getTracedAndDebugged each time but that might
-        ## be ery slow
-        try(.ess_dbg_UntraceOrUndebug(nm, env = env), TRUE)
-    }))
-}
-
-\f
-### WATCH
-.ess_watch_expressions <- list()
-
-.ess_watch_eval <- function()
-{
-    env <- as.environment("ESSR")
-    exps <- get('.ess_watch_expressions', envir = env)
-    if(length(exps) == 0) {
-        ## using old style so this can be parsed by R 1.9.1 (e.g):
-        cat('\n# Watch list is empty!\n',
-            '# a       append new expression',
-            '# i       insert new expression',
-            '# k       kill',
-            '# e       edit the expression',
-            '# r       rename',
-            '# n/p     navigate',
-            '# u/d,U   move the expression up/down',
-            '# q       kill the buffer',
-            sep="\n")
-    } else {
-        .parent_frame <- parent.frame()
-        .essWEnames <- allNames(exps)
-        len0p <- !nzchar(.essWEnames)
-        .essWEnames[len0p] <- seq_along(len0p)[len0p]
-        oo <- options(width = 10000)
-        on.exit(options(oo))
-        for(i in seq_along(exps)) {
-            cat('\n@---- ', .essWEnames[[i]], ' ',
-                rep.int('-', max(0, 35 - nchar(.essWEnames[[i]]))), '-@\n', sep = '')
-            expr <- gsub(" +", " ", paste(deparse(exps[[i]][[1]]), collapse = " "))
-            cat(paste('@---:', expr), ' \n', sep = '')
-            tryCatch(print(eval(exps[[i]],
-                                envir = .parent_frame)),
-                     error = function(e) cat('Error:', e$message, '\n' ),
-                     warning = function(w) cat('warning: ', w$message, '\n' ))
-        }
-    }
-}
-
-\f
-.ess_watch_assign_expressions <- function(elist) {
-    assign(".ess_watch_expressions", elist, envir = as.environment("ESSR"))
-}
-
-.ess_log_eval <- function(log_name) {
-    env <- as.environment("ESSR")
-    if(!exists(log_name, envir = env, inherits = FALSE))
-        assign(log_name, list(), envir = env)
-    log <- get(log_name, envir = env, inherits = FALSE)
-    .essWEnames <- allNames(.ess_watch_expressions)
-    cur_log <- list()
-    .parent_frame <- parent.frame()
-    for(i in seq_along(.ess_watch_expressions)) {
-        capture.output( {
-            cur_log[[i]] <-
-                tryCatch(eval(.ess_watch_expressions[[i]]),
-                         envir = .parent_frame,
-                         error = function(e) paste('Error:', e$message, '\n'),
-                         warning = function(w) paste('warning: ', w$message, '\n'))
-            if(is.null(cur_log[i][[1]]))
-                cur_log[i] <- list(NULL)
-        })
-    }
-    names(cur_log) <- .essWEnames
-    assign(log_name, c(log, list(cur_log)), envir = env)
-    invisible(NULL)
-}
-
-\f
-.ess_package_attached <- function(pack_name){
-    as.logical(match(paste0("package:", pack_name), search()))
-}
-
-## magrittr debug_pipe
-.ess_pipe_browser <- function(x){
-    if(is.list(x))
-        evalq({
-            browser(skipCalls = 2)
-            x
-        }, envir = x)
-    else if(is.environment(x))
-        ## enclos argumentn has no effect for unclear reason, need to hack
-        eval(bquote({
-            x <- .(environment())
-            browser(skipCalls = 2)
-            x
-        }), envir = x)
-    else {
-        browser(skipCalls = 0)
-        x
-    }
-}
diff --git a/elpa/ess-20251212.937/etc/ESSR/R/misc.R b/elpa/ess-20251212.937/etc/ESSR/R/misc.R
deleted file mode 100644 (file)
index b34970f..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-.ess_weave <- function(command, file, encoding = NULL){
-    cmd_symb <- substitute(command)
-    if (grepl('knit|purl', deparse(cmd_symb))) require(knitr)
-    od <- getwd()
-    on.exit(setwd(od))
-    setwd(dirname(file))
-    frame <- parent.frame()
-    if (is.null(encoding))
-        eval(bquote(.(cmd_symb)(.(file))), envir = frame)
-    else
-        eval(bquote(.(cmd_symb)(.(file), encoding = .(encoding))), envir = frame)
-}
-
-.ess_knit <- function(file, output = NULL){
-    library(knitr)
-    frame <- parent.frame()
-    od <- getwd()
-    on.exit(setwd(od))
-    setwd(dirname(file))
-    ## this bquote is really needed for data.table := operator to work correctly
-    eval(bquote(knit(.(file), output = .(output))), envir = frame)
-}
-
-\f
-.ess_sweave <- function(file, output = NULL){
-    od <- getwd()
-    frame <- parent.frame()
-    on.exit(setwd(od))
-    setwd(dirname(file))
-    eval(bquote(Sweave(.(file), output = .(output))), envir = frame)
-}
-
-## Users might find it useful. So don't prefix with .ess.
-.ess_htsummary <- function(x, hlength = 4, tlength = 4, digits = 3) {
-    ## fixme: simplify and generalize
-    snames <- c("mean", "sd", "min", "max", "nlev", "NAs")
-    d <- " "
-    num_sumr <- function(x){
-        c(f(mean(x, na.rm = TRUE)),
-          f(sd(x, na.rm = TRUE)),
-          f(min(x, na.rm = TRUE)),
-          f(max(x, na.rm = TRUE)),
-          d,
-          f(sum(is.na(x), na.rm = TRUE)))
-    }
-    f <- function(x) format(x, digits = digits)
-
-    if (is.data.frame(x) | is.matrix(x)) {
-        if (nrow(x) <= tlength + hlength){
-            print(x)
-        } else {
-            if (is.matrix(x))
-                x <- data.frame(unclass(x))
-            ## conversion needed, to avoid problems with derived classes such
-            ## as data.table
-            h <- as.data.frame(head(x, hlength))
-            t <- as.data.frame(tail(x, tlength))
-            for (i in 1:ncol(x)) {
-                h[[i]] <- f(h[[i]])
-                t[[i]] <- f(t[[i]])
-            }
-            ## summaries
-            sumr <- sapply(x, function(c){
-                if (is.logical(c))
-                    ## treat logical as numeric; it's harmless
-                    c <- as.integer(c)
-                if (is.numeric(c))
-                    num_sumr(c)
-                else if (is.factor(c)) c(d, d, d, d, nlevels(c), sum(is.na(c)))
-                else rep.int(d, length(snames))
-            })
-            sumr <- as.data.frame(sumr)
-            row.names(sumr) <- snames
-            dots <- rep("...", ncol(x))
-            empty <- rep.int(" ", ncol(x))
-            lines <- rep.int(" ", ncol(x))
-            df <- rbind(h, ... = dots, t, `_____` = lines, sumr, ` ` = empty)
-            print(df)
-        }
-    } else {
-        cat("head(", hlength, "):\n", sep = "")
-        print(head(x, hlength))
-        if (length(x) > tlength + hlength){
-            cat("\ntail(", tlength, "):\n", sep = "")
-            print(tail(x, tlength))
-        }
-        cat("_____\n")
-        if (is.numeric(x) || is.logical(x))
-            print(structure(num_sumr(x), names = snames), quote = FALSE)
-        else if (is.factor(x)){
-            cat("NAs: ", sum(is.na(x), na.rm = TRUE), "\n")
-            cat("levels: \n")
-            print(levels(x))
-        }
-    }
-    invisible(NULL)
-}
-
-\f
-.ess_vignettes <- function(all=FALSE) {
-    vs <- unclass(browseVignettes(all = all))
-    vs <- vs[sapply(vs, length) > 0]
-
-    mat2elist <- function(mat) {
-        if (!is.null(dim(mat))){
-            apply(mat, 1, function(r)
-                sprintf("(list \"%s\")",
-                        paste0(gsub("\"", "\\\\\"",
-                                    as.vector(r[c("Title", "Dir", "PDF",
-                                                  "File", "R")])),
-                               collapse = "\" \"")))
-        }
-    }
-    cat("(list \n",
-        paste0(mapply(function(el, name) {
-            sprintf("(list \"%s\"  %s)",
-                    name, paste0(mat2elist(el), collapse = "\n"))
-        },
-        vs, names(vs)), collapse = "\n"), ")\n")
-}
-
-.ess_Rd2txt <- function(rd) {
-    fun <- tools::Rd2txt
-    if (length(formals(fun)["stages"]))# newer R version
-        fun(rd, stages = c("build", "install", "render"))
-    else
-        fun(rd)
-}
-
-## Hacked help.start() to use with ess-rutils.el
-.ess_help_start <- function(update=FALSE, remote=NULL) {
-    home <- if (is.null(remote)) {
-                port <- tools::startDynamicHelp(NA)
-                if (port > 0L) {
-                    if (update)
-                        make.packages.html(temp=TRUE)
-                    paste0("http://127.0.0.1:", port)
-                }
-                else stop(".ess_help_start() requires the HTTP server to be running",
-                          call.=FALSE)
-            } else remote
-    paste0(home, "/doc/html/index.html")
-}
-
-\f
-.ess.rdired <- function() {
-    cat('\n')
-
-    objs <- ls(envir = .GlobalEnv)
-    if (length(objs)==0) {
-        cat("No objects to view!\n")
-        return(invisible(NULL))
-    }
-
-    names(objs) <- objs
-    objs <- lapply(objs, get, envir = .GlobalEnv)
-
-    mode <- sapply(objs, data.class)
-    length <- sapply(objs, length)
-    size <- sapply(objs, function(obj) format(object.size(obj)))
-    rows <- sapply(objs,nrow)
-       # sapply returns a list rather than a vector if there are NULLs eg nrow returns NULL for non-dataframes.  
-       # check if list, replace NULLS with NA and convert to vector
-       if (is.list(rows)) {
-               rows[sapply(rows,is.null)] <- NA
-               rows <- unlist(rows)
-       }
-    
-    d <- data.frame(mode, length, rows, size)
-    
-    var.names <- row.names(d)
-    
-    ## If any names contain spaces, we need to quote around them.
-    quotes <- rep('', length(var.names))
-    spaces <- grep(' ', var.names)
-    if (any(spaces))
-        quotes[spaces] <- '\"'
-    var.names <- paste(quotes, var.names, quotes, sep = '')
-    row.names(d) <- paste('  ', var.names, sep = '')
-
-    print(d)
-}
diff --git a/elpa/ess-20251212.937/etc/ESSR/R/mpi.R b/elpa/ess-20251212.937/etc/ESSR/R/mpi.R
deleted file mode 100644 (file)
index 0ad5cfc..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-## simple Message Parsing Interface
-
-.ess_mpi_send <- function(head, ...){
-    dots <- lapply(list(...), function(el) {
-        if (is.null(el)) "nil"
-        else if (is.logical(el)) {if (el) "t" else "nil"}
-        else as.character(el)
-    })
-    payload <- paste(dots, collapse = "\1e")
-    cat(sprintf("\e_%s\1e%s\e\\", head, payload))
-}
-
-.ess_mpi_message <- function(msg){
-    .ess_mpi_send("message", msg)
-}
-
-.ess_mpi_y_or_n <- function(prompt, callback = NULL){
-    .ess_mpi_send("y-or-n", prompt, callback)
-}
-
-.ess_mpi_eval <- function(expr, callback = NULL){
-    .ess_mpi_send("eval", expr, callback)
-}
-
-.ess_mpi_error <- function(msg) {
-    .ess_mpi_send("error", msg)
-}
-
diff --git a/elpa/ess-20251212.937/etc/ESSR/R/ns-eval.R b/elpa/ess-20251212.937/etc/ESSR/R/ns-eval.R
deleted file mode 100644 (file)
index 8dc4da8..0000000
+++ /dev/null
@@ -1,421 +0,0 @@
-## NOTE ON S3 METHODS: New S3 methods are not automatically registered. You can
-## register them manually after you have inserted method_name.my_class into your
-## package environment using ess-developer, like follows:
-##
-##    registerS3method("method_name", "my_class", my_package:::method_name.my_class)
-##
-## If an S3 methods already exists in a package, ESS-developer will do the right
-## thing.
-
-## evaluate the STRING by saving into a file and calling .ess.ns_source
-.ess.ns_eval <- function(string, visibly, output, package,
-                         file = tempfile("ESSDev"), verbose = FALSE,
-                         fallback_env = NULL, local_env = parent.frame()) {
-    cat(string, file = file)
-    on.exit(.ess.file.remove(file))
-    .ess.ns_source(file, visibly, output, package = package,
-                   verbose = verbose, fake.source = TRUE,
-                   fallback_env = fallback_env, local_env = local_env)
-}
-
-\f
-##' Source FILE into an environment. After having a look at each new object in
-##' the environment, decide what to do with it. Handles plain objects,
-##' functions, existing S3 methods, S4 classes and methods.
-##' @param fallback_env environment to assign objects which don't exist in the
-##'     package namespace
-.ess.ns_source <- function(file, visibly, output, expr,
-                           package = "", verbose = FALSE,
-                           fake.source = FALSE,
-                           fallback_env = NULL,
-                           local_env = NULL) {
-    pname <- paste("package:", package, sep = "")
-    envpkg <- tryCatch(as.environment(pname), error = function(cond) NULL)
-
-    if (is.null(envpkg)) {
-        if (suppressWarnings(require(package, quietly = TRUE, character.only = TRUE))) {
-            envpkg <- tryCatch(as.environment(pname), error = function(cond) NULL)
-        } else {
-            ## no such package; source in current (local) user environment
-            return(.ess.source(file, visibly = visibly,
-                               output = output, local = local_env,
-                               fake.source = fake.source))
-        }
-    }
-
-    envns <- tryCatch(asNamespace(package), error = function(cond) NULL)
-    if (is.null(envns))
-        stop(gettextf("Can't find a namespace environment corresponding to package name '%s\"",
-                      package), domain = NA)
-
-    ## Here we know that both envns and envpkg exists and are environments
-    if (is.null(fallback_env))
-        fallback_env <- .ess.ns_insert_essenv(envns)
-
-    ## Get all Imports envs where we propagate objects
-    pkgEnvNames <- Filter(.ess.is_package, search())
-    packages <- lapply(pkgEnvNames, function(envName) substring(envName, 9))
-    importsEnvs <- lapply(packages, function(pkgName) parent.env(asNamespace(pkgName)))
-
-    ## Evaluate the FILE into new ENV
-    env <- .ess.ns_evalSource(file, visibly, output, substitute(expr), package, fake.source)
-    envPackage <- getPackageName(env, FALSE)
-    if (nzchar(envPackage) && envPackage != package)
-        warning(gettextf("Supplied package, %s, differs from package inferred from source, %s",
-                         sQuote(package), sQuote(envPackage)), domain = NA)
-
-    ## Get all sourced objects, methods and classes
-    allObjects <- objects(envir = env, all.names = TRUE)
-    allObjects <- allObjects[!(allObjects %in% c(".cacheOnAssign", ".packageName"))]
-    MetaPattern <- methods:::.TableMetaPattern()
-    ClassPattern <- methods:::.ClassMetaPattern()
-    allPlainObjects <- allObjects[!(grepl(MetaPattern, allObjects) |
-                                    grepl(ClassPattern, allObjects))]
-    allMethodTables <- allObjects[grepl(MetaPattern, allObjects)]
-    allClassDefs <- allObjects[grepl(ClassPattern, allObjects)]
-
-    ## PLAIN OBJECTS and FUNCTIONS:
-    funcNs <- funcPkg <- newFunc <- newNs <- newObjects <- newPkg <- objectsNs <- objectsPkg <- character()
-    dependentPkgs <- list()
-
-    for (this in allPlainObjects) {
-        thisEnv <- get(this, envir = env)
-        thisNs <- NULL
-
-        ## NS
-        if (exists(this, envir = envns, inherits = FALSE)){
-            thisNs <- get(this, envir = envns)
-            if(is.function(thisNs) || is.function(thisEnv)){
-                if(is.function(thisNs) && is.function(thisEnv)){
-                    if(.ess.differs(thisEnv, thisNs)){
-                        environment(thisEnv) <- environment(thisNs)
-                        .ess.assign(this, thisEnv, envns)
-                        funcNs <- c(funcNs, this)
-                        if(exists(".__S3MethodsTable__.", envir = envns, inherits = FALSE)){
-                            S3_table <- get(".__S3MethodsTable__.", envir = envns)
-                            if(exists(this, envir = S3_table, inherits = FALSE))
-                                .ess.assign(this, thisEnv, S3_table)
-                        }
-                    }
-                }else{
-                    newNs <- c(newNs, this)
-                }
-            }else{
-                if(!identical(thisEnv, thisNs)){
-                    .ess.assign(this, thisEnv, envns)
-                    objectsNs <- c(objectsNs, this)
-                }
-            }
-        }else{
-            newNs <- c(newNs, this)
-        }
-
-        ## PKG
-        if (exists(this, envir = envpkg, inherits = FALSE)){
-            thisPkg <- get(this, envir = envpkg)
-            if(is.function(thisPkg) || is.function(thisEnv)){
-                if(is.function(thisPkg) && is.function(thisEnv)){
-                    if(.ess.differs(thisPkg, thisEnv)){
-                        environment(thisEnv) <- environment(thisPkg)
-                        .ess.assign(this, thisEnv, envpkg)
-                        funcPkg <- c(funcPkg, this)
-                    }
-                }else{
-                    newPkg <- c(newPkg, this)
-                }
-            }else{
-                if(!identical(thisPkg, thisEnv)){
-                    .ess.assign(this, thisEnv, envpkg)
-                    objectsPkg <- c(objectsPkg, this)
-                }
-            }
-        }else{
-            newPkg <- c(newPkg, this)
-        }
-
-        if (!is.null(thisNs)) {
-            isDependent <- .ess.ns_propagate(thisEnv, this, importsEnvs)
-            newDeps <- stats::setNames(list(packages[isDependent]), this)
-            dependentPkgs <- c(dependentPkgs, newDeps)
-        }
-    }
-
-    ## deal with new plain objects and functions
-    for (this in intersect(newPkg, newNs)) {
-        thisEnv <- get(this, envir = env, inherits = FALSE)
-        if (exists(this, envir = fallback_env, inherits = FALSE)){
-            thisGl <- get(this, envir = fallback_env)
-            if (.ess.differs(thisEnv, thisGl)) {
-                if (is.function(thisEnv)) {
-                    environment(thisEnv) <- envns
-                    newFunc <- c(newFunc, this)
-                } else {
-                    newObjects <- c(newObjects, this)
-                }
-                .ess.assign(this, thisEnv, fallback_env)
-                if (.is.essenv(fallback_env))
-                    .ess.assign(this, thisEnv, .GlobalEnv)
-            }
-        } else {
-            if (is.function(thisEnv)) {
-                environment(thisEnv) <- envns
-                newFunc <- c(newFunc, this)
-            } else {
-                newObjects <- c(newObjects, this)
-            }
-            .ess.assign(this, thisEnv, fallback_env)
-            if (.is.essenv(fallback_env))
-                .ess.assign(this, thisEnv, .GlobalEnv)
-        }
-    }
-
-    if(length(funcNs))
-        objectsNs <- c(objectsNs, sprintf("FUN[%s]", paste(funcNs, collapse = ", ")))
-    if(length(funcPkg))
-        objectsPkg <- c(objectsPkg, sprintf("FUN[%s]", paste(funcPkg, collapse = ", ")))
-    if(length(newFunc))
-        newObjects <- c(newObjects, sprintf("FUN[%s]", paste(newFunc, collapse = ", ")))
-
-    ## CLASSES
-    classesPkg <- classesNs <- newClasses <- character()
-    for(this in allClassDefs){
-        newPkg <- newNs <- FALSE
-        thisEnv <- get(this, envir = env)
-        if(exists(this, envir = envpkg, inherits = FALSE)){
-            if(!.ess.identicalClass(thisEnv, get(this, envir = envpkg))){
-                .ess.assign(this, thisEnv, envir = envpkg)
-                classesPkg <- c(classesPkg, this)
-            }
-        }else{
-            newPkg <- TRUE
-        }
-        if(exists(this, envir = envns, inherits = FALSE)){
-            if(!.ess.identicalClass(thisEnv, get(this, envir = envns))){
-                .ess.assign(this, thisEnv, envir = envns)
-                classesNs <- c(classesNs, this)
-            }
-        }else{
-            newNs <- TRUE
-        }
-        if(newNs && newPkg){
-            if(exists(this, envir = fallback_env, inherits = FALSE)){
-                if(!.ess.identicalClass(thisEnv, get(this, envir = fallback_env))){
-                    .ess.assign(this, thisEnv, envir = fallback_env)
-                    newClasses <- c(newClasses, this)
-                }
-            }else{
-                .ess.assign(this, thisEnv, envir = fallback_env)
-                newClasses <- c(newClasses, this)
-            }
-        }
-    }
-    if(length(classesPkg))
-        objectsPkg <- gettextf("CLS[%s]", sub(ClassPattern, "", paste(classesPkg, collapse = ", ")))
-    if(length(classesNs))
-        objectsNs <- gettextf("CLS[%s]", sub(ClassPattern, "", paste(classesNs, collapse = ", ")))
-    if(length(newClasses))
-        newObjects <- gettextf("CLS[%s]", sub(ClassPattern, "", paste(newClasses, collapse = ", ")))
-
-    ## METHODS:
-    ## Method internals: For efficiency reasons setMethod() caches
-    ## method definition into a global table which you can get with
-    ## 'getMethodsForDispatch' function, and when a method is dispatched that
-    ## table is used. When ess-developer is used to source method definitions the
-    ## two copies of the functions are identical up to the environment. The
-    ## environment of the cached object has namespace:foo as it's parent but the
-    ## environment of the object in local table is precisely namespace:foo. This
-    ## does not cause any difference in evaluation.
-    methodNames <- allMethodTables
-    methods <- sub(methods:::.TableMetaPrefix(), "", methodNames)
-    methods <- sub(":.*", "", methods)
-    methodsNs <- newMethods <- character()
-    for (i in seq_along(methods)){
-        table <- methodNames[[i]]
-        tableEnv <- get(table,  envir = env)
-        if(exists(table,  envir = envns, inherits = FALSE)){
-            inserted <- .ess.ns_insertMethods(tableEnv, get(table, envir = envns), envns)
-            if(length(inserted))
-                methodsNs <- c(methodsNs,  gettextf("%s{%s}", methods[[i]], paste(inserted, collapse = ", ")))
-        }else if(exists(table,  envir = fallback_env, inherits = FALSE)){
-            inserted <- .ess.ns_insertMethods(tableEnv, get(table, envir = fallback_env), envns)
-            if(length(inserted))
-                newMethods <- c(newMethods,  gettextf("%s{%s}", methods[[i]], paste(inserted, collapse = ", ")))
-        }else{
-            .ess.assign(table, tableEnv, envir = fallback_env)
-            newMethods <- c(newMethods,  gettextf("%s{%s}", methods[[i]], paste(objects(envir = tableEnv, all.names = T), collapse = ", ")))
-        }
-    }
-    if(length(methodsNs))
-        objectsNs <- c(objectsNs, gettextf("METH[%s]", paste(methodsNs, collapse = ", ")))
-    if(length(newMethods))
-        newObjects <- c(newObjects, gettextf("METH[%s]", paste(newMethods, collapse = ", ")))
-
-    if (verbose) {
-        msgs <- unlist(list(
-            if(length(objectsPkg))
-                sprintf("PKG: %s", paste(objectsPkg, collapse = ", ")),
-            if(length(objectsNs))
-                sprintf("NS: %s", paste(objectsNs, collapse = ", ")),
-            if(length(dependentPkgs))
-                .ess.ns_format_deps(dependentPkgs),
-            if(length(newObjects)) {
-                env_name <- .ess.ns_env_name(fallback_env)
-                sprintf("%s: %s", env_name, paste(newObjects, collapse = ", "))
-            }))
-        if(length(msgs))
-            .ess_mpi_message(paste(msgs, collapse = "  "))
-
-    }
-
-    invisible(env)
-}
-
-\f
-.ess.ns_insertMethods <- function(tableEnv,  tablePkg, envns) {
-    inserted <- character()
-    for(m in ls(envir = tableEnv, all.names = T)){
-        if(exists(m, envir = tablePkg, inherits = FALSE)){
-            thisEnv <- get(m, envir = tableEnv)
-            thisPkg <- get(m, envir = tablePkg)
-            if(is(thisEnv, "MethodDefinition") && is(thisPkg, "MethodDefinition") &&
-               .ess.differs(thisEnv@.Data, thisPkg@.Data)){
-                environment(thisEnv@.Data) <- envns
-                ## environment of cached method in getMethodsForDispatch table is still env
-                ## not a problem as such,  but might confuse users
-                .ess.assign(m, thisEnv, tablePkg)
-                inserted <- c(inserted, m)
-            }}}
-    inserted
-}
-
-## our version of R's evalSource
-.ess.ns_evalSource <- function(file, visibly, output, expr, package = "",
-                               fake.source = FALSE) {
-    envns <- tryCatch(asNamespace(package), error = function(cond) NULL)
-    if(is.null(envns))
-        stop(gettextf("Package \"%s\" is not attached and no namespace found for it",
-                      package), domain = NA)
-    env <- new.env(parent = envns)
-    env[[".packageName"]] <- package
-    methods:::setCacheOnAssign(env, TRUE)
-    if (missing(file))
-        eval(expr, envir = env)
-    else  if (is(file, "character"))
-        for (f in file) {
-            .ess.source(f, local = env, visibly = visibly,
-                        output = output, keep.source = TRUE,
-                        max.deparse.length = 300,
-                        fake.source = fake.source,
-                        message.prefix = sprintf("[%s] ", package))
-        }
-    else stop(gettextf("Invalid file argument:  got an object of class \"%s\"",
-                       class(file)[[1]]), domain = NA)
-    env
-}
-
-\f
-.ess.assign <- function(x, value, envir) {
-    ## Cannot add bindings to locked environments
-    exists <- exists(x, envir = envir, inherits = FALSE)
-    if (exists && bindingIsLocked(x, envir)) {
-        unlockBinding(x, envir)
-        assign(x, value, envir = envir, inherits = FALSE)
-        op <- options(warn = -1)
-        on.exit(options(op))
-        lockBinding(x, envir)
-    } else if (exists || !environmentIsLocked(envir)) {
-        assign(x, value, envir = envir, inherits = FALSE)
-    } else {
-        warning(sprintf("Cannot assign `%s` in locked environment", x),
-                call. = FALSE)
-    }
-    invisible(NULL)
-}
-
-.ess.identicalClass <- function(cls1, cls2, printInfo = FALSE) {
-    slots1 <- slotNames(class(cls1))
-    slots2 <- slotNames(class(cls2))
-    if(identical(slots1, slots2)){
-        vK <- grep("versionKey", slots1)
-        if(length(vK))
-            slots1 <- slots2 <- slots1[-vK]
-        out <- sapply(slots1, function(nm) identical(slot(cls1, nm), slot(cls2, nm)))
-        if(printInfo) print(out)
-        all(out)
-    }
-}
-
-.ess.differs <- function(f1, f2) {
-    if (is.function(f1) && is.function(f2)){
-        !(identical(body(f1), body(f2)) && identical(args(f1), args(f2)))
-    }else
-        !identical(f1, f2)
-}
-
-\f
-.ess.is_package <- function(envName) {
-  isPkg <- identical(substring(envName, 0, 8), "package:")
-  isPkg && (envName != "package:base")
-}
-
-.ess.ns_propagate <- function(obj, name, importsEnvs) {
-  containsObj <- vapply(importsEnvs, logical(1), FUN = function(envs) {
-    name %in% names(envs)
-  })
-
-  lapply(importsEnvs[containsObj], .ess.assign,
-         x = name, value = obj)
-
-  containsObj
-}
-
-
-.ess.ns_format_deps <- function(dependentPkgs) {
-    pkgs <- unique(unlist(dependentPkgs, use.names = FALSE))
-
-    lapply(pkgs, function(pkg) {
-        isDep <- vapply(dependentPkgs, function(deps) pkg %in% deps, logical(1))
-        pkgDependentObjs <- names(dependentPkgs[isDep])
-        sprintf("DEP:%s [%s]   ", pkg, paste(pkgDependentObjs, collapse = ", "))
-    })
-}
-
-.ess.ns_env_name <- function(env) {
-    name <- environmentName(env)
-    name <-
-        if (name == "") "Local"
-        else if (grepl("^essenv:", name)) "NEW"
-        else name
-    name
-}
-
-\f
-.ess.ns_insert_essenv <- function(nsenv) {
-    if (is.character(nsenv))
-        nsenv <- asNamespace(nsenv)
-    stopifnot(isNamespace(nsenv))
-    if (identical(nsenv, .BaseNamespaceEnv))
-        return(.GlobalEnv)
-    essenv_name <- sprintf("essenv:%s", environmentName(nsenv))
-    nsenv_parent <- parent.env(nsenv)
-    if (environmentName(nsenv_parent) == essenv_name) {
-        return(nsenv_parent)
-    }
-    essenv <- new.env(parent = nsenv_parent)
-    essenv[[".__ESSENV__."]] <- TRUE
-    attr(essenv, "name") <- essenv_name
-    nssym <- ".__NAMESPACE__."
-    nssym_val <- get(nssym, envir = nsenv, inherits = FALSE)
-    unlockBinding(nssym, nsenv)
-    nsenv[[nssym]] <- NULL
-    on.exit({
-        nsenv[[nssym]] <- nssym_val
-        lockBinding(nssym, nsenv)
-    })
-    parent.env(nsenv) <- essenv
-    essenv
-}
-
-.is.essenv <- function(env) {
-    exists(".__ESSENV__.", envir = env, inherits = FALSE)
-}
diff --git a/elpa/ess-20251212.937/etc/ESSR/R/pkg.R b/elpa/ess-20251212.937/etc/ESSR/R/pkg.R
deleted file mode 100644 (file)
index ebd0463..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-
-.ess_keep <- function(.x, .f, ...) {
-  is_true <- vapply(.x, .f, logical(1), ...)
-  .x[is_true]
-}
-
-.ess_devtools_functions <- function() {
-  if (!requireNamespace("devtools")) {
-    .ess_mpi_error("devtools is not installed")
-    stop("internal error")
-  }
-  devtools_env <- asNamespace("devtools")
-  exports <- getNamespaceExports("devtools")
-  funs_exported <- as.list(devtools_env)[exports]
-
-  is_first_arg <- function(f, arg) {
-    args <- names(formals(f))
-    length(args) && args[[1]] == arg
-  }
-
-  funs_pkg <- .ess_keep(funs_exported, is.function)
-  funs_pkg <- .ess_keep(funs_pkg, is_first_arg, "pkg")
-  funs_names <- sort(names(funs_pkg))
-
-  funs_names
-}
diff --git a/elpa/ess-20251212.937/etc/Makefile b/elpa/ess-20251212.937/etc/Makefile
deleted file mode 100644 (file)
index e2d2276..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-### Makefile - for scripts and icons (./etc) of ESS distribution.
-###
-
-## Before making changes here, please take a look at Makeconf
-include ../Makeconf
-
-#ETCFILES = $(wildcard BACKBUG[S5].BAT backbug[s5] *.S sas-keys.*)
-#ETCFILES = ESSR.R ess-developer.R SVN-REVISION *.S sas-keys.* ess-sas-sh-command
-# ETCFILES_1 = *.S sas-keys.* ess-sas-sh-command *.jl
-ETCFILES_1 = ess-sas-sh-command *.jl
-isRELEASE=$(shell test -f .IS.RELEASE && echo 'yes')
-ifeq ($(isRELEASE),yes)
-  ETCFILES = .IS.RELEASE git-ref $(ETCFILES_1)
-else
-  ETCFILES =                     $(ETCFILES_1)
-endif
-
-#ICONS = $(wildcard icons/*.xpm)
-ICONS = icons/*.xpm
-
-ESSR_UTIL_FILES = ESSR/LOADREMOTE
-ESSR_CODE_FILES = ESSR/R/*.R ESSR/R/.*.R
-
-all:
-
-show-etc:
-       @echo $(ETCFILES)
-       ls -l $(ETCFILES)
-
-install :
-       $(INSTALLDIR) $(ETCDIR)/icons
-       $(INSTALLDIR) $(ETCDIR)/ESSR/R
-       $(INSTALL) $(ETCFILES) $(ETCDIR)
-       $(INSTALL) $(ICONS) $(ETCDIR)/icons
-       $(INSTALL) $(ESSR_UTIL_FILES) $(ETCDIR)/ESSR
-       $(INSTALL) $(ESSR_CODE_FILES) $(ETCDIR)/ESSR/R
-       chmod +x $(ETCDIR)/ess-sas-sh-command
-
-uninstall :
-       -cd $(ETCDIR) && $(UNINSTALL) $(ETCFILES)
-       -cd $(ETCDIR) && $(UNINSTALL) $(ICONS)
-       -cd $(ETCDIR) && $(UNINSTALL) $(ESSR_UTIL_FILES)
-       -cd $(ETCDIR) && $(UNINSTALL) $(ESSR_CODE_FILES)
-
-
-
-## 'clean'     shall remove *exactly* those things that are *not* in version control
-clean distclean:
-       rm -rf SVN-REVISION
-## 'distclean' removes also things in VC (svn, when they are remade by "make"):
-# distclean: clean
-#      rm -rf ESSR_*.tar.gz
diff --git a/elpa/ess-20251212.937/etc/all.txt b/elpa/ess-20251212.937/etc/all.txt
deleted file mode 100644 (file)
index 90ade3c..0000000
+++ /dev/null
@@ -1,1058 +0,0 @@
-ACCESS
-ACECLUS
-SAS/STAT User’s Guide
-ADAPTIVEREG
-SAS/STAT User’s Guide
-AGGREGATION
-See SAS Risk Dimensions and SAS High-Performance Risk: Procedures Guide
-ANOM
-SAS/QC User’s Guide
-ANOVA
-SAS/STAT User’s Guide
-APPEND
-Base SAS Procedures Guide
-APPSRV
-SAS/IntrNet: Application Dispatcher
-ARIMA
-SAS/ETS User’s Guide
-ASSESS
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-ASTORE
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-AUTHLIB
-Base SAS Procedures Guide
-AUTOREG
-SAS/ETS User’s Guide
-B
-Procedure
-Location of Procedure Documentation
-BCHOICE
-SAS/STAT User’s Guide
-BGLIMM
-SAS/STAT User’s Guide
-BINNING
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-BNET
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-BOM
-SAS/OR User’s Guide: Bill of Material Processing
-BOOLRULE
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-BOXPLOT
-SAS/STAT User’s Guide
-BUILD
-SAS/AF Procedure Guide
-C
-Procedure
-Location of Procedure Documentation
-CALENDAR
-Base SAS Procedures Guide
-CALIS
-SAS/STAT User’s Guide
-CALLRFC
-SAS/ACCESS Interface to R/3: User’s Guide
-CANCORR
-SAS/STAT User’s Guide
-CANDISC
-SAS/STAT User’s Guide
-CAPABILITY
-SAS/QC User’s Guide
-CARDINALITY
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-CARIMA *Available starting with SAS Viya 3.4.
-SAS Econometrics: Econometrics Procedures
-CAS
-SAS Cloud Analytic Services: CASL Reference
-CASUTIL
-SAS Cloud Analytic Services: User’s Guide
-CATALOG
-Base SAS Procedures Guide
-CATALOG for UNIX
-SAS Companion for UNIX Environments
-CATALOG for Windows
-SAS Companion for Windows
-CATALOG for z/OS
-SAS Companion for z/OS
-CATMOD
-SAS/STAT User’s Guide
-CAUSALGRAPH
-SAS/STAT User’s Guide
-CAUSALMED
-SAS/STAT User’s Guide
-CAUSALTRT
-SAS/STAT User’s Guide
-CCDM
-SAS Econometrics: Econometrics Procedures
-CCOPULA
-SAS Econometrics: Econometrics Procedures
-CESM *Available starting with SAS Viya 3.4.
-SAS Econometrics: Econometrics Procedures
-CHART
-Base SAS Procedures Guide
-CIMPORT
-Base SAS Procedures Guide
-CIMPORT for UNIX
-SAS Companion for UNIX Environments
-CIMPORT for Windows
-SAS Companion for Windows
-CIMPORT for z/OS
-SAS Companion for z/OS
-CLP
-SAS Optimization: Mathematical Optimization Procedures
-CLP
-SAS/OR User’s Guide: Constraint Programming
-CLUSTER
-SAS/STAT User’s Guide
-CNTSELECT
-SAS Econometrics: Econometrics Procedures
-COMPARE
-Base SAS Procedures Guide
-COMPILE
-See SAS Risk Dimensions and SAS High-Performance Risk: Procedures Guide
-COMPUTAB
-SAS/ETS User’s Guide
-CONTENTS
-Base SAS Procedures Guide
-CONTENTS for UNIX
-SAS Companion for UNIX Environments
-CONTENTS for Windows
-SAS Companion for Windows
-CONTENTS for z/OS
-SAS Companion for z/OS
-CONVERT for UNIX
-SAS Companion for UNIX Environments
-CONVERT for Windows
-SAS Companion for Windows
-CONVERT for z/OS
-SAS Companion for z/OS
-COPULA
-See SAS/ETS User’s Guide
-COPY
-Base SAS Procedures Guide
-CORR
-Base SAS Procedures Guide: Statistical Procedures
-CORRELATION
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-CORRESP
-SAS/STAT User’s Guide
-COUNTREG
-SAS/ETS User’s Guide
-CPANEL
-SAS Econometrics: Econometrics Procedures
-CPM
-SAS/OR User’s Guide: Project Management
-CPORT
-Base SAS Procedures Guide
-CPORT for UNIX
-SAS Companion for UNIX Environments
-CPORT for Windows
-SAS Companion for Windows
-CPORT for z/OS
-SAS Companion for z/OS
-CQLIM
-SAS Econometrics: Econometrics Procedures
-CSPATIALREG
-SAS Econometrics: Econometrics Procedures
-CUSUM
-SAS/QC User’s Guide
-CV2VIEW
-SAS/ACCESS for Relational Databases: Reference
-D
-Procedure
-Location of Procedure Documentation
-DATEKEYS
-Base SAS Procedures Guide
-DATASETS
-Base SAS Procedures Guide
-DATASETS for UNIX
-SAS Companion for UNIX Environments
-DATASETS for Windows
-SAS Companion for Windows
-DATASETS for z/OS
-SAS Companion for z/OS
-DATASOURCE
-SAS/ETS User’s Guide
-DB2EXT for z/OS
-SAS/ACCESS for Relational Databases: Reference
-DB2UTIL for z/OS
-SAS/ACCESS for Relational Databases: Reference
-DBCSTAB
-SAS National Language Support (NLS): Reference Guide
-DBF for PC Files
-SAS/ACCESS Interface to PC Files: Reference
-DBF for z/OS
-SAS Companion for z/OS
-DBLOAD
-SAS/ACCESS for Relational Databases: Reference
-DBLOAD for PC Files
-SAS/ACCESS Interface to PC Files: Reference
-DBLOAD for SYSTEM 2000 (z/OS only)
-SAS/ACCESS Interface to SYSTEM 2000: Reference
-DELETE
-Base SAS Procedures Guide
-DFIL *Available starting with SAS Viya 3.5.
-SAS Visual Forecasting: Forecasting Procedures
-DIF for PC Files
-SAS/ACCESS Interface to PC Files: Reference
-DISCRIM
-SAS/STAT User’s Guide
-DISPLAY
-Base SAS Procedures Guide
-DISTANCE
-SAS/STAT User’s Guide
-DMSRVADM
-SAS Data Quality Server: Reference
-DMSRVDATASVC
-SAS Data Quality Server: Reference
-DMSRVPROCESSSVC
-SAS Data Quality Server: Reference
-DOCUMENT
-SAS Output Delivery System: Procedures Guide
-DOWNLOAD
-SAS/CONNECT User’s Guide
-DOWNLOAD
-SAS/CONNECT for SAS Viya: User’s Guide
-DQLOCLST
-SAS Data Quality Server: Reference
-DQMATCH
-SAS Data Quality Server: Reference
-DQSCHEME
-SAS Data Quality Server: Reference
-DS2
-Base SAS Procedures Guide
-DSTODS2
-Base SAS Procedures Guide
-DTREE
-SAS/OR User’s Guide: Project Management
-E
-Procedure
-Location of Procedure Documentation
-ECM *Available starting with SAS Viya 3.4.
-SAS Econometrics: Econometrics Procedures
-ENTROPY
-SAS/ETS User’s Guide
-ESM
-SAS/ETS User’s Guide
-EXPAND
-SAS/ETS User’s Guide
-EXPLODE
-SAS documentation on support.sas.com
-EXPORT
-Base SAS Procedures Guide
-EXPORT for PC Files
-SAS/ACCESS Interface to PC Files: Reference
-F
-Procedure
-Location of Procedure Documentation
-FACTEX
-SAS/QC User’s Guide
-FACTMAC
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-FACTOR
-SAS/STAT User’s Guide
-FASTCLUS
-SAS/STAT User’s Guide
-FASTKNN
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-FCMP
-Base SAS Procedures Guide
-FEDSQL
-Base SAS Procedures Guide
-FISM
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-FMM
-SAS/STAT User’s Guide
-FMTC2ITM
-Base SAS Procedures Guide
-FONTREG
-Base SAS Procedures Guide
-FONTREG for z/OS
-SAS Companion for z/OS
-FOREST
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-FORMAT
-Base SAS Procedures Guide
-FORMAT for z/OS
-SAS Companion for z/OS
-FORMS
-SAS documentation on support.sas.com
-FREQ
-Base SAS Procedure’s Guide: Statistical Procedures
-FREQ
-SAS/STAT User’s Guide
-FREQTAB
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-FSBROWSE
-SAS/FSP Procedures Guide
-FSEDIT
-SAS/FSP Procedures Guide
-FSLETTER
-SAS/FSP Procedures Guide
-FSLIST
-Base SAS Procedures Guide
-FSVIEW
-SAS/FSP Procedures Guide
-G
-Procedure
-Location of Procedure Documentation
-G3D
-SAS/GRAPH: Reference
-G3GRID
-SAS/GRAPH: Reference
-GA
-SAS/OR User’s Guide: Local Search Optimization
-GAM
-SAS/STAT User’s Guide
-GAMMOD
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-GAMPL
-SAS/STAT User’s Guide
-GAMSELECT *Available starting with SAS Viya 3.5.
-SAS Visual Statistics: Procedures
-GANNO
-SAS/GRAPH: Reference
-GANTT
-SAS/OR User’s Guide: Project Management
-GAREABAR
-SAS/GRAPH: Reference
-GBARLINE
-SAS/GRAPH: Reference
-GCHART
-SAS/GRAPH: Reference
-GCONTOUR
-SAS/GRAPH: Reference
-GDEVICE
-SAS/GRAPH: Reference
-GEE
-SAS/STAT User’s Guide
-GENSELECT
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-GENMOD
-SAS/STAT User’s Guide
-GEOCODE
-SAS/GRAPH and Base SAS: Mapping Reference
-GFONT
-SAS/GRAPH: Reference
-GINSIDE
-SAS/GRAPH and Base SAS: Mapping Reference
-GIS
-SAS/GIS: Spatial Data and Procedure Guide
-GKPI
-SAS/GRAPH: Reference
-GLIMMIX
-SAS/STAT User’s Guide
-GLM
-SAS/STAT User’s Guide
-GLMMOD
-SAS/STAT User’s Guide
-GLMPOWER
-SAS/STAT User’s Guide
-GLMSELECT
-SAS/STAT User’s Guide
-GMAP
-SAS/GRAPH and Base SAS: Mapping Reference
-GMM *Available starting with SAS Viya 3.4.
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-GOPTIONS
-SAS/GRAPH: Reference
-GPLOT
-SAS/GRAPH: Reference
-GPROJECT
-SAS/GRAPH and Base SAS: Mapping Reference
-GRADAR
-SAS/GRAPH: Reference
-GRADBOOST
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-GREDUCE
-SAS/GRAPH and Base SAS: Mapping Reference
-GREMOVE
-SAS/GRAPH: Reference
-GREPLAY
-SAS/GRAPH: Reference
-GROOVY
-Base SAS Procedures Guide
-GSLIDE
-SAS/GRAPH: Reference
-GTILE
-SAS/GRAPH: Reference
-GVARCLUS
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-H
-Procedure
-Location of Procedure Documentation
-HADOOP
-Base SAS Procedures Guide
-HDMD
-Base SAS Procedures Guide
-HMM
-SAS Econometrics: Econometrics Procedures
-HP4SCORE
-SAS Enterprise Miner: High-Performance Procedures
-HPBIN
-Base Procedures Guide: High-Performance Procedures
-HPBNET
-SAS Enterprise Miner: High-Performance Procedures
-HPBOOLRULE
-SAS Text Miner: High-Performance Procedures
-HPCANDISC
-SAS/STAT User's Guide: High-Performance Procedures
-HPCDM
-SAS/ETS User's Guide: High-Performance Procedures
-HPCLUS
-SAS Enterprise Miner: High-Performance Procedures
-HPCOPULA
-SAS/ETS User's Guide: High-Performance Procedures
-HPCORR
-Base Procedures Guide: High-Performance Procedures
-HPCOUNTREG
-SAS/ETS User's Guide: High-Performance Procedures
-HPDECIDE
-SAS Enterprise Miner: High-Performance Procedures
-HPDMDB
-Base Procedures Guide: High-Performance Procedures
-HPDS2
-Base Procedures Guide: High-Performance Procedures
-HPEXPORT
-See SAS Risk Dimensions and SAS High-Performance Risk: Procedures Guide
-HPF
-SAS Forecast Server Procedures: User's Guide
-HPFARIMASPEC
-SAS Forecast Server Procedures: User's Guide
-HPFDIAGNOSE
-SAS Forecast Server Procedures: User's Guide
-HPFENGINE
-SAS Forecast Server Procedures: User's Guide
-HPFESMSPEC
-SAS Forecast Server Procedures: User's Guide
-HPFEVENTS
-SAS Forecast Server Procedures: User's Guide
-HPFEXMSPEC
-SAS Forecast Server Procedures: User's Guide
-HPFIDMSPEC
-SAS Forecast Server Procedures: User's Guide
-HPFMM
-SAS/STAT User's Guide: High-Performance Procedures
-HPFOREST
-SAS Enterprise Miner: High-Performance Procedures
-HPFRECONCILE
-SAS Forecast Server Procedures: User's Guide
-HPFREPOSITORY (Experimental)
-SAS Forecast Server Procedures: User's Guide
-HPFSELECT
-SAS Forecast Server Procedures: User's Guide
-HPFTEMPRECON
-SAS Forecast Server Procedures: User's Guide
-HPFUCMSPEC
-SAS Forecast Server Procedures: User's Guide
-HPGENSELECT
-SAS/STAT User's Guide: High-Performance Procedures
-HPIMPUTE
-Base Procedures Guide: High-Performance Procedures
-HPLMIXED
-SAS/STAT User's Guide: High-Performance Procedures
-HPLOGISTIC
-SAS/STAT User's Guide: High-Performance Procedures
-HPMIXED
-SAS/STAT: User’s Guide
-HPNEURAL
-SAS Enterprise Miner: High-Performance Procedures
-HPNLMOD
-SAS/STAT User's Guide: High-Performance Procedures
-HPPANEL
-SAS/ETS User's Guide: High-Performance Procedures
-HPPLS
-SAS/STAT User's Guide: High-Performance Procedures
-HPPRINCOMP
-SAS/STAT User's Guide: High-Performance Procedures
-HPQUANTSELECT
-SAS/STAT User's Guide: High-Performance Procedures
-HPQLIM
-SAS/ETS User's Guide: High-Performance Procedures
-HPREDUCE
-SAS Enterprise Miner: High-Performance Procedures
-HPREG
-SAS/STAT User's Guide: High-Performance Procedures
-HPRISK
-See SAS Risk Dimensions and SAS High-Performance Risk: Procedures Guide
-HPSAMPLE
-Base Procedures Guide: High-Performance Procedures
-HPSEVERITY
-SAS/ETS User's Guide: High-Performance Procedures
-HPSPLIT
-SAS/STAT User's Guide: High-Performance Procedures
-HPSUMMARY
-Base Procedures Guide: High-Performance Procedures
-HPSVM
-SAS Enterprise Miner: High-Performance Procedures
-HPTMINE
-SAS Text Miner: High-Performance Procedures
-HPTMSCORE
-SAS Text Miner: High-Performance Procedures
-HTTP
-Base SAS Procedures Guide
-I
-Procedure
-Location of Procedure Documentation
-ICA *Available starting with SAS Viya 3.4.
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-ICLIFETEST
-SAS/STAT User’s Guide
-ICPHREG
-SAS/STAT User’s Guide
-IML
-SAS/IML User’s Guide
-IMPORT
-Base SAS Procedures Guide
-IMPORT for PC Files
-SAS/ACCESS Interface to PC Files: Reference
-IMSTAT (Analytics)
-SAS LASR Analytic Server: Reference Guide
-IMSTAT (Data and Server Management)
-SAS LASR Analytic Server: Reference Guide
-IMXFER
-SAS LASR Analytic Server: Reference Guide
-INBREED
-SAS/STAT User’s Guide
-INFOMAPS
-Base SAS Guide to Information Maps
-IOMOPERATE
-SAS Intelligence Platform: Application Server Administration Guide
-IRT
-SAS/STAT User’s Guide
-ISHIKAWA
-SAS/QC User’s Guide
-ITEMS
-SAS Companion for z/OS
-J
-Procedure
-Location of Procedure Documentation
-JAVAINFO
-Base SAS Procedures Guide
-JSON
-Base SAS Procedures Guide
-K
-Procedure
-Location of Procedure Documentation
-KCLUS
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-KDE
-SAS/STAT User’s Guide
-KPCA *Available starting with SAS Viya 3.5.
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-KRIGE2D
-SAS/STAT User’s Guide
-L
-Procedure
-Location of Procedure Documentation
-LASR
-SAS LASR Analytic Server: Reference Guide
-LATTICE
-SAS/STAT User’s Guide
-LIFEREG
-SAS/STAT User’s Guide
-LIFETEST
-SAS/STAT User’s Guide
-LMIXED *Available starting with SAS Viya 3.4.
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-LOAN
-SAS/ETS User’s Guide
-LOCALEDATA
-SAS National Language Support (NLS): Reference Guide
-LOESS
-SAS/STAT User’s Guide
-LOGISTIC
-SAS/STAT User’s Guide
-LOGSELECT
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-LUA
-Base SAS Procedures Guide
-M
-Procedure
-Location of Procedure Documentation
-MACONTROL
-SAS/QC User’s Guide
-MAPIMPORT
-SAS/GRAPH and Base SAS: Mapping Reference
-MBANALYSIS
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-MBC *Available starting with SAS Viya 3.4.
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-MCMC
-SAS/STAT User’s Guide
-MDC
-SAS/ETS User’s Guide
-MDDB
-See SAS/MDDB Server Help in SAS Help and Documentation
-MDS
-SAS/STAT User’s Guide
-MDSUMMARY
-SAS Cloud Analytic Services: User’s Guide
-MEANS
-Base SAS Procedures Guide
-METADATA
-SAS Language Interfaces to Metadata
-METALIB
-SAS Language Interfaces to Metadata
-METAOPERATE
-SAS Language Interfaces to Metadata
-MI
-SAS/STAT User’s Guide
-MIANALYZE
-SAS/STAT User’s Guide
-MIGRATE
-Base SAS Procedures Guide
-MIXED
-SAS/STAT User’s Guide
-MODECLUS
-SAS/STAT User’s Guide
-MODEL
-SAS/ETS User’s Guide
-MODELMATRIX *Available starting with SAS Viya 3.4.
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-MTLEARN *Available starting with SAS Viya 3.4.
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-MULTTEST
-SAS/STAT User’s Guide
-MVPDIAGNOSE
-SAS/QC User’s Guide
-MVPMODEL
-SAS/QC User’s Guide
-MVPMONITOR
-SAS/QC User’s Guide
-MWPCA
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-N
-Procedure
-Location of Procedure Documentation
-NESTED
-SAS/STAT User’s Guide
-NETDRAW
-SAS/OR User’s Guide: Project Management
-NETWORK
-SAS Visual Data Mining and Machine Learning: The NETWORK Procedure
-NLIN
-SAS/STAT User’s Guide
-NLMIXED
-SAS/STAT User’s Guide
-NLMOD
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-NMF *Available starting with SAS Viya 3.5.
-SAS Visual Statistics: Procedures
-NNET
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-NPAR1WAY
-SAS/STAT User’s Guide
-O
-Procedure
-Location of Procedure Documentation
-ODSLIST
-SAS Output Delivery System: Procedures Guide
-ODSTABLE
-SAS Output Delivery System: Procedures Guide
-ODSTEXT
-SAS Output Delivery System: Procedures Guide
-OLAP
-SAS OLAP Server: User’s Guide
-OLAPCONTENTS
-SAS OLAP Server: User’s Guide
-OLAPOPERATE
-SAS OLAP Server: User’s Guide
-OPERATE
-SAS/SHARE User’s Guide
-OPTEX
-SAS/QC User’s Guide
-OPTGRAPH
-SAS OPTGRAPH Procedure : Graph Algorithms and Network Analysis
-OPTIONS
-Base SAS Procedures Guide
-OPTIONS for UNIX
-SAS Companion for UNIX Environments
-OPTIONS for Windows
-SAS Companion for Windows
-OPTIONS for z/OS
-SAS Companion for z/OS
-OPTLOAD
-Base SAS Procedures Guide
-OPTLP
-SAS Optimization: Mathematical Optimization Procedures
-OPTLP
-SAS/OR User’s Guide: Mathematical Programming
-OPTLSO
-SAS/OR User’s Guide: Local Search Optimization
-OPTMILP
-SAS Optimization: Mathematical Optimization Procedures
-OPTMILP
-SAS/OR User’s Guide: Mathematical Programming
-OPTMODEL
-SAS Optimization: Mathematical Optimization Procedures
-OPTMODEL
-SAS/OR User’s Guide: Mathematical Programming
-OPTNET
-SAS/OR User’s Guide: Network Optimization Algorithms
-OPTNETWORK
-SAS Optimization: Network Optimization Procedures
-OPTQP
-SAS Optimization: Mathematical Optimization Procedures
-OPTQP
-SAS/OR User’s Guide: Mathematical Programming
-OPTSAVE
-Base SAS Procedures Guide
-ORTHOREG
-SAS/STAT User’s Guide
-P
-Procedure
-Location of Procedure Documentation
-PANEL
-SAS/ETS User’s Guide
-PARETO
-SAS/QC User’s Guide
-PARTITION
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-PCA
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-PDLREG
-SAS/ETS User’s Guide
-PDS Procedure for z/OS
-SAS Companion for z/OS
-PDSCOPY
-SAS Companion for z/OS
-PHREG
-SAS/STAT User’s Guide
-PHSELECT
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-PLAN
-SAS/STAT User’s Guide
-PLM
-SAS/STAT User’s Guide
-PLOT
-Base SAS Procedures Guide
-PLS
-SAS/STAT User’s Guide
-PLSMOD
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-PM
-SAS/OR User’s Guide: Project Management
-PMENU
-Base SAS Procedures Guide
-PMENU for UNIX
-SAS Companion for UNIX Environments
-PMENU for Windows
-SAS Companion for Windows
-PMENU for z/OS
-SAS Companion for z/OS
-POWER
-SAS/STAT User’s Guide
-PRESENV
-Base SAS Procedures Guide
-PRINCOMP
-SAS/STAT User’s Guide
-PRINQUAL
-SAS/STAT User’s Guide
-PRINT
-Base SAS Procedures Guide
-PRINT for z/OS
-SAS Companion for z/OS
-PRINTTO
-Base SAS Procedures Guide
-PRINTTO for UNIX
-SAS Companion for UNIX Environments
-PRINTTO for Windows
-SAS Companion for Windows
-PRINTTO for z/OS
-SAS Companion for z/OS
-PROBIT
-SAS/STAT User’s Guide
-PRODUCT_STATUS
-Base SAS Procedures Guide
-PROTO
-Base SAS Procedures Guide
-PRTDEF
-Base SAS Procedures Guide
-PRTEXP
-Base SAS Procedures Guide
-PSMATCH
-SAS/STAT User’s Guide
-PWENCODE
-Base SAS Procedures Guide
-Q
-Procedure
-Location of Procedure Documentation
-QDEVICE
-Base SAS Procedures Guide
-QLIM
-SAS/ETS User’s Guide
-QTRSELECT
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-QUANTLIFE
-SAS/STAT User’s Guide
-QUANTREG
-SAS/STAT User’s Guide
-QUANTSELECT
-SAS/STAT User’s Guide
-QUEST for SYSTEM 2000 (z/OS only)
-SAS/ACCESS Interface to SYSTEM 2000: Reference
-R
-Procedure
-Location of Procedure Documentation
-RANK
-Base SAS Procedures Guide
-RAREEVENTS
-SAS/QC User’s Guide
-RDC
-SAS Risk Dimensions and SAS High-Performance Risk: Procedures Guide
-RDPOOL
-SAS Risk Dimensions and SAS High-Performance Risk: Procedures Guide
-RDSEC
-SAS Risk Dimensions and SAS High-Performance Risk: Procedures Guide
-RECOMMEND
-SAS LASR Analytic Server: Reference Guide
-REG
-SAS/STAT User’s Guide
-REGSELECT
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-REGISTRY
-Base SAS Procedures Guide
-RELEASE
-SAS Companion for z/OS
-RELIABILITY
-SAS/QC User’s Guide
-REPORT
-Base SAS Procedures Guide
-RISK
-SAS Risk Dimensions and SAS High-Performance Risk: Procedures Guide
-RMSTREG
-SAS/STAT User’s Guide
-ROBUSTREG
-SAS/STAT User’s Guide
-RPCA
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-RSREG
-SAS/STAT User’s Guide
-S
-Procedure
-Location of Procedure Documentation
-S3
-Base SAS Procedures Guide
-SANDWICH *Available starting with SAS Viya 3.5.
-SAS Visual Statistics: Procedures
-SCAPROC
-Base SAS Procedures Guide
-SCORE
-SAS/STAT User’s Guide
-SCOREACCEL
-Base SAS Procedures Guide
-SEMISUPLEARN *Available starting with SAS Viya 3.4.
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-SEQDESIGN
-SAS/STAT User’s Guide
-SEQTEST
-SAS/STAT User’s Guide
-SERVER
-SAS/SHARE User’s Guide
-SEVERITY
-SAS/ETS User’s Guide
-SEVSELECT
-SAS Econometrics: Econometrics Procedures
-SGDESIGN
-SAS ODS Graphics: Procedures Guide
-SGMAP
-SAS/GRAPH and Base SAS: Mapping Reference
-SGPANEL
-SAS ODS Graphics: Procedures Guide
-SGPIE
-SAS ODS Graphics: Procedures Guide
-SGPLOT
-SAS ODS Graphics: Procedures Guide
-SGRENDER
-SAS ODS Graphics: Procedures Guide
-SGSCATTER
-SAS ODS Graphics: Procedures Guide
-SHEWHART
-SAS/QC User’s Guide
-SIM2D
-SAS/STAT User’s Guide
-SIMILARITY
-SAS/ETS User’s Guide
-SIMLIN
-SAS/ETS User’s Guide
-SIMNORMAL
-SAS/STAT User’s Guide
-SIMSYSTEM *Available starting with SAS Viya 3.5.
-SAS Visual Statistics: Procedures
-SMCALIB *Available starting with SAS Viya 3.4.
-SAS Visual Forecasting: Forecasting Procedures
-SMPROJECT *Available starting with SAS Viya 3.4.
-SAS Visual Forecasting: Forecasting Procedures
-SMSCORE *Available starting with SAS Viya 3.4.
-SAS Visual Forecasting: Forecasting Procedures
-SMSELECT *Available starting with SAS Viya 3.4.
-SAS Visual Forecasting: Forecasting Procedures
-SMSPEC *Available starting with SAS Viya 3.4.
-SAS Visual Forecasting: Forecasting Procedures
-SOAP
-Base SAS Procedures Guide
-SORT
-Base SAS Procedures Guide
-SORT for UNIX
-SAS Companion for UNIX Environments
-SORT for Windows
-SAS Companion for Windows
-SORT for z/OS
-SAS Companion for z/OS
-SOURCE
-SAS Companion for z/OS
-SPARSEML *Available starting with SAS Viya 3.5.
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-SPATIALREG
-SAS/ETS User’s Guide
-SPC
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-SPDO *Available starting with SAS 9.4 when SPD Server SAS client software is installed and in SAS Viya 3.4 and later.
-SAS Scalable Performance Data Server: Administrator’s Guide
-SPECTRA
-SAS/ETS User’s Guide
-SPP
-SAS/STAT User’s Guide
-SQL
-SAS SQL Procedure User’s Guide
-SQOOP
-Base SAS Procedures Guide
-SSM
-SAS/ETS User’s Guide
-STANDARD
-Base SAS Procedures Guide
-STATESPACE
-SAS/ETS User’s Guide
-STDIZE
-SAS/STAT User’s Guide
-STDRATE
-SAS/STAT User’s Guide
-STEPDISC
-SAS/STAT User’s Guide
-STP
-SAS Stored Processes: Developer’s Guide
-STREAM
-Base SAS Procedures Guide
-SUMMARY
-Base SAS Procedures Guide
-SURVEYFREQ
-SAS/STAT User’s Guide
-SURVEYIMPUTE
-SAS/STAT User’s Guide
-SURVEYLOGISTIC
-SAS/STAT User’s Guide
-SURVEYMEANS
-SAS/STAT User’s Guide
-SURVEYPHREG
-SAS/STAT User’s Guide
-SURVEYREG
-SAS/STAT User’s Guide
-SURVEYSELECT
-SAS/STAT User’s Guide
-SVDD
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-SVMACHINE
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-SYSLIN
-SAS/ETS User’s Guide
-T
-Procedure
-Location of Procedure Documentation
-TABULATE
-Base SAS Procedures Guide
-TAPECOPY
-SAS Companion for z/OS
-TAPELABEL
-SAS Companion for z/OS
-TEMPLATE: Crosstabulation Templates
-SAS Output Delivery System: Procedures Guide
-TEMPLATE: Managing Template Stores
-SAS Output Delivery System: Procedures Guide
-TEMPLATE: ODS Graphics
-SAS Output Delivery System: Procedures Guide
-TEMPLATE: Style Templates
-SAS Output Delivery System: Procedures Guide
-TEMPLATE: Tabular Templates
-SAS Output Delivery System: Procedures Guide
-TEMPLATE: Tagsets
-SAS Output Delivery System: Procedures Guide
-TEXTMINE
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-TIMEDATA
-SAS/ETS User’s Guide
-TIMEID
-SAS/ETS User’s Guide
-TIMEPLOT
-Base SAS Procedures Guide
-TIMESERIES
-SAS/ETS User’s Guide
-TMODEL
-SAS/ETS User’s Guide
-TMSCORE
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-TPSPLINE
-SAS/STAT User’s Guide
-TRANSPOSE
-Base SAS Procedures Guide
-TRANSREG
-SAS/STAT User’s Guide
-TRANTAB
-SAS National Language Support (NLS): Reference Guide
-TREE
-SAS/STAT User’s Guide
-TREESPLIT
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-TSCSREG
-SAS/ETS User’s Guide
-TSINFO *Available starting with SAS Viya 3.5.
-SAS Econometrics: Econometrics Procedures
-TSINFO
-SAS Visual Forecasting: Forecasting Procedures
-TSMODEL
-SAS Econometrics: Econometrics Procedures
-TSMODEL
-SAS Visual Forecasting: Forecasting Procedures
-TSNE *Available starting with SAS Viya 3.4.
-SAS Visual Data Mining and Machine Learning: Procedures Guide
-TSRECONCILE
-SAS Visual Forecasting: Forecasting Procedures
-TTEST
-SAS/STAT User’s Guide
-U
-Procedure
-Location of Procedure Documentation
-UCM
-SAS/ETS User’s Guide
-UNIVARIATE
-Base SAS Procedure’s Guide: Statistical Procedures
-UPLOAD
-SAS/CONNECT User’s Guide
-UPLOAD
-SAS/CONNECT for SAS Viya: User’s Guide
-V
-Procedure
-Location of Procedure Documentation
-VARCLUS
-SAS/STAT User’s Guide
-VARCOMP
-SAS/STAT User’s Guide
-VARIMPUTE
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-VARIOGRAM
-SAS/STAT User’s Guide
-VARMAX
-SAS/ETS User’s Guide
-VARREDUCE
-SAS Visual Data Mining and Machine Learning: Statistical Procedures
-VASMP
-SAS LASR Analytic Server: Reference Guide
-X
-Procedure
-Location of Procedure Documentation
-X11
-SAS/ETS User’s Guide
-X12
-SAS/ETS User’s Guide
-X13
-SAS/ETS User’s Guide
-XSL
diff --git a/elpa/ess-20251212.937/etc/ess-julia.jl b/elpa/ess-20251212.937/etc/ess-julia.jl
deleted file mode 100644 (file)
index efa1ce0..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-module ESS
-
-# These methods have been deprecated / moved
-macro current_module()
-    return VERSION >= v"0.7-" ? :(@__MODULE__) : :(current_module())
-end
-
-parse = VERSION >= v"0.7-" ? Base.Meta.parse : Base.parse
-function_module = VERSION >= v"0.7-" ? Base.parentmodule : Base.function_module
-
-function all_help_topics()
-    ## There are not clear topics anymore. Approximate those with a very general
-    ## apropos(" ")
-    Base.Docs.apropos(" ")
-end 
-
-function help(topic::AbstractString)
-    if (VERSION >= v"1.0-")
-        Core.eval(parentmodule(ESS), parse("@doc $topic"))
-    elseif  (VERSION >= v"0.4-")
-        Core.eval(@current_module(), parse("@doc $topic"))
-    else
-        Base.Help.help(topic)
-    end
-end    
-
-## modified version of function show(io::IO, m::Method)
-function fun_args(m::Method)
-    tv, decls, file, line = Base.arg_decl_parts(m)
-    io = VERSION >= v"0.7-" ? Base.stdout : STDOUT::IO # STDOUT is no longer in 1.0
-    if !isempty(tv)
-        Base.show_delim_array(io, tv, '{', ',', '}', false)
-    end
-    print(io, "(")
-    join(io, [escape_string(isempty(d[2]) ? d[1] : d[1]*"::"*d[2]) for d in decls],
-         ",", ",")    
-    Base.print(io, ")")
-end 
-
-## modified versionof show(io::IO, mt::MethodTable)
-function fun_args(f::Function)
-    mt = Base.MethodList(methods(f).mt)
-    mod = function_module(f)   # Base.function_module deprecated in 0.7
-    if mod == Main
-        mod = "nil"
-    end 
-    print("(list \"$mod\" nil '(")
-    for d in mt
-        print("\"")
-        ## method
-        fun_args(d)
-        print("\" ")
-    end
-    print("))")
-end
-
-function fun_args(s::AbstractString)
-    try
-        mod = VERSION >= v"1.0-" ?  parentmodule(ESS) : @current_module()
-        m = Core.eval(mod, parse(s))
-        if ! isa(m, String)
-            fun_args(m)
-        end
-    catch
-        print("(list nil nil nil)")
-    end
-end 
-
-function fun_args(t::DataType)
-    print("(list nil nil '(")
-    for d = fieldnames(t)
-        print("\"$d\" ")
-    end
-    print("))")
-end 
-
-\f
-### OBJECT COMPLETION
-# Must print an output of the form:
-# 
-# Cache                         Module
-# Write                         Module
-# add                           Function
-# free                          Function
-function components(m::Module)
-    for v in sort(names(m, all=true, imported=true))
-        s = string(v)
-        if !startswith(s, "#") && isdefined(m,v)
-            println(rpad(s, 30), summary(Core.eval(m,v)))
-        end
-    end
-end
-
-function components(t::DataType)
-    for v in sort(fieldnames(t))
-        println(rpad(string(v), 30), "field")
-    end
-end
-
-function components(v)
-    t = typeof(v)
-    if isa(t, DataType)
-        return components(t)
-    end
-end
-
-\f
-### MISC
-function main_modules(m::Module)
-    for nm in names(m)
-        if isdefined(m, nm)
-            mod = Core.eval(m, nm)
-            if isa(mod, Module)
-                print("\"$nm\" ")
-            end
-        end
-    end
-end
-
-if VERSION >= v"0.7-"
-    main_modules() = main_modules(Base.parentmodule(@current_module()))
-else
-    main_modules() = main_modules(@current_module())
-end
-
-end 
diff --git a/elpa/ess-20251212.937/etc/ess-sas-sh-command b/elpa/ess-20251212.937/etc/ess-sas-sh-command
deleted file mode 100755 (executable)
index 7c1d910..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/bin/sh
-
-### (C) 1997, Richard M. Heiberger.
-### 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/
-
-
-# For executing SAS, and running it in the proper manner for ESS
-# (feeding output back into appropriate ESS buffers).
-
-#echo $0 $@
-#sas </dev/tty 1>$1 2>$2 $3
-
-set -x
-stdout=$1
-stderr=$2
-shift 2
-set +x
-echo sas \</dev/tty 1\>$stdout 2\>$stderr $@
-sas </dev/tty 1>$stdout 2>$stderr $@
-
-## From the SAS online tech support:
-##
-## Redirecting the SAS Log and Output under UNIX. 
-## 
-## There are several ways of redirecting the SAS Log and Output under
-## UNIX.  
-## 
-## To redirect the SAS Log, follow one of these steps: 
-## 
-##    1.
-##          In the source code, place the following line: 
-## 
-##          proc printto log=stdout;
-## 
-##          to make a duplicate copy of the log in a file in addition
-##          to redirecting it to stdout, use this command to invoke
-##          SAS:  
-## 
-##          sas -altlog doit.log doit.sas
-## 
-##    2.Execute SAS in the background and use the UNIX 'tail' command
-##      to copy lines to stdout as they are added to the log. Use the 
-##      command: 
-## 
-##      sas doit.sas &; tail -f doit.log
-## 
-## To redirect the SAS Log and Output under the Korn shell, use the
-## following command:  
-## 
-## sas -stdio < doit.sas > doit.lst 2> doit.log
-## 
-## To redirect the SAS Log and Output under the C-Shell, use the
-## following command:   
-## 
-## (sas -stdio < doit.sas > doit.lst) >& doit.log
-
-## From WWW.SAS.COM:
-## How can I make SAS in batch mode behave like interactive SAS,
-## continue running my SAS job, and not enter syntax check mode when
-## it encounters an error?
-##
-## You can specify the NOSYNTAXCHECK option when you invoke your SAS
-## program.
diff --git a/elpa/ess-20251212.937/etc/func.sas b/elpa/ess-20251212.937/etc/func.sas
deleted file mode 100644 (file)
index 78d9e1e..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-
-
-proc freq order=freq data=sashelp.vfunc;
-    tables source fnctype fncprod;
-run;
-
-/*
-title 'FNCPROD=B';
-proc print data=sashelp.vfunc;
-    where fncname>' ' & FNCPROD='B';
-run;
-
-title 'FNCPROD=X';
-proc print data=sashelp.vfunc;
-    where fncname>' ' & FNCPROD='X';
-run;
-
-title 'FNCPROD=T';
-proc print data=sashelp.vfunc;
-    where fncname>' ' & FNCPROD='T';
-run;
-
-title 'FNCPROD=I';
-proc print data=sashelp.vfunc;
-    where fncname>' ' & FNCPROD='I';
-run;
-
-    endsas;
-*/
-
-data vfunc;
-    set sashelp.vfunc end=last;
-    by fncname;
-    where fncname>' ' & (fncprod='X' | source=fncprod='B');
-    file "func.txt";
-
-    if _n_=1 then do;
-        put ";; SAS functions found in sashelp.vfunc where fncprod='X' | source=fncprod='B'";
-    end;
-    
-    if last.fncname;
-    
-    fncname=lowcase(fncname);
-
-    retain alpha 'abcdefghijklmnopqrstuvwxyz' prev 1;
-    
-    format fncname $quote32.;
-
-    i=indexc(alpha, substr(fncname, 1, 1));
-
-    if i>prev then do; 
-        prev=i;
-        put;
-    end;
-    
-    put fncname @;
-
-    if last then put;
-run;
-
-data vfunc;
-    set sashelp.vfunc end=last;
-    by fncname;
-    if last.fncname;
-
-    where fncname>' ' & (fncprod='X' | source=fncprod='B');
-    file "check-func.sas";
-
-    fncname=trim(lowcase(fncname))||'();';
-
-    put fncname;
-run;
-
-proc contents varnum;
-run;
-
-proc print;
-    var fncname;
-    format fncname $quote32.;
-run;
diff --git a/elpa/ess-20251212.937/etc/proc.sas b/elpa/ess-20251212.937/etc/proc.sas
deleted file mode 100644 (file)
index dc2a2de..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-
-/*
-all.txt scraped from
-<https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/allprodsproc/procedures.htm>;
-*/
-
-data proc;
-    length name $ 20;
-    infile 'all.txt';
-   
-    input name;
-
-    if length(name)>1 & name^='SAS';
-
-    if verify(name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ')=0;
-
-    name=lowcase(name);
-run;
-
-proc sort nodupkey data=proc;
-    by name;
-run;
-
-data proc;
-    set proc;
-    by name;
-*these PROCs are not present on my system: YMMV;
-*if it starts with HP, then it requires the high-performance products;
-    *where name not in:(
-        'aggregation', 'appsrv', 
-        'compile', 
-        'db2ext', 'db2util', 'dmsrvadm', 'dmsrvdatasvc', 'dmsrvprocesssvc',
-        'dqloclst', 'dqmatch', 'dqscheme', 
-        'gis', 
-        'hp',
-        'imstat', 'imxfer', 'items',
-        'lasr', 
-        'mddb', 
-        'optgraph',
-        'pds', 'pdscopy',
-        'quest', 
-        'rdc', 'rdpool', 'rdsec', 'recommend', 'release', 'risk',
-        'source',
-        'tapecopy', 'tapelabel',
-        'vasmp'
-        );
-run;
-
-proc print; 
-run;
-
-data proc;
-    set proc end=last;
-
-    file "proc.txt";
-
-    retain alpha 'abcdefghijklmnopqrstuvwxyz' prev 1;
-    
-    format name $quote32.;
-
-    i=indexc(alpha, substr(name, 1, 1));
-
-    if i>prev then do; 
-        prev=i;
-        put;
-    end;
-    
-    put name @;
-
-    if last then put;
-run;
-
-data proc;
-length name $ 35;
-    set proc end=last;
-format name;
-    file "check-proc.sas";
-    name='proc '||trim(name)||';run;quit;';
-    put name;
-run;
diff --git a/elpa/ess-20251212.937/etc/proc.txt b/elpa/ess-20251212.937/etc/proc.txt
deleted file mode 100644 (file)
index 9df1543..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-"access" "aceclus" "adaptivereg" "aggregation" "anom" "anova" "append" "appsrv" "arima" "assess" "astore" "authlib" "autoreg"
-"bchoice" "bglimm" "binning" "bnet" "bom" "boolrule" "boxplot" "build"
-"calendar" "calis" "callrfc" "cancorr" "candisc" "capability" "cardinality" "carima" "cas" "casutil" "catalog" "catmod" "causalgraph" "causalmed" "causaltrt" "ccdm" "ccopula" "cesm" "chart" "cimport" "clp" "cluster" "cntselect" "compare" "compile" "computab" "contents" "convert" "copula" "copy" "corr" "correlation" "corresp" "countreg" "cpanel" "cpm" "cport" "cqlim" "cspatialreg" "cusum" "cv2view"
-"datasets" "datasource" "datekeys" "db2ext" "db2util" "dbcstab" "dbf" "dbload" "delete" "dfil" "dif" "discrim" "display" "distance" "dmsrvadm" "dmsrvdatasvc" "dmsrvprocesssvc" "document" "download" "dqloclst" "dqmatch" "dqscheme" "ds2" "dstods2" "dtree"
-"ecm" "entropy" "esm" "expand" "explode" "export"
-"factex" "factmac" "factor" "fastclus" "fastknn" "fcmp" "fedsql" "fism" "fmm" "fmtc2itm" "fontreg" "forest" "format" "forms" "freq" "freqtab" "fsbrowse" "fsedit" "fsletter" "fslist" "fsview"
-"g3d" "g3grid" "ga" "gam" "gammod" "gampl" "gamselect" "ganno" "gantt" "gareabar" "gbarline" "gchart" "gcontour" "gdevice" "gee" "genmod" "genselect" "geocode" "gfont" "ginside" "gis" "gkpi" "glimmix" "glm" "glmmod" "glmpower" "glmselect" "gmap" "gmm" "goptions" "gplot" "gproject" "gradar" "gradboost" "greduce" "gremove" "greplay" "groovy" "gslide" "gtile" "gvarclus"
-"hadoop" "hdmd" "hmm" "hp4score" "hpbin" "hpbnet" "hpboolrule" "hpcandisc"t; "hpsample" "hpseverity" "hpsplit" "hpsummary" "hpsvm" "hptmine" "hptmscore" "http"
-"ica" "iclifetest" "icphreg" "iml" "import" "imstat" "imxfer" "inbreed" "infomaps" "iomoperate" "irt" "ishikawa" "items"
-"javainfo" "json"
-"kclus" "kde" "kpca" "krige2d"
-"lasr" "lattice" "lifereg" "lifetest" "lmixed" "loan" "localedata" "loess" "logistic" "logselect" "lua"
-"macontrol" "mapimport" "mbanalysis" "mbc" "mcmc" "mdc" "mddb" "mds" "mdsummary" "means" "metadata" "metalib" "metaoperate" "mi" "mianalyze" "migrate" "mixed" "modeclus" "model" "modelmatrix" "mtlearn" "multtest" "mvpdiagnose" "mvpmodel" "mvpmonitor" "mwpca"
-"nested" "netdraw" "network" "nlin" "nlmixed" "nlmod" "nmf" "nnet" "npar1way"
-"odslist" "odstable" "odstext" "olap" "olapcontents" "olapoperate" "operate" "optex" "optgraph" "options" "optload" "optlp" "optlso" "optmilp" "optmodel" "optnet" "optnetwork" "optqp" "optsave" "orthoreg"
-"panel" "pareto" "partition" "pca" "pdlreg" "pds" "pdscopy" "phreg" "phselect" "plan" "plm" "plot" "pls" "plsmod" "pm" "pmenu" "power" "presenv" "princomp" "prinqual" "print" "printto" "probit" "proto" "prtdef" "prtexp" "psmatch" "pwencode"
-"qdevice" "qlim" "qtrselect" "quantlife" "quantreg" "quantselect" "quest"
-"rank" "rareevents" "rdc" "rdpool" "rdsec" "recommend" "reg" "registry" "regselect" "release" "reliability" "report" "risk" "rmstreg" "robustreg" "rpca" "rsreg"
-"s3" "sandwich" "scaproc" "score" "scoreaccel" "semisuplearn" "seqdesign" "seqtest" "server" "severity" "sevselect"bsp;"surveymeans" "surveyphreg" "surveyreg" "surveyselect" "svdd" "svmachine" "syslin"
-"tabulate" "tapecopy" "tapelabel" "textmine" "timedata" "timeid" "timeplot" "timeseries" "tmodel" "tmscore" "tpspline" "transpose" "transreg" "trantab" "tree" "treesplit" "tscsreg" "tsinfo" "tsmodel" "tsne" "tsreconcile" "ttest"
-"ucm" "univariate" "upload"
-"varclus" "varcomp" "varimpute" "variogram" "varmax" "varreduce" "vasmp"
-"x11" "x12" "x13" "xsl"
diff --git a/elpa/ess-20251212.937/obsolete/ess-eldoc.el b/elpa/ess-20251212.937/obsolete/ess-eldoc.el
deleted file mode 100644 (file)
index 59f0c46..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-;;; ess-eldoc.el --- Use eldoc to report R function names.  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1997-2022 Free Software Foundation, Inc.
-;; Author: Stephen Eglen
-;; Created: 2007-06-30
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;;;;; eldoc functionality has been moved into the core ;;;;;
-;;;;; this file has no effect and is left in ESS in order not to break
-;;;;; users configuration
-
-;; This is an initial attempt to use the emacs facility ELDOC in R
-;; buffers.  Eldoc is used in Emacs lisp buffers to show the function
-;; arglist and docstrings for variables.  To try it, view an emacs
-;; lisp buffer, and then do M-x turn-on-eldoc-mode, and move over
-;; function and variable names.
-
-;; This file extends eldoc to work in R buffers.  It currently uses
-;; Sven's ess-r-args.el file to retrieve args for a given R function
-;; (via ess-r-args-get).  Note that it works slightly different to
-;; Sven's code, in that you just need to have the point over the name
-;; of an R function, or inside its arguments list, for eldoc to show
-;; the arg list.
-
-;; To use this functionality, simply add
-;;
-;; (require 'ess-eldoc)
-;;
-;; to your .emacs file.  When you visit a R mode, eldoc will be turned
-;; on.  However, you will first need to associate the R buffer with an
-;; *R* process so that args can be looked up -- otherwise, eldoc will
-;; silently not report anything.  So, e.g. try:
-;; C-x C-f somefile.R
-;; M-x R   (so that somefile.R is associated with *R*)
-;; eldoc should then work.
-
-;; e.g. put the following rnorm() command in an R buffer.  The line
-;; underneath shows a key of what arg list will be shown as you move
-;; across the rnorm line.
-
-;; rnorm(n=100, mean=sqrt(20), sd=10)
-;; 1111111111111222223333333311444111
-;; 1: rnorm
-;; 2: mean
-;; 3: sqrt
-;; 4: sd
-;;
-
-;; Note that the arg list for rnorm() should be shown either when you
-;; are on the function name, or in the arg list.  However, since the
-;; 2nd and 3rd arguments are also function names, the arg lists of
-;; those function names are reported instead.  This might be seen as
-;; undesirable behaviour, in which case a solution would be to only
-;; look up the function name if it is followed by (.
-
-;; If you want to use this feature in *R* buffers, add the following
-;; to .emacs:
-;; (add-hook 'inferior-ess-mode-hook 'ess-use-eldoc)
-
-
-;; In the current version, I do not cache the arg list, but that was
-;; done in an earlier version, to save repeated calls to
-;; ess-r-args-get.
-
-;; This code has been tested only in Emacs 22.1.  It will not work on
-;; Emacs 21, because it needs the variable
-;; eldoc-documentation-function.
-
-;;;; VS [25-02-2012]: all these issues were at least partially addressed in the
-;;;; new implementation:
-
-;; Bug (in eldoc?): the arg list for legend() is too long to fit in
-;; minibuffer, and it seems that we see the last N lines of the arg
-;; list, rather than the first N lines.  It would be better to see the
-;; first N lines since the more important args come first.
-
-;; Doc issue: the eldoc vars (e.g. eldoc-echo-area-use-multiline-p)
-;; work only for elisp mode.
-
-;; Issue: You will probably see the message "Using process 'R'" flash;
-;; this is generated by `ess-request-a-process', and I'd like to avoid
-;; that appearing, non-interactively.
-
-;; If *R* is currently busy (e.g. processing Sys.sleep(999)), then the
-;; eldoc commands won't work; ess-command could be silenced in this
-;; regard perhaps with a new SILENT arg for example to prevent the
-;; call to (ess-error).
-
-
-;;; Code:
-
-;; ;; This could be done on buffer local basis.
-;; (setq ess-r-args-noargsmsg "")
-
-;; ;; following two defvars are not currently used.
-;; (defvar ess-eldoc-last-name nil
-;;   "Name of the last function looked up in eldoc.
-;; We remember this to see whether we need to look up documentation, or used
-;; the cached value in `ess-eldoc-last-args'.")
-
-;;  (defvar ess-eldoc-last-args nil
-;;   "Args list last looked up for eldoc.  Used as cache.")
-
-;; (defun ess-eldoc-2 ()
-;;   ;; simple, old version.
-;;   (interactive)
-;;   (ess-r-args-get (ess-read-object-name-default)))
-
-;; (defun ess-eldoc-1 ()
-;;   "Return the doc string, or nil.
-;; This is the first version; works only on function name, not within arg list."
-;;   (interactive)
-
-;;   ;; Possible ways to get the function at point.
-;;   ;;(setq name (thing-at-point 'sexp))
-;;   ;;(setq name (ess-read-object-name-default))
-;;   ;;(setq name (find-tag-default))
-
-;;   (if ess-current-process-name
-;;       (progn
-;;      (setq name (ess-guess-fun))             ;guess the word at point.
-;;      (if (equal (length name) 0)
-;;          nil
-;;        ;; else
-;;        (unless (equal name ess-eldoc-last-name)
-;;          ;; name is different to the last name we lookedup, so get
-;;          ;; new args from R and store them.
-;;          (setq ess-eldoc-last-args (ess-r-args-get name)
-;;                ess-eldoc-last-name name))
-;;        ess-eldoc-last-args))
-;;     ;; no ESS process current.
-;;     nil)
-;; )
-
-
-;; (defsubst ess-guess-fun ()
-;;   "Guess what the function at point is."
-;;   ;; Derived from Man-default-man-entry in man.el
-;;   (let (word)
-;;     (save-excursion
-;;       (skip-chars-backward "-a-zA-Z0-9._+:")
-;;       (let ((start (point)))
-;;      (skip-chars-forward "-a-zA-Z0-9._+:")
-;;      (setq word (buffer-substring-no-properties start (point)))))
-;;       word))
-
-(defun ess-use-eldoc ()
-  "Does nothing. Defined not to break old users' code."
-  (interactive))
-
-(provide 'ess-eldoc)
-
-;;; ess-eldoc.el ends here
diff --git a/elpa/ess-20251212.937/obsolete/ess-font-lock.el b/elpa/ess-20251212.937/obsolete/ess-font-lock.el
deleted file mode 100755 (executable)
index 0487b55..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-;;; ess-font-lock.el --- font-lock color options  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2000-2022  Free Software Foundation, Inc.
-
-;; Author: Richard M. Heiberger <rmhNOSPAMtemple.edu>
-;; Created: 06 Feb 2000
-
-;; Keywords: languages, faces
-
-;; 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/
-
-;;; Commentary:
-
-;; provides syntax highlighting support.
-
-;;; Code:
-
-                                        ; Requires and autoloads
-
-(require 'font-lock)
-(require 'paren)
-
-;; FIXME: What is this doing here!?
-(if (fboundp 'show-paren-mode) (show-paren-mode 1))
-
-;;; Emacs 20.x notes:
-
-;; font-lock faces are defined in /emacs/emacs-20.5/lisp/font-lock.el
-;; The font-lock faces are applied to ESS buffers by
-;; ess-mode.el ess-inf.el ess-trns.el ess-custom.el
-;; The keywords for faces are defined in the ess[dl]*.el files.
-;; All faces can be looked at, under Emacs 20.x, with
-;;        [menu-bar] [Edit] [Text Properties] [Display Faces}
-
-(defun ess-font-lock-rmh ()
-  "Set font-lock colors to Richard Heiberger's usual choice."
-  ;; FIXME: Turn it into a Custom theme!
-  (interactive)
-
-  (set-foreground-color "Black")
-  (set-background-color "lightcyan")
-
-  (set-face-background 'mode-line "lightskyblue")
-  (set-face-foreground 'mode-line "midnightblue")
-
-  (set-face-foreground 'font-lock-comment-face "Firebrick")
-  (set-face-foreground 'font-lock-function-name-face "Blue")
-  (set-face-foreground 'font-lock-keyword-face "Purple")
-  (set-face-foreground 'font-lock-constant-face "Brown")
-  (set-face-foreground 'font-lock-string-face "VioletRed")
-  (set-face-foreground 'font-lock-type-face "Sienna")
-  (set-face-foreground 'font-lock-variable-name-face "Black"))
-
-(defun ess-font-lock-blue ()
-  "Set font-lock colors to Richard Heiberger's blue color scheme."
-  ;; FIXME: Turn it into a Custom theme!
-  (interactive)
-
-  (set-foreground-color "Black")
-  (set-background-color "LightBlue")
-
-  (set-face-foreground 'mode-line "LightBlue")
-  (set-face-background 'mode-line "DarkSlateBlue")
-
-  (set-face-foreground 'font-lock-comment-face "Firebrick")
-  (set-face-foreground 'font-lock-function-name-face "Blue")
-  (set-face-foreground 'font-lock-keyword-face "Purple")
-  (set-face-foreground 'font-lock-constant-face "Brown")
-  (set-face-foreground 'font-lock-string-face "VioletRed")
-  (set-face-foreground 'font-lock-type-face "Sienna")
-  (set-face-foreground 'font-lock-variable-name-face "Black"))
-
-(defun ess-font-lock-wheat ()
-  "Set font-lock colors to Richard Heiberger's wheat color scheme."
-  ;; FIXME: Turn it into a Custom theme!
-  (interactive)
-
-  (set-foreground-color "Black")
-  (set-background-color "Wheat")
-
-  (set-face-foreground 'mode-line "Wheat")
-  (set-face-background 'mode-line "Sienna")
-
-  (set-face-foreground 'font-lock-comment-face "Firebrick")
-  (set-face-foreground 'font-lock-function-name-face "Blue")
-  (set-face-foreground 'font-lock-keyword-face "Purple")
-  (set-face-foreground 'font-lock-constant-face "Brown")
-  (set-face-foreground 'font-lock-string-face "VioletRed")
-  (set-face-foreground 'font-lock-type-face "Sienna")
-  (set-face-foreground 'font-lock-variable-name-face "Black"))
-
-
-(defun ess-font-lock-bw ()
-  "Set font-lock colors to Richard Heiberger's black and white color scheme."
-  ;; FIXME: Turn it into a Custom theme!
-  (interactive)
-
-  (set-foreground-color "Black")
-  (set-background-color "white")
-
-  (set-face-foreground 'mode-line "gray10")
-  (set-face-background 'mode-line "gray90")
-
-  ;; modify-face is an interactive compiled Lisp function in `faces'.
-  ;; Sample usage:
-
-  ;;(modify-face FACE                        FOREGROUND BACKGROUND STIPPLE BOLD-P ITALIC-P UNDERLINE-P &optional INVERSE-P FRAME)
-
-  (modify-face 'mode-line                     "gray10"   "gray90"   nil     nil    t        nil       )
-  (modify-face 'font-lock-comment-face       "black"    "white"    nil     nil    t        nil       )
-  (modify-face 'font-lock-function-name-face "black"    "white"    nil     t      nil      nil       )
-  (modify-face 'font-lock-keyword-face       "black"    "white"    nil     nil    nil      t         )
-  (modify-face 'font-lock-constant-face      "black"    "white"    nil     t      nil      nil       )
-  (modify-face 'font-lock-string-face        "black"    "white"    nil     nil    t        t         )
-  (modify-face 'font-lock-type-face          "black"    "white"    nil     t      t        nil       )
-  (modify-face 'font-lock-variable-name-face "black"    "white"    nil     nil    nil      nil       )
-  (modify-face 'font-lock-builtin-face       "black"    "white"    nil     t      nil      nil       )
-  (modify-face 'font-lock-warning-face       "black"    "white"    nil     t      nil      nil       )
-  (modify-face 'show-paren-match-face        "gray20"   "gray80"   nil     t      nil      nil       )
-  (modify-face 'show-paren-mismatch-face     "white"    "gray40"   nil     t      t        nil       ))
-
-(defun ess-font-lock-db ()
-  "Set font-lock colors (leave fore-/back-ground alone) courtesy David Brahm <David.BrahmNOSPAMfmr.com>"
-  ;; FIXME: Turn it into a Custom theme!
-  (interactive)
-  (set-face-foreground 'font-lock-comment-face       "Firebrick")  ; #...    %...
-  (set-face-foreground 'font-lock-string-face        "SeaGreen")   ; "..."   "..."
-  (set-face-foreground 'font-lock-keyword-face       "MediumBlue") ; if      \end
-  (set-face-foreground 'font-lock-function-name-face "VioletRed")  ; talk<-  {center}
-  (set-face-foreground 'font-lock-variable-name-face "Blue")       ; xv
-  (set-face-foreground 'font-lock-type-face          "Goldenrod")  ; T,F       ?
-  (set-face-foreground 'font-lock-constant-face      "Magenta")    ; <-      {eq1}
-  )
-
-(provide 'ess-font-lock)
-
-;;; ess-font-lock.el ends here
diff --git a/elpa/ess-20251212.937/obsolete/ess-mouse.el b/elpa/ess-20251212.937/obsolete/ess-mouse.el
deleted file mode 100644 (file)
index 6e6976d..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-;;; ess-mouse.el --- Support for mouse- or cursor-sensitive actions  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2001-2022 Free Software Foundation, Inc.
-;; Author: Richard M. Heiberger <rmhNOSPAMtemple.edu>
-;; Created: 25 Mar 2001
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; Support for mouse- or cursor-sensitive actions.  This is based on
-;; and uses mouseme.el.  mouseme.el only does mouse sensitivity.
-;; The new functions ess-mouse-me and ess-mouse-me-helper do similar
-;; things based on the cursor, not the mouse, and can be bound to a
-;; keystroke.
-
-;;; Code:
-
-\f ; Requires and autoloads
-
-;;*;; Requires
-(require 'mouseme)
-(require 'ess-trns)
-;;(if (or (equal window-system 'w32)
-;;      (equal window-system 'win32)
-;;      (equal window-system 'mswindows))
-;;    (require 'essiw32b))
-
-(defun ess-mouse-me ()
-  "Popup a menu of functions to run on selected string or region."
-  (interactive)
-  (ess-mouse-me-helper
-   (lambda (name)
-     (or (x-popup-menu (list '(0 0)
-                             (get-buffer-window (get-buffer (buffer-name))))
-                       (funcall mouse-me-build-menu-function name))
-         (error "No command to run")))))
-
-
-
-(defun ess-mouse-me-helper (func)
-  "Determine the string to use to process EVENT and call FUNC to get cmd."
-  (let (name sp sm mouse beg end cmd mmtype)
-    ;; temporarily goto where the event occurred, get the name clicked
-    ;; on and enough info to figure out what to do with it
-    (save-match-data
-      (save-excursion
-        (setq sp (point))               ; saved point
-        (setq sm (mark t))              ; saved mark
-;;;     (set-buffer (window-buffer (posn-window (event-start event))))
-;;;     (setq mouse (goto-char (posn-point (event-start event))))
-        (setq mouse (point))  ;; ess-mouse-me-helper
-        ;; if there is a region and point is inside it
-        ;; check for sm first incase (null (mark t))
-        ;; set name to either the thing they clicked on or region
-        (if (and sm
-                 (or (and transient-mark-mode mark-active)
-                     (eq last-command 'mouse-drag-region))
-                 (>= mouse (setq beg (min sp sm)))
-                 (<= mouse (setq end (max sp sm))))
-            (setq name (buffer-substring beg end))
-          (setq name (funcall mouse-me-get-string-function))
-          (if (listp name)
-              (setq beg (nth 1 name)
-                    end (nth 2 name)
-                    name (car name))
-            (goto-char mouse)
-            (while (not (looking-at (regexp-quote name)))
-              (backward-char 1))
-            (setq beg (point))
-            (setq end (search-forward name))))))
-    ;; check if name is null, meaning they clicked on no word
-    (if (or (null name)
-            (and (stringp name) (string= name "" )))
-        (error "No string to pass to function"))
-    ;; popup a menu to get a command to run
-    (setq cmd (funcall func name))
-    ;; run the command, eval'ing if it was a list
-    (if (listp cmd)
-        (setq cmd (eval cmd t)))
-    (setq mmtype (get cmd 'mouse-me-type))
-    (cond ((eq mmtype 'region)
-           (funcall cmd beg end))
-          ((eq mmtype 'string)
-           (funcall cmd name))
-          (t
-           (funcall cmd name)))))
-
-(defcustom ess-S-mouse-me-menu-commands-alist
-  '("S-Plus 4 and 6 GUI under Windows"
-    ("Edit.data"   . ess-mouse-me-Edit.data)
-    "----"
-    ("print"       . ess-mouse-me-print)
-    ("summary"     . ess-mouse-me-summary)
-    ("plot"        . ess-mouse-me-plot)
-    ("show"        . ess-mouse-me-show)
-    ("help"        . ess-display-help-on-object)
-    ("args"        . ess-mouse-me-args)
-    "----"
-    ("Browser on"  . ess-mouse-me-browser-on)
-    ("Browser off" . ess-mouse-me-browser-off))
-  "Command menu used by `mouse-me-build-menu'.
-A alist of elements where each element is either a cons cell or a string.
-If a cons cell the car is a string to be displayed in the menu and the
-cdr is either a function to call passing a string to, or a list which evals
-to a function to call passing a string to.  If the element is a string
-it makes a non-selectable element in the menu.  To make a separator line
-use a string consisting solely of hyphens.
-
-The function returned from this menu will be called with one string
-argument.  Or if the function has the symbol property `mouse-me-type'
-and if its value is the symbol `region' it will be called with the
-beginning and ending points of the selected string.  If the value is
-the symbol `string' it will be called with one string argument."
-  :type '(repeat sexp)
-  :group 'mouseme)
-
-
-(defun ess-mouse-me-Edit.data (string)
-  (ess-mouse-me-eval-expanded string "Edit.data(" ")" nil nil nil))
-
-(defun ess-mouse-me-print (string)
-  (ess-mouse-me-eval-expanded string "" "" nil nil t))
-(defun ess-mouse-me-summary (string)
-  (ess-mouse-me-eval-expanded string "summary(" ")" nil nil t))
-(defun ess-mouse-me-plot (string)
-  (ess-mouse-me-eval-expanded string "plot(" ")") nil nil nil)
-(defun ess-mouse-me-show (string)
-  (ess-mouse-me-eval-expanded string "show(" ")") nil nil nil)
-(defun ess-mouse-me-args (string)
-  (ess-mouse-me-eval-expanded string "args(" ")" nil nil t))
-
-(defun ess-mouse-me-browser-on (string)
-  (if (equal (substring ess-dialect 0 1) "R")
-      (ess-eval-linewise (concat "debug(" string ")"))
-    (ess-mouse-me-eval-expanded string "trace(" ", exit=browser)") nil nil nil))
-
-(defun ess-mouse-me-browser-off  (string)
-  (if (equal (substring ess-dialect 0 1) "R")
-      (ess-eval-linewise (concat "undebug(" string ")"))
-    (ess-mouse-me-eval-expanded string "untrace(" ")") nil nil nil))
-
-
-
-(defun ess-mouse-me-eval-expanded (string &optional head tail commands-buffer
-                                          _page value-returned)
-  "Send the expanded STRING to the inferior-ess process using `ess-command'
-after first concating the HEAD and TAIL.  Put answer in COMMANDS-BUFFER if
-specified, otherwise in \"tmp-buffer\".  In either
-case the buffer containing the answer is renamed to the value of the
-constructed command.  If PAGE is non-nil, expand
-the string one more time by embedding it in a \"page()\" command."
-  (interactive)
-  (let* (scommand
-         ;; page-scommand
-         (lproc-name ess-local-process-name)
-         (ess-mouse-customize-alist ess-local-customize-alist))
-    (if (not head) (setq head "summary("))
-    (if (not tail) (setq tail ")"))
-    (if (not commands-buffer) (setq commands-buffer
-                                    (get-buffer-create "tmp-buffer")))
-    (setq scommand (concat head string tail))
-
-    (ess-make-buffer-current)
-    (pop-to-buffer-same-window commands-buffer)
-    (ess-setq-vars-local (eval ess-mouse-customize-alist t) (current-buffer))
-    (setq ess-local-process-name lproc-name)
-    (ess-command (concat scommand "\n") commands-buffer)
-    (if (not value-returned) (pop-to-buffer-same-window (nth 1 (buffer-list))))
-    (if (not value-returned)
-        nil
-      (if ess-microsoft-p                      ;; there ought to be a filter
-          (while (search-forward "\r" nil t)   ;; function to keep the ^M
-            (replace-match "" nil t)))         ;; from showing up at all
-      (ess-transcript-mode)
-      (setq ess-local-process-name lproc-name)
-      (rename-buffer scommand))))
-
-
-\f ; Provide package
-
-(provide 'ess-mouse)
-
-
-
-;;;;;;;; STARTUP STUFF ;;;;;;;;;;;;
-
-(make-variable-buffer-local 'mouse-me-menu-commands)
-
-(defun ess-S-mouse-me-menu-commands ()
-  (if (equal ess-language "S")
-      (setq mouse-me-menu-commands ess-S-mouse-me-menu-commands-alist)))
-
-;;       (define-key ess-mode-map              [S-mouse-3] 'ess-mouse-me)
-;;       (define-key inferior-ess-mode-map     [S-mouse-3] 'ess-mouse-me)
-;;       (defun ess-S-mouse-me-ess-transcript-mode ()
-;;         (define-key ess-transcript-mode-map [S-mouse-3] 'ess-mouse-me))
-;;
-(add-hook 'ess-mode-hook            #'ess-S-mouse-me-menu-commands)
-(add-hook 'inferior-ess-mode-hook   #'ess-S-mouse-me-menu-commands)
-(add-hook 'ess-transcript-mode-hook #'ess-S-mouse-me-menu-commands)
-;; (add-hook 'ess-transcript-mode-hook 'ess-S-mouse-me-ess-transcript-mode)
-
-
-;;; ess-mouse.el ends here
diff --git a/elpa/ess-20251212.937/obsolete/ess-r-a.el b/elpa/ess-20251212.937/obsolete/ess-r-a.el
deleted file mode 100644 (file)
index 7872fba..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-;;; ess-r-a.el -- Possible local customizations for R with ESS.  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1997-2022 Free Software Foundation, Inc.
-;; Author: A.J. Rossini <blindglobeNOSPAMgmail.com>
-;; Created: 17 November 1999
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; The purpose of this file is to demonstrate some of the extras that
-;; have been constructed for the ESS R mode; if they prove
-;; interesting, then they might be migrated to ess-r-mode, the primary
-;; ESS R mode tools.
-
-;;; Code:
-(require 'ess-inf)
-(require 'ess-r-mode)
-
-;; you can invoke ESS/R from emacs by typing
-;;      C-u M-x essr
-;; with vsize set to (for example) 40M, and nsize set to 600000.
-
-;; Undefined on non-apple devices
-(declare-function ns-do-applescript "nsfns.m" (script))
-(declare-function do-applescript "ess-r-a" (script))
-(unless (fboundp 'do-applescript)
-  (defalias 'do-applescript #'ns-do-applescript))
-
-(defalias 'essr
-  (read-kbd-macro
-   "C-u M-x R RET - - vsize = 40M SPC - - nsize = 600000 2*RET"))
-
-(defun ess-r-do-region (start end)
-  "Send from START to END to R via AppleScript."
-  (interactive "r\nP")
-  (message "Starting evaluation...")
-  (do-applescript (concat
-                   "try\n"
-                   "tell application \"R\"\n"
-                   "activate\n"
-                   "with timeout of 0 seconds\n"
-                   "cmd \"" (buffer-substring start end)
-                   "\"\n"
-                   "end timeout\n"
-                   "end tell\n"
-                   "end try\n"))
-  (message "Finished evaluation"))
-
-(defun ess-r-do-line ()
-  "Send the current line to R via AppleScript."
-  (interactive) ;; "r\nP")
-  (message "Starting evaluation...")
-  (save-excursion
-    (let ((end (point)))
-      (move-to-column 0)
-      (do-applescript (concat
-                       "try\n"
-                       "tell application \"R\"\n"
-                       "activate\n"
-                       "with timeout of 0 seconds\n"
-                       "cmd \"" (buffer-substring (point) end)
-                       "\"\n"
-                       "end timeout\n"
-                       "end tell\n"
-                       "end try\n"))))
-  (message "Finished evaluation"))
-
-(defun ess-r-var (beg end)
-  "Load the current region of numbers into an R variable.
-Prompts for a variable name. If none is given, it uses a default
-variable name, e. BEG and END denote the region in the current
-buffer to be sent."
-  (interactive "r")
-  (save-window-excursion
-    (let ((tmp-file (make-temp-file "ess-r-var"))
-          cmd
-          var)
-      (write-region beg end tmp-file)
-
-      ;; Decide on the variable name to use in R; could use completion.
-      (setq var (read-string "R Variable name (default e): "))
-      (if (equal var "")
-          (setq var "e"))
-
-      ;; Command to send to the R process.  Get R to delete the file
-      ;; rather than Emacs in case it takes R a long time to run the
-      ;; scan command.
-      (setq cmd (concat var " <- scan(\""  tmp-file "\"); "
-                        "unlink(\"" tmp-file "\")" ))
-
-      ;; Put the output from the scan command into the process buffer so
-      ;; the user has a record of it.
-      (ess-execute cmd 'buffer))))
-
-
-;;; Peter Dalgaard's code.
-;;; This needs to be cleaned and validated!
-
-(defun pd::set-up-demo ()
-  (run-ess-r)
-  (split-window-vertically 6)
-  (find-file "demos.R")
-
-  ;; Don't need to run this as a function -- ought to be fine if set
-  ;; just once.
-
-  (defun ajr::scroll-to-end::peterD (emacs)
-    "Goal: map prompt to bottom of the screen after every command.
-Alternatively, use the scroll-in-place package, not sure where that
-is)."
-    (interactive)
-    (other-buffer 1)
-    (if (= emacs "emacs")
-        (setq scroll-up-aggressively t)
-      (setq scroll-conservatively -4)) ;; <- change this
-    (other-buffer -1))
-
-  (defun show-max-other-window ()
-    (interactive)
-    (other-window 1)
-    (comint-show-maximum-output)
-    (other-window -1))
-
-  ;; call this once
-  ;; (ajr::scroll-to-end::peterD "emacs")
-
-  (global-set-key [f11] #'show-max-other-window)
-  (global-set-key [f12] #'ess-eval-line-visibly-and-step))
-
-
-\f ; Provide package
-
-(provide 'ess-r-a)
-
-;;; ess-r-a.el ends here
diff --git a/elpa/ess-20251212.937/obsolete/mouseme.el b/elpa/ess-20251212.937/obsolete/mouseme.el
deleted file mode 100644 (file)
index 82e7c61..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-;;; mouseme.el --- mouse menu with commands that operate on strings  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1997-2022 by Free Software Foundation, Inc.
-
-;; Author: Howard Melman <howardNOSPAMsilverstream.com>
-;; Keywords: mouse, menu
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; This package provides a command `mouse-me' to be bound to a mouse
-;; button.  It pops up a menu of commands that operate on strings or a
-;; region.  The string passed to the selected command is the word or
-;; symbol clicked on (with surrounding quotes or other punctuation
-;; removed), or the region (if either it was just selected with the
-;; mouse or if it was active with `transient-mark-mode' on).  If the
-;; command accepts a region, the selected region (or the region of the
-;; word or symbol clicked on) will be passed to the command.
-
-;; The idea is that for any given string in a buffer you may want to
-;; do different things regardless of the mode of the buffer.  URLs
-;; now appear in email, news articles, comments in code, and in plain
-;; text.  You may want to visit that URL in a browser or you may just
-;; want to copy it to the kill-ring.  For an email address you might
-;; want to compose mail to it, finger it, look it up in bbdb, copy it to
-;; the kill ring.  For a word you may want to spell check it, copy it,
-;; change its case, grep for it, etc.  Mouse-me provides a menu to
-;; make this easy.
-
-;; The menu popped up is generated by calling the function in the
-;; variable `mouse-me-build-menu-function' which defaults to calling
-;; `mouse-me-build-menu' which builds the menu from the variable
-;; `mouse-me-menu-commands'.  See the documentation for these
-;; functions and variables for details.
-
-;; To install, add something like the following to your ~/.emacs:
-;;   (require 'mouseme)
-;;   (global-set-key [S-mouse-2] 'mouse-me)
-
-;;; Code:
-
-(require 'browse-url)
-(require 'thingatpt)
-
-(eval-when-compile (require 'compile))
-
-;;;; Variables
-
-(defgroup mouseme nil
-  "Popup menu of commands that work on strings."
-  :prefix "mouse-me-"
-  :group 'hypermedia)
-
-(defcustom mouse-me-get-string-function 'mouse-me-get-string
-  "Function used by `mouse-me' to get string when no region selected.
-The default is `mouse-me-get-string' but this variable may commonly
-be made buffer local and set to something more appropriate for
-a specific mode (e.g., `word-at-point').  The function will be called
-with no arguments and with point at where the mouse was clicked.
-It can return either the string or to be most efficient, a list of
-three elements: the string and the beginning and ending points of the
-string in the buffer."
-  :type 'function
-  :options '(mouse-me-get-string))
-
-(defcustom mouse-me-build-menu-function 'mouse-me-build-menu
-  "Function used by `mouse-me' to build the popup menu.
-The default is `mouse-me-build-menu' but this variable may commonly
-be made buffer local and set to something more appropriate for
-a specific mode.  The function will be called with one argument,
-the string selected, as returned by `mouse-me-get-string-function'."
-  :type 'function
-  :options '(mouse-me-build-menu))
-
-(defvar mouse-me-grep-use-extension 't
-  "If non-nil `mouse-me-grep' grep's in files with current file's extension.")
-
-(defcustom mouse-me-menu-commands
-  '(("Copy" . kill-new)
-    ("Kill" . kill-region)
-    ("Capitalize" . capitalize-region)
-    ("Lowercase" . downcase-region)
-    ("Uppercase" . upcase-region)
-    ("ISpell" . ispell-region)
-    "----"
-    ("Browse URL" . browse-url)
-    ("Dired" . dired)
-    ("Execute File" . mouse-me-execute)
-    ("Mail to" . compose-mail)
-    ("Finger" . mouse-me-finger)
-    ("BBDB Lookup" . mouse-me-bbdb)
-    "----"
-    ("Imenu" . imenu)
-    ("Find Tag" . find-tag)
-    ("Grep" . mouse-me-grep)
-    ("Find-Grep" . mouse-me-find-grep)
-    "----"
-    ("Apropos" . apropos)
-    ("Describe Function" . mouse-me-describe-function)
-    ("Describe Variable" . mouse-me-describe-variable)
-    ("Command Info" . mouse-me-emacs-command-info)
-    ("Man Page" . (if (fboundp 'woman) 'woman 'man))
-    ("Profile Function" . mouse-me-elp-instrument-function))
-  "Command menu used by `mouse-me-build-menu'.
-A list of elements where each element is either a cons cell or a string.
-If a cons cell the car is a string to be displayed in the menu and the
-cdr is either a function to call passing a string to, or a list which evals
-to a function to call passing a string to.  If the element is a string
-it makes a non-selectable element in the menu.  To make a separator line
-use a string consisting solely of hyphens.
-
-The function returned from this menu will be called with one string
-argument.  Or if the function has the symbol property `mouse-me-type'
-and if its value is the symbol `region' it will be called with the
-beginning and ending points of the selected string.  If the value is
-the symbol `string' it will be called with one string argument."
-  :type '(repeat sexp))
-
-(put 'kill-region 'mouse-me-type 'region)
-(put 'ispell-region 'mouse-me-type 'region)
-(put 'capitalize-region 'mouse-me-type 'region)
-(put 'downcase-region 'mouse-me-type 'region)
-(put 'upcase-region 'mouse-me-type 'region)
-
-;;;; Commands
-
-;;;###autoload
-(defun mouse-me (event)
-  "Popup a menu of functions to run on selected string or region."
-  (interactive "e")
-  (mouse-me-helper event (lambda (name)
-                           (or (x-popup-menu event (funcall mouse-me-build-menu-function name))
-                               (error "No command to run")))))
-
-;;;; Exposed Functions
-
-;; Some tests:
-;; <URL:http://foo.bar.com/sss/ss.html>
-;; <http://foo.bar.com/sss/ss.html>
-;; http://foo.bar.com/sss/ss.html
-;; http://www.ditherdog.com/howard/
-;; mailto:howardNOSPAMsilverstream.com
-;; howardNOSPAMsilverstream.com
-;; <howardNOSPAMsilverstream.com>
-;; import com.sssw.srv.agents.AgentsRsrc;
-;; public AgoHttpRequestEvent(Object o, String db, Request r)
-;; <DIV><A href=3D"http://www.amazon.com/exec/obidos/ASIN/156592391X"><IMG =
-;; <A HREF="http://www.suntimes.com/ebert/ebert.html">
-;; d:\howard\elisp\spoon
-;; \howard\elisp\spoon
-;; \\absolut\howard\elisp\spoon
-;; //absolut/d/Howard/Specs/servlet-2.1.pdf
-;; \\absolut\d\Howard\Specs\servlet-2.1.pdf
-;; gnuserv-frame.
-
-(defun mouse-me-get-string ()
-  "Return a string from the buffer of text surrounding point.
-Returns a list of three elements, the string and the beginning and
-ending positions of the string in the buffer in that order."
-  (save-match-data
-    (save-excursion
-      (let ((start (point)) beg end str)
-        (skip-syntax-forward "^ >()\"")
-        (setq end (point))
-        (goto-char start)
-        (skip-syntax-backward "^ >()\"")
-        (setq beg (point))
-        (setq str (buffer-substring-no-properties beg end))
-        ;; remove junk from the beginning
-        (if (string-match "^\\([][\"'`.,?:;!@#$%^&*()_+={}|<>-]+\\)" str)
-            (setq str (substring str (match-end 1))
-                  beg (+ beg (match-end 1))))
-        ;; remove URL: from the front, it's common in email
-        (if (string-match "^\\(URL:\\)" str)
-            (setq str (substring str (match-end 1))
-                  beg (+ beg (match-end 1))))
-        ;; remove junk from the end
-        (if (string-match "\\([][\"'.,?:;!@#$%^&*()_+={}|<>-]+\\)$" str)
-            (setq end (- end (length (match-string 1 str))) ; must set end first
-                  str (substring str 0 (match-beginning 1))))
-        (list str beg end)))))
-
-(defun mouse-me-build-menu (name)
-  "Return a menu tailored for NAME for `mouse-me' from `mouse-me-menu-commands'."
-  (list "Mouse Me" (cons "Mouse Me"
-                         (append (list (cons
-                                        (if (< (length name) 65)
-                                            name
-                                          "...Long String...")
-                                        'kill-new)
-                                       "---")
-                                 mouse-me-menu-commands))))
-
-;;;; Commands for the menu
-
-(defun mouse-me-emacs-command-info (string)
-  "Look in Emacs info for command named STRING."
-  (interactive "sCommand: ")
-  (let ((s (intern-soft string)))
-    (if (and s (commandp s))
-        (Info-goto-emacs-command-node s)
-      (error "No command named `%s'" string))))
-
-(defun mouse-me-describe-function (string)
-  "Describe function named STRING."
-  (interactive "sFunction: ")
-  (let ((s (intern-soft string)))
-    (if (and s (fboundp s))
-        (describe-function s)
-      (error "No function named `%s'" string))))
-
-(defun mouse-me-describe-variable (string)
-  "Desribe variable named STRING."
-  (interactive "sVariable: ")
-  (let ((s (intern-soft string)))
-    (if (and s (boundp s))
-        (describe-variable s)
-      (error "No variable named `%s'" string))))
-
-(defun mouse-me-elp-instrument-function (string)
-  "Instrument Lisp function named STRING."
-  (interactive "sFunction: ")
-  (let ((s (intern-soft string)))
-    (if (and s (fboundp s))
-        (elp-instrument-function s)
-      (error "Must be the name of an existing Lisp function"))))
-
-(defun mouse-me-execute (string)
-  "Execute STRING as a filename."
-  (interactive "sFile: ")
-  (if (fboundp 'w32-shell-execute)
-      (w32-shell-execute "open" (convert-standard-filename string))
-    (message "This function currently working only in W32.")))
-
-
-(defun mouse-me-bbdb (string)
-  "Lookup STRING in bbdb."
-  (interactive "sBBDB Lookup: ")
-  (if (fboundp 'bbdb)
-      (bbdb string nil)
-    (error "BBDB not loaded")))
-
-(defun mouse-me-finger (string)
-  "Finger a STRING mail address."
-  (interactive "sFinger: ")
-  (save-match-data
-    (if (string-match "\\(.*\\)@\\([-.a-zA-Z0-9]+\\)$" string)
-        (finger (match-string 1 string) (match-string 2 string))
-      (error "Not in user@host form: %s" string))))
-
-(defun mouse-me-grep (string)
-  "Grep for a STRING."
-  (interactive "sGrep: ")
-  (require 'compile)
-  (grep-compute-defaults)
-  (let ((ext (mouse-me-buffer-file-extension)))
-    (grep (concat grep-command string
-                  (if mouse-me-grep-use-extension
-                      (if ext
-                          (concat " *" ext)
-                        " *"))))))
-
-(defun mouse-me-find-grep (string)
-  "Grep for a STRING."
-  (interactive "sGrep: ")
-  (grep-compute-defaults)
-  (let ((reg grep-find-command)
-        (ext (mouse-me-buffer-file-extension)))
-    (if (string-match "\\(^.+-type f \\)\\(.+$\\)" reg)
-        (setq reg (concat (match-string 1 reg)
-                          (if mouse-me-grep-use-extension
-                              (concat "-name \"*" ext "\" "))
-                          (match-string 2 reg))))
-    (grep-find (concat reg string))))
-
-;;;; Internal Functions
-
-(defun mouse-me-buffer-file-extension ()
-  "Return the extension of the current buffer's filename or nil.
-Returned extension is a string beginning with a period."
-  (let* ((bfn (buffer-file-name))
-         (filename (and bfn (file-name-sans-versions bfn)))
-         (index (and filename (string-match "\\.[^.]*$" filename))))
-    (if index
-        (substring filename index)
-      "")))
-
-(defun mouse-me-helper (event func)
-  "Determine the string to use to process EVENT and call FUNC to get cmd."
-  (let (name sp sm mouse beg end cmd mmtype)
-    ;; temporarily goto where the event occurred, get the name clicked
-    ;; on and enough info to figure out what to do with it
-    (save-match-data
-      (save-excursion
-        (setq sp (point))               ; saved point
-        (setq sm (mark t))              ; saved mark
-        (set-buffer (window-buffer (posn-window (event-start event))))
-        (setq mouse (goto-char (posn-point (event-start event))))
-        ;; if there is a region and point is inside it
-        ;; check for sm first incase (null (mark t))
-        ;; set name to either the thing they clicked on or region
-        (if (and sm
-                 (or (and transient-mark-mode mark-active)
-                     (eq last-command 'mouse-drag-region))
-                 (>= mouse (setq beg (min sp sm)))
-                 (<= mouse (setq end (max sp sm))))
-            (setq name (buffer-substring beg end))
-          (setq name (funcall mouse-me-get-string-function))
-          (if (listp name)
-              (setq beg (nth 1 name)
-                    end (nth 2 name)
-                    name (car name))
-            (goto-char mouse)
-            (while (not (looking-at (regexp-quote name)))
-              (backward-char 1))
-            (setq beg (point))
-            (setq end (search-forward name))))))
-    ;; check if name is null, meaning they clicked on no word
-    (if (or (null name)
-            (and (stringp name) (string= name "" )))
-        (error "No string to pass to function"))
-    ;; popup a menu to get a command to run
-    (setq cmd (funcall func))
-    ;; run the command, eval'ing if it was a list
-    (if (listp cmd)
-        (setq cmd (eval cmd t)))
-    (setq mmtype (get cmd 'mouse-me-type))
-    (cond ((eq mmtype 'region)
-           (funcall cmd beg end))
-          ((eq mmtype 'string)
-           (funcall cmd name))
-          (t
-           (funcall cmd name)))))
-
-(provide 'mouseme)
-
-;;; mouseme.el ends here
diff --git a/elpa/ess-20251212.937/obsolete/msdos.el b/elpa/ess-20251212.937/obsolete/msdos.el
deleted file mode 100644 (file)
index f3e1d9a..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-;;; msdos.el --- Run an MS-DOS shell in an NTemacs buffer with bash as the shell  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1999-2022 Free Software Foundation, Inc.
-;; Author: Richard M. Heiberger <rmhNOSPAMtemple.edu>
-;; Created: February 1999
-;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
-
-;; This file is part of GNU Emacs.
-
-;;; License:
-;;
-;; This program 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 3 of the License, or
-;; (at your option) any later version.
-;;
-;; This program 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see
-;; <http://www.gnu.org/licenses/>
-
-;;; Commentary:
-
-;; The file msdos.el in the next mail message opens an *msdos* buffer
-;; in shell-mode and msdos-minor-mode.  When cmdproxy.exe/command.com
-;; is the Emacs shell, then this gets various setting right that M-x
-;; shell currently misses.  The function M-x msdos-minor-mode could be
-;; automatically run by Emacs in shell-mode in that case.
-
-;; When bash is the Emacs shell, msdos.el still opens a
-;; cmdproxy.exe/command.com shell in the buffer *msdos*.  There are
-;; occasions when it is necessary to run DOS character-based programs
-;; in an Emacs window.
-
-;; I followed the suggestion by AndrewI to look at M-x shell and modify
-;; it.  It turns out not to have been trivial.
-
-;;; Code:
-
-(require 'shell); and hence 'comint
-
-;;; Customization and Buffer Variables
-
-(defcustom explicit-msdos-shell-file-name "cmdproxy.exe"
-  "*If non-nil, is file name to use for explicitly requested msdos
-inferior shell."
-  :type '(choice (const :tag "None" nil) file)
-  :group 'shell)
-
-(defcustom explicit-msdos-comspec-file-name
-  (if (w32-using-nt)
-      "cmd.exe"
-    "command.com")
-  "*If non-nil, is file name to use for explicitly requested COMSPEC
-environment variable."
-  :type '(choice (const :tag "None" nil) file)
-  :group 'shell)
-
-(defvar-local msdos-minor-mode nil
-  "Non-nil if using msdos-minor mode as a minor mode of some other mode.")
-
-(defun msdos ()
-  "Run an inferior msdos shell, with I/O through buffer *msdos*.
-This function is intended to be used in an Ntemacs session in which
-bash is the primary shell.  But sometimes an MSDOS window, within emacs,
-is also needed.
-
-If buffer exists but shell process is not running, make new shell.
-If buffer exists and shell process is running, just switch to buffer `*msdos*'.
-Program used comes from variable `explicit-msdos-shell-file-name'.
-If a file `~/.emacs_SHELLNAME' exists, it is given as initial input
- (Note that this may lose due to a timing error if the shell
-  discards input when it starts up.)
-The buffer is put in Shell mode, giving commands for sending input
-and controlling the subjobs of the shell.  See `shell-mode'.
-See also the variable `shell-prompt-pattern'.
-
-The buffer is put into \\[msdos-minor-mode].  See `msdos-minor-mode'.
-
-The COMSPEC environment variable in the inferior shell, but not in the emacs
-process, is set to `explicit-msdos-comspec-file-name'.
-The SHELL environment variable in the inferior shell, but not in the emacs
-process, is set to `explicit-msdos-shell-file-name'.
-
-The shell file name (sans directories) is used to make a symbol name
-such as `explicit-csh-args'.  If that symbol is a variable,
-its value is used as a list of arguments when invoking the shell.
-
-\(Type \\[describe-mode] in the shell buffer for a list of commands.)"
-  (interactive)
-  (if (not (comint-check-proc "*msdos*"))
-      (let* ((prog explicit-msdos-shell-file-name)
-             (name (file-name-nondirectory prog))
-             (startfile (concat "~/.emacs_" name))
-             (xargs-name (intern-soft (concat "explicit-" name "-args")))
-             shell-buffer
-             (comspec (getenv "COMSPEC"))
-             (shell (getenv "SHELL"))
-             )
-        (save-excursion
-          (setenv "COMSPEC" explicit-msdos-comspec-file-name)
-          (setenv "SHELL" explicit-msdos-shell-file-name)
-          (set-buffer (apply #'make-comint "msdos" prog
-                             (if (and xargs-name (boundp xargs-name))
-                                 (symbol-value xargs-name))
-                             (if (file-exists-p startfile)
-                                 (concat "/k " startfile))))
-          (setenv "COMSPEC" comspec)
-          (setenv "SHELL" shell)
-          (setq shell-buffer (current-buffer))
-          (shell-mode)
-          (msdos-minor-mode)
-          (sleep-for 4) ; need to wait, else working too fast!
-                      ;;; The `exit' warning should precede the "c:\" prompt.
-                      ;;; If not, then increase the sleep-for time!
-          (goto-char (point-min))
-          (insert
-           "Remember to exit this buffer with `exit'.  If you kill the
-buffer without exiting, you may not be able to shut down Windows cleanly.")
-          (goto-char (point-max)))
-        (pop-to-buffer shell-buffer))
-    (pop-to-buffer "*msdos*")))
-
-
-(defun msdos-minor-mode ()
-  "Minor mode for running msdos in a shell-mode buffer:
-a. Uses \\[set-buffer-process-coding-system] to set the coding system
-to `'raw-text-dos'.  The DOS C-m C-l end-of-line is critical.  The
-shell freezes without it.
-
-b. The variable `comint-completion-addsuffix' is set to `\\' for directories.
-
-c. Prevents echoing of commands.
-
-d. strips ctrl-m from output.
-"
-  (interactive)
-  (setq msdos-minor-mode t)
-  (set (make-local-variable 'comint-completion-addsuffix) '("\\" . " "))
-  (setq comint-process-echoes t)
-  (add-hook 'comint-output-filter-functions #'shell-strip-ctrl-m nil t)
-  (set-process-coding-system (get-buffer-process (current-buffer)) 'raw-text-dos 'raw-text-dos)
-  ;; buffer-process-coding-system is critical.
-  )
-
-;; Install ourselves:
-
-
-(put 'msdos-minor-mode 'permanent-local t)
-(or (assq 'msdos-minor-mode minor-mode-alist)
-    (setq minor-mode-alist
-          (append minor-mode-alist
-                  (list '(msdos-minor-mode " msdos")))))
-
-;; Provide ourselves:
-
-(provide 'msdos)
-
-;;; msdos.el ends here
diff --git a/elpa/ess-20260424.1544/README-elpa b/elpa/ess-20260424.1544/README-elpa
new file mode 100644 (file)
index 0000000..cfd2c3b
--- /dev/null
@@ -0,0 +1,5 @@
+
+Emacs Speaks Statistics (ESS) is a package designed to support editing of
+scripts and interaction with various statistical analysis programs such as R,
+S-Plus, SAS, Stata and OpenBUGS/JAGS. For more details please visit ESS home
+page at https://ess.r-project.org/
diff --git a/elpa/ess-20260424.1544/dir b/elpa/ess-20260424.1544/dir
new file mode 100644 (file)
index 0000000..7765d89
--- /dev/null
@@ -0,0 +1,19 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+\1f
+File: dir,     Node: Top       This is the top of the INFO tree
+
+  This (the Directory node) gives a menu of major topics.
+  Typing "q" exits, "H" lists all Info commands, "d" returns here,
+  "h" gives a primer for first-timers,
+  "mEmacs<Return>" visits the Emacs manual, etc.
+
+  In Emacs, you can click mouse button 2 on a menu item or cross reference
+  to select it.
+
+* Menu:
+
+Emacs
+* ESS: (ess).                   Emacs Speaks Statistics (R/S/S+, SAS, 
+                                  BUGS/NIMBLE and Stata).
diff --git a/elpa/ess-20260424.1544/ess-autoloads.el b/elpa/ess-20260424.1544/ess-autoloads.el
new file mode 100644 (file)
index 0000000..a66066b
--- /dev/null
@@ -0,0 +1,449 @@
+;;; ess-autoloads.el --- automatically extracted autoloads (do not edit)   -*- lexical-binding: t -*-
+;; Generated by the `loaddefs-generate' function.
+
+;; This file is part of GNU Emacs.
+
+;;; Code:
+
+(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
+
+
+\f
+;;; Generated autoloads from ess.el
+
+(autoload 'ess-version "ess"
+"Return a string with ESS version information." t)
+(autoload 'ess-submit-bug-report "ess"
+"Submit a bug report to the ESS maintainers." t)
+(register-definition-prefixes "ess" '("ess"))
+
+\f
+;;; Generated autoloads from ess-bugs-d.el
+
+(autoload 'ess-bugs-mode "ess-bugs-d"
+"Major mode for BUGS.
+
+In addition to any hooks its parent mode `ess-mode' might have run,
+this mode runs the hook `ess-bugs-mode-hook', as the final or
+penultimate step during initialization.
+
+\\{ess-bugs-mode-map}" t)
+(add-to-list 'auto-mode-alist '("\\.[Bb][Uu][Gg]\\'" . ess-bugs-mode))
+(add-to-list 'auto-mode-alist '("\\.[Bb][Oo][Gg]\\'" . ess-bugs-mode))
+(add-to-list 'auto-mode-alist '("\\.[Bb][Mm][Dd]\\'" . ess-bugs-mode))
+(register-definition-prefixes "ess-bugs-d" '("ess-"))
+
+\f
+;;; Generated autoloads from ess-bugs-l.el
+
+(register-definition-prefixes "ess-bugs-l" '("ess-bugs-"))
+
+\f
+;;; Generated autoloads from ess-custom.el
+
+(defvar ess-lisp-directory (file-name-directory (or load-file-name buffer-file-name))
+"Directory containing ess-site.el(c) and other ESS Lisp files.")
+(custom-autoload 'ess-lisp-directory "ess-custom" t)
+(add-to-list 'load-path (directory-file-name ess-lisp-directory))
+(add-to-list 'load-path (directory-file-name (expand-file-name "obsolete" ess-lisp-directory)))
+(put 'ess-indent-offset 'safe-local-variable #'numberp)
+(put 'ess-style 'safe-local-variable #'symbolp)
+(register-definition-prefixes "ess-custom" '("R-" "S+" "S-" "comint-highlight-prompt" "ess-" "inferior-"))
+
+\f
+;;; Generated autoloads from ess-gretl.el
+
+(autoload 'ess-gretl-mode "ess-gretl"
+"Major mode for editing gretl source.  See `ess-mode' for more help.
+
+In addition to any hooks its parent mode might have run, this mode
+runs the hook `ess-gretl-mode-hook', as the final or penultimate step
+during initialization.
+
+\\{ess-gretl-mode-map}" t)
+(autoload 'gretl "ess-gretl"
+"Call `gretl',
+Optional prefix (C-u) allows to set command line arguments, such as
+--vsize.  This should be OS agnostic.
+If you have certain command line arguments that should always be passed
+to gretl, put them in the variable `inferior-gretl-args'.
+
+(fn &optional START-ARGS)" t)
+(register-definition-prefixes "ess-gretl" '("ess-gretl-" "gretl-" "inferior-gretl-args"))
+
+\f
+;;; Generated autoloads from ess-help.el
+
+(register-definition-prefixes "ess-help" '("ess-"))
+
+\f
+;;; Generated autoloads from ess-inf.el
+
+(autoload 'ess-load-file "ess-inf"
+"Load FILENAME into an inferior ESS process.
+This handles Tramp when working on a remote.
+
+(fn &optional FILENAME)" t)
+(register-definition-prefixes "ess-inf" '("ess-" "inferior-ess" "update-ess-process-name-list"))
+
+\f
+;;; Generated autoloads from ess-julia.el
+
+(autoload 'ess-julia-mode "ess-julia"
+"Major mode for julia files.
+
+In addition to any hooks its parent mode `julia-mode' might have run,
+this mode runs the hook `ess-julia-mode-hook', as the final or
+penultimate step during initialization.
+
+\\{ess-julia-mode-map}" t)
+(autoload 'run-ess-julia "ess-julia"
+"Start an inferior julia process.
+Optional prefix START-ARGS (\\[universal-argument]) allows to set
+command line arguments, such as --load=<file>. This should be OS
+agnostic. If you have certain command line arguments that should
+always be passed to julia, put them in the variable
+`inferior-julia-args'.
+
+(fn &optional START-ARGS)" t)
+(defalias 'julia #'run-ess-julia)
+(register-definition-prefixes "ess-julia" '("ac-source-ess-julia-objects" "company-ess-julia-objects" "ess-" "inferior-"))
+
+\f
+;;; Generated autoloads from ess-mode.el
+
+(autoload 'ess-mode "ess-mode"
+"Major mode for editing ESS source.
+Optional arg ALIST describes how to customize the editing mode.
+Optional arg PROC-NAME is name of associated inferior process.
+
+\\{ess-mode-map}
+
+You can send text to the inferior ESS process from other buffers containing
+ESS source.
+    `ess-eval-region' sends the current region to the ESS process.
+    `ess-eval-buffer' sends the current buffer to the ESS process.
+    `ess-eval-function' sends the current function to the ESS process.
+    `ess-eval-line' sends the current line to the ESS process.
+    `ess-switch-to-ESS' switches the current buffer to the ESS process buffer.
+    `ess-switch-to-end-of-ESS' switches the current buffer to the ESS process
+        buffer and puts point at the end of it.
+
+    `ess-eval-region-and-go', `ess-eval-buffer-and-go',
+        `ess-eval-function-and-go', and `ess-eval-line-and-go' switch to the S
+        process buffer after sending their text.
+
+    `ess-load-file' sources a file of commands to the ESS process.
+
+\\[ess-indent-command] indents for ESS code.
+\\[backward-delete-char-untabify] converts tabs to spaces as it moves back.
+Comments are indented in a similar way to Emacs-lisp mode:
+       `###'     beginning of line
+       `##'      the same level of indentation as the code
+       `#'       the same column on the right, or to the right of such a
+                 column if that is not possible.(default value 40).
+                 \\[indent-for-comment] command automatically inserts such a
+                 `#' in the right place, or aligns such a comment if it is
+                 already inserted.
+\\[ess-indent-exp] command indents each line of the syntactic unit following point.
+
+Variables controlling indentation style:
+ `ess-indent-offset'
+    Indentation of ESS statements within surrounding block.
+    The surrounding block's indentation is the indentation of the line on
+    which the open-brace appears.
+ `ess-offset-block'
+    Indentation of blocks opened with curly braces or anonymous parentheses.
+ `ess-offset-arguments'
+    Indentation of function arguments or bracket indices.
+ `ess-offset-arguments-newline'
+    Indentation of function arguments or bracket indices when the opening
+    delimiter is immediately followed by a newline.
+ `ess-offset-continued'
+    Indentation style for continued statements.
+ `ess-align-nested-calls'
+    Functions whose nested calls should be aligned.
+ `ess-align-arguments-in-calls'
+    Calls in which arguments should be aligned.
+ `ess-align-continuations-in-calls'
+    Whether ignore indentation after an operator in calls
+ `ess-align-blocks'
+    Blocks that should always be aligned vertically.
+ `ess-indent-from-lhs'
+    Whether function calls given as argument should be indented from the
+    parameter name.
+ `ess-indent-from-chain-start'
+    Whether to indent arguments from the first of several consecutive calls.
+ `ess-indent-with-fancy-comments'
+    Non-nil means distinguish between #, ##, and ### for indentation.
+
+Furthermore, \\[ess-set-style] command enables you to set up predefined ess-mode
+indentation style. See `ess-style-alist' for predefined styles.
+
+In addition to any hooks its parent mode `prog-mode' might have run,
+this mode runs the hook `ess-mode-hook', as the final or penultimate
+step during initialization." t)
+(register-definition-prefixes "ess-mode" '("ess-"))
+
+\f
+;;; Generated autoloads from ess-r-completion.el
+
+(register-definition-prefixes "ess-r-completion" '("ac-source-R" "company-R-" "ess-"))
+
+\f
+;;; Generated autoloads from ess-r-flymake.el
+
+(register-definition-prefixes "ess-r-flymake" '("ess-r-"))
+
+\f
+;;; Generated autoloads from ess-r-mode.el
+
+(autoload 'run-ess-r "ess-r-mode"
+"Call \\='R\\=', the \\='GNU S\\=' system from the R Foundation.
+Optional prefix (\\[universal-argument]) allows to set command line arguments, such as
+--vsize.  This should be OS agnostic.
+If you have certain command line arguments that should always be passed
+to R, put them in the variable `inferior-R-args'.
+
+START-ARGS can be a string representing an argument, a list of
+such strings, or any other non-nil value.  In the latter case, you
+will be prompted to enter arguments interactively.
+
+(fn &optional START-ARGS)" t)
+(autoload 'R "ess-r-mode"
+"
+
+(fn &optional START-ARGS)" t)
+(autoload 'ess-r-mode "ess-r-mode"
+"Major mode for editing R source.  See `ess-mode' for more help.
+
+In addition to any hooks its parent mode might have run, this mode
+runs the hook `ess-r-mode-hook', as the final or penultimate step
+during initialization.
+
+\\{ess-r-mode-map}" t)
+(defalias 'R-mode #'ess-r-mode)
+(defalias 'r-mode #'ess-r-mode)
+(add-to-list 'auto-mode-alist '("/R/.*\\.q\\'" . ess-r-mode))
+(add-to-list 'auto-mode-alist '("\\.[rR]\\'" . ess-r-mode))
+(add-to-list 'auto-mode-alist '("\\.[rR]profile\\'" . ess-r-mode))
+(add-to-list 'auto-mode-alist '("NAMESPACE\\'" . ess-r-mode))
+(add-to-list 'auto-mode-alist '("CITATION\\'" . ess-r-mode))
+(autoload 'ess-r-transcript-mode "ess-r-mode"
+"A Major mode for R transcript files.
+
+In addition to any hooks its parent mode `ess-transcript-mode' might
+have run, this mode runs the hook `ess-r-transcript-mode-hook', as the
+final or penultimate step during initialization.
+
+\\{ess-r-transcript-mode-map}" t)
+(add-to-list 'auto-mode-alist '("\\.[Rr]out\\'" . ess-r-transcript-mode))
+(add-to-list 'interpreter-mode-alist '("Rscript" . ess-r-mode))
+(add-to-list 'interpreter-mode-alist '("r" . ess-r-mode))
+(add-to-list 'auto-mode-alist '("/Makevars\\(\\.win\\)?\\'" . makefile-mode))
+(add-to-list 'auto-mode-alist '("DESCRIPTION\\'" . conf-colon-mode))
+(register-definition-prefixes "ess-r-mode" '("R-" "ess-" "inferior-ess-r-" "r-transcript-mode" "run-ess-r-newest"))
+
+\f
+;;; Generated autoloads from ess-r-package.el
+
+(register-definition-prefixes "ess-r-package" '("ess-"))
+
+\f
+;;; Generated autoloads from ess-r-syntax.el
+
+(register-definition-prefixes "ess-r-syntax" '("ess-"))
+
+\f
+;;; Generated autoloads from ess-r-xref.el
+
+(register-definition-prefixes "ess-r-xref" '("ess-r-xref-"))
+
+\f
+;;; Generated autoloads from ess-rd.el
+
+(autoload 'Rd-mode "ess-rd"
+"Major mode for editing R documentation source files.
+
+Type \\[list-abbrevs] to display the built-in abbrevs for Rd
+keywords.To automatically turn on the abbrev(iate) features, add
+the following to your Emacs configuration file:
+
+  (add-hook \\='Rd-mode-hook #\\='abbrev-mode)" t)
+(add-to-list 'auto-mode-alist '("\\.Rd\\'" . Rd-mode))
+(register-definition-prefixes "ess-rd" '("Rd-"))
+
+\f
+;;; Generated autoloads from ess-rdired.el
+
+(autoload 'ess-rdired "ess-rdired"
+"Show R objects from the global environment in a separate buffer.
+You may interact with these objects, see `ess-rdired-mode' for
+details." t)
+(register-definition-prefixes "ess-rdired" '("ess-rdired-"))
+
+\f
+;;; Generated autoloads from ess-roxy.el
+
+(autoload 'ess-roxy-mode "ess-roxy"
+"Minor mode for editing ROxygen documentation.
+
+This is a minor mode.  If called interactively, toggle the `Ess-Roxy
+mode' mode.  If the prefix argument is positive, enable the mode, and if
+it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
+mode if ARG is nil, omitted, or is a positive number.  Disable the mode
+if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate the variable `ess-roxy-mode'.
+
+The mode's hook is called both when the mode is enabled and when it is
+disabled.
+
+(fn &optional ARG)" t)
+(register-definition-prefixes "ess-roxy" '("ess-"))
+
+\f
+;;; Generated autoloads from ess-s-lang.el
+
+(add-to-list 'auto-mode-alist '("\\.[Ss]t\\'" . S-transcript-mode))
+(add-to-list 'auto-mode-alist '("\\.Sout\\'" . S-transcript-mode))
+(register-definition-prefixes "ess-s-lang" '("S+common-cust-alist" "S-" "ess-" "inferior-S-language-start"))
+
+\f
+;;; Generated autoloads from ess-sas-a.el
+
+(register-definition-prefixes "ess-sas-a" '("ess-" "sas-program"))
+
+\f
+;;; Generated autoloads from ess-sas-d.el
+
+(autoload 'SAS-mode "ess-sas-d"
+"Major mode for editing SAS source.  See `ess-mode' for more help.
+
+In addition to any hooks its parent mode might have run, this mode
+runs the hook `SAS-mode-hook', as the final or penultimate step during
+initialization.
+
+\\{SAS-mode-map}" t)
+(add-to-list 'auto-mode-alist '("\\.[Ss][Aa][Ss]\\'" . SAS-mode))
+(register-definition-prefixes "ess-sas-d" '("SAS" "ess-" "inferior-SAS-args"))
+
+\f
+;;; Generated autoloads from ess-sas-l.el
+
+(register-definition-prefixes "ess-sas-l" '("SAS-" "backward-page-top-of-window" "beginning-of-sas-" "ess-" "fix-page-breaks" "forward-page-top-of-window" "indent-sas-statement" "next-sas-proc" "sas-" "set-sas-file-" "submit-sas" "switch-to-"))
+
+\f
+;;; Generated autoloads from ess-sp6-d.el
+
+(autoload 'S+-mode "ess-sp6-d"
+"Major mode for editing S+ source.  See `ess-mode' for more help.
+
+(fn &optional PROC-NAME)" t)
+(register-definition-prefixes "ess-sp6-d" '("S+" "ess-"))
+
+\f
+;;; Generated autoloads from ess-toolbar.el
+
+(register-definition-prefixes "ess-toolbar" '("ess-"))
+
+\f
+;;; Generated autoloads from ess-tracebug.el
+
+(register-definition-prefixes "ess-tracebug" '("ess-" "inferior-ess-" "org-"))
+
+\f
+;;; Generated autoloads from ess-trns.el
+
+(autoload 'ess-transcript-mode "ess-trns"
+"Major mode for transcript files.
+
+Type \\[ess-transcript-send-command] to send a command in the
+transcript to the current inferior process. \\[ess-transcript-copy-command]
+copies the command but does not execute it, allowing you to edit it in
+the process buffer first.
+
+Type \\[ess-transcript-clean-region] to delete all outputs and prompts
+in the region, leaving only the commands.
+
+In addition to any hooks its parent mode `ess-mode' might have run,
+this mode runs the hook `ess-transcript-mode-hook', as the final or
+penultimate step during initialization." t)
+(register-definition-prefixes "ess-trns" '("ess-transcript-"))
+
+\f
+;;; Generated autoloads from ess-utils.el
+
+(defvar ess-elisp-trace-mode nil
+"Non-nil if Ess-Elisp-Trace mode is enabled.
+See the `ess-elisp-trace-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `ess-elisp-trace-mode'.")
+(custom-autoload 'ess-elisp-trace-mode "ess-utils" nil)
+(autoload 'ess-elisp-trace-mode "ess-utils"
+"Toggle tracing of ess-prefixed functions.
+
+Tracing is useful for debugging background ESS behaviour. When
+enabled, all functions prefixed in `ess-' and `inferior-ess' are
+instrumented with `trace-function'. Tracing is turned off by
+calling `untrace-function' on these functions.
+
+This is a global minor mode.  If called interactively, toggle the
+`Ess-Elisp-Trace mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
+mode if ARG is nil, omitted, or is a positive number.  Disable the mode
+if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value \\='ess-elisp-trace-mode)'.
+
+The mode's hook is called both when the mode is enabled and when it is
+disabled.
+
+(fn &optional ARG)" t)
+(register-definition-prefixes "ess-utils" '("ess-" "with-ess-process-buffer"))
+
+\f
+;;; Generated autoloads from essd-els.el
+
+(autoload 'ess-remote "essd-els"
+"Execute this command from within a buffer running a process.
+It runs `ess-add-ess-process' to add the PROC-NAME to
+`ess-process-name-alist' and to make it the
+`ess-current-process-name'. It then prompts the user for an ESS
+language and sets the editing characteristics appropriately.
+
+To use this command, first start a process on a remote computer by
+manual use of telnet, rlogin, ssh, or some other protocol.  Start the
+relevant program (\"S\" or \"R\" or \"sas -stdio\") in that buffer.  Once
+you are talking to S or R or SAS, then do \\[ess-remote] to make
+the current buffer an inferior-ess buffer with the right behavior for
+the language you are currently working with.  With S and R, use C-c
+C-n to send lines over.  With SAS, use C-c i
+`ess-eval-line-and-step-invisibly' to send lines over invisibly.
+
+DIALECT is the desired ess-dialect. If nil, ask for dialect
+
+(fn &optional PROC-NAME DIALECT)" t)
+(register-definition-prefixes "essd-els" '("S+elsewhere" "ess-" "inferior-ess-remote-pager"))
+\f
+;;; End of scraped data
+
+(provide 'ess-autoloads)
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; no-native-compile: t
+;; coding: utf-8-emacs-unix
+;; End:
+
+;;; ess-autoloads.el ends here
diff --git a/elpa/ess-20260424.1544/ess-bugs-d.el b/elpa/ess-20260424.1544/ess-bugs-d.el
new file mode 100644 (file)
index 0000000..062e951
--- /dev/null
@@ -0,0 +1,309 @@
+;;; ess-bugs-d.el --- ESS[BUGS] dialect  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2008-2022 Free Software Foundation, Inc.
+
+;; Author: Rodney Sparapani
+;; Maintainer: ESS-help <ess-helpNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Code:
+
+(require 'ess-bugs-l)
+(require 'ess-utils)
+(require 'ess-inf)
+(require 'ess-mode)
+
+(defvar ess-bugs-command "OpenBUGS" "Default BUGS program in PATH.")
+(make-local-variable 'ess-bugs-command)
+
+(defvar ess-bugs-monitor '("") "Default list of variables to monitor.")
+(make-local-variable 'ess-bugs-monitor)
+
+(defvar ess-bugs-thin 1 "Default thinning parameter.")
+(make-local-variable 'ess-bugs-thin)
+
+(defvar ess-bugs-chains 1 "Default number of chains.")
+(make-local-variable 'ess-bugs-chains)
+
+(defvar ess-bugs-burnin 10000 "Default burn-in.")
+(make-local-variable 'ess-bugs-burnin)
+
+(defvar ess-bugs-update 10000 "Default number of updates after burnin.")
+(make-local-variable 'ess-bugs-update)
+
+(defvar ess-bugs-system nil "Default whether BUGS recognizes the system command.")
+
+(defvar ess-bugs-font-lock-keywords
+  (list
+   ;; .bug files
+   (cons "#.*\n"                        font-lock-comment-face)
+
+   (cons "^[ \t]*\\(model\\|var\\)\\>"
+         font-lock-keyword-face)
+
+   (cons (concat "\\<d\\(bern\\|beta\\|bin\\|binom\\|"
+                 "car_normal\\|car_proper\\|cat\\|chisq\\|chisqr\\|CRP\\|"
+                 "dexp\\|dirch\\|dirich\\|"
+                 "exp\\|flat\\|\\(gen[.]\\|inv\\)?gamma\\|halfflat\\|hyper\\|"
+                 "interval\\|lkj_corr_cholesky\\|laplace\\|lnorm\\|logis\\|"
+                 "mnorm\\|mt\\|multi\\|multinom\\|mvt\\|"
+                 "negbin\\|nbinom\\|norm\\(mix\\)?\\|par\\|pois\\|sum\\|t\\|"
+                 "unif\\|weib\\|weibull\\|\\(inv\\)?wish\\|wishart\\)[ \t\n]*(")
+         font-lock-constant-face)
+
+   (cons (concat "\\<\\(abs\\|acos\\|acosh\\|asin\\|asinh\\|atan\\|atanh\\|"
+                 "asCol\\|asRow\\|backsolve\\|besselK\\|ceiling\\|chol\\|"
+                 "cos\\|C\\|dim\\|\\(i\\)?cloglog\\|cube\\|"
+                 "eigen\\|equals\\|exp\\|expm\\|expAv\\|expit\\|"
+                 "floor\\|for\\|forwardsolve\\|"
+                 "inprod\\|interp[.]lin\\(e\\)?\\|inverse\\|"
+                 "lgamma\\|length\\|lfactorial\\|"
+                 "log\\|log1p\\|\\(i\\)?logit\\|logdet\\|logfact\\|loggam\\|"
+                 "max\\|mean\\|mexp\\|min\\|order\\|"
+                 "pmax\\|pmin\\|phi\\|pow\\|\\(i\\)?probit\\|prod\\|"
+                 "rank\\|ranked\\|round\\|"
+                 "sd\\|sin\\|solve\\|sort\\|sqrt\\|step\\|sum\\|svd\\|"
+                 "t\\|tan\\|trunc\\|T\\)[ \t\n]*(")
+         font-lock-function-name-face)
+
+   ;; .bmd files
+   (cons (concat (regexp-opt '(
+                               "dicClear" "dicSet" "dicStats"
+                               "infoMemory" "infoModules" "infoNodeMethods"
+                               "infoNodeTypes" "infoNodeValues"
+                               "infoUpdatersbyDepth" "infoUpdatersbyName"
+                               "modelCheck" "modelCompile" "modelData"
+                               "modelDisable" "modelEnable" "modelGenInits"
+                               "modelInits" "modelPrecision" "modelQuit"
+                               "modelSaveState" "modelSetAP" "modelSetIts"
+                               "modelSetOR" "modelSetRN" "modelUpdate"
+                               "ranksClear" "ranksSet" "ranksStats"
+                               "samplesAutoC" "samplesBgr" "samplesCoda"
+                               "samplesDensity" "samplesHistory" "samplesSet"
+                               "sampleStats" "samplesThin"
+                               "summaryClear" "summarySet" "summaryStats"
+                               ) 'words) "(")
+         font-lock-function-name-face)
+
+   (cons (concat (regexp-opt '("Local Variables" "End") 'words) ":")
+         font-lock-keyword-face)
+   )
+  "ESS[BUGS]: Font lock keywords."
+  )
+
+(defun ess-bugs-switch-to-suffix (suffix &optional bugs-chains bugs-monitor bugs-thin
+                                         bugs-burnin bugs-update)
+  "ESS[BUGS]: Switch to file with suffix."
+  (find-file (concat ess-bugs-file-dir ess-bugs-file-root suffix))
+
+  (if (equal 0 (buffer-size)) (progn
+                                (if (equal ".bug" suffix) (progn
+                                        ;(insert "var ;\n")
+                                                            (insert "model {\n")
+                                                            (insert "    for (i in 1:N) {\n    \n")
+                                                            (insert "    }\n")
+                                                            (insert "}\n")
+                                                            (insert "#Local Variables" ":\n")
+                                        ;           (insert "#enable-local-variables: :all\n")
+                                                            (insert "#ess-bugs-chains:1\n")
+                                                            (insert "#ess-bugs-monitor:(\"\")\n")
+                                                            (insert "#ess-bugs-thin:1\n")
+                                                            (insert "#ess-bugs-burnin:10000\n")
+                                                            (insert "#ess-bugs-update:10000\n")
+                                                            (insert "#End:\n")
+                                                            ))
+
+                                (if (equal ".bmd" suffix) (let
+                                                              ((ess-bugs-temp-chains "") (ess-bugs-temp-monitor ""))
+
+                                                            (if bugs-chains (setq ess-bugs-chains bugs-chains))
+                                                            (if bugs-monitor (setq ess-bugs-monitor bugs-monitor))
+                                                            (if bugs-thin (setq ess-bugs-thin bugs-thin))
+
+                                                            (setq ess-bugs-temp-chains
+                                                                  (concat "modelCompile(" (format "%d" ess-bugs-chains) ")\n"))
+
+                                                            (setq bugs-chains ess-bugs-chains)
+
+                                                            (while (< 0 bugs-chains)
+                                                              (setq ess-bugs-temp-chains
+                                                                    (concat ess-bugs-temp-chains
+                                                                            "modelInits('" ess-bugs-file-root
+                                                                            ".##" (format "%d" bugs-chains) "', "
+                                                                            (format "%d" bugs-chains) ")\n"))
+                                                              (setq bugs-chains (- bugs-chains 1)))
+
+                                                            (setq ess-bugs-temp-monitor "")
+
+                                                            (while (and (listp ess-bugs-monitor) (consp ess-bugs-monitor))
+                                                              (if (not (string-equal "" (car ess-bugs-monitor)))
+                                                                  (setq ess-bugs-temp-monitor
+                                                                        (concat ess-bugs-temp-monitor "samplesSet('"
+                                                                                (car ess-bugs-monitor)
+                                        ;", thin(" (format "%d" ess-bugs-thin)
+                                                                                "')\n")))
+                                                              (setq ess-bugs-monitor (cdr ess-bugs-monitor)))
+
+                                                            (insert "modelCheck('" ess-bugs-file-root ".bug')\n")
+                                                            (insert "modelData('" ess-bugs-file-root ".bdt')\n")
+                                                            (insert (ess-replace-in-string ess-bugs-temp-chains "##" "in"))
+                                                            (insert "modelGenInits()\n")
+                                                            (insert "modelUpdate(" (format "%d" bugs-burnin) ")\n")
+                                        ;(insert "modelUpdate(" (format "%d" (* bugs-thin bugs-burnin)) ")\n")
+                                                            (insert ess-bugs-temp-monitor)
+                                                            (insert "modelUpdate(" (format "%d" (* bugs-thin bugs-update)) ")\n")
+                                        ;           (insert (ess-replace-in-string
+                                        ;               (ess-replace-in-string ess-bugs-temp-chains
+                                        ;                   "modelCompile([0-9]+)" "#") "##" "to"))
+
+                                                            (if (< 1 bugs-thin) (insert "samplesThin(" (format "%d" bugs-thin) ")\n"))
+
+                                                            (insert "samplesCoda('*', '" ess-bugs-file-root "')\n")
+
+                                        ;           (if ess-bugs-system (progn
+                                        ;               (insert "system rm -f " ess-bugs-file-root ".ind\n")
+                                        ;               (insert "system ln -s " ess-bugs-file-root "index.txt " ess-bugs-file-root ".ind\n")
+
+                                        ;               (setq bugs-chains ess-bugs-chains)
+
+                                        ;               (while (< 0 bugs-chains)
+                                        ;                   (setq ess-bugs-temp-chain (format "%d" bugs-chains))
+
+                                        ;                   ;.txt not recognized by BOA and impractical to over-ride
+                                        ;                   (insert "system rm -f " ess-bugs-file-root ess-bugs-temp-chain ".out\n")
+                                        ;                   (insert "system ln -s " ess-bugs-file-root "chain" ess-bugs-temp-chain ".txt "
+                                        ;                       ess-bugs-file-root ess-bugs-temp-chain ".out\n")
+                                        ;                   (setq bugs-chains (- bugs-chains 1)))))
+
+                                                            (insert "modelQuit()\n")
+                                                            (insert "Local Variables" ":\n")
+                                        ;           (insert "enable-local-variables: :all\n")
+                                                            (insert "ess-bugs-chains:" (format "%d" ess-bugs-chains) "\n")
+                                                            (insert "ess-bugs-command:\"" ess-bugs-command "\"\n")
+                                                            (insert "End:\n")
+                                                            ))
+                                ))
+  )
+
+(defun ess-bugs-na-bmd (bugs-command)
+  "ESS[BUGS]: Perform the Next-Action for .bmd."
+                                        ;(ess-save-and-set-local-variables)
+  (if (equal 0 (buffer-size)) (ess-bugs-switch-to-suffix ".bmd")
+                                        ;else
+    (shell)
+    (ess-sleep)
+
+    (when (and (when (fboundp 'w32-shell-dos-semantics)
+                 (w32-shell-dos-semantics))
+               (string-equal ":" (substring ess-bugs-file 1 2)))
+      (insert (substring ess-bugs-file 0 2)))
+
+    (comint-send-input)
+    (insert "cd \"" ess-bugs-file-dir "\"")
+    (comint-send-input)
+
+                                        ;    (let ((ess-bugs-temp-chains ""))
+                                        ;
+                                        ;       (while (< 0 bugs-chains)
+                                        ;           (setq ess-bugs-temp-chains
+                                        ;               (concat (format "%d " bugs-chains) ess-bugs-temp-chains))
+                                        ;           (setq bugs-chains (- bugs-chains 1)))
+
+    ;; (insert "echo '"
+    ;;       ess-bugs-batch-pre-command " " bugs-command " < "
+    ;;       ess-bugs-file-root ".bmd > " ess-bugs-file-root ".bog 2>&1 "
+    ;;       ess-bugs-batch-post-command "' > " ess-bugs-file-root ".bsh")
+    ;; (comint-send-input)
+
+    ;; (insert "at -f " ess-bugs-file-root ".bsh now")
+
+    ;; (comint-send-input)
+
+    (insert "echo '"
+            ess-bugs-batch-pre-command " " bugs-command " < "
+            ess-bugs-file-root ".bmd > " ess-bugs-file-root ".bog 2>&1 "
+            ess-bugs-batch-post-command "' | at now")
+
+    (comint-send-input)
+    ))
+
+(defun ess-bugs-na-bug ()
+  "ESS[BUGS]: Perform Next-Action for .bug"
+
+  (if (equal 0 (buffer-size)) (ess-bugs-switch-to-suffix ".bug")
+                                        ;else
+    (ess-save-and-set-local-variables)
+    (ess-bugs-switch-to-suffix ".bmd"
+                               ess-bugs-chains ess-bugs-monitor ess-bugs-thin ess-bugs-burnin ess-bugs-update))
+  )
+
+;;;###autoload
+(define-derived-mode ess-bugs-mode ess-mode "ESS[BUGS]"
+  "Major mode for BUGS."
+  (setq-local comment-start "#")
+  (setq font-lock-defaults '(ess-bugs-font-lock-keywords nil t))
+  (setq ess-language "S") ; mimic S for ess-smart-underscore
+  (unless (when (fboundp 'w32-shell-dos-semantics)
+            (w32-shell-dos-semantics))
+    (add-hook 'comint-output-filter-functions #'ess-bugs-exit-notify-sh)))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.[Bb][Uu][Gg]\\'" . ess-bugs-mode))
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.[Bb][Oo][Gg]\\'" . ess-bugs-mode))
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.[Bb][Mm][Dd]\\'" . ess-bugs-mode))
+
+(defun ess-sci-to-dec ()
+  "For BUGS/S family: Express +/-0.000E+/-0 or +/-0.0e+/-00 as a decimal."
+  (interactive)
+  (setq buffer-read-only nil)
+  (save-excursion (goto-char 0)
+                  (save-match-data (let ((ess-temp-replacement-string nil)
+                                         (ess-temp-replacement-9 0)
+                                         (ess-temp-replacement-diff 0))
+                                     (while (search-forward-regexp "-?[0-9][.][0-9][0-9]?[0-9]?[Ee][+-][0-9][0-9]?" nil t)
+                                       (setq ess-temp-replacement-string
+                                             (int-to-string (string-to-number (match-string 0))))
+                                       (setq ess-temp-replacement-diff (- (match-end 0) (match-beginning 0)))
+                                       (save-match-data
+                                         (setq ess-temp-replacement-9
+                                               (string-match "99999999999$" ess-temp-replacement-string))
+
+                                         (if (not ess-temp-replacement-9)
+                                             (setq ess-temp-replacement-9
+                                                   (string-match "000000000001$" ess-temp-replacement-string))))
+
+                                       (if ess-temp-replacement-9
+                                           (setq ess-temp-replacement-string
+                                                 (substring ess-temp-replacement-string 0 ess-temp-replacement-9)))
+
+                                       (setq ess-temp-replacement-diff
+                                             (- ess-temp-replacement-diff (string-width ess-temp-replacement-string)))
+
+                                       (while (> ess-temp-replacement-diff 0)
+                                         (setq ess-temp-replacement-string (concat ess-temp-replacement-string " "))
+                                         (setq ess-temp-replacement-diff (- ess-temp-replacement-diff 1)))
+
+                                       (replace-match ess-temp-replacement-string))))))
+
+(provide 'ess-bugs-d)
+
+;;; ess-bugs-d.el ends here
diff --git a/elpa/ess-20260424.1544/ess-bugs-l.el b/elpa/ess-20260424.1544/ess-bugs-l.el
new file mode 100644 (file)
index 0000000..a3a8246
--- /dev/null
@@ -0,0 +1,291 @@
+;;; ess-bugs-l.el --- ESS[BUGS] languages  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2006-2020 Free Software Foundation, Inc.
+
+;; Author: Rodney Sparapani
+;; Maintainer: ESS-help <ess-helpNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Code:
+
+(require 'shell)
+(require 'ess-utils)
+(defvar ess-bugs-command)
+(defvar ess-bugs-chains)
+;;(defvar ess-jags-command)
+;;(defvar ess-jags-chains)
+(defvar ess-bugs-default-bins)
+
+(declare-function ess-bugs-na-bug "ess-bugs-d")
+;;(declare-function ess-jags-na-bug "ess-jags-d")
+(declare-function ess-bugs-na-bmd "ess-bugs-d")
+;;(declare-function ess-jags-na-jmd "ess-jags-d")
+
+(defgroup ess-bugs nil
+  "ESS: BUGS."
+  :group 'ess
+  :prefix "ess-")
+
+(defcustom ess-bugs-batch-method
+  (if (and ess-microsoft-p
+           (fboundp 'w32-shell-dos-semantics)
+           (w32-shell-dos-semantics))
+      'dos
+    'sh)
+  "Method used by `ess-bugs-batch'.
+The default is based on the value of the Emacs variable `system-type'
+and, on Windows machines, the function `w32-shell-dos-semantics'.
+\\='sh           if *shell* runs a Bourne-like or a C-like Unix shell
+\\='dos          if *shell* runs a DOS-like Windows shell
+
+Unix users will get \\='sh by default.
+
+Windows users running a DOS-like *shell* will get \\='dos by default,
+while those running a Unix-like *shell* will get \\='sh by default.
+
+Users whose default is not \\='sh, but are accessing a remote machine with
+`telnet' or `ssh', should have the following in their init file:
+   (setq-default ess-bugs-batch-method \\='sh)"
+  :group 'ess-bugs
+  :type '(choice (const :tag "Bourne/C-like Unix Shell" sh)
+                 (const :tag "DOS-like Windows shell" dos)))
+
+(defcustom ess-bugs-batch-post-command
+  (if (equal ess-bugs-batch-method 'sh) "&" " ")
+  "ESS[BUGS]: Modifiers at the end of the batch BUGS command line."
+  :group 'ess-bugs
+  :type  'string
+  )
+
+(defcustom ess-bugs-batch-pre-command
+  (if (equal ess-bugs-batch-method 'sh) "nohup nice time"
+    (if ess-microsoft-p "start"))
+  "ESS[BUGS]: Modifiers at the beginning of the batch BUGS command line."
+  :group 'ess-bugs
+  :type  'string
+  )
+
+
+(defcustom ess-bugs-default-burn-in "500"
+  "ESS[BUGS]: Burn-in iterations to discard."
+  :group 'ess-bugs
+  :type  'string
+  )
+
+(defcustom ess-bugs-default-update "1000"
+  "ESS[BUGS]: Iterations to store."
+  :group 'ess-bugs
+  :type  'string
+  )
+
+(defvar ess-bugs-batch-command ";"
+  "ESS[BUGS]: The name of the command to run BUGS in batch mode."
+  )
+
+(defvar ess-bugs-file "."
+  "ESS[BUGS]: BUGS file with PATH.")
+
+(defvar ess-bugs-file-root "."
+  "ESS[BUGS]: Root of BUGS file.")
+
+(defvar ess-bugs-file-suffix "."
+  "ESS[BUGS]: Suffix of BUGS file.")
+
+(defvar ess-bugs-file-dir "."
+  "ESS[BUGS]: Directory of BUGS file.")
+
+(defvar ess-bugs-file-data "..."
+  "ESS[BUGS]: BUGS data file.")
+
+(defcustom ess-bugs-inits-suffix ".in"
+  "ESS[BUGS]: BUGS init file suffix."
+  :group 'ess-bugs
+  :type  'string
+  )
+
+(defcustom ess-bugs-data-suffix ".dat"
+  "ESS[BUGS]: BUGS data file suffix."
+  :group 'ess-bugs
+  :type  'string
+  )
+
+(defcustom ess-bugs-mode-hook nil
+  "ESS[BUGS]: List of functions to call upon entering mode."
+  :group 'ess-bugs
+  :type 'hook)
+
+(defvar ess-bugs-monitor-vars " "
+  "ESS[BUGS]: List of BUGS variables to be written out to a file.")
+
+(defvar ess-bugs-stats-vars " "
+  "ESS[BUGS]: List of BUGS variables to be summarized with statistics.")
+
+(defvar ess-bugs-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (quote [f2])  #'ess-revert-wisely)
+    ;;(define-key map "\C-c\C-c" #'ess-bugs-next-action)
+    (define-key map "<" #'ess-bugs-hot-arrow) ;; NIMBLE needs equals character
+;;    (define-key map "=" #'ess-bugs-hot-arrow)
+;;    (define-key map "_" #'ess-bugs-hot-arrow)
+    map)
+  "ESS[BUGS]: Keymap for mode.")
+
+(defvar ess-bugs-syntax-table
+  (let ((table (make-syntax-table)))
+    (modify-syntax-entry ?\\ "." table)
+    (modify-syntax-entry ?# "<" table)
+    (modify-syntax-entry ?\n ">" table)
+    (modify-syntax-entry ?\( "()" table)
+    (modify-syntax-entry ?\)  ")(" table)
+    (modify-syntax-entry ?. "w" table)
+    table)
+  "ESS[BUGS]: Syntax table for mode.")
+
+(defun ess-bugs-file ()
+  "ESS[BUGS]: Set internal variables dealing with BUGS files.
+Set `ess-bugs-file', `ess-bugs-file-root', `ess-bugs-file-suffix'
+and `ess-bugs-file-dir'."
+  (let ((ess-bugs-temp-string (buffer-name)))
+    (setq ess-bugs-file (expand-file-name ess-bugs-temp-string))
+    (setq ess-bugs-file-dir
+          (convert-standard-filename (file-name-directory ess-bugs-file)))
+    (setq ess-bugs-file-root
+          (file-name-nondirectory (file-name-sans-extension ess-bugs-file)))
+
+    (if (fboundp 'file-name-extension)
+        (setq ess-bugs-file-suffix (file-name-extension ess-bugs-temp-string))
+      ;;else
+      (setq ess-bugs-file-suffix (car (last (split-string ess-bugs-temp-string "[.]")))))
+
+    (setq ess-bugs-file-suffix
+          (downcase (car (split-string (concat "." ess-bugs-file-suffix) "[<]"))))
+
+    (setq ess-bugs-file (concat ess-bugs-file-dir ess-bugs-file-root ess-bugs-file-suffix))
+    )
+  )
+
+(defun ess-bugs-exit-notify-sh (string)
+  "ESS[BUGS]: 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-bugs-hot-arrow ()
+  "ESS[BUGS]: Substitute <- for = key press"
+  (interactive)
+  (insert " <- "))
+
+;; (defun ess-bugs-next-action ()
+;;   "ESS[BUGS/JAGS]: Perform the appropriate next action."
+;;   (interactive)
+;;   (ess-bugs-file)
+
+;;   (cond ((equal ".bug" ess-bugs-file-suffix) (ess-bugs-na-bug))
+;;         ((equal ".jag" ess-bugs-file-suffix) (ess-jags-na-bug))
+;;         ((equal ".bmd" ess-bugs-file-suffix)
+;;          (ess-save-and-set-local-variables)
+;;          (ess-bugs-na-bmd ess-bugs-command ess-bugs-chains))
+;;         ((equal ".jmd" ess-bugs-file-suffix)
+;;          (ess-save-and-set-local-variables)
+;;          (ess-jags-na-jmd ess-jags-command ess-jags-chains)))
+;;   )
+
+(defun ess-bugs-sci-to-round-4-dp ()
+  "ESS[BUGS]: round output from +/-0.000E+/-0 to 4 decimal places."
+  (interactive)
+  (setq buffer-read-only nil)
+  (save-excursion (goto-char 0)
+                  (save-match-data (let ((ess-bugs-replacement-string nil)
+                                         (ess-bugs-replacement-9 0)
+                                         (ess-bugs-replacement-diff 0))
+                                     (while (search-forward-regexp "-?[0-9][.][0-9][0-9][0-9]E[+-][0-9]" nil t)
+                                       (setq ess-bugs-replacement-string
+                                             (int-to-string (string-to-number (match-string 0))))
+                                       (setq ess-bugs-replacement-diff (- (match-end 0) (match-beginning 0)))
+                                       (save-match-data
+                                         (setq ess-bugs-replacement-9
+                                               (string-match "99999999999$" ess-bugs-replacement-string))
+
+                                         (if (not ess-bugs-replacement-9)
+                                             (setq ess-bugs-replacement-9
+                                                   (string-match "000000000001$" ess-bugs-replacement-string))))
+
+                                       (if ess-bugs-replacement-9
+                                           (setq ess-bugs-replacement-string
+                                                 (substring ess-bugs-replacement-string 0 ess-bugs-replacement-9)))
+
+                                       (setq ess-bugs-replacement-diff
+                                             (- ess-bugs-replacement-diff (string-width ess-bugs-replacement-string)))
+
+                                       (while (> ess-bugs-replacement-diff 0)
+                                         (setq ess-bugs-replacement-string (concat ess-bugs-replacement-string " "))
+                                         (setq ess-bugs-replacement-diff (- ess-bugs-replacement-diff 1)))
+
+                                       (replace-match ess-bugs-replacement-string))))))
+
+;;; ESS[BUGS-Shell] for running BUGS interactively
+(defgroup ess-bugs-shell nil
+  "ESS: BUGS-Shell."
+  :group 'ess-bugs
+  :prefix "ess-")
+
+(defcustom ess-bugs-shell-buffer-name "BUGS"
+  "ESS[BUGS-Shell]: The name of the BUGS-Shell buffer."
+  :group 'ess-bugs-shell
+  :type  'string)
+
+(defcustom ess-bugs-shell-command "OpenBUGS"
+  "ESS[BUGS-Shell]: The name of the command to run BUGS interactively.
+
+Set to the name of the batch BUGS script that comes with ESS or
+to the name of BUGS command. Make sure it is in your PATH or
+add path to the command name."
+  :group 'ess-bugs-shell
+  :type  'string)
+
+(defcustom ess-bugs-shell-default-output-file-root "bugs"
+  "ESS[BUGS-Shell]: Default value for the root of output files."
+  :group 'ess-bugs-shell
+  :type  'string)
+
+(defcustom ess-bugs-shell-mode-hook nil
+  "ESS[BUGS-Shell]: List of functions to call upon entering mode."
+  :group 'ess-bugs-shell
+  :type 'hook)
+
+(defun ess-bugs-shell ()
+  "Create a buffer with BUGS running as a subprocess."
+  (interactive)
+  (pop-to-buffer-same-window (concat "*" ess-bugs-shell-buffer-name "*"))
+  (make-comint ess-bugs-shell-buffer-name ess-bugs-shell-command nil
+               ess-bugs-default-bins ess-bugs-shell-default-output-file-root)
+  (comint-mode)
+  (setq shell-dirtrackp t
+        major-mode 'bugs-shell-mode
+        mode-name "ESS[BUGS-Shell]"
+        comint-prompt-regexp "^Bugs> *")
+  (make-local-variable 'font-lock-defaults)
+  (setq font-lock-defaults '(ess-bugs-font-lock-keywords nil t))
+  (run-mode-hooks 'ess-bugs-shell-mode-hook)
+  )
+
+(provide 'ess-bugs-l)
+
+;;; ess-bugs-l.el ends here
diff --git a/elpa/ess-20260424.1544/ess-custom.el b/elpa/ess-20260424.1544/ess-custom.el
new file mode 100644 (file)
index 0000000..8476527
--- /dev/null
@@ -0,0 +1,2529 @@
+;;; ess-custom.el --- Customize variables for ESS  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1997-2026 Free Software Foundation, Inc.
+
+;; Author: Rodney Sparapani
+;; Maintainer: ESS-help <ess-helpNOSPAMr-project.org>
+;; Keywords: languages
+
+;; This file is part of GNU Emacs
+
+;; 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/
+
+
+
+;; 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/
+
+
+;;; Commentary:
+;; This file holds defcustoms for ESS. It is required by ess-utils.el,
+;; which in turn is required by almost every other ESS file.
+
+;;; Code:
+(require 'comint)
+
+;; 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 (memq system-type '(ms-dos windows-nt))
+  "Value is t if the OS is one of Microsoft's, nil otherwise.")
+
+;; Customization Groups
+
+(defgroup ess nil
+  "ESS: Emacs Speaks Statistics."
+  :group 'languages
+  :link '(info-link "(ESS)")
+  :link '(url-link "https://ess.r-project.org/"))
+
+(defgroup ess-edit nil
+  "ESS: editing behavior, including comments/indentation."
+  :group 'ess
+  :prefix "ess-")
+
+(defgroup ess-proc nil
+  "ESS: process control."
+  :group 'ess
+  :prefix "ess-")
+
+(defgroup ess-command nil
+  "ESS: Commands for various things."
+  :group 'ess
+  :prefix "ess-")
+
+(defgroup ess-help nil
+  "ESS: help functions."
+  :group 'ess
+  :prefix "ess-")
+
+(defgroup ess-hooks nil
+  "ESS: hooks for customization."
+  :group 'ess
+  :prefix "ess-")
+
+(defgroup ess-S nil
+  "ESS: S Languages."
+  :group 'ess
+  :prefix "ess-")
+
+(defgroup ess-SPLUS nil
+  "ESS: S-PLUS Dialect of S."
+  :group 'ess-S
+  :prefix "ess-")
+
+(defgroup ess-R nil
+  "ESS: R Dialect of S."
+  :group 'ess-S
+  :prefix "ess-")
+
+(defgroup ess-Julia nil
+  "ESS: Julia."
+  :group 'ess
+  :prefix "julia-")
+
+(defgroup ess-sas nil
+  "ESS: SAS."
+  :group 'ess
+  :prefix "ess-")
+
+(defgroup ess-roxy nil
+  "Mode for editing in-code Roxygen documentation."
+  :group 'ess
+  :group 'convenience
+  :group 'ess-extras
+  :prefix "ess-"
+  :group 'tools)
+
+(defgroup ess-extras nil
+  "Extra utilities for ESS."
+  :group 'ess
+  :prefix "ess-")
+
+(defgroup ess-faces nil
+  "Faces and face options for ESS modes."
+  :group 'ess
+  :group 'faces
+  :prefix "ess-")
+
+
+\f ; User changeable variables
+
+;;*;; Options and Initialization
+
+;;;###autoload
+(defcustom ess-lisp-directory
+  (file-name-directory
+   (or load-file-name
+       buffer-file-name))
+  "Directory containing ess-site.el(c) and other ESS Lisp files."
+  :group 'ess
+  :type 'directory
+  :package-version '(ess . "25.01.1"))
+
+(defcustom ess-etc-directory
+  ;; Try to detect the `etc' folder only if not already set up by distribution
+  (let (dir)
+    (dolist (d '("./etc/" "../../etc/ess/" "../etc/" "../etc/ess/"))
+      (setq d (expand-file-name d ess-lisp-directory))
+      (when (file-directory-p d)
+        (setq dir d)))
+    dir)
+  "Location of the ESS etc/ directory.
+The ESS etc directory stores various auxiliary files that are useful
+for ESS, such as icons."
+  :group 'ess
+  :type 'directory
+  :package-version '(ess . "25.01.1"))
+
+;; Depending on how ESS is loaded the `load-path' might not contain
+;; the `lisp' directory. For this reason we need to add it before we
+;; start requiring ESS files
+;;;###autoload
+(add-to-list 'load-path (directory-file-name ess-lisp-directory))
+;; Add ess-lisp-directory/obsolete to load-path; files here will
+;; automatically warn that they are obsolete when loaded.
+;;;###autoload
+(add-to-list 'load-path (directory-file-name (expand-file-name "obsolete" ess-lisp-directory)))
+
+(unless (file-directory-p ess-etc-directory)
+  (display-warning 'ess (format "Could not find directory `ess-etc-directory': %s"
+                                ess-etc-directory) :error))
+
+;; Menus and pulldowns.
+
+(defcustom ess-imenu-use-p (fboundp 'imenu)
+  "Non-nil means use imenu facility.
+This value can be overridden by mode-specific variables, such
+as `ess-imenu-use-S'."
+  :group 'ess
+  :type  'boolean)
+
+(defcustom ess-imenu-use-S ess-imenu-use-p
+  "Non-nil means include an Imenu menu item in S buffers."
+  :group 'ess
+  :type  'boolean)
+
+(defcustom ess-auto-width-visible nil
+  "When non-nil, echo width setting in the inferior buffer.
+See `ess-auto-width'. Be warned that ESS can set the width a
+lot."
+  :group 'ess
+  :type 'boolean
+  :package-version '(ess . "25.01.1"))
+
+(defcustom ess-auto-width nil
+  "When non-nil, set the width option when the window configuration changes.
+When \\='frame, set the width to the frame width. When \\='window, set
+the width to the window width. If an integer, set the width to
+that integer. If it's a negative integer, set the width to the
+window's width minus that number. Anything else is treated as
+\\='window."
+  :group 'ess
+  :type '(choice (const :tag "Do nothing" :value nil)
+                 (const :tag "Frame width" :value frame)
+                 (const :tag "Window width" :value window)
+                 (integer :tag "Integer value"))
+  :package-version '(ess . "25.01.1"))
+
+(defcustom ess-handy-commands '(("change-directory"     . ess-change-directory)
+                                ("install.packages"     . ess-install-library)
+                                ("library"              . ess-library)
+                                ("objects[ls]"          . ess-execute-objects)
+                                ("help-apropos"         . ess-display-help-apropos)
+                                ("help-index"           . ess-display-package-index)
+                                ("help-object"          . ess-display-help-on-object)
+                                ("search"               . ess-execute-search)
+                                ("set-width"            . ess-execute-screen-options)
+                                ("setRepos"             . ess-setRepositories)
+                                ("sos"                  . ess-sos)
+                                ("vignettes"            . ess-display-vignettes)
+                                )
+  "An alist of custom ESS commands.
+These are available for call by function `ess-handy-commands' and
+`ess-smart-comma' function."
+  :group 'ess
+  :type 'alist)
+
+(defvar-local ess--local-handy-commands nil
+  "Store handy commands locally.")
+
+(defcustom ess-describe-at-point-method nil
+  "Whether `ess-describe-object-at-point' should use a tooltip.
+If nil display in an electric buffer. If \\='tooltip display in
+a tooltip.
+
+See also `tooltip-hide-delay' and variable `tooltip-delay'."
+  :group 'ess-utils
+  :type '(choice (const :tag "buffer" :value nil ) (const tooltip)))
+
+(defvaralias
+  'ess-R-describe-object-at-point-commands
+  'ess-r-describe-object-at-point-commands)
+(defcustom ess-r-describe-object-at-point-commands
+  '(("str(%s)")
+    (".ess_htsummary(%s, hlength = 20, tlength = 20)")
+    ("summary(%s, maxsum = 20)"))
+  "A list of commands cycled by `ess-describe-object-at-point'.
+%s is substituted with the name at point.
+
+The value of each element is nil and is not used in current
+implementation."
+  :group 'ess-R
+  :type 'alist)
+
+(defcustom ess-S-describe-object-at-point-commands
+  ess-R-describe-object-at-point-commands
+  "An alist of commands cycled by `ess-describe-object-at-point'.
+%s is substitute with the name at point. The value is not used as
+ yet."
+  :group 'S+
+  :type 'alist)
+
+
+(defcustom ess-can-eval-in-background t
+  "If non-nil ESS can perform caching and other background activities.
+This allows ESS to call the subprocess on idle time."
+  :group 'ess
+  :type 'boolean)
+
+(defcustom ess-user-full-name (user-full-name)
+  "The full name of the user."
+  :group 'ess
+  :type 'string)
+
+(defcustom ess-blink-region t
+  "If t evaluated region is highlighted for a shortwhile.
+See also `ess-blink-delay'"
+  :group 'ess
+  :type 'boolean)
+
+(defcustom ess-blink-delay .3
+  "Number of seconds to highlight the evaluated region."
+  :group 'ess
+  :type 'number)
+
+(defcustom ess-ask-for-ess-directory t
+  "When non-nil ask the process directory when ESS process starts.
+When set to nil, and the process is invoked with an universal
+argument, the directory is prompted for."
+  :group 'ess
+  :type 'boolean)
+
+(defcustom ess-ask-about-transfile nil
+  "Non-nil means ask about a transcript file before running ESS."
+  :group 'ess
+  :type 'boolean)
+
+(defcustom ess-display-buffer-reuse-frames t
+  "Non-nil means \\[display-buffer] reuses existing frames.
+See `display-buffer-reuse-frames'."
+  :group 'ess
+  :type 'boolean)
+
+(defvar-local ess-language nil
+  "Determines the language to use for the current buffer.
+See also `ess-dialect'.")
+
+(defvar-local ess-dialect nil
+  "String version of the dialect being run for the inferior process.
+This, plus `ess-language', should be able to determine the exact
+version of the statistical package being executed in the particular
+buffer.")
+
+(defvaralias 'ess-directory-function 'ess-startup-directory-function)
+(defcustom ess-startup-directory-function nil
+  "Function to return the directory that ESS is run from.
+Value of `ess-startup-directory' has precedence over this function."
+  :group 'ess
+  :type '(choice (const nil) function))
+
+(defvaralias 'ess-directory 'ess-startup-directory)
+(defcustom ess-startup-directory nil
+  "The directory to run ESS processes from.
+If a string it should be a directory from which to start the
+process. If a symbol, the symbol's value should be a directory.
+
+For example, the following setting would always start the process
+in the directory of the current file:
+
+   (setq ess-startup-directory \\='default-directory)
+
+If `ess-startup-directory' is nil (the default) and
+`ess-startup-directory-function' is non-nil, the value returned
+by `ess-startup-directory-function' is used as a directory.
+
+If `ess-startup-directory-function' is nil, then the current
+project as returned by `project-current' is used. For files which
+mark an R project see `ess-r-project'. For example you can add
+.Rprofile to a sub-directory of a project to mark it as R
+sub-project.
+
+Finally, if not in a project (`project-current' returned nil) the
+`default-directory' is used. It is normally the directory of the
+current file.
+
+See also `ess-ask-for-ess-directory'."
+  :group 'ess
+  :type '(choice (const nil) directory symbol))
+
+
+(defcustom ess-history-directory nil
+  "Directory to pick up `ess-history-file' from.
+If this is nil, the history file is relative to the startup
+directory of the inferior process (see `ess-startup-directory')."
+  :group 'ess
+  :type '(choice (const nil) directory))
+
+(defcustom ess-history-file t
+  "File to pick up history from.  nil means *no* history is read or written.
+t means something like \".Rhistory\".
+If this is a relative file name, it is relative to `ess-history-directory'.
+Consequently, if that is set explicitly, you will have one history file
+for all projects."
+  :group 'ess
+  :type '(choice (const :tag "Off" nil)
+                 (const :tag "On" t)
+                 file))
+
+(defcustom ess-plain-first-buffername t
+  "When non-nil, the first process buffer created does not have a number.
+In other words, it is R:foo rather than R:1:foo. Subsequent
+processes buffers are always numbered (e.g. R:2:foo."
+  :group 'ess
+  :type 'boolean)
+
+
+(define-obsolete-variable-alias
+  'ess-use-inferior-program-name-in-buffer-name
+  'ess-use-inferior-program-in-buffer-name "ESS 18.10")
+(defcustom ess-use-inferior-program-in-buffer-name nil
+  "For R, use e.g., `R-2.1.0' or `R-devel' (the program name) for buffer name.
+Avoids the plain dialect name."
+  :group 'ess
+  :type 'boolean)
+
+(defcustom  ess-use-ido t
+  "If t ess will try to use ido completion whenever possible.
+
+By default ESS uses enables IDO flex matching. See
+`ido-enable-flex-matching' for details on flex matching and
+`ess-ido-flex-matching' on how to disable it for ESS, if you
+don't want it.
+
+See info node `(ido) Top' for more information about how ido
+works."
+  :group 'ess
+  :require 'ido
+  :type 'boolean)
+
+
+(defcustom ess-tab-complete-in-script nil
+  "If non-nil, TAB tries to complete if it does not indent in script buffers.
+See also `ess-first-tab-never-complete'."
+  :group 'ess
+  :type 'boolean)
+(make-obsolete-variable 'ess-tab-complete-in-script 'tab-always-indent "ESS 19.04" 'set)
+
+(define-obsolete-variable-alias 'ess-first-tab-never-completes-p
+  'ess-first-tab-never-complete "ESS 19.04")
+(defcustom ess-first-tab-never-complete 'symbol
+  "If t, first TAB never tries to complete in `ess-mode'.
+If \\='symbol first TAB doesn't try to complete if next char is a
+valid symbol constituent.
+
+If \\='symbol-or-paren  don't complete if next char is closed paren
+)}] or symbol character.
+
+If \\='symbol-or-paren-or-punct don't complete if next char is
+punctuation +-=% etc, or closed paren or symbol.
+
+If \\='unless-eol - first TAB completes only at end of line.
+
+If nil first TAB always tries to complete (this might be too
+aggressive and dangerous)."
+  :group 'ess
+  :type '(choice (const nil)
+                 (const symbol)
+                 (const symbol-or-paren)
+                 (const symbol-or-paren-or-punct)
+                 (const unless-eol)
+                 (const t)))
+
+(defcustom ess-use-eldoc t
+  "If t, activate eldoc in `ess-mode' and `inferior-ess-mode' buffers.
+If \\='script-only activate in `ess-mode' buffers only.
+
+See also `ess-eldoc-show-on-symbol'."
+  :group 'ess-extras
+  :type '(choice (const t) (const script-only) (const nil)))
+
+
+(defcustom ess-eldoc-show-on-symbol nil
+  "If non-nil, show help string whenever the point is on a symbol.
+If nil show only when the point is in a function call, i.e. after (."
+  :group 'ess-extras
+  :type  'boolean)
+
+(defcustom ess-eldoc-abbreviation-style 'normal
+  "Controls how `eldoc' displays information that does not fit on a line.
+
+A symbol which can be
+
+- nil: do nothing
+- mild: Replace TRUE, FALSE with T,F
+- normal: Try mild + shorten the default values longer than 10
+  characters.
+- strong: Try normal + completely remove default values except
+  =F,=T,=d where d is a digit.
+- aggressive (or t): Try strong + truncate the doc string to fit
+  into minibuffer.
+
+The default style is \\='normal.
+
+Ess-eldoc also honors the value of
+`eldoc-echo-area-use-multiline-p'. If this variable is not t (the
+default), doc strings are truncated to fit into minibufer. This
+allows the use of different abbreviation styles with the
+truncation."
+  :group 'ess
+  :type '(choice (const nil) (const mild) (const normal) (const strong) (const aggressive) (const t)))
+
+(defcustom ess-use-flymake t
+  "If non-nil activate flymake in `ess-mode' buffers.
+If \\='process, only check if the buffer has an inferior process."
+  :group 'ess
+  :type '(choice (const :tag "Always" t)
+                 (const :tag "With running inferior process" process)
+                 (const :tag "Never" nil))
+  :package-version '(ess . "25.01.1"))
+
+(defcustom ess-use-auto-complete t
+  "If non-nil, activate auto-complete support.
+If t, activate auto-complete support in `ess-mode' and
+`inferior-ess-mode' buffers. If \\='script-only activate in `ess-mode'
+buffers only.
+
+If non-nil add `ac-source-R' and `ac-source-filename' to the
+`ac-sources' buffer local variable.
+
+ESS defines three AC sources `ac-source-R',`ac-source-R-objects'
+and `ac-source-R-args'. See auto-complete package
+documentation (http://cx4a.org/software/auto-complete/) for how
+to install your custom sources."
+  :group 'ess-extras
+  :type '(choice (const t) (const script-only) (const nil)))
+(make-obsolete-variable 'ess-use-auto-complete "Auto-complete is unmaintained; use company-mode instead"
+                        "ESS 19.04" 'set)
+
+(defcustom ess-use-company t
+  "If t, activate company support in `ess-mode' and `inferior-ess-mode' buffers.
+If non-nil add `company-R-args' and `company-R-objects' to the
+`company-backends'. If \\='script-only activate in `ess-mode' buffers
+only."
+  :group 'ess-extras
+  :type '(choice (const t) (const script-only) (const nil)))
+
+(defcustom ess-company-arg-prefix-length nil
+  "Minimum prefix for ess company function argument completion."
+  :group 'ess-extras
+  :type '(choice (const :tag "Default" nil)
+                 integer))
+
+(defcustom ess-use-tracebug t
+  "If t, load `ess-tracebug' when R process starts."
+  :group 'ess-extras
+  :type  'boolean)
+
+(defcustom  ess-ido-flex-matching t
+  "If t, ido for ESS completion uses flex matching.
+See `ido-enable-flex-matching' for details.
+If you have an old computer, or you load lot of packages, you
+might want to set this to nil."
+  :group 'ess
+  :type 'boolean)
+
+(defvar ess--completing-hist nil
+  "Variable to store completion history.
+Used by `ess-completion-read' command.")
+
+(defvar-local ess-smart-operators ()
+  "List of smart operators to be used in ESS and IESS modes.
+Not to be set by users. It is redefined by mode specific
+settings, such as `ess-r-smart-operators'.")
+
+(defvaralias 'ess-R-smart-operators 'ess-r-smart-operators)
+(defvar ess-r-smart-operators nil
+  "If nil, don't use any of smart operators.
+If t, use all. If an explicit list of operators, use only those
+operators.
+
+In current version of ESS, it controls the behavior of
+`ess-smart-comma' only, but will be enriched in the near future.")
+
+
+(defvar ess-no-skip-regexp "[ \t\n]*\\'"
+  "If `ess-next-code-line' sees this line, it doesn't jump over.
+
+Used to avoid annoying jumping by ess-eval.*-and-step to end of
+buffer or end chunks etc.")
+
+(make-obsolete-variable 'ess-smart-S-assign-key nil "ESS 18.10")
+
+(defcustom ess-assign-list (cons (or (bound-and-true-p ess-S-assign) " <- ")
+                                 '(" <<- " " = " " -> " " ->> "))
+  "List of assignment operators.
+`ess-cycle-assign' uses this list.  These strings must
+contain spaces on either side."
+  ;; Note that spaces on either side is not strictly true (as in the
+  ;; function won't error), but matching <-/<<- is broken without
+  ;; them.
+  :type '(repeat string)
+  :group 'ess
+  :package-version '(ess . "25.01.1"))
+
+(defvar ess-S-assign)
+(make-obsolete-variable 'ess-S-assign 'ess-assign-list "ESS 18.10")
+
+(defcustom ess-r-prettify-symbols
+  '(("<-" . (?\s (Br . Bl) ?\s (Bc . Bc) ?←))
+    ("->" . (?\s (Br . Bl) ?\s (Bc . Bc) ?→))
+    ("->>" .  (?\s (Br . Bl) ?\s (Br . Bl) ?\s
+                   (Bl . Bl) ?- (Bc . Br) ?- (Bc . Bc) ?>
+                   (Bc . Bl) ?- (Br . Br) ?>))
+    ("<<-" .  (?\s (Br . Bl) ?\s (Br . Bl) ?\s
+                   (Bl . Bl) ?< (Bc . Br) ?- (Bc . Bc) ?-
+                   (Bc . Bl) ?< (Br . Br) ?-)))
+  ;; Setup prettify-symbols-alist to show "pretty" arrows, but make
+  ;; sure that they arrows use the same amount of spacing as <- and
+  ;; <<- to ensure indentation does not change when
+  ;; prettify-symbols-mode is turned on/off.
+  "Alist of symbols prettifications, see `prettify-symbols-alist'.
+This gets appended to `prettify-symbols-alist', so set it to nil
+if you want to disable R specific prettification."
+  :group 'ess-R
+  :type '(alist :key-type string :value-type symbol)
+  :package-version '(ess . "25.01.1"))
+
+;;*;; Variables concerning editing behavior
+
+(defcustom ess-filenames-map t
+  "If non-nil, filenames and objects are the same in an attached directory.
+This is not true for DOS and other OS's with limited filename
+lengths. Even if this is set incorrectly, the right things will
+probably still happen, however."
+  :group 'ess-edit
+  :type 'boolean)
+
+(defcustom ess-keep-dump-files t
+  "Variable controlling whether to delete dump files after a successful load.
+If nil: always delete.  If `ask', confirm to delete.  If `check', confirm
+to delete, except for files created with `ess-dump-object-into-edit-buffer'.
+Anything else, never delete.  This variable only affects the behavior
+of `ess-load-file'.  Dump files are never deleted if an error occurs
+during the load."
+  :group 'ess-edit
+  :type '(choice (const :tag "Check" :value check)
+                 (const :tag "Ask" :value ask)
+                 (const :tag "Always keep" :value t)
+                 (const :tag "Always delete" :value nil)))
+
+(defcustom ess-delete-dump-files nil
+  "Non-nil means delete dump files after they are created.
+This applies to dump files created with
+`ess-dump-object-into-edit-buffer', only.
+
+Boolean flag which determines what to do with the dump files
+generated by \\[ess-dump-object-into-edit-buffer], as follows:
+
+        If non-nil: dump files are deleted after each use, and so appear
+only transiently. The one exception to this is when a loading error
+occurs, in which case the file is retained until the error is
+corrected and the file re-loaded.
+
+        If nil: dump files are not deleted, and backups are kept
+as usual.  This provides a simple method for keeping an archive of S
+functions in text-file form.
+
+Auto-save is always enabled in dump-file buffers to enable recovery
+from crashes.
+
+This is useful to prevent source files being created for objects
+you don't actually modify.  Once the buffer is modified and saved
+however, the file is not subsequently deleted unless
+`ess-keep-dump-files' is nil, and the file is successfully loaded
+back into S."
+  :group 'ess-edit
+  :type 'boolean)
+
+(defcustom ess-fill-calls t
+  "If non-nil, refilling inside a call arranges arguments.
+In other words, refilling a paragraph inside a function or
+indexing call will arrange the arguments according to
+`fill-column' as in:
+
+  fun_call(argument1, argument2,
+           argument3, argument4)
+
+
+Refilling repeatedly cycles through different styles and
+eventually to the original formatting.
+
+ The second style formats according to one argument per line:
+
+  fun_call(argument1,
+           argument2,
+           argument3,
+           argument4)
+
+When `ess-fill-calls-newlines' is t, the second style becomes:
+
+  fun_call(
+      argument1,
+      argument2,
+      argument3,
+      argument4
+  )
+
+
+Setting `ess-offset-arguments' to `prev-line' or `prev-call'
+activates a third style. It keeps one argument per line except
+for the first N arguments. N is controlled with a prefix. For
+example, calling \\[fill-paragraph] three times sets N to 1 while
+calling \\[fill-paragraph] twice then \\[universal-argument] 2
+\\[fill-paragraph] sets N to 2. Here what the default produces:
+
+  fun_call(argument1,
+      argument2,
+      argument3,
+      argument4,
+      argument5
+  )
+
+This style is useful for refilling R6 or ggproto class
+definitions.
+
+
+The blinking of the refilled region can be disabled with
+`ess-blink-refilling'."
+  :group 'ess-edit
+  :type 'boolean)
+
+(defcustom ess-fill-continuations t
+  "Controls filling of continuations.
+If non-nil, refilling a paragraph inside a continuation of
+statements (expressions separated by operators) will arrange all
+its elements, never going past `fill-column'.
+
+  lm(outcome ~ pred1 + pred2 +
+       pred3 + pred4, data)
+
+Refilling repeatedly cycles through different styles and
+eventually to the original formatting.
+
+The second style lay out the statements according to one
+expression per line:
+
+  lm(outcome ~
+       pred1 +
+       pred2 +
+       pred3 +
+       pred4, data)
+
+The blinking of the refilled region can be disabled with
+`ess-blink-refilling'."
+  :group 'ess-edit
+  :type 'boolean)
+
+(defcustom ess-fill-calls-newlines nil
+  "When non-nil, refilling may place newlines before and after delimiters.
+When non-nil, the second refilling style produces newlines
+after and before the opening and closing delimiters. This is
+intended for example for dplyr-style code:
+
+  fun_call(
+      argument1,
+      argument2,
+      argument3,
+      argument4
+  )
+
+Note that this setting is temporary and likely to be replaced in
+a future ESS version by a more comprehensive and flexible way to
+set refill styles."
+  :group 'ess-edit
+  :type 'boolean)
+
+(defcustom ess-blink-refilling t
+  "When non-nil, refilling blinks the filling region."
+  :group 'ess-edit
+  :type 'boolean)
+
+(define-obsolete-variable-alias 'ess-mode-silently-save 'ess-save-silently "ESS 19.04")
+(defcustom ess-save-silently 'auto
+  "If non-nil, possibly save buffers without asking.
+If t, save without asking. If \\='auto, save without asking if
+either `compilation-ask-about-save' or variable `auto-save-visited-mode'
+is non-nil. Affects `ess-save-file'."
+  :group 'ess-edit
+  :type '(choice (const :tag "Do not save without asking." :value nil)
+                 (const :tag "Use compilation-ask-about-save and auto-save-visited-mode."
+                        :value auto)
+                 (const :tag "Save without asking." :value t))
+  :package-version '(ess . "25.01.1"))
+
+;;*;; Variables controlling editing
+
+;;;*;;; Edit buffer processing
+(defcustom ess-function-template " <- function( )\n{\n\n}\n"
+  "If non-nil, function template used when editing nonexistent objects.
+
+The edit buffer will contain the object name in quotes, followed by
+this string. Point will be placed after the first parenthesis or
+bracket."
+  :group 'ess-edit
+  :type 'string)
+
+;;;*;;; Indentation parameters
+
+(define-obsolete-variable-alias 'ess-tab-always-indent 'tab-always-indent "ESS 19.04")
+
+(define-obsolete-variable-alias 'ess-indent-level 'ess-indent-offset "15.09")
+(defvar ess-indent-offset 2
+  "Main indentation offset that is commonly inherited by other offsets.
+See `ess-style-alist' for all available offsets.")
+;;;###autoload
+(put 'ess-indent-offset 'safe-local-variable #'numberp)
+
+
+(defvar ess-offset-arguments 'open-delim
+  "Indent for arguments of function calls or indexing brackets.
+This variables has an effect only when the ( or [ are not
+directly followed by a new line. See
+`ess-offset-arguments-newline' for indentation after closing
+newline.
+
+When set to `open-delim', arguments are indented relative to the
+opening parenthesis of the closest function call:
+
+  object <- call(argument, other_call(argument,
+                                      other_argument))
+
+
+When set to `prev-call', arguments are indented relative to the
+closest function call:
+
+  object <- call(argument, other_call(argument,
+                               other_argument))
+
+
+When set to `prev-line', arguments are indented relative to the
+preceding line:
+
+  object <- call(argument, other_call(argument,
+      other_argument))
+
+This setting can also be set to a list containing the the offset
+type and the offset size, such as `'(prev-call 2)'. Otherwise,
+`ess-indent-offset' is used as a default. See `ess-style-alist'
+for other offsets controlling indentation.")
+
+(define-obsolete-variable-alias 'ess-arg-function-offset-new-line 'ess-offset-arguments-newline "15.09")
+(defvar ess-offset-arguments-newline 'prev-call
+  "Indent of arguments when ( or [ is followed by a new line.
+
+When set to `open-delim', arguments on a new line are indented
+relative to the opening parenthesis of the closest function call:
+
+  object <- call(argument, other_call(
+                                      argument,
+                                      other_argument
+                                      ))
+
+
+When set to `prev-call', arguments on a new line are indented relative to
+the closest function call:
+
+  object <- call(argument, other_call(
+                               argument,
+                               other_argument
+                           ))
+
+You can control the details of indentation at `prev-call' with
+`ess-indent-from-lhs' and `ess-indent-from-chain-start'.
+
+
+When set to `prev-line', arguments on a new line are indented
+relative to the preceding line:
+
+  object <- call(argument, other_call(
+      argument,
+      other_argument
+  ))
+
+This setting can also be set to a list containing the the offset
+type and the offset size, such as `'(prev-call 2)'. Otherwise,
+`ess-indent-offset' is used as a default. See `ess-style-alist'
+for other offsets controlling indentation.")
+
+(defvar ess-offset-block 'prev-line
+  "Controls indentation for blocks.
+A block is usually declared with braces but a statement wrapped
+in anonymous parentheses is also considered a block. This offset
+can be either `prev-call', `prev-line' or `open-delim'.
+
+When set to `open-delim', blocks are indented relative to the
+opening parenthesis of the closest function call:
+
+  call(argument, other_call(parameter = {
+                                stuff
+                            }, {
+                                stuff
+                            }))
+
+  call(argument, lapply(data, function(x) {
+                            body
+                        }))
+
+
+When set to `prev-call', blocks are indented relative to the
+closest function call:
+
+  call(argument, other_call(parameter = {
+                     stuff
+                 }, {
+                     stuff
+                 }))
+
+  call(argument, lapply(data, function(x) {
+                     body
+                 }))
+
+You can control the details of indentation at `prev-call' with
+`ess-indent-from-lhs' and `ess-indent-from-chain-start'.
+
+
+When set to `prev-line', blocks are indented relative to the
+preceding line:
+
+  call(argument, other_call(parameter = {
+      stuff
+  }, {
+      stuff
+  }))
+
+  call(argument, lapply(data, function(x) {
+      body
+  }))
+
+This setting can also be set to a list containing the the offset
+type and the offset size, such as `'(prev-call 2)'. Otherwise,
+`ess-indent-offset' is used as a default. See `ess-style-alist'
+for other offsets controlling indentation.")
+
+(define-obsolete-variable-alias 'ess-first-continued-statement-offset 'ess-offset-continued "15.09")
+(define-obsolete-variable-alias 'ess-continued-statement-offset 'ess-offset-continued "15.09")
+(defvar ess-offset-continued 'straight
+  "This setting controls indentation of continued statements.
+That is, consecutive statements separated by operators.
+
+When set to \\='straight, continued statements are indented as follows:
+
+  object %>%
+      some_function() %>%
+      other_function()
+
+When set to \\='cascade:
+
+  object %>%
+      some_function() %>%
+          other_function()
+
+The \\='straight and \\='cascade settings are actually equivalent to
+\\='(straight . t) and \\='(cascade . t), where t represents the
+base indent size. More generally, you can supply \\='(straight . N)
+to control the size of indentation.
+
+See `ess-style-alist' for for an overview of ESS indentation.")
+
+(defvar ess-align-nested-calls '("ifelse")
+  "List of strings for which `ess-offset-arguments-newline' is ignored.
+These calls will be vertically aligned instead. For example, if
+`ifelse' is a member of the list, nested ifelse calls are
+indented like this:
+
+    object <- ifelse(condition1, out1,
+              ifelse(condition2, out2, out3))
+
+See `ess-style-alist' for for an overview of ESS indentation.")
+
+(defvar ess-align-arguments-in-calls '("function[ \t]*(")
+  "A list of regexes where `ess-offset-arguments' is ignored.
+List of regexes specifying the calls where `ess-offset-arguments'
+should have no effect on function declarations. The arguments of
+those calls will be aligned from the opening parenthesis.
+
+By default, function declarations are overridden. If for example
+`ess-offset-arguments' is set to `prev-line', then function calls
+are normally indented as in:
+
+  some_function(argument1,
+      argument2, argument3
+  )
+
+However, the parameters of function declarations will be
+vertically aligned:
+
+  fun <- function(argument1,
+                  argument2
+                  argument3) {
+      body
+  }
+
+See `ess-style-alist' for further details.")
+
+(defvar ess-align-continuations-in-calls t
+  "Whether continuations inside calls are indented from the opening delimiter.
+This produces the following indentation:
+
+  10 + (1 + 2 +
+        3 + 4)
+  object[variable1 +
+         variable2]
+
+  if (test1 || test2 ||
+      test3 || test4) {
+      any(test5 &
+          test6)
+  }
+
+instead of
+
+  10 + (1 + 2 +
+            3 + 4)
+  object[variable1 +
+             variable2]
+
+  if (test1 || test2 ||
+        test3 || test4) {
+      any(test5 &
+            test6)
+  }
+
+Definition operators (`<-', `=', `:=' and `~') still trigger an
+indentation in all cases. Also, operators at top level and in
+curly brackets are not affected by this setting and always induce
+an offset:
+
+  {
+      var1 +
+          var2
+  }
+
+See `ess-style-alist' for for an overview of ESS indentation.")
+
+(defvar ess-align-blocks '(control-flow)
+  "List of block types for which `ess-offset-blocks' is ignored.
+The overridden blocks are vertically aligned. The list can
+contain either or both of the symbols `control-flow' and
+`fun-decl'.
+
+With `control-flow', if, else for and while blocks will always be
+aligned vertically. With `fun-decl', the body of a function
+declaration will always be aligned with the call to
+`function'.")
+
+(define-obsolete-variable-alias 'ess-arg-function-offset 'ess-indent-from-lhs "15.09")
+(defvar ess-indent-from-lhs '(arguments fun-decl-opening)
+  "List of elements that are indented from the left side of an assignment.
+The list accepts the symbol `arguments' and `fun-decl-opening'.
+
+For arguments, this setting only has an effect for offsets set to
+`prev-call'. When set, this indentation is produced:
+
+  some_function(parameter = other_function(
+                                argument
+                            ))
+
+  object <- some_function(
+                argument1,
+                argument2
+            )
+
+instead of:
+
+  some_function(parameter = other_function(
+                    argument
+                ))
+
+  object <- some_function(
+      argument1,
+      argument2
+  )
+
+
+`fun-decl-opening' refers to the opening curly following a function
+declaration. Setting it produces:
+
+  object <-
+      function(argument)
+  {
+      body
+  }
+
+instead of:
+
+  object <-
+      function(argument)
+      {
+          body
+      }
+
+This is useful when (a) you have a long function name and want to
+break a line after `<-' so that you have room to lay out the
+arguments within `fill-column' characters; (b) you still want to
+align the function body from the LHS to save horizontal space.
+
+See `ess-style-alist' for for an overview of ESS indentation.")
+
+(defvar ess-indent-from-chain-start t
+  "When non-nil, chained calls are treated as if they were one call.
+Indentation will start from the first one. This setting only has
+an effect for offsets set to `prev-call' or block offsets set to
+`opening-delim'.
+
+If nil:
+
+  some_function(other_function(
+                    argument
+                ))
+
+If t:
+
+  some_function(other_function(
+      argument
+  ))
+
+See `ess-style-alist' for for an overview of ESS indentation.")
+
+;;added rmh 2Nov97 at request of Terry Therneau
+(define-obsolete-variable-alias 'ess-fancy-comments 'ess-indent-with-fancy-comments "15.09")
+(defcustom ess-indent-with-fancy-comments t
+  "Non-nil means distinguish between #, ##, and ### for indentation.
+See `ess-style-alist' for for an overview of ESS indentation."
+  :type 'boolean
+  :group 'ess-edit)
+
+;;;*;;; Editing styles
+
+(defvar ess-style-alist
+  `((BSD
+     (ess-indent-offset                . 8)
+     (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
+     (ess-offset-arguments-newline     . ,(default-value 'ess-offset-arguments-newline))
+     (ess-offset-block                 . prev-call)
+     (ess-offset-continued             . ,(default-value 'ess-offset-continued))
+     (ess-align-nested-calls           . ,(default-value 'ess-align-nested-calls))
+     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
+     (ess-align-continuations-in-calls . ,(default-value 'ess-align-continuations-in-calls))
+     (ess-align-blocks                 . ,(default-value 'ess-align-blocks))
+     (ess-indent-from-lhs              . ,(default-value 'ess-indent-from-lhs))
+     (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
+     (ess-indent-with-fancy-comments   . ,(default-value 'ess-indent-with-fancy-comments)))
+
+    (C++
+     (ess-indent-offset                . 4)
+     (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
+     (ess-offset-arguments-newline     . ,(default-value 'ess-offset-arguments-newline))
+     (ess-offset-block                 . prev-call)
+     (ess-offset-continued             . ,(default-value 'ess-offset-continued))
+     (ess-align-nested-calls           . ,(default-value 'ess-align-nested-calls))
+     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
+     (ess-align-continuations-in-calls . ,(default-value 'ess-align-continuations-in-calls))
+     (ess-align-blocks                 . ,(default-value 'ess-align-blocks))
+     (ess-indent-from-lhs              . (arguments))
+     (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
+     (ess-indent-with-fancy-comments   . ,(default-value 'ess-indent-with-fancy-comments)))
+
+    ;; CLB added rmh 2Nov97 at request of Terry Therneau
+    (CLB
+     (ess-indent-offset                . ,(default-value 'ess-indent-offset))
+     (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
+     (ess-offset-arguments-newline     . ,(default-value 'ess-offset-arguments-newline))
+     (ess-offset-block                 . ,(default-value 'ess-offset-block))
+     (ess-offset-continued             . (straight 4))
+     (ess-align-nested-calls           . ,(default-value 'ess-align-nested-calls))
+     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
+     (ess-align-continuations-in-calls . ,(default-value 'ess-align-continuations-in-calls))
+     (ess-align-blocks                 . ,(default-value 'ess-align-blocks))
+     (ess-indent-from-lhs              . ,(default-value 'ess-indent-from-lhs))
+     (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
+     (ess-indent-with-fancy-comments   . ,(default-value 'ess-indent-with-fancy-comments)))
+
+    (GNU
+     (ess-indent-offset                . ,(default-value 'ess-indent-offset))
+     (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
+     (ess-offset-arguments-newline     . (prev-call 4))
+     (ess-offset-block                 . ,(default-value 'ess-offset-block))
+     (ess-offset-continued             . ,(default-value 'ess-offset-continued))
+     (ess-align-nested-calls           . ,(default-value 'ess-align-nested-calls))
+     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
+     (ess-align-continuations-in-calls . ,(default-value 'ess-align-continuations-in-calls))
+     (ess-align-blocks                 . ,(default-value 'ess-align-blocks))
+     (ess-indent-from-lhs              . ,(default-value 'ess-indent-from-lhs))
+     (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
+     (ess-indent-with-fancy-comments   . ,(default-value 'ess-indent-with-fancy-comments)))
+
+    (K&R
+     (ess-indent-offset                . 5)
+     (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
+     (ess-offset-arguments-newline     . ,(default-value 'ess-offset-arguments-newline))
+     (ess-offset-block                 . prev-call)
+     (ess-offset-continued             . ,(default-value 'ess-offset-continued))
+     (ess-align-nested-calls           . ,(default-value 'ess-align-nested-calls))
+     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
+     (ess-align-continuations-in-calls . ,(default-value 'ess-align-continuations-in-calls))
+     (ess-align-blocks                 . ,(default-value 'ess-align-blocks))
+     (ess-indent-from-lhs              . ,(default-value 'ess-indent-from-lhs))
+     (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
+     (ess-indent-with-fancy-comments   . ,(default-value 'ess-indent-with-fancy-comments)))
+
+    ;; added ajr 17.Feb'04 to match "common R" use (== DEFAULT apart from  offset = 4)
+    (RRR
+     (ess-indent-offset                . 4)
+     (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
+     (ess-offset-arguments-newline     . ,(default-value 'ess-offset-arguments-newline))
+     (ess-offset-block                 . ,(default-value 'ess-offset-block))
+     (ess-offset-continued             . ,(default-value 'ess-offset-continued))
+     (ess-align-nested-calls           . ,(default-value 'ess-align-nested-calls))
+     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
+     (ess-align-continuations-in-calls . ,(default-value 'ess-align-continuations-in-calls))
+     (ess-align-blocks                 . ,(default-value 'ess-align-blocks))
+     (ess-indent-from-lhs              . ,(default-value 'ess-indent-from-lhs))
+     (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
+     (ess-indent-with-fancy-comments   . ,(default-value 'ess-indent-with-fancy-comments)))
+
+    (RRR+
+     (ess-indent-offset                . 4)
+     (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
+     (ess-offset-arguments-newline     . ,(default-value 'ess-offset-arguments-newline))
+     (ess-offset-block                 . open-delim)
+     (ess-offset-continued             . ,(default-value 'ess-offset-continued))
+     (ess-align-nested-calls           . ,(default-value 'ess-align-nested-calls))
+     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
+     (ess-align-continuations-in-calls . ,(default-value 'ess-align-continuations-in-calls))
+     (ess-align-blocks                 . ,(default-value 'ess-align-blocks))
+     (ess-indent-from-lhs              . (arguments))
+     (ess-indent-from-chain-start      . nil)
+     (ess-indent-with-fancy-comments   . ,(default-value 'ess-indent-with-fancy-comments)))
+
+    (RStudio
+     (ess-indent-offset                . ,(default-value 'ess-indent-offset))
+     (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
+     (ess-offset-arguments-newline     . prev-line)
+     (ess-offset-block                 . ,(default-value 'ess-offset-block))
+     (ess-offset-continued             . ,(default-value 'ess-offset-continued))
+     (ess-align-nested-calls           . nil)
+     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
+     (ess-align-continuations-in-calls . nil)
+     (ess-align-blocks                 . nil)
+     (ess-indent-from-lhs              . (arguments))
+     (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
+     (ess-indent-with-fancy-comments   . nil))
+
+    (RStudio-
+     (ess-indent-offset                . ,(default-value 'ess-indent-offset))
+     (ess-offset-arguments             . prev-line)
+     (ess-offset-arguments-newline     . prev-line)
+     (ess-offset-block                 . ,(default-value 'ess-offset-block))
+     (ess-offset-continued             . ,(default-value 'ess-offset-continued))
+     (ess-align-nested-calls           . nil)
+     (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
+     (ess-align-continuations-in-calls . nil)
+     (ess-align-blocks                 . nil)
+     (ess-indent-from-lhs              . (arguments))
+     (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
+     (ess-indent-with-fancy-comments   . nil))
+
+    (DEFAULT
+      (ess-indent-offset                . ,(default-value 'ess-indent-offset))
+      (ess-offset-arguments             . ,(default-value 'ess-offset-arguments))
+      (ess-offset-arguments-newline     . ,(default-value 'ess-offset-arguments-newline))
+      (ess-offset-block                 . ,(default-value 'ess-offset-block))
+      (ess-offset-continued             . ,(default-value 'ess-offset-continued))
+      (ess-align-nested-calls           . ,(default-value 'ess-align-nested-calls))
+      (ess-align-arguments-in-calls     . ,(default-value 'ess-align-arguments-in-calls))
+      (ess-align-continuations-in-calls . ,(default-value 'ess-align-continuations-in-calls))
+      (ess-align-blocks                 . ,(default-value 'ess-align-blocks))
+      (ess-indent-from-lhs              . ,(default-value 'ess-indent-from-lhs))
+      (ess-indent-from-chain-start      . ,(default-value 'ess-indent-from-chain-start))
+      (ess-indent-with-fancy-comments   . ,(default-value 'ess-indent-with-fancy-comments))))
+
+  "Predefined formatting styles for ESS code.
+Use `ess-set-style' to apply a style in all R buffers. The values of
+all styles except OWN are fixed. To change the value of variables
+in the OWN group, customize the variable `ess-own-style-list'.
+DEFAULT style picks default (aka global) values from ESS
+indentation variables. In addition, ESS provides many indentation
+styles, the most important being the RRR and the RStudio
+variants.
+
+RRR is the common R style that adheres closely to R internal
+standards. RRR+ is the same except it also aligns blocks in
+function calls with the opening delimiter, producing more
+indentation. The C++ style (named like this for historical
+reasons rather than any resemblance to existing C++ indentation
+schemes) is halfway between these two styles and indent block
+arguments from the start of the surrounding function's name.
+
+The RStudio style closely mimics the indentation of the RStudio
+editor. RStudio- is the same except it does not align arguments
+in function calls, which corresponds to the settings of some
+RStudio users.
+
+ESS indentation is fully specified by the following offsets and
+variables. See the documentation of these variables for examples.
+
+Offsets:
+
+ - `ess-indent-offset': main offset inherited by other settings
+
+ - `ess-offset-arguments': offset type for function and bracket
+   arguments
+
+ - `ess-offset-arguments-newline': offset type of arguments
+   when ( or [ is followed by a new line.
+
+ - `ess-offset-block': offset type for brace and anonymous
+   parenthesis blocks
+
+ - `ess-offset-continued': offset type for continuation lines in
+   multiline statements
+
+
+Overrides (implies vertical alignment):
+
+ - `ess-align-nested-calls': functions whose nested calls
+   should be aligned.
+
+ - `ess-align-arguments-in-calls': calls where
+   `ess-offset-arguments' should be ignored
+
+ - `ess-align-continuations-in-calls': whether to ignore
+   `ess-offset-continued' in calls.
+
+ - `ess-align-blocks': whether to ignore `ess-offset-blocks' for
+   function declarations or control flow statements.
+
+
+Control variables:
+
+ - `ess-indent-from-lhs': whether to indent arguments from
+   left-hand side of an assignment or parameter declaration.
+
+ - `ess-indent-from-chain-start': whether to indent arguments from
+   the first of several consecutive calls.
+
+ - `ess-indent-with-fancy-comments': whether to indent #, ## and
+   ### comments distinctly.")
+
+(defun ess-add-style (key entries)
+  "Add a new style to `ess-style-list'.
+The new style has KEY and ENTRIES. Remove any existing entry with
+the same KEY before adding the new one."
+  (setq ess-style-alist (assq-delete-all key ess-style-alist))
+  (add-to-list 'ess-style-alist (cons key entries)))
+
+(defcustom ess-own-style-list (cdr (assoc 'RRR ess-style-alist))
+  "Indentation variables for your own style.
+Set `ess-style' to \='OWN to use these values. To change
+these values, use the customize interface. See the documentation
+of each variable for its meaning."
+  :group 'ess-edit
+  :type 'alist
+  :initialize #'custom-initialize-set
+  :set (lambda (symbol value)
+         (set symbol value)
+         (ess-add-style 'OWN value)))
+
+;;;###autoload
+(put 'ess-style 'safe-local-variable #'symbolp)
+
+(define-obsolete-variable-alias 'ess-default-style 'ess-style "ESS 19.04")
+(defcustom ess-style 'RRR
+  "Current ESS indentation style, see `ess-style-alist' for more.
+See the variable `ess-style-alist' for how these groups (RRR,
+DEFAULT, GNU, BSD, ...) map onto different settings for
+variables. OWN style is defined in `ess-own-style-list' and you
+can customize it to your needs. DEFAULT style picks default (aka
+global) values from ESS indentation variables.
+
+Prefer `ess-set-style' to set the current style. This variable
+has an effect if set before a buffer is visited (e.g. in your
+Emacs initialization file) or as a file or directory local
+variable (see Info node `(Emacs) File Variables'."
+  :type '(choice (const OWN)
+                 (const GNU)
+                 (const BSD)
+                 (const C++)
+                 (const CLB)
+                 (const K&R)
+                 (const RRR)
+                 (const RRR+)
+                 (const RStudio)
+                 (const RStudio-)
+                 (const DEFAULT))
+  :group 'ess-edit
+  :safe #'symbolp)
+
+;;*;; Variables controlling behavior of dump files
+
+(defcustom ess-source-directory
+  (or (getenv "TMPDIR") (getenv "TMP") (getenv "TEMP") temporary-file-directory)
+  "Directory in which to place dump files.
+This can be a string (an absolute directory name ending in a slash) or
+a lambda expression of no arguments which will return a suitable string
+value.  The lambda expression is evaluated with the process buffer as the
+current buffer.
+
+This always dumps to a sub-directory (\".Src\") of the current ess
+working directory (i.e. first elt of search list)."
+  :group 'ess-edit
+  :type 'directory
+  :package-version '(ess . "25.01.1"))
+
+(defvar ess-dump-filename-template nil
+  "Internal. Initialized by dialects.")
+
+(defcustom ess-dump-filename-template-proto (concat (user-login-name) ".%s.S")
+  "Prototype template for filenames of dumped objects.
+The ending `S' is replaced by the current \\[ess-suffix], to give
+`ess-dump-filename-template' when an inferior ESS process starts.
+
+By default, gives filenames like `user.foofun.S', so as not to clash with
+other users if you are using a shared directory. Other alternatives:
+\"%s.S\" ; Don't bother uniquifying if using your own directory(ies)
+\"dumpdir\"; Always dump to a specific filename. This makes it impossible
+to edit more than one object at a time, though.
+ (make-temp-name \"scr.\") ; Another way to uniquify"
+  ;; MM: The last 3-4 lines above suck (I don't understand them) -- FIXME --
+
+  :group 'ess-edit
+  :type 'string)
+
+(defcustom ess-pre-run-hook nil
+  "Hook to call before starting up ESS.
+Good for setting up your directory."
+  :group 'ess-hooks
+  :type 'hook)
+
+(defcustom ess-post-run-hook nil
+  "Hook to call just after the ESS process starts up.
+Currently this should not be used to interact with the inferior
+process because this hook runs too early, before the inferior
+mode had a chance to properly start up the process. To interact
+with the process, you must use a mode-specific hook like
+`ess-r-post-run-hook'."
+  :group 'ess-hooks
+  :type 'hook)
+
+(defcustom ess-send-input-hook nil
+  "Hook called just before line input is sent to the process."
+  :group 'ess-hooks
+  :type 'hook)
+
+;; ---- ./ess-roxy.el : ------------
+
+(defcustom ess-roxy-package "roxygen2"
+  "The name of the R package to use for Roxygen."
+  :group 'ess-roxy
+  :type 'string)
+
+(defcustom ess-roxy-tags-noparam '("export" "noRd")
+  "The tags used in roxygen fields that can be used alone.
+Used to decide highlighting and tag completion."
+  :group 'ess-roxy
+  :type '(repeat string))
+
+(defcustom ess-roxy-tags-param '("author" "aliases" "concept" "details"
+                                 "example" "examples" "examplesIf"
+                                 "format" "keywords"
+                                 "method" "exportMethod"
+                                 "name" "note" "param"
+                                 "include" "references" "return" "returns"
+                                 "seealso" "source" "docType"
+                                 "title" "TODO" "usage" "import"
+                                 "exportClass" "exportPattern"
+                                 "exportS3Method" "S3method"
+                                 "inherit" "inheritParams" "inheritSection"
+                                 "importFrom" "importClassesFrom"
+                                 "importMethodsFrom" "useDynLib"
+                                 "rawNamespace"
+                                 "rdname" "section" "slot" "description"
+                                 "md" "eval" "evalNamespace" "family")
+  "The tags used in roxygen fields that require a parameter.
+Used to decide highlighting and tag completion."
+  :group 'ess-roxy
+  :type '(repeat string))
+
+(defcustom ess-roxy-template-alist
+  (list (cons "description"  ".. content for \\description{} (no empty lines) ..")
+        (cons "details" ".. content for \\details{} ..")
+        (cons "title" "")
+        (cons "param"  "")
+        (cons "return" "")
+        (cons "author" ess-user-full-name))
+  "The tags and defaults to insert when creating empty templates.
+Param is a place holder for where to enter
+parameters. Description and details do not use @ tags, but are
+instead placed at the beginning of the entry (and should
+therefore also be at the beginning of this template to give
+syntactically correct roxygen entries)"
+  :group 'ess-roxy
+  :type '(alist :key-type string :value-type string))
+
+(defcustom ess-roxy-fill-param-p nil
+  "When non-nil `ess-roxy-update-entry' fills (wraps) parameters."
+  :group 'ess-roxy
+  :type '(choice (const :tag "Off" nil)
+                 (const :tag "On" t)))
+
+(defcustom ess-roxy-hide-show-p nil
+  "Non-nil means ess-roxy uses function `hs-minor-mode' for block hiding with TAB."
+  :group 'ess-roxy
+  :type '(choice (const :tag "Off" nil)
+                 (const :tag "On" t)))
+
+(defcustom ess-roxy-start-hidden-p nil
+  "Non-nil means all blocks should be hidden from start."
+  :group 'ess-roxy
+  :type '(choice (const :tag "Off" nil)
+                 (const :tag "On" t)))
+
+(defcustom ess-roxy-str "##'"
+  "Prefix string to insert before each line in new roxygen blocks.
+In existing roxygen blocks, the prefix is taken from the line at
+point"
+  :group 'ess-roxy
+  :type 'string)
+
+(defvar ess-roxy-insert-prefix-on-newline t
+  "When non-nil, `ess-roxy-newline' inserts the roxy prefix on newlines.")
+
+\f ; System variables
+
+;; SJE -- this should not be defcustom - user does not set it.
+(defvaralias 'ess-current-process-name 'ess-local-process-name)
+(defvar-local ess-local-process-name nil
+  "The name of the ESS process associated with the current buffer.")
+(put 'ess-local-process-name 'risky-local-variable t)
+(put 'ess-local-process-name 'permanent-local t)
+
+(defcustom ess-switch-to-end-of-proc-buffer t
+  "If non-nil, \\<ess-mode-map>\\[ess-switch-to-inferior-or-script-buffer] goes to the end of the process buffer."
+  :group 'ess
+  :type 'boolean)
+
+(defcustom ess-gen-proc-buffer-name-function 'ess-gen-proc-buffer-name:project-or-simple
+  "Function used for generation of the buffer name of the new ESS processes.
+It should accept one argument PROC-NAME, a string specifying
+internal process name (R, R:2, etc).
+
+Provided default options are:
+
+`ess-gen-proc-buffer-name:simple'
+ *proc*
+
+`ess-gen-proc-buffer-name:directory'
+  *proc:dir*
+`ess-gen-proc-buffer-name:abbr-long-directory'
+  *proc:abbr-long-dir*
+`ess-gen-proc-buffer-name:project-or-simple'
+  *proc:project-root* or *proc*
+`ess-gen-proc-buffer-name:project-or-directory'
+  *proc:project-root* or *proc:dir*
+
+Strategies based on projects default to built-in strategies if
+there is no project root in the current directory."
+  :group 'ess
+  :type '(choice (const :tag "*proc*"     ess-gen-proc-buffer-name:simple)
+                 (const :tag "*proc:dir*" ess-gen-proc-buffer-name:directory)
+                 (const :tag "*proc:abbr-long-dir*" ess-gen-proc-buffer-name:abbr-long-directory)
+                 (const :tag "*proc:project-root* or *proc*"     ess-gen-proc-buffer-name:project-or-simple)
+                 (const :tag "*proc:project-root* or *proc:dir*" ess-gen-proc-buffer-name:project-or-directory)
+                 function)
+  :package-version '(ess . "25.01.1"))
+
+
+(defcustom ess-kermit-command "gkermit -T"
+  "Kermit command invoked by `ess-kermit-get' and `ess-kermit-send'."
+  :group 'ess
+  :type  'string)
+
+(defcustom ess-kermit-prefix "#"
+  "String files must begin with to use kermit file transfer."
+  :group 'ess
+  :type  'string)
+
+(defcustom ess-kermit-remote-directory "."
+  "Buffer local variable that designates remote directory of file."
+  :group 'ess
+  :type  'string)
+(make-variable-buffer-local 'ess-kermit-remote-directory)
+
+;;*;; Regular expressions
+
+(defcustom ess-dumped-missing-re
+  "\\(<-\nDumped\n\\'\\)\\|\\(<-\\(\\s \\|\n\\)*\\'\\)"
+  "Regex determines if dumped objects are replaced by `ess-function-template'.
+
+If a dumped object's buffer matches this re, then it is replaced
+by `ess-function-template'."
+  :group 'ess
+  :type 'regexp)
+
+(defcustom ess-dump-error-re
+  (if (string= ess-language "S") "\nDumped\n\\'"
+    "[Ee]rror")
+  "Regexp used to detect an error when loading a file."
+  :group 'ess
+  :type 'regexp)
+
+(defcustom ess-r-outline-style 'none
+  "Outline convention used by `ess-r-mode'.
+Choose between comment rulers like RStudio (\"### Section title ----\"),
+\"Org-like\" headings (\"### *** Section title\"), or no outline support.
+
+When using the RStudio outline style, `ess-indent-with-fancy-comments'
+is automatically set to nil locally in the buffer. When switching back,
+the original local binding is restored; if the variable was not
+buffer-local, the current global default applies. You can also use
+(setq ess-style \\='RStudio) to achieve the same effect globally."
+  :group 'ess-R
+  :type '(choice (const :tag "No outline support" none)
+                 (const :tag "RStudio comment rulers" RStudio)
+                 (const :tag "Org-Like (### *** headings)" Org-like))
+  :safe #'symbolp)
+
+
+\f ; ess-inf: variables for inferior-ess.
+
+(defvar inferior-ess-own-frame nil
+  "Non-nil means that inferior ESS buffers should start in their own frame.
+This variable is deprecated.
+please add an entry to `display-buffer-alist' instead. See Info
+node `(ess)Customizing startup'. For example:
+
+\(add-to-list \\='display-buffer-alist
+             \\='(\"*R\"
+  (display-buffer-reuse-window display-buffer-pop-up-frame)))")
+(make-obsolete-variable 'inferior-ess-own-frame 'display-buffer-alist "ESS 19.04")
+(make-obsolete-variable 'inferior-ess-frame-alist "It is ignored. Use `display-buffer-alist' and `pop-up-frame-alist' instead." "ESS 19.04")
+(make-obsolete-variable 'inferior-ess-same-window 'display-buffer-alist "ESS 19.04")
+
+(defcustom inferior-ess-jit-lock-chunk-size 10000
+  "Default for (buffer local) `jit-lock-chunk-size' in inferior ESS buffers."
+  :group 'ess-proc
+  :type 'integer)
+
+
+(defvaralias 'inferior-R-program 'inferior-ess-r-program)
+(define-obsolete-variable-alias 'inferior-R-program-name
+  'inferior-ess-r-program "ESS 18.10")
+(define-obsolete-variable-alias 'inferior-ess-r-program-name
+  'inferior-ess-r-program "ESS 18.10")
+(defcustom inferior-ess-r-program (if ess-microsoft-p
+                                      "Rterm"
+                                    "R")
+  "Program name for invoking an inferior ESS with \\[R]."
+  :group 'ess-R
+  :type '(choice (string) file))
+
+(defcustom inferior-R-args ""
+  "String of arguments used when starting R.
+See also `ess-R-readline'."
+  :group 'ess-R
+  :type 'string)
+
+(defcustom ess-R-readline nil
+  "When non-nil, use readline in R.
+nil indicates that \"--no-readline \" should be used as argument
+when starting R. This may very slightly speedup interaction. On
+the other hand, readline is necessary for expansion of
+\"~username/\" in paths. Note that readline interprets
+tabs (tabular characters) in R source files as asking for file
+name completion. This can mess up evaluation completely."
+  :group 'ess-R
+  :type 'boolean)
+
+(defvaralias 'inferior-R-objects-command 'inferior-ess-r-objects-command)
+(defcustom inferior-ess-r-objects-command "print(objects(pos=%d, all.names=TRUE), max=1e6)\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)
+
+(defvar ess-getwd-command nil
+  "Command string retrieving the working directory from the process.")
+
+(defvar ess-setwd-command nil
+  "Command string to set working directory.
+Should contain a formatting %s to be replaced by a
+path (as in `setwd(%s)\\n'.")
+
+(defcustom ess-program-files ;; 32 bit version
+  (if (and ess-microsoft-p
+           (fboundp 'w32-short-file-name))
+      (if (getenv "ProgramW6432")
+          (w32-short-file-name (getenv "ProgramFiles(x86)"));; always 32 on 64 bit OS
+        (w32-short-file-name (getenv "ProgramFiles")))      ;; always 32 on 32 bit OS
+    nil)
+  "Name for 32-bit programs.
+
+Safe (no embedded blanks) 8.3 name for 32-bit programs that works
+across internationalization."
+  :group 'ess
+  :type '(choice (string) (const nil)))
+
+(defcustom ess-program-files-64 ;; 64 bit version
+  (when (and ess-microsoft-p (fboundp 'w32-short-file-name) (getenv "ProgramW6432"))
+    (w32-short-file-name (getenv "ProgramW6432")))
+  "Name for 64-bit programs.
+
+Safe (no embedded blanks) 8.3 name for 64-bit programs that works
+across internationalization."
+  :group 'ess
+  :type '(choice (string) (const nil)))
+
+(defcustom ess-directory-containing-R nil
+  "When non-nil, a directory containing R.
+nil means the search for all occurrences of R on the machine will
+use the default location of the R directory
+ (inside \"c:/Program Files\" in English locale Windows systems).
+Non-nil values mean use the specified location as the
+directory in which \"R/\" is located.  For example, setting
+`ess-directory-containing-R' to \"c:\" will tell ESS to search
+for R versions with path names of the form \"c:/R/R-x.y.z\".
+
+Currently only used when `ess-microsoft-p'.  If you change the
+value of this variable, you need to restart Emacs for it to take
+effect.  It also needs to be set before you load ess-site as its
+value is used once only when ESS is loaded."
+  :group 'ess
+  :type '(choice (directory) (const nil)))
+
+(defcustom ess-rterm-version-paths nil
+  "Stores the full path file names of Rterm versions computed via \\[ess-find-rterm].
+If you have versions of R in locations other than in
+../../R-*/bin/Rterm.exe or ../../rw*/bin/Rterm.exe, relative to
+the directory in the variable `exec-path' containing your default
+location of Rterm, you will need to redefine this variable with a
+`custom-set-variables' statement in your site-start.el or .emacs
+file."
+  :group 'ess-R
+  :type '(repeat string))
+
+(define-obsolete-variable-alias 'inferior-S3-program-name
+  'inferior-S3-program "ESS 18.10")
+(defcustom inferior-S3-program "/disk05/s/S"
+  "Program name for invoking an inferior ESS with S3()."
+  :group 'ess-S
+  :type 'string)
+
+(define-obsolete-variable-alias
+  'inferior-S-elsewhere-program-name
+  'inferior-S-elsewhere-program "ESS 18.10")
+(defcustom inferior-S-elsewhere-program "sh"
+  "Program name to invoke an inferior ESS with S on a different computer."
+  :group 'ess-proc
+  :type 'string)
+
+(defvaralias 'S+6-dialect-name 'S+-dialect-name)
+(defcustom S+-dialect-name "S+"
+  "Name of `dialect' for S-PLUS 6.x and later.
+Easily changeable in a user's `.emacs'."
+  :group 'ess-SPLUS
+  :type 'string)
+
+(define-obsolete-variable-alias 'inferior-S+-program-name
+  'inferior-S+-program "ESS 18.10")
+(defcustom inferior-S+-program
+  (if ess-microsoft-p
+      (concat ess-program-files "/TIBCO/splus82/cmd/Splus.exe")
+    "Splus")
+  "Program name to invoke S+.
+On Unix/Linux, use the Splus executable.  On Windows, the default
+value is correct for a default installation of S-Plus 8.1 and
+with bash as the shell.  For any other version or location,
+change this value in ess-site.el or site-start.el.  Use the 8.3
+version of the path name.  Use double backslashes if you use the
+msdos shell."
+  :group 'ess-SPLUS
+  :type '(choice (string) (file)))
+
+(defvaralias 'inferior-S+6-start-args 'inferior-S+-start-args)
+(defvaralias 'inferior-Splus-args 'inferior-S+-start-args)
+(defcustom inferior-S+-start-args ""
+  "String of arguments used when starting S.
+These arguments are currently passed only to S+6 and higher."
+  :group 'ess-SPLUS
+  :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 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 \\[ess-quit].
+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)))
+
+(define-obsolete-variable-alias 'inferior-SAS-program-name
+  'inferior-SAS-program "ESS 18.10")
+(defcustom inferior-SAS-program "sas"
+  "Program name for invoking an inferior ESS with SAS()."
+  :group 'ess-sas
+  :type '(choice (string) (file)))
+
+(defvaralias 'R-editor 'ess-r-editor)
+(defcustom ess-r-editor "emacsclient"
+  "Editor called by R process with `edit()' command."
+  :group 'ess
+  :type 'string)
+
+(defvaralias 'R-pager 'ess-r-pager)
+(defcustom ess-r-pager 'nil ; Usually nil is correct as ESS and page() cooperate.
+  "Pager called by R process with `page()' command."
+  :group 'ess
+  :type '(choice (const nil) string))
+
+(defcustom S-editor "emacsclient"
+  "Editor called by S process with `edit()' command."
+  :group 'ess
+  :type 'string)
+
+(defcustom S-pager
+  (if ess-microsoft-p "emacsclientw.exe" "emacsclient")
+  "Pager called by S process with `page()' command."
+  :group 'ess
+  :type 'string)
+
+(defvar-local ess-editor nil
+  "Editor command.
+
+Editor by which the process sends information to an Emacs buffer
+for editing and then to be returned to the process.")
+
+(defvar-local ess-pager nil
+  "Pager by which the process sends information to an Emacs buffer.")
+
+(defvar-local inferior-ess-language-start nil
+  "Initialization commands sent to the ESS process.")
+
+(define-obsolete-variable-alias 'inferior-ess-program-name
+  'inferior-ess-program "ESS 18.10")
+(defvar-local inferior-ess-program nil
+  "Default program name for invoking `inferior-ess'.
+The other variables ...-program should be changed, for the
+corresponding program.")
+
+(make-obsolete-variable 'inferior-ess-start-args
+                        "Use the language specific variables like `inferior-R-args'"
+                        "ESS 19.04")
+(defvar inferior-ess-start-args ""
+  "String of arguments passed to the ESS process.
+If you wish to pass arguments to a process, see e.g. `inferior-R-args'.")
+
+(defcustom inferior-ess-pager (if ess-microsoft-p "console" "cat")
+  "Pager to use for reporting help files and similar things."
+  :group 'ess-proc
+  :type 'string)
+
+(defvar-local inferior-ess-primary-prompt "> "
+  "Regular expression used by `ess-mode' to detect the primary prompt.")
+
+(defvar-local inferior-ess-secondary-prompt nil
+  "Regular expression used by `ess-mode' to detect the secondary prompt.
+This is issued by S to continue an incomplete expression.
+Set to nil if language doesn't support secondary prompt.")
+
+(defvar ess-traceback-command nil
+  "Command to generate error traceback.")
+
+;; Need this to recognize prompts of the form  + + + > > >
+;; and "+ . + ", but not "Abcd. "
+(defvar inferior-S-prompt "[]a-zA-Z0-9.[]*[+ ]*> \\(?:[>+.] \\)*"
+  "Regexp used in S and R inferior and transcript buffers for prompt navigation.
+Must not be anchored to BOL.")
+
+;;*;; Variables controlling interaction with the ESS process
+
+(defcustom ess-execute-in-process-buffer nil
+  "Non-nil means the ess-execute- commands output to the process buffer.
+Otherwise, they get their own temporary buffer."
+  :group 'ess-proc
+  :type 'boolean)
+
+(defcustom ess-eval-empty nil
+  "Non-nil means `ess-eval-line*' will send empty lines to the ESS process."
+  :group 'ess-proc
+  :type 'boolean)
+
+(defvaralias 'ess-eval-visibly-p 'ess-eval-visibly)
+
+(defcustom ess-eval-visibly 'nowait
+  "Non-nil means ess-eval- commands display commands in the process buffer.
+If \\='nowait, ESS shows input commands in the process buffer, but
+doesn't wait for the process. Thus all the output is printed
+after the input lines.
+
+If t, ESS waits after each line of the command for the process
+output. This results in a nice sequence of input and output but
+stalls Emacs on long output (like Sys.sleep(5) in R).
+
+If nil, ESS doesn't print input commands and doesn't wait for the
+process.
+
+This variable also affect the evaluation of input code in
+iESS. The effect is similar to the above. If t then ess waits for
+the process output, otherwise not."
+  :group 'ess-proc
+  :package-version '(ess . "25.01.1")
+  :type '(choice (const t) (const nowait) (const nil)))
+
+(defcustom ess-eval-deactivate-mark (fboundp 'deactivate-mark); was nil till 2010-03-22
+  "Non-nil means that after ess-eval- commands the mark is deactivated."
+  :group 'ess-proc
+  :type 'boolean)
+
+(defcustom ess-use-R-completion t
+  "Non-nil means use R-builtin completion mechanism when available."
+  :group 'ess-proc
+  :type 'boolean)
+
+(defcustom ess-sleep-for-shell (if ess-microsoft-p 5 1)
+  "Pause before sending output to the shell."
+  :group 'ess-proc
+  :type  'number)
+
+\f ; System variables
+;; VS[06-04-2016]: fixme: move all inf vars into ess-inf.el.
+
+;;*;; Variables relating to multiple processes
+
+(defvar-local ess--mode-line-process-indicator '("" ess-local-process-name)
+  "List of ESS mode-line indicators.
+Local in process buffers and must start with a string. Changes of
+this variable are automatically reflected in mode-lines of the
+process and all associated with it buffers.
+
+Each symbol must evaluate to one of the standard mode line
+objects. See info node `(elisp)Mode Line Data').  Add a symbol
+with `add-to-list' and remove with `delq'. Note that the symbols
+which are part of this list should better have
+\\='risky-local-variable property set to t, otherwise the text
+properties are not displayed.
+
+External utilities such as `ess-tracebug' and `ess-developer'
+customize this variable to indicate changes in the process
+status.")
+(put 'ess--mode-line-process-indicator 'risky-local-variable t)
+
+(defvar-local ess--local-mode-line-process-indicator '("")
+  "List of local process indicators.
+See `ess--mode-line-process-indicator' for how to set it.
+
+This is an internal variable used by tools like `ess-developer'
+and `ess-tracebug'.")
+(put 'ess--local-mode-line-process-indicator 'risky-local-variable t)
+
+;;*;; Inferior ESS commands
+
+(defvar-local ess-load-command "source('%s')\n"
+  "Dialect specific format-string for building the ess command to load a file.
+
+This format string should use %s to substitute a file name and should
+result in an ESS expression that will command the inferior ESS to load
+that file.")
+
+(defvar-local ess-eval-command nil
+  "Dialect specific format-string for building the command to evaluate a string.
+
+It is usually faster to send a string to remote processes than a
+file.  The latter involves Tramp and can be quite slow.  When
+possible, a dialect should implement that command and use it
+preferentially.
+
+This format string should use %s as a placeholder for the string
+to be evaluated and, optionally, %f for the file name to be
+reported in the error references.
+
+The resulting command should not echo code or print any
+transitory output.  See also `ess-eval-visibly-command' and
+`ess-eval-visibly-noecho-command'.")
+
+(defvar-local ess-build-eval-message-function nil
+  "Dialect-specific function for formatting an evaluation message.")
+
+(defcustom inferior-ess-dump-command "dump(\"%s\",file=\"%s\")\n"
+  "Format-string for building the ess command to dump an object into a file.
+Use first %s to substitute an object name.
+Use second %s to substitute the dump file name."
+  :group 'ess-command
+  :type 'string)
+
+(defvar-local inferior-ess-help-command "help(\"%s\")\n"
+  "Format-string for building the ESS command to ask for help on an object.
+This format string should use %s to substitute an object name.")
+
+(defcustom inferior-ess-r-help-command ".ess.help('%s')\n"
+  "Format-string for building the R command to ask for help on an object.
+This format string should use %s to substitute an object name.
+If set, changes will take effect when next R session is started."
+  :group 'ess-command
+  :type 'string)
+
+(defvar-local inferior-ess-exit-command "q()\n"
+  "Format-string for building the ess command to exit.
+This format string should use %s to substitute an object name.")
+
+(defvar-local 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")
+
+(defcustom inferior-ess-safe-names-command
+  "tryCatch(base::print(base::names(%s), max=1e6), error=function(e){})\n"
+  "Format string for ESS command to extract names from an object *safely*.
+
+%s is replaced by an \"object name\" -- usually a list or data
+frame, but in R also e.g., `package:stats'."
+  :group 'ess-command
+  :type 'string)
+
+;;*;; Regular expressions
+(defvar-local inferior-ess-prompt nil
+  "The regular expression  used for recognizing prompts.
+
+It is always used in transcript mode.  In inferior ess mode it is
+used only if `comint-use-prompt-regexp' is t.
+
+If not set in language's customize-alist it is constructed at run time
+from `inferior-ess-primary-prompt' and `inferior-ess-secondary-prompt'.")
+
+
+(defvar-local ess-change-sp-regexp ""
+  "The regexp for matching the S/R/.. commands that change the search path.")
+
+(defvar ess-S+-change-sp-regexp
+  "\\(attach(\\([^)]\\|$\\)\\|detach(\\|collection(\\|library(\\|module(\\|source(\\)"
+  "The regexp for matching the S-plus commands that change the search path.")
+
+(defvaralias 'ess-R-change-sp-regexp 'ess-r-change-sp-regexp)
+(defvar ess-r-change-sp-regexp
+  "\\(attach(\\([^)]\\|$\\)\\|detach(\\|library(\\|require(\\|source(\\)"
+  "The regexp for matching the R commands that change the search path.")
+
+;;*;; Process-dependent variables
+
+(defvar-local ess-sl-modtime-alist nil
+  "Alist of modification times for all ess directories accessed this session.")
+
+(defvar-local ess-prev-load-dir/file nil
+  "Cached value for `ess-load-file'.
+
+This symbol saves the (directory . file) pair used in the last
+`ess-load-file' command.  Used for determining the default in the next one.")
+
+(defvar-local ess-object-list nil
+  ;; This is a list of the currently known object names.  It is
+  ;; current only for one command entry; it exists under the
+  ;; assumption that the list of objects doesn't change while entering
+  ;; a command.
+  "Cache of object names.")
+
+(defvar-local ess-help-topics-list nil
+  ;; List of currently known help topics.
+  "Cache of help topics.")
+
+;;*;; Miscellaneous system variables
+
+;; 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.")
+
+(defvar-local ess-object-name-db nil
+  "Alist of lists of object names, with directory names as keys.
+The file ess-namedb.el is loaded (if it exists) to define this variable.
+See also function `ess-create-object-name-db'.")
+
+;;;*;;; Font-lock support
+
+;; "Reserved Words" -- part 1 --
+(defvar ess-RS-constants
+  '("TRUE" "FALSE" "NA" "NULL" "Inf" "NaN"))
+(defvar ess-R-constants
+  (append ess-RS-constants
+          '("NA_integer_" "NA_real_" "NA_complex_" "NA_character_")))
+(defvar ess-S-constants
+  (append ess-RS-constants
+          '("T" "F")))
+
+(defvar ess-R-keywords
+  '("if" "else" "repeat" "while" "function" "for" "in" "next" "break"
+    "switch" "function" "return" "on.exit" "stop" ".Defunct" "tryCatch"
+    "withRestarts" "invokeRestart"
+    "recover" "browser")
+  "Reserved words or special functions in the R language.")
+
+(defvar ess-r--keystrings
+  '("\\" "\?")
+  "Reserved non-word strings or special functions whose names
+include special characters in the R language.
+
+Similar font-locking usage as `ess-R-keywords', but dedicated to
+strings that should not be treated as `words’ by `regexp-opt' in
+`ess-r--find-fl-keyword'.")
+
+(defvar ess-S-keywords
+  (append ess-R-keywords '("terminate")))
+
+;; only some of these keywords "look like functions but are not":
+(defvar ess-S-non-functions
+  '("if" "for" "function" "while"))
+
+;; first the common ones
+(define-obsolete-variable-alias 'ess-S-modifyiers 'ess-S-modifiers "18.10")
+(defvar ess-S-modifiers
+  '("library" "attach" "detach" "source" "module"
+    "message" "warning"))
+
+(define-obsolete-variable-alias 'ess-R-modifyiers 'ess-R-modifiers "18.10")
+(defvar ess-R-modifiers
+  '("library" "attach" "detach" "source" "require"
+    "setwd" "options" "par" "load" "rm"
+    "message" "warning"  ".Deprecated"
+    "signalCondition" "withCallingHandlers"))
+
+(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-R-assign-ops
+  ;; don't want "=" here which is not only for assign
+  '("<<-" "<-" "->" "->>"))
+(defvar ess-S-assign-ops ess-R-assign-ops)
+
+(defvar ess-R-function-name-regexp
+  (concat "\\("      "\\sw+" "\\)"
+          "[ \t]*"   "\\(<-\\)"
+          "[ \t\n]*" "\\(function\\b\\|\\(\\\\[ \t\n(]+\\)\\)"))
+;; "[ \t\n(]+" after "\\\\" since cannot use "\\b" to bound a non-word
+
+(defvar ess-S-function-name-regexp
+  ess-R-function-name-regexp)
+
+(defvar ess-font-lock-keywords nil
+  "A name of the dialect specific font-lock keywords in the current buffer.
+See `ess-R-font-lock-keywords' for an example. This is an
+internal variable.")
+
+(defvar ess-fl-keyword:fun-calls
+  (cons "\\(\\sw+\\)[\t ]*(" '(1 ess-function-call-face keep))
+  "Font lock for function calls.")
+
+(defvar ess-fl-keyword:numbers
+  (cons "\\b\\.?[0-9]+[.eEL]?[0-9]*\\b" 'ess-numbers-face)
+  "Font lock for numbers.")
+
+(defvar ess-fl-keyword:delimiters
+  (cons "\\s(\\|\\s)" 'ess-paren-face)
+  "Font lock for parenthesis.")
+
+(defvar ess-fl-keyword:=
+  (cons "=" 'ess-paren-face)
+  "Font lock for equal sign (=).")
+
+(defvar ess-fl-keyword:operators
+  (cons "[-=+*></|&]+" 'ess-operator-face)
+  "Operators.")
+
+(defvar ess-S-fl-keyword:modifiers
+  (cons (regexp-opt ess-S-modifiers 'words)
+        'ess-modifiers-face)     ; modify search list or source (i.e. directives)
+  "Font lock keyword R modifiers.")
+
+(defvar ess-S-fl-keyword:fun-defs
+  (cons ess-S-function-name-regexp
+        '(1 font-lock-function-name-face t))
+  "Font-lock function definitions keyword.")
+
+(defvar ess-S-fl-keyword:keywords
+  (cons (regexp-opt ess-S-keywords 'words) 'ess-keyword-face))
+
+(defvar ess-S-fl-keyword:assign-ops
+  (cons (regexp-opt ess-S-assign-ops) 'ess-assignment-face)
+  "Font-lock assign operators.")
+
+(defvar ess-S-fl-keyword:constants
+  (cons (regexp-opt ess-S-constants 'words) 'ess-constant-face)
+  "Font-lock constants keyword.")
+
+(defcustom ess-S-font-lock-keywords
+  '((ess-S-fl-keyword:modifiers . t)
+    (ess-S-fl-keyword:fun-defs  . t)
+    (ess-S-fl-keyword:keywords  . t)
+    (ess-S-fl-keyword:assign-ops . t)
+    (ess-S-fl-keyword:constants . t)
+    (ess-fl-keyword:fun-calls)
+    (ess-fl-keyword:numbers)
+    (ess-fl-keyword:operators)
+    (ess-fl-keyword:delimiters)
+    (ess-fl-keyword:=))
+  "An alist of available font-lock keywords for the S mode.
+The key of each cons cell is a name of the keyword. The value
+should be t or nil to indicate if the keyword is activated by
+default or not."
+  :group 'ess-S
+  :group 'ess-faces
+  :type '(repeat (cons symbol boolean)))
+
+(defvar ess-R-fl-keyword:modifiers
+  '(eval . (cons (concat "\\(" (regexp-opt ess-R-modifiers 'words) "\\)\\s-*(")
+                 '(1 ess-modifiers-face)))
+  "Font-lock keyword R modifiers.
+See `ess-R-modifiers' for the list of modifiers.")
+
+(defvar ess-R-fl-keyword:fun-defs
+  '(eval . (cons ess-R-function-name-regexp
+                 '(1 font-lock-function-name-face nil)))
+  "Font-lock keyword for function names in function definitions.
+When this keyword is on, function names on the left hand side of
+<- are highlighted with `font-lock-function-name-face'.")
+
+(defvar ess-R-fl-keyword:keywords
+  '(ess-r--find-fl-keyword . ess-keyword-face)
+  "Font lock keyword for `ess-R-keywords'.")
+
+(defvar ess-R-fl-keyword:assign-ops
+  '(eval . (cons (regexp-opt ess-R-assign-ops) 'ess-assignment-face))
+  "Font-lock assign operators.
+See `ess-R-assign-ops' for the ops.")
+
+(defvar ess-R-fl-keyword:constants
+  '(eval . (cons (regexp-opt ess-R-constants 'words) 'ess-constant-face))
+  "Font-lock constants keyword.
+See `ess-R-constants' for the list of constants.")
+
+(defvar ess-R-fl-keyword:F&T
+  '("\\b[FT]\\b" . ess-constant-face)
+  "Highlight T and F in addition to TRUE and FALSE in R.")
+
+(defvar ess-R-fl-keyword:%op% nil
+  "Highlight %op% operators.")
+
+(defcustom ess-R-font-lock-keywords
+  '((ess-R-fl-keyword:keywords   . t)
+    (ess-R-fl-keyword:constants  . t)
+    (ess-R-fl-keyword:modifiers  . t)
+    (ess-R-fl-keyword:fun-defs   . t)
+    (ess-R-fl-keyword:assign-ops . t)
+    (ess-R-fl-keyword:%op%       . t)
+    (ess-fl-keyword:fun-calls)
+    (ess-fl-keyword:numbers)
+    (ess-fl-keyword:operators)
+    (ess-fl-keyword:delimiters)
+    (ess-fl-keyword:=)
+    (ess-R-fl-keyword:F&T))
+  "An alist of available font-lock keywords for the R mode.
+The key of each cons cell is a name of the keyword. The value
+should be t or nil to indicate if the keyword is active or not."
+  :group 'ess-R
+  :group 'ess-faces
+  :type '(repeat (cons symbol boolean)))
+
+(defvar ess-S-fl-keyword:prompt
+  (cons (concat "^" inferior-S-prompt) 'comint-highlight-prompt)
+  "Highlight prompts missed by comint.")
+
+(defvar ess-fl-keyword:matrix-labels
+  ;; also matches subsetting
+  (cons "\\[,?[1-9][0-9]*,?\\]" 'ess-matrix-face)
+  "Matrix and vector numeric labels.")
+
+(defvar ess-R-fl-keyword:messages
+  (cons (regexp-opt ess-R-message-prefixes 'enc-paren)
+        'font-lock-warning-face)
+  "Inferior-ess problems or errors.")
+
+(defvaralias 'inferior-R-font-lock-keywords 'inferior-ess-r-font-lock-keywords)
+(defcustom inferior-ess-r-font-lock-keywords
+  '((ess-S-fl-keyword:prompt      . t)
+    (ess-R-fl-keyword:keywords    . t)
+    (ess-R-fl-keyword:constants   . t)
+    (ess-R-fl-keyword:modifiers   . t)
+    (ess-R-fl-keyword:messages    . t)
+    (ess-R-fl-keyword:fun-defs    . t)
+    (ess-R-fl-keyword:assign-ops  . t)
+    (ess-fl-keyword:matrix-labels . t)
+    (ess-fl-keyword:fun-calls)
+    (ess-fl-keyword:numbers)
+    (ess-fl-keyword:operators)
+    (ess-fl-keyword:delimiters)
+    (ess-fl-keyword:=)
+    (ess-R-fl-keyword:F&T))
+  "Font-lock patterns used in `inferior-ess-r-mode' buffers.
+The key of each cons cell is a name of the keyword.  The value
+should be t or nil to indicate if the keyword is active or not."
+  :group 'ess-R
+  :group 'ess-faces
+  :type '(repeat (cons symbol boolean)))
+
+(defvar ess-S-fl-keyword:messages
+  (cons (regexp-opt ess-S-message-prefixes 'enc-paren)
+        'font-lock-warning-face)
+  "Inferior-ess problems or errors.")
+
+(defcustom inferior-S-font-lock-keywords
+  '((ess-S-fl-keyword:prompt    . t)
+    (ess-S-fl-keyword:messages  . t)
+    (ess-S-fl-keyword:modifiers . t)
+    (ess-S-fl-keyword:fun-defs  . t)
+    (ess-S-fl-keyword:keywords  . t)
+    (ess-S-fl-keyword:assign-ops        . t)
+    (ess-S-fl-keyword:constants . t)
+    (ess-fl-keyword:fun-calls)
+    (ess-fl-keyword:numbers)
+    (ess-fl-keyword:operators)
+    (ess-fl-keyword:delimiters)
+    (ess-fl-keyword:=))
+  "Font-lock patterns used in inferior-S-mode buffers.
+The key of each cons cell is a name of the keyword.  The value
+should be t or nil to indicate if the keyword is active by
+default."
+  :group 'ess-S
+  :group 'ess-faces
+  :type '(repeat (cons symbol boolean)))
+
+\f
+;;;*;;; ess-help variables
+
+;; This will never need to be loaded independently of any of the other modules,
+;; but they can all call it so we may as well put it here.
+
+(defcustom ess-help-pop-to-buffer t
+  "If non-nil ess-help buffers are given focus during the display.
+If non-nil, `ess-display-help' uses `pop-to-buffer' to display
+help, otherwise it uses `display-buffer', which does not select
+the help window."
+  :group 'ess-help
+  :type 'boolean)
+
+(defcustom ess-help-own-frame nil
+  "Controls whether ESS help buffers should start in a different frame.
+
+Possible values are:
+   nil: Display help in current frame.
+  \\='one: All help buffers are shown in one dedicated frame.
+     t: Each help buffer gets its own frame.
+
+If this is non-nil,`ess-help-reuse-window' is ignored. The
+parameters of the own frame are stored in
+`ess-help-frame-alist'."
+  :group 'ess-help
+  :type '(choice (const :tag "Display in current frame" nil)
+                 (const :tag "Display in one frame" one)
+                 (const :tag "Always display in a new frame" t)))
+
+(defcustom ess-help-reuse-window t
+  "If t, ESS tries to display new help buffers in the existing help window.
+This variable is ignored if `ess-help-own-frame' is non-nil."
+  :type 'boolean
+  :group 'ess-help)
+
+(defcustom ess-help-frame-alist default-frame-alist
+  "Alist of frame parameters used to create help frames.
+This defaults to `default-frame-alist' and is used only when
+the variable `ess-help-own-frame' is non-nil."
+  :group 'ess-help
+  :type 'alist
+  :package-version '(ess . "25.01.1"))
+
+\f ; Faces
+;;;=====================================================
+
+(defconst comint-highlight-prompt 'comint-highlight-prompt)
+
+(defconst ess-function-call-face 'ess-function-call-face)
+(defface ess-function-call-face
+  '((default (:slant normal :inherit font-lock-function-name-face)))
+  "Font Lock face used to highlight function calls in ess buffers."
+  :group 'ess-faces)
+
+(defconst ess-numbers-face 'ess-numbers-face)
+(defface ess-numbers-face
+  '((default (:slant normal :inherit font-lock-type-face)))
+  "Font Lock face used to highlight numbers in `ess-mode' buffers."
+  :group 'ess-faces)
+
+(defconst ess-operator-face 'ess-operator-face)
+(defface ess-operator-face
+  '((default (:inherit font-lock-constant-face)))
+  "Font Lock face for operators."
+  :group 'ess-faces)
+
+(defconst ess-%op%-face 'ess-%op%-face)
+(defface ess-%op%-face
+  '((default (:inherit ess-operator-face)))
+  "Font Lock face used to highlight %op% operators in `ess-mode' buffers."
+  :group 'ess-faces)
+
+(defconst ess-assignment-face 'ess-assignment-face)
+(defface ess-assignment-face
+  '((default (:inherit font-lock-constant-face)))
+  "Font lock face used to highlight assignment operators."
+  :group 'ess-faces)
+
+(defconst ess-paren-face 'ess-paren-face)
+(defface ess-paren-face
+  '((default (:inherit font-lock-constant-face)))
+  "Font lock face used to highlight parentheses."
+  :group 'ess-faces)
+
+(defconst ess-operator-face 'ess-operator-face)
+(defface ess-operator-face
+  '((default (:inherit font-lock-constant-face)))
+  "Font lock face used to highlight operators."
+  :group 'ess-faces)
+
+(defconst ess-modifiers-face 'ess-modifiers-face)
+(defface ess-modifiers-face
+  '((default (:inherit font-lock-constant-face)))
+  "Font lock face used to highlight modifiers.
+In `R-mode', for example, this includes \"library,\" \"attach,\"
+and others. See `ess-R-modifiers'."
+  :group 'ess-faces)
+
+(defconst ess-constant-face 'ess-constant-face)
+(defface ess-constant-face
+  '((default (:inherit font-lock-type-face)))
+  "Font lock face used to highlight constants.
+In `ess-r-mode', for example, this includes TRUE, FALSE, Inf and
+others. See `ess-R-constants'."
+  :group 'ess-faces)
+
+(defconst ess-matrix-face 'ess-matrix-face)
+(defface ess-matrix-face
+  '((default (:inherit font-lock-constant-face)))
+  "Font lock face used to highlight row/column labels in matrices."
+  :group 'ess-faces)
+
+(defconst ess-keyword-face 'ess-keyword-face)
+(defface ess-keyword-face
+  '((default (:inherit font-lock-keyword-face)))
+  "Font lock face used to highlight reserved keywords.
+In `ess-r-mode', for example, this includes \"while,\" \"if/else\",
+\"function,\" and others. See `ess-R-keywords'."
+  :group 'ess-faces)
+
+(defconst ess-r-control-flow-keyword-face 'ess-r-control-flow-keyword-face)
+(defface ess-r-control-flow-keyword-face
+  '((default (:inherit ess-keyword-face)))
+  "Font lock face used to highlight control flow keywords.
+In `R-mode', for example, this includes \"switch(),\"
+\"tryCatch()\", and \"stop(),\". See
+`ess-R-control-flow-keywords'. By default, these keywords are
+highlighted with the same face as `ess-R-keywords'"
+  :group 'ess-faces)
+
+(defcustom ess-help-kill-bogus-buffers t
+  "Non-nil means kill ESS help buffers immediately if they are \"bogus\"."
+  :group 'ess-help
+  :type 'boolean)
+
+(defvar ess-execute-screen-options-command nil
+  "Dialect specific command run by `ess-execute-screen-options'.")
+
+(defvar-local ess-funargs-command  nil
+  "Dialect specific command to return a list of function arguments.
+See `ess-function-arguments' and .ess_funargs command in R and
+S+ for details of the format that should be returned.")
+
+\f ; System variables
+;;;=====================================================
+;;; Users note: You will rarely have to change these
+;;; variables.
+
+;;*;; Variables relating to ess-help-mode
+
+;;-- ess-help-S-.. and  ess-help-R-.. : in  ess-s-lang.el (are used in ess-inf).
+
+(defvar-local ess-help-sec-keys-alist nil
+  "Alist of (key . string) pairs for use in section searching.")
+
+(defvar-local ess-help-sec-regex nil
+  "Reg(ular) Ex(pression) of section headers in help file.")
+
+\f ; julia-mode
+(define-obsolete-variable-alias 'inferior-julia-program-name
+  'inferior-julia-program "ESS 18.10")
+(defcustom inferior-julia-program (or (executable-find "julia-basic")
+                                      "julia")
+  "Executable for Julia.
+Should be an absolute path to the julia executable."
+  :group 'ess-Julia
+  :type '(choice (string) (file)))
+
+;; FIXME
+(defvar-local ess-mode-completion-syntax-table nil "Completion and help syntax table for `ess-mode'.")
+
+\f ; Buffer local customization stuff
+
+(defcustom ess-error-buffer-name "*ESS-errors*"
+  "Name of buffer to keep process error messages in.
+Created for each process."
+  :group 'ess-proc
+  :type 'string)
+
+(defvar ess-error-regexp-alist nil
+  "List of symbols which are looked up in `compilation-error-regexp-alist-alist'.")
+
+(defcustom ess-write-to-dribble t
+  "Non-nil means write to `ess-dribble-buffer'.
+See also `ess-verbose'."
+  :group 'ess-proc
+  :type 'boolean
+  :package-version '(ess . "25.01.1"))
+
+(defcustom ess-verbose nil
+  "Non-nil means write more information to `ess-dribble-buffer' than usual."
+  :group 'ess-proc
+  :type 'boolean)
+
+(defvar ess-dribble-buffer "*ESS*"
+  "Buffer or name of buffer for printing debugging information.")
+
+(defvar-local ess-local-customize-alist nil
+  "Buffer local settings for proper behavior.
+Used to store the values for passing on to newly created buffers.")
+
+(defvar ess-mode-editing-alist nil
+  "Variable settings for `ess-mode'.")
+
+(defvar-local ess-transcript-minor-mode nil
+  "Non-nil if using `ess-transcript-mode' as a minor mode of some other mode.")
+
+(defvar-local ess-listing-minor-mode nil
+  "Non-nil if using `ess-listing-minor-mode'.")
+
+(defvar ess-STERM nil
+  "Placeholder for dialect-specific STERM.")
+
+(make-obsolete-variable 'ess-S-loop-timeout "It is ignored." "ESS 18.10")
+(make-obsolete-variable 'ess-mode-load-hook "It is ignored." "ESS 18.10")
+(make-obsolete-variable 'ess-speedbar-use-p "It is ignored." "ESS 18.10")
+(make-obsolete-variable 'ess-synchronize-evals "It is ignored." "ESS 18.10")
+(make-obsolete-variable 'ess-eval-visibly-at-end "It is ignored." "ESS 18.10")
+(make-obsolete-variable 'ess-font-lock-mode 'global-font-lock-mode "ESS 18.10")
+(provide 'ess-custom)
+
+;;; ess-custom.el ends here
diff --git a/elpa/ess-20260424.1544/ess-gretl.el b/elpa/ess-20260424.1544/ess-gretl.el
new file mode 100644 (file)
index 0000000..1d79b5d
--- /dev/null
@@ -0,0 +1,579 @@
+;; ess-gretl.el --- ESS gretl mode and inferior interaction  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2022 Free Software Foundation, Inc.
+;; Author: Ahmadou Dicko, Spinu Vitalie and Allin Cottrell
+;; Maintainer: ESS Core Team <ESS-coreNOSPAMr-project.org>
+;; Created: 01-10-2012 (ESS 12.09)
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+;;  start the inferior with M-x gretl.
+
+;;; Code:
+
+(require 'compile); for compilation-* below
+(require 'ess-r-mode)
+
+
+(add-to-list 'auto-mode-alist '("\\.inp\\'" . ess-gretl-mode))
+
+
+(defvar gretl-syntax-table
+  (let ((table (make-syntax-table)))
+    (modify-syntax-entry ?_ "w" table)   ; underscores in words
+    (modify-syntax-entry ?@ "w" table)
+    (modify-syntax-entry ?# "<" table)   ; #  single-line comment start
+    (modify-syntax-entry ?\n ">" table)  ; \n single-line comment end
+    (modify-syntax-entry ?\{ "(} " table)
+    (modify-syntax-entry ?\} "){ " table)
+    (modify-syntax-entry ?\[ "(] " table)
+    (modify-syntax-entry ?\] ")[ " table)
+    (modify-syntax-entry ?\( "() " table)
+    (modify-syntax-entry ?\) ")( " table)
+    (modify-syntax-entry ?\r " "  table)
+    (modify-syntax-entry ?+ "."   table)
+    (modify-syntax-entry ?- "."   table)
+    (modify-syntax-entry ?= "."   table)
+    (modify-syntax-entry ?* "."   table)
+    (modify-syntax-entry ?/ "."   table)
+    (modify-syntax-entry ?> "."   table)
+    (modify-syntax-entry ?< "."   table)
+    (modify-syntax-entry ?& "."   table)
+    (modify-syntax-entry ?| "."   table)
+    (modify-syntax-entry ?! "."   table)
+    (modify-syntax-entry ?\\ "\\" table)
+    (modify-syntax-entry ?\' "."  table)
+    (modify-syntax-entry ?\` "w"  table)
+    (modify-syntax-entry ?\" "\"" table)
+    (modify-syntax-entry ?. "w"   table)
+    (modify-syntax-entry ?_ "w"   table)
+    (modify-syntax-entry ?\% "."  table)
+    (modify-syntax-entry ?\# "<"  table)
+    (modify-syntax-entry ?\n ">"  table)
+    table)
+  "Syntax table for `ess-gretl-mode'.")
+
+;; syntax table that holds within strings
+(defvar ess-gretl-mode-string-syntax-table
+  (let ((table (make-syntax-table)))
+    table)
+  "Syntax table for `ess-gretl-mode' that holds within strings.")
+
+(defcustom gretl-continuation-offset 4
+  "Extra indentation applied to Gretl continuation lines."
+  :type 'integer
+  :group 'ess-gretl)
+
+(defvar gretl-continuation-regexp
+  "[^#%\n]*\\(\\\\\\|\\.\\.\\.\\)\\s-*\\(\\s<.*\\)?$")
+
+(defcustom gretl-continuation-string "\\"
+  "Character string used for Gretl continuation lines.  Normally \\."
+  :type 'string
+  :group 'ess-gretl)
+
+;; (defconst gretl-string-regex
+;;   "\"[^\"]*?\\(\\(\\\\\\\\\\)*\\\\\"[^\"]*?\\)*\"")
+
+(defconst gretl-function-header-regexp
+  (concat "^\\s-*\\<\\(function\\)\\>"
+         "\\([^=;\n]*=[ \t]*\\|[ \t]*\\)\\(\\w+\\)\\>")
+  "Regexp to match a Gretl function header.
+The string `function' and its name are given by the first and third
+parenthetical grouping.")
+
+;; (defconst ess-function-call-regexp
+;;   "\\s\"?\\(\\(\\sw\\|\\s_\\)+\\(<-\\)?\\)\\s\"?*\\s-*("
+;;   "Regexp for function names")
+
+(defvar gretl-command-words
+  '("add" "adf" "anova" "append" "ar" "ar1" "arbond" "arch"
+    "arima" "biprobit" "break" "boxplot" "chow" "clear" "coeffsum" "coint"
+    "coint2" "corr" "corrgm" "cusum" "data" "dataset" "delete" "diff"
+    "difftest" "discrete" "dpanel" "dummify" "duration" "elif" "else" "end"
+    "endif" "endloop" "eqnprint" "equation" "estimate" "fcast" "foreign" "fractint"
+    "freq" "function" "funcerr" "garch" "genr" "gmm" "gnuplot" "graphpg"
+    "hausman" "heckit" "help" "hsk" "hurst" "if" "include" "info"
+    "intreg" "kalman" "kpss" "labels" "lad" "lags" "ldiff" "leverage"
+    "levinlin" "logistic" "logit" "logs" "loop" "mahal" "makepkg" "meantest"
+    "mle" "modeltab" "modprint" "modtest" "mpols" "negbin" "nls" "normtest"
+    "nulldata" "ols" "omit" "open" "orthdev" "outfile" "panel" "pca"
+    "pergm" "textplot" "poisson" "print" "printf" "probit" "pvalue" "quantreg"
+    "qlrtest" "qqplot" "quit" "rename" "reset" "restrict" "rmplot" "run"
+    "runs" "scatters" "sdiff" "set" "setinfo" "setobs" "setmiss" "shell"
+    "smpl" "spearman" "sprintf" "square" "sscanf" "store" "summary" "system"
+    "tabprint" "tobit" "tsls" "var" "varlist" "vartest" "vecm" "vif"
+    "wls" "xcorrgm" "xtab" "debug" "return" "catch" "for" "foreach"
+    "while" "const" "3sls" "liml" "fiml"
+    "sur" "params" "deriv" "orthog" "weights" "series" "scalar")
+  "Commands in Gretl (these names are also reserved).")
+
+(defvar gretl-genr-functions
+ '("abs" "sin" "cos" "tan" "asin" "acos" "atan" "sinh"
+   "cosh" "tanh" "asinh" "acosh" "atanh" "log" "ln" "log10"
+   "log2" "exp" "sqrt" "diff" "ldiff" "sdiff" "lags" "int"
+   "round" "ceil" "floor" "sort" "dsort" "sortby" "ranking" "orthdev"
+   "nobs" "firstobs" "lastobs" "uniform" "normal" "cum" "missing" "ok"
+   "misszero" "lrvar" "quantile" "median" "gini" "zeromiss" "sum" "mean"
+   "min" "max" "sd" "var" "sst" "cnorm" "dnorm" "qnorm"
+   "gammafun" "lngamma" "digamma" "resample" "pnobs" "pmin" "pmax" "pmean"
+   "psd" "hpfilt" "bkfilt" "bwfilt" "fracdiff" "boxcox" "cov" "corr"
+   "movavg" "I" "zeros" "ones" "seq" "replace" "muniform" "mnormal"
+   "sumc" "sumr" "meanc" "meanr" "sdc" "minc" "maxc" "minr"
+   "maxr" "iminc" "imaxc" "iminr" "imaxr" "fft" "ffti" "cmult"
+   "cdiv" "mcov" "mcorr" "mxtab" "cdemean" "cholesky" "psdroot" "inv"
+   "invpd" "ginv" "diag" "transp" "vec" "vech" "unvech" "upper"
+   "lower" "rows" "cols" "det" "ldet" "tr" "onenorm" "infnorm"
+   "rcond" "rank" "qform" "mlag" "qrdecomp" "eigensym" "eigengen" "nullspace"
+   "princomp" "mexp" "fdjac" "BFGSmax" "obsnum" "isseries" "isscalar" "islist"
+   "isstring" "isnull" "nelem" "pdf" "cdf" "invcdf" "pvalue" "critical"
+   "randgen" "urcpval" "values" "mshape" "svd" "mols" "mpols" "mrls"
+   "mread" "mwrite" "selifc" "selifr" "polroots" "dummify" "wmean" "wvar"
+   "wsd" "xpx" "filter" "kfilter" "ksmooth" "ksimul" "trimr" "getenv"
+   "argname" "obslabel" "readfile" "grab" "strstr" "strncmp" "strlen" "sscanf"
+   "varname" "varnum" "tolower" "colnames" "rownames" "ljungbox" "msortby" "lincomb"
+   "imhof" "toepsolv" "diagcat" "xmin" "xmax" "corrgm" "mcovg" "fcstats"
+   "bessel" "fraclag" "mreverse" "deseas" "pergm" "irr" "npv" "logistic"
+   "weekday" "kdensity" "monthlen" "epochday" "setnote" "invmills" "polyfit" "chowlin"
+   "varsimul" "strsplit" "inlist" "errmsg" "isconst" "irf" "inbundle")
+  "Builtin functions for Gretl's genr command.")
+
+
+(defvar gretl-option-flags
+  '("addstats" "all" "anova" "append"
+    "arch" "arma-init" "asymptotic" "auto"
+    "autocorr" "auxiliary" "balanced" "bartlett"
+    "between" "bootstrap" "both" "breusch-pagan"
+    "byobs" "by" "c" "close"
+    "coded" "cols" "column" "comfac"
+    "complete" "conditional" "contiguous" "continue"
+    "continuous" "control" "covariance" "cross"
+    "cross-section" "crt" "csv" "ct"
+    "ctt" "cubes-only" "dat" "database"
+    "dataset" "db" "degrees" "dhansen"
+    "difference" "diffuse" "discrete" "dpdstyle"
+    "drop-empty" "drop-first" "drop-last" "dummy"
+    "dynamic" "equal" "exit" "exponential"
+    "fcp" "fixed-effects" "from-file" "full"
+    "func" "gamma" "geomean" "gls"
+    "gmm" "gnu-R" "gnu-octave" "gph"
+    "gzipped" "hausman-reg" "hessian" "hilu"
+    "impulse-responses" "input" "inst" "integrate"
+    "intervals" "inverse-fit" "iterate" "jackknife"
+    "jbera" "jitter" "jmulti" "kendall"
+    "lags" "lagselect" "lbfgs" "lillie"
+    "liml" "linear-fit" "list" "loess-fit"
+    "log" "loglogistic" "lognormal" "logs"
+    "matrix" "matrix-diff" "medians" "ml"
+    "model1" "multi" "multinomial" "nc"
+    "next" "no-corc" "no-dates" "no-df-corr"
+    "no-gradient-check" "no-header" "no-missing" "no-scaling"
+    "no-stats" "normal" "normality" "notches"
+    "numerical" "odbc" "omit-obs" "one-scale"
+    "opg" "orthdev" "other" "out-of-sample"
+    "output" "overwrite" "p-values" "panel"
+    "panel-vars" "plot" "pooled" "preserve"
+    "print-final" "progress-bar" "progressive" "pwe"
+    "quadratic-fit" "quiet" "quit" "radians"
+    "random" "random-effects" "rank-sum" "raw"
+    "rc" "replace" "restrict" "restructure"
+    "reverse" "robust" "rolling" "row"
+    "rtf" "save" "save-all" "save-ehat"
+    "save-xbeta" "scalars" "seasonals" "send-data"
+    "sign" "signed-rank" "silent" "simple"
+    "simple-print" "single-yaxis" "skip-df" "spearman"
+    "special-time-series" "squares" "squares-only" "stacked-cross-section"
+    "stacked-time-series" "static" "stdresid" "suppress-fitted"
+    "swilk" "system" "t-ratios" "tall"
+    "test-down" "tex" "time-dummies" "time-series"
+    "to-file" "to_file" "traditional" "trend"
+    "two-step" "unequal-vars" "uniform" "unit-weights"
+    "variance-decomp" "vcv" "verbose" "wald"
+    "weibull" "weights" "white" "white-nocross"
+    "with-impulses" "with-lines" "write" "www"
+    "x-12-arima" "y-diff-only" "z-scores" "zeros")
+  "Gretl option flags.")
+
+(defvar gretl-internal-vars
+ '("Fstat" "T" "ahat" "aic" "bic" "chisq" "coeff_ci"
+   "coeff" "compan" "datatype" "df" "dwpval" "ec" "ehat"
+   "error" "ess" "fcast" "fcerr" "gmmcrit" "hausman" "hqc"
+   "h" "jalpha" "jbeta" "jvbeta" "kalman_llt" "kalman_lnl" "kalman_s2"
+   "kalman_t" "kalman_uhat" "llt" "lnl" "mnlprobs" "ncoeff" "nobs"
+   "nscan" "nvars" "obs" "pd" "pvalue" "rho" "rlnl"
+   "rsq" "s00" "s01" "s11" "sample" "sargan" "sigma"
+   "stderr" "stopwatch" "sysA" "sysB" "sysGamma" "t1" "t2"
+   "test" "trsq" "uhat" "unit" "vcv" "version" "vma"
+   "windows" "xlist" "xtxinv" "yhat" )
+  "Model- and dataset-related variables.")
+
+(defconst gretl-block-start-keywords
+  (list "loop" "foreign" "function" "gmm" "if" "system" "mle" "nls" "restrict"))
+
+(defconst gretl-block-other-keywords
+  (list "else" "elif"))
+
+(defconst gretl-block-end-keywords
+  (list "end" "endif" "endloop"))
+
+(defvar gretl-keywords
+  (append gretl-block-start-keywords
+         gretl-block-other-keywords
+         gretl-block-end-keywords
+         '("break"))
+  "Reserved words in Gretl.")
+
+
+(defun gretl-at-keyword (kw-list)
+  ; not a keyword if used as a field name, X.word, or quoted, :word
+  (and (or (= (point) 1)
+          (and (not (equal (char-before (point)) ?.))
+               (not (equal (char-before (point)) ?:))))
+       (not (ess-inside-string-or-comment-p (point)))
+       (not (ess-inside-brackets-p (point)))
+       (member (current-word) kw-list)))
+
+
+(defconst gretl-font-lock-keywords
+  (list
+   ;; Fontify all builtin keywords.
+   (cons (concat "\\<\\(" (regexp-opt gretl-keywords) "\\)\\>")
+        'font-lock-keyword-face)
+   ;; Fontify all option flags.
+   (cons (concat "[ \t]--\\(" (regexp-opt gretl-option-flags) "\\)")
+        'font-lock-constant-face)
+   ;; Fontify all command words.
+   (cons (concat "\\<\\(" (regexp-opt gretl-command-words) "\\)\\>")
+        'font-lock-builtin-face)
+   ;; Fontify all builtin operators.
+   (cons "\\(&\\||\\|<=\\|>=\\|==\\|<\\|>\\|!=\\|!\\)"
+        (if (boundp 'font-lock-builtin-face)
+            'font-lock-builtin-face
+          'font-lock-preprocessor-face))
+   ;; Fontify all internal variables.
+   (cons (concat "\\$\\(" (regexp-opt gretl-internal-vars) "\\)\\>")
+        'font-lock-variable-name-face)
+
+   ;; Fontify all genr functions.
+   (cons (concat "\\<\\(" (regexp-opt gretl-genr-functions) "\\)\\>")
+        'font-lock-variable-name-face)
+   ;; Fontify all function declarations.
+   (list gretl-function-header-regexp
+        '(1 font-lock-keyword-face)
+        '(3 font-lock-function-name-face nil t)))
+  "Additional Gretl expressions to highlight.")
+
+
+(defvar gretl-block-begin-regexp
+  (concat "\\<\\(" (regexp-opt gretl-block-start-keywords) "\\)\\>"))
+
+(defvar gretl-block-else-regexp
+  (concat "\\<\\(" (regexp-opt gretl-block-other-keywords) "\\)\\>"))
+
+(defvar gretl-block-end-regexp
+  (concat "\\<\\(" (regexp-opt gretl-block-end-keywords) "\\)\\>"))
+
+(defvar gretl-block-begin-or-end-regexp
+  (concat gretl-block-begin-regexp "\\|" gretl-block-end-regexp))
+
+
+(defvar gretl-block-else-or-end-regexp
+  (concat gretl-block-else-regexp "\\|" gretl-block-end-regexp))
+
+(defvar gretl-basic-offset 4)
+
+(defvar gretl-block-match-alist
+  '(("loop" . ("endloop"))
+    ("if" . ("else" "elif" "endif"))
+    ("nls" . ("end"))
+    ("mle" . ("end"))
+    ("gmm" . ("end"))
+    ("foreign" . ("end"))
+    ("restrict" . ("end"))
+    ("kalman" . ("end"))
+    ("system" . ("end")))
+  "Alist with Gretl's matching block keywords.
+Has Gretl's begin keywords as keys and a list of the matching else or
+end keywords as associated values.")
+
+
+
+; get the position of the last open block
+(defun gretl-last-open-block-pos (min)
+  (let ((count 0))
+    (while (not (or (> count 0) (<= (point) min)))
+      (backward-word 1)
+      (setq count
+           (cond ((gretl-at-keyword gretl-block-start-keywords)
+                  (+ count 1))
+                 ((and (zerop (string-match "\\(?:e\\(?:l\\(?:if\\|se\\)\\|nd\\(?:if\\|loop\\)?\\)\\)" (current-word)))
+                       (not (ess-inside-comment-p)) (not (ess-inside-brackets-p)))
+                  (- count 1))
+                 (t count))))
+    (if (> count 0)
+       (point)
+      nil)))
+
+
+(defun gretl-last-open-block (min)
+  (let ((pos (gretl-last-open-block-pos min)))
+    (and pos
+        (progn
+          (goto-char pos)
+          (+ gretl-basic-offset (current-indentation))))))
+
+
+; return indent implied by a special form opening on the previous line, if any
+(defun gretl-form-indent ()
+  (forward-line -1)
+  (end-of-line)
+  (backward-sexp)
+  (if (gretl-at-keyword gretl-block-other-keywords)
+      (+ gretl-basic-offset (current-indentation))
+    (if (char-equal (char-after (point)) ?\()
+        (progn
+          (backward-word 1)
+          (let ((cur (current-indentation)))
+            (if (gretl-at-keyword gretl-block-start-keywords)
+                (+ gretl-basic-offset cur)
+              nil)))
+      nil)))
+
+
+(defun gretl-indent-line ()
+  "Indent current line of gretl code."
+  (interactive)
+  (end-of-line)
+  (indent-line-to
+   (or (and (ess-inside-string-p (line-beginning-position)) 0)
+       (save-excursion (ignore-errors (gretl-form-indent)))
+       (save-excursion
+         (let ((endtok (progn
+                         (beginning-of-line)
+                         (forward-to-indentation 0)
+                         (gretl-at-keyword gretl-block-end-keywords))))
+           (ignore-errors (+ (gretl-last-open-block (point-min))
+                             (if endtok (- gretl-basic-offset) 0)))))
+       ;; previous line ends in =
+       (save-excursion
+            (if (and (not (equal (point-min) (line-beginning-position)))
+                         (progn
+                           (forward-line -1)
+                           (end-of-line) (backward-char 1)
+                           (equal (char-after (point)) ?=)))
+                (+ gretl-basic-offset (current-indentation))
+              nil))
+       ;; take same indentation as previous line
+       (save-excursion (forward-line -1)
+                              (current-indentation))
+       0))
+  (when (gretl-at-keyword gretl-block-end-keywords)
+    (forward-word 1)))
+
+;; (defun gretl-send-string-function (process string visibly)
+;;   (let ((gretl-process (get-process "gretlcli")))
+;;     (process-send-string process (format ess-load-command file)))
+
+
+;; (defun gretl-send-string-function (process string visibly)
+;;   (let ((file (concat temporary-file-directory "gretl_eval_region.inp")))
+;;     (with-temp-file file
+;;       (insert string))
+;;     (process-send-string process (format ess-load-command file))))
+
+(defun gretl--get-words-from-command (command start-reg end-reg proc)
+  (with-current-buffer (ess-command command nil nil nil nil proc)
+    (goto-char (point-min))
+    (let ((beg (or (re-search-forward start-reg nil t)
+                   (point-min)))
+          (end (progn (goto-char (point-max))
+                      (or (re-search-backward end-reg)
+                          (point-max))))
+          acum)
+      (goto-char beg)
+      (skip-chars-forward "\n")
+      (while (re-search-forward "[^ \t\n]+" end t)
+        (push (match-string-no-properties 0) acum))
+      acum)))
+
+(cl-defmethod ess-help-get-topics (proc &context (ess-dialect "gretl"))
+  (delete-dups
+   (append gretl-command-words gretl-genr-functions
+           gretl-block-end-keywords gretl-block-other-keywords
+           gretl-block-start-keywords
+           (gretl--get-words-from-command "help\n" "are:" "^For" proc)
+           (gretl--get-words-from-command "help functions\n" "Accessors:" "^Functions" proc)
+           (gretl--get-words-from-command "help functions\n" "^Functions" "^For" proc)
+           )))
+
+;; (defvar ess-gretl-error-regexp-alist '(gretl-in gretl-at)
+;;   "List of symbols which are looked up in `compilation-error-regexp-alist-alist'.")
+
+;; (add-to-list 'compilation-error-regexp-alist-alist
+;;              '(gretl-in  "^\\s-*in [^ \t\n]* \\(at \\(.*\\):\\([0-9]+\\)\\)" 2 3 nil 2 1))
+;; (add-to-list 'compilation-error-regexp-alist-alist
+;;              '(gretl-at "^\\s-*\\(at \\(.*\\):\\([0-9]+\\)\\)"  2 3 nil 2 1))
+
+
+(defvar gretl-customize-alist
+  '((comint-use-prompt-regexp          . t)
+    (inferior-ess-primary-prompt       . "\\? ")
+    (inferior-ess-secondary-prompt     . "\\ ")
+    (inferior-ess-prompt               . "\\? ")
+    (ess-local-customize-alist         . gretl-customize-alist)
+    (inferior-ess-program              . "gretlcli")
+    (ess-load-command                  . "open \"%s\"\n")
+    ;; (ess-dump-error-re                      . "in \\w* at \\(.*\\):[0-9]+")
+    ;; (ess-error-regexp                       . "\\(^\\s-*at\\s-*\\(?3:.*\\):\\(?2:[0-9]+\\)\\)")
+    ;; (ess-error-regexp-alist         . ess-gretl-error-regexp-alist)
+    ;; (inferior-ess-objects-command   . inferior-gretl-objects-command)
+    ;; (inferior-ess-search-list-command       . "search()\n")
+    ;; inferior-ess-help-command               . gretl-help-command)
+    (inferior-ess-help-command         . "help %s\n")
+    (ess-language                      . "gretl")
+    (ess-dialect                       . "gretl")
+    (ess-suffix                                . "inp")
+    (ess-dump-filename-template                . (replace-regexp-in-string
+                                          "S$" ess-suffix ; in the one from custom:
+                                          ess-dump-filename-template-proto))
+    (ess-change-sp-regexp              . nil );ess-r-change-sp-regexp)
+    (ess-help-sec-regex                        . ess-help-r-sec-regex)
+    (ess-help-sec-keys-alist           . ess-help-r-sec-keys-alist)
+    (ess-function-pattern              . ess-r-function-pattern)
+    (ess-object-name-db-file           . "ess-r-namedb.el" )
+    ;; (ess-imenu-mode-function                . nil)
+    (ess-smart-operators               . ess-r-smart-operators)
+    (inferior-ess-exit-command         . "exit\n")
+    ;;harmful for shell-mode's C-a: -- but "necessary" for ESS-help?
+    (inferior-ess-language-start       . nil)
+    (ess-STERM         . "iESS")
+    )
+  "Variables to customize for Gretl -- set up later than Emacs initialization.")
+
+;; (defcustom inferior-gretl-program "gretlcli"
+;;   "*The program to use for running gretl scripts."
+;;   :type 'string
+;;   :group 'ess-gretl)
+
+;; (defvar ess-gretl-versions '("gretcli")
+;;   "List of partial strings for versions of Julia 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 Julia is made available.  ")
+
+(defcustom inferior-gretl-args ""
+  "String of arguments used when starting gretl."
+  :group 'ess-gretl
+  :type 'string)
+
+;;;###autoload
+(define-derived-mode ess-gretl-mode ess-mode "ESS[gretl]"
+  "Major mode for editing gretl source.  See `ess-mode' for more help."
+  ;;(setq imenu-generic-expression R-imenu-generic-expression)
+  (ess-setq-vars-local gretl-customize-alist)
+  (setq font-lock-defaults `(,gretl-font-lock-keywords))
+  (setq-local paragraph-start (concat "\\s-*$\\|" page-delimiter))
+  (setq-local paragraph-separate (concat "\\s-*$\\|" page-delimiter))
+  (setq-local paragraph-ignore-fill-prefix t)
+  (setq-local comment-start "# ")
+  (setq-local comment-add 1)
+  (setq-local comment-start-skip "\\s<+\\s-*")
+  (setq-local comment-column 40)
+  (setq-local indent-line-function #'gretl-indent-line)
+  (setq-local ess-local-customize-alist gretl-customize-alist)
+  (when (fboundp 'ess-add-toolbar) (ess-add-toolbar)))
+
+
+(defvar ess-gretl-post-run-hook nil
+  "Functions run in process buffer after Gretl starts.")
+
+;;;###autoload
+(defun gretl (&optional start-args)
+  "Call `gretl',
+Optional prefix (C-u) allows to set command line arguments, such as
+--vsize.  This should be OS agnostic.
+If you have certain command line arguments that should always be passed
+to gretl, put them in the variable `inferior-gretl-args'."
+  (interactive "P")
+  ;; get settings, notably inferior-ess-r-program :
+  ;; (if (null inferior-gretl-program)
+  ;;     (error "'inferior-gretl-program' does not point to 'gretl-release-basic' executable")
+  (ess-write-to-dribble-buffer   ;; for debugging only
+   (format
+    "\n(Gretl): ess-dialect=%s, buf=%s"
+    ess-dialect (current-buffer)))
+  (let* ((r-start-args
+             (concat inferior-gretl-args " " ; add space just in case
+                         (if start-args
+                             (read-string
+                              (concat "Starting Args [other than `"
+                                          inferior-gretl-args
+                                          "'] ? "))
+                           nil)))
+         (inf-buf (inferior-ess r-start-args gretl-customize-alist)))
+    (setq-local indent-line-function #'gretl-indent-line)
+    (setq-local gretl-basic-offset 4)
+    (setq indent-tabs-mode nil)
+    (goto-char (point-max))
+    ;; (if inferior-ess-language-start
+    ;;         (ess-eval-linewise inferior-ess-language-start
+    ;;                            nil nil nil 'wait-prompt)))
+    (with-current-buffer inf-buf
+      (run-mode-hooks 'ess-gretl-post-run-hook))
+    inf-buf))
+
+
+;;;; IMENU
+
+;; (defvar gretl-imenu-generic-expression
+;;   '(("Function (_)" "^\\s-*function\\s-+\\(_[^ \t\n]*\\)" 1)
+;;     ("Function" "^\\s-*function\\s-+\\([^_][^ \t\n]*\\)" 1)
+;;     ("Const" "^\\s-*const \\([^ \t\n]*\\)" 1)
+;;     ("Type"  "^\\s-*\\w*type\\w* \\([^ \t\n]*\\)" 1)
+;;     ("Load"      " *\\(load\\)(\\([^ \t\n)]*\\)" 2)
+;;     ;; ("Classes" "^.*setClass(\\(.*\\)," 1)
+;;     ;; ("Coercions" "^.*setAs(\\([^,]+,[^,]*\\)," 1) ; show from and to
+;;     ;; ("Generics" "^.*setGeneric(\\([^,]*\\)," 1)
+;;     ;; ("Methods" "^.*set\\(Group\\|Replace\\)?Method(\"\\(.+\\)\"," 2)
+;;     ;; ;;[ ]*\\(signature=\\)?(\\(.*,?\\)*\\)," 1)
+;;     ;; ;;
+;;     ;; ;;("Other" "^\\(.+\\)\\s-*<-[ \t\n]*[^\\(function\\|read\\|.*data\.frame\\)]" 1)
+;;     ;; ("Package" "^.*\\(library\\|require\\)(\\(.*\\)," 2)
+;;     ;; ("Data" "^\\(.+\\)\\s-*<-[ \t\n]*\\(read\\|.*data\.frame\\).*(" 1)))
+;;     ))
+
+
+;; (defun ess-imenu-gretl (&optional arg)
+;;   "Gretl Language Imenu support for ESS."
+;;   (interactive)
+;;   (setq imenu-generic-expression gretl-imenu-generic-expression)
+;;   (imenu-add-to-menubar "Imenu-gretl"))
+
+
+;; (defun ess-imenu-gretl (&optional arg)
+;;   "Gretl Language Imenu support for ESS."
+;;   (interactive)
+;;   (setq imenu-generic-expression gretl-imenu-generic-expression)
+;;   (imenu-add-to-menubar "Imenu-jl"))
+
+
+(provide 'ess-gretl)
+
+;;; ess-gretl.el ends here
diff --git a/elpa/ess-20260424.1544/ess-help.el b/elpa/ess-20260424.1544/ess-help.el
new file mode 100644 (file)
index 0000000..7c99708
--- /dev/null
@@ -0,0 +1,864 @@
+;;; ess-help.el --- Support for viewing ESS help files  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1989-2022 Free Software Foundation, Inc.
+
+;; Author: David Smith <dsmithNOSPAMstats.adelaide.edu.au>
+;; Created: 7 Jan 1994
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; Code for dealing with ESS help files.  See README.<LANGUAGE> where
+;; <LANGUAGE> is one of `S', `SAS', `Stata' or `XLispStat'.
+
+;;; Code:
+
+\f ; Requires and autoloads
+(require 'cl-lib)
+(eval-when-compile
+  (require 'tramp))
+(require 'info)
+(require 'ess-mode)
+(require 'ess-inf)
+(require 'ess-utils)
+(require 'ansi-color)
+
+(declare-function ess-r-help-mode "ess-r-mode")
+(declare-function ess-stata-help-mode "ess-stata-lang")
+
+
+(defcustom ess-help-mode-hook nil
+  "Functions to call when entering `ess-help-mode'."
+  :group 'ess-hooks
+  :type 'hook)
+
+(defvar ess--help-frame nil
+  "Stores the frame used for displaying R help buffers.")
+
+(defvar ess-help--aliases-timeout 10
+  "The large timeout is necessary for some users (#1025, #1081).")
+
+\f ; ess-help-mode
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;; In this section:
+;;;;
+;;;; * The function ess-display-help-on-object
+;;;; * The major mode ess-help-mode
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(cl-defgeneric ess--help-major-mode ()
+  "Determine which help major mode to call, and call it.
+Uses `ess-dialect' to determine the appropriate help mode."
+  (ess-help-mode))
+
+(defun ess--help-get-bogus-buffer-substring (buffer &optional nr-first)
+  "Return non-nil if BUFFER looks like a bogus ESS help buffer.
+Return the pair (match-beg. match-end) which can be used in error
+message. NR-FIRST is the number of characters at the start of the
+buffer to examine when deciding if the buffer if bogus. If nil,
+the first 150 characters of the buffer are searched."
+  (if (not nr-first) (setq nr-first 150))
+  (with-current-buffer buffer
+    (let ((PM (point-min))
+          (case-fold-search t)
+          searching res)
+      (setq res
+            (or  ;; evaluate up to first non-nil (or end):
+             (< (- (point-max) PM) 80); buffer less than 80 chars
+             (not (setq searching t))
+             ;; todo: move to customize-alist
+             (progn (goto-char PM) ;; R:
+                    (re-search-forward "Error in help"    nr-first t))
+             (progn (goto-char PM) ;; S-plus 5.1 :
+                    (re-search-forward "^cat: .*--"       nr-first t))
+             (progn (goto-char PM) ;; S version 3 ; R :
+                    (re-search-forward "no documentation .+" nr-first t))
+             (progn (goto-char PM) ;; stata
+                    (re-search-forward "^help .*not found" nr-first t))))
+      (ess-write-to-dribble-buffer
+       (format " |--> %s [searching %s]\n" res searching))
+      (when res
+        (if searching
+            (buffer-substring (match-beginning 0) (match-end 0))
+          (buffer-string))))))
+
+(defun ess-help-get-local-help-buffers ()
+  (ess-force-buffer-current)
+  (cl-remove-if-not
+   (lambda (buffer)
+     (let* ((pattern (concat "*help[" ess-current-process-name "]("))
+            (name (buffer-name buffer))
+            (candidate (when (> (length name) (length pattern))
+                         (substring name 0 (length pattern))) ))
+       (when (string= pattern candidate)
+         buffer)))
+   (buffer-list)))
+
+(defvar-local ess-help-type nil
+  "Type of help file, help, index, vignettes etc.
+Local in `ess-help' buffers.")
+
+(defvar-local ess-help-object nil
+  "Name of the object the help is displayed for.
+Is name of the package for package index.
+Local in `ess-help' buffers.")
+(put 'ess-help-object 'permanent-local t)
+
+(defun ess-display-help-on-object (object &optional command)
+  "Display documentation for OBJECT.
+If prefix ARG is given, force an update of the cached help topics
+and query the ESS process for the help file instead of reusing an
+existing buffer if it exists. Uses the variable
+`inferior-ess-help-command' for the actual help command. Prompts
+for the object name based on the cursor location for all cases
+except the S-Plus GUI. With S-Plus on Windows (both GUI and in an
+inferior Emacs buffer) the GUI help window is used. If COMMAND is
+supplied, it is used instead of `inferior-ess-help-command'."
+  (interactive
+   (progn
+     (ess-force-buffer-current)
+     (when current-prefix-arg
+       (ess-help--reset-cache))
+     (list (ess-find-help-file "Help on"))))
+  (let* ((hb-name (concat "*help[" ess-current-process-name "]("
+                          (replace-regexp-in-string "^\\?\\|`" "" object) ")*"))
+         (old-hb-p (get-buffer hb-name))
+         (tbuffer (get-buffer-create hb-name)))
+    (when (or (not old-hb-p)
+              (ess-process-get 'sp-for-help-changed?)
+              (ess--help-get-bogus-buffer-substring old-hb-p))
+      (ess-with-current-buffer tbuffer
+        (ess--flush-help-into-current-buffer object command)
+        (setq ess-help-object object)
+        (ess--help-major-mode)
+        (setq truncate-lines nil
+              ess-help-type 'help)))
+    (unless (ess--help-kill-bogus-buffer-maybe tbuffer)
+      (ess-display-help tbuffer))))
+
+(defun ess-help--reset-cache ()
+  "Reset all cached help files."
+  (ess-process-put 'sp-for-help-changed? t)
+  (ess-help--reset-cache-override))
+
+(cl-defgeneric ess-help--reset-cache-override ())
+
+(defun ess-help-revert-buffer (_ignore-auto _noconfirm)
+  "Revert the current help buffer.
+This reloads the documentation. IGNORE-AUTO and NOCONFIRM are
+ignored."
+  (ess-process-put 'sp-for-help-changed? t)
+  (ess-display-help-on-object ess-help-object))
+
+(defalias 'ess-help #'ess-display-help-on-object)
+
+(cl-defgeneric ess-build-help-command (object)
+  "Build a string command for retrieving help on OBJECT."
+  (format inferior-ess-help-command object))
+
+(defun ess--flush-help-into-current-buffer (object &optional command)
+  (let ((inhibit-modification-hooks t)
+        (inhibit-read-only t))
+    (delete-region (point-min) (point-max))
+    (let ((command (if (and command (string-match-p "%s" command))
+                       (format command object)
+                     command)))
+      (ess-command (or command (ess-build-help-command object))
+                   (current-buffer)))
+    (ess-help-underline)
+    (unless (string= ess-language "STA")
+      (ess-nuke-help-bs))
+    (goto-char (point-min))
+    (set-buffer-modified-p 'nil)))
+
+(defun ess--help-kill-bogus-buffer-maybe (buffer)
+  "Internal, try to kill bogus BUFFER with message. Return t if killed."
+  (when ess-help-kill-bogus-buffers
+    (let ((bog-mes  (ess--help-get-bogus-buffer-substring buffer)))
+      (when bog-mes
+        ;; The following is giving erroneous messages when help is displayed in the browser
+        ;; (when (< (length bog-mes) 10) ;;no message at all, how to treat this properly?
+        ;;   (setq bog-mes (format "No documentation found; %s" bog-mes)))
+        (ess-write-to-dribble-buffer
+         (format "(ess-help: kill bogus buffer %s ..\n" (buffer-name buffer)))
+        (message "%s" (replace-regexp-in-string  "\n" "" bog-mes))
+        ;; (ding) ;; don't ding, in julia a lot of doc strings are very short
+        (kill-buffer buffer)))))
+
+(defun ess-display-help-in-browser ()
+  "Displaying HTML help where available, using \\[browse-url]."
+  (interactive)
+  (unless (string-match "^R" ess-dialect)
+    (user-error "Sorry, not implemented for %s " ess-dialect))
+  (if (or (not ess-help-object)
+          (not (eq ess-help-type 'help)))
+      (message "No help topic found")
+    (ess-command (format "help('%s', help_type='html')\n" ess-help-object))))
+
+(defun ess--button-action (&optional button)
+  "Provide help on object at the beginning of line.
+It's intended to be used in R-index help pages. Load the package
+if necessary.  It is bound to RET and C-m in R-index pages."
+  (let* ((string (button-label button))
+         (command (ess-build-help-command string)))
+    (ess-display-help-on-object string command)))
+
+(cl-defgeneric ess-help-commands ()
+  "Return an alist of dialect specific retriever commands.
+Currently understood commands:
+- package-for-object - command to get the package of current
+  help object
+- packages - command to get a list of available
+  packages (REQUIRED)
+- package-index - command to get the package index (REQUIRED)
+- index-keyword-reg - regexp used to find keywords for linking in
+  index listing only (1st subexpression is used)
+- index-start-reg - regexp from where to start searching for
+   keywords in index listing"
+  (user-error "Not implemented for %s " ess-dialect))
+
+(cl-defmethod ess-help-commands (&context (ess-dialect "R"))
+  '((package-for-object . "sub('package:', '', .ess.findFUN('%s'))\n")
+    (packages           . ".packages(all.available=TRUE)\n")
+    (package-index      . ".ess.help(package='%s', help.type='text')\n")
+    (index-keyword-reg  . "^\\([^ \t\n:]+\\)")
+    (index-start-reg    . "^Index:")))
+
+(defun ess-display-package-index (&optional package)
+  "Prompt for package name and display its index."
+  (interactive
+   (list (let* ((coms (ess-help-commands))
+                (all-packs (ess-get-words-from-vector (cdr (assoc 'packages coms))))
+                (pack (or (when (and ess-help-object
+                                     (cdr (assoc 'package-for-object coms))
+                                     (eq ess-help-type 'help))
+                            (car (ess-get-words-from-vector
+                                  (format (cdr (assoc 'package-for-object coms))
+                                          ess-help-object))))
+                          (car (member (ess-read-object-name-default) all-packs)))))
+           (ess-completing-read "Index of" all-packs nil nil nil nil pack))))
+  (let ((coms (ess-help-commands)))
+    (ess--display-indexed-help-page
+     (format (cdr (assoc 'package-index coms)) package)
+     (cdr (assoc 'index-keyword-reg coms))
+     (format "*help[%s](index:%s)*"  ess-dialect package)
+     'index nil nil (cdr (assoc 'index-start-reg coms)) package)))
+
+(defun ess--display-indexed-help-page (command item-regexp title help-type
+                                               &optional action help-echo reg-start help-object)
+  "Internal function to display help pages with linked actions.
+COMMAND to produce the indexed help page,
+ITEM-REGEXP -- first subexpression is highlighted,
+TITLE of the help page,
+HELP-TYPE to be stored in `ess-help-type' local variable,
+ACTION is a function with no argument (default is `ess--button-action'),
+HELP-ECHO if given becomes the help-echo property of the button,
+REG-START gives the start location from where to search linkifying,
+          and HELP-OBJECT becomes `ess-help-object'."
+  (let ((inhibit-modification-hooks t)
+        (alist          ess-local-customize-alist)
+        (pname ess-local-process-name)
+        (buff (get-buffer-create title)))
+    (ess-with-current-buffer buff
+      (setq buffer-read-only nil)
+      (delete-region (point-min) (point-max))
+      (setq ess-local-process-name pname)
+      (ess--help-major-mode)
+      (ess-setq-vars-local (eval alist t))
+      (setq ess-help-object help-object
+            ess-help-sec-regex "\\(^\\s-.*\n\\)\\|\\(^\n\\)")
+      (ess--foreground-command command buff)
+      (ess-help-underline)
+      (set-buffer-modified-p 'nil)
+      (goto-char (point-min))
+      (when reg-start ;; go to the beginning of listing
+        (re-search-forward  reg-start  nil t))
+      (when item-regexp
+        ;;linkify the buffer
+        (save-excursion
+          (while (re-search-forward item-regexp nil t)
+            (make-text-button (match-beginning 1) (match-end 1)
+                              'mouse-face 'highlight
+                              'action (or action #'ess--button-action)
+                              'help-object (buffer-substring-no-properties (match-beginning 1) (match-end 1))
+                              'follow-link t
+                              'help-echo (or help-echo "help on object")))))
+      (save-excursion ;; why R help adds all these spaces?
+        (goto-char (point-min))
+        (when (re-search-forward "Index:\n\n" nil t)
+          (let ((beg (point)))
+            (forward-paragraph 1)
+            (align-regexp beg (point) "\\(\\s-+\\)"))))
+      (setq buffer-read-only t)
+      (setq ess-help-type help-type)
+      (setq truncate-lines nil))
+    (unless (ess--help-kill-bogus-buffer-maybe buff)
+      (ess-display-help buff))))
+
+(defun ess-display-help-apropos (&optional pattern)
+  "Create an ess-apropos buffer with a *linked* list of apropos topics."
+  (interactive "sPattern: ")
+  (let (com regexp)
+    (cond ((equal ess-dialect "R")
+           (setq com "help.search('%s')\n"
+                 regexp "^\\([^ \t\n:]+::[^ \t\n:]+\\)[ \t\n]+"))
+          ((equal ess-dialect "julia")
+           (setq com "apropos(\"%s\")\n"
+                 regexp "^\\(\\(\\w\\|\\s_\\)+\\)("))
+          ((equal ess-dialect "stata")
+           (setq com "hsearch %s\n"
+                 regexp "^[\t ]*[0-9]+\\.[\t ]+\\(.+\\)$"))
+          (t (error "Not implemented for dialect %s" ess-dialect)))
+    (ess--display-indexed-help-page
+     (format com pattern) regexp
+     (format "*ess-apropos[%s](%s)*" ess-current-process-name pattern)
+     'apropos)))
+
+(defun ess-display-demos ()
+  "Create an ess-demos buffer with a *linked* list of available demos."
+  (interactive)
+  (let (com regexp)
+    (cond ((equal ess-dialect "R")
+           (setq com "demo()\n"
+                 regexp "^\\([^ \n:]+\\)  +"))
+          (t (error "Not implemented for dialect %s" ess-dialect)))
+    (ess--display-indexed-help-page
+     com regexp
+     (format "*ess-demos[%s]*" ess-current-process-name)
+     'demos #'ess--action-demo)))
+
+(defun ess--action-demo (&optional button)
+  "Provide help on object at the beginning of line.
+It's intended to be used in R-index help pages. Load the package
+if necessary.  It is bound to RET and C-m in R-index pages."
+  (let* ((string (button-label button))
+         (command
+          (cond ((equal ess-dialect "R")
+                 (format "demo('%s')\n" string))
+                (t (error "Not implemented for dialect %s" ess-dialect)))))
+    (ess-eval-linewise command)
+    (ess-switch-to-end-of-ESS)))
+
+(defun ess-display-vignettes (&optional all)
+  "Display vignettes if available for the current dialect.
+With (prefix) ALL non-nil, use `vignette(*, all=TRUE)`, i.e., from all installed
+ packages, which can be *very* slow."
+  (interactive "P")
+  (ess--display-vignettes-override all))
+
+(cl-defgeneric ess--display-vignettes-override (_all)
+  "Display vignettes for the current dialect.
+See `ess-display-vignettes' for ALL."
+  (user-error "Sorry, not implemented for %s" ess-dialect))
+
+(defun ess--action-open-in-emacs (pos)
+  (display-buffer (find-file-noselect (get-text-property pos 'help-echo))))
+(defun ess--action-R-open-vignette (pos)
+  (ess-eval-linewise (format "vignette('%s', package='%s')\n"
+                             (get-text-property pos 'vignette)
+                             (get-text-property pos 'package))))
+
+(defalias 'ess-help-quit #'quit-window)
+(make-obsolete 'ess-help-quit 'quit-window "16.04")
+
+(defun ess-display-help (buff)
+  "Display buffer BUFF.
+If `ess-help-pop-to-buffer' is non-nil, call `pop-to-buffer',
+otherwise call `display-buffer' to display the buffer.
+
+You may control how help buffers are displayed by EITHER setting
+an entry in `display-buffer-alist' (see examples in info
+node `(ess) Controlling buffer display') OR setting the
+ESS-specific variables `ess-help-own-frame',
+`ess-help-reuse-window', `ess-help-frame-alist', and
+`ess-display-buffer-reuse-frames'."
+  (let* ((action (cond (ess-help-own-frame
+                        '(display-buffer-reuse-window
+                          display-buffer-use-some-frame
+                          display-buffer-pop-up-frame))
+                       (ess-help-reuse-window
+                        '(display-buffer-reuse-window
+                          ess-display-buffer-reuse-mode-window
+                          display-buffer-pop-up-window
+                          display-buffer-use-some-window))
+                       (t '(display-buffer-pop-up-window
+                            display-buffer-use-some-window))))
+         (alist `((mode . (ess-help-mode ess-r-help-mode ess-stata-help-mode ess-julia-help-mode))
+                  (reusable-frames . ,ess-display-buffer-reuse-frames)
+                  ;; `display-buffer-use-some-frame' uses this to
+                  ;; determine whether to use the frame or not.
+                  (frame-predicate . (lambda (f)
+                                       (when (equal ess-help-own-frame 'one)
+                                         ;; Note we're always returning
+                                         ;; nil for `ess-help-own-frame' t.
+                                         (frame-parameter f 'ess-help-frame))))
+                  ;; If `display-buffer' makes a new frame, these are
+                  ;; given as frame parameters.
+                  (pop-up-frame-parameters . ,(append ess-help-frame-alist
+                                                      `((auto-hide-function . delete-frame)
+                                                        (ess-help-frame . ,(equal ess-help-own-frame 'one)))))))
+         (display-alist `(,action . ,alist)))
+    (if ess-help-pop-to-buffer
+        (pop-to-buffer buff display-alist)
+      (display-buffer buff display-alist))))
+
+(defun ess-help-web-search (cmd)
+  "Search the web for documentation on CMD."
+  (interactive "sSearch for: ")
+  (ess--help-web-search-override cmd))
+
+(cl-defgeneric ess--help-web-search-override (_cmd)
+  "Dialect-specific override for `ess-help-web-search', which see for CMD."
+  (error "Not implemented for %s" ess-dialect))
+
+(defun ess-manual-lookup ()
+  "Search manual for documentation."
+  (interactive)
+  (ess--manual-lookup-override))
+
+(cl-defgeneric ess--manual-lookup-override ()
+  "Dialect-specific override for `ess-manual-lookup'."
+  (error "Not implemented for %s" ess-dialect))
+
+(defvar ess-doc-map
+  (let (ess-doc-map)
+    (define-prefix-command 'ess-doc-map)
+    (define-key ess-doc-map "\C-e" #'ess-describe-object-at-point)
+    (define-key ess-doc-map "e" #'ess-describe-object-at-point)
+    (define-key ess-doc-map "\C-d" #'ess-display-help-on-object)
+    (define-key ess-doc-map "d" #'ess-display-help-on-object)
+    (define-key ess-doc-map "\C-i" #'ess-display-package-index)
+    (define-key ess-doc-map "i" #'ess-display-package-index)
+    (define-key ess-doc-map "\C-a" #'ess-display-help-apropos)
+    (define-key ess-doc-map "a" #'ess-display-help-apropos)
+    (define-key ess-doc-map "\C-v" #'ess-display-vignettes)
+    (define-key ess-doc-map "v" #'ess-display-vignettes)
+    (define-key ess-doc-map "\C-o" #'ess-display-demos)
+    (define-key ess-doc-map "o" #'ess-display-demos)
+    (define-key ess-doc-map "\C-w" #'ess-help-web-search)
+    (define-key ess-doc-map "w" #'ess-help-web-search)
+    (define-key ess-doc-map "\C-m" #'ess-manual-lookup)
+    (define-key ess-doc-map "m" #'ess-manual-lookup)
+    ess-doc-map)
+  "ESS documentation map.")
+
+
+(defvar ess-help-mode-map
+  (let ((map (make-keymap)))
+    (define-key map "\C-m" #'next-line)
+    (define-key map "h" #'ess-display-help-on-object)
+    (define-key map "w" #'ess-display-help-in-browser)
+    (define-key map "i" #'ess-display-package-index)
+    (define-key map "a" #'ess-display-help-apropos)
+    (define-key map "v" #'ess-display-vignettes)
+    (define-key map "l" #'ess-eval-line-visibly-and-step)
+    (define-key map "r" #'ess-eval-region-and-go)
+    (define-key map "f" #'ess-eval-function-or-paragraph-and-step)
+    (define-key map "n" #'ess-skip-to-next-section)
+    (define-key map "p" #'ess-skip-to-previous-section)
+    (define-key map "/" #'isearch-forward)
+    (define-key map "x" #'ess-kill-buffer-and-go)
+    (define-key map "k" #'kill-this-buffer)
+    (define-key map "\C-c\C-s" #'ess-switch-process)
+    (define-key map "\C-c\C-r" #'ess-eval-region)
+    (define-key map "\C-c\M-r" #'ess-eval-region-and-go)
+    (define-key map "\C-c\C-f" #'ess-eval-function)
+    (define-key map "\M-\C-x"  #'ess-eval-function)
+    (define-key map "\C-c\M-f" #'ess-eval-function-and-go)
+    (define-key map "\C-c\C-j" #'ess-eval-line)
+    (define-key map "\C-c\C-n" #'ess-eval-line-visibly-and-step)
+    (define-key map "\C-c\C-c"   #'ess-eval-region-or-function-or-paragraph-and-step)
+    (define-key map [(control return)] #'ess-eval-region-or-line-visibly-and-step)
+    (define-key map "\C-c\M-j" #'ess-eval-line-and-go)
+    (define-key map "\M-\C-a"  #'ess-goto-beginning-of-function-or-para)
+    (define-key map "\M-\C-e"  #'ess-goto-end-of-function-or-para)
+    (define-key map "\C-c\C-y" #'ess-switch-to-ESS)
+    (define-key map "\C-c\C-z" #'ess-switch-to-end-of-ESS)
+    (define-key map "\C-c\C-l" #'ess-load-file)
+    (define-key map "\C-c\M-l" #'ess-load-file); alias, as in #'iESS#' where C-c C-l is comint-list-*
+    (define-key map "\C-c\C-v" #'ess-display-help-on-object)
+    (define-key map "\C-c\C-k" #'ess-request-a-process)
+    (define-key map "\C-c\C-d"   'ess-doc-map)
+    (define-key map "\C-c\C-e"   'ess-extra-map)
+    (define-key map "\C-c\C-t"   'ess-dev-map)
+    map)
+  "Keymap for ESS help mode.")
+
+;; One reason for the following menu is to <TEACH> the user about key strokes
+(defvar ess-help-mode-menu
+  '("ESS-help"
+    ["Search forward"          isearch-forward t]
+    ["Next section"            ess-skip-to-next-section t]
+    ["Previous section"                ess-skip-to-previous-section t]
+    ["Help on section skipping"        ess-describe-sec-map t]
+    ["Beginning of buffer"     beginning-of-buffer t]
+    ["End of buffer"           end-of-buffer t]
+    "-"
+    ["Help on ..."             ess-display-help-on-object t]
+    ["Apropos of ..."          ess-display-help-apropos t]
+    ["Index of ..."            ess-display-package-index t]
+    ["Vignettes"               ess-display-vignettes t]
+    ["Open in browser"         ess-display-help-in-browser t]
+    "-"
+    ["Eval line"               ess-eval-line-and-step t]
+    ["Eval paragraph & step"   ess-eval-paragraph-and-step t]
+    ["Eval region & go"                ess-eval-region-and-go t]
+    ["Switch to ESS process"   ess-switch-to-ESS t]
+    ["Switch to end of ESS proc." ess-switch-to-end-of-ESS t]
+    ["Switch _the_ process"    ess-switch-process t]
+    "-"
+    ["Kill buffer"             kill-this-buffer t]
+    ["Kill buffer & go"                ess-kill-buffer-and-go t]
+    "-"
+    ["Handy commands"          ess-handy-commands t])
+  "Menu used in ess-help mode.")
+
+(easy-menu-define ess-help-mode-menu-map ess-help-mode-map
+  "Menu keymap for ess-help mode." ess-help-mode-menu)
+
+(define-derived-mode ess-help-mode special-mode "ESS Help"
+  "Mode for viewing ESS help files."
+  :group 'ess-help
+  ;; FIXME
+  ;; (if ess-mode-syntax-table ;;set in advance by ess-setq-local
+  ;;     (set-syntax-table ess-mode-syntax-table))
+  (setq-local revert-buffer-function #'ess-help-revert-buffer)
+  (setq show-trailing-whitespace nil))
+
+\f
+;;*;; User commands defined in ESS help mode
+
+(defun ess-skip-to-help-section ()
+  "Jump to a section heading of a help buffer.
+The section selected is determined by the command letter used to
+invoke the command, as indicated by `ess-help-sec-keys-alist'.
+Use \\[ess-describe-sec-map] to see which keystrokes find which
+sections."
+  (interactive)
+  (let ((old-point (point))
+        (case-fold-search nil)
+        (the-sec (cdr (assoc last-command-event ess-help-sec-keys-alist))))
+    (cl-assert the-sec nil (format "Invalid section key: %c" last-command-event))
+    (goto-char (point-min))
+    (if (re-search-forward (concat "^" the-sec) nil t)
+        (progn (recenter)
+               (beginning-of-line))
+      (message "No %s section in this help. Sorry." the-sec)
+      (goto-char old-point))))
+
+(defun ess-skip-to-next-section ()
+  "Jump to next section in ESS help buffer."
+  (interactive)
+  (let ((case-fold-search nil))
+    (when (looking-at-p ess-help-sec-regex)
+      (forward-line))
+    (if (re-search-forward ess-help-sec-regex nil 'no-error)
+        (beginning-of-line)
+      (message "No more sections."))))
+
+(defun ess-skip-to-previous-section ()
+  "Jump to previous section in ESS help buffer."
+  (interactive)
+  (let ((case-fold-search nil))
+    (if (re-search-backward ess-help-sec-regex nil 'no-error)
+        (beginning-of-line)
+      (message "No previous section."))))
+
+(defun ess-kill-buffer-and-go nil
+  "Kill the current buffer and switch back to the ESS process."
+  (interactive)
+  (kill-buffer (current-buffer))
+  (when (and ess-current-process-name (get-process ess-current-process-name))
+    (ess-switch-to-ESS nil)))
+
+(defun ess-describe-sec-map nil
+  "Display help for the `s' key."
+  (interactive)
+  (let ((keys-alist ess-help-sec-keys-alist))
+    (describe-function 'ess-skip-to-help-section)
+
+    (with-current-buffer "*Help*"
+      (setq buffer-read-only nil)
+      (goto-char (point-max))
+      (insert "\n\nCurrently defined keys are:
+
+Keystroke    Section
+---------    -------\n")
+      (dolist (cs keys-alist)
+        (insert "    "
+                (car cs)
+                "      "
+                (cdr cs) "\n")))))
+
+(defun ess-helpobjs-at-point--read-obj ()
+  (let* ((obj (ess-read-object-name-default)))
+    ;; Exclude numbers
+    (unless (and obj (not (string-match "[[:alpha:]]" obj)))
+      obj)))
+
+(defun ess-unqualify-symbol (object)
+  (if (string-match "^[[:alnum:].]+::?" object)
+      (substring object (match-end 0))
+    object))
+
+(defun ess-helpobjs-at-point (slist)
+  "Return a list (def obj fun).
+Obj is a name at point, fun is the name of the function call
+point is in, and def is either obj or fun (in that order) which
+has a a help file, i.e. it is a member of SLIST (string-list).
+nil otherwise."
+  (let* ((obj (ess-helpobjs-at-point--read-obj))
+         (unqualified-obj (and obj (ess-unqualify-symbol obj)))
+         ;; FIXME: probably should use syntactic logic here
+         (fun (ignore-errors
+                (save-excursion
+                  (save-restriction
+                    (narrow-to-region (max (point-min) (- (point) 1000))
+                                      (point-max))
+                    (backward-up-list 1)
+                    (backward-char 1)
+                    (ess-read-object-name-default))))))
+    (list (or (car (member obj slist))
+              (when (member unqualified-obj slist)
+                obj)
+              (car (member fun slist)))
+          obj fun)))
+
+(cl-defgeneric ess-help-get-topics (proc)
+  "Return a list of help topics from PROC."
+  (user-error "Not supported for %s (process: %s)" ess-dialect proc))
+
+(defun ess-find-help-file (p-string)
+  "Find help, prompting for P-STRING."
+  (ess-make-buffer-current)
+  (let* ((help-files-list (ess-help-get-topics ess-current-process-name))
+         (hlpobjs (delq nil (ess-helpobjs-at-point help-files-list))))
+    (ess-completing-read p-string (append hlpobjs help-files-list)
+                         nil nil nil nil (car hlpobjs))))
+
+\f
+;;*;; Utility functions
+
+(defun ess-get-help-files-list ()
+  "Return a list of files which have help available."
+  (apply #'nconc
+         (mapcar (lambda (str)
+                   (let ((dirname (concat str "/.Help")))
+                     (and (file-directory-p dirname)
+                          (directory-files dirname))))
+                 (ess-search-list))))
+
+(defun ess-get-help-aliases-list ()
+  "Return a list of aliases which have help available."
+  (message "Retrieving RDS aliases...")
+  ;; ess-command locks display, make sure the above message is visible
+  (redisplay t)
+  (ess-write-to-dribble-buffer "Processing RDS files ...\n")
+  ;; FIXME: This should be run asynchronously
+  (prog1 (ess-get-words-from-vector ".ess.getHelpAliases()\n"
+                                    nil nil nil ess-help--aliases-timeout)
+    (message "Retrieving RDS aliases...done")))
+
+(defun ess-nuke-help-bs ()
+  "Remove ASCII underlining and overstriking performed by ^H codes."
+  ;; This function is a modification of nuke-nroff-bs in man.el from the
+  ;; standard Emacs 18 lisp library.
+  ;; Nuke underlining and overstriking (only by the same letter)
+  (goto-char (point-min))
+  (while (search-forward "\b" nil t)
+    (let* ((preceding (char-after (- (point) 2)))
+           (following (following-char)))
+      (cond ((= preceding following)
+             ;; x\bx
+             (delete-char -2))
+            ((= preceding ?\_)
+             ;; _\b
+             (delete-char -2))
+            ((= following ?\_)
+             ;; \b_
+             (delete-region (1- (point)) (1+ (point)))))))
+  (goto-char (point-min))
+  (let ((case-fold-search nil)); 'URL' != 'url' ('libcurl: ' on ?capabilities)
+    (while (re-search-forward "\\bURL: " nil t); test with ?rtags
+      ;; quick fix for C-x f confusion (getting into tramp)
+      (delete-region (match-beginning 0) (match-end 0))))
+  ;; Crunch blank lines
+  (goto-char (point-min))
+  (while (re-search-forward "\n\n\n\n*" nil t)
+    (replace-match "\n\n"))
+  ;; Nuke blanks lines at start.
+  (goto-char (point-min))
+  (skip-chars-forward "\n")
+  (delete-region (point-min) (point)))
+
+(defun ess-help-underline ()
+  "Replace _^H codes with underline face."
+  (save-excursion
+    (goto-char (point-min))
+    (while (search-forward "_\b" nil t)
+      (delete-char -2)
+      (put-text-property (point) (1+ (point)) 'face 'underline))))
+
+;;*;; Link to Info
+(defun ess-goto-info (node)
+  "Display node NODE from `ess-mode' info."
+  (require 'info)
+  (split-window)
+  (Info-goto-node (concat "(ess)" node)))
+
+\f
+;; describe object at point
+
+(defvar-local ess-describe-object-at-point-commands nil
+  "Commands cycled by `ess-describe-object-at-point'.
+Dialect specific.")
+
+(defvar ess--descr-o-a-p-commands nil)
+
+(defun ess-describe-object-at-point ()
+  "Get info for object at point, & display it in an electric buffer or tooltip.
+If region is active use it instead of the object at point.
+
+This is an electric command (`ess--execute-electric-command'),
+which means that you can use the last key to cycle through the
+action set (in this case `C-e'). After invocation of this command
+all standard Emacs commands, except those containing `window' in
+their names, remove the electric *ess-describe* buffer. Use
+`other-window' to switch to *ess-describe* window.
+
+Customize `ess-describe-at-point-method' if you want to display
+the description in a tooltip. See also
+`ess-r-describe-object-at-point-commands' (and similar option for
+other dialects)."
+  (interactive)
+  (if (not ess-describe-object-at-point-commands)
+      (message "Not implemented for dialect %s" ess-dialect)
+    (ess-force-buffer-current)
+    (let ((map (make-sparse-keymap))
+          (objname (or (and (use-region-p)
+                            (buffer-substring-no-properties (point) (mark)))
+                       (ess-symbol-at-point)))
+          ess--descr-o-a-p-commands) ;; used in ess--describe-object-at-point
+      (unless objname (error "No object at point "))
+      (define-key map (vector last-command-event)
+                  #'ess--describe-object-at-point)
+      ;; todo: put digits into the map
+      (let* ((inhibit-quit t) ;; C-g removes the buffer
+             (buf (ess--execute-electric-command
+                   map (format "Press %s to cycle"
+                               (single-key-description last-command-event))
+                   nil nil objname))
+             ;; read full command
+             (keys (read-key-sequence-vector ""))
+             (command (and keys (key-binding keys))))
+        (when (and (commandp command)
+                   (bufferp buf)
+                   (or (not (symbolp command)) ;; kill on lambdas
+                       (not (string-match "window" (symbol-name command)))))
+          (kill-buffer buf)) ;; bury does not work here :( (Emacs bug?)
+        (setq unread-command-events
+              (append keys unread-command-events))))))
+
+(defun ess--describe-object-at-point (_ev objname)
+  (setq ess--descr-o-a-p-commands (or ess--descr-o-a-p-commands
+                                      (symbol-value ess-describe-object-at-point-commands)))
+  (let* ((com (format (car (pop ess--descr-o-a-p-commands)) objname))
+         (buf (get-buffer-create "*ess-describe*"))
+         pos)
+    (unless (eq ess-describe-at-point-method 'tooltip)
+      ;; can take some time for the command to execute
+      (display-buffer buf))
+    (sit-for .01)
+    (ess-command (concat com "\n") buf) ;; erases buf
+    (with-current-buffer buf
+      (goto-char (point-min))
+      (insert (propertize (format "%s:\n\n" com) 'face 'font-lock-string-face))
+      (forward-line -1)
+      (setq pos (point))
+      ;; set the keys that we are used to in help mode
+      (special-mode)
+      (let ((inhibit-read-only t))
+        (ansi-color-apply-on-region (point-min) (point-max))))
+    (if (eq ess-describe-at-point-method 'tooltip)
+        (ess-tooltip-show-at-point
+         (with-current-buffer buf (buffer-string))  0 30)
+      (display-buffer buf)
+      (set-window-point (get-buffer-window buf) pos) ;; don't move window point
+      buf)))
+
+(with-no-warnings
+  ;; We're just backporting here, don't care about compiler warnings
+  (defalias 'ess-display-buffer-reuse-mode-window
+    ;; TODO: Remove once we drop support for Emacs 25
+    (if (fboundp 'display-buffer-reuse-mode-window)
+        'display-buffer-reuse-mode-window
+      (lambda (buffer alist)
+        (let* ((alist-entry (assq 'reusable-frames alist))
+               (alist-mode-entry (assq 'mode alist))
+              (frames (cond (alist-entry (cdr alist-entry))
+                            ((if (eq pop-up-frames 'graphic-only)
+                                 (display-graphic-p)
+                               pop-up-frames)
+                             0)
+                            (display-buffer-reuse-frames 0)
+                            (t (last-nonminibuffer-frame))))
+               (inhibit-same-window-p (cdr (assq 'inhibit-same-window alist)))
+              (windows (window-list-1 nil 'nomini frames))
+               (buffer-mode (with-current-buffer buffer major-mode))
+               (allowed-modes (if alist-mode-entry
+                                  (cdr alist-mode-entry)
+                                buffer-mode))
+               (curwin (selected-window))
+               (curframe (selected-frame)))
+          (unless (listp allowed-modes)
+            (setq allowed-modes (list allowed-modes)))
+          (let (same-mode-same-frame
+                same-mode-other-frame
+                derived-mode-same-frame
+                derived-mode-other-frame)
+            (dolist (window windows)
+              (let ((mode?
+                     (with-current-buffer (window-buffer window)
+                       (cond ((memq major-mode allowed-modes)
+                              'same)
+                             ((derived-mode-p allowed-modes)
+                              'derived)))))
+                (when (and mode?
+                           (not (and inhibit-same-window-p
+                                     (eq window curwin))))
+                  (push window (if (eq curframe (window-frame window))
+                                   (if (eq mode? 'same)
+                                       same-mode-same-frame
+                                     derived-mode-same-frame)
+                                 (if (eq mode? 'same)
+                                     same-mode-other-frame
+                                   derived-mode-other-frame))))))
+            (let ((window (car (nconc same-mode-same-frame
+                                      same-mode-other-frame
+                                      derived-mode-same-frame
+                                      derived-mode-other-frame))))
+              (when (window-live-p window)
+                (prog1 (window--display-buffer buffer window 'reuse alist)
+                  (unless (cdr (assq 'inhibit-switch-frame alist))
+                    (window--maybe-raise-frame (window-frame window))))))))))))
+
+(provide 'ess-help)
+;;; ess-help.el ends here
diff --git a/elpa/ess-20260424.1544/ess-inf.el b/elpa/ess-20260424.1544/ess-inf.el
new file mode 100644 (file)
index 0000000..28c7935
--- /dev/null
@@ -0,0 +1,3270 @@
+;;; ess-inf.el --- Support for running S as an inferior Emacs process  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1989-2025 Free Software Foundation, Inc.
+
+;; Author: David Smith <dsmithNOSPAMstats.adelaide.edu.au>
+;; Created: 7 Jan 1994
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; Code for handling running ESS processes.
+
+;;; Code:
+
+(eval-when-compile
+  (require 'cl-lib)
+  (require 'tramp)
+  (require 'subr-x))
+(require 'ess-utils)
+(require 'ess)
+(require 'ess-tracebug)
+
+(require 'ansi-color)
+(require 'comint)
+(require 'compile)
+(require 'format-spec)
+(require 'overlay)
+(require 'project)
+
+;; Don't require tramp at run time. It's an expensive library to load.
+;; Instead, guard calls with (require 'tramp) and silence the byte
+;; compiler.
+(declare-function tramp-sh-handle-expand-file-name "tramp-sh" (name &optional dir))
+(declare-function tramp-dissect-file-name "tramp" (name &optional nodefault))
+(declare-function tramp-tramp-file-p "tramp" (name))
+(declare-function inferior-ess-r-mode "ess-r-mode" ())
+(declare-function inferior-ess-julia-mode "ess-julia" ())
+(declare-function inferior-ess-stata-mode "ess-stata-mode" ())
+(declare-function extract-rectangle-bounds "rect" (start end))
+
+(declare-function ess-mode "ess-mode" ())
+(declare-function ess-complete-object-name "ess-r-completion" ())
+;; FIXME:This one should not be necessary
+(declare-function ess-display-help-on-object "ess-help" (object &optional command))
+(declare-function ess-dump-object-into-edit-buffer "ess-mode" (object))
+
+(defvar add-log-current-defun-header-regexp)
+
+;; The following declares can be removed once we drop Emacs 25
+(declare-function tramp-file-name-method "tramp")
+(declare-function tramp-file-name-user "tramp")
+(declare-function tramp-file-name-host "tramp")
+(declare-function tramp-file-name-localname "tramp")
+(declare-function tramp-file-name-hop "tramp")
+
+(defcustom inferior-ess-mode-hook nil
+  "Hook for customizing inferior ESS mode.
+Called after `inferior-ess-mode' is entered and variables have
+been initialized."
+  :group 'ess-hooks
+  :type 'hook)
+
+(defvar inferior-ess-mode-syntax-table
+  (let ((tab (copy-syntax-table comint-mode-syntax-table)))
+    tab)
+  "Syntax table for `inferior-ess-mode'.")
+
+(defun inferior-ess--set-major-mode (dialect)
+  "Set major mode according to DIALECT."
+  (cond ((string= "R" dialect)
+         (progn (require 'ess-r-mode)
+                (inferior-ess-r-mode)))
+        ((string= "julia" dialect)
+         (progn (require 'ess-julia)
+                (inferior-ess-julia-mode)))
+        ((string= "stata" dialect)
+         (progn (require 'ess-stata-mode)
+                (inferior-ess-stata-mode)))
+        ;; FIXME: we need this horrible hack so that
+        ;; inferior-ess-mode-syntax-table gets set for
+        ;; languages that still rely on the old way of doing
+        ;; things (before we used define-derived-mode for
+        ;; inferior modes).
+        (t
+         (progn
+           (setq-local inferior-ess-mode-syntax-table
+                       (eval (or (alist-get 'inferior-ess-mode-syntax-table ess-local-customize-alist)
+                                 (alist-get 'ess-mode-syntax-table ess-local-customize-alist))
+                             t))
+           (inferior-ess-mode)))))
+
+\f ;;*;; Process handling
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; In this section:
+;;;
+;;; * User commands for starting an ESS process
+;;; * Functions called at startup
+;;; * Process handling code
+;;; * Multiple process implementation
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;*;; Starting a process
+(defun ess-proc-name (n name)
+  "Return name of process N, as a string, with NAME prepended.
+If `ess-plain-first-buffername', then initial process is number-free."
+  (concat name
+          (if (not (and ess-plain-first-buffername
+                        (= n 1))) ; if not both first and plain-first add number
+              (concat ":" (number-to-string n)))))
+
+(defvar-local inferior-ess--local-data nil
+  "Program name and arguments used to start the inferior process.")
+
+(defvar inferior-ess--last-started-process-buffer nil
+  "Useful in unit tests to check initialisation errors.
+In that case the command fails before it can return the process
+buffer to us. This global variable can be checked instead.")
+
+(defun inferior-ess (start-args customize-alist &optional no-wait)
+  "Start inferior ESS process.
+Without a prefix argument, starts a new ESS process, or switches
+to the ESS process associated with the current buffer. With
+START-ARGS (perhaps specified via \\[universal-argument]), starts
+the process with those args. The current buffer is used if it is
+an `inferior-ess-mode' or `ess-transcript-mode' buffer.
+
+If `ess-ask-about-transfile' is non-nil, you will be asked for a
+transcript file to use.  If there is no transcript file, the
+buffer name will be like *R* or *R2*, determined by
+`ess-gen-proc-buffer-name-function'.
+
+Takes the program name from the variable `inferior-ess-program'.
+
+See Info node `(ess)Customizing startup' and
+`display-buffer-alist' to control where and how the buffer is
+displayed.
+
+\(Type \\[describe-mode] in the process buffer for a list of
+commands.)
+
+CUSTOMIZE-ALIST is the list of dialect-specific variables.  When
+non-nil, NO-WAIT tells ESS not to wait for the process to finish.
+This may be useful for debugging."
+  ;; Use the current buffer if it is in inferior-ess-mode or ess-trans-mode
+  ;; If not, maybe ask about starting directory and/or transcript file.
+  ;; If no transfile, use buffer *S*
+  ;; This function is primarily used to figure out the Process and
+  ;; buffer names to use for inferior-ess.
+  (run-hooks 'ess-pre-run-hook)
+  (let* ((dialect (eval (cdr (assoc 'ess-dialect customize-alist)) t))
+         (process-environment process-environment)
+         ;; Use dialect if not R, R program name otherwise
+         (temp-dialect (if ess-use-inferior-program-in-buffer-name ;VS[23-02-2013]: FIXME: this should not be here
+                           (if (string-equal dialect "R")
+                               (file-name-nondirectory inferior-ess-r-program)
+                             dialect)
+                         dialect))
+         (inf-buf (inferior-ess--get-proc-buffer-create temp-dialect))
+         (proc-name (buffer-local-value 'ess-local-process-name inf-buf)))
+    (with-current-buffer inf-buf
+      ;; TODO: Get rid of this, we should rely on modes to set the
+      ;; variables they need.
+      (ess-setq-vars-local customize-alist)
+      (inferior-ess--set-major-mode ess-dialect)
+      ;; Set local variables after changing mode because they might
+      ;; not be permanent
+      (setq default-directory
+            (inferior-ess--maybe-prompt-startup-directory proc-name temp-dialect))
+      (setq inferior-ess--local-data (cons inferior-ess-program start-args))
+      ;; Read the history file
+      (when ess-history-file
+        (setq comint-input-ring-file-name
+              (expand-file-name (if (eql t ess-history-file)
+                                    (concat "." ess-dialect "history")
+                                  ess-history-file)
+                                ess-history-directory))
+        (comint-read-input-ring))
+      ;; Show the buffer
+      ;; TODO: Remove inferior-ess-own-frame after ESS 19.04, then just have:
+      ;; (pop-to-buffer inf-buf)
+      (pop-to-buffer inf-buf (with-no-warnings
+                               (when inferior-ess-own-frame
+                                 '(display-buffer-pop-up-frame))))
+      (let ((proc (inferior-ess--start-process inf-buf proc-name start-args)))
+        (ess-make-buffer-current)
+        (goto-char (point-max))
+        (unless no-wait
+          (ess-write-to-dribble-buffer "(inferior-ess: waiting for process to start (before hook)\n")
+          (ess-wait-for-process proc nil 0.01 t))
+        (unless (and proc (eq (process-status proc) 'run))
+          (error "Process %s failed to start" proc-name))
+        (setq-local font-lock-fontify-region-function #'inferior-ess-fontify-region)
+        (setq-local ess-sl-modtime-alist nil)
+        (run-hooks 'ess-post-run-hook)
+        ;; User initialization can take some time ...
+        (unless no-wait
+          (ess-write-to-dribble-buffer "(inferior-ess): waiting for process (after hook)\n")
+          (ess-wait-for-process proc)))
+      (setq inferior-ess--last-started-process-buffer inf-buf)
+      inf-buf)))
+
+(defun inferior-ess--get-proc-buffer-create (name)
+  "Get a process buffer, creating a new one if needed.
+This always returns a process-less buffer. The variable
+`ess-local-process-name' is set in the buffer with the name of
+the next process to spawn. This name may be different from the
+buffer name, depending on how `ess-gen-proc-buffer-name-function'
+generated the latter from NAME."
+  (let* ((proc-name (let ((ntry 1))
+                      ;; Find the next non-existent process N (*R:N*)
+                      (while (get-process (ess-proc-name ntry name))
+                        (setq ntry (1+ ntry)))
+                      (ess-proc-name ntry name)))
+         (inf-name (funcall ess-gen-proc-buffer-name-function proc-name)))
+    (let ((buf (cond
+                ;; Try to use current buffer, if inferior-ess-mode but
+                ;; no process
+                ((and (not (comint-check-proc (current-buffer)))
+                      (derived-mode-p 'inferior-ess-mode))
+                 ;; Don't change existing buffer name in this case. It
+                 ;; is very common to restart the process in the same
+                 ;; buffer.
+                 (setq proc-name ess-local-process-name)
+                 (current-buffer))
+                ;; Pick up a transcript file
+                (ess-ask-about-transfile
+                 (let ((transfilename (read-file-name
+                                       "Use transcript file (default none):" nil "")))
+                   (if (string= transfilename "")
+                       (get-buffer-create inf-name)
+                     (find-file-noselect (expand-file-name transfilename)))))
+                ;; Create a new buffer or take the *R:N* buffer if
+                ;; already exists (it should contain a dead process)
+                (t
+                 (get-buffer-create inf-name)))))
+      ;; We generated a new process name but there might still be a
+      ;; live process in the buffer in corner cases because of
+      ;; `ess-gen-proc-buffer-name-function` or if the user renames
+      ;; inferior buffers
+      (when (comint-check-proc buf)
+        (error "Can't start a new session in buffer `%s` because one already exists"
+               inf-name))
+      (with-current-buffer buf
+        (setq-local ess-local-process-name proc-name))
+      buf)))
+
+(defun ess--accumulation-buffer (proc)
+  "Return, creating if needed, the accumulation buffer for PROC."
+  (let ((abuf (process-get proc :accum-buffer)))
+    (if (buffer-live-p abuf)
+        abuf
+      (let ((abuf (get-buffer-create (format " *%s:accum*" (process-name proc)))))
+        (process-put proc :accum-buffer abuf)
+        (with-current-buffer abuf
+          (buffer-disable-undo)
+          (setq-local inhibit-modification-hooks t))
+        abuf))))
+
+(defvar-local 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!
+
+(defvar-local 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")
+
+(defvar-local 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")
+
+(defun inferior-ess-fontify-region (beg end &optional verbose)
+  "Fontify output by output to avoid fontification spilling over prompts.
+BEG and END signify the bounds, VERBOSE gets passed to
+`font-lock-default-fontify-region'."
+  (let* ((buffer-undo-list t)
+         (font-lock-dont-widen t)
+         (font-lock-extend-region-functions nil)
+         (pos1 beg)
+         (pos2))
+    (when (< beg end)
+      (with-silent-modifications
+        ;; fontify chunks from prompt to prompt
+        (while (< pos1 end)
+          (goto-char pos1)
+          (comint-next-prompt 1)
+          (setq pos2 (min (point) end))
+          (save-restriction
+            (narrow-to-region pos1 pos2)
+            (font-lock-default-fontify-region pos1 pos2 verbose))
+          (setq pos1 pos2))
+        ;; highlight errors
+        (setq compilation--parsed beg)
+        `(jit-lock-bounds ,beg . ,end)))))
+
+(defun ess-gen-proc-buffer-name:simple (proc-name)
+  "Function to generate buffer name by wrapping PROC-NAME in *proc-name*.
+See `ess-gen-proc-buffer-name-function'."
+  (format "*%s*" proc-name))
+
+(defun ess-gen-proc-buffer-name:directory (proc-name)
+  "Return a buffer name by wrapping PROC-NAME in *PROC-NAME:DIR-NAME*.
+DIR-NAME is a short directory name. See
+`ess-gen-proc-buffer-name-function'."
+  (format "*%s:%s*" proc-name (file-name-nondirectory
+                               (directory-file-name default-directory))))
+
+(defun ess-gen-proc-buffer-name:abbr-long-directory (proc-name)
+  "Return a buffer name in the form *PROC-NAME:ABBREVIATED-LONG-DIR-NAME*.
+PROC-NAME is a string representing an internal process
+name. ABBREVIATED-LONG-DIR-NAME is an abbreviated full directory
+name. Abbreviation is performed by `abbreviate-file-name'. See
+`ess-gen-proc-buffer-name-function'."
+  (format "*%s:%s*" proc-name (abbreviate-file-name default-directory)))
+
+(defun ess-gen-proc-buffer-name:project-or-simple (proc-name)
+  "Function to generate buffer name in the form *PROC-NAME:PROJECT-ROOT*.
+PROC-NAME is a string representing an internal process name. If
+no project directory has been found use
+`ess-gen-proc-buffer-name:simple'. See
+`ess-gen-proc-buffer-name-function'."
+  (if-let ((p (project-current))
+           (proj (ess--project-root p)))
+      (format "*%s:%s*" proc-name (file-name-nondirectory
+                                   (directory-file-name proj)))
+    (ess-gen-proc-buffer-name:simple proc-name)))
+
+(defun ess-gen-proc-buffer-name:project-or-directory (proc-name)
+  "Function to generate buffer name in the form *PROC-NAME:PROJECT-ROOT*.
+PROC-NAME is a string representing an internal process name.
+PROJECT-ROOT is directory name returned by `ess--project-root' if
+defined. If no project directory has been found, use
+`ess-gen-proc-buffer-name:directory'. See
+`ess-gen-proc-buffer-name-function'."
+  (if-let ((p (project-current))
+           (proj (ess--project-root p)))
+      (format "*%s:%s*" proc-name (file-name-nondirectory
+                                   (directory-file-name proj)))
+    (ess-gen-proc-buffer-name:directory proc-name)))
+
+;; This ensures that people who have this set in their init file don't
+;; get errors about undefined functions after upgrading ESS:
+(define-obsolete-function-alias 'ess-gen-proc-buffer-name:projectile-or-simple
+  #'ess-gen-proc-buffer-name:project-or-simple "ESS 19.04")
+(define-obsolete-function-alias 'ess-gen-proc-buffer-name:projectile-or-directory
+  #'ess-gen-proc-buffer-name:project-or-directory "ESS 19.04")
+
+(defun inferior-ess-available-p (&optional proc)
+  "Return non-nil if PROC is not busy."
+  (when-let ((proc (or proc (ess-get-current-process))))
+    (unless (process-get proc 'busy)
+      (or (ess-debug-active-p proc) ; don't send empty lines in debugger
+          (when-let ((last-check (process-get proc 'last-availability-check)))
+            (time-less-p (process-get proc 'last-eval) last-check))
+          (progn
+            ;; Send an empty string and waiting a bit to make sure we are not busy.
+            (process-send-string proc "\n")
+            (inferior-ess-mark-as-busy proc)
+            (process-put proc 'availability-check t)
+            ;; Start with a very conservative waiting time and quickly average
+            ;; down to the actual response.
+            (let ((avresp (or (process-get proc 'average-response-time) 0.1))
+                  (ts (current-time)))
+              (when (accept-process-output proc (max 0.005 (* 2.0 avresp)))
+                (let ((avresp (/ (+ (* 2.0 avresp)
+                                    (float-time (time-subtract (current-time) ts)))
+                                 3.0)))
+                  (process-put proc 'average-response-time avresp)))
+              (process-put proc 'last-availability-check ts))
+            (not (process-get proc 'busy)))))))
+
+(defun inferior-ess--set-status (proc string)
+  "Internal function to set the status of process PROC.
+Return non-nil if the process is in a ready (not busy) state."
+  ;; TODO: do it in one search, use starting position, use prog1
+  (let ((ready (string-match-p (concat "\\(" inferior-ess-primary-prompt "\\)\\'") string)))
+    (process-put proc 'busy-end? (and ready (process-get proc 'busy)))
+    ;; When "\n" inserted from inferior-ess-available-p, delete the prompt.
+    (when (and ready
+               (process-get proc 'availability-check)
+               (string-match-p (concat inferior-ess-primary-prompt "\\'") string))
+      (process-put proc 'suppress-next-output? t))
+    (process-put proc 'availability-check nil)
+    (when ready
+      (process-put proc 'running-async? nil))
+    (process-put proc 'busy (not ready))
+    (process-put proc 'sec-prompt
+                 (when inferior-ess-secondary-prompt
+                   (string-match (concat "\\(" inferior-ess-secondary-prompt "\\)\\'") string)))
+    ready))
+
+(defun ess--command-delimited-output-info (buf delim)
+  "Detect positions of accumulated output.
+Return positions after START, before END, after prompt. If any is
+not found, returns nil. The last position marks the start of new
+output, if any."
+  (with-current-buffer buf
+    (save-excursion
+      (save-match-data
+        (goto-char (point-min))
+        (when (re-search-forward (ess--delimiter-start-re delim) nil t)
+          (let ((start (1+ (match-end 0))))
+            (when (re-search-forward (ess--delimiter-end-re delim) nil t)
+              (when (not (equal (line-beginning-position)
+                                (match-beginning 0)))
+                (error "Missing newline in command output"))
+              (let ((end (max (1- (match-beginning 0))
+                              start)))
+                (goto-char (1+ (match-end 0)))
+                (when (re-search-forward inferior-ess-primary-prompt nil t)
+                  (let* ((prompt-end (match-end 0))
+                         (new (when (> (point-max) prompt-end)
+                                prompt-end)))
+                    (list start end new)))))))))))
+
+(defun ess--command-output-info (buf)
+  "Detect positions of accumulated output.
+Like `ess--command-delimited-output-info' but detects prompts
+without the benefit of output delimiters. This is much less
+robust. This might leave parasite output at the start of BUF
+(e.g. `+' prompts with multiline commands). The result might be
+incomplete if the command output includes a line that ends with
+`> ' and which happens to be the last characters in a partial
+output (process output passed to filters is split in batches at
+arbitrary locations). In that case the rest of the output will be
+inserted in the process buffer instead of the command buffer."
+  (with-current-buffer buf
+    (save-excursion
+      (save-match-data
+        (goto-char (point-min))
+        (when (re-search-forward (concat inferior-ess-primary-prompt
+                                         "\\(\n\\|\\'\\)")
+                                 nil t)
+          (goto-char (match-beginning 0))
+          (let ((end (max (1- (line-beginning-position))
+                          (point-min)))
+                (new (when (> (point-max) (line-end-position))
+                       (1+ (line-end-position)))))
+            (list (point-min) end new)))))))
+
+;; Be careful that new output might come in after the closing
+;; delimiter or prompt. This could happen when a background command is
+;; interrupted asynchronously and the user has sent new inputs before
+;; the process has finished interrupting.
+(defun ess--command-set-status (proc buf info)
+  (with-current-buffer buf
+    (unwind-protect
+        (progn
+          (let* ((beg (nth 0 info))
+                 (end (nth 1 info))
+                 (new (nth 2 info))
+                 (output (buffer-substring beg end))
+                 (new-output (when new
+                               (buffer-substring new (point-max)))))
+            ;; Delete the start delimiter and anything before it.
+            ;; This takes care of `+` continuation lines that occur
+            ;; with multi-line commands. Delete anything after the
+            ;; end delimiter, including the prompt and new output
+            (delete-region (point-min) (point-max))
+            (insert output)
+            new-output))
+      (process-put proc 'busy nil))))
+
+(defun ess--delimiter-start-re (delim)
+  (concat "\\(" delim "-START\r*$\\)"))
+
+(defun ess--delimiter-end-re (delim)
+  (concat "\\(" delim "-END\r*\\)"))
+
+(defun ess--delimiter-error-start-re ()
+  "\1e\1eESSR::ERROR \\(\"\\)")
+
+(defun ess--delimiter-error-end-re ()
+  "\\(\"\\)\1e\1e")
+
+(defun inferior-ess-mark-as-busy (proc)
+  "Put PROC's busy value to t."
+  (process-put proc 'busy t)
+  (process-put proc 'sec-prompt nil))
+
+(defun inferior-ess-run-callback (proc string)
+  ;; callback is stored in 'callbacks proc property. Callbacks is a list that
+  ;; can contain either functions to be called with two arguments PROC and
+  ;; STRING, or cons cells of the form (func . suppress). If SUPPRESS is non-nil
+  ;; next process output will be suppressed.
+  (unless (process-get proc 'busy)
+    ;; only one callback is implemented for now
+    (let* ((cb (car (process-get proc 'callbacks)))
+           (listp (not (functionp cb)))
+           (suppress (and listp (consp cb) (cdr cb)))
+           (cb (if (and listp (consp cb))
+                   (car cb)
+                 cb)))
+      (when cb
+        (when ess-verbose
+          (ess-write-to-dribble-buffer "executing callback ...\n"))
+        (when suppress
+          (process-put proc 'suppress-next-output? t))
+        (process-put proc 'callbacks nil)
+        (condition-case-unless-debug err
+            (funcall cb proc string)
+          (error (message "%s" (error-message-string err))))))))
+
+(defun ess--if-verbose-write-process-state (proc string &optional filter)
+  "Write information about PROC, STRING, and FILTER to the dribble buffer."
+  (ess-if-verbose-write
+   (format "\n%s:
+    --> busy:%s busy-end:%s sec-prompt:%s interruptable:%s <--
+    --> running-async:%s callback:%s suppress-next-output:%s <--
+    --> dbg-active:%s is-recover:%s <--
+    --> cmd-buffer:%s cmd-output-delimiter:%s <--
+    --> string:%s<--\n"
+           (upcase (or filter "normal-filter"))
+           (process-get proc 'busy)
+           (process-get proc 'busy-end?)
+           (process-get proc 'sec-prompt)
+           (process-get proc 'interruptable?)
+           (process-get proc 'running-async?)
+           (if (process-get proc 'callbacks) "yes")
+           (process-get proc 'suppress-next-output?)
+           (process-get proc 'dbg-active)
+           (process-get proc 'is-recover)
+           (process-get proc 'cmd-buffer)
+           (process-get proc 'cmd-output-delimiter)
+           (if (> (length string) 150)
+               (format "%s .... %s" (substring string 0 50) (substring string -50))
+             string))))
+
+(defun inferior-ess-output-filter (proc string)
+  "Standard output filter for the inferior ESS process PROC.
+Ring Emacs bell if process output starts with an ASCII bell, and pass
+the rest to `comint-output-filter'.
+Taken from octave-mod.el."
+  (inferior-ess--set-status proc string)
+  (ess--if-verbose-write-process-state proc string)
+  (inferior-ess-run-callback proc string)
+  (if (process-get proc 'suppress-next-output?)
+      ;; works only for suppressing short output, for time being is enough (for callbacks)
+      (process-put proc 'suppress-next-output? nil)
+    (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 PROC.
+This marks the process with a MESSAGE, at a particular time point."
+  (let ((abuf (process-get proc :accum-buffer)))
+    (when (buffer-live-p abuf)
+      (kill-buffer abuf)))
+  (let ((pbuf (process-buffer proc)))
+    (when (buffer-live-p pbuf)
+      (with-current-buffer pbuf
+        (save-excursion
+          (setq message (substring message 0 -1)) ; strip newline
+          (set-buffer (process-buffer proc))
+          (comint-write-input-ring)
+          (goto-char (point-max))
+          (insert-before-markers
+           (format "\nProcess %s %s at %s\n"
+                   (process-name proc) message (current-time-string))))))))
+
+;; FIXME: This list is structured as '(("R:2") ("R")). It doesn't
+;; appear the CDR are used. Can probably just be '("R:2" "R").
+(defvar ess-process-name-list nil
+  "Alist of active ESS processes.")
+
+(defun inferior-ess--start-process (buf proc-name switches)
+  "Make a comint process in buffer BUF with process PROC-NAME.
+SWITCHES is passed to `comint-exec'. BUF is guaranteed to be a
+process-less buffer because it was created with
+`inferior-ess--get-proc-buffer-create'."
+  (with-current-buffer buf
+    (if (eq (buffer-size) 0) nil
+      (goto-char (point-max))
+      (insert "\^L\n")))
+  (let ((process-environment
+         (nconc
+          (list "STATATERM=emacs"
+                (format "PAGER=%s" inferior-ess-pager))
+          ;; This lets R code know whether Emacs was running with a
+          ;; light or dark background at startup time
+          (let ((bg-mode (frame-parameter nil 'background-mode)))
+            (when (memq bg-mode '(light dark))
+              (list (format "ESS_BACKGROUND_MODE=%s" (symbol-name bg-mode)))))
+          process-environment))
+        (tramp-remote-process-environment
+         (nconc ;; it contains a pager already, so append
+          (when (boundp 'tramp-remote-process-environment)
+            (copy-sequence tramp-remote-process-environment))
+          (list "STATATERM=emacs"
+                (format "PAGER=%s" inferior-ess-pager)))))
+    (comint-exec buf
+                 proc-name
+                 inferior-ess-program
+                 nil
+                 (when switches
+                   (split-string switches))))
+  (let ((proc (get-buffer-process buf)))
+    ;; Set the process hooks
+    (set-process-sentinel proc #'ess-process-sentinel)
+    (set-process-filter proc #'inferior-ess-output-filter)
+    (inferior-ess-mark-as-busy proc)
+    ;; Add this process to ess-process-name-list, if needed
+    (let ((conselt (assoc proc-name ess-process-name-list)))
+      (unless conselt
+        (setq ess-process-name-list
+              (cons (cons proc-name nil) ess-process-name-list))))
+    proc))
+
+
+;;*;; Requester functions called at startup
+(defun inferior-ess--get-startup-directory ()
+  "Return a startup directory."
+  (let ((dir (or (when (boundp 'ess-startup-directory)
+                   (if (symbolp ess-startup-directory)
+                       (symbol-value ess-startup-directory)
+                     ess-startup-directory))
+                 (and ess-startup-directory-function
+                      (funcall ess-startup-directory-function))
+                 (when-let ((proj (project-current)))
+                   (ess--project-root proj))
+                 default-directory)))
+    (directory-file-name dir)))
+
+(defun inferior-ess--maybe-prompt-startup-directory (procname _dialect)
+  "Possibly prompt for a startup directory.
+When `ess-ask-for-ess-directory' is non-nil, prompt.  PROCNAME is
+the name of the inferior process (e.g. \"R:1\"), and DIALECT is
+the language dialect (e.g. \"R\")."
+  (let ((default-dir (inferior-ess--get-startup-directory)))
+    (if ess-ask-for-ess-directory
+        (let ((prompt (format "%s starting project directory? " procname))
+              (display-buffer-overriding-action nil) ; hack to let helm display a buffer
+              )
+          (ess-prompt-for-directory default-dir prompt))
+      default-dir)))
+
+(defun ess-prompt-for-directory (default prompt)
+  "PROMPT for a directory, using DEFAULT as the usual."
+  (let* ((def-dir (file-name-as-directory default))
+         (the-dir (expand-file-name
+                   (file-name-as-directory
+                    (read-directory-name prompt def-dir def-dir t nil)))))
+    (if (file-directory-p the-dir) nil
+      (error "%s is not a valid directory" the-dir))
+    the-dir))
+
+
+;;*;; General process handling code
+
+(defmacro ess-with-current-buffer (buffer &rest body)
+  "Like `with-current-buffer' but with transfer of some essential
+local ESS vars like `ess-local-process-name'."
+  (declare (indent 1) (debug t))
+  (let ((lpn (make-symbol "lpn"))
+        (dialect (make-symbol "dialect"))
+        (alist (make-symbol "alist")))
+    `(let ((,lpn ess-local-process-name)
+           (,dialect ess-dialect)
+           (,alist ess-local-customize-alist))
+       (with-current-buffer ,buffer
+         (ess-setq-vars-local (eval ,alist t))
+         (setq ess-local-process-name ,lpn)
+         (setq ess-dialect ,dialect)
+         ,@body))))
+
+(dolist (mode '(emacs-lisp-mode lisp-interaction-mode))
+  (font-lock-add-keywords
+   mode
+   '(("(\\(ess-with-current-buffer\\)\\s +\\(\\(\\w\\|\\s_\\)+\\)"
+      (1 font-lock-keyword-face)
+      (2 font-lock-variable-name-face)))))
+
+(defun ess-get-process (&optional name use-another)
+  "Return the ESS process named by NAME.
+If USE-ANOTHER is non-nil, and the process NAME is not
+running (anymore), try to connect to another if there is one. By
+default (USE-ANOTHER is nil), the connection to another process
+happens interactively (when possible)."
+  (setq name (or name ess-local-process-name))
+  (cl-assert name nil "No ESS process is associated with this buffer now")
+  (update-ess-process-name-list)
+  (cond ((assoc name ess-process-name-list)
+         (get-process name))
+        ((= 0 (length ess-process-name-list))
+         (save-current-buffer
+           (message "trying to (re)start process %s for language %s ..."
+                    name ess-language)
+           (ess-start-process-specific ess-language ess-dialect)
+           ;; and return the process: "call me again"
+           (ess-get-process name)))
+        ;; else: there are other running processes
+        (use-another ; connect to another running process : the first one
+         (let ((other-name (car (elt ess-process-name-list 0))))
+           ;; "FIXME": try to find the process name that matches *closest*
+           (message "associating with *other* process '%s'" other-name)
+           (ess-get-process other-name)))
+        ((and (not noninteractive)
+              (y-or-n-p
+               (format "Process %s is not running, but others are. Switch? " name)))
+         (ess-force-buffer-current (concat ess-dialect " process to use: ") 'force)
+         (ess-get-process ess-current-process-name))
+        (t (error "Process %s is not running" name))))
+
+(defun inferior-ess-default-directory ()
+  "Return the `default-directory' of the process."
+  (ess-get-process-variable 'default-directory))
+
+;;--- Unfinished idea (ESS-help / R-help ) -- probably not worth it...
+;;- (defun ess-set-inferior-program (filename)
+;;-   "Allows to set or change `inferior-ess-program', the program (file)name."
+;;-   (interactive "fR executable (script) file: ")
+;;-   ;; "f" : existing file {file name completion} !
+;;-   (setq inferior-ess-program filename))
+;; the inferior-ess-program is initialized in the customize..alist,
+;; e.g. from  inferior-ess-r-program ... --> should change rather these.
+;; However these really depend on the current ess-language!
+;; Plan: 1) must know and use ess-language
+;;       2) change the appropriate  inferior-<ESSlang>-program
+;; (how?) in R/S : assign(paste("inferior-",ESSlang,"-p...."),  filename))
+
+
+;;*;; Multiple process handling code
+
+;; FIXME: It seems the only effect of this function is to remove dead
+;; processes from `ess-process-name-list'. Am I missing something?
+(defun ess-make-buffer-current nil
+  "Make the process associated with the current buffer the current ESS process.
+Returns the name of the process, or nil if the current buffer has none."
+  (update-ess-process-name-list)
+  ;; (if ess-local-process-name
+  ;;     (setq ess-current-process-name ess-local-process-name))
+  ess-local-process-name)
+
+(defun ess-get-process-variable (var)
+  "Return the variable VAR (symbol) local to ESS process called NAME (string)."
+  (buffer-local-value var (process-buffer (ess-get-process ess-local-process-name))))
+
+(defun ess-set-process-variable (var val)
+  "Set variable VAR (symbol) local to ESS process called NAME (string) to VAL."
+  (with-current-buffer (process-buffer (ess-get-process ess-local-process-name))
+    (set var val)))
+
+(defun ess-process-live-p (&optional proc)
+  "Check if the local ess process is alive.
+Return nil if current buffer has no associated process, or
+process was killed. PROC defaults to `ess-local-process-name'"
+  (when-let ((proc (or proc (ess-get-current-process))))
+    (process-live-p proc)))
+
+(defun ess-process-get (propname &optional proc)
+  "Return the variable PROPNAME (symbol) of the current ESS process.
+PROC defaults to process with name `ess-local-process-name'."
+  (process-get (or proc (get-process ess-local-process-name)) propname))
+
+(defun ess-process-put (propname value &optional proc)
+  "Set the variable PROPNAME (symbol) to VALUE in the current ESS process.
+PROC defaults to the process given by `ess-local-process-name'"
+  (process-put (or proc (get-process ess-local-process-name)) propname value))
+
+(defun ess-start-process-specific (language dialect)
+  "Start an ESS process.
+Typically from a language-specific buffer, using DIALECT.
+LANGUAGE is ignored."
+  (save-current-buffer
+    (let ((dsymb (intern dialect)))
+      (if (fboundp dsymb)
+          (funcall dsymb)
+        (error "No ESS processes running; not yet implemented to start (%s,%s)"
+               language dialect)))))
+
+(defmacro ess--with-no-pop-to-buffer (&rest body)
+  "Disable some effects of `pop-to-buffer'.
+Prevent `display-buffer' from performing an action and save the
+current buffer to prevent `pop-to-buffer' from setting a new
+current buffer."
+  ;; `pop-to-buffer' might still raise windows and frames so it may be
+  ;; better to have our own configurable `ess--pop-to-buffer' wrapper.
+  (declare (indent 0)
+           (debug (&rest form)))
+  `(let ((display-buffer-overriding-action '(display-buffer-no-window (allow-no-window . t))))
+     (save-current-buffer
+       ,@body)))
+
+(defun ess-request-a-process (message &optional noswitch ask-if-1)
+  "Ask for a process, and make it the current ESS process.
+If there is exactly one process, only ask if ASK-IF-1 is non-nil.
+Also switches to the process buffer unless NOSWITCH is non-nil.
+Interactively, NOSWITCH can be set by giving a prefix argument.
+Returns the name of the selected process. MESSAGE may get passed
+to `ess-completing-read'."
+  (interactive (list "Switch to which ESS process? " current-prefix-arg))
+  (update-ess-process-name-list)
+  (let* ((ess-dialect (or ess-dialect
+                          (ess-completing-read
+                           "Set `ess-dialect'"
+                           (delete-dups (list "R" "S+" (or (bound-and-true-p S+-dialect-name) "S+")
+                                              "stata" (or (bound-and-true-p STA-dialect-name) "stata")
+                                              "julia" "SAS")))))
+         (pname-list (delq nil ;; keep only those matching dialect and `ess-gen-proc-buffer-name-function'
+                           (append
+                            (mapcar (lambda (lproc)
+                                      (and (equal ess-dialect
+                                                  (buffer-local-value
+                                                   'ess-dialect
+                                                   (process-buffer (get-process (car lproc)))))
+                                           (not (equal ess-local-process-name (car lproc)))
+                                           (car lproc)))
+                                    ess-process-name-list)
+                            ;; append local only if running
+                            (when (assoc ess-local-process-name ess-process-name-list)
+                              (list ess-local-process-name)))))
+         (num-processes (length pname-list))
+         proc auto-started?)
+    (when (or (= 0 num-processes)
+              (and (= 1 num-processes)
+                   (not (equal ess-dialect ;; don't auto connect if from different dialect
+                               (buffer-local-value
+                                'ess-dialect
+                                (process-buffer (get-process
+                                                 (car pname-list))))))))
+      ;; Try to start "the appropriate" process, don't show the buffer
+      ;; since we handle that explicitly with no-switch
+      (ess-if-verbose-write
+       "ess-request-a-process: Can't find a process, starting a new one\n")
+      (ess--with-no-pop-to-buffer
+        (ess-start-process-specific ess-language ess-dialect))
+      (setq num-processes 1
+            pname-list (car ess-process-name-list)
+            auto-started? t))
+    ;; now num-processes >= 1 :
+    (let* ((proc-buffers (mapcar (lambda (lproc)
+                                   (buffer-name (process-buffer (get-process lproc))))
+                                 pname-list)))
+      (setq proc
+            (if (or auto-started?
+                    (and (not ask-if-1)
+                         (= 1 num-processes)
+                         (message "Using process `%s'" (car proc-buffers))))
+                (car pname-list)
+              (unless (and ess-current-process-name
+                           (get-process ess-current-process-name))
+                (setq ess-current-process-name nil))
+              ;; ask for buffer name not the *real* process name:
+              (let ((buf (ess-completing-read message (append proc-buffers (list "*new*")) nil t nil nil)))
+                (if (not (equal buf "*new*"))
+                    (process-name (get-buffer-process buf))
+                  ;; Prevent new process buffer from being popped
+                  ;; because we handle display depending on the value
+                  ;; of `no-switch`
+                  (ess-if-verbose-write
+                   "ess-request-a-process: User requested a new process\n")
+                  (ess--with-no-pop-to-buffer
+                    (ess-start-process-specific ess-language ess-dialect))
+                  (caar ess-process-name-list))))))
+    ;; Always display buffer if auto-started but do not select it if
+    ;; NOSWITCH is set
+    (when (or auto-started? (not noswitch))
+      (let ((proc-buf (ess-get-process-buffer proc)))
+        (if noswitch
+            (display-buffer proc-buf)
+          (pop-to-buffer proc-buf))
+        ;; If inferior startup has already finished, set screen
+        ;; options again in case the post-run hook ran before a new
+        ;; screen config was created by `pop-to-buffer' (#1243).
+        (with-current-buffer proc-buf
+          (ess--execute-screen-options-bg))))
+    proc))
+
+(defun ess-force-buffer-current (&optional prompt force no-autostart ask-if-1)
+  "Make sure the current buffer is attached to an ESS process.
+If not, or FORCE (prefix argument) is non-nil, prompt for a
+process name with PROMPT. If NO-AUTOSTART is nil starts the new
+process if process associated with current buffer has
+died. `ess-local-process-name' is set to the name of the process
+selected.  `ess-dialect' is set to the dialect associated with
+the process selected. ASK-IF-1 asks user for the process, even if
+there is only one process running.  Returns the inferior buffer if
+it was successfully forced, throws an error otherwise."
+  (interactive
+   (list (concat ess-dialect " process to use: ") current-prefix-arg nil))
+  (let ((proc-name (ess-make-buffer-current)))
+    (cond ((and (not force) proc-name (get-process proc-name)))
+          ;; Make sure the source buffer is attached to a process
+          ((and ess-local-process-name (not force) no-autostart)
+           (error "Process %s has died" ess-local-process-name))
+          ;; Request a process if `ess-local-process-name' is nil
+          (t
+           (let* ((prompt (or prompt "Process to use: "))
+                  (proc (ess-request-a-process prompt 'no-switch ask-if-1)))
+             (setq ess-local-process-name proc)))))
+  (process-buffer (get-process ess-local-process-name)))
+
+(defalias 'inferior-ess-force #'ess-force-buffer-current)
+
+(defun ess-switch-process ()
+  "Force a switch to a new underlying process."
+  (interactive)
+  (ess-force-buffer-current "Process to use: " 'force nil 'ask-if-1))
+
+(defun ess-get-current-process ()
+  (when ess-local-process-name
+    (get-process ess-local-process-name)))
+
+(defun ess-get-current-process-buffer ()
+  (when-let ((proc (ess-get-current-process)))
+    (process-buffer proc)))
+
+(defun ess-get-next-available-process (&optional dialect ignore-busy background)
+  "Return first available (aka not busy) process of dialect DIALECT.
+DIALECT defaults to the local value of ess-dialect. Return nil if
+no such process has been found. If BACKGROUND is non-nil, only
+processes that are allowed to evaluate in the background are
+matched."
+  (setq dialect (or dialect ess-dialect))
+  (when (and dialect (or (not background)
+                         ess-can-eval-in-background))
+    (let (proc)
+      (catch 'found
+        (dolist (p (cons ess-local-process-name
+                         (mapcar #'car ess-process-name-list)))
+          (when p
+            (setq proc (get-process p))
+            (when (and proc
+                       (process-live-p proc)
+                       (equal dialect
+                              (buffer-local-value 'ess-dialect (process-buffer proc)))
+                       ;; Check that we can evaluate in background
+                       ;; before checking for availability to
+                       ;; avoid issues with newline handshakes
+                       (or (not background)
+                           (ess-can-eval-in-background proc))
+                       (or ignore-busy
+                           (inferior-ess-available-p proc)))
+              (throw 'found proc))))))))
+
+(defun ess-get-next-available-bg-process (&optional proc dialect ignore-busy)
+  "Returns first avaiable process only if background evaluations are allowed.
+Same as `ess-get-next-available-process' but checks for
+`ess-can-eval-in-background'."
+  (if proc
+      (ess-can-eval-in-background proc)
+    (ess-get-next-available-process dialect ignore-busy 'background)))
+
+
+;;*;;; Commands for switching to the process buffer
+
+(defun ess-switch-to-ESS (eob-p)
+  "Switch to the current inferior ESS process buffer.
+With (prefix) EOB-P non-nil, positions cursor at end of buffer."
+  (interactive "P")
+  (ess-force-buffer-current)
+  (pop-to-buffer (buffer-name (process-buffer (get-process ess-current-process-name)))
+                 '(nil . ((inhibit-same-window . t))))
+  (when eob-p (goto-char (point-max))))
+
+(defun ess-switch-to-end-of-ESS ()
+  "Switch to the end of the inferior ESS process buffer."
+  (interactive)
+  (ess-switch-to-ESS t))
+
+(defun ess-switch-to-inferior-or-script-buffer (toggle-eob)
+  "Switch between script and process buffer.
+This is a single-key command. Assuming that it is bound to C-c
+C-z, you can navigate back and forth between iESS and script
+buffer with C-c C-z C-z C-z ... If variable
+`ess-switch-to-end-of-proc-buffer' is t (the default) this
+function switches to the end of process buffer. If TOGGLE-EOB is
+given, the value of `ess-switch-to-end-of-proc-buffer' is
+toggled."
+  (interactive "P")
+  (let ((eob (if toggle-eob
+                 (not ess-switch-to-end-of-proc-buffer)
+               ess-switch-to-end-of-proc-buffer)))
+    (if (derived-mode-p 'inferior-ess-mode)
+        (let ((dialect ess-dialect)
+              (proc-name ess-local-process-name)
+              (blist (buffer-list)))
+          (while (and (pop blist)
+                      (with-current-buffer (car blist)
+                        (not (or (and (ess-derived-mode-p)
+                                      (equal dialect ess-dialect)
+                                      (null ess-local-process-name))
+                                 (and (ess-derived-mode-p)
+                                      (equal proc-name ess-local-process-name)))))))
+          (if blist
+              (pop-to-buffer (car blist))
+            (message "Found no buffers for `ess-dialect' %s associated with process %s"
+                     dialect proc-name)))
+      (ess-switch-to-ESS eob))
+    (when (called-interactively-p 'any)
+      (set-transient-map (let ((map (make-sparse-keymap))
+                               (key (vector last-command-event)))
+                           (define-key map key #'ess-switch-to-inferior-or-script-buffer) map)))))
+
+
+(defun ess-get-process-buffer (&optional name)
+  "Return the buffer associated with the ESS process named by NAME."
+  (process-buffer (ess-get-process (or name ess-local-process-name))))
+
+(defun update-ess-process-name-list ()
+  "Remove names with no process."
+  (let (defunct)
+    (dolist (conselt ess-process-name-list)
+      (let ((proc (get-process (car conselt))))
+        (unless (and proc (eq (process-status proc) 'run))
+          (push conselt defunct))))
+    (dolist (pointer defunct)
+      (setq ess-process-name-list (delq pointer ess-process-name-list))))
+  (if (eq (length ess-process-name-list) 0)
+      (setq ess-current-process-name nil)))
+
+\f
+;;; Functions for evaluating code
+
+;;*;; Utils for evaluation
+
+(defun ess-build-eval-command (string &optional visibly output file &rest args)
+  "Format an evaluation command.
+Wrap STRING with `ess-quote-special-chars' and dispatch on
+`ess-build-eval-command--override'."
+  (setq string (ess-quote-special-chars string))
+  (ess-build-eval-command--override string visibly output file args))
+
+(cl-defgeneric ess-build-eval-command--override
+    (string &optional _visibly _output file &rest _args)
+  "Default method to build eval command."
+  (and ess-eval-command
+       (format-spec ess-eval-command
+                    `((?s . ,string)
+                      (?f . ,file)))))
+
+(cl-defgeneric ess-build-load-command (file &optional _visibly _output &rest _args)
+  "Format a loading command.
+Dispatches on the dialect-specific `ess-build-load-command'
+and `ess-load-command', in that order."
+  (and ess-load-command
+       (format ess-load-command file)))
+
+(defun ess-wait-for-process (&optional proc sec-prompt wait force-redisplay timeout)
+  "Wait for \\='busy property of the process to become nil.
+If SEC-PROMPT is non-nil return if secondary prompt is detected
+regardless of whether primary prompt was detected or not. If WAIT
+is non-nil wait for WAIT seconds for process output before the
+prompt check, default 0.002s. When FORCE-REDISPLAY is non-nil
+force redisplay. You better use WAIT >= 0.1 if you need
+FORCE-REDISPLAY to avoid excessive redisplay. If TIMEOUT is
+non-nil stop waiting for output after TIMEOUT seconds.
+
+Returns nil if TIMEOUT was reached, non-nil otherwise."
+  (setq proc (or proc (get-process ess-local-process-name)))
+  (setq wait (or wait 0.005))
+  (setq timeout (or timeout most-positive-fixnum))
+  (let ((start-time (float-time))
+        (elapsed 0))
+    (save-excursion
+      (while (and
+              (or (eq (process-status proc) 'run)
+                  (progn
+                    (when (process-buffer proc)
+                      (display-buffer (process-buffer proc)))
+                    (error "ESS process has died unexpectedly")))
+              (< elapsed timeout)
+              (or (accept-process-output proc wait)
+                  (unless (and sec-prompt (process-get proc 'sec-prompt))
+                    (process-get proc 'busy))))
+        (when force-redisplay
+          (redisplay 'force))
+        (setq elapsed (- (float-time) start-time))
+        (when (>  elapsed .3)
+          (setq wait .3))))
+    (< elapsed timeout)))
+
+;; This filter is active under `ess-command`
+(defun inferior-ess-ordinary-filter (proc string)
+  (ess--if-verbose-write-process-state proc string "ordinary-filter")
+  (let* ((cmd-buf (process-get proc 'cmd-buffer))
+         (cmd-delim (process-get proc 'cmd-output-delimiter)))
+    (when (buffer-live-p cmd-buf)
+      (ess--exit-protect
+          (progn
+            (with-current-buffer cmd-buf
+              (goto-char (point-max))
+              (insert string))
+            (if-let ((info (if cmd-delim
+                               (ess--command-delimited-output-info cmd-buf cmd-delim)
+                             (ess--command-output-info cmd-buf))))
+                (let ((new-output (ess--command-set-status proc cmd-buf info)))
+                  (ess-if-verbose-write
+                   "ess-command (filter): Found prompt\n")
+                  (when (not (process-get proc 'busy))
+                    ;; Store new output until restoration
+                    (when new-output
+                      (process-put proc 'pending-output new-output))
+                    ;; Restore the user's process filter as soon as process is
+                    ;; available
+                    (funcall (process-get proc 'cmd-restore-function))
+                    ;; Run callback with command output
+                    (when (process-get proc 'callbacks)
+                      (inferior-ess-run-callback proc (with-current-buffer cmd-buf
+                                                        (buffer-string))))))
+              (ess-if-verbose-write
+               "ess-command (filter): Accumulating output\n")))
+        ;; Be defensive when something goes wrong. Restore process to a
+        ;; usable state.
+        (ess-if-verbose-write
+         "ess-command (filter): Early exit\n")
+        (process-put proc 'busy nil)
+        (funcall (process-get proc 'cmd-restore-function))))))
+
+(defvar ess-presend-filter-functions nil
+  "List of functions to call before sending the input string to the process.
+Each function gets one argument, a string containing the text to
+be send to the subprocess.  It should return the string sent,
+perhaps the same string that was received, or perhaps a modified
+or transformed string.
+
+The functions on the list are called sequentially, and each one
+is given the string returned by the previous one. The string
+returned by the last function is the text that is actually sent
+to the process. You can use `add-hook' to add functions to this
+list either globally or locally. The hook is executed in current
+buffer. Before execution, the local value of this hook in the
+process buffer is appended to the hook from the current buffer.")
+
+(defvar ess--inhibit-presend-hooks nil
+  "If non-nil don't run presend hooks.")
+
+(defun ess--run-presend-hooks (process string)
+  ;; run ess-presend-filter-functions and comint-input-filter-functions
+  (if ess--inhibit-presend-hooks
+      string
+    ;;return modified string
+    (let* ((pbuf (process-buffer process))
+           ;; also run proc buffer local hooks
+           (functions (unless (eq pbuf (current-buffer))
+                        (buffer-local-value 'ess-presend-filter-functions pbuf))))
+      (setq functions (append  (delq t (copy-sequence functions)) ;; even in let, delq destructs
+                               ess-presend-filter-functions))
+      (while (and functions string)
+        ;; cannot use run-hook-with-args here because string must be passed from one
+        ;; function to another
+        (if (eq (car functions) t)
+            (let ((functions
+                   (default-value 'ess-presend-filter-functions)))
+              (while (and functions string)
+                (setq string (funcall (car functions) string))
+                (setq functions (cdr functions))))
+          (setq string (funcall (car functions) string)))
+        (setq functions (cdr functions)))
+      (with-current-buffer pbuf
+        (run-hook-with-args 'comint-input-filter-functions string))
+      string)))
+
+(defun ess--concat-new-line-maybe (string)
+  "Append \\n at the end of STRING if missing."
+  (if (string-match "\n\\'" string (max (- (length string) 2) 0))
+      string
+    (concat string "\n")))
+
+(defvar ess--dbg-del-empty-p t
+  "Internal variable to control removal of empty lines during the debugging.
+Let-bind it to nil before calling `ess-send-string' or
+`ess-send-region' if no removal is necessary.")
+
+(defun inferior-ess--interrupt-subjob-maybe (proc)
+  "Internal. Interrupt the process if interruptable? process variable is non-nil.
+Hide all the junk output in temporary buffer."
+  (when (process-get proc 'interruptable?)
+    (let ((cb (cadr (process-get proc 'callbacks)))
+          (buf (get-buffer-create " *ess-temp-buff*"))
+          (old-filter (process-filter proc))
+          (old-buff (process-buffer proc)))
+      (unwind-protect
+          (progn
+            (ess-if-verbose-write "interrupting subjob ... start")
+            (process-put proc 'interruptable? nil)
+            (process-put proc 'callbacks nil)
+            (process-put proc 'running-async? nil)
+            ;; this is to avoid putting junk in user's buffer on process
+            ;; interruption
+            (set-process-buffer proc buf)
+            (set-process-filter proc #'inferior-ess-ordinary-filter)
+            (interrupt-process proc)
+            (when cb
+              (ess-if-verbose-write "executing interruption callback ... ")
+              (funcall cb proc))
+            ;; should be very fast as it inputs only the prompt
+            (ess-wait-for-process proc)
+            (ess-if-verbose-write "interrupting subjob ... finished")
+            )
+        (set-process-buffer proc old-buff)
+        (set-process-filter proc old-filter)))))
+
+\f
+;;*;; Evaluation primitives
+
+(defun ess-send-string (process string &optional visibly message _type)
+  "ESS wrapper for `process-send-string'.
+Run `comint-input-filter-functions' and current buffer's and
+PROCESS' `ess-presend-filter-functions' hooks on the input
+STRING. VISIBLY can be nil, t, \\='nowait or a string.  If string
+the behavior is as with \\='nowait with the differences that
+inserted string is VISIBLY instead of STRING (evaluated command
+is still STRING).  In all other cases the behavior is as
+described in `ess-eval-visibly'. STRING need not end with
+\\n. TYPE is a symbol indicating type of the string.
+MESSAGE is a message to display."
+  ;; No support of `visibly' when there's no secondary prompt
+  (let ((visibly (if (and (eq visibly t)
+                          (null inferior-ess-secondary-prompt))
+                     'nowait
+                   visibly))
+        (string (ess--run-presend-hooks process string)))
+    (inferior-ess--interrupt-subjob-maybe process)
+    (inferior-ess-mark-as-busy process)
+    (process-put process 'last-eval (current-time))
+    (cond
+     ;; Wait after each line
+     ((eq visibly t)
+      (let ((ess--inhibit-presend-hooks t))
+        (ess-eval-linewise string)))
+     ;; Insert command and eval invisibly
+     ((or (stringp visibly)
+          (eq visibly 'nowait))
+      (with-current-buffer (process-buffer process)
+        (save-excursion
+          (goto-char (process-mark process))
+          (insert-before-markers
+           (propertize (format "%s\n"
+                               (replace-regexp-in-string
+                                "\n" "\n+ "
+                                (if (stringp visibly) visibly string)))
+                       'font-lock-face 'comint-highlight-input)))
+        (process-send-string process (ess--concat-new-line-maybe string))))
+     (t
+      (process-send-string process (ess--concat-new-line-maybe string))))
+    (when message
+      (message "%s" message))))
+
+(defun ess-send-region (process start end &optional visibly message type)
+  "Low level ESS version of `process-send-region'.
+If VISIBLY call `ess-eval-linewise', else call
+`ess-send-string'. If MESSAGE is supplied, display it at the
+end. Run current buffer's and PROCESS'
+`ess-presend-filter-functions' hooks. TYPE is a symbol indicating
+type of the region."
+  (cond
+   ((ess-tracebug-p)
+    (ess-tracebug-send-region process start end visibly message type))
+   (t (ess-send-region--override process start end visibly message type))))
+
+(cl-defgeneric ess-send-region--override (process start end visibly message type)
+  (ess-send-string process (buffer-substring start end) visibly message type))
+
+\f
+;;*;; Evaluation commands
+
+(defun ess-load-file--normalise-file (file)
+  "Handle Tramp and system peculiarities."
+  (require 'tramp)
+  (let* ((file (if (tramp-tramp-file-p file)
+                   (tramp-file-name-localname (tramp-dissect-file-name file))
+                 file))
+         (file (if ess-microsoft-p
+                   (ess-replace-in-string file "[\\]" "/")
+                 file)))
+    (abbreviate-file-name file)))
+
+(defun ess-load-file--normalise-buffer (file)
+  (when (ess-save-file file)
+    (error "Buffer %s has not been saved" (buffer-name file)))
+  (let ((source-buffer (get-file-buffer file)))
+    (if source-buffer
+        (with-current-buffer source-buffer
+          (when (buffer-modified-p) (save-buffer))
+          (ess-force-buffer-current "Process to load into: "))
+      (ess-force-buffer-current "Process to load into: "))))
+
+;;;###autoload
+(defun ess-load-file (&optional filename)
+  "Load FILENAME into an inferior ESS process.
+This handles Tramp when working on a remote."
+  (interactive (list (or (and (ess-derived-mode-p)
+                              (buffer-file-name))
+                         (expand-file-name
+                          (read-file-name "Load source file: " nil nil t)))))
+  (ess-load-file--normalise-buffer filename)
+  (setq filename (ess-load-file--normalise-file filename))
+  (ess-load-file--override filename)
+  (message "Loaded %s" filename))
+
+(cl-defgeneric ess-load-file--override (filename)
+  (let ((command (ess-build-load-command filename nil t)))
+    (ess-send-string (ess-get-process) command t)))
+
+;; ;;; VS[03-09-2012]: Test Cases:
+;; (ess-command "a<-0\n" nil nil nil nil (get-process "R"))
+;; (ess-async-command-delayed "Sys.sleep(5);a<-a+1;cat(1:10)\n" nil
+;;                            (get-process "R") (lambda (proc) (message "done")))
+;; (ess-async-command-delayed "Sys.sleep(5)\n" nil (get-process "R")
+;;                            (lambda (proc) (message "done")))
+;; (process-get (get-process "R") 'running-async?)
+
+(defun ess-command--get-proc (proc no-prompt-check)
+  (if proc
+      (unless ess-local-process-name
+        (setq ess-local-process-name (process-name proc)))
+    (setq proc (ess-get-process ess-local-process-name)))
+  (unless no-prompt-check
+    (when (process-get proc 'busy)
+      (user-error "ESS process not ready. Finish your command before trying again")))
+  proc)
+
+(defvar inferior-ess--output-delimiter-count 0)
+(defun inferior-ess--output-delimiter ()
+  (setq inferior-ess--output-delimiter-count (1+ inferior-ess--output-delimiter-count))
+  (format "ess-output-delimiter%s" inferior-ess--output-delimiter-count))
+
+(defvar ess--command-default-timeout most-positive-fixnum)
+
+;; NOTE: We might want to switch to something like `cl-defun' with
+;; keyword arguments given the length of the signature. Would also
+;; make it easier to deprecate arguments.
+(defun ess-command (cmd &optional out-buffer _sleep no-prompt-check wait proc
+                        force-redisplay timeout)
+  "Send the ESS process CMD and delete the output from the ESS process buffer.
+If an optional second argument OUT-BUFFER exists save the output
+in that buffer. OUT-BUFFER is erased before use. CMD should have
+a terminating newline. Guarantees that the value of `.Last.value'
+will be preserved.
+
+`ess-command' is executes CMD in the background synchronously,
+meaning that the Emacs UI blocks while CMD is running. Make sure
+that CMD returns immediately. Blocking the UI for more than 0.1
+seconds should generally be considered a bug.
+
+SLEEP is deprecated and no longer has any effect. WAIT,
+FORCE-REDISPLAY, and TIMEOUT are as in `ess-wait-for-process' and
+are passed to `ess-wait-for-process'. The default timeout is 30
+seconds. The process is interrupted with `interrupt-process' when
+the timeout is reached or when an error occurs.
+
+PROC should be a process, if nil the process name is taken from
+`ess-local-process-name'.  This command doesn't set \\='last-eval
+process variable.
+
+Note: for critical, or error prone code you should consider
+wrapping the code into:
+
+ local({
+    olderr <- options(error=NULL)
+    on.exit(options(olderr))
+    ...
+ })"
+  (let ((out-buffer (or out-buffer (get-buffer-create " *ess-command-output*")))
+        (proc (ess-command--get-proc proc no-prompt-check))
+        (delim (inferior-ess--output-delimiter))
+        (timeout (or timeout ess--command-default-timeout)))
+    (with-current-buffer (process-buffer proc)
+      (let* ((proc-forward-alist (ess--alist (ess-local-process-name
+                                              inferior-ess-primary-prompt)))
+             (format-command-alist (ess-process-get 'format-command-alist))
+             (use-delimiter (alist-get 'use-delimiter format-command-alist))
+             (rich-cmd (if-let ((cmd-fun (alist-get 'fun format-command-alist)))
+                           (funcall cmd-fun
+                                    (ess--strip-final-newlines cmd)
+                                    (cons 'output-delimiter delim))
+                         cmd))
+             (early-exit t))
+        (ess-if-verbose-write (format "(ess-command '%s' ..)\n" cmd))
+        ;; Swap the process buffer with the output buffer before
+        ;; sending the command
+        (unwind-protect
+            (condition-case err
+                (progn
+                  ;; The process is restored from the filter once it's
+                  ;; available again (i.e. a prompt or delimiter is
+                  ;; detected). This handles the synchronous case when the
+                  ;; command runs to completion, as well as the
+                  ;; asynchronous case when an early exit occurs. The most
+                  ;; common cause of early exits are interrupts sent by
+                  ;; Emacs when the user types (see `when-no-input'). In
+                  ;; these cases we forward the interrupt to the process
+                  ;; and return to the caller right away. We can't restore
+                  ;; synchronously after an interrupt because the output
+                  ;; of the background command would spill into the
+                  ;; process buffer of the user when the process doesn't
+                  ;; interrupt in time.
+                  (process-put proc 'cmd-restore-function
+                               (ess--command-make-restore-function proc))
+                  (when use-delimiter
+                    (process-put proc 'cmd-output-delimiter delim))
+                  (process-put proc 'cmd-buffer out-buffer)
+                  (set-process-filter proc #'inferior-ess-ordinary-filter)
+                  (with-current-buffer out-buffer
+                    (ess-setq-vars-local proc-forward-alist)
+                    (setq buffer-read-only nil)
+                    (erase-buffer)
+                    (inferior-ess-mark-as-busy proc)
+                    (process-send-string proc rich-cmd)
+                    ;; Need time for ess-create-object-name-db on PC
+                    (if no-prompt-check
+                        (sleep-for 0.02) ; 0.1 is noticeable!
+                      (unless (ess-wait-for-process proc nil wait force-redisplay timeout)
+                        (error "Timeout during background ESS command `%s'"
+                               (ess--strip-final-newlines cmd))))
+                    (setq early-exit nil)))
+              (error (setq early-exit err))
+              (quit (setq early-exit err)))
+          (if early-exit
+              (ess--command-error-handler proc out-buffer use-delimiter delim early-exit)
+            (with-current-buffer out-buffer
+              (goto-char (point-min))
+              (when (re-search-forward (ess--delimiter-error-start-re) nil t)
+                (let ((start (1+ (match-beginning 1))))
+                  (when (re-search-forward (ess--delimiter-error-end-re) nil t)
+                    (let ((end (match-beginning 1)))
+                      (error "R error during background ESS command `%s'\nError: %s"
+                             (ess--strip-final-newlines cmd)
+                             (buffer-substring start end)))))))))))
+    out-buffer))
+
+(defun ess--command-error-handler (proc
+                                   out-buffer
+                                   use-delimiter
+                                   delim
+                                   early-exit)
+  (let ((inhibit-quit t))
+    ;; In case of early exit send an interrupt to the
+    ;; process to abort the command
+    (with-current-buffer out-buffer
+      (goto-char (point-min))
+      (when (and use-delimiter
+                 (not (re-search-forward (ess--delimiter-start-re delim) nil t)))
+        ;; CMD probably failed to parse if the start delimiter
+        ;; can't be found in the output. Disable the delimiter
+        ;; before interrupt to avoid a freeze.
+        (ess-write-to-dribble-buffer
+         "Disabling output delimiter because CMD failed to parse\n")
+        (process-put proc 'cmd-output-delimiter nil))
+      (goto-char (point-max))
+      (ess--interrupt proc)))
+  ;; Can be `t` when early exit is caused e.g. by a throw instead of
+  ;; an error or a quit. This happens in tests and within
+  ;; `while-no-input'.
+  (unless (eq early-exit t)
+    (when (and (eq (car early-exit) 'quit)
+               (y-or-n-p (concat "Background background command interrupted with a user quit.\n"
+                                 "Would you like to disable background evaluations in this process?")))
+      (process-put proc 'bg-eval-disabled t))
+    (signal (car early-exit) (cdr early-exit))))
+
+;; (ess-process-get 'ess-format-command-alist)
+;;   "Alist of mode-specific parameters for formatting a command.
+;; All elements are optional.
+;;
+;; - `fun': A formatting function for running a command. First
+;;   argument is the background command to run. Must include a
+;;   catch-all `&rest` parameter for extensibility.
+;;
+;; - `use-delimiter' : Whether to wait for an output sentinel. If
+;;   non-nil, `fun' should get the `cmd-output-delimiter' element of the
+;;   alist of parameters and ensure the sentinel is written to the
+;;   process output at the end of the command."
+
+(defun ess--command-make-restore-function (proc)
+  (let ((old-pf (process-filter proc)))
+    (lambda ()
+      (set-process-filter proc old-pf)
+      (process-put proc 'cmd-output-delimiter nil)
+      (process-put proc 'cmd-buffer nil)
+      (when-let ((pending (process-get proc 'pending-output)))
+        (process-put proc 'pending-output nil)
+        (funcall old-pf proc pending)))))
+
+;; TODO: Needs some Julia tests as well
+(defun ess--foreground-command (cmd &optional out-buffer _sleep no-prompt-check wait proc)
+  "Same as `ess-command' but does not timeout.
+Currently blocks the Emacs UI. Eventually it would make sense to
+lock the inferior to prevent interactions and use
+`ess-async-command' with a callback."
+  (let ((timeout most-positive-fixnum))
+    (ess-command cmd out-buffer nil no-prompt-check wait proc nil timeout)))
+
+(defun ess-boolean-command (com &optional buf wait)
+  "Like `ess-command' but expects COM to print TRUE or FALSE.
+If TRUE (or true) is found return non-nil otherwise nil.
+Example (ess-boolean-command \"2>1\n\")"
+  (with-current-buffer (ess-command com buf nil nil wait)
+    (goto-char (point-min))
+    (let ((case-fold-search t))
+      (re-search-forward "true" nil t))))
+
+(defun ess-string-command (com &optional buf wait)
+  "Returns the output of COM as a string."
+  (with-current-buffer (ess-command com buf nil nil wait)
+    (buffer-substring (point-min) (point-max))))
+
+(defun ess-async-command (com &optional buf proc callback interrupt-callback)
+  "Asynchronous version of `ess-command'.
+COM, BUF, WAIT and PROC are as in `ess-command'.
+
+CALLBACK is a function of two arguments (PROC STRING) to run
+after the successful execution. When INTERRUPT-CALLBACK is
+non-nil, user evaluation can interrupt the
+job. INTERRUPT-CALLBACK should be either t or a function of one
+argument (PROC) to be called on interruption.
+
+NOTE: Currently this function should be used only for background
+jobs like caching. ESS tries to suppress any output from the
+asynchronous command, but long output of COM will most likely end
+up in user's main buffer."
+  (setq proc (or proc (get-process ess-local-process-name)))
+  (cond ((not (and proc (eq (process-status proc) 'run)))
+         (error "Process %s is dead" proc))
+        ((process-get proc 'busy)
+         (error "Process %s is busy" proc))
+        ((process-get proc 'running-async?)
+         (error "Process %s is already running an async command" proc)))
+  (when (eq interrupt-callback t)
+    (setq interrupt-callback (lambda (_proc))))
+  (process-put proc 'callbacks (list (cons callback 'suppress-output)
+                                     interrupt-callback))
+  (process-put proc 'interruptable? (and interrupt-callback t))
+  (process-put proc 'running-async? t)
+  (ess-command com buf nil 'no-prompt-check .01 proc))
+
+(defun ess-async-command-delayed (com buf proc &optional callback delay)
+  "Delayed asynchronous ess-command.
+COM and BUF are as in `ess-command'. DELAY is a number of idle
+seconds to wait before starting the execution of the COM. On
+interruption (by user's evaluation) ESS tries to rerun the job
+after next DELAY seconds, and the whole process repeats itself
+until the command manages to run completely. DELAY defaults to
+`ess-idle-timer-interval' + 3 seconds. You should always provide
+PROC for delayed evaluation, as the current process might change,
+leading to unpredictable consequences. This function is a wrapper
+of `ess-async-command' with an explicit interrupt-callback."
+  (let* ((delay (or delay
+                    (+ ess-idle-timer-interval 3)))
+         (int-cb  `(lambda (proc)
+                     (ess-async-command-delayed ,com ,buf proc ,callback ,delay)))
+         (com-fun `(lambda ()
+                     (when (eq (process-status ,proc)  'run) ; do nothing if not running
+                       (if (or (process-get ,proc 'busy) ; if busy, try later
+                               (process-get ,proc 'running-async?))
+                           ;; idle timer doesn't work here
+                           (run-with-timer ,delay nil 'ess-async-command-delayed
+                                           ,com ,buf ,proc ,callback ,delay))
+                       (ess-async-command ,com ,buf ,proc ,callback ',int-cb)))))
+    (run-with-idle-timer delay nil com-fun)))
+
+(defun ess-load-library ()
+  "Prompt and load dialect specific library/package/module.
+Note that in R these are called `packages' and the name of this
+function has nothing to do with R package mechanism, but it
+rather serves a generic, dialect independent purpose. It is also
+similar to `load-library' Emacs function."
+  (interactive)
+  (let ((ess-eval-visibly-p t)
+        (packs (ess-installed-packages))
+        pack)
+    (setq pack (ess-completing-read "Load" packs))
+    (ess-load-library--override pack)
+    (ess--mark-search-list-as-changed)))
+
+(cl-defgeneric ess-installed-packages ()
+  "Return a list of installed packages.")
+
+(cl-defgeneric ess-load-library--override (pack)
+  "Load library/package PACK.")
+
+\f
+;;*;;  Evaluating lines, paragraphs, regions, and buffers.
+
+(defun ess-eval-linewise (text &optional invisibly eob even-empty
+                               wait-last-prompt sleep-sec wait-sec)
+  "Evaluate TEXT in the ESS process buffer as if typed in w/o tabs.
+Waits for prompt after each line of input, so won't break on large texts.
+
+If optional second arg INVISIBLY is non-nil, don't echo commands.
+If it is a string, just include that string. If optional third
+arg EOB is non-nil, display ESS process buffer after evaluation.
+If optional 4th arg EVEN-EMPTY is non-nil, also send empty
+text (e.g. an empty line). If 5th arg WAIT-LAST-PROMPT is
+non-nil, also wait for the prompt after the last line; if 6th arg
+SLEEP-SEC is a number, ESS will call `(\\[sleep-for] SLEEP-SEC)'
+at the end of this function. If the 7th arg WAIT-SEC is set, it
+will be used instead of the default .001s and be passed to
+\\[ess-wait-for-process].
+
+Run `comint-input-filter-functions' and
+`ess-presend-filter-functions' of the associated PROCESS on the
+TEXT."
+  (ess-force-buffer-current "Process to use: ")
+  ;; Use this to evaluate some code, but don't wait for output.
+  (let* ((deactivate-mark)           ; keep local {do *not* deactivate wrongly}
+         (inf-proc (ess-get-process ess-current-process-name))
+         (inf-buf (process-buffer inf-proc))
+         (win (get-buffer-window inf-buf t)))
+    (setq text (ess--concat-new-line-maybe
+                (ess--run-presend-hooks inf-proc text)))
+    (with-current-buffer inf-buf
+      (setq text (propertize text 'field 'input 'front-sticky t))
+      (goto-char (marker-position (process-mark inf-proc)))
+      (when (stringp invisibly)
+        (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))
+      (while (or (> (length text) 0) even-empty)
+        (setq even-empty nil)
+        (let* ((pos (string-match "\n\\|$" text))
+               (input (if (= (length text) 0)
+                          "\n"
+                        (concat (substring text 0 pos) "\n"))))
+          (setq text (substring text (min (length text) (1+ pos))))
+          (goto-char (marker-position (process-mark inf-proc)))
+          (when win
+            (set-window-point win (process-mark inf-proc)))
+          (unless invisibly
+            ;; for consistency with comint :(
+            (insert (propertize input 'font-lock-face 'comint-highlight-input))
+            (set-marker (process-mark inf-proc) (point)))
+          (inferior-ess-mark-as-busy inf-proc)
+          (process-send-string inf-proc input))
+        (when (or (> (length text) 0)
+                  wait-last-prompt)
+          (ess-wait-for-process inf-proc t (or wait-sec 0.001))))
+      (when eob
+        (display-buffer inf-buf))
+      ;; This used to be conditioned on EOB but this is no longer the
+      ;; case since commit fd90550d in 2012 (probably an accident)
+      (goto-char (marker-position (process-mark inf-proc)))
+      (when win
+        (with-selected-window win
+          (goto-char (point))
+          ;; this is crucial to avoid resetting window-point
+          (recenter (- -1 scroll-margin))))))
+  (when (numberp sleep-sec)
+    (sleep-for sleep-sec)))
+
+\f
+;;;*;;; Evaluate only
+
+(defun ess-eval-region--normalise-region (start end)
+  "Clean the region from START to END for evaluation.
+This trims newlines at beginning and end of the region because
+they might throw off the debugger."
+  (save-excursion
+    (goto-char start)
+    (skip-chars-forward "\n\t ")
+    (setq start (point))
+    (unless mark-active
+      (ess-blink-region start end))
+    (goto-char end)
+    (skip-chars-backward "\n\t ")
+    (setq end (point))
+    (cons start end)))
+
+(defun ess-eval-region (start end vis &optional message type)
+  "Send the region from START to END to the inferior ESS process.
+VIS switches the meaning of `ess-eval-visibly'. If given,
+MESSAGE is `message'ed. TYPE is a symbol indicating what type of
+region this is. If command `rectangle-mark-mode' is active, send
+the lines of the rectangle separately to the inferior process."
+  (interactive "r\nP")
+  (ess-force-buffer-current "Process to use: ")
+  (message "Starting evaluation...")
+  (unless ess-local-customize-alist
+    ;; External applications might call ess-eval-* functions; make it
+    ;; easier for them
+    (ess-setq-vars-local (symbol-value (ess-get-process-variable 'ess-local-customize-alist))))
+  (if (bound-and-true-p rectangle-mark-mode)
+      ;; If we're in rectangle-mark-mode, loop over each line of the
+      ;; rectangle. Send them separately.
+      (let ((reclines (extract-rectangle-bounds (min (mark) (point)) (max (mark) (point)))))
+        (mapc (lambda (l)
+                (ess--eval-region (car l) (cdr l) vis message type))
+              reclines))
+    (ess--eval-region start end vis message type)))
+
+(defun ess--eval-region (start end vis &optional message type)
+  "Helper function for `ess-eval-region', which see.
+START, END, VIS, MESSAGE, and TYPE described there."
+  (let* ((se (ess-eval-region--normalise-region start end))
+         (start (car se))
+         (end (cdr se)))
+    (let ((visibly (if vis (not ess-eval-visibly) ess-eval-visibly))
+          (message (or message "Eval region"))
+          (proc (ess-get-process)))
+      (save-excursion
+        (ess-send-region proc start end visibly message type)))
+    (when ess-eval-deactivate-mark
+      (ess-deactivate-mark))
+    (list start end)))
+
+(defun ess-eval-buffer (&optional vis)
+  "Send the current buffer to the inferior ESS process.
+VIS has same meaning as for `ess-eval-region'."
+  (interactive "P")
+  (ess-eval-region (point-min) (point-max) vis "Eval buffer" 'buffer))
+
+(defun ess-eval-buffer-from-beg-to-here (&optional vis)
+  "Send region from beginning to point to the inferior ESS process.
+VIS has same meaning as for `ess-eval-region'."
+  (interactive "P")
+  (ess-eval-region (point-min) (point) vis "Eval buffer till point"))
+
+(defun ess-eval-buffer-from-here-to-end (&optional vis)
+  "Send region from point to end of buffer to the inferior ESS process.
+VIS has same meaning as for `ess-eval-region'."
+  (interactive "P")
+  (ess-eval-region (point) (point-max) vis "Eval buffer till end"))
+
+(defun ess-eval-function (&optional vis)
+  "Send the current function to the inferior ESS process.
+Prefix arg VIS toggles visibility of ess-code as for
+`ess-eval-region'. Returns nil if not inside a function."
+  (interactive "P")
+  (ess-force-buffer-current)
+  (save-excursion
+    (ignore-errors
+      ;; Evaluation is forward oriented
+      (forward-line -1)
+      (ess-next-code-line 1))
+    (let ((pos (point))
+          beg end msg)
+      (end-of-defun)
+      (beginning-of-defun)
+      ;; While we are the beginning of the function, get the function
+      ;; name. FIXME: should use our ess-function-pattern.
+      (setq msg (format "Eval function: %s"
+                        (if (looking-at add-log-current-defun-header-regexp)
+                            (match-string 1)
+                          (buffer-substring (point) (line-end-position)))))
+      (setq beg (point))
+      (end-of-defun)
+      (setq end (point))
+      (when (or (< pos beg)
+                (< end pos))
+        (error "Not in a function"))
+      (if (ess-tracebug-p)
+          (ess-tracebug-send-function (get-process ess-local-process-name) beg end vis msg)
+        (ess-eval-region beg end vis msg)))))
+
+(defun ess-eval-paragraph (&optional vis)
+  "Send the current paragraph to the inferior ESS process.
+Prefix arg VIS toggles visibility of ess-code as for `ess-eval-region'."
+  (interactive "P")
+  (let ((start-pos (point)))
+    (if (= (line-beginning-position) (point-min))
+        (ess-next-code-line 0)
+      ;; Evaluation is forward oriented
+      (forward-line -1)
+      (ess-next-code-line 1))
+    (when (< (point) start-pos)
+      (goto-char start-pos))
+    (save-excursion
+      (let ((beg (progn (backward-paragraph) (point)))
+            (end (progn (forward-paragraph) (point))))
+        (ess-eval-region beg end vis)))))
+
+(defun ess-eval-function-or-paragraph (&optional vis)
+  "Send the current function if \\[point] is inside one.
+Otherwise send the current paragraph to the inferior ESS process.
+Prefix arg VIS toggles visibility of ess-code as for
+`ess-eval-region'. Returns \\='function if a function was evaluated
+or \\='paragraph if a paragraph."
+  (interactive "P")
+  (condition-case nil
+      (progn (ess-eval-function vis)
+             'function)
+    ;; TODO: Maybe be smarter than just catching all errors?
+    (error (ess-eval-paragraph vis)
+           'paragraph)))
+
+(defun ess-eval-function-or-paragraph-and-step (&optional vis)
+  "Send the current function if \\[point] is inside one.
+Otherwise send the current paragraph to the inferior ESS process.
+Prefix arg VIS toggles visibility of ess-code as for
+`ess-eval-region'."
+  (interactive "P")
+  (ess-skip-thing (ess-eval-function-or-paragraph vis))
+  (ess-next-code-line))
+
+(defun ess-eval-region-or-function-or-paragraph (&optional vis)
+  "Send the region, function, or paragraph depending on context.
+Send the region if it is active. If not, send function if `point'
+is inside one, otherwise the current paragraph. Treats
+rectangular regions as `ess-eval-region' does. Prefix arg VIS
+toggles visibility of ess-code as for `ess-eval-region'."
+  (interactive "P")
+  (if (use-region-p)
+      (ess-eval-region (region-beginning) (region-end) vis)
+    (ess-eval-function-or-paragraph vis)))
+
+(defun ess-eval-region-or-function-or-paragraph-and-step (&optional vis)
+  "Send the region, function, or paragraph depending on context.
+Send the region if it is active. If not, send function if `point'
+is inside one, otherwise the current paragraph. Treats
+rectangular regions as `ess-eval-region' does. After evaluation
+step to the next code line or to the end of region if region was
+active. Prefix arg VIS toggles visibility of ess-code as for
+`ess-eval-region'."
+  (interactive "P")
+  (ess-skip-thing (ess-eval-region-or-function-or-paragraph vis))
+  (ess-next-code-line))
+
+(defun ess-eval-region-or-line-and-step (&optional vis)
+  "Evaluate region if active, otherwise `ess-eval-line-and-step'.
+See `ess-eval-region' for the meaning of VIS. Treats rectangular
+regions as `ess-eval-region' does."
+  (interactive "P")
+  (if (use-region-p)
+      (ess-eval-region (region-beginning) (region-end) vis)
+    (ess-eval-line-and-step)))
+
+(defun ess-eval-region-or-line-visibly-and-step ()
+  "Evaluate region if active, otherwise the current line and step.
+Evaluation is done visibly.
+
+Note that when inside a package and namespaced evaluation is in
+place (see `ess-r-set-evaluation-env') evaluation of multiline
+input will fail."
+  (interactive)
+  (ess-force-buffer-current)
+  (display-buffer (ess-get-process-buffer)
+                  ;; Use a different window for the process buffer:
+                  '(nil (inhibit-same-window . t))
+                  ;; Pass t to reusable-frames if users have help in
+                  ;; own frames, otherwise help frames get split to
+                  ;; display the inferior.
+                  (or (equal ess-help-own-frame 'one)
+                      ess-help-own-frame))
+  (let ((ess-eval-visibly t))
+    (ess-eval-region-or-line-and-step)))
+
+(defun ess-eval-line (&optional vis)
+  "Send the current line to the inferior ESS process.
+VIS has same meaning as for `ess-eval-region'."
+  (interactive "P")
+  (let* ((beg (line-beginning-position))
+         (end (line-end-position))
+         (msg (format "Loading line: %s" (buffer-substring beg end))))
+    (ess-eval-region beg end vis msg)))
+
+(defun ess-eval-line-and-step (&optional vis)
+  "Evaluate the current line and step to the \"next\" line.
+See `ess-eval-region' for VIS."
+  (interactive "P")
+  (ess-eval-line vis)
+  (ess-skip-thing 'line)
+  (ess-next-code-line))
+
+(defun ess-eval-line-visibly-and-step (&optional simple-next)
+  "Evaluate the current line visibly and step to the \"next\" line.
+If SIMPLE-NEXT is non-nil, possibly via prefix arg, first skip
+empty and commented lines. When the variable `ess-eval-empty'
+is non-nil both SIMPLE-NEXT and EVEN-EMPTY are interpreted as
+true.
+
+Note that when inside a package and namespaced evaluation is in
+place (see `ess-r-set-evaluation-env'), the evaluation of
+multiline input will fail."
+  (interactive "P")
+  (ess-force-buffer-current)
+  (display-buffer (ess-get-process-buffer)
+                  ;; Use a different window for the process buffer:
+                  '(nil (inhibit-same-window . t))
+                  ;; Pass t to reusable-frames if users have help in
+                  ;; own frames, otherwise help frames get split to
+                  ;; display the inferior.
+                  (or (equal ess-help-own-frame 'one)
+                      ess-help-own-frame))
+  (let ((ess-eval-visibly t)
+        (ess-eval-empty (or ess-eval-empty simple-next)))
+    (ess-eval-line)
+    (ess-skip-thing 'line)
+    (ess-next-code-line)))
+
+(defun ess-eval-line-invisibly-and-step ()
+  "Evaluate the current line invisibly and step to the next line.
+Evaluate all comments and empty lines."
+  (interactive)
+  (let ((ess-eval-visibly nil))
+    (ess-eval-line-and-step)))
+(define-obsolete-function-alias 'ess-eval-line-and-step-invisibly
+  #'ess-eval-line-invisibly-and-step "18.10")
+
+\f
+;;;*;;; Evaluate and switch to S
+
+(defun ess-eval-region-and-go (start end &optional vis)
+  "Send region from START to END to the inferior process buffer.
+START and END default to the current region, and rectangular
+regions are treated as `ess-eval-region'. VIS has same meaning as
+for `ess-eval-region'."
+  (interactive "r\nP")
+  (ess-eval-region start end vis)
+  (ess-switch-to-ESS t))
+
+(defun ess-eval-buffer-and-go (&optional vis)
+  "Send the current buffer to the inferior S and switch to the process buffer.
+VIS has same meaning as for `ess-eval-region'."
+  (interactive "P")
+  (ess-eval-buffer vis)
+  (ess-switch-to-ESS t))
+
+(defun ess-eval-function-and-go (&optional vis)
+  "Send the current function, then switch to the inferior process buffer.
+VIS has same meaning as for `ess-eval-region'."
+  (interactive "P")
+  (ess-eval-function vis)
+  (ess-switch-to-ESS t))
+
+(defun ess-eval-line-and-go (&optional vis)
+  "Send the current line, then switch to the inferior process buffer.
+VIS has same meaning as for `ess-eval-region'."
+  (interactive "P")
+  (ess-eval-line vis)
+  (ess-switch-to-ESS t))
+
+(defun ess-eval-paragraph-and-go (&optional vis)
+  "Send the current paragraph, then switch to the inferior process buffer.
+VIS has same meaning as for `ess-eval-region'."
+  (interactive "P")
+  (ess-eval-paragraph vis)
+  (ess-switch-to-ESS t))
+
+(defun ess-eval-paragraph-and-step (&optional vis)
+  "Evaluate the current paragraph and move point to the next line.
+If not inside a paragraph, evaluate the next one. VIS has same
+meaning as for `ess-eval-region'."
+  (interactive "P")
+  (ess-eval-paragraph vis)
+  (ess-skip-thing 'paragraph)
+  (ess-next-code-line))
+
+\f ; Inferior ESS mode
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;; In this section:
+;;;;
+;;;; * The major mode inferior-ess-mode
+;;;; * Process handling code
+;;;; * Completion code
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;*;; Major mode definition
+
+(defvar inferior-ess-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "\C-y"              #'ess-yank)
+    (define-key map "\r"       #'inferior-ess-send-input)
+    (define-key map "\C-a"     #'comint-bol)
+    ;; 2010-06-03 SJE
+    ;; disabled this in favor of ess-dirs.  Martin was not sure why this
+    ;; key was defined anyway in this mode.
+    ;;(define-key map "\M-\r"    #'ess-transcript-send-command-and-move)
+    (define-key map "\C-c\M-l" #'ess-load-file)
+    (define-key map "\C-c`"    #'ess-show-traceback)
+    (define-key map [(control ?c) ?~] #'ess-show-call-stack)
+    (define-key map "\C-c\C-d" #'ess-dump-object-into-edit-buffer)
+    (define-key map "\C-c\C-v" #'ess-display-help-on-object)
+    (define-key map "\C-c\C-q" #'ess-quit)
+    (define-key map "\C-c\C-s" #'ess-execute-search)
+    (define-key map "\C-c\C-x" #'ess-execute-objects)
+    (define-key map "\C-c\034" #'ess-abort) ; \C-c\C-backslash
+    (define-key map "\C-c\C-z" #'ess-switch-to-inferior-or-script-buffer) ; mask comint map
+    (define-key map "\C-d"     #'delete-char)   ; EOF no good in S
+    (define-key map "\t"       #'completion-at-point)
+    (define-key map "\M-?"     #'ess-complete-object-name); stealing  M-? from xref(standard Emacs)
+    (define-key map "\C-c\C-k" #'ess-request-a-process)
+    (define-key map ","        #'ess-smart-comma)
+    (define-key map "\C-c\C-d"  'ess-doc-map)
+    (define-key map "\C-c\C-e"  'ess-extra-map)
+    (define-key map "\C-c\C-t"  'ess-dev-map)
+    map)
+  "Keymap for `inferior-ess' mode.")
+
+(easy-menu-define
+  inferior-ess-mode-menu inferior-ess-mode-map
+  "Menu for use in Inferior S mode"
+  '("iESS"
+    ["Quit"                    ess-quit                        t]
+    ["Reload process"          inferior-ess-reload             t]
+    ;; ["Send and move"  ess-transcript-send-command-and-move  t]
+    ["Copy command"            comint-copy-old-input           t]
+    ["Send command"            inferior-ess-send-input         t]
+    ["Switch to script buffer" ess-switch-to-inferior-or-script-buffer t]
+    ["Get help on S object"    ess-display-help-on-object      t]
+    "------"
+    ("Process"
+     ["Process Echoes" (lambda () (interactive)
+                         (setq comint-process-echoes (not comint-process-echoes)))
+      :active t
+      :style toggle
+      :selected comint-process-echoes]
+     ("Eval visibly "
+      :filter ess--generate-eval-visibly-submenu ))
+    "------"
+    ("Utils"
+     ["Attach directory"       ess-execute-attach      t]
+     ["Display object list"    ess-execute-objects     t]
+     ["Display search list"    ess-execute-search      t]
+     ["Edit S object"  ess-dump-object-into-edit-buffer t]
+     ["Enter S command"                ess-execute             t]
+     ["Jump to error"          ess-parse-errors        t]
+     ["Load source file"       ess-load-file           t]
+     ["Resynch S completions"  ess-resynch             t]
+     ["Recreate R versions known to ESS"
+      (lambda () (interactive) (ess-r-redefine-runners 'verbose)) t]
+     )
+    "------"
+    ("start-dev" :visible nil); <-- ??
+    ("end-dev" :visible nil)
+    "------"
+    ("Font Lock"
+     :active ess-font-lock-keywords
+     :filter ess--generate-font-lock-submenu)
+    "------"
+    ["Describe"         describe-mode                       t]
+    ["Send bug report"  ess-submit-bug-report               t]
+    ["About"            (ess-goto-info "Entering Commands") t]
+    ))
+
+
+(defvar ess-mode-minibuffer-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map minibuffer-local-map)
+    (define-key map "\t"       #'ess-complete-object-name)
+    (define-key map "\C-\M-i"  #'ess-complete-object-name) ;; doesn't work:(
+    (define-key map "\C-c\C-s" #'ess-execute-search)
+    (define-key map "\C-c\C-x" #'ess-execute-objects)
+    map)
+  "Keymap used in `ess-execute'.")
+
+(define-derived-mode inferior-ess-mode comint-mode "iESS"
+  "Major mode for interacting with an inferior ESS process.
+To learn more about how to use inferior ess modes, see Info
+node `(ess)Top'. If you accidentally suspend your process, use
+\\[comint-continue-subjob] to continue it."
+  :group 'ess-proc
+  (setq-local comint-input-sender 'inferior-ess-input-sender)
+  (setq-local font-lock-fontify-region-function
+              #'inferior-ess-fontify-region)
+  ;; If comint-process-echoes is t  inferior-ess-input-sender
+  ;; recopies the input, otherwise not
+  (setq-local comint-process-echoes (not (member ess-language '("SAS" "XLS" "OMG" "julia"))))
+
+  (when comint-use-prompt-regexp ;; why comint is not setting this? bug?
+    (setq-local inhibit-field-text-motion t))
+
+  (unless inferior-ess-prompt ;; build when unset
+    (setq inferior-ess-prompt
+          (concat "\\("
+                  inferior-ess-primary-prompt
+                  (when inferior-ess-secondary-prompt "\\|")
+                  inferior-ess-secondary-prompt
+                  "\\)")))
+  (setq comint-prompt-regexp (concat "^" inferior-ess-prompt))
+
+  (setq mode-line-process
+        '(" ["
+          ess--mode-line-process-indicator
+          ess--local-mode-line-process-indicator
+          "]: %s"))
+
+  ;;; Completion support ----------------
+  (remove-hook 'completion-at-point-functions #'comint-completion-at-point t) ;; reset the hook
+  (add-hook 'completion-at-point-functions
+            #'comint-c-a-p-replace-by-expanded-history nil 'local)
+  (add-hook 'completion-at-point-functions #'ess-filename-completion nil 'local)
+
+  ;; hyperlinks support
+  (goto-address-mode t)
+
+  ;; Avoid spaces after filenames
+  (setq-local comint-completion-addsuffix (cons "/" ""))
+
+  (setq comint-input-autoexpand t) ; Only for completion, not on input.
+
+  (add-hook 'window-configuration-change-hook #'ess-set-width nil t)
+  (setq-local indent-tabs-mode nil)
+
+  (setq-local paragraph-start (concat inferior-ess-primary-prompt "\\|\^L"))
+  (setq-local paragraph-separate "\^L")
+  (setq-local jit-lock-chunk-size inferior-ess-jit-lock-chunk-size))
+
+
+\f
+;;*;; Commands used exclusively in inferior-ess-mode
+
+;;;*;;; Main user commands
+
+(defun inferior-ess-input-sender (proc string)
+  (inferior-ess--interrupt-subjob-maybe proc)
+  (let ((comint-input-filter-functions nil)) ; comint runs them, don't run twice.
+    (if comint-process-echoes
+        (ess-eval-linewise string nil nil ess-eval-empty)
+      (ess-send-string proc string))))
+
+(defvar ess-help-arg-regexp "\\(['\"]?\\)\\([^,=)'\"]*\\)\\1"
+  "Reg(ular) Ex(pression) of help(.) arguments.  MUST: 2nd \\(.\\) = arg.")
+
+(defun inferior-ess-send-input ()
+  "Sends the command on the current line to the ESS process."
+  (interactive)
+  (run-hooks 'ess-send-input-hook)
+  (unless (ess-process-get 'busy)
+    ;; avoid new line insertion
+    (ess-process-put 'prev-prompt nil))
+  (comint-send-input)
+  (setq ess-object-list nil))
+
+(defun inferior-ess--goto-input-start:field ()
+  "Move point to the beginning of input skipping all continuation lines.
+If in the output field, goes to the beginning of previous input
+field.
+Note: `inferior-ess-secondary-prompt' should match exactly."
+  (goto-char (field-beginning))
+  ;; move to the beginning of non-output field
+  (while (and (not (bobp))
+              (eq (field-at-pos (point)) 'output))
+    (goto-char (field-beginning nil t)))
+  ;; skip all secondary prompts
+  (let ((pos (field-beginning (point) t))
+        (secondary-prompt (concat "^" inferior-ess-secondary-prompt)))
+    (while (and pos
+                (if (eq (get-text-property pos 'field) 'output)
+                    (string-match secondary-prompt (field-string-no-properties pos))
+                  t))
+      (goto-char pos)
+      (setq pos (previous-single-property-change pos 'field)))))
+
+(defun inferior-ess--goto-input-end:field ()
+  "Move point to the end of input skipping all continuation lines.
+If in the output field, goes to the beginning of previous input
+field. NOTE: to be used only with fields, see
+`comint-use-prompt-regexp'."
+  ;; this func is not used but might be useful some day
+  (goto-char (field-end))
+  (let ((pos (point))
+        (secondary-prompt (concat "^" inferior-ess-secondary-prompt)))
+    (while (and pos
+                (if (eq (get-text-property pos 'field) 'output)
+                    (string-match secondary-prompt (field-string-no-properties pos))
+                  t))
+      (goto-char pos)
+      (setq pos (next-single-property-change pos 'field)))))
+
+(defun inferior-ess--get-old-input:field ()
+  "Return the ESS command surrounding point (use with fields)."
+  (save-excursion
+    (if (eq (field-at-pos (point)) 'output)
+        (if (called-interactively-p 'any)
+            (error "No command on this line")
+          ;; else, just return ""
+          "")
+      (inferior-ess--goto-input-start:field)
+      (let ((command (field-string-no-properties (point)))
+            (pos (next-single-property-change (point) 'field ))
+            (secondary-prompt (concat "^" inferior-ess-secondary-prompt)))
+        (while (and pos
+                    (cond
+                     ((eq (get-text-property pos 'field) 'input)
+                      (setq command (concat command "\n" (field-string-no-properties pos))))
+                     ((eq (get-text-property pos 'field) 'output)
+                      (string-match secondary-prompt (field-string-no-properties pos)))
+                     (t)));; just skip if unknown
+          (setq pos (next-single-property-change pos 'field)))
+        command))))
+
+;; TODO: error when entering a multiline function
+;; check.integer <- function(N){
+;;      is.integer(N) | !length(grep("[^[:digit:]]", as.character(N)))
+;; }
+(defun inferior-ess--goto-input-start:regexp ()
+  "Move point to the beginning of input skipping all continuation lines.
+If in the output field, goes to the beginning of previous input."
+  (beginning-of-line)
+  (unless (looking-at inferior-ess-prompt)
+    (re-search-backward (concat "^" inferior-ess-prompt) nil t))
+  ;; at bol
+  (when (and inferior-ess-secondary-prompt
+             (looking-at inferior-ess-secondary-prompt))
+    (while (and (> (forward-line -1) -1)
+                (looking-at inferior-ess-secondary-prompt))))
+  (unless (looking-at inferior-ess-prompt)
+    (error "Beginning of input not found"))
+  (comint-skip-prompt))
+
+(defun inferior-ess--get-old-input:regexp ()
+  "Return the ESS command surrounding point (use regexp)."
+  ;;VS[03-09-2012]: This should not rise errors!! Troubles comint-interrupt-subjob
+  (save-excursion
+    (let* ((inhibit-field-text-motion t)
+           command)
+      (beginning-of-line)
+      (when  (and inferior-ess-secondary-prompt
+                  (looking-at inferior-ess-secondary-prompt))
+        (inferior-ess--goto-input-start:regexp))
+      (beginning-of-line)
+      (if (looking-at inferior-ess-prompt) ; cust.var, might not include sec-prompt
+          (progn
+            (comint-skip-prompt)
+            (setq command (buffer-substring-no-properties (point) (line-end-position)))
+            (when inferior-ess-secondary-prompt
+              (while (progn (forward-line 1)
+                            (looking-at inferior-ess-secondary-prompt))
+                (re-search-forward inferior-ess-secondary-prompt (line-end-position) t)
+                (setq command (concat command "\n"
+                                      (buffer-substring-no-properties (point) (line-end-position))))))
+            (forward-line -1)
+            command)
+        (message "No command at this point")
+        ""))))
+
+(defun inferior-ess-get-old-input ()
+  "Return the ESS command surrounding point."
+  (if comint-use-prompt-regexp
+      (inferior-ess--get-old-input:regexp)
+    (inferior-ess--get-old-input:field)))
+
+(defun ess-can-eval-in-background (&optional proc)
+  "Can the current process be used for background commands.
+Inspects the `ess-can-eval-in-background' variable as well as the
+`bg-eval-disabled' property of PROC or of the current process, if
+any. This makes it possible to disable background evals for a
+specific process, for instance in case it was not initialized
+properly."
+  (when ess-can-eval-in-background
+    (when-let ((proc (or proc (ess-get-current-process))))
+      (not (process-get proc 'bg-eval-disabled)))))
+
+\f
+;;;*;;; Hot key commands
+
+(defun ess-execute-objects (posn)
+  "Send the objects() command to the ESS process.
+By default, gives the objects at position 1.
+A prefix argument toggles the meaning of `ess-execute-in-process-buffer'.
+A prefix argument of 2 or more means get objects for that position.
+A negative prefix argument gets the objects for that position
+  and toggles `ess-execute-in-process-buffer' as well."
+  (interactive "P")
+  (ess-make-buffer-current)
+  (let* ((num-arg (if (listp posn)
+                      (if posn -1 1)
+                    (prefix-numeric-value posn)))
+         (the-posn (if (< num-arg 0) (- num-arg) num-arg))
+         (invert (< num-arg 0))
+         (the-command (format inferior-ess-objects-command the-posn ".*"))
+         (the-message (concat ">>> Position "
+                              (number-to-string the-posn)
+                              " ("
+                              (nth (1- the-posn) (ess-search-list))
+                              ")\n")))
+    (ess-execute the-command invert "S objects" the-message)))
+
+(defun ess-execute-search (invert)
+  "Send the `inferior-ess-search-list-command' command.
+INVERT is as in `ess-execute'. E.g. search(..) in S."
+  (interactive "P")
+  (ess-execute inferior-ess-search-list-command  invert "S search list"))
+
+;; FIXME --- this *only* works in S / S-plus; not in R
+;; -----     ("at least" is not assigned to any key by default)
+(defun ess-execute-attach (dir &optional posn)
+  "Attach a directory in the `ess-language' process with the attach() command.
+When used interactively, user is prompted for DIR to attach and
+prefix argument is used for POSN (or 2, if absent.)
+Doesn't work for data frames."
+  (interactive "Attach directory: \nP")
+  (ess-execute (concat "attach(\""
+                       (directory-file-name (expand-file-name dir))
+                       "\""
+                       (if posn (concat "," (number-to-string
+                                             (prefix-numeric-value posn))))
+                       ")") 'buffer)
+  (ess-process-put 'sp-for-help-changed? t))
+
+(defun ess-execute-screen-options (&optional invisibly)
+  "Cause S to set the \"width\" option to 1 less than the window width.
+Also sets the \"length\" option to 99999. When INVISIBLY is
+non-nil, don't echo to R subprocess. This is a good thing to put
+in `ess-r-post-run-hook' or `ess-S+-post-run-hook'."
+  (interactive)
+  (ess-if-verbose-write
+   (format "ess-execute-screen-options: invisibly=%s\n" invisibly))
+  (if (null ess-execute-screen-options-command)
+      (message "Not implemented for '%s'" ess-dialect)
+    (let ((command (ess-calculate-width 'window)))
+      (if invisibly
+          (ess-command command)
+        (ess-eval-linewise command nil nil nil 'wait-prompt)))))
+
+;; Runs in background if inferior is not busy
+(defun ess--execute-screen-options-bg ()
+  (when (and ess-execute-screen-options-command
+             (inferior-ess-available-p))
+    (ess-execute-screen-options t)))
+
+(defun ess-calculate-width (opt)
+  "Calculate width command given OPT.
+OPT can be \\='window, \\='frame, or an integer. Return a command
+suitable to send to the inferior process (e.g.
+\"options(width=80, length=999999)\")."
+  (when (null ess-execute-screen-options-command)
+    (error "Not implemented for %s" ess-dialect))
+  (let (command)
+    (cond ((and (integerp opt)
+                (>= opt 0))
+           (setq command (format ess-execute-screen-options-command opt)))
+          ((or (eql 'window opt)
+               (and (integerp opt)
+                    (> 0 opt)))
+           ;; We cannot use (window-width) here because it returns sizes
+           ;; in default (frame) characters which leads to incorrect
+           ;; sizes with scaled fonts.To solve this we approximate font
+           ;; width in pixels and use window-pixel-width to compute the
+           ;; approximate number of characters that fit into line.
+           (let* ((wedges (window-inside-pixel-edges))
+                  (wwidth (- (nth 2 wedges) (nth 0 wedges)))
+                  (nchars (floor (/ wwidth (default-font-width)))))
+             (when (and (integerp opt)
+                        (> 0 opt))
+               (setq nchars (- nchars (- opt))))
+             (setq command (format ess-execute-screen-options-command
+                                   nchars))))
+          ((eql 'frame opt)
+           (setq command
+                 (format ess-execute-screen-options-command (frame-width))))
+          (t (error "OPT (%s) not 'window, 'frame or an integer" opt)))
+    command))
+
+(defun ess-set-width ()
+  "Set the width option.
+A part of `window-configuration-change-hook' in inferior ESS
+buffers."
+  (when (and ess-auto-width
+             ess-execute-screen-options-command)
+    ;; `window-configuration-change-hook' runs with the window selected.
+    (let ((proc (get-buffer-process (window-buffer)))
+          command)
+      ;; TODO: Set the width once the process is no longer busy.
+      (when (and (process-live-p proc)
+                 (not (process-get proc 'busy)))
+        (setq command (ess-calculate-width ess-auto-width))
+        (if ess-auto-width-visible
+            (ess-eval-linewise command nil nil nil 'wait-prompt)
+          (ess-command command))))))
+
+(defun ess-execute (command &optional invert buff message)
+  "Send a command to the ESS process.
+A newline is automatically added to COMMAND.  Prefix arg (or second arg
+INVERT) means invert the meaning of
+`ess-execute-in-process-buffer'.  If INVERT is \\='buffer, output is
+forced to go to the process buffer.  If the output is going to a
+buffer, name it *BUFF*.  This buffer is erased before use.  Optional
+fourth arg MESSAGE is text to print at the top of the buffer (defaults
+to the command if BUFF is not given.)"
+  (interactive (list
+                ;; simpler way to set proc name in mb?
+                (let ((enable-recursive-minibuffers t)
+                      (proc-name (progn (ess-force-buffer-current)
+                                        ess-local-process-name)))
+                  (with-current-buffer (get-buffer " *Minibuf-1*") ;; FIXME: hardcoded name
+                    (setq ess-local-process-name proc-name))
+                  (read-from-minibuffer "Execute> " nil
+                                        ess-mode-minibuffer-map))
+                current-prefix-arg))
+  (ess-make-buffer-current)
+  (let ((the-command (concat command "\n"))
+        (buff-name (concat "*" (or buff "ess-output") "*"))
+        (in-pbuff (if invert (or (eq invert 'buffer)
+                                 (not ess-execute-in-process-buffer))
+                    ess-execute-in-process-buffer)))
+    (if in-pbuff
+        (ess-eval-linewise the-command)
+      (ess-with-current-buffer (get-buffer-create buff-name)
+        (ess-command the-command (current-buffer) nil nil nil
+                     (get-process ess-local-process-name))
+        (ansi-color-apply-on-region (point-min) (point-max))
+        (goto-char (point-min))
+        (if message (insert message)
+          (insert "> " the-command))
+        (display-buffer (current-buffer))))))
+
+\f
+;;;*;;; Quitting
+
+(cl-defgeneric ess-quit--override (_arg)
+  "Stop the inferior process."
+  (let ((proc (ess-get-process)))
+    (ess-cleanup)
+    (when ess-eval-visibly
+      (goto-char (marker-position (process-mark proc)))
+      (insert inferior-ess-exit-command))
+    (process-send-string proc inferior-ess-exit-command)))
+
+(defun ess-quit (&optional arg)
+  "Issue an exiting command to the inferior process.
+Runs `ess-cleanup'. ARG gets passed to a language specific
+method, see `ess-quit--override'."
+  (interactive "P")
+  (unless (ess-process-live-p)
+    (user-error "No live ESS process associated with this buffer"))
+  (ess-force-buffer-current "Process to quit: ")
+  (ess-interrupt)
+  (ess-make-buffer-current)
+  (ess-quit--override arg))
+
+(defvar ess--interrupt-timeout 5)
+
+(defun ess-interrupt ()
+  "Interrupt the inferior process.
+This sends an interrupt and quits a debugging session."
+  (interactive)
+  (inferior-ess-force)
+  (let ((proc (ess-get-process)))
+    (ess--interrupt proc)
+    (unless (ess-wait-for-process proc nil nil nil
+                                  ess--interrupt-timeout)
+      (error "Timeout while interrupting process"))
+    (with-current-buffer (process-buffer proc)
+      (goto-char (process-mark proc)))))
+
+(defun ess--interrupt (proc)
+  (interrupt-process proc comint-ptyp)
+  ;; Workaround for Windows terminals. NOTE: Is this really needed
+  ;; for background commands? Or just for interactive interrupts?
+  (unless (memq system-type '(gnu/linux darwin))
+    (process-send-string nil "\n")))
+
+(defun ess-abort ()
+  "Kill the ESS process, without executing .Last or terminating devices.
+If you want to finish your session, use \\[ess-quit] instead."
+;;; Provided as a safety measure over the default binding of C-c C-z in
+;;; comint-mode-map.
+  (interactive)
+  (ding)
+  (message "WARNING: \\[inferior-ess-exit-command] will not be executed and graphics devices won't finish properly!")
+  (sit-for 2)
+  (if (y-or-n-p "Still abort? ")
+      (comint-quit-subjob)
+    (message "Good move.")))
+
+(defun ess-cleanup ()
+  "Cleanup buffers associated with the 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. Uses `display-buffer' to display the process buffer. It
+is run automatically by \\[ess-quit]."
+  (interactive)
+  (let* ((the-procname (or (ess-make-buffer-current) ess-local-process-name))
+         (buf (buffer-name (process-buffer (get-process the-procname)))))
+    (unless the-procname
+      (error "I don't know which ESS process to clean up after!"))
+    (when
+        (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))))
+      (dolist (buf (buffer-list))
+        (with-current-buffer buf
+          ;; Consider buffers for which ess-local-process-name is
+          ;; the same as the-procname
+          (when (and (not (get-buffer-process buf))
+                     ess-local-process-name
+                     (equal ess-local-process-name the-procname))
+            (kill-buffer buf)))))
+    (display-buffer buf)
+    buf))
+
+(defun inferior-ess-reload (&optional start-args)
+  "Reload the inferior process.
+START-ARGS gets passed to the dialect-specific
+`inferior-ess-reload-override'."
+  (interactive)
+  (let* ((inf-buf (inferior-ess-force))
+         (inf-proc (get-buffer-process inf-buf))
+         (inf-start-data (buffer-local-value 'inferior-ess--local-data inf-buf))
+         (start-name (car inf-start-data))
+         (start-args (or start-args (cdr inf-start-data))))
+    ;; Interrupt early so we can get working directory
+    (ess-interrupt)
+    ;; Quit debugging session before reloading
+    (when (ess-debug-active-p)
+      (ess-debug-command-quit)
+      (ess-wait-for-process inf-proc nil nil nil 1))
+    (save-window-excursion
+      ;; Make sure we don't ask for directory again
+      ;; Use current working directory as default
+      (let ((project-find-functions nil)
+            (ess-startup-directory-function nil)
+            (ess-startup-directory (ess-get-process-variable 'default-directory))
+            (ess-ask-for-ess-directory nil))
+        (ess-quit 'no-save)
+        (inferior-ess--wait-for-exit inf-proc)
+        (with-current-buffer inf-buf
+          (inferior-ess-reload--override start-name start-args))))))
+
+(cl-defgeneric inferior-ess-reload--override (_start-name _start-args)
+  (user-error "Reloading not implemented for %s" ess-dialect))
+
+(defun inferior-ess--wait-for-exit (proc)
+  "Wait for process PROC to exit.
+This should be used instead of `ess-wait-for-process' for waiting
+after issuing a quit command as the latter assumes a live process."
+  (let ((start-time (float-time)))
+    (while (eq (process-status proc) 'run)
+      (accept-process-output proc 0.002)
+      (when (> (- (float-time) start-time) 30)
+        (error "Timeout while quitting process")))))
+
+\f
+;;;*;;; 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 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."
+  (let* ((entry (nth (1- posn) alist))
+         (dir (car entry))
+         (timestamp (car (cdr entry)))
+         (new-modtime (and timestamp
+                           (ess-dir-modtime dir))))
+    ;; Refresh the object listing if necessary
+    (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."
+  (and ess-filenames-map
+       (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, i.e., for R or any non-S language!"
+  (let ((path (ess-search-list))
+        result)
+    (while (and (not result) path)
+      (setq result (file-attributes
+                    (concat (file-name-as-directory (car path))
+                            object)))
+      (setq path (cdr path)))
+    (nth 5 result)))
+
+(defun ess-modtime-gt (mod1 mod2)
+  "Return t if MOD1 is later than MOD2."
+  (and mod1
+       (or (> (car mod1) (car mod2))
+           (and (= (car mod1) (car mod2))
+                (> (car (cdr mod1)) (car (cdr mod2)))))))
+
+(defun ess-get-object-list (name &optional exclude-first)
+  "Return a list of current S object names associated with process NAME.
+Uses `ess-object-list' if that is non-nil. If EXCLUDE-FIRST is
+non-nil, don't return objects in first position (.GlobalEnv)."
+  (or ess-object-list ;; <<-  MM: this is now always(?) nil; we cache the *-modtime-alist
+      (with-current-buffer (process-buffer (ess-get-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-process-get 'sp-for-help-changed?))
+            (progn (ess-write-to-dribble-buffer "--> (ess-get-modtime-list)\n")
+                   (ess-get-modtime-list))
+          ;;else
+          (ess-write-to-dribble-buffer " using existing ess-sl-modtime-alist\n"))
+        (let* ((alist ess-sl-modtime-alist)
+               (i 2)
+               (n (length alist))
+               result)
+          (ess-write-to-dribble-buffer (format " (length alist) : %d\n" n))
+          (unless exclude-first
+            ;; re-read of position 1 :
+            (setq result (ess-extract-onames-from-alist alist 1 'force)))
+          (ess-write-to-dribble-buffer
+           (format " have re-read pos=1: -> length %d\n" (length result)))
+          ;; 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 (delete-dups result))))))
+
+(defun ess-get-words-from-vector (command &optional no-prompt-check wait proc
+                                          timeout)
+  "Evaluate the S command COMMAND, which returns a character vector.
+Return the elements of the result of COMMAND as an alist of
+strings. COMMAND should have a terminating newline.
+NO-PROMPT-CHECK, WAIT, PROC, and TIMEOUT are passed to `ess-command'.
+
+FILTER may be the keyword \\='non-... or nil. To avoid truncation of
+long vectors, wrap your command (%s) like this, or a version with
+explicit options(max.print=1e6): \"local({ out <- try({%s});
+print(out, max=1e6) })\n\"."
+  (unless proc
+    (inferior-ess-force))
+  (let* ((tbuffer (get-buffer-create
+                   " *ess-get-words*")); initial space: disable-undo
+         (word-RE
+          (concat "\\("
+                  "\\\\\"" "\\|" "[^\"]" ;  \" or non-"-char
+                  "\\)*"))
+         (full-word-regexp
+          (concat "\"" "\\(" word-RE "\\)"
+                  "\""
+                  "\\( \\|$\\)"; space or end
+                  ))
+         words)
+    (ess-command command tbuffer 'sleep no-prompt-check wait proc nil timeout)
+    (with-current-buffer tbuffer
+      (goto-char (point-min))
+      (while (re-search-forward full-word-regexp nil t)
+        (setq words (cons (buffer-substring (match-beginning 1) (match-end 1))
+                          words))))
+    (ess-if-verbose-write
+     (if (> (length words) 5)
+         (format " |-> (length words)= %d\n" (length words))
+       (format " |-> words= '%s'\n" words)))
+    (reverse words)))
+
+(defun ess-get-words-from-vector--foreground (command &optional no-prompt-check wait proc)
+  (let ((timeout most-positive-fixnum))
+    (ess-get-words-from-vector command no-prompt-check wait proc timeout)))
+
+(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) "___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)
+  "Return alist of S object names in directory (or object) OBJ.
+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 the command
+`inferior-ess-safe-names-command'. If POS is supplied return the
+result of the command in `inferior-ess-objects-command'. If OBJ
+is nil or not a directory, POS must be supplied. In all cases,
+the value is an list of object names."
+  (cond ((and (stringp obj)
+              (string-match-p "ESSR" obj))
+         nil)
+        ;; FIXME: in both cases below, the same fallback "objects(POS)" is used -- merge!
+        ((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
+                  ;; first try .Data subdirectory:
+                  ;;FIXME: move ".Data" or ``this function'' to ess-sp6-d.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)))))
+        ((and obj ;; want names(obj)
+              (ess-get-words-from-vector
+               (format inferior-ess-safe-names-command obj))))
+        (pos
+         (ess-get-words-from-vector
+          (format inferior-ess-objects-command pos)))))
+
+(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)))
+
+(defun ess-function-arguments (funname &optional proc)
+  "Get FUNARGS from cache or ask the process for it.
+Return FUNARGS - a list with the first element being a
+cons (PACKAGE_NAME . TIME_STAMP), second element is a string
+giving arguments of the function as they appear in documentation,
+third element is a list of arguments of all methods. If PROC is
+given, it should be an ESS process. If PACKAGE_NAME is nil, and
+TIME_STAMP is less recent than the time of the last user
+interaction to the process, then update the entry. PACKAGE_NAME
+is also nil when FUNNAME was not found, or FUNNAME is a special
+name that contains :,$ or @."
+  (when (and funname ;; usually returned by ess--fn-name-start (might be nil)
+             (or proc (ess-process-live-p)))
+    (let* ((proc (or proc (get-process ess-local-process-name)))
+           (cache (or (process-get proc 'funargs-cache)
+                      (let ((cache (make-hash-table :test 'equal)))
+                        (process-put proc 'funargs-cache cache)
+                        cache)))
+           (args (gethash funname cache))
+           (pack (caar args))
+           (ts   (cdar args)))
+      (when (and args
+                 (and (time-less-p ts (process-get proc 'last-eval))
+                      (or (null pack)
+                          (equal pack ""))))
+        ;; reset cache
+        (setq args nil))
+      (or args
+          (cadr (assoc funname (process-get proc 'funargs-pre-cache)))
+             (and
+              (not (process-get proc 'busy))
+              (with-current-buffer (ess-command (format ess-funargs-command
+                                                                            (ess-quote-special-chars funname))
+                                                                nil nil nil nil proc)
+                (goto-char (point-min))
+                (when (re-search-forward "(list" nil t)
+                  (goto-char (match-beginning 0))
+                  (setq args (ignore-errors (eval (read (current-buffer)) t)))
+                  (when args
+                        (setcar args (cons (car args) (current-time)))))
+                ;; push even if nil
+                (puthash (substring-no-properties funname) args cache)))))))
+
+;;; 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 is loaded when `ess-mode' is
+loaded. It defines the variable `ess-object-name-db', which is
+used for completions. Before you call this function, modify the S
+search list so that it contains all the non-changing (i.e.
+system) S directories. All positions of the search list except
+for position 1 are searched and stored in the database. After
+running this command, you should move ess-namedb.el to a
+directory in the `load-path'."
+  (interactive)
+  (setq ess-object-name-db nil)
+  (let ((search-list (cdr (ess-search-list)))
+        (pos 2)
+        name
+        (buffer (get-buffer-create " *ess-db*"))
+        (temp-object-name-db nil))
+
+    (ess-write-to-dribble-buffer
+     (format "(object db): search-list=%s \n " search-list))
+    (while search-list
+      (message "Searching %s" (car search-list))
+      (setq temp-object-name-db (cons (cons (car search-list)
+                                            (ess-object-names nil pos))
+                                      temp-object-name-db))
+      (setq search-list (cdr search-list))
+      (ess-write-to-dribble-buffer
+       (format "(object db): temp-obj-name-db=%s \n pos=%s"
+               temp-object-name-db pos))
+      (setq pos (1+ pos)))
+    (with-current-buffer buffer
+      (erase-buffer)
+      (insert "(setq ess-object-name-db '")
+      (prin1 temp-object-name-db (current-buffer))
+      (insert ")\n")
+      (setq name (expand-file-name ess-object-name-db-file))
+      (write-region (point-min) (point-max) name)
+      (message "Wrote %s" name))
+    (kill-buffer buffer)
+    (setq ess-object-name-db temp-object-name-db)))
+
+(defun ess-resynch nil
+  "Reread all directories and objects in `ess-search-list' for completions."
+  (interactive)
+  (if (ess-make-buffer-current) nil
+    (error "Not an ESS process buffer"))
+  (setq
+   ess-sl-modtime-alist nil
+   ess-object-list nil
+   ess-object-name-db nil ; perhaps it would be better to reload?
+   )
+  (ess-process-put 'sp-for-help-changed? t)
+  ;; Action! :
+  (ess-get-modtime-list))
+
+(defun ess-filename-completion ()
+  "Return completion only within string or comment."
+  (save-restriction ;; explicitly handle inferior-ess
+    (ignore-errors
+      (when (and (derived-mode-p 'inferior-ess-mode)
+                 (> (point) (process-mark (get-buffer-process (current-buffer)))))
+        (narrow-to-region (process-mark (get-buffer-process (current-buffer)))
+                          (point-max))))
+    (when (and (not (equal ?` (nth 3 (syntax-ppss (point)))))
+               (ess-inside-string-or-comment-p (point)))
+      (append (comint-filename-completion) '(:exclusive no)))))
+
+(defun ess-complete-filename ()
+  "Do file completion only within strings."
+  (declare (obsolete comint-filename-completion "ESS 19.04"))
+  (save-restriction ;; explicitly handle inferior-ess
+    (ignore-errors
+      (when (and (derived-mode-p 'inferior-ess-mode)
+                 (> (point) (process-mark (get-buffer-process (current-buffer)))))
+        (narrow-to-region (process-mark (get-buffer-process (current-buffer)))
+                          (point-max))))
+    (when (or (ess-inside-string-or-comment-p (point))) ;; usable within ess-mode as well
+      (comint-dynamic-complete-filename))))
+
+(defun ess-after-pathname-p nil
+  ;; Heuristic: after partial pathname if it looks like we're in a
+  ;; string, and that string looks like a pathname. Not the best for
+  ;; use with unix() (or it's alias, !). Oh well.
+  (declare (obsolete comint-filename-completion "ESS 19.04"))
+  (save-excursion
+    (save-match-data
+      (let ((opoint (point)))
+        (and (re-search-backward "\\(\"\\|'\\)[~/#$.a-zA-Z0-9][^ \t\n\"']*"
+                                 nil t)
+             (eq opoint (match-end 0)))))))
+
+\f
+;;*;; Functions handling the search list
+
+(defun ess-search-list (&optional force-update)
+  "Return the current search list as a list of strings.
+Elements which are apparently directories are expanded to full
+dirnames. Don't try to use cache if FORCE-UPDATE is non-nil. Is
+*NOT* used by \\[ess-execute-search], but by \\[ess-resynch],
+\\[ess-get-object-list], \\[ess-get-modtime-list],
+\\[ess-execute-objects], \\[ess-object-modtime],
+\\[ess-create-object-name-db], and (indirectly) by
+\\[ess-get-help-files-list]."
+  (with-current-buffer
+      (ess-get-process-buffer ess-current-process-name);to get *its* local vars
+    (let ((result nil)
+          (slist (ess-process-get 'search-list))
+          (tramp-mode nil)) ;; hack for bogus file-directory-p below
+      (if (and slist
+               (not force-update)
+               (not (ess-process-get 'sp-for-help-changed?)))
+          slist
+        ;; else, re-compute:
+        (ess-write-to-dribble-buffer " (ess-search-list ... ) ")
+        (let ((tbuffer (get-buffer-create " *search-list*"))
+              (homedir default-directory)
+              (my-search-cmd inferior-ess-search-list-command); from ess-buffer
+              elt)
+          (ess-command my-search-cmd tbuffer 0.05); <- sleep for dde only; does (erase-buffer)
+          (with-current-buffer tbuffer
+            ;; guaranteed by the initial space in its name: (buffer-disable-undo)
+            (goto-char (point-min))
+            (ess-write-to-dribble-buffer
+             (format "after '%s', point-max=%d\n" my-search-cmd (point-max)))
+            (while (re-search-forward "\"\\([^\"]*\\)\"" nil t)
+              (setq elt (buffer-substring (match-beginning 1) (match-end 1)))
+              ;;Dbg: (ess-write-to-dribble-buffer (format "  .. elt= %s \t" elt))
+              (if (and (string-match "^[^/]" elt)
+                       (file-directory-p (concat homedir elt)))
+                  (progn
+                    ;;Dbg: (ess-write-to-dribble-buffer "*IS* directory\n")
+                    (setq elt (concat homedir elt)))
+                ;;else
+                ;;dbg
+                ;;-             (ess-write-to-dribble-buffer "not dir.\n")
+                )
+              (setq result (append result (list elt))))
+            (kill-buffer tbuffer)))
+        result))))
+
+;;; ess-sl-modtime-alist is a list with elements as follows:
+;;;  * key             (directory or object name)
+;;;  * modtime         (list of 2 integers)
+;;;  * name, name ...  (accessible objects in search list posn labeled by key)
+;;; 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 (&optional cache-var-name exclude-first)
+  "Record directories in the search list, and the objects in those directories.
+The result is stored in CACHE-VAR-NAME. If nil, CACHE-VAR-NAME
+defaults to `ess-sl-modtime-alist'. If EXCLUDE-FIRST is non-nil
+don't recompile first object in the search list."
+  ;; Operation applies to process of current buffer
+  (let* ((searchlist (if exclude-first
+                         (cdr (ess-search-list))
+                       (ess-search-list)))
+         (index (if exclude-first 2 1))
+         (cache-name (or cache-var-name 'ess-sl-modtime-alist))
+         pack newalist)
+    (while searchlist
+      (setq
+       pack  (car searchlist)
+       newalist (append newalist
+                        (list (or (assoc pack (symbol-value cache-name))
+                                  (append
+                                   (list pack (ess-dir-modtime pack))
+                                   (prog2
+                                       (message "Forming completions for %s..." pack)
+                                       (ess-object-names pack index)
+                                     (message "Forming completions for %s...done" pack))))))
+       index  (1+ index)
+       searchlist  (cdr searchlist)))
+    ;;DBG:
+    (ess-write-to-dribble-buffer
+     (format "(%s): created new alist of length %d\n"
+             cache-var-name (length newalist)))
+    (set cache-name 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 process variable `search-list' up to
+date. `ess-completing-read' in \\[ess-read-object-name] uses this
+list indirectly when it prompts for help or for an object to
+dump. From ESS 12.09 this is not necessary anymore, as the search
+path is checked on idle time. It is kept for robustness and
+backward compatibility only."
+  (when ess-change-sp-regexp
+    (if (string-match ess-change-sp-regexp str)
+        (ess-process-put 'sp-for-help-changed? t))))
+
+\f
+;;; Miscellaneous routines
+
+;;;*;;; Routines for reading object names
+(defun ess-read-object-name (p-string)
+  "Read an object name from the minibuffer with completion, and return it.
+P-STRING is the prompt string."
+  (let* ((default (ess-read-object-name-dump))
+         (object-list (ess-get-object-list ess-local-process-name))
+         (spec (ess-completing-read p-string object-list nil nil nil nil default)))
+    (list (cond
+           ((string= spec "") default)
+           (t spec)))))
+
+(defun ess-read-object-name-default ()
+  "Return the object name at point, or nil if none."
+  (ignore-errors
+    (save-excursion
+      ;; The following line circumvents an 18.57 bug in following-char
+      (if (eobp) (backward-char 1))   ; Hopefully buffer is not empty!
+      ;; Get onto a symbol
+      (catch 'nosym          ; bail out if there's no symbol at all before point
+        (while (let ((sc (char-syntax (following-char))))
+                 (not (or (= sc ?w) (= sc ?_))))
+          (if (bobp) (throw 'nosym nil) (backward-char 1))))
+      (let*
+          ((end (progn (forward-sexp 1) (point)))
+           (beg (progn (backward-sexp 1) (point))))
+        (buffer-substring-no-properties beg end)))))
+
+(defun ess-read-object-name-dump ()
+  "Return the object name at point, or \"Temporary\" if none."
+  (ignore-errors
+    (save-excursion
+      ;; Get onto a symbol
+      (catch 'nosym ; bail out if there's no symbol at all before point
+        (while (/= (char-syntax (following-char)) ?w)
+          (if (bobp) (throw 'nosym nil) (backward-char 1)))
+        (let*
+            ((end (progn (forward-sexp 1) (point)))
+             (beg (progn (backward-sexp 1) (point)))
+             (object-name (buffer-substring beg end)))
+          (or object-name "Temporary"))))))
+
+;;;; start of ess-smart-operators
+;;;; inspired by slime repl shortcuts
+
+(defvar ess--handy-history nil)
+
+(defun ess-handy-commands ()
+  "Request and execute a command from variable `ess-handy-commands'."
+  (interactive)
+  (let* ((commands (or ess--local-handy-commands
+                       ess-handy-commands))
+         (hist (and (assoc (car ess--handy-history)
+                           commands)
+                    (car ess--handy-history))))
+    (call-interactively
+     (cdr (assoc (ess-completing-read "Execute"
+                                      (sort (mapcar #'car commands)
+                                            #'string-lessp)
+                                      nil t nil 'ess--handy-history hist)
+                 commands)))))
+
+(defun ess-smart-comma ()
+  "If comma is invoked at the process marker of an ESS inferior
+buffer, request and execute a command from `ess-handy-commands'
+list."
+  (interactive)
+  (let ((proc (get-buffer-process (current-buffer))))
+    (if (and proc
+             (eq (point) (marker-position (process-mark proc))))
+        (ess-handy-commands)
+      (if ess-smart-operators
+          (progn
+            (delete-horizontal-space)
+            (insert ", ")
+            (unless (derived-mode-p 'inferior-ess-mode)
+              (indent-according-to-mode)))
+        (insert ",")))))
+
+\f ; directories
+(defun ess-set-working-directory (path &optional no-error)
+  "Set the current working to PATH for the ESS buffer and iESS process.
+NO-ERROR prevents errors when this has not been implemented for
+`ess-dialect'."
+  (interactive "DChange working directory to: ")
+  (if ess-setwd-command
+      (let* ((remote (file-remote-p path))
+             (path (if remote
+                       (progn
+                         (require 'tramp-sh)
+                         (tramp-sh-handle-expand-file-name path))
+                     path))
+             (lpath (if remote
+                        (with-parsed-tramp-file-name path v v-localname)
+                      path)))
+        (ess-eval-linewise (format ess-setwd-command lpath))
+        (ess-set-process-variable 'default-directory
+                                  (file-name-as-directory path)))
+    (unless no-error
+      (error "Not implemented for dialect %s" ess-dialect))))
+
+(defalias 'ess-change-directory #'ess-set-working-directory)
+(define-obsolete-function-alias
+  'ess-use-dir #'ess-set-working-directory "ESS 18.10")
+
+(defun ess-use-this-dir (&rest _ignore)
+  "Set the current process directory to the directory of this file.
+`default-directory' is used as a fallback."
+  (interactive)
+  (let ((dir (if buffer-file-name
+                 (file-name-directory buffer-file-name)
+               default-directory)))
+    (ess-set-working-directory (abbreviate-file-name dir))))
+
+(defun ess-get-working-directory (&optional no-error)
+  "Retrieve the current working directory from the current ess process."
+  (if ess-getwd-command
+      (abbreviate-file-name (car (ess-get-words-from-vector ess-getwd-command)))
+    (unless no-error
+      (error "Not implemented for dialect %s" ess-dialect))))
+
+(defun ess-synchronize-dirs ()
+  "Set Emacs' current directory to be the same as the subprocess directory.
+To be used in `ess-idle-timer-functions'."
+  (when (and (ess-can-eval-in-background)
+             ess-getwd-command
+             (inferior-ess-available-p))
+    (ess-when-new-input last-sync-dirs
+      (ess-if-verbose-write "\n(ess-synchronize-dirs)\n")
+      (let ((lpath (car (ess-get-words-from-vector ess-getwd-command))))
+        (setq default-directory
+              (file-name-as-directory
+               (ess--derive-connection-path default-directory lpath))))
+      default-directory)))
+
+(defun ess-dirs ()
+  "Set Emacs' current directory to be the same as the *R* process."
+  ;; Note: This function is not necessary anymore. The Emacs
+  ;; default-directory and subprocess working directory are
+  ;; synchronized automatically.
+  (interactive)
+  (let* ((dir (car (ess-get-words-from-vector "getwd()\n")))
+         (new-default-dir (ess--derive-connection-path default-directory dir)))
+    (message "(ESS / default) directory: %s" dir)
+    (setq default-directory (file-name-as-directory new-default-dir))))
+
+(defun ess--derive-connection-path (old new)
+  "Derive a (possibly remote) path with an updated local filename.
+A new connection path is derived from OLD (a path) and NEW (a
+path), in such a way that the host and connection information (if
+any) in OLD is retained in the NEW path. NEW must be an absolute
+path, and can be a remote path"
+  (concat (file-remote-p old)
+          (or (file-remote-p new 'localname) new)))
+
+;; search path
+(defun ess--mark-search-list-as-changed ()
+  "Internal. Mark all the search-list related variables as changed."
+  ;; other guys might track their own
+  (ess-process-put 'sp-for-help-changed? t)
+  (ess-process-put 'sp-for-ac-changed? t))
+
+(defun ess-cache-search-list ()
+  "To be used in `ess-idle-timer-functions', to set search path related variables."
+  (when (and (ess-can-eval-in-background)
+             inferior-ess-search-list-command)
+    (ess-when-new-input last-cache-search-list
+      (let ((path (ess-search-list 'force))
+            (old-path (process-get *proc* 'search-list)))
+        (when (not (equal path old-path))
+          (process-put *proc* 'search-list path)
+          (ess--mark-search-list-as-changed)
+          path)))))
+
+\f
+;;*;; Temporary buffer handling
+(defun ess-display-temp-buffer (buff)
+  "Display the buffer BUFF.
+Uses `temp-buffer-show-function' and respects
+`ess-display-buffer-reuse-frames'."
+  (if (fboundp temp-buffer-show-function)
+      (funcall temp-buffer-show-function buff))
+  (display-buffer buff '(display-buffer-reuse-window) ess-display-buffer-reuse-frames))
+
+(defun ess--inject-code-from-file (file &optional chunked)
+  "Load code from FILE into process.
+If CHUNKED is non-nil, split the file by \\^L separator (must be at
+bol) and load each chunk separately."
+  ;; This is different from ess-load-file as it works by directly loading the
+  ;; string into the process and thus works on remotes.
+  (let ((proc-name ess-local-process-name)
+        (dialect ess-dialect)
+        (send-1 (lambda (str)
+                  (if (string= ess-dialect "R")
+                      ;; avoid detection of intermediate prompts
+                      (ess-command (concat "{" str "}\n"))
+                    (ess-command str)))))
+    (with-temp-buffer
+      (setq ess-local-process-name proc-name
+            ess-dialect dialect)
+      (insert-file-contents-literally file)
+      (if chunked
+          (let ((beg (point-min)))
+            (goto-char beg)
+            (while (re-search-forward "^\f" nil t)
+              (funcall send-1 (buffer-substring beg (point)))
+              (setq beg (point)))
+            (funcall send-1 (buffer-substring (point) (point-max))))
+        (funcall send-1 (buffer-string))))))
+
+(defun ess-check-modifications nil
+  "Check whether loading this file would overwrite some ESS objects
+which have been modified more recently than this file, and confirm
+if this is the case."
+  (declare (obsolete "Do not use" "21.04"))
+  (when (> (length ess-change-sp-regexp) 0)
+    (and (buffer-file-name) ess-filenames-map
+         (let ((sourcemod (nth 5 (file-attributes (buffer-file-name))))
+               (objname))
+           (save-excursion
+             (goto-char (point-min))
+             ;; Get name of assigned object, if we can find it
+             (setq objname
+                   (and
+                    (re-search-forward
+                     "^\\s *\"?\\(\\(\\sw\\|\\s_\\)+\\)\"?\\s *[<_]"
+                     nil
+                     t)
+                    (buffer-substring (match-beginning 1)
+                                      (match-end 1)))))
+           (and
+            sourcemod                  ; the file may have been deleted
+            objname                    ; may not have been able to
+                                        ; find name
+            (ess-modtime-gt (ess-object-modtime objname) sourcemod)
+            (not (y-or-n-p
+                  (format
+                   "The ESS object %s is newer than this file. Continue? "
+                   objname)))
+            (error "Aborted"))))))
+
+(define-obsolete-function-alias 'ess-check-source #'ess-save-file "ESS 19.04")
+(defun ess-save-file (file)
+  "If FILE (a string) has an unsaved buffer, offer to save it.
+Return t if the buffer existed and was modified, but was not
+saved. If `ess-save-silently' is non-nil, the buffer is
+saved without offering."
+  (when-let ((buff (find-buffer-visiting file)))
+    (when (and (buffer-modified-p buff)
+               (or (eql ess-save-silently t)
+                   (and (eql ess-save-silently 'auto)
+                        (or (not compilation-ask-about-save)
+                            (bound-and-true-p
+                             ;; Only added in Emacs 26.1
+                             auto-save-visited-mode)))
+                   (y-or-n-p
+                    (format "Buffer %s is modified. Save? "
+                            (buffer-name buff)))))
+      (with-current-buffer buff
+        (save-buffer)))
+    (buffer-modified-p buff)))
+
+\f
+;;*;; Error messages
+
+(defun ess-parse-errors (&optional showerr _reset)
+  "Jump to error in last loaded ESS source file.
+With prefix argument SHOWERR, only show the errors ESS reported. RESET
+is for compatibility with `next-error' and is ignored."
+  (interactive "P")
+  (ess-make-buffer-current)
+  (let ((errbuff (get-buffer ess-error-buffer-name)))
+    (when (not errbuff)
+      (error "You need to do a load first!"))
+    (set-buffer errbuff)
+    (goto-char (point-max))
+    ;; FIXME: R does not give "useful" error messages by default. We
+    ;; could try to use a more useful one, via
+    ;; options(error=essErrorHandler)
+    (cond ((re-search-backward ess-error-regexp nil t)
+           (let* ((filename (buffer-substring (match-beginning 3) (match-end 3)))
+                  (fbuffer (get-file-buffer filename))
+                  (linenum
+                   (string-to-number
+                    (buffer-substring (match-beginning 2) (match-end 2))))
+                  (errmess (buffer-substring (match-beginning 1) (match-end 1))))
+             (if showerr
+                 (ess-display-temp-buffer errbuff)
+               (if fbuffer nil
+                 (setq fbuffer (find-file-noselect filename))
+                 (with-current-buffer fbuffer
+                   ;; TODO: ess-mode is surely wrong here, but I don't
+                   ;; think we need this whole function anymore?
+                   (when (fboundp 'ess-mode)
+                     (ess-mode))))
+               (pop-to-buffer fbuffer)
+               (ess-goto-line linenum))
+             (princ errmess t)))
+          (t
+           (message "Not a syntax error.")
+           (ess-display-temp-buffer errbuff)))))
+
+(defun ess-error (msg)
+  "Something bad has happened.
+Display the S buffer, and cause an error displaying MSG."
+  (declare (obsolete error "ESS 18.10"))
+  (display-buffer (process-buffer (get-process ess-local-process-name)))
+  (error msg))
+
+(provide 'ess-inf)
+;;; ess-inf.el ends here
diff --git a/elpa/ess-20260424.1544/ess-julia.el b/elpa/ess-20260424.1544/ess-julia.el
new file mode 100644 (file)
index 0000000..27ebed2
--- /dev/null
@@ -0,0 +1,460 @@
+;; ess-julia.el --- ESS julia mode and inferior interaction  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2022 Free Software Foundation, Inc.
+;; Author: Vitalie Spinu
+;; Maintainer: Vitalie Spinu
+;; Created: 02-04-2012 (ESS 12.03)
+;; Keywords: ESS, julia
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;;  Customize inferior-julia-program to point to your julia binary
+;;  and start the inferior with M-x julia.
+
+;;  As of Sept 2015, this file depends heavily on julia-mode.el from the Julia
+;;  sources.  If you install ESS using `make', this will work fine, otherwise
+;;  ensure that julia-mode.el is on your path before loading this file.
+
+;;; Code:
+
+(require 'ess-help)
+(require 'ess-inf)
+(require 'ess-r-mode)
+(require 'ess-utils)
+;; Don't require `julia-mode' to compile this file.
+(when t (require 'julia-mode))
+(declare-function julia-mode "julia-mode" ())
+(declare-function julia-mode-latexsub-completion-at-point-before "julia-mode" ())
+(declare-function julia-mode-latexsub-completion-at-point-around "julia-mode" ())
+(defvar julia-mode-syntax-table)
+
+(defvar ac-prefix)
+(declare-function company-in-string-or-comment "company")
+(declare-function company-doc-buffer "company")
+
+(defcustom inferior-julia-args ""
+  "String of arguments (see `julia --help') used when starting julia."
+  :group 'ess-julia
+  :type 'string)
+
+(eval-when-compile
+  (require 'cl-lib))
+
+(defun ess-julia-send-string-function (process string _visibly)
+  "Send the Julia STRING to the PROCESS.
+VISIBLY is not currently used."
+  (let ((file (concat temporary-file-directory "julia_eval_region.jl")))
+    (with-temp-file file
+      (insert string))
+    (process-send-string process (format ess-load-command file))))
+
+\f
+;;; HELP
+(cl-defmethod ess-help-get-topics (proc &context (ess-dialect "julia"))
+  (append (with-current-buffer (ess--foreground-command "ESS.all_help_topics()\n")
+            (split-string (buffer-string) "\n"))
+          (ess-julia--get-objects proc)))
+
+(defun ess-julia--retrieve-topics (url)
+  (with-current-buffer (url-retrieve-synchronously url)
+    (require 'url)
+    (goto-char (point-min))
+    (let (out)
+      (while (re-search-forward
+              "toctext[ \"]+href=\"\\([^>]+\\)\">\\([^<]+\\)</a" nil t)
+        (push (propertize (match-string 2)
+                          :manual (concat url (match-string 1)))
+              out))
+      (kill-buffer)
+      (nreverse out))))
+
+(defvar ess-julia--manual-topics nil)
+(cl-defmethod ess--manual-lookup-override (&context (ess-dialect "julia"))
+  "Look up topics at https://docs.julialang.org/en/latest/manual/."
+  (let* ((pages (or ess-julia--manual-topics
+                    (setq ess-julia--manual-topics
+                          (ess-julia--retrieve-topics
+                           "https://docs.julialang.org/en/latest/"))))
+         (page (ess-completing-read "Lookup:" pages nil t)))
+    (browse-url (get-text-property 1 :manual page))))
+
+(defun ess-julia-input-sender (proc string)
+  "Function to send PROC STRING submitted by user.
+See `comint-input-sender'."
+  (save-current-buffer
+    (let* ((help-?-regexp "^ *\\(?:\\(?1: *?\\? *\\)\\(?2:.+\\)\\)")
+           (help-?-match (string-match help-?-regexp string)))
+      (cond (help-?-match
+             (ess-display-help-on-object (match-string 2 string))
+             (process-send-string proc "\n"))
+            (t ;; normal command
+             (inferior-ess-input-sender proc string))))))
+
+(cl-defmethod ess-installed-packages (&context (ess-dialect "julia"))
+  "Return list of installed julia packages."
+  ;; FIXME: This doesn't work if the user hasn't done "using Pkg" yet
+  (ess-get-words-from-vector "keys(Pkg.installed())\n"))
+
+(cl-defmethod ess-load-library--override (pack &context (ess-dialect "julia"))
+  (ess-eval-linewise (format "using %s\n" pack)))
+
+\f
+;;; COMPLETION
+
+(defun ess-julia-object-completion ()
+  "Return completions in format required by `completion-at-point-functions'."
+  (let ((proc (ess-get-next-available-process ess-dialect t))
+        (beg (ess-symbol-start)))
+    (if proc
+        (when beg
+          (let* ((prefix (buffer-substring-no-properties beg (point)))
+                 (obj (and (string-match "\\(.*\\)\\..*$" prefix)
+                           (match-string 1 prefix)))
+                 (beg (if obj
+                          (+ beg 1 (length obj))
+                        beg)))
+            (list beg (point)
+                  (nreverse (mapcar #'car (ess-julia--get-objects proc obj)))
+                  :exclusive 'no)))
+      (when (string-match "complet" (symbol-name last-command))
+        (message "No ESS process of dialect %s started" ess-dialect)
+        nil))))
+
+(defun ess-julia-objects (prefix &optional proc)
+  "Given PREFIX get all cached objects from PROC."
+  (when prefix
+    (let ((proc (or proc (ess-get-next-available-process nil t))))
+      (if (string-match "\\(.*\\)\\..*$" prefix)
+          (let ((module (match-string 1 prefix)))
+            (mapcar (lambda (el) (concat module "." (car el)))
+                    (ess-julia--get-objects proc module)))
+        (ess-julia--get-objects proc)))))
+
+(defun ess-julia--get-objects (&optional proc obj)
+  "Return all available objects.
+Local caching might be used. If MODULE is given, return only
+objects from that MODULE."
+  (setq proc (or proc (ess-get-process)))
+  (when (stringp proc)
+    (setq proc (get-process proc)))
+  (when (process-live-p proc)
+    (let ((objects (process-get proc 'objects)))
+      (if (process-get proc 'busy)
+          (if obj
+              (assoc obj objects)
+            (process-get proc 'objects))
+        (if obj
+            (or (cdr (assoc obj objects))
+                ;; don't cache composite objects and datatypes
+                (ess-julia--get-components proc obj))
+          ;; this segment is entered when user completion at top level is
+          ;; requested, either Tab or AC. Hence Main is always updated.
+          (let ((modules (ess-get-words-from-vector
+                          "ESS.main_modules()\n" nil nil proc))
+                (loc (process-get proc 'last-objects-cache))
+                (lev (process-get proc 'last-eval)))
+            (prog1
+                (apply #'nconc
+                       (mapcar
+                        (lambda (mod)
+                          ;; we are caching all modules, and reinit Main every
+                          ;; time user enters commands
+                          (copy-sequence
+                           (or (and (or (not (equal mod "Main"))
+                                        (ignore-errors (time-less-p lev loc)))
+                                    (cdr (assoc mod objects)))
+                               (ess-julia--get-components proc mod t))))
+                        modules))
+              (process-put proc 'last-objects-cache (current-time)))))))))
+
+(defun ess-julia--get-components (proc obj &optional cache?)
+  (with-current-buffer (ess--foreground-command (format "ESS.components(%s)\n" obj)
+                                                nil nil nil nil proc)
+    (goto-char (point-min))
+    (let (list)
+      (while (re-search-forward
+              "^\\([^ \t\n]+\\) +\\([^ \t\n]+\\)$" nil t)
+        (push (cons (match-string 1) (match-string 2)) list))
+      (when cache?
+        (let ((objects (process-get proc 'objects)))
+          (push (cons obj list) objects)
+          (process-put proc 'objects objects)))
+      list)))
+
+(defun ess-julia-get-object-help-string (sym)
+  "Help string for ac."
+  (let ((proc (ess-get-next-available-process nil t)))
+    (if (null proc)
+        "No free ESS process found"
+      (let ((buf (get-buffer-create " *ess-command-output*")))
+        (with-current-buffer (process-buffer proc)
+          (ess-with-current-buffer buf
+            (ess--flush-help-into-current-buffer sym nil)))
+        (with-current-buffer buf
+          (ess-help-underline)
+          (goto-char (point-min))
+          (buffer-string))))))
+
+(defvar ac-source-ess-julia-objects
+  '((prefix     . ess-symbol-start)
+    (requires   . 2)
+    (candidates . ess-ac-julia-objects)
+    (document   . ess-julia-get-object-help-string))
+  "Auto-completion source for julia objects.")
+
+(defun ess-ac-julia-objects ()
+  (require 'auto-complete)
+  (ess-julia-objects ac-prefix))
+
+(declare-function company-begin-backend "company.el")
+
+(defun company-ess-julia-objects (command &optional arg &rest _ignored)
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-ess-julia-objects))
+    (prefix (unless (company-in-string-or-comment)
+              (let ((start (ess-symbol-start)))
+                (when start (buffer-substring-no-properties start (point))))))
+    (candidates (let ((proc (ess-get-next-available-process)))
+                  (when proc
+                    (all-completions arg (mapcar (lambda (x) (or (car-safe x) x))
+                                                 (ess-julia-objects arg proc))))))
+    (doc-buffer (company-doc-buffer (ess-julia-get-object-help-string arg)))))
+
+\f
+;;; ERRORS
+(defvar ess-julia-error-regexp-alist '(ess-julia-in ess-julia-at ess-julia-while-load)
+  "List of symbols which are looked up in `compilation-error-regexp-alist-alist'.")
+
+(add-to-list 'compilation-error-regexp-alist-alist
+             '(ess-julia-in  "^\\s-*in [^ \t\n]* \\(at \\(.*\\):\\([0-9]+\\)\\)" 2 3 nil 2 1))
+(add-to-list 'compilation-error-regexp-alist-alist
+             '(ess-julia-at "^\\S-+\\s-+\\(at \\(.*\\):\\([0-9]+\\)\\)"  2 3 nil 2 1))
+(add-to-list 'compilation-error-regexp-alist-alist
+             '(ess-julia-while-load "^\\s-*\\(while loading\\s-\\(.*\\), in .* on line +\\([0-9]+\\)\\)"  2 3 nil 2 1))
+
+\f
+;;; ELDOC
+(defun ess-julia-eldoc-function (&rest _ignored)
+  "Return the doc string, or nil.
+If an ESS process is not associated with the buffer, do not try
+to look up any doc strings. Honors `eldoc-echo-area-use-multiline-p'."
+  (when (and (ess-can-eval-in-background)
+             (ess-process-live-p)
+             (not (ess-process-get 'busy)))
+    (let ((funname (or (and ess-eldoc-show-on-symbol ;; aggressive completion
+                            (symbol-name (ess-symbol-at-point)))
+                       (car (ess--fn-name-start))))
+          (multiline (eq t eldoc-echo-area-use-multiline-p)))
+      (when funname
+        (let* ((args (copy-sequence (nth 2 (ess-function-arguments funname))))
+               (W (- (window-width (minibuffer-window)) (+ 4 (length funname))))
+               (doc (concat (propertize funname 'face font-lock-function-name-face) ": ")))
+          (when args
+            (setq args (sort args (lambda (s1 s2)
+                                    (< (length s1) (length s2)))))
+            (setq doc (concat doc (pop args)))
+            (while (and args (or multiline (< (+ (length doc) (length (car args))) W)))
+              (setq doc (concat doc "  " (pop args))))
+            (when (and args (< (length doc) W))
+              (setq doc (concat doc " {--}")))
+            doc))))))
+
+\f
+;;; CORE
+(defvar ess-julia-customize-alist
+  '((inferior-ess-primary-prompt   . "\\w*> ")
+    (inferior-ess-secondary-prompt . nil)
+    (inferior-ess-prompt           . "\\w*> ")
+    (ess-local-customize-alist     . 'ess-julia-customize-alist)
+    (inferior-ess-program          . inferior-julia-program)
+    (ess-load-command              . "include(expanduser(\"%s\"))\n")
+    (ess-funargs-command           . "ESS.fun_args(\"%s\")\n")
+    (ess-dump-error-re             . "in \\w* at \\(.*\\):[0-9]+")
+    (ess-error-regexp              . "\\(^\\s-*at\\s-*\\(?3:.*\\):\\(?2:[0-9]+\\)\\)")
+    (ess-error-regexp-alist        . ess-julia-error-regexp-alist)
+    (ess-mode-completion-syntax-table . ess-julia-completion-syntax-table)
+    ;; (inferior-ess-objects-command    . inferior-ess-r-objects-command)
+    ;; (inferior-ess-search-list-command        . "search()\n")
+    (inferior-ess-help-command     . "ESS.help(\"%s\")\n")
+    ;; (inferior-ess-help-command       . "help(\"%s\")\n")
+    (ess-language                  . "julia")
+    (ess-dialect                   . "julia")
+    (ess-suffix                    . "jl")
+    (ess-dump-filename-template    . (replace-regexp-in-string
+                                      "S$" ess-suffix ; in the one from custom:
+                                      ess-dump-filename-template-proto))
+    (ess-mode-editing-alist        . nil)
+    (ess-change-sp-regexp          . nil );ess-r-change-sp-regexp)
+    (ess-help-sec-regex            . ess-help-r-sec-regex)
+    (ess-help-sec-keys-alist       . ess-help-r-sec-keys-alist)
+    (ess-function-pattern          . ess-r-function-pattern)
+    (ess-object-name-db-file       . "ess-jl-namedb.el" )
+    (ess-smart-operators           . ess-r-smart-operators)
+    (inferior-ess-exit-command     . "exit()\n")
+    ;;harmful for shell-mode's C-a: -- but "necessary" for ESS-help?
+    (inferior-ess-language-start   . nil)
+    (ess-STERM                     . "iESS")
+    (ess-editor                    . ess-r-editor)
+    (ess-pager                     . ess-r-pager)
+    (ess-getwd-command             . "pwd()\n")
+    (ess-setwd-command             . "cd(expanduser(\"%s\"))\n"))
+  "Variables to customize for Julia.")
+
+(cl-defmethod ess--help-web-search-override (cmd &context (ess-dialect "julia"))
+  "Offer to search the web for a Julia command."
+  (browse-url (format "https://docs.julialang.org/en/latest/search/?q=%s" cmd)))
+
+(defvar ess-julia-completion-syntax-table
+  (let ((table (copy-syntax-table ess-r-mode-syntax-table)))
+    (modify-syntax-entry ?. "_" table)
+    ;; (modify-syntax-entry ?: "_" table)
+    ;; (modify-syntax-entry ?$ "_" table)
+    (modify-syntax-entry ?@ "_" table)
+    table)
+  "Syntax table used for completion and help symbol lookup.
+It makes underscores and dots word constituent chars.")
+
+(cl-defmethod ess-help-commands (&context (ess-dialect "julia"))
+  '((packages      . "_ess_list_categories()\n")
+    (package-index . "_ess_print_index(\"%s\")\n")
+    (index-keyword-reg . "^\\(.*+\\):$*")
+    (index-start-reg   . ":")))
+
+(defvar ess-julia-mode-syntax-table (copy-syntax-table julia-mode-syntax-table))
+
+(defvar ess-julia-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map ess-mode-map)
+    map)
+  "Keymap for `ess-julia-mode'.")
+
+;;;###autoload
+(define-derived-mode ess-julia-mode julia-mode "ESS[julia]"
+  "Major mode for julia files."
+  :group 'ess-Julia
+  (setq-local ess-local-customize-alist ess-julia-customize-alist)
+  (setq ess-dialect "julia")
+  (ess-setq-vars-local ess-julia-customize-alist)
+  ;; eldoc
+  (ess--setup-eldoc #'ess-julia-eldoc-function)
+  ;; auto-complete
+  (ess--setup-auto-complete '(ac-source-ess-julia-objects))
+  ;; company
+  (ess--setup-company '(company-ess-julia-objects))
+  ;; for emacs >= 24
+  (remove-hook 'completion-at-point-functions #'ess-filename-completion 'local) ;; should be first
+  (add-hook 'completion-at-point-functions #'ess-julia-object-completion nil 'local)
+  (add-hook 'completion-at-point-functions #'ess-filename-completion nil 'local)
+  (add-hook 'completion-at-point-functions #'julia-mode-latexsub-completion-at-point-before nil 'local)
+  (add-hook 'completion-at-point-functions #'julia-mode-latexsub-completion-at-point-around nil 'local)
+  (if (fboundp 'ess-add-toolbar) (ess-add-toolbar)))
+
+;; Inferior mode
+(defvar inferior-ess-julia-mode-syntax-table
+  (copy-syntax-table ess-julia-mode-syntax-table)
+  "Syntax table for `inferior-ess-julia-mode'.")
+
+(define-derived-mode inferior-ess-julia-mode inferior-ess-mode "iESS[julia]"
+  "Major mode for inferior julia processes."
+  :group 'ess-Julia
+  (ess-setq-vars-local ess-julia-customize-alist)
+  (setq-local comint-use-prompt-regexp t)
+  (setq comint-prompt-regexp (concat "^" inferior-ess-prompt))
+  (setq ess-dialect "julia")
+  ;; eldoc
+  (ess--setup-eldoc #'ess-julia-eldoc-function)
+  ;; auto-complete
+  (ess--setup-auto-complete '(ac-source-ess-julia-objects) t)
+  ;; company
+  (ess--setup-company '(company-ess-julia-objects) t)
+  (remove-hook 'completion-at-point-functions #'ess-filename-completion 'local) ;; should be first
+  (add-hook 'completion-at-point-functions #'ess-julia-object-completion nil 'local)
+  (add-hook 'completion-at-point-functions #'ess-filename-completion nil 'local)
+  (add-hook 'completion-at-point-functions #'julia-mode-latexsub-completion-at-point-before nil 'local)
+  (add-hook 'completion-at-point-functions #'julia-mode-latexsub-completion-at-point-around nil 'local)
+  (setq comint-input-sender #'ess-julia-input-sender))
+
+(defvar ess-julia-mode-hook nil)
+(defvar ess-julia-post-run-hook nil
+  "Functions run in process buffer after starting julia process.")
+
+;;;###autoload
+(defun run-ess-julia (&optional start-args)
+  "Start an inferior julia process.
+Optional prefix START-ARGS (\\[universal-argument]) allows to set
+command line arguments, such as --load=<file>. This should be OS
+agnostic. If you have certain command line arguments that should
+always be passed to julia, put them in the variable
+`inferior-julia-args'."
+  (interactive "P")
+  ;; get settings, notably inferior-julia-program :
+  (if (null inferior-julia-program)
+      (error "'inferior-julia-program' does not point to 'julia' or 'julia-basic' executable")
+    (ess-write-to-dribble-buffer   ;; for debugging only
+     (format
+      "\n(julia): ess-dialect=%s, buf=%s, start-arg=%s\n current-prefix-arg=%s\n"
+      ess-dialect (current-buffer) start-args current-prefix-arg))
+    (let* ((jl-start-args
+               (concat inferior-julia-args " " ; add space just in case
+                           (if start-args
+                                   (read-string
+                         (concat "Starting Args"
+                                 (if inferior-julia-args
+                                     (concat " [other than '" inferior-julia-args "']"))
+                                 " ? "))
+                             nil))))
+      (let ((inf-buf (inferior-ess jl-start-args ess-julia-customize-alist)))
+        (with-current-buffer inf-buf
+          (ess--tb-start)
+          ;; Remove ` from julia's logo
+          (goto-char (point-min))
+          (while (re-search-forward "`" nil t)
+            (replace-match "'"))
+          ;; Remove an offending unmatched parenthesis
+          (goto-char (point-min))
+          (forward-line 4)
+          (when (re-search-forward "(" nil t)
+            (replace-match "|"))
+          (goto-char (point-max))
+          ;; --> julia helpers from ../etc/ess-julia.jl :
+          (ess--inject-code-from-file (format "%sess-julia.jl" ess-etc-directory))
+          (run-mode-hooks 'ess-julia-post-run-hook))
+        inf-buf))))
+
+;;;###autoload
+(defalias 'julia #'run-ess-julia)
+
+(cl-defmethod ess--help-major-mode (&context (ess-dialect "julia"))
+  (ess-julia-help-mode))
+
+(define-derived-mode ess-julia-help-mode ess-help-mode "ESS[Julia] Help"
+  "Major mode for Julia documentation."
+  :group 'ess-help
+  (let ((inhibit-read-only t))
+    ;; Julia help buffers can contain color if julia starts with
+    ;; --color=yes
+    (ansi-color-apply-on-region (point-min) (point-max))))
+
+(add-to-list 'auto-mode-alist '("\\.jl\\'" . ess-julia-mode))
+
+(provide 'ess-julia)
+;;; ess-julia.el ends here
diff --git a/elpa/ess-20260424.1544/ess-mode.el b/elpa/ess-20260424.1544/ess-mode.el
new file mode 100644 (file)
index 0000000..4bc3583
--- /dev/null
@@ -0,0 +1,685 @@
+;;; ess-mode.el -- Emacs Speaks Statistics root mode.  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1994-2022 Free Software Foundation, Inc.
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+;; This file defines ess-mode from which other modes (like ess-r-mode)
+;; derive.
+
+;;; Code:
+
+(require 'ess)
+
+(eval-when-compile
+  (require 'cl-lib)
+  (require 'subr-x))
+(require 'ess-inf)
+
+;; Silence the byte compiler
+(declare-function R "ess-r-mode" (&optional start-args))
+(declare-function S+ "ess-sp6-d" (&optional proc-name))
+(declare-function SAS "ess-sas-d" ())
+
+;; FIXME:This one should not be necessary
+(declare-function ess-display-help-on-object "ess-help" (object &optional command))
+
+;; ESS mode
+;; Major mode definition
+
+;;*;; Hooks
+
+(defcustom ess-mode-hook nil
+  "Hook for customizing ESS each time it is entered."
+  :group 'ess-hooks
+  :type 'hook)
+
+(defvar ess-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap yank] #'ess-yank)
+    (define-key map "\C-c\C-r"   #'ess-eval-region)
+    (define-key map "\C-c\M-r"   #'ess-eval-region-and-go)
+    (define-key map "\C-c\C-b"   #'ess-eval-buffer)
+    (define-key map "\C-c\M-b"   #'ess-eval-buffer-and-go)
+    (define-key map (kbd "C-c C-<up>")   #'ess-eval-buffer-from-beg-to-here)
+    (define-key map (kbd "C-c C-<down>") #'ess-eval-buffer-from-here-to-end)
+    (define-key map "\C-c\C-f"   #'ess-eval-function)
+    (define-key map "\C-c\M-f"   #'ess-eval-function-and-go)
+    (define-key map "\C-c\C-c"   #'ess-eval-region-or-function-or-paragraph-and-step)
+    (define-key map "\C-c\C-p"   #'ess-eval-paragraph-and-step)
+    (define-key map "\C-c\M-p"   #'ess-eval-paragraph-and-go)
+    (define-key map "\C-\M-x"    #'ess-eval-region-or-function-or-paragraph)
+    (define-key map "\C-c\C-n"   #'ess-eval-line-visibly-and-step)
+    (define-key map "\C-c\C-j"   #'ess-eval-line)
+    (define-key map [(control return)] #'ess-eval-region-or-line-visibly-and-step)
+    (define-key map "\C-c\M-j"   #'ess-eval-line-and-go)
+    ;; FIXME: The next three can only work in S/R - mode
+    (define-key map "\C-\M-a"    #'ess-goto-beginning-of-function-or-para)
+    (define-key map "\C-\M-e"    #'ess-goto-end-of-function-or-para)
+    (define-key map "\C-xnd"     #'ess-narrow-to-defun-or-para)
+    (define-key map "\C-xnf"     #'ess-narrow-to-defun-or-para)
+    (define-key map "\C-c\C-z"   #'ess-switch-to-inferior-or-script-buffer)
+    (define-key map "\C-c\C-l"   #'ess-load-file)
+    ;;; Make an alias because C-c C-l is taken up by comint in inferiors
+    (define-key map "\C-c\M-l"   #'ess-load-file)
+    (define-key map "\C-c\C-v"   #'ess-display-help-on-object)
+    (define-key map "\C-c\C-s"   #'ess-switch-process)
+    (define-key map "\C-c\C-k"   #'ess-force-buffer-current)
+    (define-key map "\C-c`"      #'ess-show-traceback)
+    (define-key map [(control ?c) ?~] #'ess-show-call-stack)
+    (define-key map "\C-\M-q"    #'ess-indent-exp)
+    (define-key map "{"          #'skeleton-pair-insert-maybe)
+    (define-key map "}"          #'skeleton-pair-insert-maybe)
+    (define-key map "\C-\M-h"    #'ess-mark-function-or-para)
+    (define-key map "\t"         #'ess-indent-or-complete)
+    (define-key map "\C-c\C-q"   #'ess-quit)
+    (define-key map "\M-\r"      #'ess-use-this-dir)
+    (define-key map ","          #'ess-smart-comma)
+    (define-key map "\C-c\C-d"   'ess-doc-map)
+    (define-key map "\C-c\C-e"   'ess-extra-map)
+    (define-key map "\C-c\C-t"   'ess-dev-map)
+    map)
+  "Keymap for `ess-mode'.")
+
+;; Redefine `indent-new-comment-line' commands for Emacs < 26. Emacs
+;; 27 binds M-j to `default-indent-new-line' which calls
+;; `comment-line-break-function' if point is in a comment. We set this
+;; function in the mode init.
+(substitute-key-definition #'indent-new-comment-line
+                           #'ess-indent-new-comment-line
+                           ess-mode-map global-map)
+
+(defvar ess-extra-map
+  (let (ess-extra-map)
+    (define-prefix-command 'ess-extra-map)
+    (define-key ess-extra-map "\C-d" #'ess-dump-object-into-edit-buffer)
+    (define-key ess-extra-map "d"    #'ess-dump-object-into-edit-buffer)
+    (define-key ess-extra-map "\C-e" #'ess-execute)
+    (define-key ess-extra-map "e"    #'ess-execute)
+    (define-key ess-extra-map "\C-i" #'ess-install-library)
+    (define-key ess-extra-map "i"    #'ess-install-library)
+    (define-key ess-extra-map "\C-l" #'ess-load-library)
+    (define-key ess-extra-map "l"    #'ess-load-library)
+    (define-key ess-extra-map "\C-r" #'inferior-ess-reload)
+    (define-key ess-extra-map "r"    #'inferior-ess-reload)
+    (define-key ess-extra-map "\C-s" #'ess-set-style)
+    (define-key ess-extra-map "s"    #'ess-set-style)
+    (define-key ess-extra-map "\C-t" #'ess-build-tags-for-directory)
+    (define-key ess-extra-map "t"    #'ess-build-tags-for-directory)
+    (define-key ess-extra-map "\C-w" #'ess-execute-screen-options)
+    (define-key ess-extra-map "w"    #'ess-execute-screen-options)
+    (define-key ess-extra-map "/"    #'ess-set-working-directory)
+    ess-extra-map)
+  "ESS extra map.")
+
+(easy-menu-define
+  ess-mode-menu ess-mode-map
+  "Menu for use in `ess-mode'."
+  '("ESS" ; ESS-mode
+    ["Load file"                ess-load-file t]
+    ["Eval region | func | para" ess-eval-region-or-function-or-paragraph t]
+    ["Eval region | func | para & step" ess-eval-region-or-function-or-paragraph-and-step t]
+    ["Eval region | line" ess-eval-region-or-line-visibly-and-step t]
+    ["Enter expression" ess-execute                 t]
+    ;; sub menus
+    "------"
+    ("Process"
+     ["Goto end of process buffer"  ess-switch-to-end-of-ESS        t]
+     ["Switch to process buffer"    ess-switch-to-inferior-or-script-buffer t]
+     ["Switch process"   ess-switch-process              t]
+     ;; ["Recreate R and S versions known to ESS" (ess-r-s-versions-creation+menu) t]
+     ("Start Process"
+      ["R"     R   :help "Start a new R process" :active t]
+      ["S"     S   :help "Start a new S process" :active t]
+      ["Sqpe" Sqpe ess-microsoft-p] ;; :help "Start a new Sqpe process" :active t
+      ["S+6-existing" S+6-existing ess-microsoft-p] ;; :help "Access an existing S process" :active t
+      ["SAS"   SAS-menu t] ;;  :help "Start a new SAS process" :active t
+      ;; The following menu item "Other" is a place-holder that will
+      ;; be replaced with the other versions of R and Sqpe that can be run.
+      ;; See `ess-r-define-runners' and ess-site.el
+      ("Other"
+       ["No other R or Sqpe versions" nil nil])
+      ["About"
+       (ess-goto-info "Starting up") t]
+      ;; :help "Read about starting a new ESS process" :active t]
+      )
+     ("Eval visibly "
+      :filter ess--generate-eval-visibly-submenu)
+     ["Quit process" ess-quit t]
+     ["Reload process" inferior-ess-reload t])
+    "------"
+    ("ESS Eval"
+     ["Eval region | func | para" ess-eval-region-or-function-or-paragraph t]
+     ["Eval region | func | para & step" ess-eval-region-or-function-or-paragraph-and-step t]
+     ["Eval region | line & step" ess-eval-region-or-line-visibly-and-step t]
+     "-----"
+     ["Eval buffer"     ess-eval-buffer                    t]
+     ["Eval buffer till here" ess-eval-buffer-from-beg-to-here t]
+     ["Eval buffer from here" ess-eval-buffer-from-here-to-end t]
+     ["Eval region"     ess-eval-region                    t]
+     ["Eval function"   ess-eval-function                  t]
+     ["Eval line"       ess-eval-line                      t]
+     ["Eval line & step" ess-eval-line-and-step            t]
+     ["Eval paragraph"   ess-eval-paragraph                t]
+     ["Eval paragraph & step" ess-eval-paragraph-and-step  t]
+     ["About"           (ess-goto-info "Evaluating code")  t]
+     )
+    ("Eval and Go"
+     ["Eval buffer"     ess-eval-buffer-and-go            t]
+     ["Eval region"     ess-eval-region-and-go            t]
+     ["Eval function"   ess-eval-function-and-go          t]
+     ["Eval line"       ess-eval-line-and-go              t]
+     ["Eval paragraph"  ess-eval-paragraph-and-go         t]
+     ["About"           (ess-goto-info "Evaluating code") t]
+     )
+    ("Motion"
+     ["Beginning of function or para"   ess-goto-beginning-of-function-or-para       t]
+     ["End of function or para"         ess-goto-end-of-function-or-para             t]
+     "-----"
+     ["Backward list"           backward-list                   t]
+     ["Forward list"            forward-list                    t]
+     ["Next parenthesis"        down-list                       t]
+     ["Enclosing parenthesis"   backward-up-list                t]
+     ["Backward sexp"           backward-sexp                   t]
+     ["Forward sexp"            forward-sexp                    t]
+     ["About"                   (Info-goto-node "(Emacs)Lists") t]
+     )
+    ("ESS Edit"
+     ["Edit new object"   ess-dump-object-into-edit-buffer      t]
+     ["Complete Filename" comint-replace-by-expanded-filename   t]
+     ["Complete File or Object"   ess-indent-or-complete        t]
+     ["Kill sexp"         kill-sexp                             t]
+     ["Mark function"     ess-mark-function-or-para             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]
+     )
+    "------"
+    ("start-dev" :visible nil)
+    ("end-dev" :visible nil)
+    "------"
+    ("Font Lock"
+     :active ess-font-lock-keywords
+     :filter ess--generate-font-lock-submenu)
+    "------"
+    ["Describe"         describe-mode                   t]
+    ["About editing" (ess-goto-info "Editing")  t]
+    ["Read ESS info" (ess-goto-info "") t]
+    ["Send bug report"  ess-submit-bug-report           t]))
+
+;;;###autoload
+(define-derived-mode ess-mode prog-mode "ESS"
+  "Major mode for editing ESS source.
+Optional arg ALIST describes how to customize the editing mode.
+Optional arg PROC-NAME is name of associated inferior process.
+
+\\{ess-mode-map}
+
+You can send text to the inferior ESS process from other buffers containing
+ESS source.
+    `ess-eval-region' sends the current region to the ESS process.
+    `ess-eval-buffer' sends the current buffer to the ESS process.
+    `ess-eval-function' sends the current function to the ESS process.
+    `ess-eval-line' sends the current line to the ESS process.
+    `ess-switch-to-ESS' switches the current buffer to the ESS process buffer.
+    `ess-switch-to-end-of-ESS' switches the current buffer to the ESS process
+        buffer and puts point at the end of it.
+
+    `ess-eval-region-and-go', `ess-eval-buffer-and-go',
+        `ess-eval-function-and-go', and `ess-eval-line-and-go' switch to the S
+        process buffer after sending their text.
+
+    `ess-load-file' sources a file of commands to the ESS process.
+
+\\[ess-indent-command] indents for ESS code.
+\\[backward-delete-char-untabify] converts tabs to spaces as it moves back.
+Comments are indented in a similar way to Emacs-lisp mode:
+       `###'     beginning of line
+       `##'      the same level of indentation as the code
+       `#'       the same column on the right, or to the right of such a
+                 column if that is not possible.(default value 40).
+                 \\[indent-for-comment] command automatically inserts such a
+                 `#' in the right place, or aligns such a comment if it is
+                 already inserted.
+\\[ess-indent-exp] command indents each line of the syntactic unit following point.
+
+Variables controlling indentation style:
+ `ess-indent-offset'
+    Indentation of ESS statements within surrounding block.
+    The surrounding block's indentation is the indentation of the line on
+    which the open-brace appears.
+ `ess-offset-block'
+    Indentation of blocks opened with curly braces or anonymous parentheses.
+ `ess-offset-arguments'
+    Indentation of function arguments or bracket indices.
+ `ess-offset-arguments-newline'
+    Indentation of function arguments or bracket indices when the opening
+    delimiter is immediately followed by a newline.
+ `ess-offset-continued'
+    Indentation style for continued statements.
+ `ess-align-nested-calls'
+    Functions whose nested calls should be aligned.
+ `ess-align-arguments-in-calls'
+    Calls in which arguments should be aligned.
+ `ess-align-continuations-in-calls'
+    Whether ignore indentation after an operator in calls
+ `ess-align-blocks'
+    Blocks that should always be aligned vertically.
+ `ess-indent-from-lhs'
+    Whether function calls given as argument should be indented from the
+    parameter name.
+ `ess-indent-from-chain-start'
+    Whether to indent arguments from the first of several consecutive calls.
+ `ess-indent-with-fancy-comments'
+    Non-nil means distinguish between #, ##, and ### for indentation.
+
+Furthermore, \\[ess-set-style] command enables you to set up predefined ess-mode
+indentation style. See `ess-style-alist' for predefined styles."
+  :group 'ess
+  ;; TODO: get rid of these and rely on modes to set variables properly
+  (when-let ((alist (buffer-local-value 'ess-local-customize-alist (current-buffer))))
+    (ess-setq-vars-local alist))
+  (when-let ((alist ess-mode-editing-alist))
+    (ess-setq-vars-local alist))
+  ;; Keep <tabs> out of the code.
+  (setq-local indent-tabs-mode nil)
+  (setq-local comment-line-break-function #'ess-newline-and-indent)
+  (setq mode-line-process
+        '(" ["
+          (:eval (ess--get-mode-line-indicator))
+          ess--local-mode-line-process-indicator
+          "]"))
+  (add-hook 'ess-idle-timer-functions #'ess-synchronize-dirs nil 'local))
+
+(defun ess--get-mode-line-indicator ()
+  "Get `ess--mode-line-process-indicator' from process buffer.
+Internal function to be used for dynamic mode-line display in
+`ess-mode'."
+  (if ess-local-process-name
+      (let* ((proc (get-process ess-local-process-name))
+             (buff (when proc (process-buffer proc))))
+        (if (and proc (buffer-live-p buff))
+            (with-current-buffer buff
+              (mapcar (lambda (e) (eval e t)) ess--mode-line-process-indicator))
+          "none"))
+    "none"))
+
+\f
+;;; User commands in ess-mode
+
+(defun ess-install-library (&optional update package)
+  "Install PACKAGE for current dialect.
+With UPDATE, update cached package list."
+  (interactive "P")
+  (ess-install-library--override update package))
+
+(cl-defgeneric ess-install-library--override (update package)
+  "See `ess-install-library' for UPDATE, PACKAGE."
+  (when update (message "Don't know how to update for %s" ess-dialect))
+  (error "Cannot install %s, not available for %s" package ess-dialect))
+
+
+;; Motion / manipulation commands
+
+(defun ess-goto-beginning-of-function-or-para ()
+  "If inside a function go to the beginning of it.
+Otherwise go to the beginning of paragraph."
+  (interactive)
+  (let ((start-pos (point))
+        beg end)
+    (beginning-of-defun)
+    (setq beg (point))
+    (end-of-defun)
+    (setq end (point))
+    (goto-char beg)
+    (unless (and (< beg start-pos)
+                 (> end start-pos))
+      (let ((par-pos (save-excursion
+                       (goto-char start-pos)
+                       (forward-comment most-negative-fixnum)
+                       (backward-paragraph)
+                       (forward-comment most-positive-fixnum)
+                       (point))))
+        (if (< end par-pos)
+            (goto-char par-pos)
+          (goto-char beg))))))
+
+(defun ess-goto-end-of-function-or-para ()
+  "If inside a function go to end of it.
+Otherwise go to the end of paragraph."
+  (interactive)
+  (let ((pos (point))
+        beg end)
+    (end-of-defun)
+    (setq end (point))
+    (beginning-of-defun)
+    (setq beg (point))
+    (goto-char end)
+    (when (or (< beg pos)
+              (> end pos))
+      (let ((par-pos (save-excursion
+                       (goto-char pos)
+                       (forward-comment most-positive-fixnum)
+                       (forward-paragraph)
+                       (point))))
+        (when (<= par-pos beg)
+          (goto-char par-pos))))))
+
+(defun ess-mark-function-or-para ()
+  "Put mark at end of ESS function, point at beginning."
+  (interactive)
+  (ess-goto-beginning-of-function-or-para)
+  (push-mark (point))
+  (ess-goto-end-of-function-or-para)
+  (exchange-point-and-mark))
+
+(define-obsolete-function-alias 'ess-mark-function
+  #'ess-mark-function-or-para "15.09")
+
+(defun ess-narrow-to-defun-or-para ()
+  "Make text outside current function invisible.
+If text is already narrowed, this is removed before narrowing to the
+current function."
+  (interactive)
+  (save-excursion
+    (widen)
+    (let* ((beg (progn (ess-goto-beginning-of-function-or-para)
+                       (point)))
+           (end (progn (ess-goto-end-of-function-or-para)
+                       (point))))
+      (narrow-to-region beg end))))
+
+(define-obsolete-function-alias 'ess-narrow-to-defun
+  #'ess-narrow-to-defun-or-para "15.09")
+
+;; FIXME: Support soft breaks with `insert-and-inherit'. See
+;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Hard-and-Soft-Newlines.html
+(defun ess-newline-and-indent (&optional _soft)
+  (ess-indent-new-comment-line))
+
+(defun ess-indent-new-comment-line ()
+  "Like `indent-new-comment-line' but accounts for roxygen comments."
+  (interactive)
+  (cond ((and (fboundp 'ess-roxy-indent-new-comment-line)
+              (string= ess-dialect "R"))
+         (ess-roxy-indent-new-comment-line))
+        (t
+         (indent-new-comment-line))))
+
+\f
+;;; Formatting / indentation
+(defvar-local ess--installed-style-vars nil
+  "A cons of the form (STYLE . VARS).
+VARS is a list of all style vars which were not set explicitly to
+buffer local values by the user in mode hooks.")
+
+(defun ess-set-style (&optional style _quiet)
+  "Set up the `ess-mode' style variables from the `ess-style' variable.
+If STYLE argument is given, use that instead. It makes the ESS
+indentation style variables buffer local. QUIET is for backward
+compatibility and is ignored.
+
+In programs, when STYLE is nil, the `ess-style' is installed. In
+this case, if `ess-style' is buffer local, all settings are
+overwritten, otherwise only those settings which are not already
+buffer local. For example, `ess-style' is buffer local when it is
+set in .dir-locals and thus must have priority over the user
+settings in the mode hook."
+  (interactive
+   (list (let ((styles (mapcar (lambda (x) (symbol-name (car x)))
+                               ess-style-alist)))
+           (intern (ess-completing-read
+                    "Set ESS mode indentation style"
+                    styles nil t nil nil ess-style)))))
+  (let* ((keep-local (and (null style)
+                          (not (local-variable-p 'ess-style))))
+         (style (or style ess-style))
+         (style-alist (or (cdr (assq style ess-style-alist))
+                          (error "Bad ESS style: %s" style)))
+         (vars (if keep-local
+                   ;; Install, but Keep user's buffer-local settings.
+                   (cl-loop for (var . _) in (cdr (assq 'DEFAULT ess-style-alist))
+                            unless (local-variable-p var)
+                            collect var)
+                 (mapcar #'car style-alist))))
+    (when (called-interactively-p 'any)
+      (message "Set indentation style to %s" style))
+    (mapc (lambda (var)
+            (make-local-variable var)
+            (set var (cdr (assq var style-alist))))
+          vars)
+    style))
+
+(defun ess-indent-command (&optional whole-exp)
+  "Indent current line as ESS code, or in some cases insert a tab character.
+If `tab-always-indent' is non-nil, always indent current line.
+Otherwise, indent the current line only if point is at the left
+margin or in the line's indentation; otherwise insert a tab. If
+given, WHOLE-EXP means indent rigidly all the lines of the
+expression starting after point so that this line becomes
+properly indented. The relative indentation among the lines of
+the expression are preserved.
+
+If in a roxygen block at the beginning of the line with
+`ess-roxy-hide-show-p' non-nil, call `ess-roxy-toggle-hiding'
+instead of indenting."
+  (interactive "P")
+  (cond ((and (fboundp 'ess-roxy-entry-p)
+              (fboundp 'ess-roxy-toggle-hiding)
+              (bolp)
+              (ess-roxy-entry-p)
+              ess-roxy-hide-show-p)
+         (ess-roxy-toggle-hiding))
+        (whole-exp
+         ;; If arg, always indent this line as S
+         ;; and shift remaining lines of expression the same amount.
+         (let ((shift-amt (funcall indent-line-function))
+               beg end)
+           (save-excursion
+             (if tab-always-indent
+                 (beginning-of-line))
+             (setq beg (point))
+             (backward-up-list 1)
+             (forward-list 1)
+             (setq end (point))
+             (goto-char beg)
+             (forward-line 1)
+             (setq beg (point)))
+           (if (> end beg)
+               (indent-code-rigidly beg end shift-amt))))
+        ((and (not tab-always-indent)
+              (save-excursion
+                (skip-chars-backward " \t")
+                (not (bolp))))
+         (insert-tab))
+        (t (funcall indent-line-function))))
+
+(defun ess-indent-or-complete ()
+  "When region is selected indent the region.
+Otherwise, if `tab-always-indent' is \\='complete, try to indent, if
+code is already indented, complete instead. Also see
+`ess-first-tab-never-complete'."
+  (interactive)
+  (if (use-region-p)
+      (indent-region (region-beginning) (region-end))
+    (let ((shift (let ((indent (current-indentation)))
+                   (ess-indent-command)
+                   (- (current-indentation) indent))))
+      (when (and (or (equal tab-always-indent 'complete)
+                     ess-tab-complete-in-script)
+                 (numberp shift) ;; can be nil if tab-always-indent is nil
+                 (equal shift 0)
+                 (or (eq last-command 'ess-indent-or-complete)
+                     (null ess-first-tab-never-complete)
+                     (and (eq ess-first-tab-never-complete 'unless-eol)
+                          (looking-at "\\s-*$"))
+                     (and (eq ess-first-tab-never-complete 'symbol)
+                          (not (looking-at "\\w\\|\\s_")))
+                     (and (eq ess-first-tab-never-complete 'symbol-or-paren)
+                          (not (looking-at "\\w\\|\\s_\\|\\s)")))
+                     (and (eq ess-first-tab-never-complete 'symbol-or-paren-or-punct)
+                          (not (looking-at "\\w\\|\\s_\\|\\s)\\|\\s.")))))
+        (completion-at-point)))))
+
+(defun ess-indent-exp ()
+  "Indent each line of the ESS grouping following point."
+  (interactive)
+  (cond ((and (fboundp 'ess-r-indent-exp)
+              (string= ess-dialect "R"))
+         (ess-r-indent-exp))
+        (t
+         (save-excursion
+           (let ((start (point))
+                 (end (ignore-errors (forward-sexp 1) (point))))
+             (when end
+               (indent-region start end)))))))
+
+(defun ess-indent-line ()
+  "Indent current line as ESS code.
+Return the amount the indentation changed by."
+  (declare (obsolete 'indent-line-function "ESS 19.04"))
+  (funcall indent-line-function))
+
+\f
+;;; Dump Objects
+
+(defun ess-dump-object-into-edit-buffer (object)
+  "Edit an ESS OBJECT in its own buffer.
+Without a prefix argument, this simply finds the file pointed to by
+`ess-source-directory'.  If this file does not exist, or if a
+prefix argument is given, a dump() command is sent to the ESS process to
+generate the source buffer."
+  (interactive
+   (progn
+     (ess-force-buffer-current "Process to dump from: ")
+     (ess-read-object-name "Object to edit")))
+  (let* ((dirname (file-name-as-directory
+                   (if (stringp ess-source-directory)
+                       ess-source-directory
+                     (with-current-buffer (process-buffer (ess-get-process
+                                                           ess-local-process-name))
+                       (ess-setq-vars-local ess-local-customize-alist)
+                       (apply ess-source-directory nil)))))
+         (filename (concat dirname (convert-standard-filename (format ess-dump-filename-template object))))
+         (old-buff (get-file-buffer filename)))
+    ;; If the directory doesn't exist, offer to create it
+    (unless (file-exists-p (directory-file-name dirname))
+      (if (y-or-n-p (format "Directory %s does not exist. Create it? " dirname))
+          (make-directory (directory-file-name dirname))
+        (error "Directory %s does not exist" dirname)))
+    ;; Three options:
+    ;;  (1) Pop to an existing buffer containing the file in question
+    ;;  (2) Find an existing file
+    ;;  (3) Create a new file by issuing a dump() command to S
+    ;; Force option (3) if there is a prefix arg
+    (cond (current-prefix-arg
+           (ess-dump-object object filename))
+          (old-buff
+           (pop-to-buffer old-buff))
+          ((file-exists-p filename)
+           (ess-find-dump-file-other-window filename)
+           (message "Read %s" filename))
+          (t (ess-dump-object object filename)))))
+
+(defun ess-dump-object (object filename)
+  "Dump the ESS object OBJECT into file FILENAME."
+  (unless (file-writable-p filename)
+    (error "Can't dump %s as %f is not writeable" object filename))
+  (let ((dump-cmd (format inferior-ess-dump-command object filename)))
+    ;; Make sure we start fresh
+    (when (get-file-buffer filename)
+      (kill-buffer (get-file-buffer filename)))
+    (ess-command dump-cmd)
+    (message "Dumped in %s" filename)
+    (ess-find-dump-file-other-window filename)
+    ;; PD, 1Apr97
+    ;;This ensures that the object gets indented according to ess-mode,
+    ;;not as the R/S deparser does it. At the same time, it gets rid
+    ;;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.
+    (unless ess-keep-dump-files
+      (make-local-variable 'make-backup-files)
+      (setq make-backup-files nil))
+    ;; Don't get confirmation to delete dumped files when loading
+    (when (eq ess-keep-dump-files 'check)
+      (setq ess-keep-dump-files nil))
+    ;; Delete the file if necessary
+    (when ess-delete-dump-files
+      (delete-file (buffer-file-name)))))
+
+(defun ess-find-dump-file-other-window (filename)
+  "Find ESS source file FILENAME in another window."
+  (unless (file-readable-p filename)
+    (ess-write-to-dribble-buffer
+     (format "%s does not exist. Bad dump, starting fresh." filename)))
+  ;; Generate a buffer with the dumped data
+  (find-file-other-window filename)
+  (auto-save-mode 1)            ; Auto save in this buffer
+  (when (and ess-function-template
+             (goto-char (point-max))
+             (re-search-backward ess-dumped-missing-re nil t))
+    (replace-match ess-function-template t t)
+    (set-buffer-modified-p nil) ; Don't offer to save if killed now
+    (goto-char (point-min))
+    (ignore-errors
+      ;; This may fail if there are no opens
+      (down-list 1))))
+
+\f
+;;; Runners
+
+(defun ess-define-runner (name dialect &optional path)
+  "Create a function NAME.
+This function starts the inferior process with the specified
+version. DIALECT can be \"R,\" \"S,\", \"SAS.\" If given, PATH
+should be the absolute path to the program. It defaults to NAME."
+  (let ((name name)
+        (dialect dialect)
+        (path path))
+    (fset (intern name)
+          (lambda (&optional start-args)
+            "Start this process version in an inferior ESS buffer.
+Function defined using `ess-define-runner'."
+            (interactive "P")
+            (cond ((string= dialect "R")
+                   (let ((inferior-ess-r-program (or path name)))
+                     (require 'ess-r-mode)
+                     (R start-args)))
+                  ((string= dialect "S")
+                   (let ((inferior-S+-program (or path name)))
+                     (require 'ess-sp6-d)
+                     (S+)))
+                  ((string= dialect "SAS")
+                   (let ((inferior-SAS-program (or path name)))
+                     (require 'ess-sas-d)
+                     (SAS))))))))
+
+
+
+(provide 'ess-mode)
+
+;;; ess-mode.el ends here
diff --git a/elpa/ess-20260424.1544/ess-pkg.el b/elpa/ess-20260424.1544/ess-pkg.el
new file mode 100644 (file)
index 0000000..c09b7e8
--- /dev/null
@@ -0,0 +1,20 @@
+;; -*- no-byte-compile: t; lexical-binding: nil -*-
+(define-package "ess" "20260424.1544"
+  "Emacs Speaks Statistics."
+  '((emacs "25.1"))
+  :url "https://ess.r-project.org/"
+  :commit "bb84ad5717ead180488cf4f266c38eace890e314"
+  :revdesc "bb84ad5717ea"
+  :authors '(("David Smith" . "dsmithNOSPAMstats.adelaide.edu.au")
+             ("A.J. Rossini" . "blindglobeNOSPAMgmail.com")
+             ("Richard M. Heiberger" . "rmhNOSPAMtemple.edu")
+             ("Kurt Hornik" . "Kurt.HornikNOSPAMR-project.org")
+             ("Martin Maechler" . "maechlerNOSPAMstat.math.ethz.ch")
+             ("Rodney A. Sparapani" . "rsparapaNOSPAMmcw.edu")
+             ("Stephen Eglen" . "stephenNOSPAMgnu.org")
+             ("Sebastian P. Luque" . "spluqueNOSPAMgmail.com")
+             ("Henning Redestig" . "henning.redNOSPAMgooglemail.com")
+             ("Vitalie Spinu" . "spinuvitNOSPAMgmail.com")
+             ("Lionel Henry" . "lionel.hryNOSPAMgmail.com")
+             ("J. Alexander Branham" . "alex.branhamNOSPAMgmail.com"))
+  :maintainers '(("ESS Core Team" . "ESS-coreNOSPAMr-project.org")))
diff --git a/elpa/ess-20260424.1544/ess-r-completion.el b/elpa/ess-20260424.1544/ess-r-completion.el
new file mode 100644 (file)
index 0000000..3c388cb
--- /dev/null
@@ -0,0 +1,518 @@
+;;; ess-r-completion.el --- R completion  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015-2022 Free Software Foundation, Inc.
+;; Author: Vitalie Spinu
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+;; Provide completion support in R buffers.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'ess-inf)
+(require 'ess-help)
+
+(eval-when-compile
+  (require 'subr-x))
+
+(defvar ac-auto-start)
+(defvar ac-prefix)
+(defvar ac-point)
+(defvar ac-use-comphist)
+(declare-function company-begin-backend "company")
+(declare-function company-doc-buffer "company")
+
+(defcustom ess-R-argument-suffix " = "
+  "Suffix appended by `ac-source-R' and `ac-source-R-args' to candidates."
+  :group 'ess-R
+  :type 'string)
+
+\f
+;;;*;;; ElDoc
+
+(defun ess-r-eldoc-function (&rest _ignored)
+  "Return the doc string, or nil.
+If an ESS process is not associated with the buffer, do not try
+to look up any doc strings."
+  (when eldoc-mode
+    (when-let ((proc (ess-get-next-available-bg-process))
+               (funname (or (and ess-eldoc-show-on-symbol ;; Aggressive completion
+                                 (thing-at-point 'symbol))
+                            (car (ess--fn-name-start)))))
+      (let* ((args (ess-function-arguments funname proc))
+             (bargs (cadr args))
+             (doc (mapconcat (lambda (el)
+                               (if (equal (car el) "...")
+                                   "..."
+                                 (concat (car el) "=" (cdr el))))
+                             bargs ", "))
+             (margs (nth 2 args))
+             (W (- (window-width (minibuffer-window)) (+ 4 (length funname))))
+             (multiline (eq t eldoc-echo-area-use-multiline-p))
+             doc1)
+        (when doc
+          (setq doc (ess-eldoc-docstring-format funname doc (not multiline)))
+          (when (or multiline (and margs (< (length doc1) W)))
+            (setq doc1 (concat doc (propertize "  || " 'face font-lock-function-name-face)))
+            (while (and margs (< (length doc1) W))
+              (let ((head (pop margs)))
+                (unless (assoc head bargs)
+                  (setq doc doc1
+                        doc1 (concat doc1 head  "=, ")))))
+            (when (equal (substring doc -2) ", ")
+              (setq doc (substring doc 0 -2)))
+            (when (and margs (< (length doc) W))
+              (setq doc (concat doc " {--}"))))
+          doc)))))
+
+(defun ess-eldoc-docstring-format (funname doc &optional truncate)
+  (save-match-data
+    (let* (;; Subtract 1 from window width since will cause a wraparound and
+           ;; resize of the echo area.
+           (W (1- (- (window-width (minibuffer-window))
+                     (+ 2 (length funname))))))
+      (setq doc
+            (if (or (<= (length doc) W)
+                    (null ess-eldoc-abbreviation-style)
+                    (eq 'none ess-eldoc-abbreviation-style))
+                doc
+              ;;MILD filter
+              (setq doc (replace-regexp-in-string "TRUE" "T" doc))
+              (setq doc (replace-regexp-in-string "FALSE" "F" doc))
+              (if (or (<= (length doc) W)
+                      (eq 'mild ess-eldoc-abbreviation-style))
+                  doc
+                ;;NORMAL filter (deal with long defaults)
+                (setq doc (replace-regexp-in-string
+                           ;; function calls inside default docs foo(xxxx{..})
+                           "([^)]\\{8\\}\\([^)]\\{4,\\}\\))"
+                           "{.}" doc nil nil 1))
+                (if (<= (length doc) W)
+                    doc
+                  (setq doc (replace-regexp-in-string
+                             " +[^ \t=,\"\]+=[^ \t]\\{10\\}\\([^ \t]\\{4,\\}\\)\\(,\\|\\'\\)"
+                             "{.}," doc nil nil 1))
+                  (if (<= (length doc) W)
+                      doc
+                    (setq doc (replace-regexp-in-string
+                               " +[^ \t=,\"]+=\\([^ \t]\\{10,\\}\\)\\(,\\|\\'\\)"
+                               "{.}," doc nil nil 1))
+                    (if (or (<= (length doc) W)
+                            (eq 'normal ess-eldoc-abbreviation-style))
+                        doc
+                      ;;STRONG filter (replace defaults)
+                      (setq doc (replace-regexp-in-string
+                                 " *[^ \t=,\"\\]* = \\([^ \t]\\{4,\\}\\)\\(,\\|\\'\\)"
+                                 "{.}," doc nil nil 1))
+                      (if (<= (length doc) W)
+                          doc
+                        (setq doc (replace-regexp-in-string
+                                   "\\(=[^FT0-9].+?\\)\\(, [^ =,\"\\]+=\\|\\'\\)"
+                                   "" doc nil nil 1))
+                        (setq doc (replace-regexp-in-string
+                                   "\\(=[^FT0-9].+?\\)\\(, [^ =,\"\\]+,\\|\\'\\)"
+                                   "" doc nil nil 1))
+                        (if (or (<= (length doc) W)
+                                (eq 'strong ess-eldoc-abbreviation-style))
+                            doc
+                          ;;AGGRESSIVE filter (truncate what is left)
+                          (concat (substring doc 0 (- W 4)) "{--}")))))))))
+      (when (and truncate (> (length doc) W))
+        (setq doc (concat (substring doc 0 (- W 4)) "{--}")))
+      (format "%s: %s" (propertize funname 'face 'font-lock-function-name-face) doc))))
+
+\f
+;;;*;;; OBJECTS
+
+(defun ess-r-object-completion ()
+  "Return completions at point as required in `completion-at-point-functions'."
+  (if (ess-make-buffer-current)
+      (let* ((funstart (cdr (ess--fn-name-start)))
+             (completions (ess-r-get-rcompletions funstart))
+             (token (pop completions)))
+        (when completions
+          (list (- (point) (length token)) (point)
+                completions)))
+    (when (string-match "complete" (symbol-name last-command))
+      (message "No ESS process associated with current buffer")
+      nil)))
+
+(defun ess-complete-object-name ()
+  "Perform completion on object preceding point.
+Uses `ess-r-complete-object-name' when `ess-use-R-completion' is non-nil,
+and `ess-internal-complete-object-name' otherwise."
+  (interactive)
+  (if (ess-make-buffer-current)
+      (if ess-use-R-completion
+          (ess-r-complete-object-name)
+        (ess-internal-complete-object-name))
+    ;; else give a message on second invocation
+    (when (string-match "complete" (symbol-name last-command))
+      (message "No ESS process associated with current buffer")
+      nil)))
+
+(define-obsolete-function-alias 'ess-list-object-completions #'ess-complete-object-name "ESS 19.04")
+
+;; This one is needed for R <= 2.6.x -- hence *not* obsoleting it
+(defun ess-internal-complete-object-name ()
+  "Perform completion on `ess-language' object preceding point.
+The object is compared against those objects known by
+`ess-get-object-list' and any additional characters up to ambiguity are
+inserted.  Completion only works on globally-known objects (including
+elements of attached data frames), and thus is most suitable for
+interactive `command-line' entry, and not so much for function editing
+since local objects (e.g. argument names) aren't known.
+
+Use \\[ess-resynch] to re-read the names of the attached directories.
+This is done automatically (and transparently) if a directory is
+modified (S only!), so the most up-to-date list of object names is always
+available.  However attached dataframes are *not* updated, so this
+command may be necessary if you modify an attached dataframe."
+  (ess-make-buffer-current)
+  (if (memq (char-syntax (preceding-char)) '(?w ?_))
+      (let* ((comint-completion-addsuffix nil)
+             (bounds (ess-bounds-of-symbol))
+             (beg (car bounds))
+             (end (cdr bounds))
+             (full-prefix (buffer-substring beg end))
+             (pattern full-prefix)
+             ;; See if we're indexing a list with `$'
+             (listname (if (string-match "\\(.+\\)\\$\\(\\(\\sw\\|\\s_\\)*\\)$"
+                                         full-prefix)
+                           (progn
+                             (setq pattern
+                                   (if (not (match-beginning 2)) ""
+                                     (substring full-prefix
+                                                (match-beginning 2)
+                                                (match-end 2))))
+                             (substring full-prefix (match-beginning 1)
+                                        (match-end 1)))))
+             ;; 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)
+                             ;; Default case: It hangs here when
+                             ;;    options(error=recover) :
+                             (ess-get-object-list ess-current-process-name)))))
+        ;; always return a non-nil value to prevent history expansions
+        (or (completion-in-region beg end components) 'none))))
+
+(defun ess-r-get-rcompletions (&optional start end prefix allow-3-dots)
+  "Call R internal completion utilities (rcomp) for possible completions.
+Optional START and END delimit the entity to complete, default to
+bol and point.  If PREFIX is given, perform completion on
+PREFIX.  First element of the returned list is the completion
+token.  Needs version of R >= 2.7.0."
+  (let* ((start (or start
+                    (if prefix
+                        0
+                      (save-excursion (comint-bol nil) (point)))))
+         (end (or end (if prefix (length prefix) (point))))
+         (prefix (or prefix (buffer-substring start end)))
+         ;; (opts1 (if no-args "op<-rc.options(args=FALSE)" ""))
+         ;; (opts2 (if no-args "rc.options(op)" ""))
+         (call1 (format ".ess_get_completions(\"%s\", %d, \"%s\")"
+                        (ess-quote-special-chars prefix)
+                        (- end start)
+                        ess-R-argument-suffix))
+         (cmd (if allow-3-dots
+                  (concat call1 "\n")
+                (concat "local({ r <- " call1 "; r[r != '...='] })\n"))))
+    (ess-get-words-from-vector cmd)))
+
+(defun ess-r-complete-object-name ()
+  "Completion in R via R's completion utilities (formerly `rcompgen').
+To be used instead of ESS' completion engine for R versions >= 2.7.0."
+  (let ((possible-completions (ess-r-get-rcompletions))
+        token-string)
+    (when possible-completions
+      (setq token-string (pop possible-completions))
+      (or (completion-in-region (- (point) (length token-string))
+                                (point)
+                                possible-completions)
+          'none))))
+
+(defvar ess--cached-sp-objects nil)
+
+(defun ess--get-cached-completions (prefix &optional _point)
+  (if (string-match-p "[]:$@[]" prefix)
+      ;; call proc for objects
+      (cdr (ess-r-get-rcompletions nil nil prefix))
+    ;; else, get cached list of objects
+    (with-ess-process-buffer 'no-error ;; use proc buf alist
+      (ess-when-new-input last-cached-completions
+        (if (and ess--cached-sp-objects
+                 (not  (process-get *proc* 'sp-for-ac-changed?)))
+            ;; if global cache is already there, only re-read local .GlobalEnv
+            (progn
+              (unless ess-sl-modtime-alist
+                ;; initialize if empty
+                (setq ess-sl-modtime-alist '((".GlobalEnv" nil))))
+              ;; fixme: Make adaptive. Not on all remotes are slow; For lots of
+              ;; objects in .GlobalEnv,locals could also be slow.
+              (unless (file-remote-p default-directory)
+                (ess-extract-onames-from-alist ess-sl-modtime-alist 1 'force)))
+          (if ess--cached-sp-objects
+              (ess-get-modtime-list 'ess--cached-sp-objects 'exclude-first)
+            (ess-get-modtime-list)
+            (setq ess--cached-sp-objects (cdr ess-sl-modtime-alist)))
+          ;; reread new package, but not rda, much faster and not needed anyways
+          (process-put *proc* 'sp-for-ac-changed? nil)))
+      (apply #'append
+             (cl-cddar ess-sl-modtime-alist) ; .GlobalEnv
+             (mapcar #'cddr ess--cached-sp-objects)))))
+
+\f
+;;;*;;; ARGUMENTS
+
+(defvar ess-r--funargs-pre-cache
+  '(("plot"
+     (("graphics")
+      (("x" . "")    ("y" . "NULL")    ("type" . "p")    ("xlim" . "NULL")    ("ylim" . "NULL")    ("log" . "")    ("main" . "NULL")    ("sub" . "NULL")    ("xlab" . "NULL")    ("ylab" . "NULL")
+       ("ann" . "par(\"ann\")")     ("axes" . "TRUE")    ("frame.plot" . "axes")    ("panel.first" . "NULL")    ("panel.last" . "NULL")    ("asp" . "NA")    ("..." . ""))
+      ("x" "y" "..." "ci" "type" "xlab" "ylab" "ylim" "main" "ci.col" "ci.type" "max.mfrow" "ask" "mar" "oma" "mgp" "xpd" "cex.main" "verbose" "scale" "xlim" "log" "sub" "ann" "axes" "frame.plot"
+       "panel.first" "panel.last" "asp" "center" "edge.root" "nodePar" "edgePar" "leaflab" "dLeaf" "xaxt" "yaxt" "horiz"
+       "zero.line" "verticals" "col.01line" "pch" "legend.text" "formula" "data" "subset" "to" "from" "newpage" "vp" "labels"
+       "hang" "freq" "density" "angle" "col" "border" "lty" "add" "predicted.values" "intervals" "separator" "col.predicted"
+       "col.intervals" "col.separator" "lty.predicted" "lty.intervals" "lty.separator" "plot.type" "main2" "par.fit" "grid"
+       "panel" "cex" "dimen" "abbrev" "which" "caption" "sub.caption" "id.n" "labels.id" "cex.id" "qqline" "cook.levels"
+       "add.smooth" "label.pos" "cex.caption" "rows" "levels" "conf" "absVal" "ci.lty" "xval" "do.points" "col.points" "cex.points"
+       "col.hor" "col.vert" "lwd" "set.pars" "range.bars" "col.range" "xy.labels" "xy.lines" "nc" "yax.flip" "mar.multi" "oma.multi")))
+    ("print"
+     (("base")
+      (("x" . "")    ("digits" . "NULL")    ("quote" . "TRUE")    ("na.print" . "NULL")    ("print.gap" . "NULL")    ("right" . "FALSE")    ("max" . "NULL")    ("useSource" . "TRUE")    ("..." . ""))
+      ("x" "..." "digits" "signif.stars" "intercept" "tol" "se" "sort" "verbose" "indent" "style" ".bibstyle" "prefix" "vsep" "minlevel" "quote" "right" "row.names" "max" "na.print" "print.gap"
+       "useSource" "diag" "upper" "justify" "title" "max.levels" "width" "steps" "showEnv" "newpage" "vp" "cutoff" "max.level" "give.attr" "units" "abbrCollate" "print.x" "deparse" "locale" "symbolic.cor"
+       "loadings" "zero.print" "calendar"))))
+  "Alist of cached arguments for time consuming functions.")
+
+\f
+;;;*;;; HELP
+
+(defun ess-r-get-object-help-string (sym)
+  "Help string for ac."
+  (let ((proc (ess-get-next-available-bg-process)))
+    (if (null proc)
+        "No free ESS process found"
+      (let ((buf (get-buffer-create " *ess-command-output*")))
+        (when (string-match ":+\\(.*\\)" sym)
+          (setq sym (match-string 1 sym)))
+        (with-current-buffer (process-buffer proc)
+          (ess-with-current-buffer buf
+            (ess--flush-help-into-current-buffer sym nil)))
+        (with-current-buffer buf
+          (ess-help-underline)
+          (goto-char (point-min))
+          (buffer-string))))))
+
+(defun ess-r-get-arg-help-string (sym &optional proc)
+  "Help string for ac."
+  (setq sym (replace-regexp-in-string " *= *\\'" "" sym))
+  (let ((proc (ess-get-next-available-bg-process proc)))
+    (if (null proc)
+        "No free ESS process found"
+      (let ((fun (car ess--fn-name-start-cache)))
+        (with-current-buffer (ess-command (format ".ess_arg_help('%s','%s')\n" sym fun)
+                                          nil nil nil nil proc)
+          (goto-char (point-min))
+          (forward-line)
+          (buffer-substring-no-properties (point) (point-max)))))))
+
+\f
+;;;*;;; COMPANY
+;; https://company-mode.github.io
+
+(defun company-R-objects (command &optional arg &rest _ignored)
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-R-objects))
+    (prefix (unless (ess-inside-string-or-comment-p)
+              (let ((start (ess-symbol-start)))
+                (when start
+                  (buffer-substring-no-properties start (point))))))
+    (candidates (when-let ((proc (ess-get-next-available-bg-process)))
+                  (with-current-buffer (process-buffer proc)
+                    (all-completions arg (ess--get-cached-completions arg)))))
+    (doc-buffer (company-doc-buffer (ess-r-get-object-help-string arg)))))
+
+(defun company-R-args (command &optional arg &rest _ignored)
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-R-args))
+    (prefix (unless (ess-inside-string-or-comment-p)
+              (let ((start (ess-arg-start)))
+                (when start
+                  (let ((prefix (buffer-substring-no-properties start (point))))
+                    (if ess-company-arg-prefix-length
+                        (cons prefix (>= (length prefix)
+                                         ess-company-arg-prefix-length))
+                      prefix))))))
+    (candidates (when-let ((proc (ess-get-next-available-bg-process)))
+                  (let* ((args (delete "..." (nth 2 (ess-function-arguments
+                                                     (car ess--fn-name-start-cache) proc))))
+                         (args (mapcar (lambda (a) (concat a ess-R-argument-suffix))
+                                       args)))
+                    (all-completions arg args))))
+    ;; Displaying help for the argument in the echo area is disabled
+    ;; by default for performance reasons. It causes delays or hangs (#1062).
+    (meta (when (bound-and-true-p ess-r--company-meta)
+            (when-let ((proc (ess-get-next-available-bg-process)))
+              (when (with-current-buffer (process-buffer proc)
+                      (not (file-remote-p default-directory)))
+                ;; fixme: ideally meta should be fetched with args
+                (let ((doc (ess-r-get-arg-help-string arg proc)))
+                  (replace-regexp-in-string "^ +\\| +$" ""
+                                            (replace-regexp-in-string "[ \t\n]+" " " doc)))))))
+    (sorted t)
+    (require-match 'never)
+    (doc-buffer (company-doc-buffer (ess-r-get-arg-help-string arg)))))
+
+(defun company-R-library (command &optional arg &rest _ignored)
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-R-library))
+    (prefix (and (member (car (ess--fn-name-start))
+                         '("library" "require"))
+                 (let ((start (ess-symbol-start)))
+                   (and start (buffer-substring start (point))))))
+    (candidates (when (ess-can-eval-in-background)
+                  (all-completions arg (ess-installed-packages))))
+    (annotation "<pkg>")
+    (duplicates nil)
+    (sorted t)))
+
+;; FIXME: There's a lot of overlap between `ess-r-package-completion'
+;; and `company-R-library'. Can we merge them somehow?
+(defun ess-r-package-completion ()
+  "Return installed packages if in a call to library or require.
+Return format suitable for `completion-at-point-functions'."
+  (when (and (ess-can-eval-in-background)
+             (member (car (ess--fn-name-start))
+                     '("library" "require")))
+    (list (ess-symbol-start)
+          (point)
+          (ess-installed-packages)
+          :annotation-function
+          (lambda (_) " <pkg>"))))
+
+\f
+;;;*;;; AC SOURCES
+;; http://cx4a.org/software/auto-complete/index.html
+;; auto-complete is de-facto unmaintained, users should switch to `company-mode'.
+
+(defvar ac-source-R
+  '((prefix     . ess-ac-start)
+    ;; (requires   . 0) ::)
+    (candidates . ess-ac-candidates)
+    ;; (action  . ess-ac-action-args) ;; interfere with ac-fallback mechanism on RET (which is extremely annoying in inferior buffers)
+    (document   . ess-ac-help))
+  "Combined ad-completion source for R function arguments and R objects.")
+(make-obsolete-variable 'ac-source-R "Use company-mode instead" "ESS 19.04")
+
+(defun ess-ac-start ()
+  (when (ess-process-live-p)
+    (or (ess-arg-start)
+        (ess-symbol-start))))
+(make-obsolete-variable 'ess-ac-start "Use company-mode instead" "ESS 19.04")
+
+(defun ess-ac-candidates ()
+  "OBJECTS + ARGS."
+  (let ((args (with-no-warnings
+                ;; suppress obsolete warnings
+                (ess-ac-args))))
+    ;; sort of intrusive but right
+    (if (and ac-auto-start
+             (< (length ac-prefix) ac-auto-start))
+        args
+      (if args
+          (append args (with-no-warnings
+                         ;; suppress obsolete warnings
+                         (ess-ac-objects t)))
+        (with-no-warnings
+          ;; suppress obsolete warnings
+          (ess-ac-objects))))))
+(make-obsolete-variable 'ess-ac-candidates "Use company-mode instead" "ESS 19.04")
+
+(defun ess-ac-help (sym)
+  (if (string-match-p "= *\\'" sym)
+      (ess-r-get-arg-help-string sym)
+    (ess-r-get-object-help-string sym)))
+(make-obsolete-variable 'ess-ac-help "Use company-mode instead" "ESS 19.04")
+
+;; OBJECTS
+(defvar  ac-source-R-objects
+  '((prefix     . ess-symbol-start)
+    ;; (requires   . 2)
+    (candidates . ess-ac-objects)
+    (document   . ess-r-get-object-help-string))
+  "Auto-completion source for R objects.")
+(make-obsolete-variable 'ac-source-R-objects "Use company-mode instead" "ESS 19.04")
+
+(defun ess-ac-objects (&optional no-kill)
+  "Get all cached objects."
+  (declare (obsolete "Use company-mode instead" "ESS 19.04"))
+  (let ((aprf ac-prefix))
+    (when (and aprf (ess-process-live-p))
+      (unless no-kill ;; workaround
+        (kill-local-variable 'ac-use-comphist))
+      (ess--get-cached-completions aprf ac-point))))
+
+;; ARGS
+(defvar  ac-source-R-args
+  '((prefix     . ess-arg-start)
+    ;; (requires   . 0)
+    (candidates . ess-ac-args)
+    ;; (action     . ess-ac-action-args)
+    (document   . ess-r-get-arg-help-string))
+  "Auto-completion source for R function arguments.")
+(make-obsolete-variable 'ac-source-R-args "Use company-mode instead" "ESS 19.04")
+
+(defun ess-ac-args ()
+  "Get the args of the function when inside parentheses."
+  (declare (obsolete "Use company-mode-instead" "ESS 19.04"))
+  (when  (and ess--fn-name-start-cache ;; set in a call to ess-arg-start
+              (ess-process-live-p))
+    (let ((args (nth 2 (ess-function-arguments (car ess--fn-name-start-cache)))))
+      (if args
+          (setq-local ac-use-comphist nil)
+        (kill-local-variable 'ac-use-comphist))
+      (delete "..." args)
+      (mapcar (lambda (a) (concat a ess-R-argument-suffix))
+              args))))
+
+(provide 'ess-r-completion)
+
+;;; ess-r-completion.el ends here
diff --git a/elpa/ess-20260424.1544/ess-r-flymake.el b/elpa/ess-20260424.1544/ess-r-flymake.el
new file mode 100644 (file)
index 0000000..f223a60
--- /dev/null
@@ -0,0 +1,249 @@
+;;; ess-r-flymake.el --- A ess-r Flymake backend  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2022 Free Software Foundation, Inc.
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; Flymake is the built-in Emacs package that supports on-the-fly
+;; syntax checking.  This file adds support for this in ess-r-mode by
+;; relying on the lintr package, available on CRAN and currently
+;; hosted at https://github.com/r-lib/lintr.
+
+;;; Code:
+
+(eval-when-compile (require 'cl-lib))
+(require 'ess-inf)
+(require 'flymake)
+
+;; Appease the byte compiler for Emacs 25. Remove after dropping
+;; support for Emacs 25.
+(declare-function flymake-diag-region "flymake")
+(declare-function flymake-make-diagnostic "flymake")
+(declare-function flymake--overlays "flymake")
+(declare-function ess-r-project "ess-r-mode")
+(declare-function ess-r-package-project "ess-r-package")
+
+(defcustom ess-r-flymake-linters
+  '("closed_curly_linter = NULL"
+    "commas_linter = NULL"
+    "commented_code_linter = NULL"
+    "infix_spaces_linter = NULL"
+    "line_length_linter = NULL"
+    "object_length_linter = NULL"
+    "object_name_linter = NULL"
+    "object_usage_linter = NULL"
+    "open_curly_linter = NULL"
+    "pipe_continuation_linter = NULL"
+    "single_quotes_linter = NULL"
+    "spaces_inside_linter = NULL"
+    "spaces_left_parentheses_linter = NULL"
+    "trailing_blank_lines_linter = NULL"
+    "trailing_whitespace_linter = NULL")
+  "Default linters to use.
+Can be either a string with R expression to be used as
+is (e.g. `lintr::default_linters').  Or a list of strings where
+each element is passed as argument to `lintr::linters_with_defaults'."
+  :group 'ess-R
+  :type '(choice string (repeat string))
+  :package-version '(ess . "18.10"))
+
+(defcustom ess-r-flymake-lintr-cache t
+  "If non-nil, cache lintr results."
+  :group 'ess-R
+  :type 'boolean
+  :package-version '(ess . "18.10"))
+
+(defvar-local ess-r--flymake-proc nil)
+
+(defvar-local ess-r--lintr-file nil
+  "Location of the .lintr config file for this buffer.")
+
+(defvar ess-r--flymake-def-linter
+  (replace-regexp-in-string
+   "[\n\t ]+" " "
+   "esslint <- function(str, ...) {
+    if (!suppressWarnings(requireNamespace('lintr', quietly=TRUE))) {
+        cat('@@error: @@`lintr` package not installed')
+    } else if (packageVersion('lintr') <= '3.0.0') {
+        cat('@@error: @@Need `lintr` version > v3.0.0')
+    } else {
+        tryCatch(lintr::lint(text=str, ..., parse_settings=TRUE),
+                 error = function(e) {
+                   cat('@@warning: @@', conditionMessage(e))
+                 })
+    }
+};"))
+
+(defun ess-r--find-lintr-file ()
+  "Return the absolute path to the .lintr config file.
+Check first the current directory, then the project root, then
+the package root, then the user's home directory. Return nil if
+we couldn't find a .lintr file."
+  ;; VS[2022-01-26]: Can't this entire thing be replaced by
+  ;; `(locate-dominating-file ".lintr")`?
+  (let* ((cur-file (expand-file-name ".lintr" default-directory))
+         (pkg (cdr (ess-r-package-project)))
+         (pkg-file (and pkg (expand-file-name ".lintr" pkg)))
+         (proj (ess-r-project))
+         (proj-file (and proj (expand-file-name ".lintr" proj)))
+         (home-file (expand-file-name ".lintr" (getenv "HOME"))))
+    (cond ((file-readable-p cur-file)
+           cur-file)
+          ((and proj-file (file-readable-p proj-file))
+           proj-file)
+          ((and pkg-file (file-readable-p pkg-file))
+           pkg-file)
+          ((file-readable-p home-file)
+           home-file))))
+
+(defun ess-r--flymake-linters ()
+  "If `ess-r-flymake-linters' is a string, use that.
+Otherwise, construct a string to pass to lintr::linters_with_defaults."
+  (replace-regexp-in-string
+   "[\n\t ]+" " "
+   (if (stringp ess-r-flymake-linters)
+       ess-r-flymake-linters
+     (concat "lintr::linters_with_defaults("
+             (mapconcat #'identity
+                        ess-r-flymake-linters
+                        ", ")
+             ")"))))
+
+(defun ess-r--flymake-msg-type (str)
+  "Transform STR into log level."
+  (cond ((string= str "error: ") :error)
+        ((string= str "warning: ") :warning)
+        ((string= str "style: ") :note)
+        (t (error "Invalid msg type %s" str))))
+
+(defun ess-r--flymake-check-errors ()
+  "Check for critical errors and return non-nil if such occurred."
+  (goto-char (point-min))
+  (when (re-search-forward "@@\\(\\(error\\|warning\\): \\)@@" nil t)
+    (let ((type (ess-r--flymake-msg-type (match-string 1)))
+          (msg (buffer-substring-no-properties (match-end 0) (point-max))))
+      (flymake-log type msg)
+      (eq type :error))))
+
+(defun ess-r--flymake-parse-output (msg-buffer src-buffer report-fn)
+  "Parse the content of MSG-BUFFER for lint locations.
+SRC-BUFFER is the original source buffer.  Collect all messages
+into a list and call REPORT-FN on it."
+  (with-current-buffer msg-buffer
+    (if (ess-r--flymake-check-errors)
+        (with-current-buffer src-buffer
+          ;; we are in the sentinel here; don't throw but remove our hook instead
+          (remove-hook 'flymake-diagnostic-functions #'ess-r-flymake t))
+      (goto-char (point-min))
+      (cl-loop
+       while (search-forward-regexp
+              ;; Regex to match the output lint() gives us.
+              (rx line-start "<text>:"
+                  ;; row
+                  (group-n 1 (one-or-more num)) ":"
+                  ;; column
+                  (group-n 2 (one-or-more num)) ": "
+                  ;; type
+                  (group-n 3 (| "style: " "warning: " "error: "))
+                  ;; msg
+                  (group-n 4 (one-or-more not-newline)) line-end)
+              nil t)
+       for msg = (match-string 4)
+       for (beg . end) = (let ((line (string-to-number (match-string 1)))
+                               (col (string-to-number (match-string 2))))
+                           (flymake-diag-region src-buffer line col))
+       for type = (ess-r--flymake-msg-type (match-string 3))
+       collect (flymake-make-diagnostic src-buffer beg end type msg)
+       into diags
+       finally (funcall report-fn diags)))))
+
+(defun ess-r-flymake (report-fn &rest _args)
+  "A Flymake backend for ESS-R modes.  Relies on the lintr package.
+REPORT-FN is flymake's callback function."
+  (unless (executable-find inferior-ess-r-program)
+    (error "Cannot find program '%s'" inferior-ess-r-program))
+  ;; Kill the process if earlier check was found. The sentinel of the earlier
+  ;; check will detect this.
+  (when (process-live-p ess-r--flymake-proc)
+    (kill-process ess-r--flymake-proc))
+  (if (and (eql ess-use-flymake 'process)
+           (not (ess-process-live-p)))
+      (progn
+        (funcall report-fn nil)
+        (mapc #'delete-overlay (flymake--overlays)))
+    (let ((src-buffer (current-buffer)))
+      (setq ess-r--flymake-proc
+            (make-process
+             :name "ess-r-flymake" :noquery t :connection-type 'pipe
+             :buffer (generate-new-buffer " *ess-r-flymake*")
+             :command (list inferior-R-program
+                            "--no-save" "--no-restore" "--no-site-file" "--no-init-file" "--slave"
+                            "-e" (concat
+                                  (when ess-r--lintr-file
+                                    (concat "options(lintr.linter_file = \"" ess-r--lintr-file "\");"))
+                                  ess-r--flymake-def-linter
+                                  ;; commandArgs(TRUE) returns everything after
+                                  ;; --args as a character vector
+                                  "esslint(commandArgs(TRUE)"
+                                  (unless ess-r--lintr-file
+                                    (concat ", linters = " (ess-r--flymake-linters)))
+                                  (when ess-r-flymake-lintr-cache
+                                    ", cache = TRUE")
+                                  ")")
+                            "--args" (buffer-substring-no-properties
+                                      (point-min) (point-max)))
+             :sentinel
+             (lambda (proc _event)
+               (cond
+                ((eq 'exit (process-status proc))
+                 (unwind-protect
+                     (if (eq proc (buffer-local-value 'ess-r--flymake-proc src-buffer))
+                         (ess-r--flymake-parse-output (process-buffer proc) src-buffer report-fn)
+                       (flymake-log :warning "Canceling obsolete check %s" proc))
+                   (kill-buffer (process-buffer proc))))
+                ((not (eq 'run (process-status proc)))
+                 (kill-buffer (process-buffer proc))))))))))
+
+(defun ess-r-setup-flymake ()
+  "Setup flymake for ESS.
+Activate flymake only if `ess-use-flymake' is non-nil."
+  (when ess-use-flymake
+    (when (< emacs-major-version 26)
+      (error "ESS-flymake requires Emacs version 26 or later"))
+    (when (string= "R" ess-dialect)
+      (setq ess-r--lintr-file (ess-r--find-lintr-file))
+      (add-hook 'flymake-diagnostic-functions #'ess-r-flymake nil t)
+      ;; Try not to enable flymake if flycheck is already running:
+      (unless (bound-and-true-p flycheck-mode)
+        (flymake-mode)))))
+
+;; Enable flymake in Emacs 26+
+(when (<= 26 emacs-major-version)
+  (if (eval-when-compile (<= 26 emacs-major-version))
+      (add-hook 'ess-r-mode-hook #'ess-r-setup-flymake)
+    (when ess-use-flymake
+      (display-warning 'ess "ESS was compiled with older version of Emacs;\n    `ess-r-flymake' won't be available"))))
+
+(provide 'ess-r-flymake)
+
+;;; ess-r-flymake.el ends here
diff --git a/elpa/ess-20260424.1544/ess-r-mode.el b/elpa/ess-20260424.1544/ess-r-mode.el
new file mode 100644 (file)
index 0000000..8e13c49
--- /dev/null
@@ -0,0 +1,3149 @@
+;;; ess-r-mode.el --- R customization  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1997-2026 Free Software Foundation, Inc.
+;; Author: A.J. Rossini
+;; Created: 12 Jun 1997
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; This file defines all the R customizations for ESS.  See ess-s-lang.el
+;; for general S language customizations.
+
+;;; Code:
+
+(eval-when-compile
+  (require 'subr-x))
+(require 'cl-lib)
+(require 'compile)
+(require 'ess-mode)
+(require 'ess-help)
+(require 'ess-s-lang)
+(require 'ess-roxy)
+(require 'ess-r-completion)
+(require 'ess-r-syntax)
+(require 'ess-r-package)
+(require 'ess-trns)
+(require 'ess-r-xref)
+(when (>= emacs-major-version 26) (require 'ess-r-flymake)) ; Flymake rewrite in Emacs 26
+
+(declare-function ess-rdired "ess-rdired" ())
+
+(defcustom ess-r-mode-hook nil
+  "Hook run when entering `ess-r-mode'."
+  :options '(electric-layout-local-mode)
+  :type 'hook
+  :group 'ess-R)
+
+;; Define and run old hook for backward compatibility. We don't
+;; obsolete it with warnings because this is a historically important
+;; user-facing variable and it would not be worth the trouble.
+(defvar R-mode-hook nil
+  "This variable is obsolete since ESS 19.04;
+use `ess-r-mode-hook' instead.")
+(add-hook 'ess-r-mode-hook (lambda () (run-hooks 'R-mode-hook)))
+
+(defcustom ess-r-fetch-ESSR-on-remotes nil
+  "If non-nil, when loading ESSR, fetch it from the GitHub repository.
+Otherwise source from local ESS installation. When the value is
+\\='ess-remote, fetch only with ess-remote's and not with TRAMP
+connections. When t, always fetch from remotes. Change this
+variable when loading ESSR code on remotes fails for you.
+
+Fetching happens once per new ESSR version. The archive is stored
+in ~/.config/ESSR/ESSRv[VERSION].rds file. You can download and
+place it there manually if the remote has restricted network
+access."
+  :type '(choice (const :tag "Never" nil)
+                 (const :tag "With ess-remote only" ess-remote)
+                 (const :tag "Always" t))
+  :group 'ess-R)
+
+;; Silence the byte compiler
+(defvar add-log-current-defun-header-regexp)
+
+;; TODO: Refactor so as to not rely on dynamic scoping.  After that
+;; refactor, also remove the file-local-variable byte-compile-warnings
+;; (not lexical) at the bottom.
+(defvar containing-sexp)
+(defvar indent-point)
+(defvar prev-containing-sexp)
+
+(define-obsolete-variable-alias 'ess-r-versions 'ess-r-runner-prefixes "ESS 19.04")
+(defcustom ess-r-runner-prefixes
+  (let ((r-ver '("R-1" "R-2" "R-3" "R-4" "R-5" "R-6" "R-7" "R-devel" "R-patched")))
+    (if (eq system-type 'darwin) (append r-ver '("R32" "R64")) r-ver))
+  "List of partial strings for versions of R to access within ESS.
+Each string specifies the start of a filename. If a filename
+beginning with one of these strings is found on variable
+`exec-path', a command for that version of R is made available.
+For example, if the file \"R-1.8.1\" is found and this variable
+includes the string \"R-1\", a function called `R-1.8.1' will be
+available to run that version of R. If duplicate versions of the
+same program are found (which happens if the same path is listed
+on variable `exec-path' more than once), they are ignored by
+calling `delete-dups'. Set this variable to nil to disable
+searching for other versions of R. Setting this variable directly
+does not take effect; use either \\[customize-option] or set the
+value by using `ess-r-runners-reset'."
+  :group 'ess-R
+  :package-version '(ess . "19.04")
+  :type '(repeat string)
+  :set #'ess-r-runners-reset
+  ;; Use `custom-initialize-default' since we call
+  ;; `ess-r-define-runners' at the end of this file directly.
+  :initialize #'custom-initialize-default)
+
+
+\f
+;;*;; Mode definition
+
+;;;*;;; UI (Keymaps / Menus)
+(defvar ess-dev-map
+  (let (ess-dev-map)
+    (define-prefix-command 'ess-dev-map)
+    (define-key ess-dev-map "\C-s" #'ess-r-set-evaluation-env)
+    (define-key ess-dev-map "s"    #'ess-r-set-evaluation-env)
+    (define-key ess-dev-map "T"    #'ess-toggle-tracebug)
+    (define-key ess-dev-map "\C-l" #'ess-r-devtools-load-package)
+    (define-key ess-dev-map "l"    #'ess-r-devtools-load-package)
+    (define-key ess-dev-map "`"    #'ess-show-traceback)
+    (define-key ess-dev-map "~"    #'ess-show-call-stack)
+    (define-key ess-dev-map "\C-w" #'ess-watch)
+    (define-key ess-dev-map "w"    #'ess-watch)
+    (define-key ess-dev-map "\C-d" #'ess-debug-flag-for-debugging)
+    (define-key ess-dev-map "d"    #'ess-debug-flag-for-debugging)
+    (define-key ess-dev-map "\C-u" #'ess-debug-unflag-for-debugging)
+    (define-key ess-dev-map "u"    #'ess-debug-unflag-for-debugging)
+    (define-key ess-dev-map "\ 4"   #'ess-debug-unflag-for-debugging)
+    (define-key ess-dev-map "\C-b" #'ess-bp-set)
+    (define-key ess-dev-map "b"    #'ess-bp-set)
+    (define-key ess-dev-map "\ 2"   #'ess-bp-set-conditional)
+    (define-key ess-dev-map "B"    #'ess-bp-set-conditional)
+    (define-key ess-dev-map "\C-L" #'ess-bp-set-logger)
+    (define-key ess-dev-map "L"    #'ess-bp-set-logger)
+    (define-key ess-dev-map "\C-o" #'ess-bp-toggle-state)
+    (define-key ess-dev-map "o"    #'ess-bp-toggle-state)
+    (define-key ess-dev-map "\C-k" #'ess-bp-kill)
+    (define-key ess-dev-map "k"    #'ess-bp-kill)
+    (define-key ess-dev-map "\C-K" #'ess-bp-kill-all)
+    (define-key ess-dev-map "K"    #'ess-bp-kill-all)
+    (define-key ess-dev-map "\C-n" #'ess-bp-next)
+    (define-key ess-dev-map "n"    #'ess-bp-next)
+    (define-key ess-dev-map "i"    #'ess-debug-goto-input-event-marker)
+    (define-key ess-dev-map "I"    #'ess-debug-goto-input-event-marker)
+    (define-key ess-dev-map "\C-p" #'ess-bp-previous)
+    (define-key ess-dev-map "p"    #'ess-bp-previous)
+    (define-key ess-dev-map "\C-e" #'ess-debug-toggle-error-action)
+    (define-key ess-dev-map "e"    #'ess-debug-toggle-error-action)
+    (define-key ess-dev-map "0"    #'ess-electric-selection)
+    (define-key ess-dev-map "1"    #'ess-electric-selection)
+    (define-key ess-dev-map "2"    #'ess-electric-selection)
+    (define-key ess-dev-map "3"    #'ess-electric-selection)
+    (define-key ess-dev-map "4"    #'ess-electric-selection)
+    (define-key ess-dev-map "5"    #'ess-electric-selection)
+    (define-key ess-dev-map "6"    #'ess-electric-selection)
+    (define-key ess-dev-map "7"    #'ess-electric-selection)
+    (define-key ess-dev-map "8"    #'ess-electric-selection)
+    (define-key ess-dev-map "9"    #'ess-electric-selection)
+    (define-key ess-dev-map "?"    #'ess-tracebug-show-help)
+    ess-dev-map)
+  "Keymap for commands related to development and debugging.")
+
+(defvar ess-r-package-check-map
+  (let (ess-r-package-check-map)
+    (define-prefix-command 'ess-r-package-check-map)
+    (define-key ess-r-package-check-map "\C-c" #'ess-r-devtools-check-package)
+    (define-key ess-r-package-check-map "c"    #'ess-r-devtools-check-package)
+    (define-key ess-r-package-check-map "\C-w" #'ess-r-devtools-check-with-winbuilder)
+    (define-key ess-r-package-check-map "w"    #'ess-r-devtools-check-with-winbuilder)
+    (define-key ess-r-package-check-map "h"    #'ess-r-rhub-check-package)
+    ess-r-package-check-map)
+  "Keymap for R package checks.")
+
+(defvar ess-r-package-dev-map
+  (let (ess-r-package-dev-map)
+    (define-prefix-command 'ess-r-package-dev-map)
+    (define-key ess-r-package-dev-map "\C-s" #'ess-r-set-evaluation-env)
+    (define-key ess-r-package-dev-map "s"    #'ess-r-set-evaluation-env)
+    (define-key ess-r-package-dev-map "\C-a" #'ess-r-devtools-execute-command)
+    (define-key ess-r-package-dev-map "a"    #'ess-r-devtools-execute-command)
+    (define-key ess-r-package-dev-map "\C-e" #'ess-r-devtools-execute-command)
+    (define-key ess-r-package-dev-map "e"    #'ess-r-devtools-execute-command)
+    (define-key ess-r-package-dev-map "\C-b" #'ess-r-devtools-build)
+    (define-key ess-r-package-dev-map "b"    #'ess-r-devtools-build)
+    (define-key ess-r-package-dev-map "\C-c" 'ess-r-package-check-map)
+    (define-key ess-r-package-dev-map "c"    'ess-r-package-check-map)
+    (define-key ess-r-package-dev-map "\C-d" #'ess-r-devtools-document-package)
+    (define-key ess-r-package-dev-map "d"    #'ess-r-devtools-document-package)
+    (define-key ess-r-package-dev-map "g"    #'ess-r-devtools-install-github)
+    (define-key ess-r-package-dev-map "\C-i" #'ess-r-devtools-install-package)
+    (define-key ess-r-package-dev-map "i"    #'ess-r-devtools-install-package)
+    (define-key ess-r-package-dev-map "\C-l" #'ess-r-devtools-load-package)
+    (define-key ess-r-package-dev-map "l"    #'ess-r-devtools-load-package)
+    (define-key ess-r-package-dev-map "\C-t" #'ess-r-devtools-test-package)
+    (define-key ess-r-package-dev-map "t"    #'ess-r-devtools-test-package)
+    (define-key ess-r-package-dev-map "\C-u" #'ess-r-devtools-unload-package)
+    (define-key ess-r-package-dev-map "u"    #'ess-r-devtools-unload-package)
+    ess-r-package-dev-map))
+
+(easy-menu-define ess-roxygen-menu nil
+  "Roxygen submenu."
+  '("Roxygen"
+    :visible (and ess-dialect (string-match "^R" ess-dialect))
+    ["Update/Generate Template" ess-roxy-update-entry           t]
+    ["Preview Rd"        ess-roxy-preview-Rd                    t]
+    ["Preview HTML"      ess-roxy-preview-HTML                  t]
+    ["Preview text"      ess-roxy-preview-text                  t]
+    ["Hide all"          ess-roxy-hide-all                      t]
+    ["Toggle Roxygen Prefix"     ess-roxy-toggle-roxy-region    t]))
+
+(easy-menu-define ess-tracebug-menu nil
+  "Tracebug submenu."
+  '("Tracebug"
+    :visible (and ess-dialect (string-match "^R" ess-dialect))
+    ;; :enable ess-local-process-name
+    ["Active?"  ess-toggle-tracebug
+     :style toggle
+     :selected (or (and (ess-process-live-p)
+                        (ess-process-get 'tracebug))
+                   ess-use-tracebug)]
+    ["Show traceback" ess-show-traceback (ess-process-live-p)]
+    ["Show call stack" ess-show-call-stack (ess-process-live-p)]
+    ["Watch" ess-watch  (and (ess-process-live-p)
+                             (ess-process-get 'tracebug))]
+    ["Error action cycle" ess-debug-toggle-error-action (and (ess-process-live-p)
+                                                             (ess-process-get 'tracebug))]
+    "----"
+    ["Flag for debugging" ess-debug-flag-for-debugging ess-local-process-name]
+    ["Unflag for debugging" ess-debug-unflag-for-debugging ess-local-process-name]
+    "----"
+    ["Set BP" ess-bp-set t]
+    ["Set conditional BP" ess-bp-set-conditional t]
+    ["Set logger BP" ess-bp-set-logger t]
+    ["Kill BP" ess-bp-kill t]
+    ["Kill all BPs" ess-bp-kill-all t]
+    ["Next BP" ess-bp-next t]
+    ["Previous BP" ess-bp-previous t]
+    "-----"
+    ["About" ess-tracebug-show-help t]))
+
+(easy-menu-define ess-r-package-menu nil
+  "Package Development submenu."
+  '("Package development"
+    :visible (and ess-dialect (string-match "^R" ess-dialect))
+    ["Active?" ess-r-package-mode
+     :style toggle
+     :selected ess-r-package-mode]
+    ["Select package for evaluation" ess-r-set-evaluation-env t]))
+
+(easy-menu-add-item ess-mode-menu nil ess-roxygen-menu "end-dev")
+(easy-menu-add-item ess-mode-menu nil ess-r-package-menu "end-dev")
+(easy-menu-add-item ess-mode-menu nil ess-tracebug-menu "end-dev")
+(easy-menu-add-item inferior-ess-mode-menu nil ess-r-package-menu "end-dev")
+(easy-menu-add-item inferior-ess-mode-menu nil ess-tracebug-menu "end-dev")
+
+(defvar ess-r-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-=") #'ess-cycle-assign)
+    ;;(define-key map "\M-?" #'ess-complete-object-name); not stealing  M-?  from "standard Emacs"
+    (define-key map (kbd "C-c C-.") 'ess-rutils-map)
+    map))
+
+(defvar ess-r-mode-syntax-table
+  (let ((table (copy-syntax-table S-syntax-table)))
+    ;; Letting Emacs treat backquoted names and %ops% as strings solves
+    ;; many problems with regard to nested strings and quotes
+    (modify-syntax-entry ?` "\"" table)
+    (modify-syntax-entry ?% "\"" table)
+    ;; Underscore is valid in R symbols
+    (modify-syntax-entry ?_ "_" table)
+    (modify-syntax-entry ?: "." table)
+    (modify-syntax-entry ?@ "." table)
+    (modify-syntax-entry ?$ "." table)
+    (modify-syntax-entry ?\\ "." table)
+    table)
+  "Syntax table for `ess-r-mode'.")
+
+(defvar ess-r-completion-syntax-table
+  (let ((table (copy-syntax-table ess-r-mode-syntax-table)))
+    (modify-syntax-entry ?. "_" table)
+    (modify-syntax-entry ?: "_" table)
+    (modify-syntax-entry ?$ "_" table)
+    (modify-syntax-entry ?@ "_" table)
+    table)
+  "Syntax table used for completion and help symbol lookup.
+It makes underscores and dots word constituent chars.")
+
+(defvar ess-r-namespaced-load-verbose t
+  "Whether to display information on namespaced loading.
+When t, loading a file into a namespaced will output information
+about which objects are exported and which stay hidden in the
+namespace.")
+
+(defconst ess-r--outline-rstudio-regexp
+  "^[ \t]*#+ +.*\\(?:----\\|====\\|####\\)\\s-*$"
+  "R outline Regexp when `ess-r-outline-style' is `RStudio'.")
+
+(defconst ess-r--outline-org-like-regexp
+  "^\\(?:> \\)?###\\s-+\\(\\*+\\)\\s-+.*$"
+  "R outline regexp used when `ess-r-outline-style' is `Org-like'.")
+
+(defconst ess-r-outline-style-alist
+  `((none
+     (outline-regexp . "\\`a\\`")
+     (outline-level  . ,#'ess-r--outline-level-none))
+    (RStudio
+     (outline-regexp . ,ess-r--outline-rstudio-regexp)
+     (outline-level  . ,#'ess-r--outline-level-rstudio))
+    (Org-like
+     (outline-regexp . ,ess-r--outline-org-like-regexp)
+     (outline-level  . ,#'ess-r--outline-level-org-like)))
+  "Mapping between outline styles and their regexp/level helpers.")
+
+(defun ess-r--outline-style-definition (&optional style)
+  "Return the style definition for STYLE, defaulting to `ess-r-outline-style'."
+  (let ((style (or style ess-r-outline-style)))
+    (or (assq style ess-r-outline-style-alist)
+        (error "Unknown ESS outline style: %s" style))))
+
+(defun ess-r--outline-style-value (key &optional style)
+  "Return value for KEY in STYLE's definition."
+  (cdr (assq key (cdr (ess-r--outline-style-definition style)))))
+
+(defun ess-r--outline-level-rstudio ()
+  "Compute outline level for `RStudio` style headings."
+  (save-excursion
+    (beginning-of-line)
+    (if (looking-at "^[ \t]*\\(#+\\)\\s-")
+        (length (match-string 1))
+      1000)))
+
+(defun ess-r--outline-level-org-like ()
+  "Compute outline level for `Org-like` style headings."
+  (save-excursion
+    (beginning-of-line)
+    (if (looking-at "^\\(?:> \\)?###\\s-+\\(\\*+\\)\\s-+")
+        (length (match-string 1))
+      1000)))
+
+(defun ess-r--outline-level-none ()
+  "Dummy outline level function for no outline support."
+  1000)
+
+(defun ess-r-outline-level ()
+  "R mode `outline-level` dispatcher for the current outline style."
+  (funcall (ess-r--outline-style-value 'outline-level)))
+
+(defvar-local ess-r--saved-indent-with-fancy-comments nil
+  "Saved state of `ess-indent-with-fancy-comments' before RStudio style.
+Stored as (VALUE . WAS-LOCAL) to restore both value and local binding.")
+
+(defun ess-r-set-outline-style (&optional style)
+  "Apply STYLE (or `ess-r-outline-style') to the current buffer.
+
+When switching to RStudio style, `ess-indent-with-fancy-comments' is
+automatically set to nil locally. The previous value is saved and
+restored when switching to a different style."
+  (interactive
+   (list (intern (completing-read
+                 "Outline style"
+                 (mapcar (lambda (entry) (symbol-name (car entry)))
+                         ess-r-outline-style-alist)
+                 nil t nil nil
+                 (symbol-name (or ess-r-outline-style 'none))))))
+  (let* ((style (or style ess-r-outline-style))
+         (entry (ess-r--outline-style-definition style))
+         (old-style ess-r-outline-style)
+         (new-style (car entry)))
+    ;; Handle ess-indent-with-fancy-comments adjustment
+    (cond
+     ;; Switching TO RStudio style
+     ((and (eq new-style 'RStudio)
+           (not (eq old-style 'RStudio)))
+      ;; Save current value if not already saved
+      (unless ess-r--saved-indent-with-fancy-comments
+        (setq ess-r--saved-indent-with-fancy-comments
+              (cons (if (local-variable-p 'ess-indent-with-fancy-comments)
+                        ess-indent-with-fancy-comments
+                      (default-value 'ess-indent-with-fancy-comments))
+                    (local-variable-p 'ess-indent-with-fancy-comments))))
+      (setq-local ess-indent-with-fancy-comments nil))
+     ;; Switching FROM RStudio style to another
+     ((and (eq old-style 'RStudio)
+           (not (eq new-style 'RStudio))
+           ess-r--saved-indent-with-fancy-comments)
+      ;; Restore saved value and local state
+      (let ((saved-value (car ess-r--saved-indent-with-fancy-comments))
+            (saved-local (cdr ess-r--saved-indent-with-fancy-comments)))
+        (if saved-local
+            (setq-local ess-indent-with-fancy-comments saved-value)
+          (when (local-variable-p 'ess-indent-with-fancy-comments)
+            (kill-local-variable 'ess-indent-with-fancy-comments))))
+      (setq ess-r--saved-indent-with-fancy-comments nil)))
+    ;; Apply outline style
+    (setq-local ess-r-outline-style new-style)
+    (setq-local outline-regexp (ess-r--outline-style-value 'outline-regexp style))
+    (setq-local outline-level #'ess-r-outline-level)))
+
+;; The syntax class for '\' is punctuation character to handle R 4.1
+;; lambdas. Inside strings it should be treated as an escape
+;; character which we ensure here.
+(defun ess-r--syntax-propertize-backslash ()
+  (when (nth 3 (save-excursion (syntax-ppss (1- (point)))))
+    (string-to-syntax "\\")))
+
+;; Adapted from `python-syntax-stringify'
+(defun ess-r--syntax-propertize-raw-string-opening ()
+  (let* ((raw-beg (match-beginning 0))
+         (quote-beg (1+ raw-beg))
+         (ppss (save-excursion (goto-char raw-beg) (syntax-ppss)))
+         (string-start (and (eq t (nth 3 ppss)) (nth 8 ppss))))
+    (cond
+     ;; Inside a comment
+     ((nth 4 ppss)
+      nil)
+     ;; This set of quotes delimits the start of a string
+     ((null string-start)
+      (put-text-property quote-beg (1+ quote-beg)
+                         'syntax-table (string-to-syntax "|"))))))
+
+(defun ess-r--syntax-propertize-raw-string-closing ()
+  (let* ((quote-end (match-end 0))
+         (quote-chr (aref (match-string 3) 0))
+         (dashes (match-string 2))
+         (matching-delim (pcase (match-string 1)
+                           (`")" ?\() (`"}" ?{) (`"]" ?\[)))
+         (ppss (save-excursion (goto-char quote-end) (syntax-ppss)))
+         (string-start (and (eq t (nth 3 ppss)) (nth 8 ppss))))
+    (when string-start
+      (save-match-data
+        (save-excursion
+          (goto-char string-start)
+          (when (equal (char-after) quote-chr)
+            (forward-char)
+            (re-search-forward "-*" nil t)
+            (let ((matching-dashes (match-string 0)))
+              (when (or (not matching-dashes)
+                        (string= matching-dashes dashes))
+                (when (equal (char-after) matching-delim)
+                  (put-text-property (1- quote-end) quote-end
+                                     'syntax-table (string-to-syntax "|")))))))))))
+
+(defconst ess-r--syntax-propertize-function
+  (syntax-propertize-rules
+   ("[rR]\\([\"']\\)\\(-*\\)\\([([{]\\)"
+    (0 (ignore (ess-r--syntax-propertize-raw-string-opening))))
+   ("\\([])}]\\)\\(-*\\)\\([\"']\\)"
+    (0 (ignore (ess-r--syntax-propertize-raw-string-closing))))
+   ("\\\\"
+    (0 (ess-r--syntax-propertize-backslash)))))
+
+(defun ess-r-font-lock-syntactic-face-function (state)
+  (if (nth 3 state)
+      ;; string case
+      (let ((string-end (save-excursion
+                          (ess-goto-char (nth 8 state))
+                          (ess-forward-sexp)
+                          (point))))
+        (cond
+         ((eq (nth 3 state) ?%)
+          (if (eq (point) (1- string-end))
+              (when (cdr (assq 'ess-fl-keyword:operators ess-R-font-lock-keywords))
+                'ess-operator-face)
+            (if (cdr (assq 'ess-R-fl-keyword:%op% ess-R-font-lock-keywords))
+                'ess-%op%-face
+              nil)))
+         ((save-excursion
+            (and (cdr (assq 'ess-R-fl-keyword:fun-defs ess-R-font-lock-keywords))
+                 (ess-goto-char string-end)
+                 (ess-looking-at "<-")
+                 (ess-goto-char (match-end 0))
+                 (ess-looking-at "function\\b\\|\\\\" t)))
+          font-lock-function-name-face)
+         ((save-excursion
+            (and (cdr (assq 'ess-fl-keyword:fun-calls ess-R-font-lock-keywords))
+                 (ess-goto-char string-end)
+                 (ess-looking-at "(")))
+          ess-function-call-face)
+         ((eq (nth 3 state) ?`)
+          nil)
+         (t
+          font-lock-string-face)))
+    font-lock-comment-face))
+
+;; Don't fontify backquoted symbols as strings
+(defun inferior-ess-r-font-lock-syntactic-face-function (state)
+  (if (nth 3 state)
+      (if (eq (nth 3 state) ?`)
+          nil
+        font-lock-string-face)
+    font-lock-comment-face))
+
+(defvar ess-r--non-fn-kwds
+  '("in" "else" "break" "next" "repeat")
+  "Reserved words that should not be treated as names of special
+functions by `ess-r--find-fl-keyword'; such reserved words do
+not need to be followed by an open parenthesis to trigger
+font-locking.
+See also `ess-r--non-fn-kstrs'.")
+
+(defvar ess-r--non-fn-kstrs
+  '("\?")
+  "Reserved non-word strings that should not be treated as names of
+special functions by `ess-r--find-fl-keyword'; such reserved
+strings do not need to be followed by an open parenthesis to
+trigger font-locking.
+See also `ess-r--non-fn-kwds'.")
+
+(defvar-local ess-r--keyword-regexp nil)
+(defun ess-r--find-fl-keyword (limit)
+  "Search for R keyword or keystring and set the match data.
+To be used as part of `font-lock-defaults' keywords."
+  (unless ess-r--keyword-regexp
+    (let (fn-kwds non-fn-kwds fn-kstrs non-fn-kstrs)
+      (dolist (kw ess-R-keywords)
+        (if (member kw ess-r--non-fn-kwds)
+            (push kw non-fn-kwds)
+          (push kw fn-kwds)))
+      (dolist (kw ess-r--keystrings)
+       (if (member kw ess-r--non-fn-kstrs)
+           (push kw non-fn-kstrs)
+         (push kw fn-kstrs)))
+      (setq ess-r--keyword-regexp
+            (concat "\\("
+                    (regexp-opt non-fn-kwds 'words)
+                    "\\|"
+                    (regexp-opt non-fn-kstrs t)
+                    "\\)\\|\\("
+                    (regexp-opt fn-kwds 'words)
+                    "\\|"
+                    (regexp-opt fn-kstrs t)
+                    "\\)"))))
+  (let (out)
+    (while (and (not out)
+                (re-search-forward ess-r--keyword-regexp limit t))
+      (save-match-data
+        (setq out (if (match-beginning 1)
+                      ;; Non-function-like keywords: Always fontified
+                      ;; except for `in` for which we check it's part
+                      ;; of a `for` construct. Ideally we'd check that
+                      ;; other keywords like `break` or `next` are
+                      ;; part of the right syntactic construct but
+                      ;; that requires robust and efficient detection
+                      ;; of complete expressions.
+                      (if (string= (match-string 1) "in")
+                          (save-excursion
+                            (goto-char (match-beginning 1))
+                            (and (ess-backward-up-list)
+                                 (forward-word -1)
+                                 (looking-at "for\\s-*(")))
+                        t)
+                    ;; Function-like keywords: check if they are
+                    ;; followed by an open paren
+                    (looking-at "\\s-*(")))))
+    out))
+
+(define-obsolete-variable-alias 'R-customize-alist 'ess-r-customize-alist "ESS 18.10.2")
+(defvar ess-r-customize-alist
+  (append
+   '((ess-local-customize-alist             . 'ess-r-customize-alist)
+     (ess-dialect                           . "R")
+     (ess-suffix                            . "R")
+     (ess-traceback-command                 . ess-r-traceback-command)
+     (ess-call-stack-command                . ess-r-call-stack-command)
+     (ess-mode-completion-syntax-table      . ess-r-completion-syntax-table)
+     (ess-build-eval-message-function       . #'ess-r-build-eval-message)
+     (ess-dump-filename-template            . ess-r-dump-filename-template)
+     (ess-change-sp-regexp                  . ess-r-change-sp-regexp)
+     (ess-help-sec-regex                    . ess-help-r-sec-regex)
+     (ess-help-sec-keys-alist               . ess-help-r-sec-keys-alist)
+     (ess-function-pattern                  . ess-r-function-pattern)
+     (ess-object-name-db-file               . "ess-r-namedb.el")
+     (ess-smart-operators                   . ess-r-smart-operators)
+     (inferior-ess-program                  . inferior-ess-r-program)
+     (inferior-ess-objects-command          . inferior-ess-r-objects-command)
+     (inferior-ess-search-list-command      . "base::search()\n")
+     (inferior-ess-help-command             . inferior-ess-r-help-command)
+     (inferior-ess-exit-command             . "q()")
+     (ess-error-regexp-alist                . ess-r-error-regexp-alist)
+     (ess-describe-object-at-point-commands . 'ess-r-describe-object-at-point-commands)
+     (ess-STERM                             . "iESS")
+     (ess-editor                            . ess-r-editor)
+     (ess-pager                             . ess-r-pager))
+   S-common-cust-alist)
+  "Variables to customize for R.")
+
+(cl-defmethod ess-build-tags-command (&context (ess-dialect "R"))
+  "Return tags command for R."
+  "rtags('%s', recursive = TRUE, pattern = '\\\\.[RrSs](rw)?$',ofile = '%s')")
+
+(defvar ess-r-traceback-command
+  "local({cat(geterrmessage(), \
+'---------------------------------- \n', \
+fill=TRUE); try(traceback(), silent=TRUE)})\n")
+
+(defvar ess-r-call-stack-command "traceback(1)\n")
+
+(defun ess-r-format-command (cmd &rest args)
+  (let ((sentinel (alist-get 'output-delimiter args)))
+    (ess-r--format-call ".ess.command(local(%s), '%s')\n" cmd sentinel)))
+
+(defvar ess-r-format-command-alist
+  '((fun           . ess-r-format-command)
+    (use-delimiter . t)))
+
+(defvar ess-r-dump-filename-template
+  (replace-regexp-in-string
+   "S$" "R" ess-dump-filename-template-proto))
+
+(defvar ess-r-ac-sources
+  '(ac-source-R))
+
+(defvar ess-r-company-backends
+  '((company-R-library company-R-args company-R-objects :separate)))
+
+(defconst ess-help-r-sec-regex "^[A-Z][A-Za-z].+:$"
+  "Reg(ular) Ex(pression) of section headers in help file.")
+
+(defconst ess-help-r-sec-keys-alist
+  '((?a . "\\s *Arguments:")
+    (?d . "\\s *Description:")
+    (?D . "\\s *Details:")
+    (?t . "\\s *Details:")
+    (?e . "\\s *Examples:")
+    (?n . "\\s *Note:")
+    (?r . "\\s *References:")
+    (?s . "\\s *See Also:")
+    (?u . "\\s *Usage:")
+    (?v . "\\s *Value[s]?")     ;
+    )
+  "Alist of (key . string) pairs for use in help section searching.")
+
+(defvar ess-r-error-regexp-alist '(R R1 R2 R3 R4 R-rlang R-recover)
+  "List of symbols which are looked up in `compilation-error-regexp-alist-alist'.")
+
+(dolist (l '(;; Takes precedence over R1 below in English locales, and allows spaces in file path
+             (R "\\(\\(?: at \\|(@\\)\\([^#()\n:]+\\)[#:]\\([0-9]+\\)\\)"  2 3 nil 2 1)
+             ;; valgrind, testthat, rlang/shiny style
+             ;; e.g. (stl_numeric.h:183), (test-parsers.R:238:3) [.../R/file.R#158]
+             (R1 "\\s(\\([^0-9][^ ():\n]+\\)[#:]\\([0-9]+\\)[#:]?\\([0-9]+\\)?\\s)" 1 2 nil 2)
+             (R2 "(\\(\\w+ \\([^())\n]+\\)#\\([0-9]+\\)\\))"  2 3 nil 2 1)
+             ;; Precedes R4 and allows spaces in file path, Starts at bol or with ": " (patterns 3,4,5,6,9)
+             (R3 "\\(?:^ *\\|: ?\\)\\([^-+[:digit:] \t\n]:?[^: \t\n]*\\):\\([0-9]+\\):\\(?:\\([0-9]+\\):\\)?"  1 2 3 2 1)
+             ;; Don't start with digit; no spaces
+             (R4 "\\([^-+ [:digit:]][^: \t\n]+\\):\\([0-9]+\\):\\([0-9]+\\):"  1 2 3 2 1)
+             (R-rlang "^ *[0-9]+\\..* \\(\\([^ :]+\\):\\([0-9]+\\):\\([0-9]+\\)\\)$" 2 3 4 nil 1)
+             (R-recover " *[0-9]+: +\\([^:\n\t]+?\\)#\\([0-9]+:\\)"  1 2 nil 2 1)))
+  (cl-pushnew l compilation-error-regexp-alist-alist))
+
+(define-obsolete-variable-alias 'ess-r-versions-created 'ess-r-created-runners "ESS 18.10")
+(defvar ess-r-created-runners nil
+  "List of R-versions found from `ess-r-runner-prefixes' on the system.")
+
+
+;;;*;;; Mode init
+
+(define-obsolete-variable-alias 'ess-R-post-run-hook 'ess-r-post-run-hook "ESS 18.10.2")
+
+;; We moved the set-wd instruction from `inferior-ess' to here to
+;; avoid sending R code to gdb or lldb before we had a chance to
+;; send "run". So this is no longer generic and inferior modes need
+;; to call this manually. One way to fix this would be to make
+;; `inferior-ess' a `cl-defgeneric'.
+(defvar ess-r-post-run-hook nil
+  "Functions run in process buffer after the initialization of R process.
+Make sure to call blocking commands (e.g. based on `ess-command')
+first. Streaming commands (e.g. based on `ess-send-string')
+should come last, otherwise they will make R busy and the
+blocking commands will throw an error.")
+
+;;;###autoload
+(defun run-ess-r (&optional start-args)
+  "Call \\='R\\=', the \\='GNU S\\=' system from the R Foundation.
+Optional prefix (\\[universal-argument]) allows to set command line arguments, such as
+--vsize.  This should be OS agnostic.
+If you have certain command line arguments that should always be passed
+to R, put them in the variable `inferior-R-args'.
+
+START-ARGS can be a string representing an argument, a list of
+such strings, or any other non-nil value.  In the latter case, you
+will be prompted to enter arguments interactively."
+  (interactive "P")
+  (ess-write-to-dribble-buffer   ;; for debugging only
+   (format
+    "\n(R): ess-dialect=%s, buf=%s, start-arg=%s\n current-prefix-arg=%s\n"
+    ess-dialect (current-buffer) start-args current-prefix-arg))
+  (unless (or (file-remote-p default-directory)
+              (when ess-startup-directory
+                (file-remote-p (if (symbolp ess-startup-directory)
+                                   (symbol-value ess-startup-directory)
+                                 ess-startup-directory)))
+              ;; TODO: Once we drop Emacs 26 support, can probably
+              ;; just use the REMOTE argument of `executable-find'.
+              (executable-find inferior-ess-r-program))
+    (display-warning 'ess (format "%s could not be found on the system. Try running `run-ess-r-newest' instead, which searches your system for R." inferior-ess-r-program) :error)
+    (user-error "%s program not found" inferior-ess-r-program))
+  (let* ((r-always-arg
+          (if (or ess-microsoft-p (eq system-type 'cygwin))
+              "--ess "
+            ;; else: "Unix alike"
+            (if (not ess-R-readline) "--no-readline ")))
+         (start-args
+          (cond ((stringp start-args)
+                 start-args)
+                ((and start-args
+                      (listp start-args)
+                      (cl-every #'stringp start-args))
+                 (mapconcat #'identity start-args " "))
+                (start-args
+                 (read-string
+                  (concat "Starting Args"
+                          (if r-always-arg
+                              (concat " [other than '" r-always-arg "']"))
+                          " ? ")))))
+         (r-start-args
+          (concat r-always-arg
+                  inferior-R-args " "   ; add space just in case
+                  start-args))
+         (debug (string-match-p " -d \\| --debugger=" r-start-args))
+         use-dialog-box)
+    (when (or ess-microsoft-p
+              (eq system-type 'cygwin))
+      (setq use-dialog-box nil)
+      (when ess-microsoft-p ;; default-process-coding-system would break UTF locales on Unix
+        (setq default-process-coding-system '(undecided-dos . undecided-dos))))
+
+    (let ((inf-buf (inferior-ess r-start-args ess-r-customize-alist debug)))
+      (with-current-buffer inf-buf
+        (ess-process-put 'funargs-pre-cache ess-r--funargs-pre-cache)
+        (if debug
+            (progn
+              ;; We need to use callback, because R might start with a gdb process
+              (ess-process-put 'callbacks '(inferior-ess-r--init-callback))
+              ;; Trigger the callback
+              (process-send-string (get-buffer-process inf-buf) "r\n"))
+          (ess-r-initialize)
+          (comint-goto-process-mark)))
+      inf-buf)))
+
+;;;###autoload
+(defun R (&optional start-args)
+  (interactive "P")
+  ;; FIXME: Current ob-R expects current buffer set to process buffer
+  (set-buffer (run-ess-r start-args)))
+
+(defun inferior-ess-r--init-callback (_proc _name)
+  (ess-r-initialize))
+
+(defvar ess-r--init-timeout 5
+  "Maximum time for R to become available on startup.
+If the timeout is reached, an error is thrown advising the user
+to run `ess-r-initialize' again.")
+
+(define-obsolete-function-alias 'R-initialize-on-start
+  #'ess-r-initialize "ESS 19.04")
+
+(defun ess-r-initialize ()
+  "This function is run after the first R prompt.
+Executed in process buffer."
+  (interactive)
+  (condition-case err
+      (progn
+        (unless (ess-wait-for-process nil nil nil nil ess-r--init-timeout)
+          (error "Process is busy"))
+        (ess-command (ess-r--init-options-command))
+        (ess-r-load-ESSR))
+    (error (ess-r--init-error-handler err))
+    (quit (ess-r--init-error-handler)))
+  (ess-process-put 'format-command-alist ess-r-format-command-alist)
+  (ess-process-put 'bg-eval-disabled nil)
+  (ess-execute-screen-options t)
+  (ess-set-working-directory default-directory)
+  (when ess-use-tracebug
+    (ess-tracebug 1))
+  (add-hook 'ess-presend-filter-functions #'ess-R-scan-for-library-call nil 'local)
+  ;; Wait before running user hook so they can call blocking commands
+  (ess-wait-for-process)
+  (run-hooks 'ess-r-post-run-hook)
+  (ess-wait-for-process))
+
+(defun ess-r--init-error-handler (&optional err)
+  (ess-write-to-dribble-buffer "Failed to start ESSR\n")
+  (when-let ((proc (and ess-local-process-name
+                        (get-process ess-local-process-name))))
+    (process-put proc 'bg-eval-disabled t))
+  (let ((msgs `("ESSR failed to start, please call `ess-r-initialize' to recover"
+                ,@(when err
+                    (concat "Caused by error: " (error-message-string err))))))
+    (error (mapconcat 'identity msgs "\n"))))
+
+;; FIXME: Should we stop setting `str.dendogram.last`? See:
+;; https://emacs.stackexchange.com/questions/27673/ess-dendrograms-appearance-of-last-branch/27729#27729
+;;
+;; FIXME: We don't use `ess-r-pager`? It's nil by default and
+;; documented that this should not normally be set
+(defun ess-r--init-options-command ()
+  (let ((args (list (format "STERM = '%s'" ess-STERM)
+                    "str.dendrogram.last = '\\''"
+                    (format "editor = '%s'" ess-r-editor)
+                    (ess-r--update-opt-if-eq "pager"
+                                             "file.path(R.home(), 'bin', 'pager')"
+                                             (format "'%s'" inferior-ess-pager))
+                    "show.error.locations = TRUE")))
+    (format "options(%s)\n" (mapconcat 'identity args ", "))))
+
+(defun ess-r--update-opt-if-eq (opt old new)
+  (let ((actual (format "getOption('%s')" opt)))
+    (format "%s = if (identical(%s, %s)) %s else %s"
+            opt
+            actual
+            old
+            new
+            actual)))
+
+(defun ess-r--skip-function ()
+  ;; Assumes the point is at function start
+  (if (looking-at-p ess-r-set-function-start)
+      (forward-list 1) ; get over the entire setXyz(...)
+    (forward-list 1) ; get over arguments
+    (if (looking-at-p "[ \t\n]*{")
+        (forward-sexp 1) ;; move over {...}
+      ;; {..}-less case
+      (skip-chars-forward " \t\n")
+      (goto-char (cadr (ess-continuations-bounds))))))
+
+;; `beginning-of-defun' protocol:
+;;  1) assumes that defuns are at the top level (e.g. always moves to bol)
+(defun ess-r-beginning-of-defun (&optional arg)
+  "Move to beginning a top level function.
+ARG is as in `beginning-of-defun'."
+  (ess-r-beginning-of-function arg t))
+
+;; `end-of-defun' protocol:
+;;  1) Uses beginning-of-defun-function with negative arg
+;;  2) Assumes that beginning-of-defun-function with -1 arg finds current defun
+;;  when point is just in front of the function
+(defun ess-r-end-of-defun (&optional arg)
+  "End of top level function.
+ARG is as in `end-of-defun'."
+  (ess-r-end-of-function arg t))
+
+(defun ess-r-beginning-of-function (&optional arg top-level)
+  "Leave (and return) the point at the beginning of the current ESS function.
+When ARG is positive, search for beginning of function backward,
+otherwise forward. Value of ARG is currently ignored. Return the
+new position, or nil if no-match. If TOP-LEVEL is non-nil, search
+for top-level functions only."
+  (setq arg (or arg 1))
+  (let ((start-point (point))
+        done)
+    ;; In case we are at the start of a function, skip past new lines.
+    (when (> arg 0)
+      ;; Start search from a forward position in order to capture current
+      ;; function start. But not when arg < 0; see end-of-defun protocol above.
+      (forward-line 2))
+    (while (and (not done)
+                (re-search-backward ess-r-function-pattern nil t arg))
+      (unless (ess-inside-string-or-comment-p)
+        (setq done
+              (if top-level
+                  (= (car (syntax-ppss (match-beginning 0))) 0)
+                t))
+        (if (< arg 0)
+            ;; move to match-end to avoid the infloop in re-search-backward
+            (goto-char (if done (match-beginning 0) (match-end 0)))
+          ;; Backward regexp match stops at the minimal match (e.g. partial
+          ;; function name), so we need a bit more work here.
+          (beginning-of-line)
+          (re-search-forward ess-r-function-pattern)
+          (goto-char (match-beginning 0))
+          (when (<= start-point (point))
+            (setq done nil)))))
+    (if done
+        (point)
+      (goto-char start-point)
+      nil)))
+
+(defun ess-r-end-of-function (&optional arg top-level)
+  "Leave the point at the end of the current function.
+When ARG is positive, search for end of function forward,
+otherwise backward. Move to point and return point if search was
+successful, otherwise nil. If TOP-LEVEL is non-nil, search for
+top level functions only."
+  (setq arg (or arg 1))
+  (let* ((start-pos (point))
+         (search-fn (lambda (lim)
+                      (let ((foundp nil))
+                        (while (and (not foundp)
+                                    (re-search-forward ess-r-function-pattern nil t))
+                          (when (< arg 0)
+                            ;; re-search-backward is a forward search
+                            ;; internally, so we need to bol in order to avoid
+                            ;; the infloop
+                            (beginning-of-line))
+                          (setq foundp
+                                (unless (ess-inside-string-or-comment-p)
+                                  (if top-level
+                                      (= 0 (car (save-excursion (syntax-ppss (match-beginning 0)))))
+                                    (>= (point) lim)))))
+                        (if foundp
+                            (progn (goto-char (match-beginning 0))
+                                   (ess-r--skip-function))
+                          (goto-char start-pos))))))
+    (ess-r-beginning-of-function 1 top-level)
+    (if (< (point) start-pos)
+        ;; Moved back. We were either inside a function or after a function.
+        (progn
+          (ess-r--skip-function)
+          ;; For negative ARG we are done.
+          (when (and (> arg 0)
+                     (<= (point) start-pos))
+            (funcall search-fn start-pos)))
+      ;; No function before point; search forward on positive ARG.
+      (when (> arg 0)
+        (funcall search-fn start-pos)))))
+
+;;;###autoload
+(define-derived-mode ess-r-mode ess-mode "ESS[R]"
+  "Major mode for editing R source.  See `ess-mode' for more help."
+  :group 'ess-R
+  (set-syntax-table ess-r-mode-syntax-table)
+  (ess-setq-vars-local ess-r-customize-alist)
+  (setq-local ess-font-lock-keywords 'ess-R-font-lock-keywords)
+  (setq-local paragraph-start (concat "\\s-*$\\|" page-delimiter))
+  (setq-local paragraph-separate (concat "\\s-*$\\|" page-delimiter))
+  (setq-local paragraph-ignore-fill-prefix t)
+  (setq-local indent-line-function #'ess-r-indent-line)
+  (setq-local comment-indent-function #'ess-calculate-indent)
+  (setq-local add-log-current-defun-header-regexp "^\\(.+\\)\\s-+<-[ \t\n]*function")
+  (setq-local font-lock-syntactic-face-function #'ess-r-font-lock-syntactic-face-function)
+  (setq-local syntax-propertize-function ess-r--syntax-propertize-function)
+  (setq-local electric-layout-rules '((?{ . after)))
+  ;; indentation
+  (add-hook 'hack-local-variables-hook #'ess-set-style nil t)
+  ;; outline
+  (add-hook 'hack-local-variables-hook #'ess-r-set-outline-style nil t)
+  ;; eldoc
+  (ess--setup-eldoc #'ess-r-eldoc-function)
+  ;; auto-complete
+  (ess--setup-auto-complete ess-r-ac-sources)
+  ;; company
+  (ess--setup-company ess-r-company-backends)
+  (setq-local prettify-symbols-alist ess-r-prettify-symbols)
+  (setq font-lock-defaults '(ess-build-font-lock-keywords nil nil ((?\. . "w") (?\_ . "w"))))
+  (remove-hook 'completion-at-point-functions #'ess-filename-completion 'local) ;; should be first
+  (add-hook 'completion-at-point-functions #'ess-r-object-completion nil 'local)
+  (add-hook 'completion-at-point-functions #'ess-r-package-completion nil 'local)
+  (add-hook 'completion-at-point-functions #'ess-filename-completion nil 'local)
+  (add-hook 'xref-backend-functions #'ess-r-xref-backend nil 'local)
+  (add-hook 'project-find-functions #'ess-r-project nil 'local)
+
+  (if (fboundp 'ess-add-toolbar) (ess-add-toolbar))
+  ;; imenu is needed for `which-function'
+  (setq imenu-generic-expression ess-imenu-S-generic-expression)
+  (when ess-imenu-use-S
+    (imenu-add-to-menubar "Imenu-R"))
+  ;; outline
+  (ess-r-set-outline-style)
+  (setq-local beginning-of-defun-function #'ess-r-beginning-of-defun)
+  (setq-local end-of-defun-function #'ess-r-end-of-defun)
+  (ess-roxy-mode))
+;;;###autoload
+(defalias 'R-mode #'ess-r-mode)
+;;;###autoload
+(defalias 'r-mode #'ess-r-mode)
+
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("/R/.*\\.q\\'" . ess-r-mode))
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.[rR]\\'" . ess-r-mode))
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.[rR]profile\\'" . ess-r-mode))
+;;;###autoload
+(add-to-list 'auto-mode-alist '("NAMESPACE\\'" . ess-r-mode))
+;;;###autoload
+(add-to-list 'auto-mode-alist '("CITATION\\'" . ess-r-mode))
+
+\f
+;;;*;;; Project detection
+
+(defvar-local ess-r-project--info-cache nil
+  "Current package info cache.
+See `ess-r-project-info' for its structure.")
+
+(defun ess-r-project (&optional dir)
+  "Return the current project as an Emacs project instance.
+R project is a directory XYZ containing either .Rprofile,
+DESCRIPTION or XYZ.Rproj file. Return a list of the form (:name
+\"XYZ\" :root \"/path/to/project\"). If DIR is provided, the
+project is searched from that directory instead of
+`default-directory'."
+  (let ((info (ess-r-project-info dir)))
+    (when (car info)
+      (cons 'ess-r-project (plist-get info :root)))))
+
+;; FIXME: remove when emacs 27 is dropped
+(unless (eval-when-compile
+          (get 'project-roots 'byte-obsolete-info))
+  (cl-defmethod project-roots ((project (head ess-r-project)))
+    "Return the project root for ESS R projects."
+    (list (cdr project))))
+
+(cl-defmethod project-root ((project (head ess-r-project)))
+  "Return the project root for ESS R projects."
+  (cdr project))
+
+(defun ess-r-project-info (&optional dir)
+  "Get the description of the R project in directory DIR.
+Return an plist with the keys :name and :root. When not in a
+project return \\='(nil). This value is cached buffer-locally for
+efficiency reasons."
+  (let ((do-cache (null dir)))
+    (if (and do-cache ess-r-project--info-cache)
+        ess-r-project--info-cache
+      (setq dir (or dir (buffer-file-name) default-directory))
+      (let ((out (or
+                  (unless (file-remote-p dir)
+                    (let ((dir (locate-dominating-file
+                                dir
+                                (lambda (dir)
+                                  (or (file-exists-p (expand-file-name ".Rprofile" dir))
+                                      (file-exists-p (expand-file-name "DESCRIPTION" dir))
+                                      (let ((nm (file-name-nondirectory (directory-file-name dir))))
+                                        (file-exists-p (expand-file-name (concat nm ".Rproj") dir))))))))
+                      (when dir
+                        (let ((dir (directory-file-name dir)))
+                          (unless (member dir (list "~" (getenv "HOME")))
+                            (list :name (file-name-nondirectory dir)
+                                  :root (expand-file-name dir)))))))
+                  '())))
+        (when do-cache
+          (setq ess-r-project--info-cache out))
+        out))))
+
+
+\f
+;;*;; Miscellaneous
+
+(defun ess-R-arch-2-bit (arch)
+  "Translate R's architecture shortcuts/directory names to `bits'.
+ARCH \"32\" or \"64\" (for now)."
+  (if (string= arch "i386")  "32"
+    ;; else:
+    "64"))
+
+(defun ess-rterm-arch-version (long-path &optional give-cons)
+  "Find a name for LONG-PATH, an absolute path to R on Windows.
+Returns either Name, a string, or a (Name . Path) cons, such as
+
+(\"R-2.12.1-64bit\"  .  \"C:/Program Files/R/R-2.12.1/bin/x64/Rterm.exe\")
+
+\"R-x.y.z/bin/Rterm.exe\" will return \"R-x.y.z\", for R-2.11.x and older.
+\"R-x.y.z/bin/i386/Rterm.exe\" return \"R-x.y.z-32bit\", for R-2.12.x and newer.
+\"R-x.y.z/bin/x64/Rterm.exe\"  return \"R-x.y.z-64bit\", for R-2.12.x and newer."
+  (let* ((dir  (directory-file-name (file-name-directory long-path)))
+         (dir2 (directory-file-name (file-name-directory dir)))
+         (v-1up (file-name-nondirectory dir));; one level up
+         (v-2up (file-name-nondirectory dir2));; two levels up; don't want "bin" ...
+         (v-3up (file-name-nondirectory ;; three levels up; no "bin" for i386, x64 ...
+                 (directory-file-name (file-name-directory dir2))))
+         (val (if (string= v-2up "bin")
+                  (concat v-3up "-" (ess-R-arch-2-bit v-1up) "bit")
+                ;; pre R-2.12.x, or when there's no extra arch-specific sub directory:
+                v-2up)))
+    (if give-cons
+        (cons val long-path)
+      val)))
+
+(defun ess-r-define-runners (&optional verbose)
+  "Generate functions for starting other versions of R.
+See `ess-r-runner-prefixes' for strings that determine which functions
+are created.  On MS Windows, this works using
+`ess-rterm-version-paths' instead.
+
+The functions will normally be placed on the menubar and stored
+as `ess-r-created-runners' upon ESS initialization."
+  (when ess-r-runner-prefixes
+    (let ((versions
+           ;; Find which versions of R we want.  Remove the pathname, leaving just
+           ;; the name of the executable.
+           (if ess-microsoft-p
+               (mapcar (lambda (v) (car (ess-rterm-arch-version v 'give-cons)))
+                       ess-rterm-version-paths)
+             (delete-dups
+              (mapcar #'file-name-nondirectory
+                      (apply #'nconc
+                             (mapcar #'ess-find-exec-completions
+                                     ess-r-runner-prefixes)))))))
+      ;; Iterate over each string in VERSIONS, creating a new defun each time.
+      (setq ess-r-created-runners versions)
+      (if verbose
+        (message "Recreated %d R versions known to ESS: %s"
+                 (length versions) versions))
+      (if ess-microsoft-p
+          (cl-mapc (lambda (v p) (ess-define-runner v "R" p)) versions ess-rterm-version-paths)
+        (mapc (lambda (v) (ess-define-runner v "R")) versions))
+      ;; Add to menu
+      (when ess-r-created-runners
+        ;; new-menu will be a list of 3-vectors, of the form:
+        ;; ["R-1.8.1" R-1.8.1 t]
+        (let ((new-menu (mapcar (lambda(x) (vector x (intern x) t))
+                                ess-r-created-runners)))
+          (easy-menu-add-item ess-mode-menu '("Start Process")
+                              (cons "Other" new-menu))
+          (easy-menu-add-item inferior-ess-mode-menu '("Process")
+                              (cons "R processes" new-menu)))))))
+
+(defun ess-r-redefine-runners (&optional verbose)
+  "Regenerate runners, i.e. `M-x R-*` possibilities.
+ Call `fmakunbound' on all elements of `ess-r-created-runners',
+ then define new runners."
+  (interactive "P")
+  (dolist (f ess-r-created-runners)
+    (fmakunbound (intern f)))
+  (setq ess-r-created-runners nil)
+  (ess-r-define-runners verbose))
+
+(defun ess-r-runners-reset (sym val)
+  "Regenerate runners.
+Set SYM to VAL and call `ess-r-redefine-runners'."
+  (set-default sym val)
+  (ess-r-redefine-runners))
+
+(define-obsolete-function-alias
+  'ess-r-versions-create #'ess-r-define-runners "ESS 18.10")
+
+(defvar ess-newest-R nil
+  "Stores the newest version of R that has been found.
+Used as a cache, within `ess-find-newest-R'. Do not use this value
+directly, but instead call the function \\[ess-find-newest-R].")
+
+
+(defcustom ess-prefer-higher-bit t
+  "Non-nil means prefer higher bit architectures of R.
+e.g. prefer 64 bit over 32 bit.  This is currently used only
+by the code on Windows for finding the newest version of R."
+  :group 'ess-R
+  :type 'boolean)
+
+(defun ess-rterm-prefer-higher-bit ()
+  "Optionally remove 32bit Rterms from being candidate for `run-ess-r-newest'.
+Return the list of candidates for being `run-ess-r-newest'. Filtering is
+done iff `ess-prefer-higher-bit' is non-nil. This is used only by
+Windows when running `ess-find-newest-R'."
+  (if ess-prefer-higher-bit
+      ;; filter out 32 bit elements
+      (let ((filtered
+             (delq nil
+                   (mapcar (lambda (x) (unless (string-match "/i386/Rterm.exe" x) x))
+                           ess-rterm-version-paths))))
+        (if (null filtered)
+            ;; if none survived filtering, keep the original list
+            ess-rterm-version-paths
+          filtered))
+    ess-rterm-version-paths))
+
+(defun run-ess-r-newest (&optional start-args)
+  "Find the newest version of R available, and run it.
+Subsequent calls to `run-ess-r-newest' will run that version,
+rather than searching again for the newest version. Providing
+START-ARGS (interactively, with \\[universal-argument]) will
+prompt for command line arguments."
+  (interactive "P")
+  (unless ess-newest-R
+    (message "Finding all versions of R on your system...")
+    (setq ess-newest-R
+          (ess-find-newest-date
+           (mapcar #'ess-r-version-date
+                   (if ess-microsoft-p
+                       (ess-rterm-prefer-higher-bit)
+                     (add-to-list 'ess-r-created-runners inferior-ess-r-program))))))
+  (let ((inferior-ess-r-program ess-newest-R))
+    (run-ess-r start-args)))
+
+(defun R-newest (&optional start-args)
+  (interactive "P")
+  ;; FIXME: Current ob-R expects current buffer set to process buffer
+  (set-buffer (run-ess-r-newest start-args)))
+
+;; (ess-r-version-date "R-2.5.1") (ess-r-version-date "R-patched")
+;; (ess-r-version-date "R-1.2.1") (ess-r-version-date "R-1.8.1")
+;; Windows:
+;;  (ess-r-version-date "C:/Program Files (x86)/R/R-2.11.1/bin/Rterm.exe")
+;; Note that for R-devel, ver-string is something like
+;; R version 2.6.0 Under development (unstable) (2007-07-14 r42234)
+;; Antique examples are 'R 1.0.1  (April 14, 2000)' or 'R 1.5.1 (2002-06-17).'
+(defun ess-r-version-date (rver)
+  "Return the date of the version of R named RVER.
+The date is returned as a date string.  If the version of R could
+not be found from the output of the RVER program, \"-1\" is
+returned."
+  (let ((date "-1")
+        (ver-string (shell-command-to-string
+                     ;; here, MS Windows (shell-command) needs a short name:
+                     (concat (if (and ess-microsoft-p
+                                      ;; silence byte compiler warns about w32-fns
+                                      (fboundp 'w32-short-file-name))
+                                 (w32-short-file-name rver)
+                               rver)
+                             " --version"))))
+    (when (string-match
+           "R \\(version \\)?[1-9][^\n]+ (\\(2[0-9-]+\\)\\( r[0-9]+\\)?"
+           ver-string)
+      (setq date (match-string 2 ver-string)))
+    (cons date rver)))
+
+(defun ess-current-R-version ()
+  "Get the version of R currently running in the ESS buffer as a string."
+  (ess-make-buffer-current)
+  (car (ess-get-words-from-vector (format "base::as.character(%s)\n"
+                                          (ess-r--format-call ".ess.Rversion")))))
+
+(defun ess-current-R-at-least (version)
+  "Is the version of R (in the ESS buffer) at least (\">=\") VERSION ?
+Examples: (ess-current-R-at-least '2.7.0)
+      or  (ess-current-R-at-least \"2.5.1\")"
+  (ess-make-buffer-current)
+  (string= "TRUE"
+           (car (ess-get-words-from-vector
+                 (format "base::as.character(%s >= \"%s\")\n"
+                         (ess-r--format-call ".ess.Rversion")
+                         version)))))
+(defun ess-find-newest-date (rvers)
+  "Find the newest version of R given in the a-list RVERS.
+Each element of RVERS is a dotted pair (date . R-version), where
+date is given as e.g.\"2007-11-30\" so that we can compare dates
+as strings.  If a date is listed as \"-1\", that version of R
+could not be found.
+
+If the value returned is nil, no valid newest version of R could be found."
+  (let (new-r this-r
+              (new-time "0"))
+    (while rvers
+      (setq this-r (car rvers)
+            rvers (cdr rvers))
+      (when (string< new-time (car this-r))
+        (setq new-time (car this-r)
+              new-r    (cdr this-r))))
+    new-r))
+
+(defun ess-find-rterm (&optional ess-R-root-dir bin-Rterm-exe)
+  "Find the full path of all occurrences of Rterm.exe under the ESS-R-ROOT-DIR.
+If ESS-R-ROOT-DIR is nil, construct it by looking for an
+occurrence of Rterm.exe in the `exec-path'. If there are no
+occurrences of Rterm.exe in the `exec-path', then use
+`ess-program-files' (which evaluates to something like
+\"c:/progra~1/R/\" in English locales) which is the default
+location for the R distribution. If BIN-RTERM-EXE is nil, then
+use \"bin/Rterm.exe\"."
+  (if (not ess-R-root-dir)
+      (let ((Rpath (executable-find "Rterm")))
+        (setq ess-R-root-dir
+              (expand-file-name
+               (if Rpath
+                   (concat (file-name-directory Rpath) "../../")
+                 (concat ess-program-files "/R/"))))
+        (ess-write-to-dribble-buffer
+         (format "(ess-find-rterm): ess-R-root-dir = '%s'\n" ess-R-root-dir))))
+
+  (if (not bin-Rterm-exe) (setq bin-Rterm-exe "bin/Rterm.exe"))
+
+  (when (file-directory-p ess-R-root-dir) ; otherwise file-name-all-.. errors
+    (setq ess-R-root-dir
+          (replace-regexp-in-string "[\\]" "/" ess-R-root-dir))
+    (let ((R-ver
+           (ess-drop-non-directories
+            (ess-flatten-list
+             (mapcar (lambda (r-prefix)
+                       (file-name-all-completions r-prefix ess-R-root-dir))
+                     (append '("rw") ess-r-runner-prefixes))))))
+      (mapcar (lambda (dir)
+                (let ((R-path
+                       (concat ess-R-root-dir
+                               (replace-regexp-in-string "[\\]" "/" dir)
+                               bin-Rterm-exe)))
+                  (if (file-exists-p R-path) R-path)))
+              R-ver))))
+
+;;;###autoload
+(define-derived-mode ess-r-transcript-mode ess-transcript-mode "ESS R Transcript"
+  "A Major mode for R transcript files."
+  :syntax-table ess-r-mode-syntax-table
+  :group 'ess
+  (ess-setq-vars-local ess-r-customize-alist)
+  (setq-local comint-prompt-regexp inferior-S-prompt)
+  (setq-local ess-font-lock-keywords 'ess-R-font-lock-keywords)
+  (setq-local paragraph-start (concat "\\s-*$\\|" page-delimiter))
+  (setq-local paragraph-separate (concat "\\s-*$\\|" page-delimiter))
+  (setq-local paragraph-ignore-fill-prefix t)
+  (setq-local indent-line-function #'ess-r-indent-line)
+  (setq-local add-log-current-defun-header-regexp "^\\(.+\\)\\s-+<-[ \t\n]*function")
+  (setq-local font-lock-syntactic-face-function #'ess-r-font-lock-syntactic-face-function)
+  (setq-local prettify-symbols-alist ess-r-prettify-symbols)
+  (setq font-lock-defaults '(ess-build-font-lock-keywords
+                             nil nil ((?\. . "w") (?\_ . "w") (?' . ".")))))
+
+(defalias 'r-transcript-mode #'ess-r-transcript-mode)
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.[Rr]out\\'" . ess-r-transcript-mode))
+;;;###autoload
+(add-to-list 'interpreter-mode-alist '("Rscript" . ess-r-mode))
+;;;###autoload
+(add-to-list 'interpreter-mode-alist '("r" . ess-r-mode))
+
+(defun ess-r-fix-T-F (&optional from quietly)
+  "Change T/F into TRUE and FALSE cautiously.
+Do not change in comments and strings. Start at FROM, which
+defaults to point, and change to end of buffer. When QUIETLY, do
+not issue messages."
+  (interactive "d\nP"); point and prefix (C-u)
+  (save-excursion
+    (goto-char from)
+    (ess-rep-regexp "\\(\\([][=,()]\\|<-\\) *\\)T\\>" "\\1TRUE"
+                    'fixcase nil (not quietly))
+    (goto-char from)
+    (ess-rep-regexp "\\(\\([][=,()]\\|<-\\) *\\)F\\>" "\\1FALSE"
+                    'fixcase nil (not quietly))))
+(define-obsolete-function-alias 'R-fix-T-F #'ess-r-fix-T-F
+  "ESS 18.10")
+
+(defvar ess--packages-cache nil
+  "Cache var to store package names.
+Used by `ess-r-install-library'.")
+
+(defvar ess--CRAN-mirror nil
+  "CRAN mirror name cache.")
+
+(cl-defmethod ess-install-library--override (update package &context (ess-dialect "R"))
+  "Prompt and install R PACKAGE.
+With argument UPDATE, update cached packages list."
+  (inferior-ess-r-force)
+  (when (equal "@CRAN@" (car (ess-get-words-from-vector "getOption('repos')[['CRAN']]\n")))
+    (ess-set-CRAN-mirror ess--CRAN-mirror)
+    (ess-wait-for-process (get-process ess-current-process-name))
+    (unless package (setq update t)))
+  (when (or update
+            (not ess--packages-cache))
+    (message "Fetching R packages ... ")
+    (setq ess--packages-cache
+          (ess-get-words-from-vector--foreground "print(rownames(available.packages()), max=1e6)\n")))
+  (let* ((ess-eval-visibly-p t)
+         (package (or package
+                      (ess-completing-read "Package to install" ess--packages-cache))))
+    (process-send-string (get-process ess-current-process-name)
+                         (format "install.packages('%s')\n" package))
+    (display-buffer (buffer-name (ess-get-process-buffer)))))
+
+(defun ess-setRepositories ()
+  "Call setRepositories()."
+  (interactive)
+  (if (not (string-match "^R" ess-dialect))
+      (message "Sorry, not available for %s" ess-dialect)
+    (ess-eval-linewise "setRepositories(FALSE)\n")))
+
+(defun ess-set-CRAN-mirror (&optional mirror)
+  "Set cran MIRROR."
+  (interactive)
+  (let ((mirror-cmd "local({r <- getOption('repos'); r['CRAN'] <- '%s';options(repos=r)})\n"))
+    (if mirror
+        (ess-command (format mirror-cmd mirror))
+      (when-let ((M1 (ess-get-words-from-vector "local({out <- getCRANmirrors(local.only=TRUE); print(paste(out$Name,'[',out$URL,']', sep=''))})\n"))
+                 (mirror (ess-completing-read "Choose CRAN mirror" M1 nil t))
+                 (url (car (cl-member mirror M1 :test #'string=))))
+        (setq ess--CRAN-mirror (progn (string-match "\\(.*\\)\\[\\(.*\\)\\]$" url)
+                                      (match-string 2 url)))
+        (ess-command (format mirror-cmd ess--CRAN-mirror)))))
+  (message "CRAN mirror: %s" (car (ess-get-words-from-vector "getOption('repos')[['CRAN']]\n"))))
+(define-obsolete-function-alias 'ess-setCRANMiror #'ess-set-CRAN-mirror "ESS 18.10")
+
+(defun ess-r-check-install-package (pkg)
+  "Check if package PKG is installed and offer to install if not."
+  (unless (ess-boolean-command (format "print(requireNamespace('%s', quietly = TRUE))\n" pkg))
+    (if (y-or-n-p (format "Package '%s' is not installed. Install? " pkg))
+        (ess-eval-linewise (format "install.packages('%s')\n" pkg))
+      (signal 'quit nil))))
+
+(define-obsolete-function-alias 'ess-r-sos #'ess-help-web-search "ESS 19.04")
+
+(cl-defmethod ess--help-web-search-override (cmd &context (ess-dialect "R"))
+  (ess-r-check-install-package "sos")
+  (ess-eval-linewise (format "sos::findFn(\"%s\", maxPages=10)" cmd)))
+
+
+(defun ess-R-scan-for-library-call (string)
+  "Detect `library/require' call in STRING and update tracking vars.
+Placed into `ess-presend-filter-functions' for R dialects."
+  (when (string-match-p "\\blibrary(\\|\\brequire(" string)
+    (ess--mark-search-list-as-changed))
+  string)
+
+(cl-defmethod ess-installed-packages (&context (ess-dialect "R"))
+  ;;; FIXME? .packages() does not cache; installed.packages() does but is slower first time
+  (ess-get-words-from-vector--foreground "print(.packages(TRUE), max=1e6)\n"))
+
+(cl-defmethod ess-load-library--override (pack &context (ess-dialect "R"))
+  "Load an R package."
+  (ess-eval-linewise (format "library('%s')\n" pack)))
+
+(define-obsolete-function-alias 'ess-library #'ess-load-library "ESS[12.09-1]")
+
+;;; smart-comma was a bad idea
+(eval-after-load "eldoc"
+  '(eldoc-add-command "ess-smart-comma"))
+
+\f
+;;*;; Interaction with R
+
+;;;*;;; Evaluation
+
+(defun ess-r-arg (param value &optional wrap)
+  (let ((value (if wrap
+                   (concat "'" value "'")
+                 value)))
+    (concat ", " param " = " value)))
+
+(defun ess-r-build-args (visibly output namespace)
+  (let ((visibly (ess-r-arg "visibly" (if visibly "TRUE" "FALSE")))
+        (output (ess-r-arg "output" (if output "TRUE" "FALSE")))
+        (pkg (when namespace (ess-r-arg "package" namespace t)))
+        (verbose (when (and namespace
+                            ess-r-namespaced-load-verbose)
+                   (ess-r-arg "verbose" "TRUE"))))
+    (concat visibly output pkg verbose)))
+
+(defun ess-r--format-call (cmd &rest objects)
+  "Prefix an ESSR command with a namespace qualifier.
+CMD is formatted with OBJECTS using `format'."
+  (concat "base::as.environment('ESSR')$"
+          (apply #'format cmd objects)))
+
+(cl-defmethod ess-build-eval-command--override (string &context (ess-dialect "R")
+                                                       &optional visibly output file &rest args)
+  "R method to build eval command."
+  (let* ((namespace (caar args))
+         (namespace (unless ess-debug-minor-mode
+                      (or namespace (ess-r-get-evaluation-env))))
+         (cmd (ess-r--format-call (if namespace ".ess.ns_eval" ".ess.eval")))
+         (file (when file (ess-r-arg "file" file t)))
+         (rargs (ess-r-build-args visibly output namespace)))
+    (concat cmd "(\"" string "\"" rargs file ")\n")))
+
+(cl-defmethod ess-build-load-command (string &context (ess-dialect "R")
+                                             &optional visibly output file &rest _args)
+  (let* ((namespace (or file (ess-r-get-evaluation-env)))
+         (cmd (ess-r--format-call (if namespace ".ess.ns_source" ".ess.source")))
+         (rargs (ess-r-build-args visibly output namespace)))
+    (concat cmd "('" string "'" rargs ")\n")))
+
+(defun ess-r-build-eval-message (message)
+  (let ((env (cond (ess-debug-minor-mode
+                    (substring-no-properties ess-debug-indicator 1))
+                   ((ess-r-get-evaluation-env)))))
+    (if env
+        (format "[%s] %s" env message)
+      message)))
+
+(defvar-local ess-r-evaluation-env nil
+  "Environment into which code should be evaluated.
+When this variable is nil, code is evaluated in the current
+environment. Currently only packages can be set as evaluation
+environments. Use `ess-r-set-evaluation-env' to set this
+variable.")
+
+(defun ess-r-get-evaluation-env ()
+  "Get current evaluation env."
+  ess-r-evaluation-env)
+
+(defun ess-r-set-evaluation-env (&optional arg)
+  "Select a package namespace for evaluation of R code.
+
+Call interactively with a prefix argument to disable evaluation
+in a namespace.  When calling from a function, ARG can be a
+string giving the package to select, any other non-nil value to
+disable, or nil to prompt for a package.
+
+If `ess-r-prompt-for-attached-pkgs-only' is non-nil, prompt only for
+attached packages."
+  (interactive "P")
+  (let ((env (cond ((stringp arg) arg)
+                   ((null arg) (ess-r--select-package-name))
+                   (t "*none*"))))
+    (if (equal env "*none*")
+        (let ((cur-env (ess-r-get-evaluation-env)))
+          (setq ess-r-evaluation-env nil)
+          (delq 'ess-r--evaluation-env-mode-line ess--local-mode-line-process-indicator)
+          (message (format "Evaluation in %s disabled" (propertize cur-env 'face font-lock-function-name-face))))
+      (setq ess-r-evaluation-env env)
+      (add-to-list 'ess--local-mode-line-process-indicator 'ess-r--evaluation-env-mode-line t)
+      (message (format "Evaluating in %s" (propertize env 'face font-lock-function-name-face))))
+    (force-mode-line-update)))
+
+(defvar-local ess-r--evaluation-env-mode-line
+  '(:eval (let ((env (ess-r-get-evaluation-env)))
+            (if env
+                (format " %s"
+                        (propertize  (if (equal env (ess-r-package-name))
+                                         "pkg"
+                                       env)
+                                     'face 'mode-line-emphasis))
+              ""))))
+(put 'ess-r--evaluation-env-mode-line 'risky-local-variable t)
+
+(defvar ess-r-namespaced-load-only-existing t
+  "Whether to load only objects already existing in a namespace.")
+
+(cl-defmethod ess-load-file--override (file &context (ess-dialect "R"))
+  (cond
+   ;; Namespaced evaluation
+   ((ess-r-get-evaluation-env)
+    (ess-r-load-file-namespaced file))
+   ;; Evaluation into current env via .ess.source()
+   (t
+    (let ((command (ess-build-load-command file nil t)))
+      (ess-send-string (ess-get-process) command)))))
+
+(defun ess-r-load-file-namespaced (&optional file)
+  "Load FILE into a package namespace.
+
+This prompts for a package when no package is currently
+selected (see `ess-r-set-evaluation-env')."
+  (ess-force-buffer-current "R process to use: ")
+  (let* ((pkg-name (ess-r-get-evaluation-env))
+         (command (ess-build-load-command file nil t pkg-name)))
+    (ess-send-string (ess-get-process) command)))
+
+(cl-defmethod ess-send-region--override (process start end visibly message type
+                                                 &context (ess-dialect "R"))
+  (cond
+   ;; Namespaced evaluation
+   ((ess-r-get-evaluation-env)
+    (ess-r-send-region-namespaced process start end visibly message))
+   ;; Evaluation into current env
+   (t
+    (ess-send-string process (buffer-substring start end) visibly message type))))
+
+(defun ess-r-send-region-namespaced (proc start end &optional visibly message)
+  "Ask for for the package and devSource region into it."
+  (or (ess-r-get-evaluation-env)
+      (ess-r-set-evaluation-env))
+  (message (ess-r-build-eval-message (or message "Eval region")))
+  (ess-send-string proc (buffer-substring start end) visibly message))
+
+
+;;;*;;; Help
+
+(cl-defmethod ess-build-help-command (object &context (ess-dialect "R"))
+  (let ((info (ess-r--split-namespace object)))
+    (if info
+        (ess-r-help--build-help-command--qualified (car info) (cdr info))
+      (ess-r-help--build-help-command--unqualified object))))
+
+(defun ess-r--split-namespace (sym)
+  (when (string-match "^[[:alnum:].]+::" sym)
+      (let ((pkg (substring-no-properties sym (match-beginning 0) (- (match-end 0) 2)))
+            (obj (substring-no-properties sym (match-end 0))))
+        (cons pkg obj))))
+
+(defvar-local ess-r-help--local-object nil)
+(defvar-local ess-r-help--local-package nil)
+(put 'ess-r-help--local-object 'permanent-local t)
+(put 'ess-r-help--local-package 'permanent-local t)
+
+(defun ess-r-help--build-help-command--qualified (pkg obj)
+  (setq ess-r-help--local-package pkg)
+  (setq ess-r-help--local-object obj)
+  (let ((obj-arg (concat "'" obj "'"))
+        (pkg-arg (ess-r-arg "package" pkg t)))
+    (ess-r--format-call ".ess.help(%s%s)\n" obj-arg pkg-arg)))
+
+(defun ess-r-help--build-help-command--unqualified (obj)
+  (if (eq ess-help-type 'index)
+      ;; We are in index page, qualify with namespace
+      (ess-r-help--build-help-command--qualified ess-help-object obj)
+    (let ((pkg (ess-r-help--find-package obj)))
+      (unless pkg
+        (error "Can't find documentation for `%s'" obj))
+      (ess-r-help--build-help-command--qualified pkg obj))))
+
+(defun ess-r-help--find-package (object)
+  "Find package where to find OBJECT.
+If there are multiple packages attached to the search path, the
+user is prompted for a package location. If OBJECT is not
+documented, returns nil."
+  (let* ((paths (ess-get-words-from-vector
+                 (format "as.character(utils::help('%s'))\n" object)))
+         (paths (if (> (length paths) 1)
+                    (cl-delete-if
+                     (lambda (x) (string-match-p "reexports$" x))
+                     paths)
+                  paths)))
+    (cond ((not paths)
+           nil)
+          ((and (> (length paths) 1)
+                (not noninteractive))
+           (let ((path (ess-completing-read "Choose location" paths nil t)))
+             (ess-r-help--get-pkg-from-help-path path)))
+          (t
+           (ess-r-help--get-pkg-from-help-path (car paths))))))
+
+(defun ess-r-help--get-pkg-from-help-path (path)
+  (file-name-nondirectory
+   (directory-file-name
+    (file-name-directory
+     (directory-file-name
+      (file-name-directory
+       path))))))
+
+(defconst inferior-ess-r--input-help (format "^ *help *(%s)" ess-help-arg-regexp))
+(defconst inferior-ess-r--input-?-help-regexp "^ *\\(?:\\(?1:[a-zA-Z ]*?\\?\\{1,2\\}\\) *\\(?2:.+\\)\\)")
+(defconst inferior-ess-r--page-regexp (format "^ *page *(%s)" ess-help-arg-regexp))
+
+(defun ess-help-r--process-help-input (proc string)
+  (let ((help-match (and (string-match inferior-ess-r--input-help string)
+                         (match-string 2 string)))
+        (help-?-match (and (string-match inferior-ess-r--input-?-help-regexp string)
+                           string))
+        (page-match   (and (string-match inferior-ess-r--page-regexp string)
+                           (match-string 2 string))))
+    (when (or help-match help-?-match page-match)
+      (cond (help-match
+             (ess-display-help-on-object help-match)
+             (process-send-string proc "\n"))
+            (help-?-match
+             (ess-help-r--display-help-? string help-?-match)
+             (process-send-string proc "\n"))
+            (page-match
+             (switch-to-buffer-other-window
+              (ess-command (concat page-match "\n")
+                           (get-buffer-create (concat page-match ".rt"))))
+             (ess-r-transcript-mode)
+             (process-send-string proc "\n")))
+      t)))
+
+(defun ess-help-r--display-help-? (string help-?-match)
+  (cond ((string-match "\\?\\?\\(.+\\)" help-?-match)
+         (ess--display-indexed-help-page (concat help-?-match "\n")
+                                         "^\\([^ \t\n]+::[^ \t\n]+\\)[ \t\n]+"
+                                         (format "*ess-apropos[%s](%s)*"
+                                                 ess-current-process-name (match-string 1 help-?-match))
+                                         'apropos))
+        ((string-match "^ *\\? *\\([^ \t]+\\)$" help-?-match)
+         (ess-display-help-on-object (match-string 1 help-?-match)))
+        ;; Anything else we send to process almost unchanged
+        (t
+         (let ((help-?-match (and (string-match inferior-ess-r--input-?-help-regexp string)
+                                  (format "%s%s" (match-string 1 string)
+                                          (ess-help-r--sanitize-topic (match-string 2 string))))))
+           (ess-display-help-on-object help-?-match "%s\n")))))
+
+(defun ess-help-r--sanitize-topic (string)
+  "Enclose help topic STRING into `` to avoid ?while ?if etc hangs."
+  (if (string-match "\\([^:]*:+\\)\\(.*\\)$" string) ; treat foo::bar correctly
+      (format "%s`%s`" (match-string 1 string) (match-string 2 string))
+    (format "`%s`" string)))
+
+
+;;;*;;; Utils for inferior R process
+
+(defun inferior-ess-r-input-sender (proc string)
+  (save-current-buffer
+    (or (ess-help-r--process-help-input proc string)
+        (inferior-ess-input-sender proc string))))
+
+(defun ess-r-load-ESSR ()
+  "Load ESSR functionality into ESSR environment.
+On remotes, when `ess-r-fetch-ESSR-on-remotes' is non-nil we
+fetch ESSR environment from github to the remote machine.
+Otherwise (the default) we source ESSR files into the remote
+process."
+  (interactive)
+  ;; `.ess.command()` is not defined until ESSR is loaded so disable
+  ;; it temporarily. Would be helpful to implement an `inferior-ess-let'
+  ;; macro .
+  (cond
+   ((file-remote-p (ess-get-process-variable 'default-directory))
+    (if (eq ess-r-fetch-ESSR-on-remotes t)
+        (or (ess-r--fetch-ESSR-remote)
+            (ess-r--load-ESSR-remote))
+      (ess-r--load-ESSR-remote)))
+   ((and (bound-and-true-p ess-remote))
+    ;; NB: With ess-remote we send by chunks because sending large sources is
+    ;; fragile
+    (if ess-r-fetch-ESSR-on-remotes
+        (or (ess-r--fetch-ESSR-remote)
+            (ess-r--load-ESSR-remote t))
+      (ess-r--load-ESSR-remote t)))
+   (t (ess-r--load-ESSR-local))))
+
+(defun ess-r--load-ESSR-local ()
+  "Load ESSR into a local process.
+Source the etc/ESSR/.load.R file into the R process. The
+.ess.ESSR.load function sources all of the contents of the
+etc/ESSR/R directory into the ESSR environment and attaches the
+environment to the search path."
+  (let* ((src-dir (expand-file-name "ESSR/R" ess-etc-directory))
+         (buf (ess-command (ess-r--load-ESSR-command src-dir))))
+    (with-current-buffer buf
+      (let ((msg (buffer-string)))
+        (when (> (length msg) 1)
+          (message (format "Messages while loading ESSR: %s" msg)))))))
+
+(defun ess-r--load-ESSR-command (src-dir)
+  (format "base::tryCatch(
+             base::local({
+               base::source('%s/.load.R', local=TRUE) #define load.ESSR
+               .ess.ESSR.load('%s')
+             }),
+             error = function(cnd) {
+               msg <- paste0('\1e\1eESSR::ERROR \"', conditionMessage(cnd), '\"\1e\1e')
+               writeLines(msg)
+             }
+           )\n"
+          src-dir
+          src-dir))
+
+(defun ess-r--load-ESSR-remote (&optional chunked)
+  "Load ESSR into a remote process through the process connection.
+Send the contents of the etc/ESSR/R directory to the remote
+process through the process connection file by file. Then,
+collect all the objects into an ESSR environment and attach to
+the search path. If CHUNKED is non-nil, split each file by \\^L
+separators and send chunk by chunk."
+  (ess-command (format ".ess.ESSRversion <<- '%s'\n" essr-version))
+  (with-temp-message "Loading ESSR into remote ..."
+    (let ((src-dir (expand-file-name "ESSR/R" ess-etc-directory)))
+      (dolist (file (directory-files src-dir t "\\.R\\'"))
+        (ess--inject-code-from-file file chunked))
+      (ess-command ".ess.collect.ESSR.objects()\n"))))
+
+(defun ess-r--fetch-ESSR-remote ()
+  "Load ESSR into a remote process through a GitHub download.
+Downloads a file with a serialized version of the R ESSR
+environment from GitHub and attaches it to the search path. If
+the file already exists on disk from a previous download then the
+download step is omitted. This function returns t if the ESSR
+load is successful, and nil otherwise."
+  (let ((loader (ess-file-content (expand-file-name "ESSR/LOADREMOTE" ess-etc-directory)))
+        (essr (or essr-version
+                  ;; FIXME: Hack: on MELPA essr-version is not set
+                  (lm-with-file (expand-file-name "ess.el" ess-lisp-directory)
+                    (lm-header "ESSR-Version"))
+                  (error "`essr-version' could not be automatically inferred from ess.el file"))))
+    (or (with-temp-message "Fetching and loading ESSR into the remote ..."
+          (ess-boolean-command (format loader essr)))
+        (let ((errmsg (with-current-buffer " *ess-command-output*" (buffer-string))))
+          (message (format "Couldn't load or download ESSR.rds on the remote.\n Error: %s\n Injecting local copy of ESSR." errmsg))
+          nil))))
+
+(cl-defmethod ess-quit--override (arg &context (ess-dialect "R"))
+  "With ARG, do not offer to save the workspace."
+  (let ((cmd (format "base::q('%s')\n" (if arg "no" "default")))
+        (sprocess (ess-get-process ess-current-process-name)))
+    (when (not sprocess) (error "No ESS process running"))
+    (ess-cleanup)
+    (ess-send-string sprocess cmd)))
+
+(defcustom inferior-ess-r-reload-hook nil
+  "Hook run when reloading the R inferior buffer."
+  :type 'hook
+  :group 'ess-R)
+
+(cl-defmethod inferior-ess-reload--override (start-name start-args &context (ess-dialect "R"))
+  "Call `run-ess-r' with START-ARGS.
+Then run `inferior-ess-r-reload-hook'."
+  (let ((inferior-ess-r-program start-name))
+    (run-ess-r start-args))
+  (run-hooks 'inferior-ess-r-reload-hook))
+
+(defun inferior-ess-r-force (&optional prompt force no-autostart ask-if-1)
+  (setq-local ess-dialect "R")
+  (ess-force-buffer-current prompt force no-autostart ask-if-1))
+
+\f
+;;*;; Editing Tools
+
+;;;*;;; Indentation Engine
+
+;; Written by Lionel Henry in mid 2015
+
+(defun ess-r-indent-line ()
+  "Indent current line as ESS R code.
+Return the amount the indentation changed by."
+  (when-let ((indent (ess-calculate-indent)))
+    (let ((case-fold-search nil)
+          (pos (- (point-max) (point)))
+          beg shift-amt)
+      (beginning-of-line)
+      (setq beg (point))
+      (skip-chars-forward " \t")
+      (setq shift-amt (- indent (current-column)))
+      (if (zerop shift-amt)
+          (if (> (- (point-max) pos) (point))
+              (goto-char (- (point-max) pos)))
+        (delete-region beg (point))
+        (indent-to indent)
+        ;; If initial point was within line's indentation,
+        ;; position after the indentation.
+        ;; Else stay at same point in text.
+        (when (> (- (point-max) pos) (point))
+          (goto-char (- (point-max) pos))))
+      shift-amt)))
+
+(defun ess-r-indent-exp ()
+  (save-excursion
+    (when current-prefix-arg
+      (ess-climb-to-top-level))
+    (let* ((bounds (ess-continuations-bounds))
+           (end (cadr bounds))
+           (beg (if current-prefix-arg
+                    (car bounds)
+                  (forward-line)
+                  (point))))
+      (indent-region beg end))))
+
+(defun ess-indent-call (&optional start)
+  (save-excursion
+    (when (ess-escape-calls)
+      (setq start (or start (point)))
+      (skip-chars-forward "^[(")
+      (forward-char)
+      (ess-up-list)
+      (indent-region start (point)))))
+
+(defun ess-offset (offset)
+  (setq offset
+        (symbol-value (intern (concat "ess-offset-" (symbol-name offset)))))
+  (when (and (not (eq offset nil))
+             (listp offset)
+             (or (numberp (cadr offset))
+                 (eq (cadr offset) t)
+                 (error "Malformed offset")))
+    (setq offset (cadr offset)))
+  (cond ((numberp offset)
+         offset)
+        ((null offset)
+         0)
+        (t
+         ess-indent-offset)))
+
+(defun ess-offset-type (offset)
+  (setq offset
+        (symbol-value (intern (concat "ess-offset-" (symbol-name offset)))))
+  (if (listp offset)
+      (car offset)
+    offset))
+
+(defun ess-overridden-blocks ()
+  (append (when (memq 'fun-decl ess-align-blocks)
+            (list (car ess-prefixed-block-patterns)))
+          (when (memq 'control-flow ess-align-blocks)
+            (append (cdr ess-prefixed-block-patterns)
+                    '("}?[ \t]*else")))))
+
+(defun ess-calculate-indent ()
+  "Return appropriate indentation for current line as ESS code.
+In usual case returns an integer: the column to indent to.
+Returns nil if line starts inside a string, t if in a comment."
+  (save-excursion
+    (beginning-of-line)
+    (let* ((indent-point (point))
+           (state (syntax-ppss))
+           (containing-sexp (cadr state))
+           (prev-containing-sexp (car (last (butlast (nth 9 state))))))
+      (back-to-indentation)
+      (cond
+       ;; Strings
+       ((ess-inside-string-p)
+        (current-indentation))
+       ;; Comments
+       ((ess-calculate-indent--comments))
+       ;; Indentation of commas
+       ((looking-at ",")
+        (ess-calculate-indent--comma))
+       ;; Arguments: Closing
+       ((ess-call-closing-p)
+        (ess-calculate-indent--call-closing-delim))
+       ;; Block: Contents (easy cases)
+       ((ess-calculate-indent--block-relatively))
+       ;; Block: Prefixed block
+       ((ess-calculate-indent--prefixed-block-curly))
+       ;; Continuations
+       ((ess-calculate-indent--continued))
+       ;; Block: Overridden contents
+       ((ess-calculate-indent--aligned-block))
+       ;; Block: Opening
+       ((ess-block-opening-p)
+        (ess-calculate-indent--block-opening))
+       ;; Bare line
+       ((and (null containing-sexp)
+             (not (ess-unbraced-block-p)))
+        0)
+       ;; Block: Closing
+       ((ess-block-closing-p)
+        (ess-calculate-indent--block 0))
+       ;; Block: Contents
+       ((ess-block-p)
+        (ess-calculate-indent--block))
+       ;; Arguments: Nested calls override
+       ((ess-calculate-indent--nested-calls))
+       ;; Arguments: Contents
+       (t
+        (ess-calculate-indent--args))))))
+
+(defun ess-calculate-indent--comments ()
+  (when ess-indent-with-fancy-comments
+    (cond
+     ;; ### or #!
+     ((or (looking-at "###")
+          (and (looking-at "#!")
+               (= 1 (line-number-at-pos))))
+      0)
+     ;; Single # comment
+     ((looking-at "#[^#']")
+      comment-column))))
+
+(defun ess-calculate-indent--comma ()
+  (when (ess-inside-call-p)
+    (let ((indent (save-excursion
+                    (ess-calculate-indent--args)))
+          (unindent (progn (skip-chars-forward " \t")
+                           ;; return number of skipped chars
+                           (skip-chars-forward ", \t"))))
+      (- indent unindent))))
+
+(defun ess-calculate-indent--call-closing-delim ()
+  (cond ((save-excursion
+           (ess-skip-blanks-backward t)
+           (eq (char-before) ?,))
+         (ess-calculate-indent--args nil))
+        ((save-excursion
+           (and (ess-ahead-operator-p)
+                (or (ess-ahead-definition-op-p)
+                    (not ess-align-continuations-in-calls))))
+         (ess-calculate-indent--continued))
+        (t
+         (ess-calculate-indent--args 0))))
+
+(defun ess-calculate-indent--block-opening ()
+  (cond
+   ;; Block is an argument in a function call
+   ((when containing-sexp
+      (ess-at-containing-sexp
+        (ess-behind-call-opening-p "[[(]")))
+    (ess-calculate-indent--block 0))
+   ;; Top-level block
+   ((null containing-sexp) 0)
+   ;; Block is embedded in another block
+   ((ess-at-containing-sexp
+      (+ (current-indentation)
+         (ess-offset 'block))))))
+
+(defun ess-calculate-indent--aligned-block ()
+  ;; Check for `else' opening
+  (if (and (memq 'control-flow ess-align-blocks)
+           (looking-at "else\\b")
+           (ess-climb-if-else))
+      (progn
+        (when (looking-at "else\\b")
+          (ess-skip-curly-backward))
+        (current-column))
+    ;; Check for braced and unbraced blocks
+    (ess-save-excursion-when-nil
+      (let ((offset (if (looking-at "[{})]")
+                        0 (ess-offset 'block))))
+        (when (and (cond
+                    ;; Unbraced blocks
+                    ((ess-climb-block-prefix))
+                    ;; Braced blocks
+                    (containing-sexp
+                     (when (ess-at-containing-sexp
+                             (looking-at "{"))
+                       (ess-escape-prefixed-block))))
+                   (cl-some #'looking-at
+                            (ess-overridden-blocks)))
+          (+ (current-column) offset))))))
+
+(defun ess-calculate-indent--block-relatively ()
+  (ess-save-excursion-when-nil
+    (let ((offset (if (looking-at "[})]") 0 (ess-offset 'block)))
+          (start-line (line-number-at-pos)))
+      (cond
+       ;; Braceless block continuations: only when not in a call
+       ((ess-save-excursion-when-nil
+          (and (not (looking-at "{"))
+               (ess-goto-char (ess-unbraced-block-p))
+               (not (looking-at "function\\b"))
+               (or (null containing-sexp)
+                   (ess-at-containing-sexp
+                     (not (looking-at "("))))))
+        (ess-maybe-climb-broken-else 'same-line)
+        (ess-skip-curly-backward)
+        (+ (current-column)
+           (ess-offset 'block)))
+       ;; Don't indent relatively other continuations
+       ((ess-ahead-continuation-p)
+        nil)
+       ;; If a block already contains an indented line, we can indent
+       ;; relatively from that first line
+       ((ess-save-excursion-when-nil
+          (and (not (looking-at "}"))
+               containing-sexp
+               (goto-char containing-sexp)
+               (looking-at "{")
+               (progn
+                 (forward-line)
+                 (back-to-indentation)
+                 (/= (line-number-at-pos) start-line))
+               (not (looking-at "[ \t]*\\(#\\|$\\)"))
+               (save-excursion
+                 (or (ess-jump-expression)
+                     (ess-jump-continuations))
+                 (< (line-number-at-pos) start-line))))
+        (current-column))
+       ;; If a block is not part of a call, we can indent relatively
+       ;; from the opening {. First check that enclosing { is first
+       ;; thing on line
+       ((and containing-sexp
+             (not (ess-unbraced-block-p))
+             (goto-char containing-sexp)
+             (ess-block-opening-p)
+             (equal (point) (save-excursion
+                              (back-to-indentation)
+                              (point))))
+        (+ (current-column) offset))))))
+
+(defun ess-arg-block-p ()
+  (unless (or (null containing-sexp)
+              ;; Unbraced blocks in a { block are not arg blocks
+              (and (ess-unbraced-block-p)
+                   (ess-at-containing-sexp
+                     (looking-at "{"))))
+    (cond
+     ;; Unbraced body
+     ((ess-at-indent-point
+        (and (ess-unbraced-block-p)
+             (goto-char containing-sexp)
+             (ess-behind-call-opening-p "[[(]")))
+      'body)
+     ;; Indentation of opening brace as argument
+     ((ess-at-containing-sexp
+        (ess-behind-call-opening-p "[[(]"))
+      'opening)
+     ;; Indentation of body or closing brace as argument
+     ((ess-at-containing-sexp
+        (and (or (looking-at "{")
+                 (ess-behind-block-paren-p))
+             prev-containing-sexp
+             (goto-char prev-containing-sexp)
+             (ess-behind-call-opening-p "[[(]")))
+      'body))))
+
+(defun ess-calculate-indent--block (&optional offset)
+  (let ((arg-block (ess-arg-block-p)))
+    (cond (arg-block
+           (ess-calculate-indent--arg-block offset arg-block))
+          (t
+           ;; Block is not part of an arguments list. Climb over any
+           ;; block opening (function declaration, etc) to indent from
+           ;; starting indentation.
+           (or (ess-climb-block-prefix)
+               (and (goto-char containing-sexp)
+                    (ess-climb-block-prefix)))
+           (+ (current-indentation) (or offset (ess-offset 'block)))))))
+
+(defun ess-calculate-indent--arg-block (offset arg-block)
+  (let* ((block-type (cond ((or (ess-at-containing-sexp
+                                  (and (eq arg-block 'body)
+                                       (ess-climb-block-prefix "function")))
+                                (ess-at-indent-point
+                                  (and (eq arg-block 'opening)
+                                       (ess-backward-sexp 2)
+                                       (looking-at "function\\b"))))
+                            'fun-decl)
+                           ((ess-at-indent-point
+                              (ess-unbraced-block-p))
+                            'unbraced)
+                           ((ess-at-containing-sexp
+                              (not (ess-ahead-attached-name-p)))
+                            'bare-block)
+                           (t)))
+         (call-pos (if (and (not (eq block-type 'unbraced))
+                            (not (eq arg-block 'opening)))
+                       (goto-char prev-containing-sexp)
+                     (prog1 containing-sexp
+                       (goto-char indent-point)))))
+    (ess-calculate-indent--args offset (ess-offset-type 'block)
+                                call-pos indent-point block-type)))
+
+;; This function is currently the speed bottleneck of the indentation
+;; engine. This is due to the need to call (ess-maximum-args-indent)
+;; to check if some previous arguments have been pushed off from their
+;; natural indentation: we need to check the whole call. This is very
+;; inefficient especially when indenting a region containing a large
+;; function call (e.g. some dplyr's data cleaning code). Should be
+;; solved by implementing a cache as in (syntax-ppss), though it's
+;; probably not worth the work.
+(defun ess-calculate-indent--args (&optional offset type call-pos to block)
+  (let* ((call-pos (or call-pos containing-sexp))
+         (max-col (prog1 (unless (eq type 'prev-line)
+                           (ess-maximum-args-indent call-pos to))
+                    (goto-char call-pos)))
+         (override (and ess-align-arguments-in-calls
+                        (save-excursion
+                          (ess-climb-object)
+                          (cl-some #'looking-at
+                                   ess-align-arguments-in-calls))))
+         (type-sym (cond (block 'block)
+                         ((looking-at "[[:blank:]]*[([][[:blank:]]*\\($\\|#\\)")
+                          'arguments-newline)
+                         (t 'arguments)))
+         (type (or type
+                   (and override 'open-delim)
+                   (ess-offset-type type-sym)))
+         (offset (or offset
+                     (and (not block) (eq type 'open-delim) 0)
+                     (ess-offset type-sym)))
+         (indent
+          (cond
+           ;; Indent from opening delimiter
+           ((eq type 'open-delim)
+            (ess-calculate-indent--args-open-delim))
+           ;; Indent from attached name
+           ((eq type 'prev-call)
+            (ess-calculate-indent--args-prev-call block))
+           ;; Indent from previous line indentation
+           ((eq type 'prev-line)
+            (let ((out (ess-calculate-indent--args-prev-line type block offset)))
+              (setq offset (pop out))
+              (pop out)))
+           (t
+            (error "Malformed offset")))))
+    (if max-col
+        (ess-adjust-argument-indent indent offset max-col block)
+      (+ indent offset))))
+
+(defun ess-calculate-indent--args-open-delim ()
+  (forward-char)
+  (current-column))
+
+(defun ess-calculate-indent--args-prev-call (block)
+  ;; Handle brackets chains such as ][ (cf data.table)
+  (ess-climb-chained-delims)
+  ;; Handle call chains
+  (if ess-indent-from-chain-start
+      (while (and (ess-backward-sexp)
+                  (when (looking-back "[[(][ \t,]*" (line-beginning-position))
+                    (goto-char (match-beginning 0)))))
+    (ess-backward-sexp))
+  (when ess-indent-from-lhs
+    (ess-climb-lhs))
+  (if (and nil
+           (eq block 'fun-decl)
+           (not (eq arg-block 'opening))
+           (not (eq (ess-offset-type type-sym) 'open-delim)))
+      (+ (ess-offset 'block) (current-column))
+    (current-column)))
+
+(defun ess-calculate-indent--args-prev-line (type block offset)
+  (ess-at-indent-point
+    (cond
+     ;; Closing delimiters are actually not indented at
+     ;; prev-line, but at opening-line
+     ((looking-at "[]})]")
+      (ess-up-list -1)
+      (when (looking-at "{")
+        (ess-climb-block-prefix))
+      (list offset (current-indentation)))
+     ;; Function blocks need special treatment
+     ((and (eq type 'prev-line)
+           (eq block 'fun-decl))
+      (goto-char containing-sexp)
+      (ess-climb-block-prefix)
+      (list offset (current-indentation)))
+     ;; Regular case
+     (t
+      ;; Find next non-empty line to indent from
+      (while (and (= (forward-line -1) 0)
+                  (looking-at "[ \t]*\\($\\|#\\)")))
+      (goto-char (ess-code-end-position))
+      ;; Climb relevant structures
+      (unless (ess-climb-block-prefix)
+        (when (eq (char-before) ?,)
+          (forward-char -1))
+        (ess-climb-expression)
+        (ess-climb-continuations))
+      ;; The following ensures that only the first line
+      ;; counts. Otherwise consecutive statements would get
+      ;; increasingly more indented.
+      (let ((offset (if (and block
+                             containing-sexp
+                             (not (eq block 'unbraced))
+                             (save-excursion
+                               (/= (line-number-at-pos)
+                                   (progn (goto-char containing-sexp)
+                                          (line-number-at-pos)))))
+                        0
+                      offset)))
+        (list offset (current-indentation)))))))
+
+;; Indentation of arguments needs to keep track of how previous
+;; arguments are indented. If one of those has a smaller indentation,
+;; we push off the current line from its natural indentation. For
+;; block arguments, we still need to push off this column so we ignore
+;; it.
+(defun ess-adjust-argument-indent (base offset max-col push)
+  (if push
+      (+ (min base max-col) offset)
+    (min (+ base offset) max-col)))
+
+;; When previous arguments are shifted to the left (can happen in
+;; several situations) compared to their natural indentation, the
+;; following lines should not get indented past them. The following
+;; function checks the minimum indentation for all arguments of the
+;; current function call or bracket indexing.
+(defun ess-maximum-args-indent (&optional from to)
+  (let* ((to (or to (point)))
+         (to-line (line-number-at-pos to))
+         (from-line (progn
+                      (goto-char (1+ (or from containing-sexp)))
+                      (line-number-at-pos)))
+         max-col)
+    (while (< (line-number-at-pos) to-line)
+      (forward-line)
+      (back-to-indentation)
+      ;; Ignore the line with the function call, the line to be
+      ;; indented, and empty lines.
+      (unless (or (>= (line-number-at-pos) to-line)
+                  (looking-at "[ \t]*\\($\\|#\\)"))
+        (let ((indent (cond
+                       ;; First line: minimum indent is right after (
+                       ((= (line-number-at-pos) from-line)
+                        (save-excursion
+                          (goto-char (1+ containing-sexp))
+                          (current-column)))
+                       ;; Handle lines starting with a comma
+                       ((save-excursion
+                          (looking-at ","))
+                        (+ (current-indentation) 2))
+                       (t
+                        (current-indentation)))))
+          (setq max-col (min indent (or max-col indent))))))
+    max-col))
+
+;; Move to leftmost side of a call (either the first letter of its
+;; name or its closing delim)
+(defun ess-move-to-leftmost-side ()
+  (when (or (looking-at "[({]")
+            (ess-behind-call-p))
+    (ess-save-excursion-when-nil
+      (let ((start-col (current-column)))
+        (skip-chars-forward "^{[(")
+        (forward-char)
+        (ess-up-list)
+        (forward-char -1)
+        (< (current-column) start-col)))))
+
+(defun ess-max-col ()
+  (let ((max-col (point)))
+    (save-excursion
+      (while (< (point) indent-point)
+        (unless (and ess-indent-with-fancy-comments
+                     (looking-at "### "))
+          (setq max-col (min max-col (current-column))))
+        (forward-line)
+        (back-to-indentation)))
+    max-col))
+
+(defun ess-calculate-indent--prefixed-block-curly ()
+  (when (looking-at "{")
+    (ess-save-excursion-when-nil
+      (let ((block-type (ess-climb-block-prefix)))
+        (cond ((ess-save-excursion-when-nil
+                 (and (memq 'fun-decl-opening ess-indent-from-lhs)
+                      (string= block-type "function")
+                      (ess-climb-operator)
+                      (ess-behind-assignment-op-p)
+                      (ess-climb-expression)))
+               (current-column))
+              ((= (save-excursion
+                    (back-to-indentation)
+                    (point))
+                  (point))
+               (ess-calculate-indent--continued)))))))
+
+(defun ess-calculate-indent--continued ()
+  "If a continuation line, return an indent of this line, otherwise nil."
+  (save-excursion
+    (let* ((cascade (eq (ess-offset-type 'continued) 'cascade))
+           (climbed (ess-climb-continuations cascade))
+           max-col)
+      (when climbed
+        (cond
+         ;; Overridden calls
+         ((and ess-align-continuations-in-calls
+               (not (eq climbed 'def-op))
+               containing-sexp
+               (save-excursion
+                 (goto-char containing-sexp)
+                 (looking-at "[[(]")))
+          (setq max-col (ess-max-col))
+          (ess-move-to-leftmost-side)
+          (+ (min (current-column) max-col)
+             (if (eq climbed 'def-op)
+                 (ess-offset 'continued)
+               0)))
+         ;; Regular case
+         (t
+          (let ((first-indent (or (eq climbed 'def-op)
+                                  (save-excursion
+                                    (when (ess-ahead-closing-p)
+                                      (ess-climb-expression))
+                                    (not (ess-climb-continuations cascade))))))
+            ;; Record all indentation levels between indent-point and
+            ;; the line we climbed. Some lines may have been pushed off
+            ;; their natural indentation. These become the new
+            ;; reference.
+            (setq max-col (ess-max-col))
+            ;; Indenting continuations from the front of closing
+            ;; delimiters looks better
+            (when
+                (ess-ahead-closing-p)
+              (backward-char))
+            (+ (min (current-column) max-col)
+               (cond
+                ((eq (ess-offset-type 'continued) 'cascade)
+                 (ess-offset 'continued))
+                (first-indent
+                 (ess-offset 'continued))
+                (t
+                 0))))))))))
+
+(defun ess-calculate-indent--nested-calls ()
+  (when ess-align-nested-calls
+    (let ((calls (mapconcat #'identity ess-align-nested-calls "\\|"))
+          match)
+      (save-excursion
+        (and containing-sexp
+             (looking-at (concat "\\(" calls "\\)("))
+             (setq match (match-string 1))
+             (goto-char containing-sexp)
+             (looking-at "(")
+             (ess-backward-sexp)
+             (looking-at (concat match "("))
+             (current-column))))))
+
+
+;;;*;;; Call filling engine
+
+;; Unroll arguments to a single line until closing marker is found.
+(defun ess-fill--unroll-lines (bounds &optional jump-cont)
+  (let* ((last-pos (point-min))
+         (containing-sexp (ess-containing-sexp-position)))
+    (goto-char (car bounds))
+    (goto-char (ess-code-end-position))
+    (while (and (/= (point) last-pos)
+                (< (line-end-position)
+                   (cadr bounds)))
+      (setq last-pos (point))
+      ;; Check whether we ended up in a sub call. In this case, jump
+      ;; over it, otherwise, join lines.
+      (let ((contained-sexp (ess-containing-sexp-position)))
+        (cond ((and contained-sexp
+                    containing-sexp
+                    (not (= containing-sexp contained-sexp)))
+               (goto-char (1+ contained-sexp))
+               (ess-up-list))
+              ;; Jump over continued statements
+              ((and jump-cont (ess-ahead-operator-p 'strict))
+               (ess-climb-token)
+               (ess-jump-continuations))
+              ;; Jump over comments
+              ((looking-at "#")
+               (forward-line)
+               (funcall indent-line-function))
+              (t
+               (join-line 1))))
+      (goto-char (ess-code-end-position)))
+    (goto-char (car bounds))))
+
+(defvar ess-fill--orig-pos nil
+  "Original position of cursor.")
+
+(defvar ess-fill--orig-state nil
+  "Backup of original code to cycle back to original state.")
+
+(defvar ess-fill--second-state nil
+  "Backup of code produce by very first cycling.
+If this is equal to orig-state, no need to cycle back to original
+state.")
+
+(defvar ess-fill--style-level nil
+  "Filling style used in last cycle.")
+
+(defun ess-fill--substring (bounds)
+  (buffer-substring (car bounds) (marker-position (cadr bounds))))
+
+;; Detect repeated commands
+(defun ess-fill-style (type bounds)
+  (let ((max-level
+         ;; This part will be simpler once we have the style alist
+         (cond ((eq type 'calls)
+                ;; No third style either when ess-offset-arguments is
+                ;; set to 'open-delim, or when ess-fill-calls-newlines
+                ;; is nil and no numeric prefix is given
+                (if (and (not (eq (ess-offset-type 'arguments)
+                                  'open-delim))
+                         (or ess-fill-calls-newlines
+                             (numberp current-prefix-arg)))
+                    3
+                  2))
+               ((eq type 'continuations)
+                2))))
+    (if (not (memq last-command '(fill-paragraph-or-region
+                                  fill-paragraph)))
+        (progn
+          ;; Record original state on first cycling
+          (setq ess-fill--orig-state (ess-fill--substring bounds))
+          (setq ess-fill--orig-pos (point))
+          (setq ess-fill--second-state nil)
+          (setq ess-fill--style-level 1))
+      ;; Also record state on second cycling
+      (when (and (= ess-fill--style-level 1)
+                 (null ess-fill--second-state))
+        (setq ess-fill--second-state (ess-fill--substring bounds)))
+      (cond ((>= ess-fill--style-level max-level)
+             (let ((same-last-and-orig (string= (ess-fill--substring bounds)
+                                                ess-fill--orig-state))
+                   (same-2nd-and-orig (string= ess-fill--orig-state
+                                               ess-fill--second-state)))
+               ;; Avoid cycling to the same state twice
+               (cond ((and same-last-and-orig
+                           same-2nd-and-orig)
+                      (setq ess-fill--style-level 2))
+                     ((or same-last-and-orig
+                          same-2nd-and-orig)
+                      (setq ess-fill--style-level 1))
+                     (t
+                      (setq ess-fill--style-level 0)))))
+            (ess-fill--style-level
+             (setq ess-fill--style-level (1+ ess-fill--style-level))))))
+  ess-fill--style-level)
+
+(let (_)
+  ;; FIXME: Transform these dynamic bindings to a state object
+  (defvar ess--infinite)
+  (defvar ess--prefix-break)
+  (defvar ess--start-pos)
+  (defvar ess--last-pos)
+  (defvar ess--last-newline)
+
+  (declare-function ess-fill-args--roll-lines "ess-r-mode")
+
+  (defun ess-fill-args (&optional style)
+    (let ((ess--start-pos (point-min))
+          (bounds (ess-args-bounds 'marker))
+          ;; Set undo boundaries manually
+          (undo-inhibit-record-point t)
+          ess--last-pos ess--last-newline ess--prefix-break
+          ess--infinite)
+      (when (not bounds)
+        (error "Could not find function bounds"))
+      (setq style (or style (ess-fill-style 'calls bounds)))
+      (if (= style 0)
+          (progn
+            (delete-region (car bounds) (marker-position (cadr bounds)))
+            (insert ess-fill--orig-state)
+            ;; Restore the point manually. (save-excursion) wouldn't
+            ;; work here because we delete the text rather than just
+            ;; modifying it.
+            (goto-char ess-fill--orig-pos)
+            (message "Back to original formatting"))
+        (when ess-blink-refilling
+          (ess-blink-region (nth 2 bounds)
+                            (1+ (marker-position (cadr bounds)))))
+        (undo-boundary)
+        (save-excursion
+          (ess-fill--unroll-lines bounds t)
+          (cond
+           ;; Some styles start with first argument on a newline
+           ((and (memq style '(2 4))
+                 ess-fill-calls-newlines
+                 (not (looking-at "[ \t]*#")))
+            (newline-and-indent))
+           ;; Third level, start a newline after N arguments
+           ((and (= style 3)
+                 (not (looking-at "[ \t]*#")))
+            (let ((i (if (numberp current-prefix-arg)
+                         current-prefix-arg
+                       1)))
+              (while (and (> i 0)
+                          (ess-jump-arg)
+                          (ess-jump-char ","))
+                (setq i (1- i))))
+            (newline-and-indent)))
+          (ess-fill-args--roll-lines style)
+          ;; Reindent surrounding context
+          (ess-indent-call (car bounds)))
+        ;; Signal marker for garbage collection
+        (set-marker (cadr bounds) nil)
+        (undo-boundary))))
+
+  (defun ess-fill-args--roll-lines (style)
+    (while (and (not (looking-at "[])]"))
+                (/= (point) (or ess--last-pos 1))
+                (not ess--infinite))
+      (setq ess--prefix-break nil)
+      ;; Record ess--start-pos as future breaking point to avoid breaking
+      ;; at `=' sign
+      (while (looking-at "[ \t]*[\n#]")
+        (forward-line)
+        (back-to-indentation))
+      (setq ess--start-pos (point))
+      (while (and (< (current-column) fill-column)
+                  (not (looking-at "[])]"))
+                  (/= (point) (or ess--last-pos 1))
+                  ;; Break after one pass if prefix is active
+                  (not ess--prefix-break))
+        (when (memq style '(2 3))
+          (setq ess--prefix-break t))
+        (ess-jump-token ",")
+        (setq ess--last-pos (point))
+        ;; Jump expression and any continuations. Reindent all lines
+        ;; that were jumped over
+        (let ((cur-line (line-number-at-pos))
+              end-line)
+          (cond ((ess-jump-arg)
+                 (setq ess--last-newline nil))
+                ((ess-token-after= ",")
+                 (setq ess--last-newline nil)
+                 (setq ess--last-pos (1- (point)))))
+          (save-excursion
+            (when (< cur-line (line-number-at-pos))
+              (setq end-line (line-number-at-pos))
+              (ess-goto-line (1+ cur-line))
+              (while (and (<= (line-number-at-pos) end-line)
+                          (/= (point) (point-max)))
+                (funcall indent-line-function)
+                (forward-line))))))
+      (when (or (>= (current-column) fill-column)
+                ess--prefix-break
+                ;; Ensures closing delim on a newline
+                (and (= style 4)
+                     (looking-at "[ \t]*[])]")
+                     (setq ess--last-pos (point))))
+        (if (and ess--last-pos (/= ess--last-pos ess--start-pos))
+            (goto-char ess--last-pos)
+          (ess-jump-char ","))
+        (cond ((looking-at "[ \t]*[#\n]")
+               (forward-line)
+               (funcall indent-line-function)
+               (setq ess--last-newline nil))
+              ;; With levels 2 and 3, closing delim goes on a newline
+              ((looking-at "[ \t]*[])]")
+               (when (and (memq style '(2 3 4))
+                          ess-fill-calls-newlines
+                          (not ess--last-newline))
+                 (newline-and-indent)
+                 ;; Prevent indenting infinitely
+                 (setq ess--last-newline t)))
+              ((not ess--last-newline)
+               (newline-and-indent)
+               (setq ess--last-newline t))
+              (t
+               (setq ess--infinite t)))))))
+
+(defun ess-fill-continuations (&optional style)
+  (let ((bounds (ess-continuations-bounds 'marker))
+        (undo-inhibit-record-point t)
+        (last-pos (point-min))
+        last-newline infinite)
+    (when (not bounds)
+      (error "Could not find statements bounds"))
+    (setq style (or style (ess-fill-style 'continuations bounds)))
+    (if (= style 0)
+        (progn
+          (delete-region (car bounds) (marker-position (cadr bounds)))
+          (insert ess-fill--orig-state)
+          (goto-char ess-fill--orig-pos)
+          (message "Back to original formatting"))
+      (when ess-blink-refilling
+        (ess-blink-region (car bounds) (marker-position (cadr bounds))))
+      (undo-boundary)
+      (save-excursion
+        (ess-fill--unroll-lines bounds)
+        (while (and (< (point) (cadr bounds))
+                    (/= (point) (or last-pos 1))
+                    (not infinite))
+          (setq last-pos (point))
+          (when (and (ess-jump-expression)
+                     (indent-according-to-mode)
+                     (not (> (current-column) fill-column)))
+            (setq last-newline nil))
+          (ess-jump-operator)
+          (if (or (and (> (current-column) fill-column)
+                       (goto-char last-pos))
+                  (= style 2))
+              (progn
+                (ess-jump-operator)
+                (unless (= (point) (cadr bounds))
+                  (when last-newline
+                    (setq infinite t))
+                  (newline-and-indent)
+                  (setq last-newline t)))
+            (setq last-newline nil)))
+        (ess-indent-call (car bounds)))
+      (set-marker (cadr bounds) nil)
+      (undo-boundary))))
+
+\f
+
+;;;*;;; Inferior R mode
+
+(defvar inferior-ess-r-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "\M-\r" #'ess-dirs)
+    (define-key map (kbd "C-c C-=") #'ess-cycle-assign)
+    (define-key map (kbd "C-c C-.") 'ess-rutils-map)
+    map)
+  "Keymap for `inferior-ess-r-mode'.")
+
+;; TOTHINK: Prevent string delimiting characters from messing up output in the
+;; inferior buffer
+(defvar inferior-ess-r-mode-syntax-table
+  (let ((table (copy-syntax-table ess-r-mode-syntax-table)))
+    (modify-syntax-entry ?% "." table)
+    (modify-syntax-entry ?\' "." table)
+    table)
+  "Syntax table for `inferior-ess-r-mode'.")
+
+(define-derived-mode inferior-ess-r-mode inferior-ess-mode "iESS"
+  "Major mode for interacting with inferior R processes."
+  :group 'ess-proc
+  (ess-setq-vars-local ess-r-customize-alist)
+  (setq-local ess-font-lock-keywords 'inferior-ess-r-font-lock-keywords)
+  (setq-local font-lock-syntactic-face-function #'ess-r-font-lock-syntactic-face-function)
+  (setq-local comint-process-echoes (eql ess-eval-visibly t))
+  (setq-local comint-prompt-regexp inferior-S-prompt)
+  (setq-local syntax-propertize-function ess-r--syntax-propertize-function)
+  (setq comint-input-sender 'inferior-ess-r-input-sender)
+  (remove-hook 'completion-at-point-functions #'ess-filename-completion 'local) ;; should be first
+  (add-hook 'completion-at-point-functions #'ess-r-object-completion nil 'local)
+  (add-hook 'completion-at-point-functions #'ess-filename-completion nil 'local)
+  (add-hook 'xref-backend-functions #'ess-r-xref-backend nil 'local)
+  (add-hook 'project-find-functions #'ess-r-project nil 'local)
+  ;; eldoc
+  (ess--setup-eldoc #'ess-r-eldoc-function)
+  ;; auto-complete
+  (ess--setup-auto-complete ess-r-ac-sources t)
+  ;; company
+  (ess--setup-company ess-r-company-backends t)
+  (setq comint-get-old-input #'inferior-ess-get-old-input)
+  (add-hook 'comint-input-filter-functions #'ess-search-path-tracker nil 'local))
+
+
+\f
+;;;*;;; R Help mode
+
+(defvar ess-r-help-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map (make-composed-keymap button-buffer-map
+                                                 ess-help-mode-map))
+    (define-key map "s<" #'beginning-of-buffer)
+    (define-key map "s>" #'end-of-buffer)
+    (define-key map "sa" #'ess-skip-to-help-section)
+    (define-key map "sd" #'ess-skip-to-help-section)
+    (define-key map "sD" #'ess-skip-to-help-section)
+    (define-key map "st" #'ess-skip-to-help-section)
+    (define-key map "se" #'ess-skip-to-help-section)
+    (define-key map "sn" #'ess-skip-to-help-section)
+    (define-key map "sr" #'ess-skip-to-help-section)
+    (define-key map "ss" #'ess-skip-to-help-section)
+    (define-key map "su" #'ess-skip-to-help-section)
+    (define-key map "sv" #'ess-skip-to-help-section)
+    map)
+  "Keymap for `ess-r-help-mode'.")
+
+(cl-defmethod ess--help-major-mode (&context (ess-dialect "R"))
+  (ess-r-help-mode))
+
+(define-derived-mode ess-r-help-mode ess-help-mode "R Help"
+  "Major mode for help buffers."
+  :group 'ess-help
+  (setq ess-dialect "R"
+        ess-help-sec-regex ess-help-r-sec-regex
+        ess-help-sec-keys-alist ess-help-r-sec-keys-alist ; TODO: Still necessary?
+        inferior-ess-help-command inferior-ess-r-help-command)
+  (ess-r-help--add-links))
+
+(define-button-type 'ess-r-help--link
+  'follow-link t
+  'action (lambda (_) (ess-r-help--button-action)))
+
+(defun ess-r-help--button-action ()
+  "Display help for button at point."
+  (let ((text (get-text-property (point) 'ess-r-help--link-text)))
+    (ess-display-help-on-object text)))
+
+(defun ess-r-help--add-links ()
+  "Add links to the help buffer."
+  (let ((links (when (ess-process-live-p)
+                 (ess-get-words-from-vector
+                  (ess-r--format-call
+                   ".ess.helpLinks('%s' %s)\n"
+                   ess-r-help--local-object
+                   (ess-r-arg "package" ess-r-help--local-package t)))))
+        (inhibit-read-only t))
+    (save-excursion
+      ;; Search for fancy quotes only. If users have
+      ;; options(useFancyQuotes) set to something other than TRUE this
+      ;; probably won't work. If it's FALSE, R outputs ascii ', but
+      ;; searching through the whole buffer takes too long.
+      (while (re-search-forward "‘\\([^[:space:]]+?\\)’" nil t)
+        (let* ((text (match-string 1))
+               (text-stripped (if (string-match-p ".*()\\'" text)
+                                  (substring text nil (- (length text) 2))
+                                text)))
+          (when (member text-stripped links)
+            (delete-region (match-beginning 0) (match-end 0))
+            (insert-text-button text
+                                'ess-r-help--link-text text-stripped
+                                'type 'ess-r-help--link
+                                'help-echo (format "mouse-2, RET: Help on %s" text))))))))
+
+(cl-defmethod ess--display-vignettes-override (all &context (ess-dialect "R"))
+  "Display R vignettes in ess-help-like buffer..
+With (prefix) ALL non-nil, use `vignette(*, all=TRUE)`, i.e.,
+from all installed packages, which can be very slow."
+  (inferior-ess-r-force)
+  (let* ((vslist (with-current-buffer
+                     (ess-command
+                      (format ".ess_vignettes(%s)\n" (if all "TRUE" "")))
+                   (goto-char (point-min))
+                   (when (re-search-forward "(list" nil t)
+                     (goto-char (match-beginning 0))
+                     (ignore-errors (eval (read (current-buffer)) t)))))
+         (proc-name ess-current-process-name)
+         (alist ess-local-customize-alist)
+         (remote (file-remote-p default-directory))
+         (buff (get-buffer-create (format "*[%s]vignettes*" ess-dialect)))
+         (inhibit-modification-hooks t)
+         (inhibit-read-only t))
+    (with-current-buffer buff
+      (setq buffer-read-only nil)
+      (delete-region (point-min) (point-max))
+      (ess-setq-vars-local (eval alist t))
+      (setq ess-local-process-name proc-name)
+      (ess--help-major-mode)
+      (setq ess-help-sec-regex "^\\w+:$"
+            ess-help-type 'vignettes)
+      (set-buffer-modified-p 'nil)
+      (goto-char (point-min))
+      (dolist (el vslist)
+        (let ((pack (car el)))
+          (insert (format "\n\n%s:\n\n" (propertize pack 'face 'underline)))
+          (dolist (el2 (cdr el))
+            (let ((path (if remote
+                            (with-no-warnings
+                              ;; Have to wrap this in with-no-warnings because
+                              ;; otherwise the byte compiler complains about
+                              ;; calling tramp-make-tramp-file-name with an
+                              ;; incorrect number of arguments on Both 26+ and 25 emacses.
+                              (if (>= emacs-major-version 26)
+                                  (with-parsed-tramp-file-name default-directory nil
+                                    (tramp-make-tramp-file-name method user domain host port (nth 1 el2)))
+                                (with-parsed-tramp-file-name default-directory nil
+                                  (tramp-make-tramp-file-name method user host (nth 1 el2)))))
+                          (nth 1 el2))))
+              (insert-text-button "doc"
+                                  'mouse-face 'highlight
+                                  'action (if remote
+                                              #'ess--action-open-in-emacs
+                                            #'ess--action-R-open-vignette)
+                                  'follow-link t
+                                  'vignette (file-name-sans-extension (nth 2 el2))
+                                  'package pack
+                                  'help-echo (concat path "/doc/" (nth 2 el2)))
+              (insert " ")
+              (insert-text-button "source"
+                                  'mouse-face 'highlight
+                                  'action #'ess--action-open-in-emacs
+                                  'follow-link t
+                                  'help-echo (concat path "/doc/" (nth 3 el2)))
+              (insert " ")
+              (insert-text-button "R"
+                                  'mouse-face 'highlight
+                                  'action #'ess--action-open-in-emacs
+                                  'follow-link t
+                                  'help-echo (concat path "/doc/" (nth 4 el2)))
+              (insert (format "\t%s\n" (nth 0 el2)))))))
+      (goto-char (point-min))
+      (insert (propertize "\t\t**** Vignettes ****\n" 'face 'bold-italic))
+      (unless (eobp) (delete-char 1))
+      (setq buffer-read-only t))
+    (ess-display-help buff)))
+
+\f
+
+;; Support for listing R packages
+
+(define-obsolete-variable-alias 'ess-rutils-buf 'ess-r-package-menu-buf "ESS 19.04")
+(define-obsolete-variable-alias 'ess-rutils-mode-map 'ess-r-package-menu-mode-map "ESS 19.04")
+(define-obsolete-function-alias 'ess-rutils-mode #'ess-r-package-menu-mode "ESS 19.04")
+
+(defvar ess-rutils-map
+  (let ((map (define-prefix-command 'ess-rutils-map)))
+    (define-key map "l" #'ess-r-package-list-local-packages)
+    (define-key map "r" #'ess-r-package-list-available-packages)
+    (define-key map "u" #'ess-r-package-update-packages)
+    (define-key map "a" #'ess-display-help-apropos)
+    (define-key map "m" #'ess-rutils-rm-all)
+    (define-key map "o" #'ess-rdired)
+    (define-key map "w" #'ess-rutils-load-workspace)
+    (define-key map "s" #'ess-rutils-save-workspace)
+    (define-key map "d" #'ess-change-directory)
+    (define-key map "H" #'ess-rutils-html-docs)
+    map))
+
+(easy-menu-define ess-rutils-mode-menu inferior-ess-mode-menu
+  "Package management."
+  '("Package management"
+    ["List local packages" ess-r-package-list-local-packages t]
+    ["List available packages" ess-r-package-list-available-packages t]
+    ["Update packages" ess-r-package-update-packages t]))
+
+(easy-menu-add-item inferior-ess-mode-menu nil ess-rutils-mode-menu "Utils")
+(easy-menu-add-item ess-mode-menu nil ess-rutils-mode-menu "Process")
+
+(defvar ess-r-package-menu-buf "*R packages*"
+  "Name of buffer to display R packages in.")
+
+(defvar ess-r-package-menu-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "l" #'ess-r-package-load)
+    (define-key map "i" #'ess-r-package-mark-install)
+    (define-key map "x" #'ess-r-package-execute-marks)
+    (define-key map "u" #'ess-r-package-unmark)
+    map)
+  "Keymap for `ess-rutils-mode'.")
+
+(define-derived-mode ess-r-package-menu-mode tabulated-list-mode "R utils"
+  "Major mode for `ess-rutils-local-pkgs' and `ess-rutils-repos-pkgs'."
+  :group 'ess-R
+  (setq ess-dialect "R")
+  (setq mode-name (concat "R packages: " ess-local-process-name))
+  (setq tabulated-list-padding 2)
+  (setq tabulated-list-format
+        `[("Name" 10 t)
+          ("Description" 50 nil)
+          ("Version" 5 t)])
+  (tabulated-list-init-header))
+
+(define-obsolete-function-alias 'ess-rutils-local-pkgs #'ess-r-package-list-local-packages "ESS 19.04")
+
+(defun ess-r-package-list-local-packages ()
+  "List all packages in all libraries."
+  (interactive)
+  (ess-r-package--list-packages (concat ".ess.rutils.ops <- options(width = 10000);"
+                                        "print(installed.packages(fields=c(\"Title\"))[, c(\"Title\", \"Version\")]);"
+                                        "options(.ess.rutils.ops); rm(.ess.rutils.ops);"
+                                        "\n")))
+
+(defun ess-r-package--list-packages (cmd)
+  "Use CMD to list packages."
+  (let ((process ess-local-process-name)
+        des-col-beginning des-col-end entries)
+    (with-current-buffer (ess-command cmd (get-buffer-create " *ess-rutils-pkgs*"))
+      (goto-char (point-min))
+      (delete-region (point) (1+ (line-end-position)))
+      ;; Now we have a buffer with package name, description, and
+      ;; version. description and version are surrounded by quotes,
+      ;; description is separated by whitespace.
+      (re-search-forward "\\>[[:space:]]+")
+      (setq des-col-beginning (current-column))
+      (goto-char (line-end-position))
+      ;; Unless someone has a quote character in their package version,
+      ;; two quotes back will be the end of the package description.
+      (dotimes (_ 2) (search-backward "\""))
+      (re-search-backward "[[:space:]]*")
+      (setq des-col-end (current-column))
+      (beginning-of-line)
+      (while (not (eobp))
+        (beginning-of-line)
+        (let* ((name (string-trim (buffer-substring
+                                   (point)
+                                   (progn (forward-char (1- des-col-beginning))
+                                          (point)))))
+               (description (string-trim (buffer-substring
+                                          (progn (forward-char 1)
+                                                 (point))
+                                          (progn (forward-char (- des-col-end des-col-beginning))
+                                                 (point)))))
+               (version (buffer-substring
+                         (progn (end-of-line)
+                                (search-backward "\"")
+                                (search-backward "\"")
+                                (forward-char 1)
+                                (point))
+                         (progn (search-forward "\"")
+                                (backward-char 1)
+                                (point)))))
+          (push
+           (list name
+                 `[(,name
+                    help-echo "mouse-2, RET: help on this package"
+                    action ess-rutils-help-on-package)
+                   ,description
+                   ,version])
+           entries)
+          (forward-line)))
+      (pop-to-buffer ess-rutils-buf)
+      (setq ess-local-process-name process)
+      (setq tabulated-list-entries entries)
+      (ess-r-package-menu-mode)
+      (tabulated-list-print))))
+
+(define-obsolete-function-alias 'ess-rutils-loadpkg #'ess-r-package-load "ESS 19.04")
+(defun ess-r-package-load ()
+  "Load package from a library."
+  (interactive)
+  (ess-execute (concat "library('" (tabulated-list-get-id)
+                       "', character.only = TRUE)")
+               'buffer))
+
+(defun ess-rutils-help-on-package (&optional _button)
+  "Display help on the package at point."
+  (interactive)
+  ;; FIXME: Should go to a help buffer
+  (ess-execute (concat "help(" (tabulated-list-get-id) ", package = '"
+                       (tabulated-list-get-id)"')")
+               'buffer))
+
+(define-obsolete-function-alias 'ess-rutils-repos-pkgs #'ess-r-package-list-available-packages "ESS 19.04")
+(defun ess-r-package-list-available-packages ()
+  "List available packages.
+Use the repositories as listed by getOptions(\"repos\") in the
+current R session."
+  (interactive)
+  (ess-r-package--list-packages
+   "{
+       .ess.rutils.ops <- options(width = 10000)
+       print(available.packages(fields=c(\"Title\"))[, c(\"Title\", \"Version\")])
+       options(.ess.rutils.ops); rm(.ess.rutils.ops)
+    }\n"))
+
+(define-obsolete-function-alias 'ess-rutils-mark-install #'ess-r-package-mark-install "ESS 19.04")
+(defun ess-r-package-mark-install ()
+  "Mark the current package for installing."
+  (interactive)
+  (tabulated-list-put-tag "i" t))
+
+(define-obsolete-function-alias 'ess-rutils-unmark #'ess-r-package-unmark "ESS 19.04")
+(defun ess-r-package-unmark ()
+  "Unmark the packages."
+  (interactive)
+  (tabulated-list-put-tag " " t))
+
+(define-obsolete-function-alias 'ess-rutils-execute-marks #'ess-r-package-execute-marks "ESS 19.04")
+(defun ess-r-package-execute-marks ()
+  "Perform all marked actions."
+  (interactive)
+  ;; Install
+  (save-excursion
+    (let ((cmd "install.packages(c(")
+          pkgs)
+      (goto-char (point-min))
+      (while (not (eobp))
+        (when (looking-at-p "i")
+          (setq pkgs (concat "\"" (tabulated-list-get-id) "\", " pkgs))
+          (tabulated-list-put-tag " "))
+        (forward-line))
+      (if pkgs
+          (progn (setq pkgs (substring pkgs 0 (- (length pkgs) 2)))
+                 (setq cmd (concat cmd pkgs "))"))
+                 (ess-execute cmd 'buffer))
+        (message "No packages marked for install")))))
+
+(define-obsolete-function-alias 'ess-rutils-update-pkgs #'ess-r-package-update-packages "ESS 19.04")
+(defun ess-r-package-update-packages (lib repo)
+  "Update packages in library LIB and repo REPO.
+This also uses checkBuilt=TRUE to rebuild installed packages if
+needed."
+  (interactive
+   (list (ess-completing-read "Library to update: " (ess-get-words-from-vector
+                                                     "as.character(.libPaths())\n"))
+         (ess-completing-read "Repo: " (ess-get-words-from-vector
+                                        "as.character(getOption(\"repos\"))\n"))))
+  (ess-execute (format "update.packages(lib.loc='%s', repos='%s', ask=FALSE, checkBuilt=TRUE)" lib repo) 'buffer))
+
+(define-obsolete-function-alias 'ess-rutils-apropos #'ess-display-help-apropos "ESS 19.04")
+
+;; Miscellaneous helper functions
+
+(defun ess-rutils-rm-all ()
+  "Remove all R objects."
+  (interactive)
+  (when (y-or-n-p "Delete all objects? ")
+    (ess-execute "rm(list=ls())" 'buffer)))
+
+(defun ess-rutils-load-workspace (file)
+  "Load workspace FILE into R."
+  (interactive "fFile with workspace to load: ")
+  (ess-execute (concat "load('" file "')") 'buffer))
+(define-obsolete-function-alias 'ess-rutils-load-wkspc #'ess-rutils-load-workspace "ESS 19.04")
+
+(defun ess-rutils-save-workspace (file)
+  "Save FILE workspace as file.RData."
+  (interactive "FSave workspace to file (no extension): ")
+  (ess-execute (concat "save.image('" file ".RData')") 'buffer))
+(define-obsolete-function-alias 'ess-rutils-save-wkspc #'ess-rutils-save-workspace "ESS 19.04")
+
+(defun ess-rutils-quit ()
+  "Kill the ess-rutils buffer and return to the iESS buffer."
+  (interactive)
+  (ess-switch-to-end-of-ESS)
+  (kill-buffer ess-rutils-buf))
+
+(defun ess-rutils-html-docs (&optional remote)
+  "Use `browse-url' to navigate R html documentation.
+Documentation is produced by a modified help.start(), that
+returns the URL produced by GNU R\\='s http server. If called with a
+prefix, the modified help.start() is called with update=TRUE. The
+optional REMOTE argument should be a string with a valid URL for
+the \\='R_HOME\\=' directory on a remote server (defaults to NULL)."
+  (interactive)
+  (let* ((update (if current-prefix-arg "update=TRUE" "update=FALSE"))
+         (remote (if (or (and remote (not (string= "" remote))))
+                     (concat "remote=" remote) "remote=NULL"))
+         (proc ess-local-process-name)
+         (rhtml (format ".ess_help_start(%s, %s)\n" update remote)))
+    (with-temp-buffer
+      (ess-command rhtml (current-buffer) nil nil nil (get-process proc))
+      (let* ((begurl (search-backward "http://"))
+             (endurl (search-forward "index.html"))
+             (url (buffer-substring-no-properties begurl endurl)))
+        (browse-url url)))))
+
+(defun ess-rutils-rsitesearch (string)
+  "Search the R archives for STRING, and show results using `browse-url'.
+If called with a prefix, options are offered (with completion)
+for matches per page, sections of the archives to search,
+displaying results in long or short formats, and sorting by any
+given field. Options should be separated by value of
+`crm-default-separator'."
+  (interactive "sSearch string: ")
+  (let ((site "https://search.r-project.org/cgi-bin/namazu.cgi?query=")
+        (okstring (replace-regexp-in-string " +" "+" string)))
+    (browse-url
+     (if current-prefix-arg
+        (let ((mpp (concat
+                    "&max="
+                    (completing-read
+                     "Matches per page: "
+                     '(("20" 1) ("30" 2) ("40" 3) ("50" 4) ("100" 5)))))
+              (format (concat
+                       "&result="
+                       (completing-read
+                        "Format: " '(("normal" 1) ("short" 2))
+                        nil t "normal" nil "normal")))
+              (sortby (concat
+                       "&sort="
+                       (completing-read
+                        "Sort by: "
+                        '(("score" 1) ("date:late" 2) ("date:early" 3)
+                          ("field:subject:ascending" 4)
+                          ("field:subject:descending" 5)
+                          ("field:from:ascending" 6) ("field:from:descending" 7)
+                          ("field:size:ascending" 8) ("field:size:descending" 9))
+                        nil t "score" nil "score")))
+              (restrict (concat
+                         "&idxname="
+                         (mapconcat
+                          #'identity
+                          (completing-read-multiple
+                           "Limit search to: "
+                           '(("Rhelp02a" 1) ("functions" 2)
+                             ("docs" 3) ("Rhelp01" 4))
+                           nil t "Rhelp02a,functions,docs" nil
+                           "Rhelp02a,functions,docs")
+                          "&idxname="))))
+          (concat site okstring mpp format sortby restrict))
+       (concat site okstring "&max=20&result=normal&sort=score"
+               "&idxname=Rhelp02a&idxname=functions&idxname=docs")))))
+
+(defun ess-rutils-help-search (string)
+  "Search for STRING using help.search()."
+  (interactive "sString to search for? ")
+  (let ((proc ess-local-process-name))
+    (pop-to-buffer "foobar")
+    (ess-command (concat "help.search('" string "')\n")
+                 (current-buffer) nil nil nil (get-process proc))))
+
+(make-obsolete 'ess-rutils-rhtml-fn "overwrite .ess_help_start instead." "ESS 18.10")
+
+
+;; Create functions that can be called for running different versions
+;; of R.
+;; FIXME: Should be set in ess-custom
+(setq ess-rterm-version-paths
+      (ess-flatten-list
+       (delete-dups
+        (if (not ess-directory-containing-R)
+            (if (getenv "ProgramW6432")
+                (let ((P-1 (getenv "ProgramFiles(x86)"))
+                      (P-2 (getenv "ProgramW6432")))
+                  (nconc
+                   ;; Always 32 on 64 bit OS, nil on 32 bit OS
+                   (ess-find-rterm (concat P-1 "/R/") "bin/Rterm.exe")
+                   (ess-find-rterm (concat P-1 "/R/") "bin/i386/Rterm.exe")
+
+                   ;; Keep this both for symmetry and because it can happen:
+                   (ess-find-rterm (concat P-1 "/R/") "bin/x64/Rterm.exe")
+
+                   ;; Always 64 on 64 bit OS, nil on 32 bit OS
+                   (ess-find-rterm (concat P-2 "/R/") "bin/Rterm.exe")
+                   (ess-find-rterm (concat P-2 "/R/") "bin/i386/Rterm.exe")
+                   (ess-find-rterm (concat P-2 "/R/") "bin/x64/Rterm.exe")))
+              (let ((PF (getenv "ProgramFiles")))
+                (nconc
+                 ;; Always 32 on 32 bit OS, depends on 32 or 64 process on 64 bit OS
+                 (ess-find-rterm (concat PF "/R/") "bin/Rterm.exe")
+                 (ess-find-rterm (concat PF "/R/") "bin/i386/Rterm.exe")
+                 (ess-find-rterm (concat PF "/R/") "bin/x64/Rterm.exe"))))
+          (let ((PF ess-directory-containing-R))
+            (nconc
+             (ess-find-rterm (concat PF "/R/") "bin/Rterm.exe")
+             (ess-find-rterm (concat PF "/R/") "bin/i386/Rterm.exe")
+             (ess-find-rterm (concat PF "/R/") "bin/x64/Rterm.exe")))))))
+(ess-r-define-runners)
+
+;;*;; Provide and auto-loads
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("/Makevars\\(\\.win\\)?\\'" . makefile-mode))
+;;;###autoload
+(add-to-list 'auto-mode-alist '("DESCRIPTION\\'" . conf-colon-mode))
+
+(provide 'ess-r-mode)
+
+;;; ess-r-mode.el ends here
diff --git a/elpa/ess-20260424.1544/ess-r-package.el b/elpa/ess-20260424.1544/ess-r-package.el
new file mode 100644 (file)
index 0000000..3513cc4
--- /dev/null
@@ -0,0 +1,598 @@
+;;; ess-r-package.el --- Package development mode for R.  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2011-2022 Free Software Foundation, Inc.
+;; Author: Lionel Henry, Vitalie Spinu
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; see appropriate documentation section of ESS user manual
+
+;;; Code:
+(require 'cl-lib)
+(require 'ess-inf)
+
+(eval-when-compile
+  (require 'subr-x)
+  (require 'tramp))
+;; Silence the byte compiler, OK because this file is only loaded by
+;; ess-r-mode and has no autoloads.
+(defvar ess-r-customize-alist)
+(declare-function ess-r-project "ess-r-mode")
+(declare-function inferior-ess-r-force "ess-r-mode")
+(declare-function ess-r-get-evaluation-env "ess-r-mode")
+(declare-function ess-r-set-evaluation-env "ess-r-mode")
+(declare-function tramp-dissect-file-name "tramp" (name &optional nodefault))
+;; This can be drop after dropping support for Emacs 25:
+(declare-function tramp-file-name-localname "tramp" (cl-x))
+
+(defvar ess-r-prompt-for-attached-pkgs-only nil
+  "If nil provide completion for all installed R packages.
+If non-nil, only look for attached packages.")
+
+(define-obsolete-variable-alias 'ess-r-package-auto-set-evaluation-env 'ess-r-package-auto-enable-namespaced-evaluation "18.04")
+(define-obsolete-variable-alias 'ess-r-package-auto-set-evaluation-env 'ess-r-package-auto-enable-namespaced-evaluation "18.04")
+(defcustom ess-r-package-auto-enable-namespaced-evaluation t
+  "If non-nil, evaluation env is set to package env automatically.
+See also `ess-r-set-evaluation-env' and `ess-r-evaluation-env'."
+  :group 'ess-r-package
+  :type 'boolean)
+
+(defvar-local ess-r-package--info-cache nil
+  "Current package info cache.
+See `ess-r-package-info' for its structure.")
+
+(defcustom ess-r-package-library-paths nil
+  "Default path to find user packages.
+Can be either a string specifying a directory or a list of
+directories. This variable is also consulted by
+`xref-find-definitions' in R buffers. See `ess-r-xref-backend'."
+  :group 'ess-r-package-library-paths
+  :type `(choice string (repeat string)))
+
+(defvar ess-r-package-root-file "DESCRIPTION"
+  "Presence of this file indicates the project's root.")
+
+(defvar ess-r-package-dirs
+  '(("R"        . 1)
+    ("r"        . 1)
+    ("tests"    . 1)
+    ("testthat" . 2)
+    ("inst"     . 1)
+    ("include"  . 2)
+    ("src"      . 1))
+  "Alist of directories names and their depth in R package hierarchy.
+This list is used to figure out whether the current file belongs
+to an R package. If the file specified in `ess-r-package-root-file'
+\(DESCRIPTION by default) is found at the presumed root directory
+of the package, the current directory is considered to be part of
+a R package.")
+
+(defvar ess-r-package-source-roots
+  '("R" "src" "tests" "inst/include")
+  "List of sub-directories within R package where source files are located.
+All children of these directories are also considered source
+containing directories.  Use `ess-r-package-source-dirs' to get
+all source dirs recursively within the current package.")
+
+\f
+;;;*;;; Package Detection
+
+(defun ess-r-package-project (&optional dir)
+  "Return the current package as an Emacs project instance.
+A project instance is a cons cell of the project type as symbol
+and the project path as string. If DIR is provided, the package
+is searched from that directory instead of `default-directory'."
+  (let ((pkg-info (ess-r-package-info dir)))
+    (when (car pkg-info)
+      (cons 'ess-r-package (plist-get pkg-info :root)))))
+
+
+;; FIXME: remove when emacs 27 is dropped
+(unless (eval-when-compile
+          (get 'project-roots 'byte-obsolete-info))
+  (cl-defmethod project-roots ((project (head ess-r-package)))
+    "Return the project root for ESS R packages"
+    (list (cdr project))))
+
+(cl-defmethod project-root ((project (head ess-r-package)))
+  "Return the project root for ESS R packages"
+  (cdr project))
+
+(defun ess-r-package-name (&optional dir)
+  "Return the name of the current package as a string."
+  (plist-get (ess-r-package-info dir) :name))
+
+(defun ess-r-package-info (&optional dir)
+  "Get the description of the R project in directory DIR.
+Return an plist with the keys :name and :root. When not in a
+package return \\='(nil). This value is cached buffer-locally for
+efficiency reasons."
+  (if (and (null dir) (car ess-r-package--info-cache))
+      ess-r-package--info-cache
+    (let* ((path (ess-r-package--find-package-path (or dir default-directory)))
+           (name (when path
+                   (ess-r-package--find-package-name path)))
+           (local (if (and path (file-remote-p path))
+                      (tramp-file-name-localname (tramp-dissect-file-name path))
+                    path))
+           (info (if name
+                     (list :name name
+                           :root local)
+                   '(nil))))
+      ;; If DIR was supplied we cannot cache in the current buffer.
+      (if dir
+          info
+        (setq-local ess-r-package--info-cache info)))))
+
+(defun ess-r-package--all-source-dirs (dir)
+  (when (file-directory-p dir)
+    (cl-loop for f in (directory-files-and-attributes dir t "\\`[^.]")
+             if (cadr f)
+             append (cons (car f) (ess-r-package--all-source-dirs (car f))))))
+
+(defun ess-r-package-source-dirs ()
+  "Get paths within current R package with source files.
+Return nil if not in a package. Search sub-directories listed in
+`ess-r-package-source-roots' are searched recursively and
+return all physically present directories."
+  (let ((pkg-root (plist-get (ess-r-package-info) :root)))
+    (when pkg-root
+      (let ((files (directory-files-and-attributes pkg-root t "\\`[^.]")))
+        (cl-loop for f in files
+                 if (and (cadr f)
+                         (cl-some (lambda (el) (string-match-p (concat "/" el "$") (car f)))
+                                  ess-r-package-source-roots))
+                 append (cons (car f)
+                              (ess-r-package--all-source-dirs (car f))))))))
+
+(defun ess-r--select-package-name ()
+  (inferior-ess-r-force)
+  (let ((pkgs (ess-get-words-from-vector
+               (format "print(.packages(%s), max = 1e6)\n"
+                       (if ess-r-prompt-for-attached-pkgs-only "FALSE" "TRUE"))))
+        (current-pkg (ess-r-package-name)))
+    (let ((env (ess-r-get-evaluation-env)))
+      (when env
+        (setq pkgs (append '("*none*") pkgs))
+        (when (equal env current-pkg)
+          (setq current-pkg "*none*"))))
+    (ess-completing-read "Package" pkgs nil nil nil nil current-pkg)))
+
+(defun ess-r-package--find-package-path (&optional dir)
+  "Get the root of R package in directory DIR.
+DIR defaults to the current buffer's file name (if non-nil) or
+`default-directory'. Root is determined by locating
+`ess-r-package-root-file'."
+  (when-let ((path (cond
+                    (dir)
+                    ((buffer-file-name)
+                     (file-name-directory (buffer-file-name)))
+                    (t
+                     default-directory)))
+             (pkg-path
+              (when path
+                (or
+                 ;; First check current directory
+                 (and (file-exists-p (expand-file-name ess-r-package-root-file path))
+                      path)
+                 ;; Check for known directories in current path
+                 (let ((current-dir (file-name-nondirectory (directory-file-name path)))
+                       known-pkg-dir known-path presumptive-path)
+                   (while (and path (not presumptive-path))
+                     (setq current-dir (file-name-nondirectory (directory-file-name path)))
+                     (if (and (setq known-pkg-dir (assoc current-dir ess-r-package-dirs))
+                              (setq known-path (ess--parent-dir path (cdr known-pkg-dir)))
+                              (file-exists-p (expand-file-name ess-r-package-root-file known-path)))
+                         (setq presumptive-path known-path)
+                       (setq path (ess--parent-dir path 1))))
+                   presumptive-path)))))
+    (directory-file-name pkg-path)))
+
+(defun ess-r-package--find-package-name (path)
+  (let ((file (expand-file-name ess-r-package-root-file path))
+        (case-fold-search t))
+    (when (file-exists-p file)
+      (with-temp-buffer
+        (insert-file-contents-literally file)
+        (goto-char (point-min))
+        (when (re-search-forward "package: \\(.*\\)" nil t)
+          (match-string 1))))))
+
+\f
+;;;*;;; UI
+
+(defun ess-r-package-use-dir ()
+  "Set process directory to current package directory."
+  (interactive)
+  (let ((pkg-root (plist-get (ess-r-package-info) :root)))
+    (if pkg-root
+        (ess-set-working-directory (abbreviate-file-name pkg-root))
+      (user-error "Not in a project"))))
+
+\f
+;;;*;;; Evaluation
+
+(defun ess-r-package-enable-namespaced-evaluation ()
+  "Enable namespaced evaluation in current buffer.
+Namespaced evaluation is enabled if
+`ess-r-package-auto-enable-namespaced-evaluation' is non-nil."
+  (when ess-r-package-auto-enable-namespaced-evaluation
+    (let ((root (plist-get (ess-r-package-info) :root)))
+      ;; Check that we are in a file within R/
+      (when (and root
+                 default-directory
+                 (> (length default-directory) (1+ (length root)))
+                 (let ((subpath (substring default-directory
+                                           (1+ (length root))
+                                           (length default-directory))))
+                   (string= (directory-file-name subpath) "R")))
+        (ess-r-set-evaluation-env (ess-r-package-name))))))
+
+(add-hook 'ess-r-mode-hook #'ess-r-package-enable-namespaced-evaluation)
+
+(defun ess-r-package-eval-linewise (command &optional msg p actions)
+  "Send COMMAND to R process.
+COMMAND is a command string with %s placeholder for the
+arguments. MSG is the message displayed in minibuffer with %s
+placeholder for the package name. P is the value of universal
+argument usually received from the upstream command and indicates
+which action in ACTIONS list to perform; if 0 or nil, first
+action, if 1 or (4) second if 2 or (16) third etc. ACTIONS is a
+list of strings (R arguments), or functions which return R
+arguments, or expressions which return R arguments."
+  (inferior-ess-r-force)
+  (let ((pkg-info (ess-r-package-info))
+        (args (ess-r-command--build-args p actions)))
+    (unless (car pkg-info)
+      (user-error "Not in a package"))
+    (ess-project-save-buffers)
+    (message msg (plist-get pkg-info :name))
+    (display-buffer (ess-get-process-buffer))
+    (let ((pkg-path (concat "'" (abbreviate-file-name (plist-get pkg-info :root)) "'")))
+      (ess-eval-linewise (format command (concat pkg-path args))))))
+
+(defun ess-r-command--build-args (ix &optional actions)
+  (let* ((n (cond ((null ix) 0)
+                  ((listp ix) (round (log (car ix) 4)))
+                  ((integerp ix) ix)
+                  (t (error "Invalid index"))))
+         (action (nth n actions))
+         (args (cond ((null action) "")
+                     ((stringp action) action)
+                     ((functionp action) (funcall action))
+                     ((listp action) (eval action t))
+                     (t (error "Invalid action")))))
+    (if (string= "" args)
+        args
+      (concat ", " args))))
+
+\f
+;;;*;;; Devtools Integration
+
+(defun ess-r-devtools-load-package (&optional arg)
+  "Interface for `devtools::load_all()'.
+With prefix ARG ask for extra args."
+  (interactive "P")
+  (ess-r-package-eval-linewise
+   "devtools::load_all(%s)\n" "Loading %s" arg
+   '("" (read-string "Arguments: " "recompile = TRUE"))))
+
+(defun ess-r-devtools-unload-package ()
+  "Interface to `devtools::unload()'."
+  (interactive)
+  (ess-r-package-eval-linewise
+   "devtools::unload(%s)\n" "Unloading %s"))
+
+(defun ess-r-devtools-check-package (&optional arg)
+  "Interface for `devtools::check()'.
+With prefix ARG ask for extra args."
+  (interactive "P")
+  (ess-r-package-eval-linewise
+   "devtools::check(%s)\n" "Checking %s" arg
+   '("" (read-string "Arguments: " "vignettes = FALSE"))))
+
+(defun ess-r-devtools-check-with-winbuilder (&optional arg)
+  "Interface for `devtools::check_win_XYZ()'.
+With prefix argument, as for arguments to `devtools::check_win_XYZ()' function."
+  (interactive "P")
+  (let ((type (completing-read "Release: " '("devel" "release" "oldrelease") nil t)))
+    (ess-r-package-eval-linewise
+     (format "devtools:::check_win_%s(%%s)\n" type)
+     "Checking %s on CRAN's Windows server" arg
+     '("" (read-string "Arguments: ")))))
+
+(defvar ess-r-rhub--history nil)
+(declare-function ess-r-check-install-package "ess-r-mode.el")
+(defun ess-r-rhub-check-package (&optional arg)
+  "Interface for `rhub::check()'.
+With prefix ARG allow for editing of the `rhub::check_for_cran()' arguments."
+  (interactive "P")
+  (inferior-ess-r-force)
+  (ess-r-check-install-package "rhub")
+  (let* ((platforms (cons "RECOMMENDED" (ess-get-words-from-vector "rhub::platforms()$name\n")))
+         (platform (completing-read "Platform: " platforms nil t  nil
+                                    ess-r-rhub--history (car ess-r-rhub--history)))
+         (cmd (if (string= "RECOMMENDED" platform)
+                  "rhub::check_for_cran(%s)\n"
+                (format "rhub::check_for_cran(%%s, platforms = '%s')\n" platform)))
+         (msg (format "Checking %%s on RHUB (%s)" platform))
+         ;; Solaris check is flaky and it seems that solaris check is not run on
+         ;; CRAN itself with --as-cran options https://github.com/r-hub/rhub/issues/339
+         (args (cond ((string-match-p "solaris" platform)
+                      "check_args = c('--no-stop-on-test-error', '--no-vignettes')")
+                     (t "check_args = c('--as-cran', '--no-stop-on-test-error')"))))
+    (ess-r-package-eval-linewise cmd msg arg
+                                 `(,args (read-string "Arguments: " ,(concat args ", valgrind = FALSE"))))))
+
+(defun ess-r-devtools-build (&optional arg)
+  "Interface for `devtools::build()'.
+With prefix ARG, build with `vignettes = FALSE'."
+  (interactive "P")
+  (ess-r-package-eval-linewise
+   "devtools::build(%s)\n" "Building %s" arg
+   '("" "vignettes = FALSE")))
+
+(defun ess-r-devtools-test-package (&optional arg)
+  "Interface for `devtools::test()'.
+With prefix argument ARG, run tests on current file only."
+  (interactive "P")
+  (ess-r-package-eval-linewise
+   "devtools::test(%s)\n" "Testing %s" arg
+   '("" ess-r-devtools--cur-file-filter)))
+
+(defun ess-r-devtools--cur-file-filter ()
+  (let ((file (or (and buffer-file-name
+                       (file-name-nondirectory buffer-file-name))
+                  (error "Buffer not visiting a file"))))
+    (format "filter = \"%s\""
+            (if (string-match "test-\\([[:alnum:]_-]+\\)\\.[rR]" file)
+                (match-string-no-properties 1 file)
+              (file-name-base buffer-file-name)))))
+
+(defvar ess-r-devtools-revdep-check-cmd
+  "local({
+  pkg_path <- %s
+  res <- devtools::revdep_check(pkg_path)
+
+  if (file.exists(file.path(pkg_path, 'revdep'))) {
+    save_path <- file.path(pkg_path, 'revdep')
+  } else {
+    save_path <- file.path(pkg_path, '.metadata', 'revdep')
+  }
+  devtools::revdep_check_save_summary(res, save_path)
+
+  logs_path <- file.path(save_path, 'logs')
+  if (!dir.exists(logs_path)) {
+    dir.create(logs_path)
+  }
+  devtools::revdep_check_save_logs(res, logs_path)
+})
+")
+
+(defun ess-project-save-buffers ()
+  "Offer to save modified files in the current project.
+Respects `ess-save-silently', which see."
+  (let ((cur-proj ess-r-package--info-cache))
+    (dolist (buf (buffer-list))
+      (when-let ((file (buffer-file-name buf))
+                 (buf-proj (buffer-local-value 'ess-r-package--info-cache buf)))
+        (when (equal cur-proj buf-proj)
+          (ess-save-file file))))))
+
+(defun ess-r-devtools-document-package (&optional arg)
+  "Interface for `devtools::document()'.
+With prefix ARG ask for extra arguments."
+  (interactive "P")
+  (ess-r-package-eval-linewise
+   "devtools::document(%s)\n" "Documenting %s" arg
+   '("" (read-string "Arguments: "))))
+
+(defun ess-r-devtools-install-package (&optional arg)
+  "Interface to `devtools::install()'.
+By default the installation is \"quick\" with arguments quick =
+TRUE, upgrade = FALSE, build = FALSE. On prefix ARG
+\\[universal-argument] install with the default
+`devtools::install()' arguments."
+  (interactive "P")
+  (ess-r-package-eval-linewise
+   "devtools::install(%s)\n" "Installing %s" arg
+   '("quick = TRUE, build = FALSE, upgrade = FALSE, keep_source = TRUE"
+     (read-string "Arguments: " "keep_source = TRUE, force = TRUE"))))
+
+(defvar ess-r-devtools--install-github-history nil)
+(defun ess-r-devtools-install-github (&optional arg)
+  "Interface to `devtools::install_github()'.
+Asks for GitHub repository in the form of user/repo. Force
+re-installation when called with a prefix ARG."
+  (interactive "P")
+  (let ((command "devtools::install_github(%s%s)")
+        (repo (format "'%s'"
+                      (read-string "User/Repo: " nil
+                                   'ess-r-devtools--install-github-history
+                                   (car ess-r-devtools--install-github-history))))
+        (args (if arg
+                  (ess-r-command--build-args 0 '((read-string "Arguments: " "force = TRUE")))
+                "")))
+    (inferior-ess-r-force)
+    (unless (derived-mode-p 'inferior-ess-mode)
+      (display-buffer (ess-get-process-buffer)
+                      '(nil . ((inhibit-same-window . t)))))
+    (message "Installing %s from github" repo)
+    (ess-eval-linewise (format command repo args))))
+
+(defun ess-r-devtools-create-package ()
+  "Interface to `devtools::create()'.
+Default location is determined by the first element of
+`ess-r-package-library-paths'."
+  (interactive)
+  (let* ((command "devtools::create(\"%s\")")
+         (default-path (if (stringp ess-r-package-library-paths)
+                           ess-r-package-library-paths
+                         (car ess-r-package-library-paths)))
+         (path (read-directory-name "Path: " default-path)))
+    (ess-eval-linewise (format command path))))
+
+(defun ess-r-devtools-execute-command (&optional arg)
+  "Asks with completion for a devtools command.
+When called with prefix ARG asks for additional arguments."
+  (interactive "P")
+  (inferior-ess-r-force)
+  (let* ((devtools-funs (ess-get-words-from-vector ".ess_devtools_functions()\n"))
+         (fun (completing-read "Function: " devtools-funs))
+         (command (format "devtools::%s(%%s)\n" fun)))
+    (ess-r-package-eval-linewise
+     command (format "Running %s" fun) arg
+     '("" (read-string "Arguments: ")))))
+
+\f
+;;;*;;; Minor Mode
+
+(defcustom ess-r-package-auto-activate t
+  "If non-nil, `ess-r-package-mode' is turned on within R packages.
+If `t' the minor mode auto-activates in R packages. See
+`ess-r-package-exclude-modes' if you wish to inhibit
+`ess-r-package-mode' in specific buffers."
+  :group 'ess-r-package
+  :type 'boolean)
+
+(defcustom ess-r-package-exclude-modes '(fundamental-mode)
+  "A list of modes where `ess-r-package' must not be activated.
+The check is done with `derived-mode-p'."
+  :group 'ess-r-package
+  :type '(repeat symbol)
+  :package-version '(ess "18.10"))
+
+(defcustom ess-r-package-enter-hook nil
+  "Normal hook run on entering `ess-r-package-mode'."
+  :group 'ess-r-package
+  :type 'hook)
+
+(defcustom ess-r-package-exit-hook nil
+  "Normal hook run on exiting `ess-r-package-mode'."
+  :group 'ess-r-package
+  :type 'hook)
+
+(defcustom ess-r-package-mode-line
+  ;; FIXME Emacs 25.1: Use `when-let'
+  '(:eval (let ((pkg-name (ess-r-package-name)))
+            (when pkg-name
+              (format " [pkg:%s]" pkg-name))))
+  "Mode line for ESS developer.
+Set this variable to nil to disable the mode line entirely."
+  :group 'ess-r-package
+  :type 'sexp
+  :risky t)
+
+(defvar ess-r-package-mode-map
+  (let ((ess-r-package-mode-map (make-sparse-keymap)))
+    (define-key ess-r-package-mode-map "\C-c\C-w" 'ess-r-package-dev-map)
+    ess-r-package-mode-map))
+
+(define-minor-mode ess-r-package-mode
+  "Minor mode for enabling R package development features.
+
+\\{ess-r-package-mode-map}"
+  :init-value nil
+  :keymap ess-r-package-mode-map
+  :lighter ess-r-package-mode-line
+  (if ess-r-package-mode
+      (progn
+        ;; Forward relevant R settings for interacting with inferior
+        ;; processes from any mode
+        (let ((vars '(ess-dialect
+                      ess-setwd-command
+                      ess-getwd-command
+                      ess-quit-function
+                      inferior-ess-reload-function)))
+          (mapc (lambda (var)
+                  (set (make-local-variable var)
+                       (eval (cdr (assq var ess-r-customize-alist)) t)))
+                vars))
+        (add-hook 'project-find-functions #'ess-r-project nil 'local)
+        (run-hooks 'ess-r-package-enter-hook))
+    (remove-hook 'project-find-functions #'ess-r-project)
+    (run-hooks 'ess-r-package-exit-hook)))
+
+(add-hook 'after-change-major-mode-hook #'ess-r-package-auto-activate)
+
+\f
+;;;*;;; Activation
+
+(defun ess-r-package-auto-activate ()
+  "Activate developer if current file is part of a package."
+  (when (and ess-r-package-auto-activate
+             (or (buffer-name) default-directory)
+             (not (eq major-mode 'minibuffer-inactive-mode))
+             (or
+              ;; users probably have these in fundamental mode
+              (member (buffer-name) '("DESCRIPTION" "NAMESPACE"))
+              (if ess-r-package-exclude-modes
+                  (not (apply #'derived-mode-p ess-r-package-exclude-modes))
+                t)))
+    (when (car (ess-r-package-info))
+      (ess-r-package-mode 1))))
+
+(defun ess-r-package-re-activate ()
+  "Restart `ess-r-package-mode'.
+First, deactivate package mode if active, and activate if in
+package mode. Use this function if state of the buffer such as
+`default-directory' has changed."
+  (when ess-r-package-mode
+    (ess-r-package-mode -1))
+  (setq ess-r-package--info-cache nil)
+  (ess-r-package-auto-activate))
+
+(defvar-local ess-r--old-default-dir nil)
+(defun ess-r-package-default-directory-tracker (&rest _)
+  (unless (equal ess-r--old-default-dir default-directory)
+    (setq ess-r--old-default-dir default-directory)
+    (ess-r-package-re-activate)))
+
+(defun ess-r-package-activate-directory-tracker ()
+  (add-hook 'after-change-functions #'ess-r-package-default-directory-tracker t t))
+
+(add-hook 'shell-mode-hook #'ess-r-package-activate-directory-tracker t)
+(add-hook 'eshell-mode-hook #'ess-r-package-activate-directory-tracker t)
+;; (require 'shell)
+(advice-add 'shell-resync-dirs :after #'ess-r-package-re-activate)
+
+\f
+;;;*;;; Deprecated variables and functions
+(defun ess-developer (&optional _val)
+  (error "As of ESS 16.04, `ess-developer' is deprecated. Use `ess-r-set-evaluation-env' instead"))
+
+(defalias 'ess-toggle-developer #'ess-developer)
+(define-obsolete-function-alias 'ess-r-devtools-check-package-buildwin #'ess-r-devtools-check-with-winbuilder "18.04")
+(define-obsolete-function-alias 'ess-r-devtools-ask #'ess-r-devtools-execute-command "18.04")
+
+(make-obsolete-variable 'ess-developer "Please use `ess-developer-select-package' and `ess-r-set-evaluation-env' instead." "16.04")
+(make-obsolete-variable 'ess-developer-root-file "Please use `ess-r-package-root-file' instead." "16.04")
+(make-obsolete-variable 'ess-developer-packages "Please use `ess-r-package-set-package' and `ess-r-set-evaluation-env' instead." "16.04")
+(make-obsolete-variable 'ess-developer-load-on-add-commands "Please use `ess-r-package-set-package' and `ess-r-set-evaluation-env' instead." "16.04")
+(make-obsolete-variable 'ess-developer-activate-in-package "Please use `ess-r-package-auto-activate' instead." "16.04")
+(make-obsolete-variable 'ess-developer-enter-hook "Please use `ess-r-package-enter-hook' instead." "16.04")
+(make-obsolete-variable 'ess-developer-exit-hook "Please use `ess-r-package-exit-hook' instead." "16.04")
+
+\f
+(provide 'ess-r-package)
+
+;;; ess-r-package.el ends here
diff --git a/elpa/ess-20260424.1544/ess-r-syntax.el b/elpa/ess-20260424.1544/ess-r-syntax.el
new file mode 100644 (file)
index 0000000..0262468
--- /dev/null
@@ -0,0 +1,1251 @@
+;;; ess-r-syntax.el --- Utils to work with R code  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015-2026 Free Software Foundation, Inc.
+;; Author: Lionel Henry <lionel.hryNOSPAMgmail.com>
+;; Created: 12 Oct 2015
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; API is not yet stable.
+
+;;; Code:
+
+(require 'ess-utils)
+(require 'regexp-opt)
+
+(eval-when-compile
+  (require 'cl-lib))
+
+\f
+;;*;; Utils
+
+;; The three following wrappers return t if successful, nil on error
+(defun ess-backward-sexp (&optional N)
+  (ess-forward-sexp (- (or N 1))))
+
+(defun ess-forward-sexp (&optional N)
+  (or N (setq N 1))
+  (condition-case nil
+      (prog1 t
+        (goto-char (or (scan-sexps (point) N)
+                       (buffer-end N))))
+    (error nil)))
+
+(defun ess-up-list (&optional N)
+  (condition-case nil
+      (let (forward-sexp-function)
+        (progn (up-list N) t))
+    (error nil)))
+
+(defun ess-backward-up-list (&optional N)
+  (ess-up-list (- (or N 1))))
+
+(defun ess-forward-char (&optional N)
+  (unless (= (point) (point-max))
+    (forward-char (or N 1))
+    t))
+
+(defun ess-backward-char (&optional N)
+  (unless (bobp)
+    (forward-char (- (or N 1)))
+    t))
+
+(defun ess-goto-char (pos)
+  "Go to POS if it is non-nil.
+If POS is nil, return nil.  Otherwise return position itself."
+  (when pos
+    (goto-char pos)))
+
+(defun ess-looking-at (regex &optional newlines)
+  "Like `looking-at' but consumes blanks and comments first."
+  (save-excursion
+    (ess-skip-blanks-forward newlines)
+    (looking-at regex)))
+
+(defmacro ess-save-excursion-when-nil (&rest body)
+  (declare (indent 0)
+           (debug (&rest form)))
+  `(let ((orig-point (point)))
+     (cond ((progn ,@body))
+           (t (prog1 nil
+                (goto-char orig-point))))))
+
+(defmacro ess-while (test &rest body)
+  "Like `while' for TEST but return t when BODY gets executed once."
+  (declare (indent 1)
+           (debug (&rest form)))
+  `(let (executed)
+     (while ,test
+       (setq executed t)
+       ,@body)
+     executed))
+
+(defmacro ess-at-indent-point (&rest body)
+  (declare (indent 0)
+           (debug (&rest form)))
+  `(save-excursion
+     (goto-char indent-point)
+     (back-to-indentation)
+     (progn ,@body)))
+
+(defvar containing-sexp)
+(defmacro ess-at-containing-sexp (&rest body)
+  (declare (indent 0)
+           (debug (&rest form)))
+  '(when (not (bound-and-true-p containing-sexp))
+     (error "Internal error: containing-sexp is nil or undefined"))
+  `(save-excursion
+     (goto-char containing-sexp)
+     (progn ,@body)))
+
+(defmacro ess-any (&rest forms)
+  "Evaluate all arguments and return non-nil if one of the arguments is non-nil.
+This is useful to trigger side-effects. FORMS follows the same
+syntax as arguments to `cond'."
+  (declare (indent 0) (debug nil))
+  `(let ((forms (list ,@(mapcar (lambda (form) `(progn ,@form)) forms))))
+     (cl-some #'identity (mapcar (lambda (e) (eval e t)) forms))))
+
+(defun ess-char-syntax (string)
+  (char-to-string (char-syntax (string-to-char string))))
+
+\f
+;;*;; Tokenisation
+
+(defun ess-token-type (token) (car (nth 0 token)))
+(defun ess-token-value (token) (cdr (nth 0 token)))
+(defun ess-token-start (token) (car (nth 1 token)))
+(defun ess-token-end (token) (cdr (nth 1 token)))
+
+(defun ess-token-refined-type (token)
+  (ess-token-type (ess-refine-token token)))
+
+(defun ess-token-after (&optional token)
+  "Return next TOKEN.
+Cons cell containing the token type and string representation."
+  (save-excursion
+    (when token
+      (goto-char (ess-token-end token)))
+    (ess-jump-token)))
+
+(defun ess-token-before (&optional token)
+  "Return previous TOKEN.
+Cons cell containing the token type and string representation."
+  (save-excursion
+    (when token
+      (goto-char (ess-token-start token)))
+    (ess-climb-token)))
+
+(defun ess-climb-token (&optional type string)
+  (ess-save-excursion-when-nil
+    (ess-escape-comment)
+    (ess-skip-blanks-backward t)
+    (let ((token (or (ess-climb-token--back)
+                     (ess-climb-token--back-and-forth)
+                     (progn (forward-char -1) (ess-token-after)))))
+      (if (or type string)
+          (when (ess-token= token type string)
+            token)
+        token))))
+
+(defun ess-token--cons (type value)
+  (if (eq type 'self)
+      (cons value nil)
+    (cons type value)))
+
+(defun ess-climb-token--back ()
+  (let* ((token-end (point))
+         (token-type (if (bobp)
+                         "buffer-start"
+                       (ess-climb-token--operator)))
+         (token-value (buffer-substring-no-properties (point) token-end)))
+    (unless (null token-type)
+      (list (ess-token--cons token-type token-value)
+            (cons (point) token-end)))))
+
+(defsubst ess-climb-token--char (&rest chars)
+  (ess-while (and chars
+                  (eq (char-before) (car chars))
+                  (ess-backward-char))
+    (setq chars (cdr chars))))
+
+;; Difficult to use regexps here because we want to match greedily
+;; backward
+(defun ess-climb-token--operator ()
+  (when (pcase (char-before)
+          ((or `?+ `?/ `?^ `?~ `?? `?!)
+           (ess-backward-char))
+          (`?=
+           (prog1 (ess-backward-char)
+             (or (ess-climb-token--char ?=)
+                 (ess-climb-token--char ?!)
+                 (ess-climb-token--char ?:)
+                 (ess-climb-token--char ?>)
+                 (ess-climb-token--char ?<))))
+          ((or `?& `?| `?* `?@ `?$)
+           (prog1 (ess-backward-char)
+             (ess-climb-token--char (char-after))))
+          (`?<
+           (ess-backward-char))
+          (`?>
+           (prog1 (ess-backward-char)
+             (or (ess-climb-token--char ?|)
+                 (ess-climb-token--char ?=)
+                 (ess-climb-token--char ?-)
+                 (and (looking-back "->" (- (point) 2))
+                      (goto-char (- (point) 2))))))
+          (`?-
+           (prog1 (ess-backward-char)
+             (ess-climb-token--char ?< ?<)))
+          (`?:
+           (prog1 (ess-backward-char)
+             (ess-climb-token--char ?: ?:))))
+    'self))
+
+(defun ess-climb-token--back-and-forth ()
+  (let ((limit (point)))
+    (when (ess-skip-token-backward)
+      (save-restriction
+        (narrow-to-region (point) limit)
+        (ess-token-after)))))
+
+(defun ess-skip-token-backward ()
+  (ess-save-excursion-when-nil
+    (cond
+     ;; Punctuation
+     ((memq (char-before) '(?, ?\;))
+      (ess-backward-char))
+     ;; Quoting delimiters
+     ((memq (char-syntax (char-before)) '(?\" ?$))
+      (ess-backward-sexp))
+     ;; Syntaxic delimiters
+     ((memq (char-syntax (char-before)) '(?\( ?\)))
+      (prog1 (ess-backward-char)
+        ;; Also skip double brackets
+        (ess-save-excursion-when-nil
+          (when (let ((current-delim (char-after)))
+                  (ess-skip-blanks-backward)
+                  (and (memq (char-before) '(?\[ ?\]))
+                       (eq current-delim (char-before))))
+            (ess-backward-char)))))
+     ;; Identifiers and numbers
+     ((/= (skip-syntax-backward "w_") 0)))))
+
+(defun ess-jump-token (&optional type string)
+  "Consume a token forward.
+Return a cons cell containing the token type and the token string
+content. Return nil when the end of the buffer is reached."
+  (ess-save-excursion-when-nil
+    (ess-skip-blanks-forward t)
+    (let* ((token-start (point))
+           (token-type (or (ess-jump-token--regexps)
+                           (ess-jump-token--literal)
+                           (ess-jump-token--infix-op)
+                           (ess-jump-token--punctuation)
+                           (progn (forward-char) "unknown")))
+           (token-value (buffer-substring-no-properties token-start (point))))
+      (let ((token (list (ess-token--cons token-type token-value)
+                         (cons token-start (point)))))
+        (if (or type string)
+            (when (ess-token= token type string)
+              token)
+          token)))))
+
+(defun ess-jump-token--literal ()
+  (cond
+   ;; Simply assume anything starting with a digit is a number. May be
+   ;; too liberal but takes care of fractional numbers, integers such
+   ;; as 10L, etc. False positives are not valid R code anyway.
+   ((looking-at "[0-9]")
+    (ess-forward-sexp)
+    "number")
+   ((or (looking-at "\\sw\\|\\s_")
+        (eq (char-after) ?`))
+    (ess-forward-sexp)
+    "identifier")
+   ((memq (char-after) '(?\" ?\'))
+    (ess-forward-sexp)
+    "string")))
+
+(defun ess-jump-token--punctuation ()
+  (or (when (= (point) (point-max))
+        "buffer-end")
+      (pcase (char-after)
+        (`?\;
+         (forward-char)
+         'self)
+        (`?,
+         (forward-char)
+         ;; Treat blanks after comma as part of an argument
+         (ess-skip-blanks-forward t)
+         ","))))
+
+(defvar ess-r-prefix-keywords-list
+  '("if" "for" "while" "function"))
+
+(defvar ess-r-keywords-list
+  (append ess-r-prefix-keywords-list '("else")))
+
+(defvar ess-r-delimiters-list
+  '("(" ")" "{" "}" "[" "]" "[[" "]]"))
+
+(defvar ess-r-operators-list
+  '("+" "-" "*" "/" "%%" "**" "^"
+    "%*%" "%/%" "%in%" "%notin%" "%o%" "%x%" "%||%" ; = ls(pattern =  "^%", baseenv())
+    "&" "&&" "|" "||" "!" "?" "~"
+    "==" "!=" "<" "<=" ">=" ">"
+    "=" "<-" "<<-" "->" "->>"
+    "$" "@" ":" "::" ":::" ":="
+    "|>" "=>"))
+
+(defvar ess-r-keywords-re
+  (concat (regexp-opt ess-r-keywords-list) "\\_>"))
+
+(defvar ess-r-delimiters-re
+  (regexp-opt ess-r-delimiters-list))
+
+(defvar ess-r-operators-re
+  (regexp-opt ess-r-operators-list))
+
+(defun ess-jump-token--regexps ()
+  (when (or (looking-at ess-r-keywords-re)
+            (looking-at ess-r-delimiters-re)
+            (looking-at ess-r-operators-re))
+    (goto-char (match-end 0))
+    'self))
+
+(defun ess-jump-token--infix-op ()
+  (or (when (looking-at ess-r-operators-re)
+        (goto-char (match-end 0))
+        'self)
+      (when (eq (char-after) ?%)
+        (ess-forward-sexp)
+        "%infix%")))
+
+(defun ess-refine-token (token)
+  (let ((refined-type
+         (pcase (ess-token-type token)
+           ;; Parameter assignment
+           (`"="
+            (save-excursion
+              (goto-char (ess-token-start token))
+              (let ((containing-sexp (ess-containing-sexp-position)))
+                (when (and containing-sexp
+                           (ess-at-containing-sexp
+                             (and (ess-token-after= "(")
+                                  (ess-token-before= '("identifier" "string"))))
+                           (save-excursion
+                             (and (ess-climb-token)
+                                  (ess-token-before= '("," "(")))))
+                  "param-assign"))))
+           ;; Quoted identifiers
+           (`"string"
+            (when (or
+                   ;; Quoted parameter names
+                   (ess-refined-token= (ess-token-after) "param-assign")
+                   ;; Quoted call names
+                   (ess-token-after= "("))
+              "identifier"))
+           ((or `"(" `")")
+            (or (save-excursion
+                  (if (ess-token-close-delimiter-p token)
+                      (ess-climb-paired-delims nil token)
+                    (goto-char (ess-token-start token)))
+                  (when (ess-token-keyword-p (ess-token-before))
+                    "prefixed-expr-delimiter"))
+                ;; Fixme: probably too crude. Better handled in parser
+                (when (ess-token= token ")")
+                  (save-excursion
+                    (ess-climb-paired-delims ")" token)
+                    (when (ess-token-before= '("identifier" "string" ")" "]" "]]" "}"))
+                      "argslist-delimiter")))))
+           ((or `"{" `"}")
+            (save-excursion
+              (unless (ess-climb-paired-delims "}" token)
+                (goto-char (ess-token-start token)))
+              (when (ess-refined-token= (ess-token-before) "prefixed-expr-delimiter")
+                "prefixed-expr-delimiter"))))))
+    (if refined-type
+        (list (cons refined-type (ess-token-value token))
+              (nth 1 token))
+      token)))
+
+
+;;;*;;; Token predicates
+
+(defun ess-token= (token &optional type string)
+  (when (and (null type)
+             (null string))
+    (error "No condition supplied"))
+  (let ((type (if (stringp type) (list type) type))
+        (string (if (stringp string) (list string) string)))
+    (and (if type (member (ess-token-type token) type) t)
+         (if string (member (ess-token-value token) string) t))))
+
+(defun ess-refined-token= (token type &optional string)
+  (ess-token= (ess-refine-token token) type string))
+
+(defun ess-token-after= (type &optional string)
+  (ess-token= (ess-token-after) type string))
+
+(defun ess-token-before= (type &optional string)
+  (ess-token= (ess-token-before) type string))
+
+(defun ess-token-open-delimiter-p (token)
+  (string= (ess-char-syntax (ess-token-type token)) "("))
+
+(defun ess-token-close-delimiter-p (token)
+  (string= (ess-char-syntax (ess-token-type token)) ")"))
+
+(defun ess-token-delimiter-p (token)
+  (or (ess-token-open-delimiter-p token)
+      (ess-token-close-delimiter-p token)))
+
+(defun ess-token-operator-p (token &optional strict)
+  (and (or (member (ess-token-type token) ess-r-operators-list)
+           (string= (ess-token-type token) "%infix%"))
+       (or (null strict)
+           (not (ess-refined-token= token "param-assign")))))
+
+(defun ess-token-keyword-p (token)
+  (member (ess-token-type token) ess-r-keywords-list))
+
+
+;;*;; Point predicates
+
+(defun ess-inside-call-p (&optional call)
+  "Return non-nil if point is in a function or indexing call."
+  (let ((containing-sexp (or (bound-and-true-p containing-sexp)
+                             (ess-containing-sexp-position))))
+    (save-excursion
+      (and (prog1 (ess-goto-char containing-sexp)
+             (ess-climb-chained-delims))
+           (save-excursion
+             (forward-char)
+             (ess-up-list))
+           (or (ess-behind-call-opening-p "(")
+               (looking-at "\\["))
+           (ess-inside-call-name-p call)))))
+
+(defun ess-inside-continuation-p ()
+  (unless (or (looking-at ",")
+              (ess-behind-call-opening-p "[[(]"))
+    (or (save-excursion
+          (ess-jump-object)
+          (and (not (ess-ahead-param-assign-p))
+               (ess-behind-operator-p)))
+        (save-excursion
+          (ess-climb-object)
+          (ess-climb-operator)
+          (and (ess-behind-operator-p)
+               (not (ess-ahead-param-assign-p)))))))
+
+(defun ess-inside-call-name-p (&optional call)
+  (save-excursion
+    (ess-climb-call-name call)))
+
+(defun ess-inside-prefixed-block-p (&optional call)
+  "Return non-nil if point is in a prefixed block.
+Prefixed blocks refer to the blocks following function
+declarations, control flow statements, etc.
+
+If CALL is not nil, check if the prefix corresponds to CALL. If
+nil, return the prefix."
+  (save-excursion
+    (ess-escape-prefixed-block call)))
+
+\f
+;;*;; Syntactic Travellers and Predicates
+
+;;;*;;; Blanks, Characters, Comments and Delimiters
+
+(defun ess-skip-blanks-backward (&optional newlines)
+  "Skip blanks and newlines backward, taking end-of-line comments into account."
+  (ess-any ((ess-skip-blanks-backward-1))
+           ((when newlines
+              (ess-while (and (not (bobp))
+                              (= (point) (line-beginning-position)))
+                (forward-line -1)
+                (goto-char (ess-code-end-position))
+                (ess-skip-blanks-backward-1))))))
+
+(defun ess-skip-blanks-backward-1 ()
+  (and (not (bobp))
+       (/= 0 (skip-syntax-backward " "))))
+
+(defun ess-skip-blanks-forward (&optional newlines)
+  "Skip blanks and newlines forward, taking end-of-line comments into account."
+  (ess-any ((/= 0 (skip-syntax-forward " ")))
+           ((ess-while (and newlines
+                            (= (point) (ess-code-end-position))
+                            (when (ess-save-excursion-when-nil
+                                    ;; Handles corner cases such as point being on last line
+                                    (let ((orig-point (point)))
+                                      (forward-line)
+                                      (back-to-indentation)
+                                      (> (point) orig-point)))
+                              (skip-chars-forward " \t")
+                              t))))))
+
+(defun ess-jump-char (char)
+  (ess-save-excursion-when-nil
+    (ess-skip-blanks-forward t)
+    (when (looking-at char)
+      (goto-char (match-end 0)))))
+
+(defun ess-escape-comment ()
+  (when (ess-inside-comment-p)
+    (prog1 (comment-beginning)
+     (skip-chars-backward "#+[ \t]*"))))
+
+(defun ess-ahead-closing-p ()
+  (memq (char-before) '(?\] ?\} ?\))))
+
+(defun ess-ahead-boundary-p ()
+  (looking-back "[][ \t\n(){},]" (1- (point))))
+
+(defun ess-escape-string ()
+  (and (nth 3 (syntax-ppss))
+       (ess-goto-char (nth 8 (syntax-ppss)))))
+
+(defun ess-climb-paired-delims (&optional type token)
+  (ess-save-excursion-when-nil
+    (let ((token (or token (ess-token-before))))
+      (goto-char (ess-token-end token))
+      (when (if type
+                (ess-token= token type)
+              (ess-token-delimiter-p token))
+        (and (ess-backward-sexp)
+             (ess-token-after))))))
+
+(defun ess-jump-paired-delims (&optional type token)
+  (ess-save-excursion-when-nil
+    (let ((token (or token (ess-token-after))))
+      (goto-char (ess-token-start token))
+      (when (if type
+                (ess-token= token type)
+              (ess-token-delimiter-p token))
+        (and (ess-forward-sexp)
+             (ess-token-before))))))
+
+\f
+;;;*;;; Blocks
+
+(defun ess-block-opening-p ()
+  (save-excursion
+    (cond
+     ((looking-at "{"))
+     ;; Opening parenthesis not attached to a function opens up a
+     ;; block too. Only pick up those that are last on their line
+     ((ess-behind-block-paren-p)))))
+
+(defun ess-block-closing-p ()
+  (save-excursion
+    (cond
+     ((looking-at "}"))
+     ((looking-at ")")
+      (forward-char)
+      (backward-sexp)
+      (not (looking-back
+            (concat ess-r-name-pattern "[[:blank:]]*")
+            (line-beginning-position)))))))
+
+(defun ess-block-p ()
+  (or (save-excursion
+        (when containing-sexp
+          (goto-char containing-sexp)
+          (ess-block-opening-p)))
+      (ess-unbraced-block-p)))
+
+;; Parenthesised expressions
+(defun ess-behind-block-paren-p ()
+  (and (looking-at "(")
+       (not (ess-ahead-attached-name-p))))
+
+(defun ess-climb-block (&optional ignore-ifelse)
+  (ess-save-excursion-when-nil
+    (cond
+     ((and (not ignore-ifelse)
+           (ess-climb-if-else 'to-start)))
+     ((and (eq (char-before) ?\})
+           (prog2
+               (forward-char -1)
+               (ess-up-list -1)
+             (ess-climb-block-prefix)))))))
+
+(defvar ess-prefixed-block-patterns
+  (mapcar (lambda (fun) (concat fun "[ \t\n]*("))
+          '("function" "if" "for" "while")))
+
+(defun ess-behind-prefixed-block-p (&optional call)
+  (if call
+      (looking-at (concat call "[ \t]*("))
+    (cl-some #'looking-at ess-prefixed-block-patterns)))
+
+(defun ess-unbraced-block-p (&optional ignore-ifelse)
+  "This indicates whether point is in front of an unbraced
+prefixed block following a control flow statement. Returns
+position of the control flow function (if, for, while, etc)."
+  (save-excursion
+    (and (ess-backward-sexp)
+         (or (and (looking-at "else\\b")
+                  (not ignore-ifelse))
+             (and (looking-at "(")
+                  (ess-backward-sexp)
+                  (cl-some #'looking-at ess-prefixed-block-patterns)
+                  (if ignore-ifelse
+                      (not (looking-at "if\\b"))
+                    t)))
+         (point))))
+
+(defun ess-climb-block-prefix (&optional call ignore-ifelse)
+  "Climb the prefix of a prefixed block.
+Prefixed blocks refer to the blocks following function
+declarations, control flow statements, etc.
+
+Should be called either in front of a naked block or in front
+of the curly brackets of a braced block.
+
+If CALL not nil, check if the prefix corresponds to CALL. If nil,
+return the prefix."
+  (ess-save-excursion-when-nil
+    (or (and (not ignore-ifelse)
+             (prog1 (and (ess-climb-if-else-call)
+                         (or (null call)
+                             (looking-at call)))
+               (when (ess-token-after= "else")
+                 (ess-climb-token "}"))))
+        (let ((pos (ess-unbraced-block-p ignore-ifelse)))
+          (and (ess-goto-char pos)
+               (if call
+                   (looking-at call)
+                 (cond ((looking-at "function")
+                        "function")
+                       ((looking-at "for")
+                        "for")
+                       ((looking-at "if")
+                        "if")
+                       ((looking-at "else")
+                        "else"))))))))
+
+(defun ess-escape-prefixed-block (&optional call)
+  "Climb outside of a prefixed block."
+  (let ((containing-sexp (or (bound-and-true-p containing-sexp)
+                             (ess-containing-sexp-position))))
+    (or (ess-save-excursion-when-nil
+          (and (ess-goto-char containing-sexp)
+               (looking-at "{")
+               (ess-climb-block-prefix call)))
+        (ess-escape-unbraced-block call))))
+
+(defun ess-escape-unbraced-block (&optional call)
+  (ess-save-excursion-when-nil
+    (while (and (not (ess-unbraced-block-p))
+                (or (ess-escape-continuations)
+                    (ess-escape-call))))
+    (ess-climb-block-prefix call)))
+
+(defun ess-jump-block ()
+  (cond
+   ;; if-else blocks
+   ((ess-jump-if-else))
+   ;; Prefixed blocks such as `function() {}'
+   ((ess-behind-prefixed-block-p)
+    (ess-jump-prefixed-block))
+   ;; Naked blocks
+   ((and (or (looking-at "{")
+             (ess-behind-block-paren-p))
+         (ess-forward-sexp)))))
+
+(defun ess-jump-prefixed-block (&optional call)
+  (ess-save-excursion-when-nil
+    (when (ess-behind-prefixed-block-p call)
+      (ess-forward-sexp 2)
+      (ess-skip-blanks-forward t)
+      (if (looking-at "{")
+          (ess-forward-sexp)
+        (prog1 (ess-jump-expression)
+          (ess-jump-continuations))))))
+
+\f
+;;;*;;; Calls
+
+(defun ess-call-closing-p ()
+  (save-excursion
+    (when (cond ((looking-at ")")
+                 (ess-up-list -1))
+                ((looking-at "]")
+                 (when (ess-up-list -1)
+                   (prog1 t (ess-climb-chained-delims)))))
+      (ess-ahead-attached-name-p))))
+
+(defun ess-behind-call-opening-p (pattern)
+  (and (looking-at pattern)
+       (ess-ahead-attached-name-p)))
+
+;; Should be called just before the opening brace
+(defun ess-ahead-attached-name-p ()
+  (save-excursion
+    (ess-climb-object)))
+
+(defun ess-ahead-param-assign-p ()
+  "Return non-nil if looking at a function argument.
+To be called just before the `=' sign."
+  (ess-refined-token= (ess-token-before) "param-assign"))
+
+(defun ess-behind-arg-p ()
+  (save-excursion
+    (ess-jump-arg)))
+
+(defun ess-behind-parameter-p ()
+  (save-excursion
+    (ess-jump-parameter)))
+
+(defun ess-jump-parameter ()
+  (ess-save-excursion-when-nil
+    (and (ess-jump-name)
+         (when (looking-at "[ \t]*=\\([^=]\\)")
+           (goto-char (match-beginning 1))
+           (ess-skip-blanks-forward)
+           t))))
+
+(defun ess-jump-arg ()
+  (ess-save-excursion-when-nil
+    (ess-skip-blanks-forward t)
+    (ess-any ((ess-jump-parameter))
+             ((ess-jump-expression))
+             ((ess-jump-continuations)))))
+
+(defun ess-arg-bounds ()
+  "Should be called in front of the argument."
+  (save-excursion
+    (let ((beg (point)))
+      (and (ess-jump-arg)
+           (list beg (point))))))
+
+(defun ess-climb-call (&optional call)
+  "Climb functions (e.g. ggplot) and parenthesised expressions."
+  (or (ess-while (ess-save-excursion-when-nil
+                   (ess-climb-name)
+                   (and (ess-climb-chained-delims ?\])
+                        ;; (ess-climb-expression)
+                        (if (eq (char-before) ?\))
+                            (ess-climb-call)
+                          (ess-climb-name))
+                        )))
+      (ess-save-excursion-when-nil
+        (when (and (memq (char-before) '(?\] ?\) ?\}))
+                   (ess-backward-sexp))
+          (if call
+              (and (ess-climb-name)
+                   (looking-at call)))
+          (prog1 t
+            (ess-climb-name))))))
+
+(defun ess-climb-call-name (&optional call)
+  (ess-save-excursion-when-nil
+    (ess-jump-name)
+    (ess-skip-blanks-forward)
+    (and (ess-behind-call-opening-p "[[(]")
+         (ess-climb-name)
+         (or (null call)
+             (looking-at call)))))
+
+(defun ess-step-to-first-arg ()
+  (let ((containing-sexp (ess-containing-sexp-position)))
+    (cond ((ess-inside-call-p)
+           (goto-char containing-sexp)
+           (forward-char)
+           t)
+          ((ess-inside-call-name-p)
+           (ess-jump-name)
+           (ess-skip-blanks-forward)
+           (forward-char)
+           t))))
+
+(defun ess-jump-to-next-arg ()
+  (and (ess-jump-arg)
+       (prog1 (ess-jump-char ",")
+         (ess-skip-blanks-forward t))))
+
+(defun ess-jump-call ()
+  (ess-save-excursion-when-nil
+    (or (and (ess-jump-object)
+             (cond ((eq (char-before) ?\)))
+                   ((looking-at "\\[")
+                    (ess-jump-chained-brackets))
+                   ((looking-at "(")
+                    (ess-forward-sexp))))
+        (and (looking-at "[ \t]*(")
+             (ess-forward-sexp)))))
+
+(defun ess-behind-call-p ()
+  (save-excursion
+    (ess-jump-object)
+    (ess-skip-blanks-forward)
+    (looking-at "[[(]")))
+
+(defun ess-climb-chained-delims (&optional delim)
+  "Should be called with point between delims, e.g. `]|['."
+  (setq delim (if delim
+                  (list delim)
+                '(?\] ?\))))
+  (ess-while (ess-save-excursion-when-nil
+               (when (memq (char-before) delim)
+                 (ess-backward-sexp)))))
+
+(defun ess-jump-chained-brackets ()
+  (ess-while (ess-save-excursion-when-nil
+               (when (eq (char-after) ?\[)
+                 (ess-forward-sexp)))))
+
+(defun ess-escape-call (&optional call)
+  (let ((containing-sexp (ess-containing-sexp-position)))
+    (if (ess-inside-call-p)
+        (ess-save-excursion-when-nil
+          (goto-char containing-sexp)
+          (ess-climb-chained-delims)
+          (and (ess-climb-name)
+               (or (null call)
+                   (looking-at call))))
+      ;; At top level or inside a block, check if point is on the
+      ;; function name.
+      (ess-save-excursion-when-nil
+        (let ((orig-pos (point)))
+          (and (ess-jump-name)
+               (looking-at "[[(]")
+               (ess-climb-name)
+               (or (null call)
+                   (looking-at call))
+               (/= (point) orig-pos)))))))
+
+(defun ess-escape-calls ()
+  (ess-while (ess-escape-call)))
+
+(defun ess-jump-inside-call ()
+  (ess-save-excursion-when-nil
+    (when (ess-jump-name)
+      (ess-skip-blanks-forward)
+      (when (looking-at "(")
+        (forward-char)
+        t))))
+
+(defun ess-args-bounds (&optional marker)
+  (let ((containing-sexp (ess-containing-sexp-position)))
+    (when (ess-inside-call-p)
+      (save-excursion
+        (let ((beg (1+ containing-sexp))
+              (call-beg (ess-at-containing-sexp
+                          (ess-climb-name)
+                          (point))))
+          ;; (ess-up-list) can't find its way when point is on a
+          ;; backquoted name, so start from `beg'.
+          (and (goto-char beg)
+               (ess-up-list)
+               (prog1 t
+                 (forward-char -1))
+               (let ((end (if marker
+                              (point-marker)
+                            (point))))
+                 (list beg end call-beg))))))))
+
+(defun ess-args-alist ()
+  "Return all arguments as an alist with cars set to argument
+names and cdrs set to the expressions given as argument. Both
+cars and cdrs are returned as strings."
+  (save-excursion
+    (when (ess-step-to-first-arg)
+      (let (args current-arg)
+        (while (and (setq current-arg (ess-cons-arg))
+                    (setq args (nconc args (list current-arg)))
+                    (ess-jump-to-next-arg)))
+        args))))
+
+(defun ess-cons-arg ()
+  "Return a cons cell of the current argument with car set to the
+parameter name (nil if not specified) and cdr set to the argument
+expression."
+  (save-excursion
+    (ess-skip-blanks-forward t)
+    (let ((param (when (ess-behind-parameter-p)
+                   (buffer-substring-no-properties
+                    (point)
+                    (prog2
+                        (ess-jump-name)
+                        (point)
+                      (ess-jump-char "=")
+                      (ess-skip-blanks-forward)))))
+          (arg (buffer-substring-no-properties
+                (point)
+                (progn
+                  (ess-jump-arg)
+                  (point)))))
+      (cons param arg))))
+
+\f
+;;;*;;; Statements
+
+(defun ess-behind-operator-p (&optional strict)
+  (ess-token-operator-p (ess-token-after) strict))
+
+(defun ess-ahead-operator-p (&optional strict)
+  (ess-token-operator-p (ess-token-before) strict))
+
+(defun ess-climb-lhs (&optional no-fun-arg climb-line)
+  (ess-save-excursion-when-nil
+    (let ((start-line (line-number-at-pos)))
+      (ess-climb-operator)
+      (when (and (or climb-line (equal (line-number-at-pos) start-line))
+                 (ess-behind-definition-op-p no-fun-arg))
+        (prog1 t
+          (ess-climb-expression))))))
+
+(defun ess-jump-lhs ()
+  (ess-save-excursion-when-nil
+    (and (ess-jump-name)
+         (ess-behind-definition-op-p)
+         (ess-jump-operator))))
+
+(defun ess-climb-operator ()
+  (when (ess-token-operator-p (ess-token-before))
+    (prog1 (ess-climb-token)
+      (ess-skip-blanks-backward))))
+
+;; Currently doesn't check that the operator is not binary
+(defun ess-climb-unary-operator ()
+  (ess-save-excursion-when-nil
+    (let ((token (ess-climb-token)))
+      (member (ess-token-type token) '("+" "-" "!" "?" "~")))))
+
+;; Currently returns t if we climbed lines, nil otherwise.
+(defun ess-climb-continuations (&optional cascade ignore-ifelse)
+  (let* ((start-line (line-number-at-pos))
+         (state (list :start-line start-line
+                      :last-line start-line
+                      :moved 0
+                      :last-pos (point)
+                      :prev-point nil
+                      :def-op nil
+                      :expr nil)))
+    (when (ess-while (and (<= (plist-get state :moved) 1)
+                          (or (ess-save-excursion-when-nil
+                               (and (ess-climb-operator)
+                                    (ess-climb-continuations--update-state state cascade 'op)
+                                    (ess-climb-expression ignore-ifelse)))
+                              (ess-climb-unary-operator))
+                          (/= (plist-get state :last-pos) (point)))
+                     (ess-climb-continuations--update-state state cascade nil)
+                     (plist-put state :last-pos (point)))
+      (when (and (plist-get state :prev-point)
+                 (or (= (plist-get state :moved) 3)
+                     (not (plist-get state :expr))))
+        (goto-char (plist-get state :prev-point)))
+      (if (plist-get state :def-op)
+          'def-op
+        (< (line-number-at-pos) (plist-get state :start-line))))))
+
+(defun ess-climb-continuations--update-state (state cascade &optional op)
+  ;; Climbing multi-line expressions should not count as moving up
+  (when op
+    (plist-put state :expr (ess-ahead-closing-p)))
+  (let ((cur-line (line-number-at-pos)))
+    (when (and (plist-get state :last-line)
+               (< cur-line (plist-get state :last-line))
+               (or cascade (not (plist-get state :expr))))
+      (plist-put state :moved (1+ (plist-get state :moved)))
+      (plist-put state :last-line cur-line)))
+  ;; Don't update counter after climbing operator or climbing too high
+  (when (and (not op)
+             (<= (plist-get state :moved) 1))
+    (plist-put state :prev-point (point)))
+  (when (and (ess-behind-definition-op-p)
+             (<= (plist-get state :moved) 1))
+    (plist-put state :def-op t))
+  t)
+
+(defun ess-jump-operator ()
+  (when (ess-behind-operator-p)
+    (ess-jump-token)
+    (ess-skip-blanks-forward t)
+    t))
+
+(defun ess-jump-continuation ()
+  (and (ess-jump-operator)
+       (ess-jump-expression)))
+
+(defun ess-jump-continuations ()
+  (let (last-pos)
+    (when (ess-while (and (or (null last-pos)
+                              (/= (point) last-pos))
+                          (setq last-pos (point))
+                          (ess-jump-continuation)))
+      ;; In calls, operators can start on newlines
+      (let ((start-line (line-number-at-pos)))
+        (when (ess-save-excursion-when-nil
+                (and (ess-inside-call-p)
+                     (ess-skip-blanks-forward t)
+                     (/= (line-number-at-pos) start-line)
+                     (ess-behind-operator-p)))
+          (ess-jump-continuations)))
+      t)))
+
+(defun ess-ahead-continuation-p (&optional or-parameter)
+  (or (ess-token-operator-p (ess-token-before) (not or-parameter))
+      (save-excursion
+        (ess-climb-block-prefix))
+      (ess-token-after= "else")
+      (save-excursion
+        (ess-climb-if-else-call))))
+
+(defun ess-token-definition-op-p (token strict)
+  (and (ess-token= token '("<-" "<<-" ":=" "~" "="))
+       (if strict
+           (not (ess-refined-token= token "param-assign"))
+         t)))
+
+(defun ess-behind-definition-op-p (&optional strict)
+  (ess-token-definition-op-p (ess-token-after) strict))
+
+(defun ess-ahead-definition-op-p (&optional strict)
+  (ess-token-definition-op-p (ess-token-before) strict))
+
+(defun ess-behind-assignment-op-p ()
+  (let ((token (ess-token-after)))
+    (and (ess-token= token '("<-" "="))
+         (not (ess-refined-token= token "param-assign")))))
+
+(defun ess-escape-continuations ()
+  (ess-any ((unless (ess-ahead-boundary-p)
+              (ess-climb-expression)))
+           ((ess-while (ess-climb-continuations)))))
+
+(defun ess-continuations-bounds (&optional marker)
+  (save-excursion
+    (let ((beg (progn
+                 (ess-escape-continuations)
+                 (point))))
+      (when beg
+        (ess-jump-expression)
+        (ess-jump-continuations)
+        (let ((end (if marker
+                       (point-marker)
+                     (point))))
+          (list beg end))))))
+
+(defun ess-climb-to-top-level ()
+  (while (ess-goto-char (ess-containing-sexp-position)))
+  (ess-escape-continuations))
+
+\f
+;;;*;;; Statements: Control Flow
+
+(defun ess-climb-if-else-call (&optional multi-line)
+  "Climb if, else, and if else calls."
+  (ess-save-excursion-when-nil
+    (cond ((ess-climb-paired-delims ")")
+           (when (ess-climb-token "if")
+             ;; Check for `else if'
+             (prog1 t
+               (ess-save-excursion-when-nil
+                 (let ((orig-line (line-number-at-pos)))
+                   (and (ess-climb-token "else")
+                        (or multi-line
+                            (eq orig-line (line-number-at-pos)))))))))
+          ((ess-climb-token "else")))))
+
+
+(defun ess-climb-if-else-body (&optional from-else)
+  (cond
+   ;; Climb braced body
+   ((ess-save-excursion-when-nil
+      (and (when (progn (ess-skip-blanks-backward t)
+                        (eq (char-before) ?\}))
+             (prog1 t (forward-char -1)))
+           (ess-up-list -1))))
+   ;; Climb unbraced body
+   ((when from-else
+      (ess-save-excursion-when-nil
+        (ess-skip-blanks-backward t)
+        (prog1 (ess-climb-expression 'ignore-ifelse)
+          (or (ess-climb-continuations nil 'ignore-ifelse)
+              (ess-climb-block-prefix nil 'ignore-ifelse))))))))
+
+(defun ess-climb-if-else (&optional to-start)
+  "Climb horizontal as well as vertical if-else chains, with or
+without curly braces."
+  ;; Don't climb if we're atop the current chain of if-else
+  (unless (ess-token-after= "if")
+    (ess-save-excursion-when-nil
+      (let ((from-else (ess-token-after= "else")))
+        (when (and (ess-climb-if-else-body from-else)
+                   (ess-climb-if-else-call to-start))
+          ;; If we start from a final else and climb to another else, we
+          ;; are in the wrong chain of if-else. In that case,
+          ;; climb-recurse to the top of the current chain and climb
+          ;; again to step in the outer chain.
+          (when (save-excursion (and from-else
+                                     (ess-jump-token "else")
+                                     (not (ess-jump-token "if"))))
+            (ess-climb-if-else 'to-start)
+            (ess-climb-continuations)
+            (ess-climb-block-prefix nil 'ignore-ifelse)
+            (ess-climb-if-else-call nil))
+          (ess-maybe-climb-broken-else)
+          (when to-start
+            (ess-climb-if-else to-start))
+          t)))))
+
+;; Broken else: if \n else
+(defun ess-maybe-climb-broken-else (&optional same-line)
+  (ess-save-excursion-when-nil
+    ;; Don't record current line if not needed (expensive operation)
+    (let ((cur-line (when same-line (line-number-at-pos))))
+      (and (ess-climb-token "else")
+           (if same-line
+               (= cur-line (line-number-at-pos))
+             t)))))
+
+(defun ess-skip-curly-backward ()
+  (re-search-backward "}[ \t]*" (line-beginning-position) t))
+
+(defun ess-jump-if-else ()
+  (let (from)
+    (ess-while (ess-save-excursion-when-nil
+                 (ess-skip-blanks-forward t)
+                 (cond
+                  ((and (not (eq from 'if))
+                        (ess-jump-if)
+                        (setq from 'if)))
+                  ((looking-at "else")
+                   (ess-forward-sexp)
+                   (or (ess-jump-if)
+                       (progn
+                         (ess-skip-blanks-forward t)
+                         (ess-jump-expression)))
+                   (setq from 'else))
+                  (t
+                   nil))))))
+
+(defun ess-jump-if ()
+  (ess-save-excursion-when-nil
+    (ess-skip-blanks-forward t)
+    (and (looking-at "if[ \t\n]*(")
+         (ess-forward-sexp 2)
+         (progn
+           (ess-skip-blanks-forward t)
+           (ess-jump-expression)))))
+
+\f
+;;;*;;; Function Declarations
+
+(defun ess-behind-defun-p ()
+  (or (looking-at "function[ \t]*(")
+      (ess-behind-enclosed-defun-p)))
+
+(defun ess-behind-enclosed-defun-p ()
+  (save-excursion
+    (and (ess-behind-call-p)
+         (ess-jump-inside-call)
+         (cl-some (lambda (arg)
+                    (string-match "^function\\b"
+                                  (cdr arg)))
+                  (ess-args-alist)))))
+
+\f
+;;;*;;; Names / Objects / Expressions
+
+;; Should  climb any names, including backquoted ones or those
+;; containing `@' or `$'. Difficult to achieve with regexps, but
+;; skipping chars is faster anyway.
+(defun ess-climb-object ()
+  (ess-save-excursion-when-nil
+    (let (climbed)
+      (ess-skip-blanks-backward)
+      ;; Backquoted names can contain any character
+      (if (and (memq (char-before) '(?` ?\" ?\'))
+               (ess-backward-sexp))
+          (setq climbed t)
+        (while (cl-some (apply-partially '/= 0)
+                        `(,(skip-syntax-backward "w_")
+                          ,(skip-chars-backward "\"'")))
+          (setq climbed t)))
+      ;; Recurse if we find an indexing char
+      (let ((tok (ess-token-before)))
+        (when (member (ess-token-type tok) '("$" "@" "::" ":::"))
+          (goto-char (ess-token-start tok))
+          (ess-climb-object)))
+      climbed)))
+
+;; Todo: split name and object climbing
+(defun ess-climb-name ()
+  (ess-climb-object))
+
+;; This jumps both object names and atomic objects like strings or
+;; numbers.
+(defun ess-jump-object ()
+  (cond
+   ;; Jump over object names
+   ((ess-jump-name))
+   ;; Jump over strings))
+   ((ess-save-excursion-when-nil
+      (skip-chars-forward " \t")
+      (memq (char-after) '(?\" ?\')))
+    (ess-forward-sexp))))
+
+(defun ess-jump-name ()
+  (ess-save-excursion-when-nil
+    (let (climbed)
+      (skip-chars-forward " \t")
+      ;; Jump over backquoted names
+      (cond ((and (eq (char-after) ?`)
+                  (looking-back ess-r-symbol-pattern
+                                (1- (point))))
+             (forward-char)
+             (setq climbed t))
+            ((eq (char-after) ?`)
+             (forward-char)
+             (when (ess-while (not (memq (char-after) '(?` ?\C-J)))
+                     (forward-char))
+               (setq climbed t)
+               (forward-char)))
+            ;; Jump over regular names
+            ((when (/= 0 (skip-syntax-forward "w_"))
+               ;; Maybe point was inside backticks
+               (when (eq (char-after) ?`)
+                 (forward-char))
+               (setq climbed t))))
+      climbed)))
+
+(defun ess-climb-expression (&optional ignore-ifelse)
+  (ess-save-excursion-when-nil
+    (or (ess-climb-block ignore-ifelse)
+        (ess-climb-call)
+        (ess-climb-object))))
+
+(defun ess-jump-expression ()
+  (or (ess-jump-block)
+      (ess-jump-call)
+      (ess-jump-object)))
+
+(provide 'ess-r-syntax)
+
+;;; ess-r-syntax.el ends here
diff --git a/elpa/ess-20260424.1544/ess-r-xref.el b/elpa/ess-20260424.1544/ess-r-xref.el
new file mode 100644 (file)
index 0000000..474cf90
--- /dev/null
@@ -0,0 +1,155 @@
+;;; ess-r-xref.el --- An xref backend for R. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2018-2020 Free Software Foundation, Inc.
+;; Author: Aaron Jacobs
+;; Created: 21 January 2018
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; This file contains an xref backend for `ess-r-mode'.
+
+;;; Code:
+
+(require 'xref)
+(require 'ess-inf)
+(require 'ess-r-package)
+(require 'ess-tracebug)
+(eval-when-compile
+  (require 'subr-x))
+
+;; Silence the byte compiler. OK because this file is only loaded by ess-r-mode.
+(declare-function inferior-ess-r-force "ess-r-mode")
+
+
+(defvar ess-r-xref-pkg-sources nil
+  "Alist of R package->directory associations.
+Each element is a cons cell (PACKAGE . DIRECTORY). This variable
+is used as a cache of package->directory associations, but could
+be used by the users for a more refined control of package
+locations than `ess-r-package-library-paths'.")
+
+(defun ess-r-xref-backend ()
+  "An `xref-backend-functions' implementation for `ess-r-mode'.
+R's xref backend searches for `ess-r-package-library-paths' when
+srcrefs point to temporary locations."
+  'ess-r)
+
+(cl-defmethod xref-backend-identifier-at-point ((_backend (eql ess-r)))
+  (when-let ((sym (ess-symbol-at-point)))
+    (symbol-name sym)))
+
+(cl-defmethod xref-backend-definitions ((_backend (eql ess-r)) symbol)
+  (when-let ((xref (ess-r-xref--xref symbol)))
+    (list xref)))
+
+(cl-defmethod xref-backend-apropos ((_backend (eql ess-r)))
+  ;; Not yet supported.
+  nil)
+
+(cl-defmethod xref-backend-identifier-completion-table ((_backend (eql ess-r)))
+  (inferior-ess-r-force)
+  (ess-get-words-from-vector--foreground ".ess_all_functions()\n"))
+
+(defun ess-r-xref--srcref (symbol)
+  (inferior-ess-r-force)
+  ;; Look for `symbol' inside the package namespace
+  (let* ((pkg (ess-r-package-name))
+         (pkg (if pkg
+                  (concat "\"" pkg "\"")
+                "NULL")))
+    (with-current-buffer (ess-command (format ".ess_srcref(\"%s\", %s)\n" symbol pkg))
+      (goto-char (point-min))
+      (if (re-search-forward "Error" nil t)
+          (progn (message "R srcref lookup failed:\n%s" (buffer-string))
+                 (sit-for 1)
+                 nil)
+        (when (re-search-forward "(" nil 'noerror)
+          (goto-char (match-beginning 0))
+          (read (current-buffer)))))))
+
+(defun ess-r-xref--pkg-srcfile (symbol src-file &optional default-pkg)
+  "Search the R package containing symbol SYMBOL for file SRC-FILE.
+DEFAULT-PKG is the name of the package where presumably SYMBOL is located."
+  (let* ((pkgs (delq nil
+                     (delete-dups
+                      (or (cons default-pkg
+                                (ess-get-words-from-vector (format ".ess_fn_pkg(\"%s\")\n" symbol)))
+                          (user-error "Can't find package for symbol %s" symbol)))))
+         (lib-dirs (cond ((stringp ess-r-package-library-paths)
+                          (list ess-r-package-library-paths))
+                         ((listp ess-r-package-library-paths)
+                          ess-r-package-library-paths)
+                         (t (user-error "Invalid value of `ess-r-package-library-paths'"))))
+         (loc (or (cl-loop for pkg in pkgs
+                           for dir = (assoc-default pkg ess-r-xref-pkg-sources)
+                           when (and dir (file-exists-p dir)) return (cons pkg dir))
+                  (cl-some (lambda (dir)
+                             (cl-loop for pkg in pkgs
+                                      for path = (expand-file-name pkg dir)
+                                      when (file-exists-p path) return (cons pkg path)))
+                           lib-dirs)))
+         (file (when loc (expand-file-name src-file (cdr loc)))))
+    (when file
+      (unless (file-readable-p file)
+        (error "Can't read %s" file))
+      ;; Cache package's source directory.
+      (unless (assoc (car loc) ess-r-xref-pkg-sources)
+        (push loc ess-r-xref-pkg-sources))
+      file)))
+
+(defun ess-r-xref--xref (symbol)
+  "Create an xref for the source file reference of R symbol SYMBOL."
+  (when-let ((ref (ess-r-xref--srcref symbol)))
+    (let ((file (nth 0 ref))
+          (line (nth 1 ref))
+          (col  (nth 2 ref)))
+      (or
+       ;; 1) Result of ESS evaluation
+       (let* ((ess-ref (gethash file ess--srcrefs))
+              (ess-buff (when ess-ref (ess--dbg-find-buffer (car ess-ref)))))
+         (when ess-buff
+           ;; FIXME: this breaks when eval is on larger spans than function
+           (xref-make symbol (xref-make-buffer-location ess-buff (nth 2 ess-ref)))))
+       ;; 2) Real file from R proc working directory
+       (unless (file-name-absolute-p file)
+         (let ((file (expand-file-name file (ess-get-process-variable 'default-directory))))
+           (when (file-readable-p file)
+             (xref-make symbol (xref-make-file-location file line col)))))
+       ;; 3) Real file from the R's working directory
+       (unless (file-name-absolute-p file)
+         (when-let ((wdir (car (ess-get-words-from-vector ess-getwd-command))))
+           (let ((file (expand-file-name file wdir)))
+             (when (file-readable-p file)
+               (xref-make symbol (xref-make-file-location file line col))))))
+       ;; 4) Real file location from the current directory
+       (when (file-readable-p file)
+         (xref-make symbol (xref-make-file-location file line col)))
+       ;; 5) Temporary sources - truncate and locate in ess-r-package-library-paths
+       (when (string-match "/\\([^/]+\\)/\\(R/.*\\)$" file)
+         (when-let ((pkg-file (ess-r-xref--pkg-srcfile
+                               symbol (match-string 2 file) (match-string 1 file))))
+           (xref-make symbol (xref-make-file-location
+                              (expand-file-name pkg-file) line col))))))))
+
+(provide 'ess-r-xref)
+
+;;; ess-r-xref.el ends here
diff --git a/elpa/ess-20260424.1544/ess-rd.el b/elpa/ess-20260424.1544/ess-rd.el
new file mode 100644 (file)
index 0000000..1089d63
--- /dev/null
@@ -0,0 +1,491 @@
+;; ess-rd.el --- Support for editing R documentation (Rd) source  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1997-2025 Free Software Foundation, Inc.
+;; Author: KH <Kurt.HornikNOSPAMci.tuwien.ac.at>
+;; Created: 25 July 1997
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+;;
+
+;;; Code:
+(eval-when-compile
+  (require 'subr-x))
+
+(require 'ess-help)
+(require 'ess-inf)
+;; Silence the byte compiler, see TODO below; can we remove these?
+(defvar ess-help-r-sec-regex)
+(defvar ess-help-r-sec-keys-alist)
+(defvar ess-r-customize-alist)
+
+(defcustom Rd-mode-hook nil
+  "Hook to be run when Rd mode is entered."
+  :type 'hook
+  :group 'ess-R
+  :group 'ess-hooks)
+
+(define-abbrev-table 'Rd-mode-skeleton-abbrev-table
+  '(("`ag" "\\arguments" nil :system t)
+    ("`al" "\\alias" nil :system t)
+    ("`au" "\\author" nil :system t)
+    ("`bf" "\\bold" nil :system t)
+    ;; not (yet) "bibcitep" "bibcitet" "bibshow" "bibinfo"
+    ("`co" "\\code" nil :system t)
+    ("`de" "\\describe" nil :system t)
+    ("`dn" "\\description" nil :system t)
+    ("`dt" "\\details" nil :system t)
+    ("`em" "\\emph" nil :system t)
+    ("`en" "\\enumerate" nil :system t)
+    ("`ex" "\\examples" nil :system t)
+    ("`fi" "\\file" nil :system t)
+    ("`fo" "\\format" nil :system t)
+    ("`it" "\\item" nil :system t)
+    ("`iz" "\\itemize" nil :system t)
+    ("`kw" "\\keyword" nil :system t)
+    ("`li" "\\link" nil :system t)
+    ("`me" "\\method" nil :system t)
+    ("`ma" "\\manual" nil :system t)
+    ("`na" "\\name" nil :system t)
+    ("`no" "\\note" nil :system t)
+    ("`re" "\\references" nil :system t)
+    ("`sa" "\\seealso" nil :system t)
+    ("`se" "\\section" nil :system t)
+    ("`so" "\\source" nil :system t)
+    ("`ss" "\\subsection" nil :system t)
+    ("`sy" "\\synopsis" nil :system t)
+    ("`ta" "\\tabular" nil :system t)
+    ("`ti" "\\title" nil :system t)
+    ("`us" "\\usage" nil :system t)
+    ("`va" "\\value" nil :system t))
+  "Abbrev table for R documentation keywords.
+All Rd mode abbrevs start with a grave accent (`)."
+  :case-fixed t)
+
+(define-abbrev-table 'Rd-mode-abbrev-table ()
+  "Abbrev table for Rd mode."
+  :parents (list Rd-mode-skeleton-abbrev-table))
+
+(defvar Rd-mode-syntax-table
+  (let ((tab (copy-syntax-table text-mode-syntax-table)))
+    (modify-syntax-entry ?\\ "\\" tab)
+    (modify-syntax-entry ?\{ "(}" tab)
+    (modify-syntax-entry ?\} "){" tab)
+    ;; Nice for editing, not for parsing ...
+    (modify-syntax-entry ?\( "()" tab)
+    (modify-syntax-entry ?\) ")(" tab)
+    (modify-syntax-entry ?\[ "(]" tab)
+    (modify-syntax-entry ?\] ")[" tab)
+    ;; To get strings right
+    ;; (modify-syntax-entry ?\' "\"" Rd-mode-syntax-table)
+    (modify-syntax-entry ?\" "\"" tab)
+    ;; To make abbrevs starting with a grave accent work ...
+    (modify-syntax-entry ?\` "w" tab)
+    ;; Comments
+    (modify-syntax-entry ?\% "<" tab)
+    (modify-syntax-entry ?\n ">" tab)
+    tab)
+  "Syntax table for `Rd-mode'.")
+
+(defvar Rd-mode-parse-syntax-table
+  (let ((tab (copy-syntax-table Rd-mode-syntax-table)))
+    ;; To make parse-partial-sexps do the thing we want for computing
+    ;; indentations
+    (modify-syntax-entry ?\( "_" tab)
+    (modify-syntax-entry ?\) "_" tab)
+    (modify-syntax-entry ?\[ "_" tab)
+    (modify-syntax-entry ?\] "_" tab)
+    tab)
+  "Syntax table for parsing Rd mode.")
+
+(defvar Rd-section-names
+  '("Rdversion" "arguments" "alias" "author" "concept" "describe" "description"
+    "details" "docType" "encoding" "enumerate" "examples" "format"
+    "itemize" "keyword" "name" "note" "preformatted" "references"
+    "seealso" "section" "source" "subsection" "synopsis"
+    "tabular" "title" "usage"
+    "value"))
+
+(defvar Rd-keywords ; to be highlighted in Rd-mode
+  '(
+    ;; the next two lines: only valid in R <= 2.8.1
+    ;; commented out on 2011-01-14 for ESS version 5.13:
+    ;; "Alpha" "Gamma" "alpha" "beta" "epsilon" "lambda" "mu" "pi" "sigma"
+    ;; "ge" "le" "left" "right"
+    ;;
+    "RdOpts" "R" "S3method" "S4method" "Sexpr"
+    "abbr" "acronym"
+    "bold" "cite" "code" "command" "cr" "dQuote" "deqn" "dfn" "dontdiff" "dontrun"
+    "dontshow" "donttest" "dots" "email" "emph" "enc" "env" "eqn" "figure" "file"
+    "href"
+    "ifelse" "if"
+    "item" "kbd" "ldots" "linkS4class" "linkS4methods" "link" "method"
+    "manual"
+    "newcommand" "option" "out"
+    "pkg" "sQuote" "renewcommand"
+    "samp" "strong" "tab" "url" "var" "verb"
+    ;; System macros (from <R>/share/Rd/macros/system.Rd ):
+    "bibcitep" "bibcitet" "bibshow" "bibinfo"
+    "CRANpkg" "PR" "sspace" "doi"
+    "I" ; should we?
+    "LaTeX"
+    "proglang"
+    "packageTitle" "packageDescription" "packageAuthor"
+    "packageMaintainer" "packageDESCRIPTION" "packageIndices"
+    ))
+
+(defvar Rd-font-lock-keywords
+  (list
+   (cons
+    (concat "\\\\\\("
+            (mapconcat #'identity Rd-section-names "\\|")
+            "\\>\\)")
+    'font-lock-constant-face) ; Rd-bold-face
+   (cons
+    (concat "\\\\\\("
+            (mapconcat #'identity Rd-keywords "\\|")
+            "\\>\\)")
+    'font-lock-keyword-face)
+   '("^#\\(ifn?def\\)\\s-+\\(\\sw+\\)"
+     (1 font-lock-builtin-face)
+     (2 font-lock-variable-name-face nil t))
+   '("^#\\(endif\\)" 1 font-lock-builtin-face))
+  "Additional Rd expressions to highlight.")
+
+(defvar Rd-indent-level 2
+  "Indentation of Rd code with respect to containing blocks.")
+
+(defvar Rd-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "\t" #'indent-according-to-mode)
+    (define-key map "\C-j" #'reindent-then-newline-and-indent)
+    (define-key map "\C-m" #'reindent-then-newline-and-indent)
+    (define-key map "\C-c\C-p" #'Rd-preview-help)
+    (define-key map "\C-c\C-j" #'Rd-mode-insert-item)
+    (define-key map "\C-c\C-e" #'Rd-mode-insert-skeleton)
+    (define-key map "\C-c\C-d" #'Rd-mode-insert-data-skeleton)
+    (define-key map "\C-c\C-f" #'Rd-font)
+    (define-key map "\C-c\C-s" #'Rd-mode-insert-section)
+    (define-key map "\C-c\C-n" #'ess-eval-line-visibly-and-step)
+    (define-key map "\C-c\C-r" #'ess-eval-region)
+    (define-key map "\C-c\C-c" #'ess-eval-region-or-function-or-paragraph-and-step)
+    (define-key map "\C-\M-x"  #'ess-eval-region-or-function-or-paragraph)
+    (define-key map "\C-c\C-v" #'ess-display-help-on-object)
+    (define-key map "\C-c\C-w" #'ess-switch-process)
+    (define-key map "\C-c\C-y" #'ess-switch-to-ESS)
+    (define-key map "\C-c\C-z" #'ess-switch-to-end-of-ESS)
+    map)
+  "Keymap used in Rd mode.")
+
+(defvar Rd-mode-menu
+  (list "Rd"
+        ["Markup [word]"                Rd-font t]
+        ["Insert Item"                  Rd-mode-insert-item t]
+        ["Insert Section"               Rd-mode-insert-section t]
+        ["Insert Skeleton"              Rd-mode-insert-skeleton t]
+        ["Insert Data Skeleton"         Rd-mode-insert-data-skeleton t]
+        "-"
+        ["Preview"                      Rd-preview-help t]
+        "-"
+        ["Eval Line"                    ess-eval-line-visibly-and-step t]
+        ["Eval Region"                  ess-eval-region t]
+        ["Switch to ESS Process"        ess-switch-to-ESS t]
+        ["Switch the ESS Process"       ess-switch-process t]
+        ["Switch to end{ESS Pr}"        ess-switch-to-end-of-ESS t]
+        "-"
+        ["Toggle Abbrev Mode"           abbrev-mode t]
+        ["Toggle Auto-Fill Mode"        auto-fill-mode t]
+        "-"
+        ["Submit Bug Report"            ess-submit-bug-report t]
+        "-"
+        ["Describe Rd Mode"             describe-mode t])
+  "Menu used in Rd mode.")
+
+(defvar Rd-to-help-command "R CMD Rd2txt"
+  "Shell command for converting R documentation source to help text.")
+
+(defvar Rd-font-list
+  '((?\C-b "\\bold{"    "}")
+    (?\C-c "\\code{"    "}")
+    (?\C-e "\\emph{"    "}")
+    (?\C-l "\\link{"    "}")
+    (?l "\\code{\\link{" "}}")
+    (?\C-m "\\email{"   "}")
+    (?\C-q "\\eqn{"     "}")
+    (?\C-u "\\url{"     "}")
+    )
+  "List of \"fonts\" used by `Rd-font'.
+Each entry is a list. The first element is the key to activate
+the font. The second element is the string to insert before
+point, and the third element is the string to insert after
+point.")
+
+
+;;;###autoload
+(define-derived-mode Rd-mode text-mode "Rd"
+  "Major mode for editing R documentation source files.
+
+Type \\[list-abbrevs] to display the built-in abbrevs for Rd
+keywords.To automatically turn on the abbrev(iate) features, add
+the following to your Emacs configuration file:
+
+  (add-hook \\='Rd-mode-hook #\\='abbrev-mode)"
+  (setq ess-language "S" ess-dialect  "R")
+  (require 'ess-r-mode)
+  (ess-setq-vars-local ess-r-customize-alist)
+
+  (setq-local indent-line-function #'Rd-mode-indent-line)
+  (setq fill-column 72)
+  (setq-local comment-start-skip "\\s<+\\s-*")
+  (setq-local comment-start "% ")
+  (setq-local comment-end "")
+  (setq font-lock-defaults
+        '(Rd-font-lock-keywords nil nil))
+
+  ;; Here is a workaround for an Emacs bug related to indirect buffers and
+  ;; spurious lockfiles that rears its ugly head with .Rd files
+  ;; https://lists.gnu.org/archive/html/bug-gnu-emacs/2013-02/msg01368.html
+  ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=14328
+  (setq-local create-lockfiles nil)
+
+  (easy-menu-define Rd-mode-menu-map Rd-mode-map
+    "Menu keymap for Rd mode." Rd-mode-menu)
+
+  (turn-on-auto-fill))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.Rd\\'" . Rd-mode))
+
+(defun Rd-describe-major-mode ()
+  "Describe the current major mode."
+  (declare (obsolete describe-mode "ESS 19.04"))
+  (describe-function major-mode))
+
+(defun Rd-mode-in-verbatim-p ()
+  "Return non-nil if in a usage, examples, or synopsis."
+  (let ((pos (point)))
+    (save-excursion
+      (if (and (re-search-backward
+                "\\\\\\(usage\\|examples\\|synopsis\\)" nil t)
+               (re-search-forward "\\s(" nil t))
+          (condition-case ()
+              (progn
+                (up-list 1)
+                (< pos (point)))
+            (error t))
+        nil))))
+
+(defun Rd-mode-in-preprocessor-line-p ()
+  "Return non-nil if in a preprocessor line."
+  (save-excursion
+    (beginning-of-line)
+    (looking-at "[ \t]*#\\(ifdef\\|endif\\)")))
+
+(defun Rd-mode-calculate-indent ()
+  "Return appropriate indentation for current line in Rd mode."
+  (save-excursion
+    (beginning-of-line)
+    (cond
+     ((Rd-mode-in-verbatim-p)
+      ;; Don't do anything in verbatims
+      nil)
+     ((Rd-mode-in-preprocessor-line-p)
+      ;; Indent to 0
+      0)
+     (t
+      (let ((p (progn
+                 (re-search-forward "[ \t]*\\s)*" (line-end-position) t)
+                 (point))))
+        (if (or (< (forward-line -1) 0)
+                (Rd-mode-in-verbatim-p))
+            0
+          (set-syntax-table Rd-mode-parse-syntax-table)
+          (while (and (or (looking-at "[ \t]*$")
+                          (Rd-mode-in-preprocessor-line-p))
+                      (not (bobp)))
+            (forward-line -1))
+          (re-search-forward "[ \t]*\\s)*" (line-end-position) t)
+          (prog1
+              (+ (current-indentation)
+                 (* (car (parse-partial-sexp (point) p))
+                    Rd-indent-level))
+            (set-syntax-table Rd-mode-syntax-table))))))))
+
+(defun Rd-mode-indent-line ()
+  "Indent current line as Rd source."
+  (when-let ((ic (Rd-mode-calculate-indent))
+             (rp (- (current-column) (current-indentation))))
+    (when (< ic 0)
+      (error "Unmatched parenthesis"))
+    (indent-line-to ic)
+    (when (> rp 0)
+      (move-to-column (+ ic rp)))))
+
+(defun Rd-mode-insert-item ()
+  "Insert \\item{ on a newline."
+  (interactive)
+  (reindent-then-newline-and-indent)
+  (insert "\\item{")
+  )
+
+(defun Rd-mode-insert-section ()
+  "Insert a section from `Rd-section-names'."
+  (interactive)
+  (let ((s (ess-completing-read
+            "Insert section: "
+            (mapcar (lambda (x) (cons x x)) Rd-section-names)
+            nil t)))
+    (if (string= s "")
+        (progn (insert "\\section{}{") (backward-char 2))
+      (insert (format "\\%s{" s)))))
+
+(defun Rd-mode-insert-skeleton ()
+  "Insert several empty Rd fields."
+  (interactive)
+  ;; Hmm: in theory this should be kept in sync with prompt()
+  ;; ---  maybe using prompt() [or promptClass()...] would be better anyway?!
+  (insert "\\name{}\n")
+  (insert "\\alias{}\n")
+  (insert "\\title{}\n")
+  (insert "\\description{\n}\n")
+  (insert "\\usage{\n}\n")
+  (insert "\\arguments{\n}\n")
+  (insert "\\value{\n}\n")
+  (insert "\\details{\n}\n")
+  (insert "\\references{\n}\n")
+  (insert "\\seealso{\n}\n")
+  (insert "\\examples{\n}\n")
+  (insert "\\author{}\n")
+  (insert "\\keyword{}\n"))
+
+(defun Rd-mode-insert-data-skeleton ()
+  "Insert several empty Rd fields."
+  (interactive)
+  ;; Hmm: in theory this should be kept in sync with prompt()
+  ;; ---  maybe using prompt() [or promptClass()...] would be better anyway?!
+  (insert "\\name{}\n")
+  (insert "\\docType{}\n")
+  (insert "\\alias{}\n")
+  (insert "\\title{}\n")
+  (insert "\\description{\n}\n")
+  (insert "\\usage{\n}\n")
+  (insert "\\format{\n}\n")
+  (insert "\\details{\n}\n")
+  (insert "\\source{}\n")
+  (insert "\\references{\n}\n")
+  (insert "\\examples{\n}\n")
+  (insert "\\keyword{datasets}\n"))
+
+
+;; This is an `easy' version of (defun TeX-font ..) in AUCtex's  tex.el ;
+;;  see TeX-font-list and also LaTeX-font-list in latex.el
+
+(defun Rd-font (what)
+  "Insert template for font command.
+WHAT determines the font to use, as specified by `Rd-font-list'."
+  (interactive "c")
+  ;;TeX had : (Rd-update-style)
+  (let* ((entry (assoc what Rd-font-list))
+         (before (nth 1 entry))
+         (after (nth 2 entry)))
+    (cond ((null entry) ;; help on possibilities :
+           (let ((help
+                  (concat
+                   "Rd Markup (available from C-c C-f):\n\n\t"
+                   "KEY          Rd-Markup\n\n"
+                   (mapconcat
+                    (lambda (entry)
+                      ;; A textual description of an ENTRY in TeX-font-list.
+                      (concat (format "%11s  "
+                                      (key-description
+                                       (char-to-string (nth 0 entry))))
+                              (format "%14s %-3s"
+                                      (nth 1 entry) (nth 2 entry))))
+                    Rd-font-list "\n"))))
+             (with-output-to-temp-buffer "*Help*"
+               (set-buffer "*Help*")
+               (insert help))))
+
+          ((region-active-p)
+           (save-excursion
+             (cond ((> (mark) (point))
+                    (insert before)
+                    (goto-char (mark))
+                    (insert after))
+                   (t
+                    (insert after)
+                    (goto-char (mark))
+                    (insert before)))))
+          (t
+           (insert before)
+           (save-excursion
+             (insert after))))))
+
+(defun Rd-preview-help (&optional via-shell)
+  "Preview the current Rd buffer contents as help.
+If the current buffer is not associated with a file, create a
+temporary one in variable `temporary-file-directory'."
+  (declare (advertised-calling-convention () "ESS 19.04"))
+  (interactive "P")                     ; If optional VIA-SHELL is set, using `Rd-to-help-command'.
+  (let ((file buffer-file-name)
+        (pbuf (get-buffer-create "R Help Preview"))
+        del-p)
+    (unless file
+      (setq file (make-temp-file "RD_" nil ".Rd"))
+      (write-region (point-min) (point-max) file)
+      (setq del-p t))
+
+    (if via-shell ;; FIXME eventually get rid of this option
+        ;; only method in ESS <= 14.09 -- calls "R" even if in "R-devel"; slower
+        (let ((shcmd (format "%s '%s'" Rd-to-help-command file)))
+          (set-buffer pbuf)
+          (erase-buffer)
+          (ess-write-to-dribble-buffer
+           (format "Rd-preview-help: (shell-command |%s| t)" shcmd))
+          (shell-command shcmd t))
+      ;; else directly:
+      (ess-force-buffer-current "R process to use: ")
+      (ess--foreground-command (format ".ess_Rd2txt(\"%s\")\n" file) pbuf)
+      (set-buffer pbuf))
+
+    ;; FIXME(2): once got rid of via-shell, consider
+    ;; (ess--flush-help-into-current-buffer file "tools::Rd2txt(\"%s\")\n")
+    ;; instead of all this :
+    (ess-setq-vars-local ess-r-customize-alist)
+    ;; mostly cut'n'paste from ess--flush-help* (see FIXME(2)):
+    (ess-help-underline)
+    (ess--help-major-mode)
+    ;; FIXME: Is this really needed?
+    (setq ess-help-sec-regex ess-help-r-sec-regex
+          ess-help-sec-keys-alist ess-help-r-sec-keys-alist)
+    (goto-char (point-min))
+    (set-buffer-modified-p 'nil)
+    (setq buffer-read-only t)
+    (setq truncate-lines nil)
+    (when del-p (delete-file file))
+    (unless (get-buffer-window pbuf 'visible)
+      (display-buffer pbuf t))))
+
+(define-obsolete-function-alias 'Rd-submit-bug-report #'ess-submit-bug-report "2018-08-16")
+
+(provide 'ess-rd)
+
+;;; ess-rd.el ends here
diff --git a/elpa/ess-20260424.1544/ess-rdired.el b/elpa/ess-20260424.1544/ess-rdired.el
new file mode 100644 (file)
index 0000000..e025a5f
--- /dev/null
@@ -0,0 +1,301 @@
+;;; ess-rdired.el --- prototype object browser for R, looks like dired mode.  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2002-2022 Free Software Foundation, Inc.
+;; Author: Stephen Eglen <stephenNOSPAManc.ed.ac.uk>
+;; Created: Thu 24 Oct 2002
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; This provides a dired-like buffer for R objects.  Instead of
+;; operating on files, we operate on R objects in the current
+;; environment.  Objects can be viewed, edited, deleted, plotted and
+;; so on.
+;; Do "M-x R" to start an R session, then create a few variables:
+;;
+;; s <- sin(seq(from=0, to=8*pi, length=100))
+;; x <- c(1, 4, 9)
+;; y <- rnorm(20)
+;; z <- TRUE
+
+;; Then in Emacs, do "M-x ess-rdired" and you should see the following in
+;; the buffer *R dired*:
+;; Name              Class    Length     Size
+;; s                  numeric    100        848 bytes
+;; x                  numeric    3          80 bytes
+;; y                  numeric    20         208 bytes
+;; z                  logical    1          56 bytes
+
+;; Type "?" in the buffer to see the documentation.  e.g. when the
+;; cursor is on the line for `s', type 'p' to plot it, or `v' to view
+;; its contents in a buffer.  Then type 'd' to delete it.
+
+;; How it works.
+
+;; Most of the hard work is done by the R routine .rdired.objects(),
+;; which, when called, produces the list of objects in a tidy format.
+;; This function is stored within the Lisp variable `ess-rdired-objects'.
+
+;; Todo - How to select alternative environments?  Currently only
+;; shows objects in the .GlobalEnv?  See BrowseEnv() in 1.6.x for way
+;; of browsing other environments.
+
+;; Todo - problem with fix -- have to wait for fix() command to return
+;; before *R* buffer can be used again.  This can get stuck, umm. not
+;; sure what is going wrong here.  Maybe add a hook to the temp buffer
+;; so that when buffer is killed, we send an instruction to R to
+;; update the value of the variable to the contents of the buffer.
+;; This way *R* doesn't have to wait.
+
+;; Todo - small bug in .rdired.objects -- if we have a variable called
+;; `my.x', its value is replaced by the value of my.x used in the
+;; sapply() calls within .rdired.objects().
+
+;;; Code:
+
+(require 'ess-inf)
+
+(eval-when-compile
+  (require 'subr-x))
+
+(defvar ess-rdired-objects ".ess.rdired()\n"
+  "Function to call within R to print information on objects.")
+
+(defvar ess-rdired-buffer "*R dired*"
+  "Name of buffer for displaying R objects.")
+
+(defvar ess-rdired-auto-update-timer nil
+  "The timer object for auto updates.")
+
+(defcustom ess-rdired-auto-update-interval 5
+  "Seconds between refreshes of the `ess-rdired' buffer."
+  :type '(choice (const :tag "No auto updates" nil) (integer :tag "Seconds"))
+  :group 'ess-R
+  :package-version '(ess . "19.04"))
+
+(defvar ess-rdired-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "d" #'ess-rdired-delete)
+    (define-key map "x" #'ess-rdired-delete)
+    (define-key map "v" #'ess-rdired-view)
+    (define-key map "V" #'ess-rdired-View)
+    (define-key map "p" #'ess-rdired-plot)
+    (define-key map "y" #'ess-rdired-type)
+    (define-key map "\C-c\C-s" #'ess-rdired-switch-process)
+    (define-key map "\C-c\C-y" #'ess-switch-to-ESS)
+    (define-key map "\C-c\C-z" #'ess-switch-to-end-of-ESS)
+    map))
+
+(define-derived-mode ess-rdired-mode tabulated-list-mode "Rdired"
+  "Major mode for output from `ess-rdired'.
+`ess-rdired' provides a dired-like mode for R objects.  It shows the
+list of current objects in the current environment, one-per-line.  You
+can then examine these objects, plot them, and so on."
+  :group 'ess-R
+  (setq mode-name (concat "RDired " ess-local-process-name))
+  (setq tabulated-list-format
+        `[("Name" 18 t)
+          ("Class" 10 t)
+          ("Length" 10 ess-rdired--length-predicate)
+          ("Rows" 10 ess-rdired--rows-predicate)
+          ("Size" 10 ess-rdired--size-predicate)])
+  (add-hook 'tabulated-list-revert-hook #'ess-rdired-refresh nil t)
+  (when (and (not ess-rdired-auto-update-timer)
+             ess-rdired-auto-update-interval)
+    (setq ess-rdired-auto-update-timer
+          (run-at-time t ess-rdired-auto-update-interval #'ess-rdired-refresh)))
+  (add-hook 'kill-buffer-hook #'ess-rdired-cancel-auto-update-timer nil t)
+  (tabulated-list-init-header))
+
+;;;###autoload
+(defun ess-rdired ()
+  "Show R objects from the global environment in a separate buffer.
+You may interact with these objects, see `ess-rdired-mode' for
+details."
+  (interactive)
+  (unless (and (string= "R" ess-dialect)
+               ess-local-process-name)
+    (error "Not in an R buffer with attached process"))
+  (let ((proc ess-local-process-name))
+    (pop-to-buffer (get-buffer-create ess-rdired-buffer))
+    (setq ess-local-process-name proc)
+    (ess-rdired-mode)
+    (ess-rdired-refresh)))
+
+(defun ess-rdired-refresh ()
+  "Refresh the `ess-rdired' buffer."
+  (let* ((buff (get-buffer-create ess-rdired-buffer))
+         (proc-name (buffer-local-value 'ess-local-process-name buff))
+         (proc (get-process proc-name))
+         (out-buff (get-buffer-create " *ess-rdired-output*"))
+         text)
+    (when (and proc-name proc
+               (not (process-get proc 'busy)))
+      (ess--foreground-command ess-rdired-objects out-buff nil nil nil proc)
+      (with-current-buffer out-buff
+        (goto-char (point-min))
+        ;; Delete two lines. One filled with +'s from R's prompt
+        ;; printing, the other with the header info from the data.frame
+        (delete-region (point-min) (1+ (line-end-position 2)))
+        (setq text (split-string (buffer-string) "\n" t "\n"))
+        (erase-buffer))
+      (with-current-buffer buff
+        (setq tabulated-list-entries
+              (mapcar #'ess-rdired--tabulated-list-entries text))
+        (let ((entry (tabulated-list-get-id))
+              (col (current-column)))
+          (tabulated-list-print)
+          (while (not (equal entry (tabulated-list-get-id)))
+            (forward-line))
+          (move-to-column col))))))
+
+(defun ess-rdired-cancel-auto-update-timer ()
+  "Cancel the timer `ess-rdired-auto-update-timer'."
+  (setq ess-rdired-auto-update-timer
+        (cancel-timer ess-rdired-auto-update-timer)))
+
+(defun ess-rdired--tabulated-list-entries (text)
+  "Return a value suitable for `tabulated-list-entries' from TEXT."
+    (let (name class length rows size)
+    (if (not (string-match-p " +\"" text))
+        ;; Normal-world
+        (setq text (split-string text " " t)
+              name (nth 0 text)
+              text (cdr text))
+      ;; Else, someone has spaces in their variable names
+      (string-match "\"\\([^\"]+\\)" text)
+      (setq name (substring (match-string 0 text) 1)
+            text (split-string (substring text (1+ (match-end 0))) " " t)))
+    (setq class (nth 0 text)
+          length (nth 1 text)
+          rows (nth 2 text)
+          size (nth 3 text))
+    (list name
+          `[(,name
+             help-echo "mouse-2, RET: View this object"
+             action ess-rdired-view)
+            ,class
+            ,length
+            ,rows
+            ,size])))
+
+(defun ess-rdired-edit ()
+  "Edit the object at point."
+  (interactive)
+  (ess-command (concat "edit(" (tabulated-list-get-id) ")\n")))
+
+(defun ess-rdired-view (&optional _button)
+  "View the object at point."
+  (interactive)
+  (ess-execute (ess-rdired-get (tabulated-list-get-id))
+               nil "R view" ))
+
+(defun ess-rdired-get (name)
+  "Generate R code to get the value of the variable NAME.
+This is complicated because some variables might have spaces in their names.
+Otherwise, we could just pass the variable name directly to *R*."
+  (concat "get(" (ess-rdired-quote name) ")")
+  )
+
+(defun ess-rdired-quote (name)
+  "Quote NAME if not already quoted."
+  (if (equal (substring name 0 1) "\"")
+      name
+    (concat "\"" name "\"")))
+
+(defun ess-rdired-View ()
+  "View the object at point in its own buffer.
+Like `ess-rdired-view', but the object gets its own buffer name."
+  (interactive)
+  (let ((objname (tabulated-list-get-id)))
+    (ess-execute (ess-rdired-get objname)
+                 nil (concat "R view " objname ))))
+
+(defun ess-rdired-plot ()
+  "Plot the object on current line."
+  (interactive)
+  (let ((objname (tabulated-list-get-id)))
+    (ess-eval-linewise (format "plot(%s)" (ess-rdired-get objname)))))
+
+(defun ess-rdired-type ()
+  "Run the mode() on command at point."
+  (interactive)
+  (let ((objname (tabulated-list-get-id))
+        ;; create a temp buffer, and then show output in echo area
+        (tmpbuf (get-buffer-create "**ess-rdired-mode**")))
+    (if objname
+        (progn
+          (ess-command (concat "mode(" (ess-rdired-get objname) ")\n")
+                       tmpbuf )
+          (set-buffer tmpbuf)
+          (message "%s" (concat
+                         objname ": "
+                         (buffer-substring (+ 4 (point-min)) (1- (point-max)))))
+          (kill-buffer tmpbuf)))))
+
+(defalias 'ess-rdired-expunge #'ess-rdired-delete)
+
+(defun ess-rdired-delete ()
+  "Delete the object at point."
+  (interactive)
+  (let ((objname (tabulated-list-get-id)))
+    (when (yes-or-no-p (format "Really delete %s? " objname))
+      (ess-eval-linewise (format "rm(%s)" (ess-rdired-quote objname)) nil nil nil t)
+      (revert-buffer))))
+
+(defun ess-rdired-switch-process ()
+  "Switch to examine different *R* process.
+If you have multiple R processes running, e.g. *R*, *R:2*, *R:3*, you can
+use this command to choose which R process you would like to examine.
+After switching to a new process, the buffer is updated."
+  (interactive)
+  (ess-switch-process)
+  (ess-rdired))
+
+(defun ess-rdired--length-predicate (A B)
+  "Enable sorting by length in `ess-rdired' buffers.
+Return t if A's length is < than B's length."
+  (let ((lenA (aref (cadr A) 2))
+        (lenB (aref (cadr B) 2)))
+    (< (string-to-number lenA) (string-to-number lenB))))
+
+(defun ess-rdired--rows-predicate (A B)
+  "Enable sorting by rows in `ess-rdired' buffers.
+Return t if A's length is < than B's length."
+  (let ((lenA (aref (cadr A) 2))
+        (lenB (aref (cadr B) 2)))
+    (< (string-to-number lenA) (string-to-number lenB))))
+
+(defun ess-rdired--size-predicate (A B)
+  "Enable sorting by size in `ess-rdired' buffers.
+Return t if A's size is < than B's size."
+  (let ((lenA (aref (cadr A) 3))
+        (lenB (aref (cadr B) 3)))
+    (< (string-to-number lenA) (string-to-number lenB))))
+
+(define-obsolete-function-alias 'ess-rdired-quit #'quit-window "ESS 19.04")
+(define-obsolete-function-alias 'ess-rdired-next-line #'forward-to-indentation "ESS 19.04")
+(define-obsolete-function-alias 'ess-rdired-previous-line #'backward-to-indentation "ESS 19.04")
+(define-obsolete-function-alias 'ess-rdired-move-to-object #'back-to-indentation "ESS 19.04")
+
+(provide 'ess-rdired)
+
+;;; ess-rdired.el ends here
diff --git a/elpa/ess-20260424.1544/ess-roxy.el b/elpa/ess-20260424.1544/ess-roxy.el
new file mode 100644 (file)
index 0000000..a8a7c56
--- /dev/null
@@ -0,0 +1,1042 @@
+;;; ess-roxy.el --- convenient editing of in-code roxygen documentation  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2009-2022 Free Software Foundation, Inc.
+;; Author: Henning Redestig <henning.red * go0glemail c-m>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; Lots of inspiration from doc-mode,
+;; https://nschum.de/src/emacs/doc-mode/
+;;
+;; Features::
+;;
+;; - basic highlighting
+;; - generating and updating templates from function definition and customized default template
+;;   - C-c C-o C-o :: update template
+;; - navigating and filling roxygen fields
+;;   - C-c TAB, M-q, C-a, ENTER, M-h :: advised tag completion, fill-paragraph,
+;;        ess-roxy-move-beginning-of-line, newline-and-indent
+;;   - C-c C-o n,p :: next, previous roxygen entry
+;;   - C-c C-o C-c :: Unroxygen region. Convenient for editing examples.
+;; - folding visibility using hs-minor-mode
+;;   - TAB :: advised ess-indent-command, hide entry if in roxygen doc.
+;; - preview
+;;   - C-c C-o C-r :: create a preview of the Rd file as generated
+;;     using roxygen
+;;   - C-c C-o C-t :: create a preview of the Rd HTML file as generated
+;;     using roxygen and the tools package
+;;   - C-c C-o t :: create a preview of the Rd text file
+;;
+;; Known issues:
+;;
+;; - hideshow mode does not work very well. In particular, if ordinary
+;;   comments precede a roxygen entry, then both will be hidden in the
+;;   same overlay from start and not unfoldable using TAB since the
+;;   roxygen prefix is not present. The planned solution is implement
+;;   a replacement for hideshow.
+;; - only limited functionality for S4 documentation.
+
+;;; Code:
+
+(require 'ess-utils)
+(require 'hideshow)
+(require 'outline)
+(eval-when-compile
+  (require 'cl-lib)
+  (require 'subr-x))
+(require 'ess-rd)
+(require 'ess-r-syntax)
+
+(defvar roxy-str)
+(defvar ess-r-mode-syntax-table)
+(declare-function ess-fill-args "ess-r-mode")
+(declare-function ess-fill-continuations "ess-r-mode")
+(declare-function inferior-ess-r-force "ess-r-mode")
+
+(defvar-local ess-roxy-re nil
+  "Regular expression to recognize roxygen blocks.")
+
+\f
+;;*;; Roxy Minor Mode
+
+(defvar ess-roxy-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-o h") #'ess-roxy-hide-all)
+    (define-key map (kbd "C-c C-o n")   #'ess-roxy-next-entry)
+    (define-key map (kbd "C-c C-o p")   #'ess-roxy-previous-entry)
+    (define-key map (kbd "C-c C-o C-o") #'ess-roxy-update-entry)
+    (define-key map (kbd "C-c C-o C-r") #'ess-roxy-preview-Rd)
+    (define-key map (kbd "C-c C-o C-w") #'ess-roxy-preview-HTML)
+    (define-key map (kbd "C-c C-o C-t")   #'ess-roxy-preview-text)
+    (define-key map (kbd "C-c C-o C-c") #'ess-roxy-toggle-roxy-region)
+    (define-key map [remap back-to-indentation] #'ess-roxy-goto-end-of-roxy-comment)
+    (define-key map [remap newline] #'ess-roxy-newline)
+    (define-key map [remap newline-and-indent] #'ess-roxy-newline)
+    (define-key map [remap ess-indent-command] #'ess-roxy-ess-indent-command)
+    (define-key map [remap move-beginning-of-line] #'ess-roxy-move-beginning-of-line)
+    (define-key map [remap beginning-of-visual-line] #'ess-roxy-move-beginning-of-line)
+    map))
+
+(defvar ess-roxy-font-lock-keywords nil
+  "Cache set by `ess-roxy-generate-keywords'.
+Used to remove keywords added by function `ess-roxy-mode'.")
+
+(defun ess-roxy-generate-keywords ()
+  "Generate a list of keywords suitable for `font-lock-add-keywords'."
+  (setq-local ess-roxy-font-lock-keywords
+              `((,(concat ess-roxy-re " *\\([@\\]"
+                          (regexp-opt ess-roxy-tags-param t)
+                          "\\)\\>")
+                 (1 'font-lock-keyword-face prepend))
+                (,(concat ess-roxy-re " *\\(@"
+                          (regexp-opt '("param" "importFrom" "importClassesFrom"
+                                        "importMethodsFrom" "describeIn")
+                                      'words)
+                          "\\)\\(?:[ \t]+\\(\\(?:\\sw+,?\\)+\\)\\)")
+                 (1 'font-lock-keyword-face prepend)
+                 (3 'font-lock-variable-name-face prepend))
+                (,(concat "[@\\]" (regexp-opt ess-roxy-tags-noparam t) "\\>")
+                 (0 'font-lock-variable-name-face prepend))
+                (,(concat ess-roxy-re)
+                 (0 'bold prepend)))))
+
+(defvar ess-roxy-fold-examples nil
+  "Whether to fold `@examples' when opening a buffer.
+Use you regular key for `outline-show-entry' to reveal it.")
+
+;;;###autoload
+(define-minor-mode ess-roxy-mode
+  "Minor mode for editing ROxygen documentation."
+  :keymap ess-roxy-mode-map
+  (if ess-roxy-mode
+      ;; Turn on `ess-roxy-mode':
+      (progn
+        (setq-local ess-roxy-re (concat "^" (string-trim comment-start) "+'"))
+        (font-lock-add-keywords nil (ess-roxy-generate-keywords))
+        (add-hook 'completion-at-point-functions #'ess-roxy-complete-tag nil t)
+        ;; Hideshow Integration
+        (when ess-roxy-hide-show-p
+          (hs-minor-mode 1)
+          (when ess-roxy-start-hidden-p
+            (ess-roxy-hide-all)))
+        ;;  Outline Integration
+        (when ess-roxy-fold-examples
+          (ess-roxy-hide-all-examples))
+        ;; Autofill
+        (setq-local paragraph-start (concat "\\(" ess-roxy-re "\\)*" paragraph-start))
+        (setq-local paragraph-separate (concat "\\(" ess-roxy-re "\\)*" paragraph-separate))
+        (setq-local adaptive-fill-function #'ess-roxy-adaptive-fill-function)
+        ;; Hooks
+        (add-hook 'ess-presend-filter-functions #'ess-roxy-remove-roxy-re nil t))
+    ;; Turn off `ess-roxy-mode':
+    ;; Hideshow
+    (when (and ess-roxy-hide-show-p hs-minor-mode)
+      (hs-show-all)
+      (hs-minor-mode))
+    ;; Hooks
+    (remove-hook 'ess-presend-filter-functions #'ess-roxy-remove-roxy-re t)
+    (font-lock-remove-keywords nil ess-roxy-font-lock-keywords)
+    ;; (setq-local syntax-propertize-function nil)
+    ;; (setq-local font-lock-fontify-region-function nil)
+    ;; (setq-local font-lock-unfontify-region-function nil)
+    )
+  ;; Regardless of turning on or off we need to re-fontify the buffer:
+  (when font-lock-mode
+    (font-lock-flush)))
+
+
+\f
+;;*;; Outline Integration
+
+(defvar ess-roxy-outline-regexp "^#+' +@examples\\|^[^#]")
+
+(defun ess-roxy-substitute-outline-regexp (command)
+  (let ((outline-regexp (if (ess-roxy-entry-p "examples")
+                            ess-roxy-outline-regexp
+                          outline-regexp)))
+    (funcall command)))
+
+(declare-function outline-cycle "outline-magic")
+(defun ess-roxy-cycle-example ()
+  (interactive)
+  (unless (featurep 'outline-magic)
+    (error "Please install and load outline-magic"))
+  ;; Don't show children when cycling @examples
+  (let ((this-command 'outline-cycle-overview))
+    (ess-roxy-substitute-outline-regexp #'outline-cycle)))
+
+(defun ess-roxy-show-example ()
+  (interactive)
+  (ess-roxy-substitute-outline-regexp #'outline-show-entry))
+
+(defun ess-roxy-hide-example ()
+  (interactive)
+  (ess-roxy-substitute-outline-regexp #'outline-hide-entry))
+
+(defun ess-roxy-hide-all-examples ()
+  (interactive)
+  (save-excursion
+    (goto-char (point-min))
+    (while (re-search-forward "^#+' +@examples\\b" nil t)
+      ;; Handle edge cases
+      (when (ess-roxy-entry-p "examples")
+        (ess-roxy-hide-example)))))
+
+(substitute-key-definition #'outline-hide-entry
+                           #'ess-roxy-hide-example
+                           ess-roxy-mode-map outline-minor-mode-map)
+
+(substitute-key-definition #'outline-show-entry
+                           #'ess-roxy-show-example
+                           ess-roxy-mode-map outline-minor-mode-map)
+
+\f
+;;*;; Function definitions
+
+(defun ess-back-to-roxy ()
+  "Go to roxy prefix."
+  (end-of-line)
+  (re-search-backward (concat ess-roxy-re " ?") (line-beginning-position))
+  (goto-char (match-end 0)))
+
+(defun ess-roxy-beg-of-entry ()
+  "Get point number at start of current entry, 0 if not in entry."
+  (save-excursion
+    (let (beg)
+      (beginning-of-line)
+      (setq beg -1)
+      (if (not (ess-roxy-entry-p))
+          (setq beg 0)
+        (setq beg (point)))
+      (while (and (= (forward-line -1) 0) (ess-roxy-entry-p))
+        (setq beg (point)))
+      beg)))
+
+(defun ess-roxy-in-header-p ()
+  "True if point is the description / details field."
+  (save-excursion
+    (let ((res t)
+          (cont (ess-roxy-entry-p)))
+      (beginning-of-line)
+      (while cont
+        (if (looking-at (concat ess-roxy-re " *[@].+"))
+            (progn (setq res nil)
+                   (setq cont nil)))
+        (setq cont (and (= (forward-line -1) 0) (ess-roxy-entry-p)))
+        )res)))
+
+(defun ess-roxy-beg-of-field ()
+  "Get point number at beginning of current field, 0 if not in entry."
+  (save-excursion
+    (let (cont beg)
+      (beginning-of-line)
+      (setq beg 0)
+      (setq cont t)
+      (while (and (ess-roxy-entry-p) cont)
+        (setq beg (point))
+        (if (looking-at (concat ess-roxy-re " *[@].+"))
+            (setq cont nil))
+        (if (ess-roxy-in-header-p)
+            (if (looking-at (concat ess-roxy-re " *$"))
+                (progn
+                  (forward-line 1)
+                  (setq beg (point))
+                  (setq cont nil))))
+        (if cont (setq cont (= (forward-line -1) 0))))
+      beg)))
+
+(defun ess-roxy-end-of-entry ()
+  "Get point number at end of current entry, 0 if not in entry."
+  (save-excursion
+    (let ((end))
+      (end-of-line)
+      (setq end -1)
+      (if (not (ess-roxy-entry-p))
+          (setq end 0)
+        (setq end (point)))
+      (while (and (= (forward-line 1) 0) (ess-roxy-entry-p))
+        (end-of-line)
+        (setq end (point)))
+      end)))
+
+(defun ess-roxy-end-of-field ()
+  "Get point number at end of current field, 0 if not in entry."
+  (save-excursion
+    (let ((end nil)
+          (cont nil))
+      (setq end 0)
+      (if (ess-roxy-entry-p) (progn (end-of-line) (setq end (point))))
+      (beginning-of-line)
+      (forward-line 1)
+      (setq cont t)
+      (while (and (ess-roxy-entry-p) cont)
+        (save-excursion
+          (end-of-line)
+          (setq end (point)))
+        (if (or (and (ess-roxy-in-header-p)
+                     (looking-at (concat ess-roxy-re " *$")))
+                (looking-at (concat ess-roxy-re " *[@].+")))
+            (progn
+              (forward-line -1)
+              (end-of-line)
+              (setq end (point))
+              (setq cont nil)))
+        (if cont (setq cont (= (forward-line 1) 0))))
+      end)))
+
+(defun ess-roxy-entry-p (&optional field)
+  "Non-nil if point is in a roxy entry.
+FIELD allows checking for a specific field with
+`ess-roxy-current-field'."
+  (and ess-roxy-mode
+       (save-excursion
+         (beginning-of-line)
+         (looking-at-p ess-roxy-re))
+       (or (null field)
+           (string= (ess-roxy-current-field) field))))
+
+(defun ess-roxy-narrow-to-field ()
+  "Go to to the start of current field."
+  (interactive)
+  (let ((beg (ess-roxy-beg-of-field))
+        (end (ess-roxy-end-of-field)))
+    (narrow-to-region beg end)))
+
+(defun ess-roxy-extract-field ()
+  (let ((field (buffer-substring (ess-roxy-beg-of-entry)
+                                 (ess-roxy-end-of-entry)))
+        (prefix-re (ess-roxy-guess-str))
+        (roxy-re ess-roxy-re))
+    (with-temp-buffer
+      (setq ess-roxy-re roxy-re)
+      (insert field)
+      (goto-char (point-min))
+      (while (re-search-forward prefix-re (point-max) 'noerror)
+        (replace-match ""))
+      (buffer-substring (point-min) (point-max)))))
+
+(defun ess-roxy-adaptive-fill-function ()
+  "Return prefix for filling paragraph or nil if not determined."
+  (when (ess-roxy-entry-p)
+    (let ((roxy-str (car (split-string (ess-roxy-guess-str) "'"))))
+      (if (ess-roxy-in-header-p)
+          (save-excursion
+            (ess-back-to-roxy)
+            (re-search-forward "\\([ \t]*\\)" (line-end-position) t)
+            (concat roxy-str "' " (match-string 1)))
+        (concat roxy-str "' " (make-string ess-indent-offset ? ))))))
+
+(defun ess-roxy-current-field ()
+  "Return the name of the field at point."
+  (and (not (ess-roxy-in-header-p))
+       (save-excursion
+         (goto-char (ess-roxy-beg-of-field))
+         (if (re-search-forward (concat ess-roxy-re
+                                        "[ \t]+@\\([[:alpha:]]+\\)")
+                                (line-end-position) t)
+             (match-string-no-properties 1)))))
+
+(defun ess-roxy-maybe-indent-line ()
+  "Indent line when point is in a field, but not in its first line."
+  (when (and (not (ess-roxy-in-header-p))
+             (not (equal (ess-roxy-current-field) "examples"))
+             (save-excursion
+               (beginning-of-line)
+               (let ((line-n (count-lines 1 (point))))
+                 (goto-char (ess-roxy-beg-of-field))
+                 (not (equal line-n (count-lines 1 (point)))))))
+    (ess-back-to-roxy)
+    (delete-region (point) (progn (skip-chars-forward " \t") (point)))
+    (insert (make-string ess-indent-offset ? ))))
+
+(defun ess-roxy-goto-func-def ()
+  "Put point at start of function.
+Go to the beginning of the current one or below the current
+roxygen entry, error otherwise"
+  (if (ess-roxy-entry-p)
+      (progn
+        (ess-roxy-goto-end-of-entry)
+        (forward-line 1)
+        (beginning-of-line))
+    (unless (looking-at-p ess-function-pattern)
+      (beginning-of-defun))))
+
+(defun ess-roxy-get-args-list-from-def ()
+  "Get args list for current function."
+  (save-excursion
+    (ess-roxy-goto-func-def)
+    (let ((args (ess-roxy-get-function-args)))
+      (mapcar (lambda (x) (cons x '(""))) args))))
+
+(defun ess-roxy-insert-args (args &optional here)
+  "Insert an ARGS list to the end of the current roxygen entry.
+If HERE is supplied start inputting `here'. Finish at end of
+line."
+  (let* ((roxy-str (ess-roxy-guess-str))
+         arg-des)
+    (if (and here (< 1 here))
+        (goto-char here)
+      (ess-roxy-goto-end-of-entry)
+      (beginning-of-line)
+      (when (not (looking-at-p "="))
+        (end-of-line)))
+    (while (stringp (caar args))
+      (setq arg-des (pop args))
+      (unless (string= (car arg-des) "")
+        (insert (concat "\n" roxy-str " @param " (car arg-des) " "))
+        (insert
+         (ess-replace-in-string (concat (car (cdr arg-des))) "\n"
+                                (concat "\n" roxy-str)))
+        (when ess-roxy-fill-param-p
+          (fill-paragraph))))))
+
+(defun ess-roxy-merge-args (fun ent)
+  "Take two args lists (alists) and return their union.
+The result holds all keys from both FUN and ENT but no duplicates and
+association from ent are preferred over entries from fun. Also,
+drop entries from ent that are not in fun and are associated with
+the empty string."
+  (let ((res-arg nil)
+        (arg-des))
+    (while (stringp (caar fun))
+      (setq arg-des (pop fun))
+      (if (assoc (car arg-des) ent)
+          (setq res-arg
+                (cons (cons (car arg-des) (cdr (assoc (car arg-des) ent))) res-arg))
+        (setq res-arg (cons (cons (car arg-des) '("")) res-arg))))
+    (while (stringp (caar ent))
+      (setq arg-des (pop ent))
+      (if (and (not (assoc (car arg-des) res-arg)) (not (string= (car (cdr arg-des)) "")))
+          (setq res-arg (cons (cons (car arg-des) (cdr arg-des)) res-arg))))
+    (nreverse res-arg)))
+
+(defun ess-roxy-update-entry ()
+  "Update the entry at point or the entry above the current function.
+Add a template empty roxygen documentation if no roxygen entry is
+available. The template can be customized via the variable
+`ess-roxy-template-alist'. The parameter descriptions can are
+filled if `ess-roxy-fill-param-p' is non-nil."
+  (interactive)
+  (unless (derived-mode-p 'ess-r-mode)
+    (user-error "%s mode not yet supported" major-mode))
+  (save-excursion
+    (let* ((args-fun (ess-roxy-get-args-list-from-def))
+           (args-ent (ess-roxy-get-args-list-from-entry))
+           (args (ess-roxy-merge-args args-fun args-ent))
+           (roxy-str (ess-roxy-guess-str))
+           (line-break "")
+           template tag-def)
+      (ess-roxy-goto-func-def)
+      (when (not (= (forward-line -1) 0))
+        (insert "\n")
+        (forward-line -1))
+      (when (and (not (looking-at "^\n")) (not (ess-roxy-entry-p)))
+        (end-of-line)
+        (insert "\n"))
+      (if (ess-roxy-entry-p)
+          (ess-roxy-insert-args args (1- (ess-roxy-delete-args)))
+        (setq template (copy-sequence ess-roxy-template-alist))
+        (while (stringp (caar template))
+          (setq tag-def (pop template))
+          (if (string= (car tag-def) "param")
+              (ess-roxy-insert-args args (point))
+            (if (string= (car tag-def) "description")
+                (insert (concat line-break roxy-str " "
+                                (cdr tag-def) "\n" roxy-str))
+              (if (string= (car tag-def) "details")
+                  (insert (concat line-break roxy-str " " (cdr tag-def)))
+                (insert (concat line-break roxy-str " @"
+                                (car tag-def) " " (cdr tag-def))))))
+          (setq line-break "\n"))))))
+
+(defun ess-roxy-goto-end-of-entry ()
+  "Put point at the bottom of the current entry or above the function at point.
+Return t if the point is left in a roxygen entry, otherwise nil.
+Error if point is not in function or roxygen entry."
+  (when (not (ess-roxy-entry-p))
+    (beginning-of-defun)
+    (forward-line -1))
+  (if (ess-roxy-entry-p)
+      (progn (goto-char (ess-roxy-end-of-entry))
+             t)
+    (forward-line)
+    nil)
+  (ess-roxy-entry-p))
+
+(defun ess-roxy-goto-beg-of-entry ()
+  "Put point at the top of the entry at point or above the function at point.
+Return t if the point is left in a roxygen
+entry, otherwise nil. Error if point is not in function or
+roxygen entry."
+  (if (not (ess-roxy-entry-p))
+      (progn
+        (goto-char (nth 0 (end-of-defun)))
+        (forward-line -1)))
+  (if (ess-roxy-entry-p)
+      (progn
+        (goto-char (ess-roxy-beg-of-entry))
+        t)
+    (forward-line) nil))
+
+(defun ess-roxy-delete-args ()
+  "Remove all args from the entry at point or above the function at point.
+Return 0 if no deletions were made other wise the point at where
+the last deletion ended"
+  (save-excursion
+    (let* ((cont t)
+           (field-beg 0)
+           entry-beg entry-end field-end)
+      (ess-roxy-goto-end-of-entry)
+      (setq entry-beg (ess-roxy-beg-of-entry))
+      (setq entry-end (ess-roxy-end-of-entry))
+      (goto-char entry-end)
+      (beginning-of-line)
+      (while (and (<= entry-beg (point)) (> entry-beg 0) cont)
+        (if (looking-at
+             (concat ess-roxy-re " *@param"))
+            (progn
+              (setq field-beg (ess-roxy-beg-of-field))
+              (setq field-end (ess-roxy-end-of-field))
+              (delete-region field-beg (+ field-end 1))))
+        (setq cont nil)
+        (if (= (forward-line -1) 0)
+            (setq cont t)))
+      field-beg)))
+
+(defun ess-roxy-get-args-list-from-entry ()
+  "Fill an args list from the entry above the function where the point is."
+  (save-excursion
+    (let* (args entry-beg field-beg field-end args-text arg-name desc)
+      (if (ess-roxy-goto-end-of-entry)
+          (progn
+            (setq roxy-str (ess-roxy-guess-str))
+            (beginning-of-line)
+            (setq entry-beg (ess-roxy-beg-of-entry))
+            (while (and (< entry-beg (point)) (> entry-beg 0))
+              (if (looking-at
+                   (concat ess-roxy-re " *@param"))
+                  (progn
+                    (setq field-beg (ess-roxy-beg-of-field))
+                    (setq field-end (ess-roxy-end-of-field))
+                    (setq args-text (buffer-substring-no-properties
+                                     field-beg field-end))
+                    (setq args-text
+                          (ess-replace-in-string args-text roxy-str ""))
+                    (setq args-text
+                          (ess-replace-in-string
+                           args-text "[[:space:]]*@param *" ""))
+                    ;; (setq args-text
+                    ;;    (ess-replace-in-string args-text "\n" ""))
+                    (string-match "[^[:space:]]*" args-text)
+                    (setq arg-name (match-string 0 args-text))
+                    (setq desc (replace-regexp-in-string
+                                (concat "^" (regexp-quote arg-name) " *") "" args-text))
+                    (setq args (cons (list (concat arg-name)
+                                           (concat desc))
+                                     args))))
+              (forward-line -1))
+            args)
+        nil))))
+
+(defun ess-roxy-toggle-roxy-region (beg end)
+  "Toggle prefix roxygen string from BEG to END.
+Add the prefix if missing, remove if found. BEG and END default
+to the region, if active, and otherwise the entire line. This is
+convenient for editing example fields."
+  (interactive "r")
+  (unless (and beg end)
+    (setq beg (line-beginning-position)
+          end (line-end-position)))
+  (ess-roxy-roxy-region beg end (ess-roxy-entry-p)))
+
+(defun ess-roxy-roxy-region (beg end &optional on)
+  (save-excursion
+    (let (RE to-string
+             (roxy-str (ess-roxy-guess-str)))
+      (narrow-to-region beg (- end 1))
+      (if on
+          (progn (setq RE (concat ess-roxy-re " +?"))
+                 (setq to-string ""))
+        (setq RE "^")
+        (setq to-string (concat roxy-str " ")))
+      (goto-char beg)
+      (while (re-search-forward RE (point-max) 'noerror)
+        (replace-match to-string))
+      (widen))))
+
+(defun ess-roxy-preview ()
+  "Generate documentation for roxygen entry at point.
+Use a connected R session (starting one if necessary) and
+`ess-roxy-package' to generate the Rd code for the entry at
+point. Place it in a buffer and return that buffer."
+  (unless (derived-mode-p 'ess-r-mode)
+    (user-error "Preview only supported in R buffers, try `ess-r-devtools-document-package' instead"))
+  (let* ((beg (ess-roxy-beg-of-entry))
+         (tmpf (make-temp-file "ess-roxy"))
+         (roxy-buf (get-buffer-create " *RoxygenPreview*"))
+         (R-old-roxy
+          (concat
+           "..results <- roxygen2:::roc_process(rd_roclet(), parse.files(P), \"\");"
+           "cat(vapply(..results, function(x) roxygen2:::rd_out_cache$compute(x, format(x)), character(1)), \"\\n\")" ))
+         (R-new-roxy
+          (concat
+           "..results <- roc_proc_text(rd_roclet(), readChar(P, file.info(P)$size));"
+           "cat(vapply(..results, format, character(1)), \"\\n\")" ))
+         (out-rd-roclet
+          (cond ((string= "roxygen" ess-roxy-package)
+                 "make.Rd2.roclet()$parse")
+                ;; must not line break strings to avoid getting +s in the output
+                ((string= "roxygen2" ess-roxy-package)
+                 (concat "(function(P) { if(packageVersion('roxygen2') < '3.0.0') {"
+                         R-old-roxy "} else {" R-new-roxy "} })"))
+                (t (error "Need to hard code the roclet output call for roxygen package '%s'"
+                          ess-roxy-package)))))
+    (when (= beg 0)
+      (error "Point is not in a Roxygen entry"))
+    (save-excursion
+      (goto-char (ess-roxy-end-of-entry))
+      (forward-line 1)
+      (if (end-of-defun)
+          (append-to-file beg (point) tmpf)
+        (while (and (forward-line 1)
+                    (not (looking-at-p "^$"))
+                    (not (eobp))
+                    (not (looking-at-p ess-roxy-re))))
+        (append-to-file beg (point) tmpf))
+      (inferior-ess-r-force)
+      (ess-force-buffer-current)
+      (unless (ess-boolean-command (concat "print(suppressWarnings(require(" ess-roxy-package
+                                           ", quietly=TRUE)))\n"))
+        (error (concat "Failed to load the " ess-roxy-package " package; "
+                       "in R, try  install.packages(\"" ess-roxy-package "\")")))
+      (ess-command (concat out-rd-roclet "(\"" tmpf "\")\n") roxy-buf)
+      (with-current-buffer roxy-buf
+        ;; Kill characters up to % in case we missed stripping prompts
+        ;; or +'s:
+        (goto-char (point-min))
+        (when (re-search-forward "%" (line-end-position) t)
+          (backward-char)
+          (delete-region (line-beginning-position) (point)))))
+    (delete-file tmpf)
+    roxy-buf))
+
+(defun ess-roxy-preview-HTML (&optional visit-instead-of-browse)
+  "Use a (possibly newly) connected R session and the roxygen package to
+generate a HTML page for the roxygen entry at point and open that
+buffer in a browser.  Visit the HTML file instead of showing it in
+a browser if `visit-instead-of-browse' is non-nil."
+  (interactive "P")
+  (let* ((roxy-buf (ess-roxy-preview))
+         (rd-tmp-file (make-temp-file "ess-roxy-" nil ".Rd"))
+         (html-tmp-file (make-temp-file "ess-roxy-" nil ".html"))
+         (rd-to-html (concat "Rd2HTML(\"" rd-tmp-file "\",\""
+                             html-tmp-file "\", stages=c(\"render\"))"))
+         )
+    (with-current-buffer roxy-buf
+      (set-visited-file-name rd-tmp-file)
+      (save-buffer)
+      (kill-buffer roxy-buf))
+    (ess-force-buffer-current)
+    (ess-command "print(suppressWarnings(require(tools, quietly=TRUE)))\n")
+    (if visit-instead-of-browse
+        (progn
+          (ess-command (concat rd-to-html "\n"))
+          (find-file html-tmp-file))
+      (ess-command (concat "browseURL(" rd-to-html ")\n")))))
+
+(defun ess-roxy-preview-text ()
+  "Use the connected R session and the roxygen package to
+generate the text help page of the roxygen entry at point."
+  (interactive)
+  (with-current-buffer (ess-roxy-preview)
+    (Rd-preview-help)))
+
+(defun ess-roxy-preview-Rd (&optional name-file)
+  "Preview Rd for the roxygen entry at point.
+Use the connected R session and the roxygen package to
+generate the Rd code for the roxygen entry at point. If called
+with a non-nil NAME-FILE (\\[universal-argument]),
+also set the visited file name of the created buffer to
+facilitate saving that file."
+  (interactive "P")
+  (let ((roxy-buf (ess-roxy-preview)))
+    (pop-to-buffer roxy-buf)
+    (if name-file
+        (save-excursion
+          (goto-char 1)
+          (search-forward-regexp "name{\\(.+\\)}")
+          (set-visited-file-name (concat (match-string 1) ".Rd"))))
+    (Rd-mode)
+    ;; why should the following be needed here? [[currently has no effect !!]]
+    ;; usually in a *.Rd file fontification happens automatically
+    (font-lock-ensure)))
+
+
+(defun ess-roxy-guess-str (&optional not-here)
+  "Guess the prefix used in the current roxygen block.
+If NOT-HERE is non-nil, guess the prefix for nearest roxygen
+block before the point."
+  (save-excursion
+    (if (ess-roxy-entry-p)
+        (progn
+          (goto-char (line-beginning-position))
+          (search-forward-regexp ess-roxy-re))
+      (if not-here
+          (search-backward-regexp ess-roxy-re)))
+    (if (or not-here (ess-roxy-entry-p))
+        (match-string 0)
+      (if (derived-mode-p 'ess-r-mode)
+          ess-roxy-str
+        (concat (string-trim comment-start) "'")))))
+
+(defun ess-roxy-hide-block ()
+  "Hide current roxygen comment block."
+  (interactive)
+  (save-excursion
+    (let ((end-of-entry (ess-roxy-end-of-entry))
+          (beg-of-entry (ess-roxy-beg-of-entry)))
+      (if (= (cdr (func-arity 'hs-hide-block-at-point)) 1)
+          ;; Emacs 31 ++ signature: single optional COMMENT-REG -- <GH>/emacs-ess/ESS/issues/1334
+          (hs-hide-block-at-point (list beg-of-entry end-of-entry))
+        ;; Emacs <= 30.x signature: (END-OF-BLOCK &optional COMMENT-REG)
+        (hs-hide-block-at-point nil (list beg-of-entry end-of-entry))))))
+
+(defun ess-roxy-toggle-hiding ()
+  "Toggle hiding/showing of a block.
+See `hs-show-block' and `ess-roxy-hide-block'."
+  (interactive)
+  (hs-life-goes-on
+   (if (hs-overlay-at (line-end-position))
+       (hs-show-block)
+     (ess-roxy-hide-block))))
+
+(defun ess-roxy-show-all ()
+  "Hide all Roxygen entries in current buffer."
+  (interactive)
+  (ess-roxy-hide-all t))
+
+(defun ess-roxy-hide-all (&optional show)
+  "Hide all Roxygen entries in current buffer."
+  (interactive)
+  (when (not ess-roxy-hide-show-p)
+    (user-error "First enable hide-show with `ess-roxy-hide-show-p'"))
+  (hs-life-goes-on
+   (save-excursion
+     (goto-char (point-min))
+     (while (re-search-forward (concat ess-roxy-re) (point-max) t 1)
+       (let ((end-of-entry (ess-roxy-end-of-entry)))
+         (if show
+             (hs-show-block)
+           (ess-roxy-hide-block))
+         (goto-char end-of-entry)
+         (forward-line 1))))))
+
+(defun ess-roxy-previous-entry ()
+  "Go to beginning of previous Roxygen entry."
+  (interactive)
+  (if (ess-roxy-entry-p)
+      (progn
+        (goto-char (ess-roxy-beg-of-entry))
+        (forward-line -1)))
+  (search-backward-regexp ess-roxy-re (point-min) t 1)
+  (goto-char (ess-roxy-beg-of-entry)))
+
+(defun ess-roxy-next-entry ()
+  "Go to beginning of next Roxygen entry."
+  (interactive)
+  (if (ess-roxy-entry-p)
+      (progn
+        (goto-char (ess-roxy-end-of-entry))
+        (forward-line 1)))
+  (search-forward-regexp ess-roxy-re (point-max) t 1)
+  (goto-char (ess-roxy-beg-of-entry)))
+
+(defun ess-roxy-get-function-args ()
+  "Return the arguments specified for the current function as a list of strings.
+Assumes point is at the beginning of the function."
+  (save-excursion
+    (let ((args-txt
+           (buffer-substring-no-properties
+            (progn
+              (search-forward-regexp "\\([=,-]+ *function *\\|^\s*function\\)" nil nil 1)
+              (+ (point) 1))
+            (progn
+              (ess-roxy-match-paren)
+              (point)))))
+      (setq args-txt (replace-regexp-in-string "#+[^\"']*\n" "" args-txt))
+      (setq args-txt (replace-regexp-in-string "([^)]+)" "" args-txt))
+      (setq args-txt (replace-regexp-in-string "=[^,]+" "" args-txt))
+      (setq args-txt (replace-regexp-in-string "[ \t\n]+" "" args-txt))
+      (split-string args-txt ","))))
+
+(defun ess-roxy-match-paren ()
+  "Go to the matching parenthesis."
+  (cond ((looking-at "\\s\(") (forward-list 1) (backward-char 1))
+        ((looking-at "\\s\)") (forward-char 1) (backward-list 1))))
+
+(defun ess-roxy-complete-tag ()
+  "Complete the tag at point."
+  (let ((bounds (ess-bounds-of-symbol)))
+    (when (and bounds
+               (save-excursion
+                 (goto-char (car bounds))
+                 (eq (following-char) ?@)))
+      (list (1+ (car bounds)) (cdr bounds)
+            (append ess-roxy-tags-noparam ess-roxy-tags-param)))))
+
+(defun ess-roxy-tag-completion ()
+  "Completion data for Emacs >= 24."
+  (when (save-excursion (re-search-backward "@\\<\\(\\w*\\)" (line-beginning-position) t))
+    (let ((beg (match-beginning 1))
+          (end (match-end 1)))
+      (when (and end (= end (point)))
+        (list beg end (append ess-roxy-tags-noparam ess-roxy-tags-param) :exclusive 'no)))))
+
+(defun ess-roxy-remove-roxy-re (string)
+  "Remove `ess-roxy-str' from STRING before sending to R process.
+Useful for sending code from example section. This function is
+placed in `ess-presend-filter-functions'."
+  ;; In the future we might want to detect chunks between markdown
+  ;; fences and strip everything that comes before `@examples`
+  (if (ess-roxy--all-prefixed string)
+      (replace-regexp-in-string (concat ess-roxy-re "\\s-*") "" string)
+    string))
+
+(defun ess-roxy--all-prefixed (string)
+  (let ((ess-roxy-re-lexical ess-roxy-re))
+    (with-temp-buffer
+      (insert string)
+      (goto-char 0)
+      (while (and (looking-at-p ess-roxy-re-lexical)
+                  (re-search-forward "\n" nil t)))
+      (looking-at-p ess-roxy-re-lexical))))
+
+(defun ess-roxy-find-par-end (stop-point &rest stoppers)
+  (mapc #'(lambda (stopper)
+            (when (and (> stop-point (point))
+                       (save-excursion
+                         (re-search-forward stopper stop-point t)))
+              (setq stop-point (match-beginning 0))))
+        stoppers)
+  (save-excursion
+    (goto-char stop-point)
+    (line-end-position 0)))
+
+\f
+;;*;; Advices
+(defmacro ess-roxy-with-filling-context (examples &rest body)
+  "Setup context (e.g. `comment-start') for filling roxygen BODY.
+EXAMPLES should be non-nil if filling an example block."
+  (declare (indent 2) (debug (&rest form)))
+  `(let ((comment-start (concat ess-roxy-re "[ \t]+#"))
+         (comment-start-skip (concat ess-roxy-re "[ \t]+# *"))
+         (comment-use-syntax nil)
+         (adaptive-fill-first-line-regexp (concat ess-roxy-re "[ \t]*"))
+         (paragraph-start (concat "\\(" ess-roxy-re "\\(" paragraph-start
+                                  "\\|[ \t]*@" "\\)" "\\)\\|\\(" paragraph-start "\\)"))
+         (temp-table (if ,examples
+                         (make-syntax-table ess-r-mode-syntax-table)
+                       Rd-mode-syntax-table)))
+     (when ,examples
+       ;; Prevent the roxy prefix to be interpreted as comment or string
+       ;; starter
+       (modify-syntax-entry ?# "w" temp-table)
+       (modify-syntax-entry ?' "w" temp-table))
+     ;; Neutralize (comment-normalize-vars) because it modifies the
+     ;; comment-start regexp in such a way that paragraph filling of
+     ;; comments in @examples fields does not work
+     (cl-letf (((symbol-function 'comment-normalize-vars) #'ignore))
+       (with-syntax-table temp-table
+         ,@body))))
+
+(defun ess-roxy-ess-indent-command (&optional whole-exp)
+  "Hide this block if we are at the beginning of the line.
+Else call `ess-indent-command'."
+  (interactive "P")
+  (if (and (bolp) (ess-roxy-entry-p) ess-roxy-hide-show-p)
+      (progn (ess-roxy-toggle-hiding))
+    (ess-indent-command whole-exp)))
+
+(defun ess--roxy-fill-block (fun &optional args)
+  "Fill a roxygen block.
+FUN should be a filling function and ARGS gets passed to it."
+  (let* ((saved-pos (point))
+         (par-start (save-excursion
+                      (if (save-excursion
+                            (and (backward-paragraph)
+                                 (forward-paragraph)
+                                 (<= (point) saved-pos)))
+                          (line-beginning-position)
+                        (progn (backward-paragraph) (point)))))
+         (par-end (ess-roxy-find-par-end
+                   (save-excursion
+                     (forward-paragraph)
+                     (point))
+                   (concat ess-roxy-re "[ \t]*@examples\\b") "^[^#]")))
+    ;; Refill the whole structural paragraph sequentially, field by
+    ;; field, stopping at @examples
+    (ess-roxy-with-filling-context nil
+        (save-excursion
+          (save-restriction
+            (narrow-to-region par-start par-end)
+            (goto-char (point-min))
+            (while (< (point) (point-max))
+              (ess-roxy-maybe-indent-line)
+              (apply fun args)
+              (forward-paragraph)))))))
+
+(defun ess-r--fill-paragraph (orig-fun &rest args)
+  "ESS fill paragraph for R mode.
+Overrides `fill-paragraph' which is ORIG-FUN when necessary and
+passes ARGS to it."
+  (cond
+   ;; Regular case
+   ((not (derived-mode-p 'ess-r-mode))
+    (apply orig-fun args))
+   ;; Filling of code comments in @examples roxy field
+   ((and (ess-roxy-entry-p)
+         (save-excursion
+           (ess-roxy-goto-end-of-roxy-comment)
+           (looking-at "#")))
+    (ess-roxy-with-filling-context t
+        (apply orig-fun args)))
+   ((and (not (ess-roxy-entry-p))
+         (ess-inside-comment-p))
+    (apply orig-fun args))
+   ;; Filling of call arguments with point on call name
+   ((and ess-fill-calls
+         (ess-inside-call-name-p))
+    (save-excursion
+      (skip-chars-forward "^([")
+      (forward-char)
+      (ess-fill-args)))
+   ;; Filling of continuations
+   ((and ess-fill-continuations
+         (ess-inside-continuation-p))
+    (ess-fill-continuations))
+   ;; Filling of call arguments
+   ((and ess-fill-calls
+         (ess-inside-call-p))
+    (ess-fill-args))
+   ;; Filling of roxy blocks
+   ((ess-roxy-entry-p)
+    (ess--roxy-fill-block orig-fun args))
+   (t
+    (apply orig-fun args))))
+(advice-add 'fill-paragraph :around #'ess-r--fill-paragraph)
+
+(defun ess-roxy-move-beginning-of-line (arg)
+  "Move point to the beginning of the current line or roxygen comment.
+If not in a roxygen comment, call `move-beginning-of-line', which
+see for ARG. If in a roxygen field, leave point at the end of a
+roxygen comment. If already there, move to the beginning of the
+line."
+  (interactive "^p")
+  (if (ess-roxy-entry-p)
+      (let ((pos (point)))
+        (ess-roxy-goto-end-of-roxy-comment)
+        (when (eql (point) pos)
+          (move-beginning-of-line nil)))
+    (move-beginning-of-line arg)))
+
+(defun ess-roxy-goto-end-of-roxy-comment ()
+  "Leave point at the end of a roxygen comment.
+If not in a roxygen entry, call `back-to-indentation'."
+  (interactive)
+  (if (ess-roxy-entry-p)
+      (progn
+        (end-of-line)
+        (re-search-backward (concat ess-roxy-re " *")
+                            (line-beginning-position) t)
+        (goto-char (match-end 0)))
+    (back-to-indentation)))
+
+(defun ess-roxy-indent-new-comment-line ()
+  (if (not (ess-roxy-entry-p))
+      (indent-new-comment-line)
+    (ess-roxy-indent-on-newline)))
+
+(define-obsolete-function-alias 'ess-roxy-newline-and-indent
+  #'ess-roxy-newline "ESS 19.04")
+(defun ess-roxy-newline ()
+  "Start a newline and insert the roxygen prefix.
+Only do this if in a roxygen block and
+`ess-roxy-insert-prefix-on-newline' is non-nil."
+  (interactive)
+  (if (and (ess-roxy-entry-p)
+           ess-roxy-insert-prefix-on-newline)
+      (ess-roxy-indent-on-newline)
+    (newline nil t)))
+
+(defun ess-roxy-indent-on-newline ()
+  "Insert a newline in a roxygen field."
+  (cond
+   ;; Point at beginning of first line of entry; do nothing
+   ((= (point) (ess-roxy-beg-of-entry))
+    (newline-and-indent))
+   ;; Otherwise: skip over roxy comment string if necessary and then
+   ;; newline and then inset new roxy comment string
+   (t
+    (let ((point-after-roxy-string
+           (save-excursion (forward-line 0)
+                           (ess-back-to-roxy)
+                           (point))))
+      (goto-char (max (point) point-after-roxy-string)))
+    (newline-and-indent)
+    (insert (concat (ess-roxy-guess-str t) " ")))))
+
+(defun ess-roxy-cpp-fill-paragraph (&rest _args)
+  "Advice for `c-fill-paragraph' that accounts for roxygen comments."
+  (cond
+   ;; Fill roxy @example's.
+   ((ess-roxy-entry-p "examples")
+    (ess--roxy-fill-block 'fill-paragraph) nil)
+   ;; Fill roxy entries.
+   ((ess-roxy-entry-p)
+    (ess--roxy-fill-block 'fill-paragraph) nil)
+   ;; Return t to signal to go on to `c-fill-paragraph'.
+   (t t)))
+
+(advice-add 'c-fill-paragraph :before-while #'ess-roxy-cpp-fill-paragraph)
+
+(defun ess-roxy-enable-in-cpp ()
+  "Enable `ess-roxy-mode' in C++ buffers in R packages."
+  (when (and (fboundp 'ess-r-package-project)
+             (ess-r-package-project))
+    (ess-roxy-mode)))
+
+(with-eval-after-load "cc-mode"
+  (add-hook 'c++-mode-hook #'ess-roxy-enable-in-cpp))
+
+(defun ess-roxy--region-p (beg end)
+  (when ess-roxy-re
+    (save-excursion
+      (goto-char beg)
+      (catch 'ess-r-not-roxy
+        (while (< (point) end)
+          (unless (looking-at-p ess-roxy-re)
+            (throw 'ess-r-not-roxy nil))
+          (forward-line))
+        t))))
+
+(provide 'ess-roxy)
+
+;;; ess-roxy.el ends here
diff --git a/elpa/ess-20260424.1544/ess-s-lang.el b/elpa/ess-20260424.1544/ess-s-lang.el
new file mode 100644 (file)
index 0000000..c02f960
--- /dev/null
@@ -0,0 +1,526 @@
+;;; ess-s-lang.el --- Support for editing S source code  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1989-2022 Free Software Foundation, Inc.
+;; Author: A.J. Rossini <rossiniNOSPAMbiostat.washington.edu>
+;; Created: 26 Aug 1997
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; Code for general editing S source code (specializes to S, S+, R).
+
+;;; Code:
+
+(require 'ess-mode)
+(require 'ess-help)
+(require 'ess-inf)
+
+(declare-function speedbar-add-supported-extension "speedbar" (extension))
+
+\f ; Configuration variables
+
+(defvar S-syntax-table
+  (let ((S-syntax-table (make-syntax-table)))
+    (modify-syntax-entry ?\\ "\\" S-syntax-table)
+    (modify-syntax-entry ?+  "."  S-syntax-table)
+    (modify-syntax-entry ?-  "."  S-syntax-table)
+    (modify-syntax-entry ?=  "."  S-syntax-table)
+    (modify-syntax-entry ?%  "."  S-syntax-table)
+    (modify-syntax-entry ?<  "."  S-syntax-table)
+    (modify-syntax-entry ?>  "."  S-syntax-table)
+    (modify-syntax-entry ?&  "."  S-syntax-table)
+    (modify-syntax-entry ?|  "."  S-syntax-table)
+    (modify-syntax-entry ?\' "\"" S-syntax-table)
+    (modify-syntax-entry ?\" "\"" S-syntax-table)
+    (modify-syntax-entry ?#  "<"  S-syntax-table) ; open comment
+    (modify-syntax-entry ?\n ">"  S-syntax-table) ; close comment
+    ;;(modify-syntax-entry ?.  "w"  S-syntax-table) ; "." used in S obj names
+    (modify-syntax-entry ?.  "_"  S-syntax-table) ; see above/below,
+                                        ; plus consider separation.
+    (modify-syntax-entry ?$  "_"  S-syntax-table); foo$comp = 1 symbol(completion)
+    (modify-syntax-entry ?@  "_"  S-syntax-table); foo@slot = 1 symbol(completion)
+    (modify-syntax-entry ?_  "_"  S-syntax-table)
+    (modify-syntax-entry ?:  "_"  S-syntax-table)
+    (modify-syntax-entry ?*  "."  S-syntax-table)
+    (modify-syntax-entry ?<  "."  S-syntax-table)
+    (modify-syntax-entry ?>  "."  S-syntax-table)
+    (modify-syntax-entry ?/  "."  S-syntax-table)
+    S-syntax-table)
+  "Syntax table for S code."
+  )
+
+(defvar S-editing-alist
+  '((paragraph-start              . (concat "\\s-*$\\|" page-delimiter))
+    (paragraph-separate           . (concat "\\s-*$\\|" page-delimiter))
+    (paragraph-ignore-fill-prefix . t)
+    ;;(comment-indent-function  . 'S-comment-indent)
+    ;;(ess-comment-indent           . 'S-comment-indent)
+    ;;(ess-calculate-indent           . 'ess-calculate-indent)
+    ;;(ess-keep-dump-files          . 'ask)
+    ;; For Changelog add, require ' ' before <- : "attr<-" is a function name :
+    (add-log-current-defun-header-regexp . "^\\(.+\\)\\s-+<-[ \t\n]*function"))
+  "General options for S and S+ source files.")
+
+(defvar inferior-S-language-start
+  '(concat "options("
+           "STERM='"    ess-STERM  "'"
+           ", str.dendrogram.last=\"'\""
+           (if ess-editor (concat ", editor='" ess-editor "'"))
+           (if ess-pager  (concat ", pager='"  ess-pager  "', help.pager='"  ess-pager  "'"))
+           ", show.error.locations=TRUE"
+           ")")
+  "S language expression for startup -- default for all S dialects.")
+
+(defconst S-common-cust-alist
+  '((ess-language                  . "S")
+    (inferior-ess-exit-command     . "q()\n")
+    (inferior-ess-language-start   . (eval inferior-S-language-start))
+    (comint-use-prompt-regexp      . t)  ;;use fields if nil
+    (comint-process-echoes        . t)
+    ;; these prompt are the same for all S-languages As long as custom prompt
+    ;; ends in inferior-ess-primary-prompt everything should work as expected.
+    (inferior-ess-primary-prompt   . "> ")
+    ;; (inferior-ess-secondary-prompt . "[+:] ") ;; catch Selection: and alike
+    (inferior-ess-secondary-prompt . "+ ") ;; catch Selection: and alike
+    (comment-start                . "#")
+    (comment-add                  . 1)
+    (comment-start-skip           . "#+ *")
+    (comment-use-syntax           . t)  ; see log for bug report 2013-06-07
+    (comment-column               . 40)
+    (ess-no-skip-regexp           . (concat "^ *@\\|" (default-value 'ess-no-skip-regexp)))
+    ;; inferior-ess-prompt is used by comint for navigation, only if
+    ;; comint-use-prompt-regexp is t; (transcript-mode also relies on this regexp)
+    (inferior-ess-prompt           . inferior-S-prompt)
+    (ess-getwd-command          . "getwd()\n")
+    (ess-setwd-command          . "setwd('%s')\n")
+    (ess-funargs-command        . ".ess_funargs(\"%s\")\n")
+    (fill-nobreak-predicate     . 'ess-inside-string-p)
+    (ess-execute-screen-options-command . "options(width=%d, length=99999)\n")
+    (font-lock-defaults           . '(ess-build-font-lock-keywords
+                                      nil nil ((?\. . "w") (?\_ . "w")))))
+  "S-language common settings for all <dialect>-customize-alist.")
+
+(defconst S+common-cust-alist
+  (append
+   '((ess-suffix                . "S")
+     (ess-help-sec-regex        . ess-help-S+-sec-regex)
+     (ess-help-sec-keys-alist   . ess-help-S+sec-keys-alist)
+     (ess-change-sp-regexp      . ess-S+-change-sp-regexp)
+     (ess-function-pattern      . ess-s-function-pattern)
+     (ess-function-template     . " <- \n#\nfunction()\n{\n\n}\n")
+     (ess-dump-filename-template . (replace-regexp-in-string
+                                    "S$" ess-suffix ; in the one from custom:
+                                    ess-dump-filename-template-proto))
+     (ess-traceback-command     . "traceback()\n")
+     (ess-mode-editing-alist    . S-editing-alist)
+
+     (ess-dumped-missing-re
+      . "\\(\\(<-\\|=\\)\nDumped\n\\'\\)\\|\\(\\(<-\\|=\\)\\(\\s \\|\n\\)*\\'\\)")
+     (ess-syntax-error-re
+      . "\\(Syntax error: .*\\) at line \\([0-9]*\\), file \\(.*\\)$")
+     (inferior-ess-objects-command  . inferior-Splus-objects-command)
+     (ess-describe-object-at-point-commands . 'ess-S-describe-object-at-point-commands)
+     (ess-editor . S-editor)
+     (ess-pager  . S-pager))
+   S-common-cust-alist)
+  "Common settings for all S+<*>-customize-alist."
+  )
+
+;;; Changes from S to S-PLUS 3.x.  (standard S3 should be in ess-s-lang!).
+
+(defconst ess-help-S+sec-keys-alist
+  '((?a . "ARGUMENTS:")
+    (?b . "BACKGROUND:")
+    (?B . "BUGS:")
+    (?d . "DESCRIPTION:")
+    (?D . "DETAILS:")
+    (?e . "EXAMPLES:")
+    (?n . "NOTE:")
+    (?O . "OPTIONAL ARGUMENTS:")
+    (?R . "REQUIRED ARGUMENTS:")
+    (?r . "REFERENCES:")
+    (?s . "SEE ALSO:")
+    (?S . "SIDE EFFECTS:")
+    (?u . "USAGE:")
+    (?v . "VALUE:"))
+  "Alist of (key . string) pairs for use in section searching.")
+;;; `key' indicates the keystroke to use to search for the section heading
+;;; `string' in an S help file. `string' is used as part of a
+;;; regexp-search, and so specials should be quoted.
+
+;; S ver.3 (NOT S-Plus)
+(defconst ess-help-S3-sec-keys-alist
+  '((?a . "ARGUMENTS:")
+    (?b . "BACKGROUND:")
+    (?B . "BUGS:")
+    (?d . "DESCRIPTION:")
+    (?D . "DETAILS:")
+    (?e . "EXAMPLES:")
+    (?n . "NOTE:")
+    (?r . "REFERENCES:")
+    (?s . "SEE ALSO:")
+    (?S . "SIDE EFFECTS:")
+    (?u . "USAGE:")
+    (?v . "VALUE:"))
+  "Help section keys for S ver.3.")
+
+;; S ver.4 (NOT S-Plus)
+(defconst ess-help-S4-sec-keys-alist
+  '((?a . "ARGUMENTS:")
+    (?b . "BACKGROUND:")
+    (?B . "BUGS:")
+    (?d . "DESCRIPTION:")
+    (?D . "DETAILS:")
+    (?e . "EXAMPLES:")
+    (?n . "NOTE:")
+    (?r . "REFERENCES:")
+    (?s . "SEE ALSO:")
+    (?S . "SIDE EFFECTS:")
+    (?u . "USAGE:")
+    (?v . "VALUE:"))
+  "Help section keys for S4.")
+
+
+(defconst ess-help-S+-sec-regex "^[A-Z.]+:$"
+  "Reg(ular) Ex(pression) of section headers in help file.")
+
+\f ; Function Definitions
+
+(defun S-comment-indent ()
+  "Indentation for S comments."
+  (if (or (looking-at "###")
+          (and (looking-at "#!") (= 1 (line-number-at-pos))))
+      (current-column)
+    (if (looking-at "##")
+        (let ((tem (when ;; FIXME ess-calculate-indent is R specific
+                       (fboundp 'ess-calculate-indent)
+                     (ess-calculate-indent))))
+          (if (listp tem) (car tem) tem))
+      (skip-chars-backward " \t")
+      (max (if (bolp) 0 (1+ (current-column)))
+           comment-column))))
+
+;;*;; S/R  Pretty-Editing
+
+(defun ess-fix-comments (&optional dont-query verbose)
+  "Fix buffer so that single-line comments start with at least '##',
+and ensure space before subsequent text."
+  (interactive "P")
+  (ess-replace-regexp-dump-to-src "#\\([A-Za-z0-9]\\)" "# \\1" nil verbose)
+  (ess-replace-regexp-dump-to-src "^\\([ \t]*#\\)\\([^#]\\)"
+                                  "\\1#\\2" dont-query verbose))
+
+(defun ess-dump-to-src (&optional dont-query verbose)
+  "Make the change in an S - dump() file to improve human readability.
+Optional arguments DONT-QUERY and VERBOSE are passed to
+`ess-replace-regexp-dump-to-src'."
+  (interactive "P")
+  (ess-replace-regexp-dump-to-src  "^\"\\([a-z.][a-z.0-9]*\\)\" *<-\n"
+                                   "\n\\1 <- "
+                                   dont-query verbose))
+
+(defun ess-num-var-round (&optional dont-query verbose)
+  "Round endings like 000000 and 99999.
+Optional argument DONT-QUERY means do not query.
+Optional argument VERBOSE gives more verbose output."
+  (interactive "P")
+  (save-excursion
+    (goto-char (point-min))
+    (let ((num 0)
+          (str "")
+          (rgxp "000000+[1-9]?[1-9]?\\>")
+          (to   ""))
+      (if dont-query
+          (ess-rep-regexp     rgxp to nil nil verbose)
+        (query-replace-regexp rgxp to nil))
+      (while (< num 9)
+        (setq str (concat (int-to-string num) "999999+[0-8]*"))
+        (if (and (numberp verbose) (> verbose 1))
+            (message (format "\nregexp: '%s'" str)))
+        (goto-char (point-min))
+        (ess-rep-regexp str (int-to-string (1+ num))
+                        'fixedcase 'literal verbose)
+        (setq num (1+ num))))))
+
+(defun ess-fix-dot (before-chars &optional dont-query verbose)
+  "Remove trailing decimal '.' (\"dot\"), before BEFORE-CHARS.
+Optional argument DONT-QUERY and VERBOSE get passed to
+`ess-replace-regexp-dump-to-src'."
+  ;; typically, before-chars =  "]:" or more
+  (ess-replace-regexp-dump-to-src
+   (concat "\\([0-9]\\)\\.\\( *[" before-chars "]\\)")
+   ;;           111      ^
+   "\\1\\2" dont-query verbose))
+
+(defun ess-fix-dot-1 (&optional do-query verbose)
+  "Remove trailing decimal '.' (\"dot\"), before ':' or ']', i.e.,
+in cases where it's ugly and nonsense.  DO-QUERY(prefix) asks before replacing."
+  (interactive "P")
+  (ess-fix-dot "]:" (not do-query) verbose))
+
+(defun ess-fix-dot-more (&optional dont-query verbose)
+  "Remove trailing decimal '.' (\"dot\", typically from S+) in more cases
+than `ess-fix-dot-1'."
+  (interactive "P")
+  (ess-fix-dot-1 nil verbose)
+  (ess-fix-dot ",)" dont-query verbose))
+
+(defun ess-fix-EQ-assign (&optional dont-query verbose not-all)
+  "Replace \"=\" by \"<-\" in places where it `might make sense', e.g.,
+for function assignments and lines not ending in \",\".
+Be *careful* for list()s of functions and when argument not-all is
+nil (as by default) !"
+  ;;TODO: "in the few places we can be very sure.."
+  ;;---- is hard in general: local functions: ok; but functions in
+  ;;  list(a = function(x) abs(x), b= function(y) bound(y))  *NOT* ok!
+  (interactive "P")
+  (ess-replace-regexp-dump-to-src
+   "^\\( *[a-z.][_a-z.0-9]*\\) *= *\\(function *(\\)"
+   "\\1 <- \\2" dont-query verbose)
+  (unless not-all
+    ;; "too" aggressive {proposing to replace function argument specs}:
+    (ess-replace-regexp-dump-to-src ;; all those *not* ending in ","
+     ;; including  Mat[ i, ] = ...,
+     ;; but not `names(x) = "..."' for that is "confused" with plot(x=x,..)
+     "^\\( *[a-z.][][, \"_a-z.0-9]*\\) *= *\\([a-z.0-9({]\\(.*[^,]\\)? *$\\)"
+     "\\1 <- \\2" nil ;; always query - often has many "false positives"
+     verbose)))
+
+;;; All of the above three :
+(defun ess-MM-fix-src (&optional dont-query verbose)
+  "Clean up ess-source code which has been produced by dump(..), and other
+code typically produced by other tools.  Produces more readable code,
+and one that is well formatted in Emacs ess-mode."
+  (interactive "P")
+  ;; each of the following does a save-excursion:
+  (ess-dump-to-src dont-query)
+  (ess-fix-comments dont-query)
+  (ess-num-var-round dont-query verbose)
+  (ess-fix-dot-more dont-query verbose)
+  (ess-fix-EQ-assign dont-query verbose 'not-all))
+
+(defun ess-fix-miscellaneous (&optional from verbose)
+  "Fix Miscellaneous S/R `ill-formation's from current \\[point].
+Particularly use \"<-\"and put spaces around operators."
+  (interactive "d\nP"); Defaults: point and prefix (C-u)
+  ;; activate by (setq ess-verbose t)
+  (ess-if-verbose-write
+   (format "ess-fix-misc begin (from = %s, verbose = %s)\n" from verbose))
+  (save-excursion
+
+    (when (and (string= ess-dialect "R")
+               (fboundp 'ess-r-fix-T-F))
+      (ess-r-fix-T-F from (not verbose)))
+
+    ;; activate by (setq ess-verbose t)
+    (ess-if-verbose-write "ess-fix-misc: after fix-T-F\n");___D___
+
+    ;; former C and matlab programmers leave trailing  ";" :
+    ;; (goto-char from) (ess-rep-regexp "; *$" "" nil 'literal verbose)
+    ;; (ess-if-verbose-write "ess-fix-misc: after trailing ';'\n");___D___
+    (goto-char from) (ess-rep-regexp ";\\( *\\)#" "\\1#" nil nil verbose)
+    (ess-if-verbose-write "ess-fix-misc: after ';' before #\n");___D___
+
+    ;;from R 1.9.x "_" is valid in names; here assume no initial / trailing '_'
+    ;; BUG: The following changes "beta_ " or " _abc"
+    ;; (goto-char from) (ess-rep-regexp " +_ *" " <- " nil 'literal verbose)
+    ;; (goto-char from) (ess-rep-regexp   "_ +" " <- " nil 'literal verbose)
+
+    (ess-if-verbose-write "ess-fix-misc: before 'around \"<-\"' :\n");___D___
+    ;; ensure space around  "<-"  ---- but only replace if necessary:
+    (goto-char from)
+    (ess-rep-regexp "\\([^< \t\n]\\)\\(<<?-\\)" "\\1 \\2" nil nil verbose)
+    (goto-char from)(ess-rep-regexp "<-\\([^ \t\n]\\)" "<- \\1" nil nil verbose)
+    ;; ensure space around  "<" (not in "<-","<=","<<-")  and ">" (not ">=") :
+    (goto-char from);; --> " <", care with "->":
+    (ess-rep-regexp "\\([^-< \t\n]\\)\\([<>]\\)" "\\1 \\2" nil nil verbose)
+    ;; ">" -> "> " , for "<", don't split "<-" nor "<<-":
+    (goto-char from)
+    (ess-rep-regexp "\\(>=?\\)\\([^= \t\n]\\)" "\\1 \\2" nil nil verbose)
+    (goto-char from)
+    (ess-rep-regexp "\\(<=?\\)\\([^-<= \t\n]\\)" "\\1 \\2" nil nil t)
+
+    (ess-if-verbose-write "ess-fix-misc: before \"=\" \"==\" .. :\n");___D___
+    ;; -- ensure space around "=", "==", "!=" :
+    (goto-char from) ;; --> " ="
+    (ess-rep-regexp "\\([^=!<> ]\\)\\([=!]?\\)=" "\\1 \\2=" nil nil verbose)
+    (goto-char from) (ess-rep-regexp "=\\([^= ]\\)" "= \\1" nil nil verbose)
+
+    (goto-char from) ;; add a space between "{" and surrounding ..char:
+    (ess-rep-regexp "{\\([.A-Za-z()]\\)" "{ \\1" 'fix nil verbose)
+    (ess-rep-regexp "\\([()]\\){" "\\1 {" 'fix nil verbose)
+    (goto-char from) ;; add a space between "}" and a preceding wordchar:
+    (ess-rep-regexp "\\([A-Za-z0-9()]\\)}" "\\1 }" 'fix nil verbose)
+    (ess-space-around "else" from verbose)
+
+    (ess-if-verbose-write "ess-fix-misc: after \"{ ... }\" :\n");___D___
+    (goto-char from) ;; add a space inside "){"
+    (ess-rep-regexp "){" ") {" 'fix nil verbose)
+
+    ;; add a newline and indent before a "}"
+    ;; --- IFF there's NO "{" or "#" AND some NON-white text on the same line:
+    ;;D (if verbose (message "\t R-fix-misc..: Hard.. '}'"))
+    (goto-char from)
+    (ess-rep-regexp "^\\([^#{\n]*[^#{ \t\n]+[ \t]*\\)}[ \t]*$"
+                    "\\1\n}" 'fix nil verbose)
+    (ess-if-verbose-write "ess-fix-misc __end__\n");___D___
+    ))
+
+(defun ess-cycle-assign ()
+  "Cycle between assignment symbols in `ess-assign-list'.
+On consecutive calls, replace the assignment symbol before point
+with the next symbol from that list. This function sets the last
+keypress to repeat it, so if it is bound to \"C-c C-=\" pressing
+\"=\" again cycles to the next assignment."
+  (interactive)
+  (if (eq last-command this-command)
+      (let ((slist ess-assign-list)
+            str)
+        ;; The or statements in the setq allow cycling past the end of
+        ;; ess-assign-list.
+        (while (and (setq str (or (car slist) (car ess-assign-list))
+                          slist (or (cdr slist) ess-assign-list))
+                    (not (and (re-search-backward str
+                                                  (- (point) (length str)) t)
+                              (not (replace-match (car slist))))))))
+    (delete-horizontal-space)
+    (insert (car ess-assign-list)))
+  (set-transient-map
+   (let ((map (make-sparse-keymap))
+         (key (format "%c" (event-basic-type last-input-event))))
+     (define-key map (kbd key) #'ess-cycle-assign)
+     map)))
+
+(defun ess-insert-assign (arg)
+  "Insert the first element of `ess-assign-list' unless in string or comment.
+If the character before point is the first element of
+`ess-assign-list', replace it with the last character typed.
+
+If `ess-language' is not \"S\", call `self-insert-command' with ARG."
+  (interactive "p")
+  (if (string= ess-language "S")
+      (let* ((assign (car ess-assign-list))
+             (event (event-basic-type last-input-event))
+             (char (ignore-errors (format "%c" event))))
+        (cond ((and char (ess-inside-string-or-comment-p))
+               (insert char))
+              ((re-search-backward assign (- (point) (length assign)) t)
+               (if (and char (numberp event))
+                   (replace-match char t t)
+                 (replace-match "")))
+              (t (delete-horizontal-space) 
+                 (insert assign))))
+    (funcall #'self-insert-command arg)))
+
+;; In case people had this in their config don't cause errors:
+(define-obsolete-function-alias 'ess-smart-S-assign #'ess-insert-assign "ESS 18.10")
+(define-obsolete-function-alias 'ess-disable-smart-S-assign #'ignore "ESS 18.10")
+
+(defun ess-add-MM-keys ()
+  "Define MM's user keys."
+  (declare (obsolete "Setup your own keybindings." "ESS 19.04"))
+  (define-key inferior-ess-mode-map "\C-cw" #'ess-execute-screen-options)
+  (define-key ess-mode-map          [?\M--] #'ess-insert-assign)
+  (define-key inferior-ess-mode-map [?\M--] #'ess-insert-assign))
+
+(defun ess-dump-args-and-go (Sfunc)
+  "Dump the function name, with arguments, to a buffer for editing.
+
+Currently, this needs to:
+   1. set the buffer to the right mode, with the right settings
+   2. format the statement,
+   3. c/function/Sfunc/
+and I need to relearn Emacs lisp (but I had to, anyway."
+  (declare (obsolete 'ess-execute "ESS 19.04"))
+  (interactive "sFunction ? ")
+  (let* ((buffname "ess-complete.R"))
+    (ess-execute (format "args(%s)" Sfunc) t buffname)
+    (pop-to-buffer (concat "*" buffname "*"))
+    (while (search-forward "function" nil t)
+      (replace-match Sfunc nil t))
+    (when (fboundp 'ess-r-mode)
+      (ess-r-mode))))
+
+;;; S imenu support
+
+;; don't use syntax classes, bad for etags
+(defvar ess-imenu-S-generic-expression
+  '(("Functions" "^\\([^ \t\n]+\\)[ \t\n]*\\(?:<-\\|=\\)[ \t\n]*function[ ]*(" 1)
+    ("Classes" "^.*setClass(\\(.*\\)," 1)
+    ("Coercions" "^.*setAs(\\([^,]+,[^,]*\\)," 1) ; show from and to
+    ("Generics" "^.*setGeneric(\\([^,]*\\)," 1)
+    ("Methods" "^.*set\\(Group\\|Replace\\)?Method(\\([^,]+,[^,]*\\)" 2)
+    ("Package" "^.*\\(library\\|require\\)(\\([^)]*\\)" 2)
+    ("Data" "^\\(.+\\)[ \t\n]-*\\(?:<-\\|=\\)[ \t\n]*\\(read\\|.*data\\.frame\\).*(" 1))
+  "Imenu generic expression for S modes.
+See `imenu-generic-expression'.")
+
+(defun ess-imenu-S (&optional _arg)
+  "S Language Imenu support for ESS.
+ARG is ignored."
+  (declare (obsolete "It is set automatically in major modes" "ESS 19.04"))
+  (imenu-add-to-menubar "Imenu-S"))
+
+
+\f ;;; Speedbar stuff.
+
+(eval-after-load "speedbar"
+  '(progn
+     (speedbar-add-supported-extension ".R")
+     (speedbar-add-supported-extension ".S")
+     (speedbar-add-supported-extension ".s")
+     (speedbar-add-supported-extension ".q")))
+
+(cl-defmethod ess-help-get-topics (proc &context (ess-dialect "R"))
+  "Return a list of current S help topics associated with process PROC.
+If `sp-for-help-changed?' process variable is non-nil or
+`ess-help-topics-list' is nil, (re)-populate the latter and
+return it.  Otherwise, return `ess-help-topics-list'."
+  (with-ess-process-buffer nil
+    (cond
+     ;; (Re)generate the list of topics
+     ((or (not ess-help-topics-list)
+          (ess-process-get 'sp-for-help-changed?))
+      (ess-process-put 'sp-for-help-changed? nil)
+      (setq ess-help-topics-list
+            (delete-dups
+             (append (ess-get-object-list proc 'exclude-1st)
+                     (ess-get-help-files-list)
+                     (ess-get-help-aliases-list)))))
+     (t
+      ess-help-topics-list))))
+
+(cl-defmethod ess-help--reset-cache-override (&context (ess-dialect "R"))
+  (ess-command ".ess.getHelpAliases(reset = TRUE)\n"
+               nil nil nil nil nil nil ess-help--aliases-timeout))
+
+(define-obsolete-function-alias 'ess-toggle-S-assign-key #'ignore "ESS 18.10")
+(define-obsolete-function-alias 'ess-smart-underscore #'ess-insert-assign "ESS 18.10")
+(define-obsolete-function-alias 'ess-insert-S-assign #'ess-insert-assign "ESS 18.10")
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.[Ss]t\\'" . S-transcript-mode))
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.Sout\\'" . S-transcript-mode))
+
+(provide 'ess-s-lang)
+
+;;; ess-s-lang.el ends here
diff --git a/elpa/ess-20260424.1544/ess-sas-a.el b/elpa/ess-20260424.1544/ess-sas-a.el
new file mode 100644 (file)
index 0000000..2ae5a19
--- /dev/null
@@ -0,0 +1,1443 @@
+;;; ess-sas-a.el --- clean-room implementation of many SAS-mode features  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1997-2022 Free Software Foundation, Inc.
+;; Author: Rodney A. Sparapani
+;; Maintainer: ESS-coreNOSPAMr-project.org
+;; Created: 17 November 1999
+;; Keywords: languages
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Code:
+
+(require 'ess-mode)
+(require 'ess-utils)
+;; 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]?\\|[pP][nN][gG]\\)"
+  "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-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"))))
+
+  "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)))
+
+;; whether the image libraries are configured is what is important here
+        (if (and (string-match "JPEG" system-configuration-features)
+                 (string-match "[.][jJ][pP][eE]?[gG]" ess-tmp-graph))
+            (find-file ess-tmp-graph)
+         (if (and (string-match "PNG" system-configuration-features)
+                  (string-match "[.][pP][nN][gG]" ess-tmp-graph))
+             (find-file ess-tmp-graph)
+        ;; ;;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="
+                        "\\|NOTE: Import cancelled.  Output dataset .* already exists."
+                       "\\|NOTE: Export cancelled.  Output file"
+                        "\\|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-revert-wisely)
+  (set-visited-file-name (concat (buffer-name) ".rtf"))
+  (when 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"))
+  (when 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\\|\f\\|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)
+  (when arg
+    ;; TODO: Why is this set up this way?
+    (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)))
+
+(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 receive: " 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 receive: " 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
diff --git a/elpa/ess-20260424.1544/ess-sas-d.el b/elpa/ess-20260424.1544/ess-sas-d.el
new file mode 100644 (file)
index 0000000..5cf147b
--- /dev/null
@@ -0,0 +1,332 @@
+;;; ess-sas-d.el --- SAS customization  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1997-2022 Free Software Foundation, Inc.
+;; Author: Richard M. Heiberger <rmhNOSPAMtemple.edu>
+;; Created: 20 Aug 1997
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; This file defines all the SAS customizations for ESS behaviors.  See
+;; ess-sas-l and ess-sas-a for the underlying general modifications.
+
+;;; Code:
+
+(require 'shell)
+(require 'ess-sas-l)
+
+(defcustom SAS-mode-hook nil
+  "Hook to run when entering SAS mode."
+  :type 'hook
+  :group 'ess-sas)
+
+(defvar inferior-SAS-args "-stdio -linesize 80 -noovp -nosyntaxcheck"
+  "Arguments to use for starting SAS.")
+
+(defvar inferior-SAS-args-temp nil
+  "Hack variable, needed for args preprocessing.
+Better logic needed!  (see 2 uses, in this file).")
+
+(defvar SAS-mode-syntax-table
+  (let ((tab (make-syntax-table)))
+    (modify-syntax-entry ?\\ "."  tab)  ;; backslash is punctuation
+    (modify-syntax-entry ?+  "."  tab)
+    (modify-syntax-entry ?-  "."  tab)
+    (modify-syntax-entry ?=  "."  tab)
+    (modify-syntax-entry ?%  "w"  tab)
+    (modify-syntax-entry ?<  "."  tab)
+    (modify-syntax-entry ?>  "."  tab)
+    (modify-syntax-entry ?&  "w"  tab)
+    (modify-syntax-entry ?|  "."  tab)
+    (modify-syntax-entry ?\' "\"" tab)
+    (modify-syntax-entry ?*  ". 23"  tab) ; comment character
+    (modify-syntax-entry ?\; "."  tab)
+    (modify-syntax-entry ?_  "w"  tab)
+    (modify-syntax-entry ?<  "."  tab)
+    (modify-syntax-entry ?>  "."  tab)
+    (modify-syntax-entry ?/  ". 14"  tab) ; comment character
+    (modify-syntax-entry ?.  "w"  tab)
+    tab)
+  "Syntax table for `SAS-mode'.")
+
+(defun ess-SAS-pre-run-hook (temp-ess-dialect)
+  "Set up log and list files for interactive SAS."
+
+  (let* ((ess-shell-buffer-name-flag (get-buffer "*shell*"))
+         ess-shell-buffer-name
+         ;; isn't pretty yet.
+         ;;  ess-local-process-name is defined after this function.
+         ;;  it needs to be defined prior to this function.
+         (tmp-procname (let ((ntry 0)
+                             (done nil))
+                         ;; find a non-existent process
+                         (while (not done)
+                           (setq ntry (1+ ntry)
+                                 done (not
+                                       (get-process (ess-proc-name
+                                                     ntry
+                                                     temp-ess-dialect)))))
+                         (ess-proc-name ntry temp-ess-dialect)))
+         ;; Following was tmp-local-process-name.  Stolen from inferior-ess
+         (ess-sas-lst-bufname (concat "*" tmp-procname ".lst*"))
+         (ess-sas-log-bufname (concat "*" tmp-procname ".log*"))
+         (explicit-shell-file-name "/bin/sh")
+         inferior-SAS-redirect-args
+         ess-sas-lst
+         ess-sas-log)
+
+    (ess-write-to-dribble-buffer
+     (format "(ess-SAS-pre-run-hook 1): ess-lang=%s, ess-dialect=%s, temp-dialect=%s, buf=%s \n"
+             ess-language
+             ess-dialect
+             temp-ess-dialect
+             (current-buffer)))
+    ;; If someone is running a *shell* buffer, rename it to avoid
+    ;; inadvertent nuking.
+    (if ess-shell-buffer-name-flag
+        (with-current-buffer "*shell*"
+          (setq ess-shell-buffer-name
+                (rename-buffer "*ess-shell-regular*" t))))
+
+    ;; Construct the LST buffer for output
+    (if (get-buffer ess-sas-lst-bufname)
+        nil
+      (with-current-buffer (shell)
+        (accept-process-output (get-buffer-process (current-buffer)) 0.2)
+        (sleep-for 2)           ; need to wait, else working too fast!
+        (setq ess-sas-lst (ess-insert-accept "tty"))
+        (SAS-listing-mode)
+        (shell-mode)
+        (ess-listing-minor-mode t)
+        (rename-buffer ess-sas-lst-bufname t)))
+
+    ;; Construct the LOG buffer for output
+    (if (get-buffer  ess-sas-log-bufname)
+        nil
+      (with-current-buffer (shell)
+        (accept-process-output (get-buffer-process (current-buffer)) 0.2)
+        (sleep-for 2)           ; need to wait, else working too fast!
+        (setq ess-sas-log (ess-insert-accept "tty"))
+                                        ;(SAS-log-mode)
+        (shell-mode)
+        (ess-transcript-minor-mode t)
+        (rename-buffer ess-sas-log-bufname t)))
+
+    (setq inferior-SAS-redirect-args (concat " "
+                                             ess-sas-lst
+                                             " "
+                                             ess-sas-log
+                                             " ")
+          inferior-SAS-args-temp (concat inferior-SAS-redirect-args
+                                         inferior-SAS-args))
+
+    ;; Restore the *shell* buffer
+    (if ess-shell-buffer-name-flag
+        (with-current-buffer ess-shell-buffer-name
+          (rename-buffer "*shell*")))
+
+    (delete-other-windows)
+    (split-window-vertically)
+    (split-window-vertically)
+    (switch-to-buffer (nth 2 (buffer-list)))
+    (other-window 2)
+    (switch-to-buffer ess-sas-log-bufname)
+    (split-window-vertically)
+    (other-window 1)
+    (switch-to-buffer ess-sas-lst-bufname)
+    (other-window 2)
+
+    ;;workaround
+    (setq inferior-SAS-program
+          (concat (file-name-as-directory ess-etc-directory)
+                  "ess-sas-sh-command"))
+    (setq inferior-ess-program inferior-SAS-program)))
+
+(defun ess-insert-accept (command)
+  "Submit command to process, get next line."
+  (interactive)
+  (goto-char (point-max))
+  (insert command)
+  (comint-send-input)
+  (accept-process-output (get-buffer-process (current-buffer)) 0.2)
+  (forward-line -1)
+  (let* ((beg (point))
+         (ess-tty-name (progn (end-of-line) (buffer-substring beg (point)))))
+    (goto-char (point-max))
+    ess-tty-name))
+
+
+(defvar SAS-customize-alist
+  '((ess-local-customize-alist     . SAS-customize-alist)
+    (ess-language                  . "SAS")
+    (ess-dialect                   . "SAS")
+    (inferior-ess-program          . inferior-SAS-program)
+    (ess-help-sec-regex            . "^[A-Z. ---]+:$")
+    (ess-help-sec-keys-alist       . " ")
+    (ess-object-name-db-file       . "ess-sas-namedb.el")
+    (inferior-ess-objects-command  . "objects(%d)");;FIXME
+    (inferior-ess-help-command     . "help(\"%s\",pager=\"cat\",window=F)\n");;FIXME
+    (inferior-ess-exit-command     . "endsas;\n")
+    (ess-loop-timeout              .  500000 )
+    (inferior-ess-primary-prompt   . "^")
+    (inferior-ess-secondary-prompt . "^")
+    (comint-use-prompt-regexp      . t)
+    (inferior-ess-start-args       . inferior-SAS-args-temp)
+    ;; (ess-pre-run-hook              . 'ess-SAS-pre-run-hook)
+    ;; (ess-local-process-name        . nil)
+    )
+  "Variables to customize for SAS")
+
+;;; The functions of interest (mode, inferior mode)
+
+;;;###autoload
+(define-derived-mode SAS-mode ess-mode "[SAS]"
+  "Major mode for editing SAS source.  See `ess-mode' for more help."
+  :group 'ess-sas
+  (ess-setq-vars-local SAS-customize-alist)
+  (setq ess-local-customize-alist SAS-customize-alist)
+  (setq-local sentence-end ";[\t\n */]*")
+  (setq-local paragraph-start "^[ \t]*$")
+  (setq-local paragraph-separate "^[ \t]*$")
+  (setq-local paragraph-ignore-fill-prefix t)
+  (setq-local adaptive-fill-mode nil)
+  (setq-local indent-line-function #'sas-indent-line)
+  (setq-local comment-start "/*")
+  (setq-local comment-start-skip "/[*]")
+  (setq-local comment-end "*/")
+  (setq-local comment-end-skip "[*]/")
+  (setq-local comment-column 40)
+  (setq-local ess-local-process-name nil)
+  (setq-local tab-stop-list ess-sas-tab-stop-list)
+  (setq-local font-lock-keywords-case-fold-search t)
+  ;; Local map settings, AFTER initialization (only if not yet defined)
+  (unless sas-mode-local-map
+    (setq sas-mode-local-map (copy-keymap (current-local-map)))
+    (ess-sas-edit-keys-set ess-sas-edit-keys-toggle)
+    (if ess-sas-local-unix-keys (ess-sas-local-unix-keys))
+    (if ess-sas-local-pc-keys (ess-sas-local-pc-keys))
+    (if ess-sas-global-unix-keys (ess-sas-global-unix-keys))
+    (if ess-sas-global-pc-keys (ess-sas-global-pc-keys)))
+  (define-key sas-mode-local-map ";" #'ess-electric-run-semicolon)
+  (define-key sas-mode-local-map (kbd "\C-c\C-w") #'ess-multi-frame-SAS)
+  ;; this is a mess
+  ;; interactive and batch commands share sas-mode-local-map,
+  ;; but the associated commands are very different
+  ;; what would be better is two maps like
+  ;; sas-batch-mode-local-map and sas-interactive-mode-local-map
+  ;; or smart function definitions that would do the appropriate
+  ;; thing for either batch or interactive sessions
+  ;; however, neither of these solutions are planned
+  ;; therefore, no key definitions can be shared between
+  ;; batch and interactive at this time, hence the lines that
+  ;; are commented below:  uncomment at your own risk
+  ;;  (define-key sas-mode-local-map "\C-c\C-p" 'ess-sas-file-path)
+  ;;  (define-key sas-mode-local-map "\C-c\C-b" 'ess-sas-submit)
+  ;;  (define-key sas-mode-local-map "\C-c\C-r" 'ess-sas-submit-region)
+  ;;  (define-key sas-mode-local-map "\C-c\C-x" 'ess-sas-goto-log)
+  ;;  (define-key sas-mode-local-map "\C-c\C-y" 'ess-sas-goto-lst)
+
+  (use-local-map sas-mode-local-map)
+
+  (setq font-lock-defaults
+        ;; KEYWORDS KEYWORDS-ONLY CASE-FOLD .....
+        '(SAS-mode-font-lock-defaults nil t)))
+
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.[Ss][Aa][Ss]\\'" . SAS-mode))
+
+;; rmh Jul 10 2003
+(defun ess-electric-run-semicolon (arg)
+  "Insert character.
+If the line contains \"run;\" or \"quit;\" and nothing else then
+indent line."
+  (interactive "P")
+  (if ess-sas-edit-keys-toggle
+      (insert ";")
+    (if (and (not arg)
+             (eolp)
+             (save-excursion
+               (skip-chars-backward " \t")
+               (backward-word 1)
+               (and (looking-at "run\\|quit")
+                    (progn
+                      (skip-chars-backward " \t")
+                      (bolp)))))
+        (progn
+          (insert last-command-event)
+          (funcall indent-line-function)
+          (save-excursion
+            (delete-char -1))))
+    (self-insert-command (prefix-numeric-value arg))))
+
+(defun SAS-menu ()
+  "Start SAS from the menu."
+  (interactive)
+  (if ess-microsoft-p
+      ;; replace with other choices for starting SAS?
+      (error "SAS cannot be started this way in ESS on Windows.")
+    (SAS)))
+
+(defun SAS ()
+  "Call \\='SAS\\=', from SAS Institute."
+  (interactive)
+  (let* ((temp-dialect "SAS")) ;(cdr (rassoc ess-dialect SAS-customize-alist))))
+    (ess-write-to-dribble-buffer
+     (format "(SAS): ess-dial=%s, temp-dial=%s\n"
+             ess-dialect
+             temp-dialect))
+    (ess-SAS-pre-run-hook temp-dialect)
+    (setq ess-eval-visibly-p nil)
+    ;; FIXME: `inferior-SAS-args' is defined from
+    ;; `inferior-SAS-args-temp' in `ess-SAS-pre-run-hook'
+    (let ((inf-buf (inferior-ess nil SAS-customize-alist)))
+      (with-current-buffer inf-buf
+        (use-local-map sas-mode-local-map))
+      inf-buf)))
+
+(defun ess-multi-frame-SAS ()
+  "Put running SAS buffers into separate frames.
+Load this function M-x load-file essx-sas.el RET.
+Then find-file myfile.sas.  If myfile.sas is already in a buffer, kill-buffer
+it and then find-file it again.
+Place the cursor in a myfile.sas buffer.  Run SAS with M-x SAS,
+Return the cursor to the myfile.sas buffer,
+then enter C-c C-w to put *SAS* *SAS.log* *SAS.lst* buffers into
+their own frames."
+  (interactive)
+  (delete-other-windows)
+  (with-current-buffer "*SAS*"
+    (make-frame))
+  (with-current-buffer "*SAS.log*"
+    (make-frame))
+  (with-current-buffer "*SAS.lst*"
+    (make-frame)))
+
+(defun ess-num-or-zero (arg)
+  "If a number, then return that number, otherwise return 0."
+  (or (and (numberp arg) arg) 0))
+
+\f ; Provide package
+
+(provide 'ess-sas-d)
+
+;;; ess-sas-d.el ends here
diff --git a/elpa/ess-20260424.1544/ess-sas-l.el b/elpa/ess-20260424.1544/ess-sas-l.el
new file mode 100644 (file)
index 0000000..97e51ce
--- /dev/null
@@ -0,0 +1,1754 @@
+;;; ess-sas-l.el --- SAS customization  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1997-2022 Free Software Foundation, Inc.
+;; Authors: Richard M. Heiberger
+;;          A.J. Rossini
+;;          Rodney Sparapani
+;; Created: 20 Aug 1997
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; This is based upon Version 1.4 of SAS mode:
+
+
+;;;    sas-mode:  indent, run etc, SAS programs.
+;;;  Author:   Tom Cook
+;;;            Dept. of Biostatistics
+;;;            University of Wisconsin - Madison
+;;;            Madison, WI 53706
+;;;            cookNOSPAMbiostat.wisc.edu
+;;;
+;;;  Acknowledgements:
+;;;  Menu code for XEmacs/Lucid emacs and startup mods
+;;;  contributed by arossiniNOSPAMbiostats.hmc.psu.edu
+;;;
+;;; Last change: 2/1/95
+;;; Last change: 01/15/02
+
+;;; Code:
+
+(require 'ess-mode)
+(require 'ess-sas-a)
+
+(declare-function SAS-mode "ess-sas-d")
+
+(put 'ess-transcript-minor-mode 'permanent-local t)
+(or (assq 'ess-transcript-minor-mode minor-mode-alist)
+    (setq minor-mode-alist
+          (append minor-mode-alist
+                  (list '(ess-transcript-minor-mode " ESStr")))))
+
+(put 'ess-listing-minor-mode 'permanent-local t)
+(or (assq 'ess-listing-minor-mode minor-mode-alist)
+    (setq minor-mode-alist
+          (append minor-mode-alist
+                  (list '(ess-listing-minor-mode " ESSlst")))))
+
+(defun ess-transcript-minor-mode (&optional arg)
+  "Toggle Ess-Transcript minor mode.
+With arg, turn Ess-Transcript minor mode on if arg is positive, off
+otherwise.  See the command `ess-transcript-mode' for more information
+on this mode."
+  (interactive "P")
+  (setq ess-transcript-minor-mode
+        (if (null arg) (not ess-transcript-minor-mode)
+          (> (prefix-numeric-value arg) 0)))
+  (force-mode-line-update)
+  (setq mode-line-process
+        '(" [" ess-local-process-name "]")))
+
+(defun ess-listing-minor-mode (&optional arg)
+  "Toggle Ess-Listing minor mode.
+With arg, turn Ess-Listing minor mode on if arg is positive, off
+otherwise.  Ess-Listing mode is used solely to place an indicator on
+the mode line."
+  (interactive "P")
+  (setq ess-listing-minor-mode
+        (if (null arg) (not ess-listing-minor-mode)
+          (> (prefix-numeric-value arg) 0)))
+  (force-mode-line-update)
+  (setq mode-line-process
+        '(" [" ess-local-process-name "]")))
+        
+(defcustom ess-automatic-sas-log-or-lst-mode t
+  "Automatically turn on `SAS-log-mode' and `SAS-listing-mode' when enabled."
+  :type 'boolean
+  :group 'ess-sas)
+
+(defun ess-SAS-log-mode-p ()
+  "Return t when when a SAS log file is detected.
+A SAS log is defined as having:
+
+1. The first line matches \"^1[ \t]*The SAS System\"
+2. The file name ends in .log.
+"
+  (and ess-automatic-sas-log-or-lst-mode
+       (save-excursion
+         (goto-char (point-min))
+         (looking-at "1[ \t]*The SAS System"))
+       (if (buffer-file-name)
+           (string-match ".log$" (buffer-file-name))
+         t)))
+
+(defun ess-SAS-listing-mode-p ()
+  "Return t when SAS listing file is detected.
+A .lst file is a SAS listing file when:
+
+1. The file name ends in .lst
+2. The corresponding log file exists and is a SAS log file.
+"
+  (when ess-automatic-sas-log-or-lst-mode
+    (let* ((bfn (buffer-file-name))
+           (log (and bfn
+                     (string-match-p "\\.lst$" bfn)
+                     (replace-regexp-in-string "\\.lst$" ".log" bfn))))
+      (and log
+           (file-exists-p log)
+           (with-temp-buffer
+             (insert-file-contents log nil 0 200)
+             (goto-char (point-min))
+             (looking-at "1[ \t]*The SAS System"))))))
+
+(add-to-list 'magic-mode-alist
+             '(ess-SAS-log-mode-p . SAS-log-mode))
+(add-to-list 'magic-mode-alist
+             '(ess-SAS-listing-mode-p . SAS-listing-mode))
+
+(define-derived-mode SAS-log-mode SAS-mode "ESS[LOG]"
+  "`ess-transcript-mode' for SAS."
+  :group 'ess-sas
+  (ess-transcript-minor-mode 1)
+  (setq buffer-read-only t) ;; to protect the buffer.
+  (buffer-disable-undo))
+
+(defvar sas-mode-local-map nil "contains modified local keymap for SAS")
+(define-derived-mode SAS-listing-mode special-mode "ESS[LST]"
+  "Fundamental mode with `ess-listing-minor-mode' and read-only."
+  :keymap sas-mode-local-map
+  :group 'ess-sas
+  (ess-listing-minor-mode 1)
+  (buffer-disable-undo))
+
+(defalias 'sas-log-mode        #'SAS-log-mode)
+(defalias 'SAS-transcript-mode #'SAS-log-mode)
+(defalias 'sas-transcript-mode #'SAS-log-mode)
+(defalias 'sas-mode #'SAS-mode)
+(defalias 'sas-listing-mode    #'SAS-listing-mode)
+
+(defcustom  sas-indent-width 4
+  "Amount to indent sas statements."
+  :group 'ess-sas
+  :type  'integer)
+
+(defcustom sas-indent-ignore-comment "\\*"
+  "Comments that start with this regular expression are ignored in indentation."
+  :group 'ess-sas
+  :type  'string)
+
+(defcustom sas-require-confirmation t
+  "Require confirmation when revisiting a modified sas-output file."
+  :group 'ess-sas
+  :type  'boolean)
+
+(defcustom sas-pre-run-hook nil
+  "Hook to execute prior to running SAS via `submit-sas'."
+  :group 'ess-sas
+  :type  'hook)
+
+(defcustom sas-notify t
+  "Beep and display message when job is done."
+  :group 'ess-sas
+  :type  'boolean)
+
+(defcustom sas-error-notify t
+  "If `sas-notify' t, indicate errors in log file upon completion."
+  :group 'ess-sas
+  :type  'boolean)
+
+(defcustom sas-get-options nil
+  "Options to be passed to SAS in sas-get-dataset."
+  :group 'ess-sas
+  :type '(choice (const nil) string))
+
+(defcustom sas-get-options-history nil
+  "History list of Options passed to SAS in sas-get-dataset."
+  :type '(choice (const nil)
+                 (string))
+  :group 'ess-sas)
+
+(defcustom sas-page-number-max-line 3
+  "Number of lines from the page break, to search for the page
+number."
+  :group 'ess-sas
+  :type  'integer)
+
+(defcustom sas-notify-popup nil
+  "If this and `sas-notify' are t), popup a window when SAS job ends."
+  :group 'ess-sas
+  :type  'boolean)
+
+(defcustom sas-tmp-libname "_tmp_"
+  "Libname to use for sas-get-dataset."
+  :group 'ess-sas
+  :type  'string)
+
+(defcustom sas-file-name nil
+  "The name of the current sas file."
+  :group 'ess-sas
+  :type '(choice (const nil) file))
+
+;; The next two are ``the inside of [...] in a regexp'' to be used in
+;; (skip-chars-(for|back)ward SAS-..-chars)
+(defcustom sas-white-chars " \t\n\f"
+  "This does NOT escape blanks (RMH, 2000/03/20)."
+  :group 'ess-sas
+  :type  'string)
+
+(defcustom sas-comment-chars (concat sas-white-chars ";")
+  "Doc?"
+  :group 'ess-sas
+  :type  'string)
+
+(defcustom ess-sas-run-regexp-opt t
+  "If you do not want to run regexp-opt, then set to nil."
+  :group 'ess-sas
+  :type 'boolean)
+
+(defvar sas-buffer-name nil)
+(defvar sas-file-root nil)
+(defvar sas-submitable nil)
+(defvar sas-dataset nil)
+
+(defvar SAS-mode-font-lock-defaults
+  (if ess-sas-run-regexp-opt
+      (list
+       ;; .log NOTE: messages
+       (cons "^NOTE [0-9]+-[0-9]+: Line generated by the invoked macro"
+             font-lock-comment-face)
+       (cons "^NOTE: .*$"                          font-lock-comment-face)
+       (cons "^      [^ @].*[.]$"                   font-lock-comment-face)
+       (cons "^      [a-z].*[a-z][ ]?$"            font-lock-comment-face)
+       (cons "^      Engine:[ ]+V.+$"              font-lock-comment-face)
+       (cons "^      Physical Name:[ ]+.+$"        font-lock-comment-face)
+       (cons "^      \\(cpu\\|real\\) time[ ]+[0-9].*$"
+             font-lock-comment-face)
+       (cons "^      decimal may be shifted by the"
+             font-lock-comment-face)
+       (cons "^NOTE: The infile "                  font-lock-comment-face)
+       (cons "^NOTE: 1 record was read from the infile "
+             font-lock-comment-face)
+       (cons "^NOTE: [1-9][0-9]* records were read from the infile "
+             font-lock-comment-face)
+       (cons "^      Filename=.*,$"                font-lock-comment-face)
+       (cons "^      File Name=.*,$"               font-lock-comment-face)
+       (cons "^      File $"                       font-lock-comment-face)
+       (cons "^      Name=.*,$"                    font-lock-comment-face)
+       (cons "^      File List=("                  font-lock-comment-face)
+       (cons "^      List=("                       font-lock-comment-face)
+       (cons "^      Owner Name=.*,$"              font-lock-comment-face)
+       (cons "^      Access Permission=.*,$"       font-lock-comment-face)
+       (cons "^      Last Modified=.*,?$"          font-lock-comment-face)
+       (cons "^      File Size (bytes)=[0-9]+$"    font-lock-comment-face)
+       (cons "^      Pipe command="                font-lock-comment-face)
+       (cons "^NOTE: The file "                    font-lock-comment-face)
+       (cons "^NOTE: 1 record was written to the file "
+             font-lock-comment-face)
+       (cons "^NOTE: [1-9][0-9]* records were written to the file "
+             font-lock-comment-face)
+       (cons "^NOTE: PROC LOGISTIC is modeling the probability that"
+             font-lock-comment-face)
+       (cons "^NOTE: PROC GENMOD is modeling the probability that"
+             font-lock-comment-face)
+       (cons "^1[ ]+The SAS System.*$"             font-lock-comment-face)
+       (cons "^\014.*$"                            font-lock-comment-face)
+       (cons "[*][*][*] ANNOTATE macros are now available [*][*][*]"
+             font-lock-comment-face)
+       (cons "For further information on ANNOTATE macros, enter,"
+             font-lock-comment-face)
+       ;; (cons "^SAS/STAT 9.3_M1, SAS/ETS 9.3_M1, SAS/OR 9.3_M1"
+       ;;       font-lock-comment-face)
+       (cons "\\(or \\)?%HELPANO.*$"
+             font-lock-comment-face)
+       (cons "^Local Variables:$"                  font-lock-comment-face)
+       (cons "^End:$"                              font-lock-comment-face)
+       (cons "^MPRINT([_A-Z0-9]+)"                 font-lock-comment-face)
+
+       ;; .log ERROR: messages
+                                        ;     (cons "^ERROR\\( [0-9]+-[1-9][0-9][0-9]\\)?: .*$"
+       (cons "^ERROR\\( [0-9]+-[0-9]+\\)?: .*$"
+             font-lock-keyword-face)
+                                        ;       ERROR:
+       (cons "^       [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
+             font-lock-keyword-face)
+                                        ;       ERROR #-###:
+       (cons "^             [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
+             font-lock-keyword-face)
+                                        ;       ERROR ##-###:
+       (cons "^              [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
+             font-lock-keyword-face)
+                                        ;       ERROR ###-###:
+       (cons "^               [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
+             font-lock-keyword-face)
+       (cons "^              a format name."       font-lock-keyword-face)
+       (cons "^       where a numeric operand is required. The condition was: "
+             font-lock-keyword-face)
+       (cons "[ ][_]+$"                            font-lock-keyword-face)
+
+       ;; .log WARNING: messages
+                                        ;(cons "^WARNING\\( [0-9]+-[1-9][0-9][0-9]\\)?: .*$"
+       (cons "^WARNING\\( [0-9]+-[0-9]+\\)?: .*$"
+             font-lock-function-name-face)
+                                        ;       WARNING:
+       (cons "^         [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
+             font-lock-function-name-face)
+                                        ;       WARNING #-###:
+       (cons "^               [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
+             font-lock-function-name-face)
+                                        ;       WARNING ##-###:
+       (cons "^                [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
+             font-lock-function-name-face)
+                                        ;       WARNING ###-###:
+       (cons "^                 [^ @].*\\([.][ ]?[ ]?\\|[,a-z][ ]\\)$"
+             font-lock-function-name-face)
+
+       ;; SAS comments
+       ;; /* */ style handled by grammar above
+       (cons "\\(^[0-9]*\\|[:;!]\\)[ \t]*%?\\*[^;/][^;]*;"
+             font-lock-comment-face)
+
+                                        ; these over-rides need to come before the more general declarations
+       (cons "\\<and("      font-lock-function-name-face)
+       (cons "\\<data="     font-lock-keyword-face)
+       (cons "\\<in:("      font-lock-function-name-face)
+       (cons "\\<index("    font-lock-function-name-face)
+       (cons "\\<input("    font-lock-function-name-face)
+       (cons "\\<libname("  font-lock-function-name-face)
+       (cons "\\<not("      font-lock-function-name-face)
+       (cons "\\<or("       font-lock-function-name-face)
+       (cons "\\<put("      font-lock-function-name-face)
+       (cons "\\<sum("      font-lock-function-name-face)
+
+                                        ; other idiosyncratic keywords
+                                        ;(cons "key="      font-lock-keyword-face)
+                                        ;(cons "/unique"   font-lock-keyword-face)
+
+       ;; SAS execution blocks: DATA, %MACRO/%MEND, %DO/%END, etc.
+       (cons (regexp-opt '(
+                           "data" "start" "return" ;"proc"
+                           "%macro" "%mend"
+                           "%do" "%to" "%by" "%end"
+                           "%goto" "%go to"
+                           "%if" "%then" "%else"
+                           "%global" "%inc" "%include" "%input" "%local" "%let" "%put" "%sysexec"
+                           ) 'words) font-lock-constant-face)
+
+       ;; SAS execution blocks that must be followed by a semi-colon
+       (cons (concat "\\<"
+                     (regexp-opt
+                      '(
+                        "run;" "quit;" "endsas;" "finish;"
+                        "cards;" "cards4;" "datalines;" "datalines4;" "lines;" "lines4;"
+                        )))
+             font-lock-constant-face)
+
+       ;; SAS statements that must be followed by a semi-colon
+       (cons (concat "\\<"
+                     (regexp-opt
+                      '(
+                        "end;" "list;" "lostcard;" "page;" "stop;" ;"return;" 
+                        )))
+             font-lock-keyword-face)
+
+       ;; SAS statements that must be followed by an equal sign
+       (cons (concat "\\<"
+                     (regexp-opt
+                      '(
+                        "compress=" "in=" "out=" "sortedby="
+                        )))
+             font-lock-keyword-face)
+
+;;;    ;; SAS procedure names
+       (cons (concat "\\<proc[ ]+"
+                     (regexp-opt '(
+"access" "aceclus" "adaptivereg" "aggregation" "anom" "anova" "append" "appsrv" "arima" "assess" "astore" "authlib" "autoreg"
+"bchoice" "bglimm" "binning" "bnet" "bom" "boolrule" "boxplot" "build"
+"calendar" "calis" "callrfc" "cancorr" "candisc" "capability" "cardinality" "carima" "cas" "casutil" "catalog" "catmod" "causalgraph" "causalmed" "causaltrt" "ccdm" "ccopula" "cesm" "chart" "cimport" "clp" "cluster" "cntselect" "compare" "compile" "computab" "contents" "convert" "copula" "copy" "corr" "correlation" "corresp" "countreg" "cpanel" "cpm" "cport" "cqlim" "cspatialreg" "cusum" "cv2view"
+"datasets" "datasource" "datekeys" "db2ext" "db2util" "dbcstab" "dbf" "dbload" "delete" "dfil" "dif" "discrim" "display" "distance" "dmsrvadm" "dmsrvdatasvc" "dmsrvprocesssvc" "document" "download" "dqloclst" "dqmatch" "dqscheme" "ds2" "dstods2" "dtree"
+"ecm" "entropy" "esm" "expand" "explode" "export"
+"factex" "factmac" "factor" "fastclus" "fastknn" "fcmp" "fedsql" "fism" "fmm" "fmtc2itm" "fontreg" "forest" "format" "forms" "freq" "freqtab" "fsbrowse" "fsedit" "fsletter" "fslist" "fsview"
+"g3d" "g3grid" "ga" "gam" "gammod" "gampl" "gamselect" "ganno" "gantt" "gareabar" "gbarline" "gchart" "gcontour" "gdevice" "gee" "genmod" "genselect" "geocode" "gfont" "ginside" "gis" "gkpi" "glimmix" "glm" "glmmod" "glmpower" "glmselect" "gmap" "gmm" "goptions" "gplot" "gproject" "gradar" "gradboost" "greduce" "gremove" "greplay" "groovy" "gslide" "gtile" "gvarclus"
+"hadoop" "hdmd" "hmm" "hp4score" "hpbin" "hpbnet" "hpboolrule" "hpcandisc" "hpcdm" "hpclus" "hpcopula" "hpcorr" "hpcountreg" "hpdecide" "hpdmdb" "hpds2" "hpexport" "hpf" "hpfarimaspec" "hpfdiagnose" "hpfengine" "hpfesmspec" "hpfevents" "hpfexmspec" "hpfidmspec" "hpfmm" "hpforest" "hpfreconcile" "hpfrepository" "hpfselect" "hpftemprecon" "hpfucmspec" "hpgenselect" "hpimpute" "hplmixed" "hplogistic" "hpmixed" "hpneural" "hpnlmod" "hppanel" "hppls" "hpprincomp" "hpqlim" "hpquantselect" "hpreduce" "hpreg" "hprisk" "hpsample" "hpseverity" "hpsplit" "hpsummary" "hpsvm" "hptmine" "hptmscore" "http"
+"ica" "iclifetest" "icphreg" "iml" "import" "imstat" "imxfer" "inbreed" "infomaps" "iomoperate" "irt" "ishikawa" "items"
+"javainfo" "json"
+"kclus" "kde" "kpca" "krige2d"
+"lasr" "lattice" "lifereg" "lifetest" "lmixed" "loan" "localedata" "loess" "logistic" "logselect" "lua"
+"macontrol" "mapimport" "mbanalysis" "mbc" "mcmc" "mdc" "mddb" "mds" "mdsummary" "means" "metadata" "metalib" "metaoperate" "mi" "mianalyze" "migrate" "mixed" "modeclus" "model" "modelmatrix" "mtlearn" "multtest" "mvpdiagnose" "mvpmodel" "mvpmonitor" "mwpca"
+"nested" "netdraw" "network" "nlin" "nlmixed" "nlmod" "nmf" "nnet" "npar1way"
+"odslist" "odstable" "odstext" "olap" "olapcontents" "olapoperate" "operate" "optex" "optgraph" "options" "optload" "optlp" "optlso" "optmilp" "optmodel" "optnet" "optnetwork" "optqp" "optsave" "orthoreg"
+"panel" "pareto" "partition" "pca" "pdlreg" "pds" "pdscopy" "phreg" "phselect" "plan" "plm" "plot" "pls" "plsmod" "pm" "pmenu" "power" "presenv" "princomp" "prinqual" "print" "printto" "probit" "proto" "prtdef" "prtexp" "psmatch" "pwencode"
+"qdevice" "qlim" "qtrselect" "quantlife" "quantreg" "quantselect" "quest"
+"rank" "rareevents" "rdc" "rdpool" "rdsec" "recommend" "reg" "registry" "regselect" "release" "reliability" "report" "risk" "rmstreg" "robustreg" "rpca" "rsreg"
+"s3" "sandwich" "scaproc" "score" "scoreaccel" "semisuplearn" "seqdesign" "seqtest" "server" "severity" "sevselect" "sgdesign" "sgmap" "sgpanel" "sgpie" "sgplot" "sgrender" "sgscatter" "shewhart" "sim2d" "similarity" "simlin" "simnormal" "simsystem" "smcalib" "smproject" "smscore" "smselect" "smspec" "soap" "sort" "source" "sparseml" "spatialreg" "spc" "spdo" "spectra" "spp" "sql" "sqoop" "ssm" "standard" "statespace" "stdize" "stdrate" "stepdisc" "stp" "stream" "summary" "surveyfreq" "surveyimpute" "surveylogistic" "surveymeans" "surveyphreg" "surveyreg" "surveyselect" "svdd" "svmachine" "syslin"
+"tabulate" "tapecopy" "tapelabel" "textmine" "timedata" "timeid" "timeplot" "timeseries" "tmodel" "tmscore" "tpspline" "transpose" "transreg" "trantab" "tree" "treesplit" "tscsreg" "tsinfo" "tsmodel" "tsne" "tsreconcile" "ttest"
+"ucm" "univariate" "upload"
+"varclus" "varcomp" "varimpute" "variogram" "varmax" "varreduce" "vasmp"
+"x11" "x12" "x13" "xsl"
+                                   ) 'words)) font-lock-constant-face)
+
+                                        ;       (cons (concat
+                                        ;             "\\<"
+                                        ;             "do[ \t]*" (regexp-opt '("over" "until" "while") t) "?"
+                                        ;             "\\>")
+                                        ;            font-lock-keyword-face)
+                                        ;
+       ;; SAS base and SAS/Graph statements
+       (cons (concat ;"\\<"
+              (regexp-opt
+               '(
+                 "do" "to" "by" "goto" ; "go"
+                 "abort" "and" "array" "assess" "attrib"
+                 "baseline" "bayes" "between" "bivar" "block" "bubble" "bubble2"
+                 "change" "choro" "class" "contains" "contrast"
+                 "delete" "display" "dm" "donut" "drop"
+                 "else" "error" "exchange" "exclude"
+                 "fcs" "file" "filename" "format" "freq"
+                 "footnote" "footnote1" "footnote2" "footnote3" "footnote4" "footnote5"
+                 "footnote6" "footnote7" "footnote8" "footnote9" "footnote10"
+                 "goptions" "grid" ; "ge" "gt"
+                 "hazardratio" "hbar" "hbar3d"
+                 "id" "if" "index" "infile" "informat" "input" ; "is" rarely used, but common false pos.
+                 "keep"
+                 "label" "length" "libname" "like" "link" "lsmeans" ; "le" "lt"
+                 "manova" "means" "merge" "missing" "model" "modify"
+                 "not" "null" ; "ne" "note"
+                 "ods" "options" "output" "otherwise" ; "or"
+                 "pageby" "parms" "pie" "pie3d" "plot" "plot2" "prism" "put"
+                 "random" "rename" "repeated" "retain"
+                 "same" "save" "scatter" "select" "set" "skip" "star" "strata" "sum" "sumby" "surface"
+                 "table" "tables" "test" "then" "time"
+                 "title" "title1" "title2" "title3" "title4" "title5"
+                 "title6" "title7" "title8" "title9" "title10"
+                 "univar" "update"
+                 "value" "var" "vbar" "vbar3d"
+                 "weight" "where" "window" "with"
+                                        ; "x"
+                 ) 'words)) ;"\\>")
+             font-lock-keyword-face)
+
+       ;; SAS/GRAPH statements not handled above
+       (cons (concat "\\<"
+                     (regexp-opt
+                      '("axis" "legend" "pattern" "symbol")) "\\([1-9][0-9]?\\)?"
+                      "\\>")
+             font-lock-keyword-face)
+
+       ;; SAS functions and SAS macro functions
+       (cons "%[a-z_][a-z_0-9]*[(;]"                  font-lock-function-name-face)
+                                        ;(cons "\\<call[ \t]+[a-z]+("                   font-lock-function-name-face)
+
+       (cons (concat ;"\\<"
+              (regexp-opt
+               '(
+;; SAS functions found in sashelp.vfunc where fncprod='X'
+                 "abs" "arcos" "arsin" "atan"
+                 "betainv" "byte"
+                 "call execute" "call label" "call module" "call modulei"
+                 "call poke" "call ranbin" "call rancau" "call ranexp"
+                 "call rangam" "call rannor" "call ranpoi" "call rantbl"
+                 "call rantri" "call ranuni" "call rxchange" "call rxfree"
+                 "call rxsubstr" "call set" "call streaminit" "call symput" "call system"
+                 "cdf" "ceil" "cinv" "collate" "compress" "convx" "convxp" "cos" "cosh" "css" "cv"
+                 "daccdb" "daccdbsl" "daccsl" "daccsyd" "dacctab"
+                 "depdb" "depdbsl" "depsl" "depsyd" "deptab"
+                 "date" "datejul" "datepart" "datetime" "day" "dhms" "dif" "digamma" "dim"
+                 "erf" "erfc" "exp"
+                 "finv" "fipname" "fipnamel" "fipstate" "floor" "fuzz"
+                 "gaminv" "gamma"
+                 "hbound" "hms" "hour"
+                 "in" "index" "indexc" "input" "int" "intck" "intnx" "intrr" "irr"
+                 "juldate"
+                 "kurtosis"
+                 "lag" "lbound" "left" "length" "lgamma" "log" "log10" "log2"
+                 "logcdf" "logpdf" "logsdf"
+                 "max" "mdy" "mean" "min" "minute" "mod" "month" "mort"
+                 "n" "netpv" "nmiss" "normal" "npv"
+                 "ordinal"
+                 "pdf"
+                 "probbeta" "probbnml" "probchi" "probf" "probgam" "probhypr" "probit" "probnegb" "probnorm" "probt"
+                 "poisson" "put"
+                 "qtr" "quantile"
+                 "rand" "range" "rank" "repeat" "reverse" "right" "round" "rxmatch" "rxparse"
+                 "ranbin" "rancau" "ranexp" "rangam" "rannor" "ranpoi" "rantbl" "rantri" "ranuni"
+                 "saving" "scan" "sdf" "second" "sign" "sin" "sinh" "sqrt" "squantile"
+                 "std" "stderr" "stfips" "stname" "stnamel" "substr" "sum" "symget"
+                 "tan" "tanh" "time" "timepart" "tinv" "today" "translate" "trigamma" "trim" "trunc"
+                 "uniform" "until" "upcase" "uss"
+                 "var" "verify"
+                 "weekday" "when" "while"
+                 "year" "yyq"
+                 "zipfips" "zipname" "zipnamel" "zipstate"
+
+;;;    ;; SAS/IML functions 
+                 "all" "allcomb" "allperm" "any" "apply" "armasim"
+                 "bin" "blankstr" "block" "branks" "bspline" "btran" "byte"
+                 "char" "choose" "col" "colvec" "concat" "contents" "convexit" "corr" "corr2cov" 
+                 "countmiss" "countn" "countunique" "cov" "cov2corr" "covlag" "cshape" "cusum"
+                 "cuprod" "cv" "cvexhull" 
+                 "datasets" "design" "designf" "det" "diag" "dimension" "distance" "do" "duration" 
+                 "echelon" "eigval" "eigvec" "expmatrix" "expandgrid" 
+                 "fft" "fftc" "forward" "froot" "full"
+                 "gasetup" "geomean" "ginv" 
+                 "hadamard" "half" "hankel" "harmean" "hdir" "hermite" "homogen"
+                 "i" "ifft" "ifftc" "importtablefromr" "insert" "inv" "invupdt" "isempty" "isskipped"
+                 "j" "jroot" 
+                 "kurtosis" 
+                 "lambertw" "listgetallnames" "listgetitem" "listgetname" "listgetsubitem" "listindex"
+                 "listlen" "loc" "logabsdet" 
+                 "mad" "magic" "mahalanobis" "moduleic" "modulein" 
+                 "name" "ncol" "nrow" "ndx2sub" "nleng" "norm" "num" 
+                 "opscal" "orpol"
+                 "parentname" "palette" "polyroot" "prod" "product" "pv"
+                 "quartile" 
+                 "rancomb" "randdirichlet" "randfun" "randmultinomial" "randmvt" "randnormal" "randwishart"
+                 "ranperk" "ranperm" "ranktie" "rates" "ratio" "remove" "repeat" "root" "row" 
+                 "rowcat" "rowcatc" "rowvec" "rsubstr" 
+                 "sample" "setdif" "shape" "shapecol" "skewness" "solve" "sparse" "splinev" "spot" 
+                 "sqrsym" "sqrvech" "ssq" "standard" "storage" "sub2ndx" "sweep" "symsqr"
+                 "t" "tablecreate" "tablecreatefromdataset" "tablegetvardata" "tablegetvarformat"
+                 "tablegetvarindex" "tablegetvarinformat" "tablegetvarlabel" "tablegetvarname"
+                 "tablegetvartype" "tableisexistingvar" "tableisvarnumeric" "tfhilbert" "tfpwv"
+                 "tfstft" "tfwindow" "toeplitz" "trace" "trisolv" "type" 
+                 "union" "unique" "uniqueby" 
+                 "value" "vecdiag" "vech" 
+                 "xmult" "xsect"
+                 "yield"
+                 
+;;;    ;; SAS functions introduced in Technical Report P-222
+                 "airy"
+                 "band" "blshift" "brshift" "bnot" "bor" "bxor"
+                 "cnonct" "compbl"
+                 "dairy" "dequote"
+                 "fnonct"
+                 "ibessel" "indexw" "inputc" "inputn"
+                 "jbessel"
+                 "lowcase"
+                 "putc" "putn"
+                 "quote"
+                 "resolve"
+                 "soundex" "sysprod"
+                 "tnonct" "tranwrd" "trimn"
+
+;;;    ;; SCL functions that are known to work with SAS macro function %sysfunc
+                 "attrc" "attrn"
+                 "cexist" "close"
+                 "dclose" "dnum" "dopen" "dread"
+                 "exist"
+                 "fclose" "fetchobs" "fileexist" "finfo" "fopen" "fput" "fwrite"
+                 "getoption" "getvarc" "getvarn"
+                 "libname" "libref"
+                 "open" "optgetn" "optsetn"
+                 "pathname"
+                 "sysmsg"
+                 "varfmt" "varlabel" "varnum" "vartype"
+                 ) 'words) ;"\\>"
+              "("); "[ \t]*(")
+             font-lock-function-name-face)
+       )
+    (list
+     ;; .log NOTE: messages
+     (cons "^NOTE: .*$"                         font-lock-constant-face)
+
+     ;; .log ERROR: messages
+     (cons "^ERROR: .*$"                        font-lock-keyword-face)
+
+     ;; .log WARNING: messages
+     (cons "^WARNING: .*$"                      font-lock-function-name-face)
+
+     ;; SAS comments
+     ;; /* */ handled by grammar above
+     ;;  (list "/\\*.*\\*/"                      0  font-lock-comment-face t)
+     (cons "\\(^[0-9]*\\|;\\)[ \t]*\\(%?\\*\\|comment\\).*\\(;\\|$\\)" font-lock-comment-face)
+
+     ;; SAS execution blocks, DATA/RUN, PROC/RUN, SAS Macro Statements
+     (cons "\\<%do[ \t]*\\(%until\\|%while\\)?\\>"
+           font-lock-constant-face)
+     ;;(cons (concat "\\(^[0-9]*\\|;\\)[ \t]*"
+     ;;"%\\(end\\|global\\|local\\|m\\(acro\\|end\\)\\)"
+     ;;"\\>")                               font-lock-constant-face)
+     (cons "\\<%\\(end\\|global\\|local\\|m\\(acro\\|end\\)\\)\\>"
+           font-lock-constant-face)
+
+     (cons (concat "\\(^[0-9]*\\|;\\|):\\|%then\\|%else\\)[ \t]*"
+                   "\\(data\\|endsas\\|finish\\|quit\\|run\\|start\\)[ \t\n;]")
+           font-lock-constant-face)
+     (cons (concat "\\(^[0-9]*\\|;\\|):\\|%then\\|%else\\)[ \t]*"
+                   ;;"proc[ \t]+[a-z][a-z_0-9]+")        font-lock-constant-face)
+                   "proc[ \t]+"
+                   ;;SAS/Base, SAS/Graph, SAS/FSP and common add-ons
+                   "\\(append"
+                   "\\|b\\(genmod\\|lifereg\\|phreg\\)"
+                   "\\|c\\(a\\(lendar\\|talog\\)\\|port\\|o\\(mpare\\|ntents\\|py\\|rr\\)\\)"
+                   "\\|d\\(atasets\\|bcstab\\|isplay\\)\\|ex\\(plode\\|port\\)"
+                   "\\|f\\(orm\\(at\\|s\\)\\|req\\|s\\(browse\\|edit\\|l\\(etter\\|ist\\)\\|view\\)\\)"
+                   "\\|g?\\(chart\\|p\\(lot\\|rint\\)\\)"
+                   "\\|g\\(anno\\|contour\\|device\\|font\\|\\(key\\)?map\\|options\\|project"
+                   "\\|re\\(duce\\|move\\|play\\)\\|slide\\|testit\\|3\\(d\\|grid\\)\\)"
+                   "\\|\\(map\\|[cg]\\)?import\\|i\\(ml\\|nsight\\)"
+                   "\\|means\\|options\\|p\\(menu\\|rintto\\)"
+                   "\\|r\\(ank\\|e\\(gistry\\|port\\)\\)"
+                   "\\|s\\(ort\\|ql\\|tandard\\|ummary\\)"
+                   "\\|t\\(abulate\\|emplate\\|imeplot\\|ran\\(spose\\|tab\\)\\)\\|univariate"
+                   ;;SAS/Stat and SAS/ETS
+                   "\\|a\\(ceclus\\|nova\\|rima\\|utoreg\\)\\|boxplot"
+                   "\\|c\\(a\\(lis\\|n\\(corr\\|disc\\)\\|tmod\\)\\|itibase\\|luster\\|o\\(mputab\\|rresp\\)\\)"
+                   "\\|discrim\\|expand\\|f\\(a\\(ctor\\|stclus\\)\\|orecast\\|req\\)"
+                   "\\|g\\(enmod\\|l\\(immix\\|m\\(mod\\|power\\|select\\)?\\)\\)\\|inbreed\\|k\\(de\\|rige2d\\)"
+                   "\\|l\\(attice\\|ife\\(reg\\|test\\)\\|o\\(ess\\|gistic\\)\\)"
+                   "\\|m\\(ds\\|ixed\\|o\\(de\\(clus\\|l\\)\\|rtgage\\)\\|ulttest\\)"
+                   "\\|n\\(ested\\|l\\(in\\|mixed\\)\\|par1way\\)\\|orthoreg"
+                   "\\|p\\(dlreg\\|hreg\\|l\\(an\\|s\\)\\|ower\\|r\\(in\\(comp\\|qual\\)\\|obit\\)\\)\\|r\\(sr\\)?eg"
+                   "\\|s\\(core\\|im\\(2d\\|lin\\)\\|pectra\\|t\\(atespace\\|dize\\|epdisc\\)\\|urvey\\(means\\|reg\\|select\\)\\|yslin\\)"
+                   "\\|t\\(phreg\\|pspline\\|r\\(ansreg\\|ee\\)\\|test\\)"
+                   "\\|var\\(clus\\|comp\\|iogram\\)\\|x11"
+                   "\\)")        font-lock-constant-face)
+
+     ;;(cons (concat "\\(^[0-9]*\\|;\\|%then\\|%else\\)[ \t]*"
+     ;;"\\(%\\(go[ \t]*to\\|i\\(f\\|n\\(clude\\|put\\)\\)\\|let\\|put\\|sysexec\\)\\)"
+     ;;"\\>")                               font-lock-constant-face)
+     (cons "\\<%\\(go[ \t]*to\\|i\\(f\\|n\\(clude\\|put\\)\\)\\|let\\|put\\|sysexec\\)\\>"
+           font-lock-constant-face)
+
+     (cons "\\<%\\(by\\|else\\|t\\(o\\|hen\\)\\)\\>"
+           font-lock-constant-face)
+
+     ;; SAS dataset options/PROC statements followed by an equal sign/left parentheses
+
+     (cons (concat
+            "[ \t(,]"
+            "\\(attrib\\|by\\|compress\\|d\\(ata\\|rop\\)\\|f\\(irstobs\\|ormat\\)"
+            "\\|i\\(d\\|f\\|n\\)\\|ke\\(ep\\|y\\)\\|l\\(abel\\|ength\\)"
+            "\\|o\\(bs\\|rder\\|ut\\)\\|rename\\|s\\(ortedby\\|plit\\)"
+            "\\|var\\|where\\)"
+            "[ \t]*=")
+           font-lock-keyword-face)
+     (cons "\\<\\(in\\(:\\|dex[ \t]*=\\)?\\|until\\|wh\\(en\\|ile\\)\\)[ \t]*("
+           font-lock-keyword-face)
+
+     ;; SAS statements
+     (cons (concat
+            "\\(^[0-9]*\\|):\\|[;,]\\|then\\|else\\)[ \t]*"
+            "\\(a\\(bort\\|rray\\|ttrib\\)\\|b\\(ayes\\|y\\)"
+            "\\|c\\(hange\\|lass\\|ontrast\\)"
+            "\\|d\\(elete\\|isplay\\|m\\|o\\([ \t]+\\(data\\|over\\)\\)?\\|rop\\)"
+            "\\|e\\(rror\\|stimate\\|xc\\(hange\\|lude\\)\\)"
+            "\\|f\\(ile\\(name\\)?\\|o\\(otnote\\(10?\\|[2-9]\\)?\\|rmat\\)\\|req\\)"
+            "\\|go\\([ \t]*to\\|ptions\\)"
+            "\\|hazardratio\\|[hv]bar\\(3d\\)?"
+            "\\|i\\(d\\|f\\|n\\(dex\\|f\\(ile\\|ormat\\)\\|put\\|value\\)\\)"
+            "\\|keep\\|l\\(abel\\|ength\\|i\\(bname\\|nk\\|st\\)\\|smeans\\)"
+            "\\|m\\(anova\\|e\\(ans\\|rge\\)\\|issing\\|od\\(el\\|ify\\)\\)\\|note"
+            "\\|o\\(ds\\|ptions\\|therwise\\|utput\\)\\|p\\(arms\\|lot2?\\|ut\\)"
+            "\\|r\\(andom\\|e\\(name\\|peated\\|tain\\)\\)"
+            "\\|s\\(ave\\|e\\(lect\\|t\\)\\|kip\\|trata\\|um\\(by\\)?\\)"
+            "\\|t\\(ables?\\|i\\(me\\|tle\\(10?\\|[2-9]\\)?\\)\\)\\|update"
+            "\\|va\\(lue\\|r\\)\\|w\\(eight\\|here\\|i\\(ndow\\|th\\)\\)"
+
+            ;; IML statements that are not also SAS statements
+            "\\|append\\|c\\(lose\\(file\\)?\\|reate\\)\\|edit\\|f\\(ind\\|orce\\|ree\\)"
+            "\\|insert\\|load\\|mattrib\\|p\\(a[ru]se\\|rint\\|urge\\)"
+            "\\|re\\(move\\|peat\\|place\\|set\\|sume\\)"
+            "\\|s\\(et\\(in\\|out\\)\\|how\\|ort\\|tore\\|ummary\\)\\|use\\)?"
+
+            "\\>")                                  font-lock-keyword-face)
+
+
+
+     ;;  (cons "\\<\\(\\(then\\|else\\)[ \t]*\\)?\\(do\\([ \t]*over\\)?\\|else\\)\\>"
+     ;;                                             font-lock-keyword-face)
+
+     ;; SAS statements that must be followed by a semi-colon
+     (cons (concat
+            "\\(^[0-9]*\\|):\\|[;,]\\|then\\|else\\)[ \t]*"
+            "\\(cards4?\\|datalines\\|end\\|l\\(ostcard\\)\\|page\\|stop\\)?"
+            "[ \t]*;")                      font-lock-keyword-face)
+
+     ;; SAS/GRAPH statements not handled above
+     (cons (concat
+            "\\(^[0-9]*\\|):\\|[;,]\\)[ \t]*"
+            "\\(axis\\|legend\\|pattern\\|symbol\\)"
+            "\\([1-9][0-9]?\\)?\\>")        font-lock-keyword-face)
+
+     ;; SAS Datastep functions and SAS macro functions
+                                        ;(cons "%[a-z_][a-z_0-9]*[ \t]*[(;]"
+     ;; SAS macro functions occasionally defined with no arguments
+     ;; which means they can be followed by any character that can
+     ;; separate tokens, however, they are most likely to be followed
+     ;; by operat-ions/ors
+     (cons "%[a-z_][a-z_0-9]*[- \t();,+*/=<>]"
+           font-lock-function-name-face)
+     (cons "\\<call[ \t]+[a-z_][a-z_0-9]*[ \t]*("
+           font-lock-function-name-face)
+
+     (cons (concat
+            "\\<"
+            "\\(a\\(bs\\|r\\(cos\\|sin\\)\\|tan\\)\\|b\\(etainv\\|yte\\)"
+            "\\|c\\(eil\\|inv\\|o\\(llate\\|mpress\\|sh?\\)\\|ss\\|v\\)"
+            "\\|dacc\\(db\\(\\|sl\\)\\|s\\(l\\|yd\\)\\|tab\\)"
+            "\\|dep\\(db\\(\\|sl\\)\\|s\\(l\\|yd\\)\\|tab\\)"
+            "\\|d\\(a\\(te\\(\\|jul\\|part\\|time\\)\\|y\\)\\|hms\\|i\\(f[0-9]*\\|m\\|gamma\\)\\)"
+            "\\|e\\(rfc?\\|xp\\)"
+            "\\|f\\(i\\(nv\\|p\\(namel?\\|state\\)\\)\\|loor\\|uzz\\)\\|gam\\(inv\\|ma\\)"
+            "\\|h\\(bound\\|ms\\|our\\)\\|i\\(n\\(dexc?\\|put\\|t\\(\\|ck\\|nx\\|rr\\)\\)\\|rr\\)"
+            "\\|juldate\\|kurtosis\\|l\\(ag[0-9]*\\|bound\\|e\\(ft\\|ngth\\)\\|gamma\\|og\\(\\|10\\|2\\)\\)"
+            "\\|m\\(ax\\|dy\\|ean\\|in\\(\\|ute\\)\\|o\\(d\\|nth\\|rt\\)\\)"
+            "\\|n\\(\\|etpv\\|miss\\|o\\(rmal\\|t\\)\\|pv\\)"
+            "\\|prob\\([ft]\\|b\\(eta\\|nml\\)\\|chi\\|gam\\|hypr\\|it\\|n\\(egb\\|orm\\)\\)"
+            "\\|ordinal\\|p\\(oisson\\|ut\\)\\|qtr\\|r\\(e\\(peat\\|verse\\)\\|ight\\|ound\\)"
+            "\\|ran\\(bin\\|cau\\|exp\\|g\\(am\\|e\\)\\|k\\|nor\\|poi\\|t\\(bl\\|ri\\)\\|uni\\)"
+            "\\|s\\(aving\\|can\\|econd\\|i\\(gn\\|nh?\\)\\|qrt\\|t\\(d\\(\\|err\\)\\|fips\\|namel?\\)\\|u\\(bstr\\|m\\)\\|ymget\\)"
+            "\\|t\\(anh?\\|i\\(me\\(\\|part\\)\\|nv\\)\\|oday\\|r\\(anslate\\|i\\(gamma\\|m\\)\\|unc\\)\\)"
+            "\\|u\\(niform\\|pcase\\|ss\\)\\|v\\(ar\\|erify\\)"
+            "\\|weekday\\|y\\(ear\\|yq\\)\\|zip\\(fips\\|namel?\\|state\\)"
+
+;;;    ;; SAS functions introduced in Technical Report P-222
+
+            "\\|airy\\|b\\(and\\|lshift\\|not\\|or\\|rshift\\|xor\\)"
+            "\\|c\\(nonct\\|ompbl\\)\\|d\\(airy\\|equote\\)\\|fnonct\\|tnonct"
+            "\\|i\\(bessel\\|n\\(dexw\\|put[cn]\\)\\)\\|jbessel\\|put[cn]"
+            "\\|lowcase\\|quote\\|resolve\\|s\\(oundex\\|ysprod\\)\\|tr\\(anwrd\\|imn\\)"
+
+;;;    ;; IML functions that are not also Datastep functions
+            "\\|a\\(ll\\|ny\\|pply\\|rmasim\\)\\|b\\(lock\\|ranks\\|tran\\)"
+            "\\|c\\(har\\|hoose\\|on\\(cat\\|tents\\|vexit\\|vmod\\)\\|ovlag\\|shape\\|usum\\|vexhull\\)"
+            "\\|d\\(atasets\\|esignf?\\|et\\|iag\\|o\\|uration\\)"
+            "\\|e\\(chelon\\|igv\\(al\\|ec\\)\\)\\|f\\(ft\\|orward\\)\\|ginv"
+            "\\|h\\(alf\\|ankel\\|dir\\|ermite\\|omogen\\)"
+            "\\|i\\(\\|fft\\|nsert\\|nv\\(updt\\)?\\)\\|j\\(\\|root\\)\\|loc\\|mad"
+            "\\|n\\(ame\\|col\\|leng\\|row\\|um\\)\\|o\\(pscal\\|rpol\\)"
+            "\\|p\\(olyroot\\|roduct\\|v\\)\\|r\\(anktie\\|ates\\|atio\\|emove\\|eturn\\|oot\\|owcatc?\\)"
+            "\\|s\\(etdif\\|hape\\|olve\\|plinev\\|pot\\|qrsym\\|ssq\\|torage\\|weep\\|ymsqr\\)"
+            "\\|t\\(\\|eigv\\(al\\|ec\\)\\|oeplitz\\|race\\|risolv\\|ype\\)"
+            "\\|uni\\(on\\|que\\)\\|v\\(alue\\|ecdiag\\)\\|x\\(mult\\|sect\\)\\|yield"
+
+;;;    ;; SCL functions that are known to work with SAS macro function %sysfunc
+
+            "\\|attr[cn]\\|c\\(exist\\|lose\\)\\|d\\(close\\|num\\|open\\|read\\)"
+            "\\|exist\\|f\\(close\\|etchobs\\|i\\(leexist\\|nfo\\)\\|open\\|put\\|write\\)"
+            "\\|get\\(option\\|var[cn]\\)\\|lib\\(name\\|ref\\)\\|op\\(en\\|t\\(getn\\|setn\\)\\)"
+            "\\|pathname\\|sysmsg\\|var\\(fmt\\|l\\(abel\\|en\\)\\|n\\(ame\\|um\\)\\|type\\)\\)"
+            "[ \t]*(")                      font-lock-function-name-face)
+     ))
+  "Font Lock regexs for SAS.")
+
+(defun beginning-of-sas-statement (arg &optional comstart)
+  "Move point to beginning of current sas statement."
+  (interactive "P")
+  (let ((pos (point))
+        )
+    (if (search-forward ";" nil 1) (forward-char -1))
+    (re-search-backward ";[ \n*/]*$" (point-min) 1 arg)
+    (skip-chars-forward sas-comment-chars)
+    (if comstart nil
+      (if (looking-at "\\*/")
+          (progn (forward-char 2)
+                 (skip-chars-forward sas-comment-chars)))
+      (while (looking-at "/\\*")
+        (if (not (search-forward "*/" pos t 1)) ;;(;; (point-max) 1 1)
+            (forward-char 2))
+        (skip-chars-forward sas-white-chars)))))
+
+(defun sas-indent-line ()
+  "Indent function for SAS mode."
+  (interactive)
+  (let (indent prev-end
+               (pos (- (point-max) (point)))
+               (case-fold-search t)
+               (cur-ind (current-indentation))
+               (comment-col (sas-comment-start-col))) ;; 2/1/95 TDC
+    (save-excursion
+      (cond ((progn
+               (back-to-indentation)
+               (or (bobp)
+                   (looking-at
+                    "data[ ;]\\|proc[ ;]\\|run[ ;]\\|quit[ ;]\\|endsas[ ;]\\|g?options[ ;]\\|%macro[ ;]\\|%mend[ ;]")))
+             ;;  Case where current statement is DATA, PROC, etc...
+             (setq prev-end (point))
+             (goto-char (point-min))
+             ;;  Added 6/27/94
+             ;;  May get fooled if %MACRO, %DO, etc embedded in comments
+             (setq indent
+                   (+ (* (- (sas-how-many "^[ \t]*%macro\\|[ \t]+%do"
+                                          prev-end)
+                            (sas-how-many "^[ \t]*%mend\\|%end" prev-end))
+                         sas-indent-width) comment-col)))  ;; 2/1/95 TDC
+            ;;  Case where current line begins with sas-indent-ignore-comment
+            ;; added 6/27/94  to leave "* ;" comments alone.
+            ((progn
+               (back-to-indentation)
+               (and (not (looking-at "\\*/"))
+                    (looking-at (concat sas-indent-ignore-comment "\\|/\\*"))))
+             (setq indent (current-indentation)))
+            ;;  Case where current statement not DATA, PROC etc...
+            (t (beginning-of-line 1)
+               (skip-chars-backward sas-white-chars)
+               (if (bobp) nil
+                 (backward-char 1))
+               (cond
+                ((looking-at ";")       ;  modified 1/31/95
+                 (setq indent (sas-next-statement-indentation)))
+                ((save-excursion;; added 4/28/94 to properly check
+                   (if (bobp) () (backward-char 1));; for end of comment
+                   (setq prev-end (point))
+                   (looking-at "\\*/"));;  improved 1/31/95
+                 (save-excursion
+                   (search-backward "*/"
+                                    (point-min) 1 1); comment start is first /*
+                   (search-forward "/*"
+                                   prev-end 1 1)    ; after previous */
+                   (backward-char 2)                ; 2/1/95 TDC
+                   (skip-chars-backward sas-white-chars)
+                   (setq indent
+                         (if (bobp) 0
+                           (if (looking-at ";")
+                               (sas-next-statement-indentation)
+                             ;;(+ (current-indentation) sas-indent-width)
+                             (current-indentation))))))
+
+                ;; added 6/27/94 to leave "* ;" comments alone
+                ((save-excursion
+                   (progn
+                     (beginning-of-sas-statement 1 t)
+                     (and (not (looking-at "\\*/"))
+                          (looking-at sas-indent-ignore-comment))))
+                 (setq indent cur-ind))
+                ((progn
+                   (beginning-of-sas-statement 1)
+                   (bobp));; added 4/13/94
+                 (setq indent sas-indent-width));; so the first line works
+                ((save-excursion
+                   (beginning-of-sas-statement 2)
+                   (looking-at "cards4?;\\|datalines4?;\\|lines4?;"))
+                 (setq indent (current-indentation))) ; So cards keep indentation.
+                (t
+                 (if (progn
+                       (save-excursion
+                         (beginning-of-line 1)
+                         (skip-chars-backward sas-white-chars)
+                         (if (bobp) nil (backward-char 1))
+                         (or (looking-at ";")
+                             (bobp) (backward-char 1) (looking-at "\\*/"))))
+                     (setq indent (+ (current-indentation) sas-indent-width))
+                   (setq indent (current-indentation))))))))
+    (save-excursion
+      (let (beg end)
+        (back-to-indentation)
+        (setq end (point))
+        (beginning-of-line 1)
+        (setq beg (point))
+        (delete-region beg end)
+        (indent-to indent)))
+    (if (> (- (point-max) pos) (point))
+        (goto-char (- (point-max) pos)))))
+
+
+;;(defun sas-indent-region (start end)
+;;  "Indent a region of SAS code."
+;;  (interactive "r")
+;;  (save-excursion
+;;    (let ((endmark (copy-marker end)))
+;;      (goto-char start)
+;;      (and (bolp) (not (eolp))
+;;         (sas-indent-line))
+;;      (indent-sexp endmark)
+;;      (set-marker endmark nil))))
+
+
+(defun indent-sas-statement (arg)
+  "Indent all continuation lines sas-indent-width spaces from first
+line of statement."
+  (interactive "p")
+  (let (end)
+    (save-excursion
+      (if (> arg 0)
+          (while (and (> arg 0) (search-forward ";" (point-max) 1 1))
+            (setq end (point))
+            (if (bobp) nil (backward-char 1))
+            (beginning-of-sas-statement 1)
+            (forward-char 1)
+            (indent-region (point)
+                           end
+                           (+ (current-column) (1- sas-indent-width)))
+            (search-forward ";" (point-max) 1 1)
+            (setq arg (1- arg)))))))
+
+;; added 9/31/94
+(defun sas-next-statement-indentation ()
+  "Returns the correct indentation of the next sas statement.
+The current version assumes that point is at the end of the statement.
+This will (hopefully) be fixed in later versions."
+  (if (bobp) 0
+    (save-excursion
+      (let ((prev-end (point)))
+        (beginning-of-sas-statement 1)
+        (while (and (not (bobp))
+                    (not (looking-at "\\*/"))
+                    (looking-at sas-indent-ignore-comment))
+          (skip-chars-backward sas-white-chars)
+          (if (bobp) nil
+            (backward-char 1))
+          (setq prev-end (point))
+          (beginning-of-sas-statement 1 t))
+        (if (or
+             (looking-at
+              (concat "data[ \n\t;]\\|"
+                      (regexp-opt '("cards;" "cards4;" "datalines;" "datalines4;" "lines;" "lines4;"))
+                      "\\|proc[ \n\t]\\|%?do[ \n\t;]\\|%macro[ \n\t]\\|/\\*"))
+             (save-excursion
+               (re-search-forward
+                "\\b%?then\\>[ \n\t]*\\b%?do\\>\\|\\b%?else\\>[ \n\t]*\\b%?do\\>"
+                prev-end 1 1))) ; fixed 1/30/95 to avoid being fooled by
+                                        ; variable names starting with "do"
+            (+ (current-indentation) sas-indent-width)
+          (if (looking-at "%?end[ ;\n]\\|%mend[ ;\n]\\|\\*/")
+              (max (- (current-indentation) sas-indent-width) 0)
+            (current-indentation)))))))
+
+;; added 2/1/95
+(defun sas-comment-start-col ()
+  "If the current line is inside a /* */ comment, returns column in which the
+opening /* appears.  returns 0 otherwise."
+  (let ((pos (point)))
+    (save-excursion
+      (if (and (search-backward "*/" (point-min) 1 1)
+               (search-forward "/*" pos 1 1))
+          (current-indentation)
+        0))))
+
+
+;;  Created 6/27/94 to verify that RUN; statements match PROC and DATA
+;;  statements.  Useful since indentation my be goofy w/o "RUN;"
+(defun sas-check-run-statements ()
+  "Check to see that \"run\" statements are matched with proc, data statements."
+  (interactive)
+  (let (pos
+        (ok t)
+        (eob-ok t))
+    (save-excursion
+      (beginning-of-line)
+      (while ok
+        (if (re-search-forward
+             "\\(^[ \t]*run[ ;]\\)\\|\\(^[ \t]*proc \\|^[ \t]*data[ ;]\\)"
+             nil 1)
+            (if (match-beginning 2)
+                (if (re-search-forward
+                     "\\(^[ \t]*run[ ;]\\)\\|\\(^[ \t]*proc \\|^[ \t]*data[ ;]\\)"
+                     nil t)
+                    (progn (setq pos (point))
+                           (setq ok (match-beginning 1)))
+                  (setq eob-ok nil pos (point-max))))
+          (setq ok nil)))
+      (setq ok (eobp)))
+    (if (and ok eob-ok) (message "Run statements match")
+      (goto-char pos)
+      (beep)
+      (message "Missing Run Statement."))))
+
+(defun sas-fix-life-tables ()
+  "Remove censored and duplicate observations from life tables generated by
+Proc Lifetest.  Operates on current region.  A major space saver if there is
+heavy censoring."
+  (interactive)
+  (if buffer-read-only (setq buffer-read-only nil))
+  (goto-char (point-min))
+  (while (re-search-forward "^.*[ ]+[.][ ]+[.][ ]+[.][ ]+.*$" nil t)
+    (replace-match "" nil nil)))
+                                        ;  (save-excursion
+                                        ;    (shell-command-on-region
+                                        ;     start end
+                                        ;     "sed '/[ ][.][ ]/d'" t)))
+;;"sed \"\\?          *\\.          *\\.          *\\.    ?d\"" t)))
+;;(vip-goto-line 1)
+;;(setq ex-g-flag nil
+;;ex-g-variant nil)
+;;(vip-ex "1,$g/           \\.           \\.           \\.    /d")))
+
+(defun sas-fix-page-numbers (offset &optional page-num)
+  "Fix number of current page in sas output files after editing.  Add
+OFFSET to actual page number."
+  (interactive "P")
+  (if (not offset) (setq offset 0))
+  (if (not page-num) (setq page-num (sas-page-number)))
+  (save-excursion
+    (if (/= (preceding-char) ?\C-l) (backward-page 1))
+    (let (end len mstart mend)
+      (save-excursion
+        (forward-line sas-page-number-max-line)
+        (setq end (point)))
+      (if (re-search-forward
+           "\\(^[0-9]+[ ]\\)\\|\\([ ][0-9]+$\\)"
+           end t)
+          (progn (setq len (- (match-end 0) (match-beginning 0))
+                       mstart (match-beginning 0)
+                       mend (match-end 0))
+                 (delete-region mstart mend)
+                 (if (eolp)
+                     (insert (format
+                              (concat "%" len "d") (+ page-num offset)))
+                   (insert (substring
+                            (concat (+ (sas-page-number) offset) "      ")
+                            0 len))))))))
+
+(defun sas-page-fix (start)
+  "Fix page numbers in sas output from point to end of file.
+If START is given this will be the number for the current page."
+  (interactive "P")
+  (let (offset (pnum (sas-page-number)))
+    (if (not start) (setq offset 0)
+      (setq offset (- start pnum)))
+    (while (not (eobp))
+      (sas-fix-page-numbers offset pnum)
+      (setq pnum (1+ pnum))
+      (forward-page 1))))
+
+(defun fix-page-breaks ()
+  "Fix page breaks in SAS 6 print files."
+  (interactive)
+  (save-excursion
+    (goto-char (point-min))
+    (if (looking-at "\f") (delete-char 1))
+                                        ;(replace-regexp "^\\(.+\\)\f" "\\1\n\f\n")
+    (while (re-search-forward "^\\(.+\\)\f" nil t)
+      (replace-match "\\1\n\f\n" nil nil))
+    (goto-char (point-min))
+                                        ;(replace-regexp "^\f\\(.+\\)" "\f\n\\1")
+    (while (re-search-forward "^\f\\(.+\\)" nil t)
+      (replace-match "\f\n\\1" nil nil))
+                                        ;    (goto-char (point-min))
+                                        ;(replace-regexp " $" "")
+                                        ;(while (re-search-forward "$" nil t)
+                                        ;     (replace-match "" nil nil))
+    (goto-char (point-min))
+                                        ;(replace-regexp " \\([^\\$]+\\)" "\n\\1")
+    (while (re-search-forward " \\([^\\$]+\\)" nil t)
+      (replace-match "\n\\1" nil nil))
+    (goto-char (point-max))
+    (if (not (bobp))
+        (progn (backward-char 1)
+               (if (not (looking-at "\n"))
+                   (progn (forward-char 1) (open-line 1)))))))
+
+(defun sas-page-number ()
+  ;; like what-page except it returns an integer page number
+  "Return page number of point in current buffer."
+  (let ((opoint (point))) (save-excursion
+                            (goto-char (point-min))
+                            (1+ (sas-how-many page-delimiter opoint)))))
+
+(defun sas-how-many (regexp &optional end)
+  ;; a copy of `how-many' which returns an integer
+  ;; rather than a message
+  "Return number of matches for REGEXP following point."
+  (let ((count 0) opoint)
+    (save-excursion
+      (while (and (not (eobp))
+                  (progn (setq opoint (point))
+                         (re-search-forward regexp end t)))
+        (if (= opoint (point))
+            (forward-char 1)
+          (setq count (1+ count))))
+      count)))
+
+(defun beginning-of-sas-proc ()
+  "Move point to beginning of sas proc, macro or data step."
+  (interactive)
+  (let ((case-fold-search t))
+    (forward-char -1)
+    (while (not (or (looking-at "data\\|proc\\|%macro")
+                    (bobp)))
+      (re-search-backward "proc\\|data\\|%macro" (point-min) 1)
+      (beginning-of-sas-statement 1))))
+
+(defun next-sas-proc (arg)
+  "Move point to beginning of next sas proc."
+  (interactive "P")
+  (let ((case-fold-search t))
+    (forward-char 1)
+    (if (re-search-forward
+         "^[ \t]*\\(data[ ;]\\|proc[ ;]\\|endsas[ ;]\\|g?options[ ;]\\|%macro[ ;]\\)"
+         nil t arg)
+        (beginning-of-sas-statement 1)
+      (forward-char -1))))
+
+(defun set-sas-file-name ()
+  "Stores the name of the current sas file."
+  (let ((name (buffer-file-name)))
+    (cond ((not name))
+          ((string-match (substring name -4 nil)
+                         "\\.sas\\|\\.lst\\|\\.log")
+
+           (setq sas-file-name (substring name 0 (- (length name) 4)))
+           (setq sas-buffer-name (buffer-name))
+           (setq sas-file-root (substring sas-buffer-name 0
+                                          (- (length sas-buffer-name) 4))))
+          (t (message "This file does not have a standard suffix")))))
+
+;;  created 6/27/94
+(defun sas-set-alternate-file-name (name)
+  "Stores the NAME of an alternate sas file.
+When this file is submitted with `submit-sas', the alternate file will
+be submitted instead.  `sas-submitable' is automatically sets to t."
+  (interactive "f")
+  (cond ((string-match (substring name -4 nil)
+                       "\\.sas\\|\\.lst\\|\\.log")
+         (setq sas-file-name (substring name 0 (- (length name) 4)))
+         (setq sas-submitable t))
+        (t (message "This file does not have a standard suffix"))))
+
+(defun switch-to-sas-source ()
+  "Switches to sas source file associated with the current file."
+  (interactive)
+  (switch-to-sas-file "sas"))
+
+(defun switch-to-sas-lst ()
+  "Switches to sas source file associated with the current file."
+  (interactive)
+  (switch-to-sas-file "lst"))
+
+(defun switch-to-sas-log ()
+  "Switches to sas source file associated with the current file."
+  (interactive)
+  (switch-to-sas-file "log"))
+
+(defun switch-to-sas-source-other-window ()
+  "Switches to sas source file associated with the current file."
+  (interactive)
+  (switch-to-sas-file-other-window "sas"))
+
+(defun switch-to-sas-lst-other-window ()
+  "Switches to sas source file associated with the current file."
+  (interactive)
+  (switch-to-sas-file-other-window "lst"))
+
+(defun switch-to-sas-log-other-window ()
+  "Switches to sas source file associated with the current file."
+  (interactive)
+  (switch-to-sas-file-other-window "log"))
+
+;;(defun switch-to-sas-file (suff &optional revert silent)
+;;  "Switches to sas \"SUFF\" file associated with the current file"
+;;  (let* ((sfile sas-file-name)
+;;       (buf (get-file-buffer (concat sfile "." suff)))
+;;       (sas-require-confirmation
+;;           (and sas-require-confirmation (not revert))))
+;;     (if (or sas-require-confirmation (string-equal suff "sas") (not buf))
+;;         (find-file (concat sfile "." suff))
+;;       (progn (switch-to-buffer buf)
+;;              (if (not (verify-visited-file-modtime (current-buffer)))
+;;                  (progn (revert-buffer t t)
+;;                         (if (not silent)
+;;                             (message "File has changed on disk.  Buffer automatically updated."))))))
+;;     (setq sas-file-name sfile))
+;;   (if (string-equal suff "sas")
+;;       (if (not (string-equal major-mode "sas-mode"))
+;;           (sas-mode))
+;;     (if (not (string-equal major-mode "sasl-mode"))
+;;         (sasl-mode))))
+;;
+;;(defun switch-to-sas-file-other-window (suff)
+;;  "Switches to sas \"SUFF\" file associated with the current file"
+;;  (let* ((sfile sas-file-name)
+;;       (buf (get-file-buffer (concat sfile "." suff))))
+;;    (if (or sas-require-confirmation (string-equal suff "sas") (not buf))
+;;      (find-file-other-window (concat sfile "." suff))
+;;      (progn (switch-to-buffer-other-window buf)
+;;           (if (not (verify-visited-file-modtime (current-buffer)))
+;;               (progn (revert-buffer t t)
+;;                      (message "File has changed on disk.  Buffer automatically updated.")))))
+;;    (setq sas-file-name sfile))
+;;  (if (string-equal suff "sas")
+;;      (if (not (string-equal major-mode "sas-mode"))
+;;        ;;(sas-mode)
+;;        )
+;;    (if (not (string-equal major-mode "sasl-mode"))
+;;      ;;(sasl-mode)
+;;      )))
+
+(defun switch-to-sas-file (suff)
+  "Switches to sas \"SUFF\" file associated with the current file."
+  (switch-to-buffer (set-sas-file-buffer suff)))
+
+(defun switch-to-sas-file-other-window (suff)
+  "Switches to sas \"SUFF\" file associated with the current file."
+  (switch-to-buffer-other-window (set-sas-file-buffer suff)))
+
+;;  The following was created 6/7/94 to handle buffers without messing up
+;;  windows.
+
+(defun set-sas-file-buffer (suff &optional revert silent)
+  "Sets current buffer to sas \"SUFF\" file associated with the current file."
+  (let* ((sfile sas-file-name)
+         (buf (get-file-buffer (concat sfile "." suff)))
+         (sas-require-confirmation
+          (and sas-require-confirmation (not revert))))
+    (if (or sas-require-confirmation (string-equal suff "sas") (not buf))
+        (set-buffer (find-file-noselect (concat sfile "." suff)))
+      (progn (set-buffer buf)
+             (if (not (verify-visited-file-modtime (current-buffer)))
+                 (progn (revert-buffer t t)
+                        (if (not silent)
+                            (message "File has changed on disk.  Buffer automatically updated."))))))
+    (setq sas-file-name sfile))
+  ;;(if (string-equal suff "sas")
+  ;; (if (not (string-equal major-mode "sas-mode")) (sas-mode))
+  ;; (if (not (string-equal major-mode "sasl-mode"))(sasl-mode))
+  (current-buffer))
+
+(defun switch-to-sas-process-buffer ()
+  "Switch to sas-process-buffer."
+  (interactive)
+  (let (buf proc-name)
+    (setq proc-name (concat "SAS" sas-file-name)
+          buf (concat "*" proc-name "*"))
+    (switch-to-buffer-other-window buf)))
+
+(defun submit-sas ()
+  ;; 6/17/94  added sas-submitable local variable.
+  "Submit SAS file as shell command."
+  (interactive)
+  (if ;; can file be run, or is it only for inclusion?
+      (or sas-submitable
+          (progn
+            (beep)
+            (y-or-n-p
+             (format
+              "Submission is disabled for this file.  Submit it anyway? "))))
+      (progn
+        ;; if buffer name has changed, tell user
+        (if (or
+             (string-equal sas-buffer-name (buffer-name))
+             (not
+              (y-or-n-p
+               (format
+                "The name of this buffer has changed.  Submit the new file? "))))
+            (setq sas-buffer-name (buffer-name))
+          (set-sas-file-name))
+        (let ((sas-file sas-file-name)
+              (sas-root sas-file-root)
+              ;;(sas-buf  sas-buffer-name)
+              proc-name
+              buf)
+
+          ;; Save buffer to SAS the right file :-).
+          (if (buffer-modified-p)
+              (if (y-or-n-p (format "Buffer %s is modified. Save it? "
+                                    (buffer-name)))
+                  (save-buffer)))
+          (setq proc-name (concat "SAS" sas-file)
+                buf (concat "*" proc-name "*"))
+          (if (get-buffer buf)
+              (save-window-excursion (switch-to-buffer buf)
+                                     (erase-buffer)
+                                     (setq default-directory
+                                           (file-name-directory sas-file))))
+
+          (run-hooks 'sas-pre-run-hook)  ;; added 8/24/94
+          (message "----  Submitting SAS job   ----")
+          ;; (switch-to-buffer buf)
+          (make-comint proc-name
+                       sas-program     ;added sas-program 4/29/94
+                       nil
+                       sas-root)
+          (save-window-excursion
+            (switch-to-buffer buf)
+            (setq sas-file-name sas-file)
+            (bury-buffer buf))
+
+          (message "----  SAS job submitted  ----   ")
+
+          (if sas-notify;;  added 4/7/94
+              (set-process-sentinel (get-process proc-name) #'sas-sentinel)
+            (display-buffer buf t))))
+    (message "----  File not submitted  ----")))
+
+;; 5/2/94 Modified sas-sentinel to check for errors in log file upon
+;; completion.
+(defun sas-sentinel (proc arg);; created 4/7/94
+  "Notify user that SAS run is done."
+  (beep)
+  ;;(if (string-equal arg "finished\n")
+  (save-excursion
+    (let (msg buf win (sbuf (concat "*" (process-name proc) "*")))
+      (setq msg
+            (format "SAS %s %s"
+                    (substring arg 0 -1)
+                    (if sas-error-notify
+                        ;;(save-window-excursion
+                        (progn
+                          (set-buffer sbuf)
+                          (setq buf (set-sas-file-buffer "log" t t))
+                          (goto-char (point-min))
+                          (setq win (get-buffer-window buf))
+                          (save-window-excursion
+                            (if win
+                                (progn
+                                  (select-window win)
+                                  (if (re-search-forward "^ERROR" nil t)
+                                      " (See .log file for errors)"
+                                    ""))
+                              (switch-to-buffer buf)
+                              (if (re-search-forward "^ERROR" nil t)
+                                  " (See .log file for errors)"
+                                ""))))
+                      "")))
+      (set-buffer sbuf)
+      (goto-char (point-max))
+      (insert msg)
+      (bury-buffer (get-buffer sbuf))
+      ;;(if (and sas-notify-popup window-system)
+      ;;    (x-popup-dialog t
+      ;;                (list "SAS Menu" (cons msg  nil) )))
+      ;;(if (not (minibuffer-window-active-p)) (princ msg))
+      (princ msg))))
+
+;; 5/2/94 Modified run-sas-on-region to separate log and output buffers.
+;;
+;;(defun run-sas-on-region (start end append &optional buffer)
+;;  "Submit region to SAS"
+;;  (interactive "r\nP")
+;;  (message "----  Running SAS  ----")
+;;  (let ((sfile sas-file-name)
+;;        (shell-file-name "/bin/sh")
+;;        serror buff)
+;;    (setq buffer (or buffer "*SAS output*"))
+;;    (save-excursion
+;;      (shell-command-on-region
+;;       start end;; added sas-program
+;;       (concat sas-program " -nonews -stdio 2> /tmp/_temp_.log" nil))
+;;      (get-buffer-create "*SAS Log*")
+;;      (save-window-excursion
+;;        (switch-to-buffer "*SAS Log*")
+;;        (erase-buffer)
+;;        (insert-file-contents "/tmp/_temp_.log")
+;;        (delete-file "/tmp/_temp_.log")
+;;        (setq serror (re-search-forward "^ERROR" nil t))
+;;        (if serror () (bury-buffer)))
+;;      (setq buff (get-buffer-create buffer))
+;;      (save-window-excursion
+;;        (switch-to-buffer buff)
+;;        (setq sas-file-name sfile)
+;;        (if append
+;;            (progn
+;;              (end-of-buffer)
+;;              (insert "\f\n"))
+;;          (erase-buffer))
+;;        (if (get-buffer "*Shell Command Output*")
+;;            (progn (insert-buffer "*Shell Command Output*")
+;;                   (kill-buffer "*Shell Command Output*"))
+;;          (insert "SAS completed with no output."))
+;;        (if append () (sasl-mode))
+;;        (message "----  SAS Complete ----")))
+;;    (if (not serror)
+;;        (switch-to-buffer-other-window  buff)
+;;      (switch-to-buffer-other-window "*SAS Log*")
+;;      (goto-char serror)
+;;      (beep)
+;;      (message "Error found in log file.")
+;;      )))
+
+(defun switch-to-dataset-log-buffer ()
+  "Switch to log buffer for run-sas-on-region."
+  (interactive)
+  (switch-to-buffer-other-window "*SAS Log*"))
+
+(defun switch-to-dataset-source-buffer ()
+  "Switch to source buffer for run-sas-on-region."
+  (interactive)
+  (switch-to-buffer-other-window (format " *sas-tmp-%s*" sas-dataset)))
+
+;;(defun sas-get-dataset (filename &optional arg opts-p append buffer vars)
+;;  "Run proc contents and proc print on SAS dataset.  Automatically prompts
+;;for SAS options to use.  Default options are defined by the variable
+;;`sas-get-options'.  Output may be updated from within output buffer with
+;;C-cr if dataset changes.  Also, the source code which generates the output
+;;may be edited with C-cs.  Typing C-cr within the output buffer reexecutes
+;;the (modified) source code."
+;;  (interactive "fName of SAS dataset (file name):")
+;;  (let ((file (file-name-nondirectory filename))
+;;        (dir (file-name-directory filename))
+;;        (opts sas-get-options)
+;;        (minibuffer-history sas-get-options-history)
+;;        buf); fsize)
+;;    (setq buffer (or buffer (concat "*" file "*")))
+;;    (setq opts (if opts-p opts (read-string "SAS options: " opts)))
+;;    (setq sas-get-options-history minibuffer-history)
+;;    (cond ((string-match (substring file -6 nil) "\\.ssd01")
+;;      (setq file (substring file 0 (- (length file) 6))))
+;;    (t (error "This file is not a SAS dataset.")))
+;;    (setq buf (format " *sas-tmp-%s*" file))
+;;    (get-buffer-create buf)
+;;    (save-window-excursion
+;;      (switch-to-buffer buf)
+;;      (erase-buffer)
+;;      (setq default-directory dir)
+;;      (if opts
+;;          (insert (format "options  %s ;\n" opts)))
+;;      (insert (format "title \"Contents of SAS dataset `%s'\" ;\n" file))
+;;      (insert (format "libname %s '%s' ;\n" sas-tmp-libname dir))
+;;      (if (not (equal arg 1))
+;;               (insert (format "proc contents data = %s.%s ;\n" sas-tmp-libname file)))
+;;      (if (equal arg 2) ()
+;;        (insert (format "proc print data = %s.%s ;\n" sas-tmp-libname file))
+;;        (if vars (insert (format "  var %s ;\n" vars))))
+;;      (run-sas-on-region (point-min) (point-max) append
+;;                         buffer)
+;;      (get-buffer buffer)
+;;      (if append () (sasd-mode))  ;; added 5/5/94
+;;      (setq sas-dataset file))
+;;    (if (get-buffer-window buffer t)
+;;        (raise-frame (window-frame (get-buffer-window buffer t)))
+;;    (display-buffer buffer (not append)))
+;;    ))
+
+;;(defun revert-sas-dataset ()
+;;  "Revert current sas dataset from disk version"
+;;  (interactive)
+;;  (let* ((file sas-dataset)
+;;        (buf (format " *sas-tmp-%s*" file))
+;;        (pos (point)))
+;;      (save-window-excursion
+;;        (switch-to-buffer buf)
+;;        (run-sas-on-region (point-min) (point-max) nil
+;;                           (concat "*" file ".ssd01*"))
+;;        )
+;;      (goto-char pos)  ;; added 6/9/94
+;;    (sasd-mode)  ;; added 5/5/94
+;;    (setq sas-dataset file)))
+
+(defun sas-insert-local-variables ()  ;; created 6/17/94
+  "Add local variables code to end of sas source file."
+  (interactive)
+  (save-excursion
+    (if (re-search-forward "\\* *Local Variables: *;" nil t)
+        ()
+      (goto-char (point-max))
+      (insert "
+
+**  Local Variables:  ;
+**  End:  ;
+page ;
+"))))
+
+\f
+;;  variables section
+(defvar sas-dir-mode-map nil)
+(defvar-local sas-directory-name nil
+  "Name of directory associated with this buffer.")
+(defvar-local sas-dir-buf-end nil)
+(defvar-local sas-sorted-by-num nil)
+;; user variables
+\f
+;; keymaps etc...
+
+(if sas-dir-mode-map ()
+  (setq sas-dir-mode-map (make-sparse-keymap))
+  (define-key sas-dir-mode-map "m" #'sas-mark-item)
+  (define-key sas-dir-mode-map "u" #'sas-unmark-item)
+  (define-key sas-dir-mode-map " " #'sas-next-line)
+  (define-key sas-dir-mode-map "\C-n" #'sas-next-line)
+  (define-key sas-dir-mode-map "\C-p" #'sas-prev-line)
+  (define-key sas-dir-mode-map "\177" #'sas-prev-line-undo)
+  (define-key sas-dir-mode-map "\C-b" #'sas-backward-page-narrow)
+  (define-key sas-dir-mode-map "\C-v" #'sas-forward-page-narrow)
+  (define-key sas-dir-mode-map "\C-m" #'sas-goto-dataset)
+  (define-key sas-dir-mode-map "t" #'sas-dir-goto-page)
+  (define-key sas-dir-mode-map "q" #'bury-buffer)
+  (define-key sas-dir-mode-map "1" #'digit-argument)
+  (define-key sas-dir-mode-map "2" #'digit-argument)
+  (define-key sas-dir-mode-map "3" #'digit-argument)
+  (define-key sas-dir-mode-map "4" #'digit-argument)
+  (define-key sas-dir-mode-map "5" #'digit-argument)
+  (define-key sas-dir-mode-map "6" #'digit-argument)
+  (define-key sas-dir-mode-map "7" #'digit-argument)
+  (define-key sas-dir-mode-map "8" #'digit-argument)
+  (define-key sas-dir-mode-map "9" #'digit-argument)
+  (define-key sas-dir-mode-map [menu-bar sas run]
+    '("Submit File " . submit-sas))
+  )
+
+(define-derived-mode sas-dir-mode special-mode "SAS"
+  "Major mode for managing sas files."
+  :group 'ess-sas
+  (setq sas-directory-name (expand-file-name default-directory)))
+
+
+;;(defun sas-make-library (directory &optional update)
+;;  "Create a buffer with the names of all sas datasets from DIRECTORY."
+;;  (interactive "DDirectory Name: ")
+;;  (let ((dir (expand-file-name directory)) buf out cont pos)
+;;    (setq buf (format " *sas-tmp-%s*" dir))
+;;    (setq out (concat "*SAS-dir-" dir))
+;;    (setq cont (concat "*SAS-cont-" dir))
+;;    (get-buffer-create buf)
+;;    (if (get-buffer out)
+;;        (if update
+;;            (progn
+;;              (set-buffer out)
+;;              (setq buffer-read-only nil)))
+;;      (setq update t))
+;;    (pop-to-buffer out)
+;;    (setq default-directory dir)
+;;    (setq pos (point))
+;;    (if update
+;;        (progn
+;;          (save-window-excursion
+;;            (set-buffer buf)
+;;            (erase-buffer)
+;;            (setq default-directory dir)
+;;            (insert "options linesize=70 pagesize=1000 ;\n")
+;;            (insert (format "title \"Contents of SAS directory `%s'\" ;\n"
+;;                            dir))
+;;            (insert (format "libname %s '%s' ;\n" sas-tmp-libname dir))
+;;            (insert (format "proc contents data = %s._all_ directory details memtype=data ;\n" sas-tmp-libname))
+;;            (run-sas-on-region (point-min) (point-max) nil
+;;                               out)
+;;            (set-buffer out)
+;;            (goto-char (point-min))
+;;            (if (= (sas-how-many page-delimiter (point-max)) 0)
+;;                (let ((buffer-read-only nil))
+;;                  (erase-buffer)
+;;                  (insert "There are no SAS datasets in this directory")
+;;                  (pop-to-buffer out))
+;;              (save-excursion
+;;                (set-buffer (get-buffer-create cont))
+;;                (setq buffer-read-only t)
+;;                (let ((buffer-read-only nil))
+;;                  (erase-buffer)
+;;                  (insert-buffer out)
+;;                  (delete-region (point-min)
+;;                                 (or (re-search-forward page-delimiter nil t)
+;;                                     (point-min)))
+;;                  (sas-page-fix 1)
+;;                  (goto-char (point-min))
+;;                  (sas-dir-mode)
+;;                  (sas-narrow-to-page)))
+;;              (if (re-search-forward page-delimiter nil t)
+;;                  (delete-region (progn (beginning-of-line) (point))
+;;                                 (point-max)))
+;;              (sas-insert-set-properties (point-min) (point-max))
+;;              )
+;;            (switch-to-buffer out t)
+;;            (goto-char (point-min))
+;;            (sas-dir-mode)
+;;            (setq sas-dir-buf-end (point-max)))
+;;          (goto-char pos)
+;;          (sas-move-to-filename (point-max))))))
+
+
+(defun sas-move-to-filename (&optional eol)
+  (or eol (setq eol (progn (end-of-line) (point))))
+  (beginning-of-line)
+  (if (re-search-forward "\\(^ *[0-9]+ *<*\\)[^:0-9\n]" eol t)
+      (goto-char (match-end 1))))
+
+(defun sas-next-line (arg)
+  "Move down one line."
+  (interactive "p")
+  (forward-line arg)
+  (sas-move-to-filename (point-max)))
+;;(and (< (point) sas-dir-buf-end)
+;;(forward-line arg)
+;;(sas-move-to-filename sas-dir-buf-end)))
+
+(defun sas-prev-line (&optional _arg)
+  "Move up one line."
+  (interactive)
+  (beginning-of-line)
+  (re-search-backward "^ *[0-9]+ *<*[^:0-9\n]" (point-min) t)
+  (sas-move-to-filename sas-dir-buf-end))
+
+(defun sas-insert-set-properties (beg end)
+  (save-excursion
+    (goto-char beg)
+    (while (< (point) end)
+      (if (sas-move-to-filename)
+          (put-text-property (point)
+                             (+ 8 (point))
+                             'mouse-face 'highlight))
+      (forward-line 1))))
+
+(defun sas-get-filename ()
+  "Return name of dataset on current line."
+  (interactive)
+  (save-excursion
+    (if (string-equal "*SAS-dir" (substring (buffer-name) 0 8))
+        (sas-move-to-filename)
+      (goto-char (point-min))
+      (re-search-forward "Data Set Name: [^.]*\\."))
+    (expand-file-name
+     (downcase (concat sas-directory-name
+                       (buffer-substring
+                        (point)
+                        (save-excursion
+                          (skip-chars-forward "A-Z0-9_")
+                          (point))) ".ssd01")))))
+
+(defun sas-get-file-number ()
+  "Return name of dataset on current line."
+  (interactive)
+  (if (sas-move-to-filename)
+      (progn (forward-word -1)
+             (re-search-forward "[0-9]*")
+             (string-to-number
+              (buffer-substring (match-beginning 0)
+                                (match-end 0))))))
+
+(defun sas-goto-page (arg)
+  "Goto top of page ARG.  If no ARG, then goto top of file."
+  (interactive "P")
+  (goto-char 1)
+  (if arg
+      (if (> arg 1)
+          (progn
+            (re-search-forward page-delimiter (point-max) 1 (1- arg)))))
+  (skip-chars-forward sas-white-chars); was " \f\n" till 5.1.13
+  (recenter 1))
+
+(defun forward-page-top-of-window (arg)
+  "Move forward to page boundary and leave first line at top of window.
+With arg, repeat, or go back if negative. A page boundary is any line
+whose beginning matches the regexp `page-delimiter'."
+  (interactive "p")
+  (forward-page arg)
+  (recenter 0))
+
+(defun backward-page-top-of-window (arg)
+  "Move backward to page boundary and leave first line at top of window.
+With arg, repeat, or go back if negative. A page boundary is any line
+whose beginning matches the regexp `page-delimiter'."
+  (interactive "p")
+  (forward-page (- arg))
+  (recenter 0))
+
+(defun sas-narrow-to-page ()
+  (save-excursion
+    (let* ((min (point-min))
+           (max (point-max)))
+      ;;(omin (point-min))
+      ;;(omax (point-max)))
+      (if (or (bolp) (beginning-of-line)
+              (looking-at page-delimiter))
+          (forward-char 1)
+        (forward-page -1))
+      (setq min (point))
+      (forward-page 1)
+      (beginning-of-line)
+      (setq max (point))
+      (narrow-to-region min max))))
+
+(defun sas-forward-page-narrow (arg)
+  "Move forward to page boundary and narrow to page.
+With arg, repeat, or go back if negative. A page boundary is any line
+whose beginning matches the regexp `page-delimiter'."
+  (interactive "p")
+  (widen)
+  (forward-page arg)
+  (sas-narrow-to-page)
+  (goto-char (point-min)))
+
+(defun sas-backward-page-narrow (arg)
+  "Move backward to page boundary and narrow to page.
+With arg, repeat, or go back if negative. A page boundary is any line
+whose beginning matches the regexp `page-delimiter'."
+  (interactive "p")
+  (goto-char (point-min))
+  (widen)
+  (forward-page (- arg))
+  (sas-narrow-to-page))
+
+(defun sas-goto-dataset (&optional page)
+  (interactive)
+  (and sas-directory-name
+       (let ((page (or page (sas-get-file-number))))
+         ;;(dir sas-directory-name))
+         (if page
+             (progn
+               (switch-to-buffer-other-window
+                (concat "*SAS-cont-" sas-directory-name))
+               (widen)
+               (sas-goto-page page)
+               (sas-narrow-to-page)
+               (goto-char (point-min)))))))
+
+
+(defun sas-dir-goto-page (page)
+  (interactive "p")
+  (widen)
+  (sas-goto-page page)
+  (sas-narrow-to-page))
+
+(defun sas-mark-item (&optional next)
+  (interactive)
+  (sas-move-to-filename)
+  (beginning-of-line)
+  (let ((buffer-read-only nil))
+    (if (re-search-forward "^\\( *[0-9]+ *\\) \\([A-Z][A-Z_0-9]*\\) "
+                           (save-excursion (end-of-line) (point)) t)
+        (replace-match "\\1<\\2>")))
+  (or next (sas-next-line 1)))
+
+(defun sas-unmark-item ()
+  (interactive)
+  (save-excursion
+    (beginning-of-line)
+    (let ((buffer-read-only nil))
+      (if (re-search-forward "^\\( *[0-9]+ *\\)<\\([A-Z][A-Z_0-9]*\\)>"
+                             (save-excursion (end-of-line) (point)) t)
+          (replace-match "\\1 \\2 ")))))
+
+(defun sas-prev-line-undo (arg)
+  (interactive "p")
+  (sas-prev-line arg)
+  (sas-unmark-item)
+  (sas-move-to-filename))
+
+(defun sas-create-var-string ()
+  (and (string-equal "*SAS-cont" (substring (buffer-name) 0 9))
+       (let (str)
+         (goto-char (point-min))
+         (while
+             (re-search-forward "^\\( *[0-9]+ *\\)<\\([A-Z][A-Z_0-9]*\\)>"
+                                nil t)
+           (setq str (concat str " " (buffer-substring (match-beginning 2)
+                                                       (match-end 2)))))
+         str)))
+
+
+(defun ess-imenu-SAS (&optional _arg)
+  "SAS language Imenu support for ESS."
+  (interactive)
+  (setq imenu-generic-expression
+        '( (nil "[ \t\n=]\\([[:alpha:]_][[:alnum:]_]*[.][[:alpha:]_][[:alnum:]_]*\\)[ ,()\t\n;]" 1)))
+  (imenu-add-to-menubar "SAS Datasets"))
+
+(provide 'ess-sas-l)
+
+;;; ess-sas-l.el ends here
diff --git a/elpa/ess-20260424.1544/ess-site.el b/elpa/ess-20260424.1544/ess-site.el
new file mode 100644 (file)
index 0000000..c298086
--- /dev/null
@@ -0,0 +1,65 @@
+;;; ess-site.el --- user customization of ESS  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1993-2020 Free Software Foundation, Inc.
+;; Author: David Smith <D.M.SmithNOSPAMlancaster.ac.uk>
+;; Created: 12 Nov 1993
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; Load path, autoloads, and major modes
+;; ========================================
+;;
+;; This file defines all the site-specific customizations for ESS. It should be
+;; edited on a per-site basis. users who wish to use ESS should add the path to
+;; ess-site to their `load-path' and require it:
+;;
+;;    (add-to-list 'load-path "/path/to/ess/lisp-directory");;
+;;    (require 'ess-site)
+;;
+;; For most users the variable ess-lisp-directory will automatically be set
+;; correctly. If you are working with an old Emacs, one in which file-truename
+;; is not defined, then you might need to change the value of ess-lisp-directory
+;; to the directory which is to contain the file ess-site.elc. This is probably
+;; the current directory, or the value of LISPDIR if it was set in the Makefile.
+;;
+;; Debug startup: (setq ess-show-load-messages t)
+
+;;; Code:
+
+(when load-file-name
+  ;; Modify this if ess-site.el is not in the ./lisp/ directory
+  (defvar ess-lisp-directory (file-name-directory load-file-name)
+    "Directory containing ess-site.el(c) and other ESS Lisp files.")
+  (add-to-list 'load-path (directory-file-name ess-lisp-directory)))
+
+;;; Loading popular dialects (they should become optional in the future)
+
+(require 'ess-r-mode)
+(require 'essd-els) ;; ess-remote
+(require 'ess-sas-d)
+(require 'ess-bugs-d)
+(require 'ess-jags-d)
+(require 'ess-toolbar)
+
+(provide 'ess-site)
+
+;;; ess-site.el ends here
diff --git a/elpa/ess-20260424.1544/ess-sp6-d.el b/elpa/ess-20260424.1544/ess-sp6-d.el
new file mode 100644 (file)
index 0000000..087c7ca
--- /dev/null
@@ -0,0 +1,196 @@
+;;; ess-sp6-d.el --- S-Plus 6 & 7 & 8  customization  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2001-2022 Free Software Foundation, Inc.
+;; Author: A.J. Rossini <rossiniNOSPAMu.washington.edu>
+;; Created: 2001/02/06
+;; Maintainer: ESS Core Team <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; AJR copied S+5 to be S+6.
+;; AJR copied S4 to be S+5.
+;; DB contributed the changes from ess-sp3-d.el to
+;; ess-s4-d.el. (removed the old ugly approach).
+;; This file defines Sp5 customizations for ess-mode.  Lots of thanks
+;; to RMH and JMC for code and suggestions
+;; Thanks to MM for making this sensible.
+
+;;; Code:
+
+(require 'ess-mode)
+(require 'ess-inf)
+(require 'ess-s-lang)
+(require 'ess-trns)
+
+
+;; You now need to make sure you've defined if you are running 5.0 or 5.1.
+;; Lots of things are broken between them, GRR...
+
+(defun S+-directory-p (directory)
+  "Splus 5++ directories have a .Data directory and a __Meta directory within."
+  (and directory
+       (file-directory-p (concat directory ".Data"))
+       (file-directory-p (concat directory ".Data/__Meta"))))
+
+(defvar S+-directory-function #'inferior-ess-default-directory)
+
+(defvaralias 'S+6-setup-directory-function 'S+-setup-directory-function)
+(defvar S+-setup-directory-function
+  (lambda (startdir)
+    (when (and startdir (S+-directory-p startdir))
+      (setenv "S_WORK"
+              (if (getenv "S_WORK")
+                  (concat startdir ":" (getenv "S_WORK"))
+                ;;(message "adding %s to S_WORK" startdir)
+                startdir)))))
+
+
+
+(defvaralias 'S+6-customize-alist 'S+-customize-alist)
+(defvar S+-customize-alist
+  (append
+   '((ess-local-customize-alist        . S+-customize-alist)
+     (ess-dialect                      . S+-dialect-name)
+     (ess-function-pattern             . ess-r-function-pattern)
+
+     (ess-object-name-db-file          . "ess-sp6-namedb.el")
+     (inferior-ess-program             . inferior-S+-program)
+     (inferior-ess-help-command        . "help(\"%s\", pager=\"slynx -dump\", window=FALSE)\n")
+     (inferior-ess-search-list-command . "searchPaths()\n")
+
+     (ess-startup-directory-function   . S+-directory-function)
+     (ess-STERM                        . "iESS"))
+   S+common-cust-alist)
+
+  "Variables to customize for S+.")
+
+(defvar ess-S+-post-run-hook nil
+  "Functions run in process buffer after the initialization of S+
+  process.")
+
+(defvar ess-S+--injected-code
+  ".ess_funargs <- function(funname){
+  ## funname <- deparse(substitute(object))
+  fun <- try(eval(parse(text=funname)), silent = TRUE)
+  if(is.function(fun)) {
+    special <- grepl('[:$@[]', funname)
+    args <- args(fun)
+    fmls <- formals(args)
+    fmls.names <- names(fmls)
+    fmls <- gsub('\\\"', '\\\\\\\"', as.character(fmls), fixed = TRUE)
+    args.alist <- sprintf(\"'(%s)\", paste(\"(\\\"\", fmls.names, \"\\\" . \\\"\", fmls, \"\\\")\", sep = '', collapse = ' '))
+    ## envname <- environmentName(environment(fun))
+    envname <-  if (special) '' else 'S+'
+    cat(sprintf('(list \\\"%s\\\" %s )\\n', envname, args.alist))
+  }
+}
+")
+
+(defalias 'S+6 #'S+)
+(defun S+ (&optional _proc-name)
+  "Call `Splus6', based on S version 4, from Bell Labs.
+New way to do it."
+  (interactive)
+  (ess-write-to-dribble-buffer
+   (format "\n(S+): ess-dialect=%s, buf=%s\n" ess-dialect (current-buffer)))
+  (let ((inf-buf (inferior-ess nil S+-customize-alist)))
+    (ess-command ess-S+--injected-code)
+    (when inferior-ess-language-start
+      (ess-eval-linewise inferior-ess-language-start))
+    (with-current-buffer inf-buf
+      (run-mode-hooks 'ess-S+-post-run-hook))
+    inf-buf))
+
+
+(defalias 'S+6-mode #'S+-mode)
+;;;###autoload
+(defun S+-mode (&optional _proc-name)
+  "Major mode for editing S+ source.  See `ess-mode' for more help."
+  (interactive)
+  (setq-local ess-local-customize-alist S+-customize-alist)
+  (ess-mode)
+  (if (fboundp 'ess-add-toolbar) (ess-add-toolbar))
+  (setq imenu-generic-expression ess-imenu-S-generic-expression)
+  (when ess-imenu-use-S (imenu-add-to-menubar "Imenu-S")))
+
+(defalias 'S+6-transcript-mode #'S+-transcript-mode)
+(define-derived-mode S+-transcript-mode ess-transcript-mode "ESS S Transcript"
+  "S-PLUS 6 transcript mode."
+  :syntax-table S-syntax-table
+  :group 'ess-S)
+
+(defvar ess-s-versions '("Splus")
+  "List of partial strings for versions of S 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 S is made available.  For example, if the
+file \"Splus7\" is found and this variable includes the string
+\"Splus\", a function called `M-x Splus7' will be available to run that
+version of S.
+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'.
+Set this variable to nil to disable searching for other versions
+of S using this method.
+If you set this variable, you need to restart Emacs (and set this variable
+before ess-site is loaded) for it to take effect.")
+(define-obsolete-variable-alias
+  'ess-s-versions-created 'ess-s-created-runners "ESS 18.10")
+(defvar ess-s-created-runners)
+(defun ess-s-define-runners ()
+  "Generate functions for starting other versions of S.
+See `ess-s-versions' for strings that determine which functions are created.
+It assumes these versions of S can be run as a substitute for Splus6.
+
+This function returns the list of functions, if any, that were
+created.  The functions will normally be placed on the menubar upon
+ESS initialization."
+  (when ess-s-versions
+    (let ((versions
+           (delete-dups
+            (mapcar #'file-name-nondirectory
+                    (apply #'nconc
+                           (mapcar #'ess-find-exec-completions
+                                   ess-s-versions))))))
+      ;; Iterate over each string in VERSIONS, creating a new defun
+      ;; each time.
+      (setq ess-s-created-runners
+            (mapc (lambda (v) (ess-define-runner v "S")) versions))
+      ;; Add to menu
+      (when ess-s-created-runners
+        ;; new-menu will be a list of 3-vectors, of the form:
+        ;; ["R-1.8.1" R-1.8.1 t]
+        (let ((new-menu (mapcar (lambda (x) (vector x (intern x) t))
+                                ess-s-created-runners)))
+          (easy-menu-add-item ess-mode-menu '("Start Process")
+                              (cons "Other" new-menu)))))))
+;; Define the runners
+(ess-s-define-runners)
+(define-obsolete-function-alias
+  'ess-s-versions-create #'ess-s-define-runners "ESS 18.10")
+
+
+
+\f ; Provide package
+
+(provide 'ess-sp6-d)
+
+;;; ess-sp6-d.el ends here
diff --git a/elpa/ess-20260424.1544/ess-toolbar.el b/elpa/ess-20260424.1544/ess-toolbar.el
new file mode 100644 (file)
index 0000000..b6d1207
--- /dev/null
@@ -0,0 +1,184 @@
+;;; ess-toolbar.el --- Support for a toolbar in ESS.  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1997-2020 Free Software Foundation, Inc.
+;; Author: Stephen Eglen
+;; Created: 2004-05-06
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; This code adds a toolbar to ESS modes for editing R and S code.
+;; Support can be added for other modes (e.g. STATA), just ask!
+;;
+;; This code is experimental. It has been tested only on Linux
+;; machines.  All feedback appreciated.
+;;
+;; 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.  See also the documentation for ess-toolbar-items
+;; if you wish to change its value.
+
+;;; Technical issues.
+
+;; 2009-03-16: toolbar code in Emacs 23 has changed slightly to 22,
+;; and presumably once Emacs 22 is no longer supported, this code can
+;; be cleaned up a bit (i.e. no need to set load-path.)
+
+;;; Code:
+
+(require 'ess-mode)
+
+(defgroup ess-toolbar nil
+  "ESS: toolbar support."
+  :group 'ess
+  :link '(emacs-commentary-link :tag "Commentary" "ess-toolbar.el")
+  :prefix "ess-")
+
+(defcustom ess-use-toolbar
+  (and (fboundp 'display-images-p) (display-images-p))
+  "Non-nil means ESS should support the toolbar."
+  :type 'boolean)
+
+
+(defcustom ess-toolbar-own-icons nil
+  "Non-nil means that we only put our toolbar entries in ESS.
+Otherwise we get standard toolbar as well as ESS entries.
+The standard toolbar items are copied from the default toolbar."
+  :type 'boolean)
+
+(defcustom ess-toolbar-global nil
+  "*Non-nil means that the ESS toolbar is available in all Emacs buffers.
+Otherwise, the ESS toolbar is present only in R/S mode buffers.
+For beginners, this is probably better set to a non-nil value."
+  :type 'boolean)
+
+(defcustom ess-toolbar-items
+  '( (R   "startr")
+     ;;(S   "spluslogo" "Start S process")
+     (S   "splus_letter_small")
+     (ess-eval-line-and-step   "rline")
+     (ess-eval-region   "rregion")
+     (ess-eval-function-or-paragraph-and-step "rregion")
+     (ess-load-file   "rbuffer")
+     (ess-eval-function   "rfunction")
+     (ess-switch-to-ESS   "switch_ess"))
+  "Items to be added to the ESS toolbar.
+Each list element has two items:
+1. the name of the function to run
+2. the icon to be used (without .xpm extension)
+
+General toolbar items are also added to the ESS toolbar
+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."
+  :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"))))
+
+(defvar ess-icon-directory
+  (expand-file-name "icons" ess-etc-directory)
+  "*Location for ESS icons.
+This variable should be set automatically by the ESS install process.
+Icons should be found in ESS/etc/icons/ directory.
+If `ess-icon-directory' is invalid, please report a bug.")
+
+(unless (file-directory-p ess-icon-directory)
+  (ess-write-to-dribble-buffer
+   "`ess-icon-directory' does not exist; using `ess-etc-directory'.\n")
+  (setq ess-icon-directory ess-etc-directory))
+
+(defvar ess-toolbar nil
+  "Toolbar items to be added to ESS editing buffers.")
+
+(defun ess-make-toolbar ()
+  "Make the ESS toolbar."
+  ;; 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.
+  (when (boundp 'tool-bar-map)
+    (setq ess-toolbar
+          (if (or ess-toolbar-own-icons (null tool-bar-map))
+              (make-sparse-keymap)
+            (copy-keymap tool-bar-map)))
+    (let ((tool-bar-map ess-toolbar)
+          (load-path (list ess-icon-directory)))
+      ;; in Emacs 22, icons are found by examining load-path, bound here
+      ;; whereas Emacs 23 seems to want them in image-load-path, set at the
+      ;; bottom of this file.
+      (mapc #'ess-add-icon ess-toolbar-items))))
+
+(defun ess-add-icon (x)
+  "Add an ESS item to the Emacs toolbar.
+X should be a list, see `ess-toolbar-items' for the format."
+  ;; By using tool-bar-add-item-from-menu instead of tool-bar-add-item
+  ;; we get the tooltips "for free" from ess-mode-map.
+  (tool-bar-add-item-from-menu (car x) (cadr x) ess-mode-map))
+
+(defun ess-add-toolbar ()
+  "Add the ESS toolbar to a particular mode.
+The toolbar is added iff `ess-toolbar-global' is nil, else the toolbar
+is added globally when ess-toolbar.el is loaded."
+  (when (and ess-toolbar (not ess-toolbar-global))
+    (setq-local tool-bar-map ess-toolbar)))
+
+;; Make the toolbars.  Each toolbar is hopefully made only when this file
+;; is loaded; we don't need it to be remade every time.
+(if ess-use-toolbar
+    (progn
+      (ess-make-toolbar)
+      ;; After making the toolbar, if ESS toolbar is needed globally,
+      ;; add it here.
+      (if ess-toolbar-global
+          (setq tool-bar-map ess-toolbar)
+        (ess-write-to-dribble-buffer "Creating global Emacs toolbar"))
+
+      ;; Check for toolbar support - needed iff ess-use-toolbar is non-nil.
+      (or
+       ;; Emacs support for images:
+       (and (fboundp 'display-images-p) (display-images-p))
+       ;; if above tests failed, give a warning.
+       (progn
+         (message "Toolbar support for ESS not available in this Emacs.")
+         ;; Not sure if we want to delay startup of ESS.
+         ;;(sit-for 2)
+         ))
+      ))
+
+;; Following needed for Emacs 23, not Emacs 22
+(when (boundp 'image-load-path)
+  (add-to-list 'image-load-path ess-icon-directory))
+
+(provide 'ess-toolbar)
+
+;;; ess-toolbar.el ends here
diff --git a/elpa/ess-20260424.1544/ess-tracebug.el b/elpa/ess-20260424.1544/ess-tracebug.el
new file mode 100644 (file)
index 0000000..36ee08e
--- /dev/null
@@ -0,0 +1,2870 @@
+;; ess-tracebug.el --- Tracing and debugging facilities for ESS.  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2011-2025 Free Software Foundation, Inc.
+;; Author: Vitalie Spinu
+;; Maintainer: Vitalie Spinu
+;; Created: Oct 14 14:15:22 2010
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;;  Ess-tracebug is a package for interactive debugging of R code from
+;;  ESS and provides such features as:
+;;  - visual debugging
+;;  - browser, recover and conditional  breakpoints
+;;  - watch window and loggers
+;;  - on the fly  debug/undebug of R functions and methods
+;;  - highlighting of error source references and easy error navigation
+;;  - interactive traceback.
+;;
+;;  For a complete description please see the documentation in the ESS
+;;  manual.
+
+;;; Code:
+
+(eval-and-compile
+  (when (< emacs-major-version 26)
+    (require 'cl))
+  (require 'cl-lib)
+  (require 'tramp)
+  (require 'subr-x)
+  (require 'ess-utils))
+(require 'comint)
+(require 'compile)
+(require 'ring)
+
+
+(defvar text-scale-mode-amount)
+(autoload 'text-scale-mode              "face-remap" "[autoload]" nil)
+
+;; Silence the byte compiler. This is OK here because this file is
+;; only loaded from ess-inf and has no autoloads.
+;; TODO: This is a LOT. Can we move some of this around?
+(defvar ess--dbg-del-empty-p)
+(defvar inferior-ess-mode-map)
+(defvar ess-mode-map)
+(defvar ess--inhibit-presend-hooks)
+
+(declare-function ess--accumulation-buffer "ess-inf")
+(declare-function ess--if-verbose-write-process-state "ess-inf")
+(declare-function ess--run-presend-hooks "ess-inf")
+(declare-function ess-boolean-command "ess-inf")
+(declare-function ess-build-eval-command "ess-inf")
+(declare-function ess-build-load-command "ess-inf")
+(declare-function ess-command "ess-inf")
+(declare-function ess-dirs "ess-inf")
+(declare-function ess-eval-region--normalise-region "ess-inf" )
+(declare-function ess-force-buffer-current "ess-inf")
+(declare-function ess-get-process "ess-inf")
+(declare-function ess-get-process-variable "ess-inf")
+(declare-function ess-get-words-from-vector "ess-inf")
+(declare-function ess-get-words-from-vector--foreground "ess-inf")
+(declare-function ess-process-get "ess-inf")
+(declare-function ess-process-live-p "ess-inf")
+(declare-function ess-process-put "ess-inf")
+(declare-function ess-send-string "ess-inf")
+(declare-function ess-switch-process "ess-inf" ())
+(declare-function ess-switch-to-ESS "ess-inf")
+(declare-function ess-switch-to-end-of-ESS "ess-inf" ())
+(declare-function ess-wait-for-process "ess-inf")
+(declare-function inferior-ess--set-status "ess-inf")
+(declare-function inferior-ess-output-filter "ess-inf")
+(declare-function inferior-ess-run-callback "ess-inf")
+
+(declare-function ess-helpobjs-at-point--read-obj "ess-help")
+(declare-function ess-r-get-evaluation-env "ess-r-mode")
+(declare-function ess-roxy--region-p "ess-roxy")
+
+(declare-function ess-r-package--all-source-dirs "ess-r-package")
+(declare-function ess-r-package-name "ess-r-package")
+(declare-function ess-r-package-source-dirs "ess-r-package")
+
+
+;; Do not require tramp at runtime. It is expensive to load. Instead,
+;; guard calls with (require 'tramp) and silence the byte compiler
+;; here.
+(declare-function tramp-dissect-file-name "tramp")
+(declare-function tramp-get-remote-tmpdir "tramp")
+;; The following declares can be removed once we drop Emacs 25
+(declare-function tramp-file-name-hop "tramp")
+(declare-function tramp-file-name-host "tramp")
+(declare-function tramp-file-name-localname "tramp")
+(declare-function tramp-file-name-method "tramp")
+(declare-function tramp-file-name-user "tramp")
+
+
+(defgroup ess-tracebug nil
+  "Error navigation and debugging for ESS.
+Currently only R is supported."
+  :link '(emacs-library-link :tag "Source Lisp File" "ess-tracebug.el")
+  :group 'ess)
+
+(defvar ess-tracebug-indicator " TB"
+  "String to be displayed in mode-line alongside the process name.
+Indicates that ess-tracebug-mode is turned on.")
+
+(defvar ess-watch-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "k" #'ess-watch-kill)
+    ;; (define-key ess-watch-mode-map "u" #'ess-watch-undelete)
+    ;; editing requires a little more work.
+    (define-key map "a" #'ess-watch-add)
+    (define-key map "i" #'ess-watch-insert)
+    (define-key map "e" #'ess-watch-edit-expression)
+    (define-key map "r" #'ess-watch-rename)
+    (define-key map "q" #'ess-watch-quit)
+    (define-key map "u" #'ess-watch-move-up)
+    (define-key map "U" #'ess-watch-move-down)
+    (define-key map "d" #'ess-watch-move-down)
+    (define-key map "n" #'ess-watch-next-block)
+    (define-key map "p" #'ess-watch-previous-block)
+    ;; R mode keybindings.
+    (define-key map "\C-c\C-s" #'ess-switch-process)
+    (define-key map "\C-c\C-y" #'ess-switch-to-ESS)
+    (define-key map "\C-c\C-z" #'ess-switch-to-end-of-ESS)
+    map)
+  "Keymap for `ess-watch-mode'.")
+
+
+(defcustom ess-tracebug-prefix nil
+  "Key to be used as prefix for all `ess-tracebug' commands.
+Set this to a key combination you don't use often, like:
+
+ (setq ess-tracebug-prefix \"\\M-t\")
+
+The postfix keys are defined in `ess-tracebug-map':
+\\{ess-tracebug-map}"
+  :type '(choice (const nil) (string))
+  :group 'ess-tracebug)
+
+(defcustom ess-tracebug-search-path nil
+  "List of directories to search for source files.
+Elements should be directory names, not file names of directories."
+  :type '(choice (const :tag "Unset" nil)
+                 (repeat :tag "Directory list" (string :tag "Directory")))
+  :group 'ess-debug)
+
+(defvar ess-watch-buffer "*R watch*"
+  "Name of the watch buffer.")
+
+(defcustom ess-watch-height-threshold nil
+  "Minimum height for splitting *R* window sensibly to make space for watch window.
+See `split-height-threshold' for a detailed description.
+
+If nil, the value of `split-height-threshold' is used."
+  :group 'ess-debug
+  :type '(choice (const nil) (integer)))
+
+(defcustom ess-watch-width-threshold nil
+  "Minimum width for splitting *R* window sensibly to make space for watch window.
+See `split-width-threshold' for a detailed description.
+
+If nil, the value of `split-width-threshold' is used."
+  :group 'ess-debug
+  :type '(choice (const nil) (integer)))
+
+(defcustom  ess-watch-scale-amount -1
+  "The number of steps to scale the watch font down (up).
+Each step scales the height of the default face in the watch
+window by the variable `text-scale-mode-step' (a negative number
+of steps decreases the height by the same amount)"
+  :group 'ess-debug
+  :type 'integer)
+
+(defvar-local ess-watch-current-block-overlay nil
+  "The overlay for currently selected block in the R watch buffer .")
+
+(defcustom ess-inject-source 'function-and-buffer
+  "Control the source injection into evaluated code.
+
+If t,  always inject source reference.
+If function,  inject only for functions,
+If function-and-buffer, inject for functions and whole buffer (the default),
+If nil, never inject.
+
+When tracebug is active (the default), ESS instructs the
+subprocess to keep the source code references.
+
+If this variable is t, you won't be able to execute blocks which
+don't form a valid R expression. That is, if your expression
+spreads multiple paragraphs, and you call
+\\[ess-eval-region-or-function-or-paragraph-and-step] on first
+paragraph, R will report an error."
+  :group 'ess-tracebug
+  :type '(choice (const nil) (const function) (const function-and-buffer) (const t)))
+
+(defcustom ess-tracebug-enter-hook nil
+  "List of functions to call on entry to `ess-tracebug' mode.
+Use `add-hook' to insert append your functions to this list."
+  :group 'ess-tracebug
+  :type 'hook)
+
+(defcustom ess-tracebug-exit-hook nil
+  "List of functions to call on exit of `ess-tracebug' mode.
+Use `add-hook' to insert append your functions to this list."
+  :group 'ess-tracebug
+  :type 'hook)
+
+(defvaralias 'ess-tracebug-map 'ess-dev-map)
+
+(defvar ess--tracebug-eval-index 0
+  "This is used by to track source references in evaluation with source.
+For example, each time `ess-eval-function' is called the evaluated
+region is marked.  When debugger enters the code it displays
+this reference number. Ess-debug finds this number in the
+referenced buffer.")
+
+;; these vars are org variables that store the src block locations
+(defvar org-edit-src-beg-marker nil)
+(defvar org-babel-current-src-block-location nil
+  "Marker pointing to the src block currently being executed.
+This may also point to a call line or an inline code block.  If
+multiple blocks are being executed (e.g., in chained execution
+through use of the :var header argument) this marker points to
+the outer-most code block.")
+
+;; hash to store source references of the form: tmpname -> (filename . src_start)
+(defvar ess--srcrefs (make-hash-table :test 'equal :size 100))
+
+(defvar ess-tracebug-original-buffer-marker nil
+  "Marker pointing to the beginning of original source code.
+If non-nil, tracebug will insert the source references based on
+this location instead of the current buffer. This is useful for
+applications, like org-babel,  that call ess evaluation functions
+from temporary buffers.")
+
+(defun ess-tracebug-p ()
+  "Return non-nil if tracebug is running."
+  (ess-process-get 'tracebug))
+
+(defun ess-make-source-refd-command (beg end visibly process)
+  "Saves a region to a temporary file in order to add source references.
+BEG and END delimit the region. Returns a string containing an
+inferior process command for loading the temporary file.  This
+command conforms to VISIBLY."
+  (let* ((filename buffer-file-name)
+         (proc-dir (ess-get-process-variable 'default-directory))
+         (remote (when (file-remote-p proc-dir)
+                   (require 'tramp)
+                   ;; should this be done in process buffer?
+                   (tramp-dissect-file-name proc-dir)))
+         (orig-marker (or ess-tracebug-original-buffer-marker
+                          org-edit-src-beg-marker
+                          org-babel-current-src-block-location))
+         orig-beg)
+    (setq ess--tracebug-eval-index (1+ ess--tracebug-eval-index))
+    (goto-char beg)
+    (skip-chars-forward " \t\n")
+    (setq beg (point))
+    (goto-char end)
+    (skip-chars-backward " \t\n")
+    (setq end (point)
+          orig-beg beg)
+
+    ;; Delete all old temp files
+    (when (and (not (ess-process-get 'busy))
+               (< 1 (float-time
+                     (time-subtract (current-time)
+                                    (ess-process-get 'last-eval)))))
+      (dolist (f (ess-process-get 'temp-source-files))
+        (and (file-exists-p f)
+             (delete-file f)))
+      (ess-process-put 'temp-source-files nil))
+
+    (when (markerp orig-marker)
+      (setq filename (buffer-file-name (marker-buffer orig-marker)))
+      (setq orig-beg (+ beg (marker-position orig-marker))))
+
+    (let ((tmpfile
+           (expand-file-name (make-temp-name
+                              (concat (file-name-nondirectory
+                                       (or filename "unknown")) "!"))
+                             (if remote
+                                 (tramp-get-remote-tmpdir remote)
+                               temporary-file-directory))))
+
+      (ess-process-put 'temp-source-files
+                       (cons tmpfile (ess-process-get 'temp-source-files)))
+
+      (when remote
+        ;; Get local name (should this be done in process buffer?)
+        (setq tmpfile (with-parsed-tramp-file-name tmpfile nil localname)))
+
+      (if (not filename)
+          (puthash tmpfile (list nil ess--tracebug-eval-index nil) ess--srcrefs)
+        (puthash tmpfile (list filename ess--tracebug-eval-index orig-beg) ess--srcrefs)
+        (puthash (file-name-nondirectory tmpfile) ; R sometimes strips dirs
+                 (list filename ess--tracebug-eval-index orig-beg) ess--srcrefs)
+        (with-silent-modifications
+          (put-text-property beg end 'tb-index ess--tracebug-eval-index)))
+      (let ((string (ess-process-buffer-substring process beg end)))
+        (or
+         ;; Sending string to subprocess is considerably faster than tramp file
+         ;; transfer. So, give priority to `ess-eval-command' if available
+         (ess-build-eval-command string visibly t tmpfile)
+         ;; When no `ess-eval-command' available, use `ess-load-command'
+         (progn
+           (write-region beg end tmpfile nil 'silent)
+           (ess-build-load-command tmpfile visibly t)))))))
+
+(defun ess-process-buffer-substring (process start end)
+  (ess--run-presend-hooks process (buffer-substring-no-properties start end)))
+
+;; Declare globally so that the bytecode compiler let-binds it
+;; properly
+(defvar-local ess-r-evaluation-env nil)
+
+(defun ess-tracebug-send-region (process start end &optional visibly message type)
+  "Send region to process adding source references as specified
+by `ess-inject-source' variable."
+  ;; Disable evaluation env if we're sending a roxy region. This is
+  ;; not the ideal place to do this.
+  (let* ((se (ess-eval-region--normalise-region start end))
+         (start (car se))
+         (end (cdr se))
+         (ess-r-evaluation-env (unless (ess-roxy--region-p start end)
+                                 (ess-r-get-evaluation-env)))
+         (inject-p  (cond ((eq type 'function)
+                           ess-inject-source)
+                          ((eq type 'buffer)
+                           (or (eq ess-inject-source t)
+                               (eq ess-inject-source 'function-and-buffer)))
+                          ((eq ess-inject-source t))
+                          ;; We need to always inject with namespaced
+                          ;; evaluation (FIXME: not right place for
+                          ;; this).
+                          (ess-r-evaluation-env)))
+         (ess--dbg-del-empty-p (unless inject-p ess--dbg-del-empty-p))
+         (string (if inject-p
+                     (ess-make-source-refd-command start end visibly process)
+                   (ess-process-buffer-substring process start end)))
+         (message (if (fboundp ess-build-eval-message-function)
+                      (funcall ess-build-eval-message-function message)
+                    message)))
+    ;; Don't run the presend hooks twice.
+    (let ((ess--inhibit-presend-hooks t))
+      (process-put process :eval-visibly visibly)
+      ;; Visible evaluation is not nice when sourcing temporary files. You get
+      ;; .ess.eval(*code*) instead of *code*.
+      (setq visibly (unless inject-p visibly))
+      (ess-send-string process string visibly message))))
+
+(defun ess-tracebug-send-function (proc start end &optional visibly message)
+  "Like `ess-tracebug-send-region' but with tweaks for functions."
+  (ess-tracebug-send-region proc start end visibly message 'function))
+
+;; * Input Ring:
+
+;; i   . Goto input event marker forwards     . `ess-debug-goto-input-event-marker'
+;; I   . Goto input event marker backwards    . `ess-debug-goto-input-event-marker'
+
+
+(defun ess-tracebug-show-help ()
+  "Show help for `ess-tracebug'."
+  (interactive)
+  (if (fboundp 'describe-keymap)
+      (describe-keymap 'ess-tracebug-map)
+    (info "(ess) ESS tracebug")))
+
+(defun ess-tracebug--propertize (dummy bitmap face &optional string )
+  "If `window-system' propertize DUMMY with fringe BITMAP and FACE.
+Otherwise, propertize line-prefix and margin with STRING and FACE"
+  (unless string
+    (setq string dummy))
+  (if window-system
+      (propertize dummy 'display (list 'left-fringe bitmap face))
+    (propertize dummy
+                'display (list '(margin left-margin)
+                               (propertize string
+                                           'font-lock-face face
+                                           'face face)))))
+
+
+(defun ess-tracebug (&optional arg)
+  "Toggle `ess-tracebug' mode.
+With ARG, turn `ess-tracebug' mode on if and only if ARG is
+positive.
+
+This mode adds to ESS the interactive debugging, breakpoint and
+error navigation functionality.  Strictly speaking `ess-tracebug'
+is not a minor mode. It integrates globally into ESS and iESS.
+
+Note: Currently, `ess-tracebug' does not detect some of R's debug
+related messages in non-English locales. To set your R messages
+to English add the following line to your .Rprofile init file:
+
+   Sys.setlocale(\"LC_MESSAGES\", \"C\")
+
+
+See `ess-tracebug-help' for the overview of ess-tracebug functionality."
+
+  ;; Note: The functionality in ess-tracebug is divided on conceptual
+  ;; grounds in tracing and debugging and could be
+  ;; activated/deactivate separately with `ess--tb-start' and
+  ;; `ess-debug-start' respectively.
+
+  (interactive "P")
+  (ess-force-buffer-current "R process to activate tracebug in: ")
+  (with-current-buffer (process-buffer (get-process ess-local-process-name))
+    (when (equal ess-dialect "R")
+      (setq arg
+            (if arg
+                (prefix-numeric-value arg)
+              (if (ess-process-get 'tracebug) -1 1)))
+      (if (> arg 0)
+          (unless (ess-process-get 'tracebug) ;; only if not already active
+            (ess--tb-start)
+            (ess-debug-start)
+            ;; (dolist (bf (buffer-list))
+            ;;   (with-current-buffer bf
+            ;;     (when (and (eq major-mode 'ess-mode)
+            ;;                (equal ess-dialect "R"))
+            ;;       (ess-bp-recreate-all))))
+            ;; watch functionality
+            (if ess-tracebug-prefix
+                (let ((comm (key-binding ess-tracebug-prefix)))
+                  ;; (message "ess-tracebug-prefix will be removed in future versions. Electric debug keys are now on [C-c] and [C-c C-t] maps.")
+                  ;; (sit-for 1)
+                  (when (commandp comm)
+                    (define-key ess-tracebug-map ess-tracebug-prefix comm))
+                  (define-key ess-mode-map ess-tracebug-prefix ess-tracebug-map)
+                  (define-key inferior-ess-mode-map ess-tracebug-prefix ess-tracebug-map)
+                  (define-key ess-watch-mode-map ess-tracebug-prefix ess-tracebug-map)))
+            (run-hooks 'ess-tracebug-enter-hook)
+            (ess-process-put 'tracebug t)
+            (message "ess-tracebug mode enabled"))
+        (when (ess-process-get 'tracebug) ;;only when active
+          (ess-process-put  'tracebug nil)
+          ;; unset the map
+          (when ess-tracebug-prefix
+            (define-key ess-mode-map ess-tracebug-prefix nil)
+            (define-key inferior-ess-mode-map ess-tracebug-prefix nil))
+          (ess--tb-stop)
+          (ess-debug-stop)
+          (run-hooks 'ess-tracebug-exit-hook)
+          (message "ess-tracebug mode disabled"))))))
+
+(defalias 'ess-toggle-tracebug #'ess-tracebug)
+
+
+;;;_* TRACEBACK
+
+;; (defface ess--tb-last-input-face
+;;   '((((class grayscale)
+;;       (background light)) (:background "DimGray"))
+;;     (((class grayscale)
+;;       (background dark))  (:background "LightGray"))
+;;     (((class color) (background light) (min-colors 88))
+;;      (:overline "medium blue" ))
+;;     (((class color) (background dark) (min-colors 88))
+;;      (:overline "deep sky blue" ))
+;;     (((background light))  (:weight bold))
+;;     (((background dark)) (:weight bold))
+;;     )
+;;   "Face to highlight currently debugged line."
+;;   :group 'ess-tracebug )
+
+(defface ess-tracebug-last-input-fringe-face
+  '((((background light) (min-colors 88)) (:foreground "medium blue" :overline "medium blue"))
+    (((background dark) (min-colors 88))  (:foreground "deep sky blue" :overline "deep sky blue"))
+    (((background light) (min-colors 8))  (:foreground "blue"))
+    (((background dark) (min-colors 8))  (:foreground "cyan")))
+  "Face for fringe bitmap for last-input position."
+  :group 'ess-tracebug)
+
+(if (fboundp 'define-fringe-bitmap)
+    (define-fringe-bitmap 'last-input-arrow
+      [#b00011111
+       #b00010000
+       #b00010000
+       #b00010000
+       #b00010000
+       #b00010000
+       #b00010000
+       #b00010000
+       #b00010000
+       #b00010000
+       #b11010111
+       #b01111100
+       #b00111000
+       #b00010000] nil nil 'top))
+
+
+(defvar ess--tb-last-input (make-marker)
+  "Marker pointing to the last user input position in iESS buffer.
+This is the place where `ess--tb-last-input-overlay' is moved.
+Local in iESS buffers with `ess-tracebug' mode enabled.")
+
+(defvar ess--tb-last-input-overlay nil
+  "Overlay to highlight the position of last input in iESS buffer.
+Local in iESS buffers.")
+
+(defvar-local ess--busy-count 0
+  "Used to compute the busy indicator.")
+
+;; (unless (boundp 'ess--busy-slash)
+;; (defvar ess--busy-slash '(32 ?\u2014 92 47))
+;; (setq ess--busy-slash (mapcar (lambda (el) (format " %c " el))
+;;                               ess--busy-slash))
+;; )
+
+
+(defvar ess--busy-slash '("   " " - " " \\ " " / "))
+(defvar ess--busy-B '("   " " B " "   "))
+(defvar ess--busy-stars '("      " "      " " *    " " **   " " ***  " " **** "))
+(defvar ess--busy-vbars '("      " "      " " |    " " ||   " " |||  " " |||| "))
+
+(defcustom ess-busy-strings ess--busy-slash
+  "List of strings to replace in turn for busy indication.
+The first element of the list is used as an indicator of the
+process being ready (i.e. not busy). Implemented lists that you
+can use `ess--busy-slash', `ess--busy-B',`ess--busy-stars',
+`ess--busy-vbars'"
+  :group 'ess
+  :type '(repeat string))
+
+(defvar ess--busy-timer nil
+  "Timer used for busy process indication.")
+
+(defcustom inferior-ess-fix-misaligned-output nil
+  "If non-nil, try to correct misaligned process output."
+  :group 'ess-tracebug
+  :type 'boolean)
+
+(defcustom inferior-ess-replace-long+ t
+  "Determines if ESS replaces long + sequences in output.
+If \\='strip, remove all such instances.  Otherwise, if non-nil, `+
++ + + ' containing 3 or more + is replaced by
+`ess-long+replacement'.
+This variable can be process-local but not buffer-local."
+  :group 'ess-tracebug
+  :type '(choice (const :tag "No replacement" nil)
+                 (const :tag "Replace all" strip)
+                 (const :tag "Replace 3 or more +" t)))
+
+(defvar ess-long+replacement ". + "
+  "Replacement used for long + prompt.
+Please don't customize this or other prompt related variables.
+ESS internal code assumes default R prompts.")
+
+(defmacro ess-copy-key (from-map to-map fun)
+  `(define-key ,to-map
+     (car (where-is-internal ,fun  ,from-map))
+     ,fun))
+
+;;;_ + traceback functions
+(defun ess--tb-make-last-input-overlay (beg end)
+  "Create an overlay to indicate the last input position."
+  (let   ((ove (make-overlay beg end)))
+    (overlay-put ove 'before-string
+                 (ess-tracebug--propertize "!"  'last-input-arrow 'ess-tracebug-last-input-fringe-face))
+    ;; (overlay-put ove 'face  'ess--tb-last-input-face)
+    (overlay-put ove 'evaporate t)
+    ove))
+
+
+(defun ess--tb-start ()
+  "Start traceback session."
+  (with-current-buffer (process-buffer (get-process ess-local-process-name))
+    (unless ess-error-regexp-alist
+      (error "Can not activate the traceback for %s dialect" ess-dialect))
+    (setq-local compilation-error-regexp-alist ess-error-regexp-alist)
+    (let (compilation-mode-font-lock-keywords)
+      (compilation-setup t))
+    (setq next-error-function #'ess-tracebug-next-error-function)
+    ;; new locals
+    (make-local-variable 'ess--tb-last-input)
+    (make-local-variable 'ess--tb-last-input-overlay)
+    (make-local-variable 'compilation-search-path)
+    (setq compilation-search-path ess-tracebug-search-path) ;; TODO: make this dialect specific
+    (ess-tracebug--set-left-margin)
+    (save-excursion
+      (goto-char comint-last-input-start)
+      (setq ess--tb-last-input (point))
+      (setq ess--tb-last-input-overlay
+            (ess--tb-make-last-input-overlay
+             (line-beginning-position) (line-end-position))))
+    ;; busy timer
+    (setq mode-line-buffer-identification
+          (list (car (propertized-buffer-identification "%3b"))
+                `(:eval  (nth ess--busy-count ess-busy-strings)))) ;; 'face 'mode-line-buffer-id))))
+    (make-local-variable 'ess--busy-timer)
+    (setq ess--busy-timer
+          (run-with-timer 2 .5 (ess--make-busy-timer-function (get-buffer-process (current-buffer)))))
+    (add-hook 'kill-buffer-hook (lambda () (when ess--busy-timer (cancel-timer ess--busy-timer))))
+    (add-hook 'comint-input-filter-functions #'ess-tracebug-set-last-input nil 'local)
+
+    ;; redefine
+    ;; TODO: all this part should go (partially gone now)
+    (advice-add 'ess-parse-errors :override #'next-error)))
+
+(defun ess--tb-stop ()
+  "Stop ess traceback session in the current ess process."
+  (with-current-buffer (process-buffer (get-process ess-current-process-name))
+    ;; restore original definitions
+    (when (equal ess-dialect "R")
+      (advice-remove 'ess-parse-errors #'next-error))
+    (if (local-variable-p 'ess--tb-last-input-overlay)
+        (delete-overlay ess--tb-last-input-overlay))
+    (kill-local-variable 'ess--tb-last-input-overlay)
+    (kill-local-variable 'ess--tb-last-input)
+    (font-lock-remove-keywords nil (compilation-mode-font-lock-keywords))
+    (font-lock-ensure)
+    (kill-local-variable 'compilation-error-regexp-alist)
+    (kill-local-variable 'compilation-search-path)
+    (cancel-timer ess--busy-timer)
+    (remove-hook 'comint-input-filter-functions #'ess-tracebug-set-last-input 'local)
+    (setq mode-line-buffer-identification (propertized-buffer-identification "%12b"))))
+
+(defvar ess--dbg-forward-ring (make-ring 10)
+  "Ring of markers to the positions of user inputs when the
+debugger or traceback events are initiated. It is used in
+`ess--dbg-goto-input-point'.")
+
+(defvar ess--dbg-backward-ring (make-ring 10)
+  "Ring of markers for the positions from `ess--dbg-goto-input-point'.
+Marks the position from which it was called. See also
+`ess--dbg-goto-debug-point'")
+
+;; (setq ess-R--tb-regexp-alist '(R R2 R3 R-recover))
+;;(pop compilation-error-regexp-alist-alist)
+
+(defun ess-show-traceback ()
+  "Display R traceback and last error message.
+Pop up a compilation/grep/occur like buffer. Usual global key
+bindings are available (\\[next-error] and \\[previous-error])
+for `next-error' and `previous-error' respectively.
+
+You can bind `no-select' versions of this commands:
+\(define-key compilation-minor-mode-map [(?n)] #\\='next-error-no-select)
+\(define-key compilation-minor-mode-map [(?p)] #\\='previous-error-no-select)"
+  (interactive)
+  (cl-assert ess-traceback-command nil
+             "Not implemented for dialect %s" ess-dialect)
+  (ring-insert ess--dbg-forward-ring (point-marker))
+  (ess-force-buffer-current "R process to use: ")
+  (let ((trbuf (get-buffer-create "*ess-traceback*"))
+        (lproc-name ess-local-process-name)
+        (alist ess-mode-editing-alist)
+        (cmd ess-traceback-command)
+        (inhibit-read-only t))
+    (setq next-error-last-buffer trbuf)
+    (with-current-buffer trbuf
+      (setq ess-local-process-name lproc-name)
+      (ess-command cmd trbuf)
+      (goto-char (point-min))
+      ;; fixme: this is R specific check
+      (cl-assert (not (re-search-forward "No traceback available" nil t)) nil
+                 "No traceback available")
+      (ess-dirs)
+      (when (boundp 'ess-r-error-regexp-alist)
+        (setq-local compilation-error-regexp-alist ess-r-error-regexp-alist))
+      (setq-local compilation-search-path ess-tracebug-search-path)
+      (ess-setq-vars-local alist)
+      (font-lock-refresh-defaults)
+      (compilation-minor-mode 1)
+      (setq next-error-function #'ess-tracebug-next-error-function)
+      (setq buffer-read-only t)
+      (pop-to-buffer trbuf))))
+
+(defvar ess-call-stack-command nil)
+(defun ess-show-call-stack ()
+  "Display current call stack.
+Also see `ess-show-traceback'"
+  (interactive)
+  (let ((ess-traceback-command ess-call-stack-command))
+    (ess-show-traceback)))
+
+(defalias 'ess-show-R-traceback #'ess-show-traceback)
+
+(defun ess--tb-next-error-goto-process-marker ()
+  ;; assumes current buffer is the process buffer with compilation enabled
+  ;; used in ess-tracebug-next-error-function
+                                        ;  (with-current-buffer (process-buffer (get-process ess-local-process-name)) ; already in comint buffer .. no need
+  (comint-goto-process-mark)
+  (set-window-point (get-buffer-window) (point))  ;moves the cursor
+  ;; FIXME: Should jump to current-debug-position,  but messes the things if in recover
+  ;; (when (ess-debug-is-active)
+  ;;   (ess-debug-goto-current-debug-position)
+  ;;   )
+  )
+
+(defun ess-tracebug-next-error-function (n &optional reset)
+  "Advance to the next error message and visits the file.
+This is the value of `next-error-function' in iESS buffers."
+  ;; Modified version of `compilation-next-error-function'.
+  (interactive "p")
+  (if reset  (goto-char (point-max)))
+  (let* (;; (columns compilation-error-screen-columns) ; buffer's local value
+         ;; (proc (or (get-buffer-process (current-buffer))
+         ;;                         (error "Current buffer has no process")))
+         (pbuff-p (get-buffer-process (current-buffer)))
+         (n (or n 1))
+         (beg-pos  ; from where the search for next error starts
+          (if (and pbuff-p
+                   (>= n 0)
+                   (comint-after-pmark-p))
+              ess--tb-last-input
+            (point)))
+         (at-error t)
+         (msg
+          (condition-case nil
+              (compilation-next-error n nil beg-pos)
+            (error
+             (when pbuff-p
+               (ess--tb-next-error-goto-process-marker))
+             (if (< n 0)
+                 (message "Before first reference")
+               (message "Beyond last reference"));(error-message-string err))
+             (setq at-error nil))))
+         (msg (if (or (not pbuff-p)
+                      (eq n 0)
+                      (> (point) ess--tb-last-input))
+                  msg
+                (ess--tb-next-error-goto-process-marker)
+                (message "Beyond last-input marker")
+                (setq at-error nil)))
+         (marker (point-marker))
+         loc)
+    (when at-error
+      (setq compilation-current-error (point-marker)
+            overlay-arrow-position (if (bolp)
+                                       compilation-current-error
+                                     (copy-marker (line-beginning-position)))
+            loc (if (fboundp 'compilation--message->loc)
+                    (compilation--message->loc msg)
+                  (car msg)))
+      (let* ((file (caar (nth 2 loc)))
+             (col (car loc))
+             (line (cadr loc))
+             (mkrs (ess--dbg-create-ref-marker file line col)))
+        (if mkrs
+            ;; is this really needed? Shall we go directly to the location?
+            (compilation-goto-locus marker (car mkrs) (cadr mkrs))
+          (message "Reference to '%s' not found" file))))))
+
+
+(defun inferior-ess-move-last-input-overlay ()
+  "Move the overlay to the point."
+  (let ((pbol (line-beginning-position)))
+    (move-overlay ess--tb-last-input-overlay
+                  pbol (max (- (point) 2) (+ pbol 2)))))
+
+
+;;;_* DEBUGGER
+(defgroup ess-debug nil
+  "Debugging for ESS"
+  :link '(emacs-library-link :tag "Source Lisp File" "ess-tracebug.el")
+  :group 'ess-tracebug
+  :prefix "ess-debug-")
+
+(defcustom  ess-debug-error-action-alist
+  '(( ""   "NONE"       "NULL" )
+    ( " r" "RECOVER"    "utils::recover")
+    ( " t" "TRACEBACK"  "base::traceback"))
+  "Alist of `on-error' actions.
+Toggled with `ess-debug-toggle-error-action'.  Each element must
+have the form (DISP SYMB ACTION) where DISP is the string to be
+displayed in the mode line when the action is in place. SYMB is
+the symbolic name of an action. ACTION is the string giving the
+actual expression to be assigned to `error' user option. See R's
+help ?options for more details."
+  :type '(alist :key-type string
+                :value-type (group string string))
+  :group 'ess-debug)
+
+(defvar ess--dbg-output-buf-prefix " *ess.dbg"
+  "The prefix of the buffer name the R debug output is directed to."  )
+
+(defvar-local ess--dbg-current-ref (make-marker)
+  "Current debug reference in *ess.dbg* buffers (a marker).")
+
+(defvar-local ess--dbg-last-ref-marker (make-marker)
+  "Last debug reference in *ess.dbg* buffer (a marker).")
+
+(defvar-local ess--dbg-buf-p nil
+  "This is t in ess.dbg buffers.")
+
+;; (defcustom ess--dbg-auto-single-key-p t
+;;   "If t entering the debug state triggers single-key mode.
+;; Set it to nil if you want to trigger single-key mode manually
+;; with the `ess-tracebug-prefix' key.
+;; ")
+
+(defvar ess--dbg-current-debug-position (make-marker)
+  "Marker to the current debugged line.
+It always point to the beginning of the currently debugged line
+and is used by overlay-arrow.
+In no-windowed Emacs an `overlay-arrow' is displayed at this position.")
+
+(unless  window-system
+  (add-to-list 'overlay-arrow-variable-list 'ess--dbg-current-debug-position))
+
+(defface ess-debug-current-debug-line-face
+  '((default (:inherit highlight)))
+  "Face used to highlight currently debugged line."
+  :group 'ess-debug)
+
+
+(defvar  ess--dbg-current-debug-overlay
+  (let ((overlay (make-overlay (point) (point))))
+    (overlay-put overlay 'face  'ess-debug-current-debug-line-face)
+    (overlay-put overlay 'evaporate t)
+    overlay)
+  ;; should be global variable!!
+  "The overlay for currently debugged line.")
+
+
+(defcustom ess-debug-blink-interval .2
+  "Time in seconds to blink the background of the debug line.
+Currently two events are defined `ref-not-found' and `same-ref'.
+Blinking colors for these events can be customized by
+corresponding faces."
+  :group 'ess-debug
+  :type 'float)
+
+(defface ess-debug-blink-ref-not-found-face
+  '((((class grayscale) (background light)) (:background "DimGray"))
+    (((class grayscale) (background dark))  (:background "LightGray"))
+    (((class color) (background light) (min-colors 88)) (:background "IndianRed4"))
+    (((class color) (background dark) (min-colors 88))  (:background "dark red"))
+    (((background light) (min-colors 8))  (:foreground "red"))
+    (((background dark) (min-colors 8))  (:foreground "red")))
+  "Face used to blink currently debugged line's background
+ when the reference file is not found. See also `ess-debug-ask-for-file'"
+  :group 'ess-debug )
+
+(defface ess-debug-blink-same-ref-face
+  '((((class grayscale) (background light)) (:background "DimGray"))
+    (((class grayscale) (background dark))  (:background "LightGray"))
+    (((class color) (background light) (min-colors 88)) (:background "steel blue"))
+    (((class color) (background dark) (min-colors 88))  (:background "midnight blue"))
+    (((background light) (min-colors 8))  (:foreground "blue"))
+    (((background dark) (min-colors 8))  (:foreground "cyan")))
+  "Face used to highlight currently debugged line when new debug
+reference is the same as the preceding one. It is highlighted for
+`ess-debug-blink-interval' seconds."
+  :group 'ess-debug )
+
+(defcustom ess-debug-ask-for-file nil
+  "If non nil, ask for file if the current debug reference is not found.
+
+If nil, the currently debugged line is highlighted for
+`ess-debug-blink-interval' seconds."
+  :group 'ess-debug
+  :type 'boolean)
+
+(defcustom ess-debug-skip-first-call t
+  "If non-nil, skip first debugger call.
+
+In R first call doesn't contain source references and is skipped
+by default."
+  :group 'ess-debug
+  :type 'boolean)
+
+(defvar ess-electric-selection-map
+  (let (ess-electric-selection-map)
+    (define-prefix-command 'ess-electric-selection-map)
+    ;; command-c and command-Q are not always working reliably
+    (define-key ess-electric-selection-map "\M-N" #'ess-debug-command-continue)
+    (define-key ess-electric-selection-map "\M-C" #'ess-debug-command-continue)
+    (define-key ess-electric-selection-map "\M-Q" #'ess-debug-command-quit)
+    (define-key ess-electric-selection-map "0" #'ess-debug-command-digit)
+    (define-key ess-electric-selection-map "1" #'ess-debug-command-digit)
+    (define-key ess-electric-selection-map "2" #'ess-debug-command-digit)
+    (define-key ess-electric-selection-map "3" #'ess-debug-command-digit)
+    (define-key ess-electric-selection-map "4" #'ess-debug-command-digit)
+    (define-key ess-electric-selection-map "5" #'ess-debug-command-digit)
+    (define-key ess-electric-selection-map "6" #'ess-debug-command-digit)
+    (define-key ess-electric-selection-map "7" #'ess-debug-command-digit)
+    (define-key ess-electric-selection-map "8" #'ess-debug-command-digit)
+    (define-key ess-electric-selection-map "9" #'ess-debug-command-digit)
+    (define-key ess-electric-selection-map "?" #'ess-tracebug-show-help)
+    ess-electric-selection-map)
+  "Keymap used to define commands for single key input mode.
+This commands are triggered by `ess-electric-selection' .
+
+\\{ess-electric-selection-map}")
+
+;;;_ + debug functions
+(defun ess-debug-set-error-action (spec)
+  "Set the on-error action.
+The SPEC should be one of the components of
+`ess-debug-error-action-alist'."
+  (let ((proc (get-process ess-local-process-name)))
+    (if spec
+        (with-current-buffer (process-buffer proc)
+          (process-put proc 'on-error-action (car spec))
+          (ess-command (format "options(error= %s )\n" (nth 2 spec))))
+      (error "Unknown action"))))
+
+(defun ess-debug-toggle-error-action ()
+  "Toggle the `on-error' action.
+The action list is in `ess-debug-error-action-alist'."
+  (interactive)
+  (ess-force-buffer-current)
+  (let* ((ev last-command-event)
+         (com-char  (event-basic-type ev))
+         (cur-action (or (ess-process-get 'on-error-action) ""))
+         actions act)
+    (setq actions
+          (cdr (member (assoc cur-action ess-debug-error-action-alist)
+                       ess-debug-error-action-alist)))
+    (unless actions
+      (setq actions ess-debug-error-action-alist))
+    (setq act (pop actions))
+    (ess-debug-set-error-action act)
+    (message "On-error action set to: %s"
+             (propertize (cadr act) 'face 'font-lock-function-name-face))
+    (while  (eq (event-basic-type (setq ev (read-event))) com-char)
+      (unless actions
+        (setq actions ess-debug-error-action-alist))
+      (setq act (pop actions))
+      (ess-debug-set-error-action act)
+      (force-mode-line-update)
+      (message "On-error action set to: %s"
+               (propertize (cadr act) 'face 'font-lock-function-name-face)))
+    (push ev unread-command-events)))
+
+(defun ess--dbg-activate-overlays ()
+  "Initialize active debug line overlays."
+  (move-overlay ess--dbg-current-debug-overlay
+                (line-beginning-position) (1+ (line-end-position)))
+  ;; used by overlay-arrow functionality on no-X,  should be bol
+  (move-marker ess--dbg-current-debug-position (line-beginning-position)))
+
+(defun ess--dbg-deactivate-overlays ()
+  "Delete debugger markers and overlays.
+Overlay arrow remains to indicate the last debug position."
+  (delete-overlay ess--dbg-current-debug-overlay)
+  (set-marker ess--dbg-current-debug-position nil))
+
+
+;;;_ + Work Flow
+(defun ess-debug-goto-input-event-marker ()
+  "Jump to the point where the last debugger/traceback etc event occurred.
+
+   Mainly useful during/after debugging, to jump to the place
+from where the code was initially executed.  This is an
+electric-command, which means that after the command is triggered a
+single key event is enough to navigate through the input-event-S-ring.
+If the key-event which triggered the command is Shift modified
+the input-event-S-ring is traversed backwards.
+
+The input-event-S-ring is a virtual object which consists of two
+rings `ess--dbg-forward-ring' and `ess--dbg-backward-ring' which
+are joint at their tops.
+
+See the more info at https://code.google.com/p/ess-tracebug/#Work-Flow"
+  (interactive)
+  (let* ((ev last-command-event)
+         (com-char  (event-basic-type ev))
+         (ring-el 0)
+         input-point)
+    (if (memq 'shift (event-modifiers ev))
+        (setq input-point (ring-ref ess--dbg-backward-ring 0))
+      (ring-insert ess--dbg-backward-ring (point-marker)) ;; insert in backward ring ;;TODO: check if the marker to this (close by?) position is already in the ring
+      (setq input-point (ring-ref ess--dbg-forward-ring 0)))
+    (when (marker-buffer input-point) ;; TODO: give a message here if buff is not found
+      (pop-to-buffer-same-window (marker-buffer input-point))
+      (when (marker-position input-point)
+        (goto-char (marker-position input-point))))
+    (while  (eq (event-basic-type  (event-basic-type (setq ev (read-event)))) com-char)
+      (if (memq 'shift (event-modifiers ev))
+          (setq ring-el (1- ring-el))
+        (setq ring-el (1+ ring-el)))
+      (if (< ring-el 0)
+          (setq input-point (ring-ref ess--dbg-backward-ring (- ring-el)))  ;; get it from backward-ring
+        ;; get it from forward-ring
+        (setq input-point (ring-ref ess--dbg-forward-ring ring-el)) )
+      (when (marker-buffer input-point)
+        (pop-to-buffer-same-window (marker-buffer input-point))
+        (when (marker-position input-point)
+          (goto-char (marker-position input-point)))))
+    (push ev unread-command-events)))
+
+(defun ess-debug-goto-debug-point ()
+  "Return to the debugging position.
+Jump to markers stored in `ess--dbg-backward-ring'. If debug
+session is active, first jump to current debug line.
+
+This is an electric-command. Shift triggers the opposite traverse
+of the ring."
+  (interactive)
+  (let* ((debug-point (ring-ref ess--dbg-backward-ring 0))
+         (ev last-command-event)
+         (com-char  (event-basic-type ev))
+         (ring-el 0))
+    (if (ess--dbg-is-active-p)
+        (progn
+          (pop-to-buffer-same-window (marker-buffer ess--dbg-current-debug-position))
+          (goto-char (marker-position ess--dbg-current-debug-position ))
+          (back-to-indentation))
+      (pop-to-buffer-same-window (marker-buffer debug-point))
+      (goto-char (marker-position debug-point)))
+    (while  (eq (event-basic-type (setq ev (read-event))) com-char)
+      (if (memq 'shift (event-modifiers ev))
+          (setq ring-el (1- ring-el))
+        (setq ring-el (1+ ring-el)))
+      (setq debug-point (ring-ref ess--dbg-backward-ring ring-el))
+      (when (marker-buffer debug-point)
+        (pop-to-buffer-same-window (marker-buffer debug-point))
+        (when (marker-position debug-point)
+          (goto-char (marker-position debug-point)))))
+    (push ev unread-command-events)))
+
+(defun ess-debug-insert-in-forward-ring ()
+  "Insert `point-marker' into the forward-ring."
+  (interactive)
+  (ring-insert ess--dbg-forward-ring (point-marker))
+  (message "Point inserted into the forward-ring"))
+
+(defvar ess-debug-indicator " DB"
+  "String to be displayed in mode-line alongside the process name.
+Indicates that ess-debug-mode is turned on. When the debugger is
+in active state this string is shown in upper case and
+highlighted.")
+
+(defvar-local ess--dbg-mode-line-debug
+  '(:eval (let ((proc (get-process ess-local-process-name)))
+            (if (and proc (process-get proc 'dbg-active))
+                (let ((str ess-debug-indicator))
+                  (ess-debug-minor-mode 1) ; activate the keymap
+                  (put-text-property 1 (length str)
+                                     'face '(:foreground "white" :background "red")
+                                     str)
+                  str)
+              (ess-debug-minor-mode -1)
+              ""))))
+(put 'ess--dbg-mode-line-debug 'risky-local-variable t)
+
+(defvar-local ess--dbg-mode-line-error-action
+  '(:eval (or (and (ess-process-live-p)
+                   (ess-process-get 'on-error-action))
+              "")))
+(put 'ess--dbg-mode-line-error-action 'risky-local-variable t)
+
+(defun ess--dbg-remove-empty-lines (string)
+  "Remove empty lines from STRING (which interfere with evals) during debug.
+This function is placed in `ess-presend-filter-functions'."
+  (if (and ess--dbg-del-empty-p (ess-process-get 'dbg-active))
+      (replace-regexp-in-string "\n\\s *$" "" string)
+    string))
+
+
+(defun ess-debug-start ()
+  "Start the debug session.
+Add to ESS the interactive debugging functionality, breakpoints,
+watch and loggers.  Integrates into ESS and iESS modes by binding
+`ess-tracebug-map' to `ess-tracebug-prefix' in
+`ess-mode-map' and `inferior-ess-mode-map' respectively."
+  (interactive)
+  (let ((dbuff (get-buffer-create (concat ess--dbg-output-buf-prefix "." ess-current-process-name "*"))) ;TODO: make dbuff a string!
+        (proc (ess-get-process ess-local-process-name))
+        (lpn ess-local-process-name))
+    (process-put proc 'dbg-buffer dbuff); buffer were the look up takes place
+    (process-put proc 'dbg-active nil)  ; t if the process is in active debug state.
+                                        ; Active debug states are usually those, in which prompt start with Browser[d]>
+    (set-process-filter proc #'inferior-ess-tracebug-output-filter)
+    (with-current-buffer (process-buffer proc)
+      (unless (equal ess-dialect "R")
+        (error "Can not activate the debugger for %s dialect" ess-dialect))
+      (add-to-list 'ess--mode-line-process-indicator 'ess--dbg-mode-line-debug t)
+      (add-to-list 'ess--mode-line-process-indicator 'ess--dbg-mode-line-error-action t)
+
+      (add-hook 'ess-presend-filter-functions #'ess--dbg-remove-empty-lines nil 'local))
+    (with-current-buffer dbuff
+      (setq ess-local-process-name lpn)
+      (buffer-disable-undo)
+      ;; (setq buffer-read-only nil)
+      (make-local-variable 'overlay-arrow-position) ;; indicator for next-error functionality in the *ess.dbg*,  useful??
+      (goto-char (point-max))
+      (setq ess--dbg-buf-p t  ;; true if in  *ess.dbg* buffer
+            ess--dbg-current-ref (point-marker)  ;; used by goto-error functionality
+            ess--dbg-last-ref-marker (point-marker)  ;; gives marker to reference of the last debugged line
+            )
+      ;;      (beginning-of-line)
+      ;; (setq buffer-read-only t)
+      )))
+
+(defun ess-debug-stop ()
+  "End the debug session.
+Kill the *ess.dbg.[R_name]* buffer."
+  ;;; process plist is not removed, TODO?low priority
+  (interactive)
+  (let ((proc (get-process ess-current-process-name))) ;;local?
+    (with-current-buffer (process-buffer proc)
+      (if (member ess-dialect '("XLS" "SAS" "STA"))
+          (error "Can not deactivate the debugger for %s dialect" ess-dialect))
+      (delq 'ess--dbg-mode-line-debug ess--mode-line-process-indicator)
+      (delq 'ess--dbg-mode-line-error-action ess--mode-line-process-indicator)
+      (remove-hook 'ess-presend-filter-functions #'ess--dbg-remove-empty-lines 'local))
+    (set-process-filter proc #'inferior-ess-output-filter)
+    (kill-buffer (process-get proc 'dbg-buffer))
+    (process-put proc 'dbg-buffer nil)
+    (process-put proc 'dbg-active nil)
+    ;; (when (buffer-live-p ess--dbg-buffer)
+    ;;   ;; (with-current-buffer ess--dbg-buffer
+    ;;   ;;   (set-buffer-modified-p nil)
+    ;;   ;;   )
+    ;;   (kill-buffer ess--dbg-buffer)
+    ;;   )
+    ))
+
+
+(defun ess--make-busy-timer-function (process)
+  "Display the spinner of prompt if PROCESS is busy."
+  `(lambda ()
+     (let ((pb ,process))
+       (when (eq (process-status pb) 'run) ;; only when the process is alive
+         (with-current-buffer (process-buffer pb)
+           (if (not (process-get pb 'busy)) ;; if ready
+               (when (> ess--busy-count 0)
+                 (setq ess--busy-count 0)
+                 (force-mode-line-update)
+                 (redisplay))
+             (setq ess--busy-count (1+ (mod  ess--busy-count  (1- (length ess-busy-strings)))))
+             (force-mode-line-update)
+             (redisplay)))))))
+
+;; (ess--make-busy-prompt-function (get-process "R"))
+
+(defun ess--dbg-is-active-p ()
+  "Return t if the current R process is in active debugging state."
+  (and (ess-process-live-p)
+       (ess-process-get  'dbg-active)))
+
+(defun ess--dbg-is-recover-p ()
+  "Return t if the current R process is in active debugging state."
+  (and (ess-process-live-p)
+       (ess-process-get  'is-recover)))
+
+(defun ess-debug-active-p (&optional proc)
+  (and (ess-process-live-p proc)
+       (or (ess-process-get 'dbg-active proc)
+           (ess-process-get 'is-recover proc))))
+
+(defvar ess--dbg-regexp-reference "debug \\w+ +\\(.+\\)#\\([0-9]+\\):")
+(defvar ess--dbg-regexp-jump "debug \\w+ ") ;; debug at ,debug bei ,etc
+(defvar ess--dbg-regexp-skip
+  ;; don't anchor to bol; secondary prompt can occur before (anything else?)
+  ;; "\\(\\(?:Called from: \\)\\|\\(?:debugging in: \\)\\|\\(?:#[0-9]*: +recover()\\)\\)")
+  "\\(\\(?:Called from: \\)\\|\\(?:#[0-9]*: +recover()\\)\\)")
+
+(defvar ess--dbg-regexp-no-skip
+  ;; exceptions for first skip (magrittr)
+  "debug_pipe")
+
+(defvar ess--dbg-regexp-debug  "\\(\\(?:Browse[][0-9]+\\)\\|\\(?:debug: \\)\\)")
+(defvar ess--dbg-regexp-selection "\\(Selection: \\'\\)")
+(defvar ess--dbg-regexp-input (concat ess--dbg-regexp-debug "\\|"
+                                      ess--dbg-regexp-selection))
+
+(defvar ess--suppress-next-output? nil)
+
+
+\f
+;;; MPI
+
+;; http://jkorpela.fi/chars/c0.html
+;; https://en.wikipedia.org/wiki/ANSI_escape_code#Escape_sequences
+(defvar ess-mpi-message-start-delimiter "\e_")
+(defvar ess-mpi-message-field-separator "\1e")
+(defvar ess-mpi-message-end-delimiter "\e\\")
+
+(define-obsolete-variable-alias 'ess-mpi-alist 'ess-mpi-handlers "ESS 19.04")
+(defvar ess-mpi-handlers
+  '(("message" . ess-mpi:message)
+    ("error"   . ess-mpi:error)
+    ("eval"    . ess-mpi:eval)
+    ("y-or-n"  . ess-mpi:y-or-n))
+  "Alist of the MPI handlers.
+Each element is of the form (TYPE . HANDLER), where TYPE is the
+message type and HANDLER is a function (symbol) to be called on
+the payload list of each message.")
+
+(defun ess-mpi:message (msg)
+  (message "%s" msg))
+
+(defun ess-mpi:error (msg)
+  (error "MPI error: %s" msg))
+
+(defun ess-mpi:eval (str &optional callback)
+  "Read STR and evaluate as Emacs expression.
+If present, the CALLBACK string is passed through `format' with
+returned value from EXPR and then sent to the subprocess."
+  (let ((result (eval (read str) t)))
+    (when callback
+      (ess-send-string (ess-get-process) (format callback result)))))
+
+(defun ess-mpi:y-or-n (prompt callback)
+  "Ask `y-or-n-p' with PROMPT.
+The CALLBACK string is passed through `format' with returned
+value from EXPR and then sent to the subprocess."
+  (let ((result (y-or-n-p prompt)))
+    (when callback
+      (let ((result (if result "TRUE" "FALSE")))
+        (ess-send-string (ess-get-process) (format callback result))))))
+
+(defun ess-mpi-convert (el)
+  (cond
+   ((string= el "nil") nil)
+   ((string= el "t") t)
+   (t el)))
+
+(defun ess-mpi-handle-messages (buf)
+  "Handle all mpi messages in BUF and delete them.
+The MPI message has the form \\^[TYPE\\^^FIELD...\\^] where TYPE is the
+type of the messages on which handlers in `ess-mpi-handlers' are
+dispatched, \\^C are ASCII control chars, and FIELDs are strings.
+Return `:incomplete' if BUF ends with an incomplete message."
+  (let ((obuf (current-buffer))
+        (out nil))
+    (with-current-buffer buf
+      (goto-char (point-min))
+      ;; This should be smarter because Emacs might cut it in the middle of the
+      ;; message. In practice this almost never happen because we are
+      ;; accumulating output into the cache buffer.
+      (while (search-forward ess-mpi-message-start-delimiter nil t)
+        (let ((mbeg0 (match-beginning 0))
+              (mbeg (match-end 0)))
+          (if (search-forward ess-mpi-message-end-delimiter nil t)
+              (let* ((mend (match-beginning 0))
+                     (mend0 (match-end 0))
+                     (msg (buffer-substring mbeg mend))
+                     (payload (mapcar #'ess-mpi-convert
+                                      (split-string msg ess-mpi-message-field-separator)))
+                     (head (pop payload))
+                     (handler (cdr (assoc head ess-mpi-handlers))))
+                (unwind-protect
+                    (if handler
+                        (with-current-buffer obuf
+                          (apply handler payload))
+                      (error "No handler defined for MPI message '%s" head))
+                  (goto-char mbeg0)
+                  (delete-region mbeg0 mend0)))
+            (setq out :incomplete))))
+      out)))
+
+(defun ess--replace-long+-in-prompt (proc prompt is-final)
+  "Replace long + + + in PROMPT based on `inferior-ess-replace-long+' value.
+If IS-FINAL means that PROMPT occurs at the end of the process
+chunk. If non-nil, special care is taken not to drop last '+'
+value as it might be a continuation prompt."
+  ;; see #576 for interesting input examples
+  (let ((len (length prompt))
+        (inferior-ess-replace-long+ (buffer-local-value
+                                     'inferior-ess-replace-long+
+                                     (process-buffer proc))))
+    (if (or (null inferior-ess-replace-long+)
+            (< len 2))
+        prompt
+      (let ((last+ (eq (elt prompt (- len 2)) ?+)))
+        (cond
+         ((eq inferior-ess-replace-long+ 'strip)
+          (if (and last+ is-final)
+              "+ "
+            "> "))
+         ((eq inferior-ess-replace-long+ t)
+          (let ((prompt (replace-regexp-in-string "\\(\\+ \\)\\{2\\}\\(\\+ \\)+"
+                                                  ess-long+replacement prompt)))
+            (if (and last+ (not is-final))
+                ;; append > for aesthetic reasons
+                (concat prompt "> ")
+              prompt)))
+         (t (error "Invalid values of `inferior-ess-replace-long+'")))))))
+
+(defun ess--offset-output (prev-prompt str)
+  "Add suitable offset to STR given the preceding PREV-PROMPT.
+Do nothing if `inferior-ess-fix-misaligned-output' is nil."
+  (if (and inferior-ess-fix-misaligned-output prev-prompt)
+      (let ((len (length prev-prompt)))
+        ;; prompts have at least 2 chars
+        (if (eq (elt prev-prompt (- len 2)) ?+)
+            ;; when last + append > for aesthetic reasons
+            (concat "> \n" str)
+          (if (eq (elt str 0) ?\n)
+              ;; don't insert empty lines
+              str
+            (concat "\n" str))))
+    str))
+
+(defun ess--flush-accumulated-output (proc)
+  "Flush accumulated output of PROC into its output buffer.
+Insertion happens chunk by chunk. A chunk is a region between two
+prompts."
+  (let* ((abuf (ess--accumulation-buffer proc))
+         (pbuf (process-buffer proc))
+         (visibly (process-get proc :eval-visibly))
+         (nowait (eq visibly 'nowait))
+         (flush-timer (process-get proc 'flush-timer)))
+    (when (> (buffer-size abuf) 0)
+      (when (timerp flush-timer)
+        (cancel-timer flush-timer))
+      (if (eq (buffer-local-value 'major-mode pbuf) 'fundamental-mode)
+          ;; FIXME: this cannot be, ess-command changes the filter
+          ;; Just in case if we are in *ess-command* buffer; restart the timer.
+          (process-put proc 'flush-timer
+                       (run-at-time .02 nil #'ess--flush-accumulated-output proc))
+        ;; Incomplete mpi should hardly happen. Only on those rare occasions
+        ;; when an mpi is issued after a long task and split by the Emacs input
+        ;; handler, or mpi printing itself takes very long.
+        (unless (eq :incomplete (ess-mpi-handle-messages abuf))
+          (with-current-buffer abuf
+            ;; Uncomment this line when debugging. This pops up the
+            ;; accumulation buffer and causes point to follow
+            ;; automatically as the parsing progresses.
+            ;; (pop-to-buffer (current-buffer))
+            (goto-char (point-min))
+            (let ((case-fold-search nil))
+              (when (re-search-forward "Error\\(:\\| +in\\)" nil t)
+                (unless (get-buffer-window pbuf 'visible)
+                  (setq next-error-last-buffer pbuf)
+                  (display-buffer pbuf nil t))))
+            (goto-char (point-min))
+            ;; First long + + in the output mirrors the sent input by the user and
+            ;; is unnecessary in nowait case. A single + can be a continuation in
+            ;; the REPL, thus we check if there is an extra output after the + .
+            (when nowait
+              (when (looking-at "\\([+>] \\)\\{2,\\}\n?")
+                (goto-char (match-end 0))
+                (when (eq (point) (point-max))
+                  ;; if this is the last prompt in the output back-up one prompt
+                  ;; (cannot happen after \n)
+                  (backward-char 2))))
+            (let ((do-clean (not (eq visibly t)))
+                  (pos2 (point))
+                  (pos1 (point))
+                  (tpos nil)
+                  (prompt nil)
+                  (regexp (if nowait
+                              ;; we cannot disambiguate printed input fields and
+                              ;; prompts in output in this case; match 2+ pluses or
+                              ;; > and 2+ spaces
+                              "\\(^\\([+>] \\)\\{2,\\}\\)\\|\\(> \\) +"
+                            "^\\([+>] \\)+"))
+                  (prev-prompt (process-get proc 'prev-prompt)))
+              (while (re-search-forward regexp nil t)
+                (setq pos1 (match-beginning 0)
+                      tpos (if nowait
+                               (or (match-end 1) (match-end 3))
+                             (match-end 0)))
+                (when (> pos1 pos2)
+                  (let ((str (buffer-substring pos2 pos1)))
+                    (comint-output-filter proc (ess--offset-output prev-prompt str))))
+                (setq pos2 tpos)
+                (setq prompt (let ((prompt (buffer-substring pos1 pos2)))
+                               (if do-clean
+                                   (ess--replace-long+-in-prompt proc prompt (eq pos2 (point-max)))
+                                 prompt)))
+                ;; Cannot bypass this trivial call to comint-output-filter because
+                ;; external tools could rely on prompts (org-babel [#598] for
+                ;; example). Setting dummy regexp in order to avoid comint erasing
+                ;; this prompt which contrasts to how we output prompts in all
+                ;; other cases.
+                (with-current-buffer pbuf
+                  (let ((comint-prompt-regexp "^$"))
+                    (comint-output-filter proc prompt)))
+                (setq prev-prompt (and do-clean prompt)
+                      pos1 pos2))
+              ;; insert last chunk if any
+              (unless (eq pos1 (point-max))
+                (let ((str (buffer-substring-no-properties pos1 (point-max))))
+                  (comint-output-filter proc (ess--offset-output prev-prompt str))
+                  (setq prev-prompt nil)))
+              (process-put proc 'prev-prompt prev-prompt)
+              (process-put proc 'flush-time (and (process-get proc 'busy)
+                                                 (float-time)))
+              (erase-buffer))))))))
+
+(defun inferior-ess-tracebug-output-filter (proc string)
+  "Standard output filter for the inferior ESS process.
+When `ess-debug' is active, this is the filter. Call
+`inferior-ess-output-filter'. Check for debug
+reg-expressions (see `ess--dbg-regexp-debug',...), when found
+puts iESS in the debugging state. If in debugging state, mirrors
+the output into *ess.dbg* buffer."
+  (let* ((is-iess (or (derived-mode-p 'ess-watch-mode)
+                      (derived-mode-p 'inferior-ess-mode)))
+         (pbuf (process-buffer proc))
+         (abuf (ess--accumulation-buffer proc))
+         (dbuff (process-get proc 'dbg-buffer))
+         (wbuff (get-buffer ess-watch-buffer))
+         (was-in-dbg (process-get proc 'dbg-active))
+         (was-in-recover (process-get proc 'is-recover))
+         (input-point (point-marker))
+         (match-jump (string-match ess--dbg-regexp-jump string))
+         (match-input (string-match ess--dbg-regexp-input string))
+         (match-selection (and match-input
+                               (match-string 2 string))) ;; Selection:
+         (match-skip (and ess-debug-skip-first-call
+                          (string-match ess--dbg-regexp-skip string)
+                          (not (string-match ess--dbg-regexp-no-skip string))))
+         (match-dbg (or match-skip (and match-input (not match-selection))))
+         (is-ready (inferior-ess--set-status proc string))
+         (new-time (float-time))
+         (last-time (process-get proc 'flush-time))
+         (flush-timer (process-get proc 'flush-timer)))
+
+    ;; current-buffer is still the user's input buffer here
+    (ess--if-verbose-write-process-state proc string "tracebug-filter")
+    (inferior-ess-run-callback proc string)
+    (process-put proc 'is-recover match-selection)
+
+    (if (or (process-get proc 'suppress-next-output?)
+            ess--suppress-next-output?)
+
+        ;; works only for suppressing short output, enough for now (for callbacks)
+        (process-put proc 'suppress-next-output? nil)
+
+      (with-current-buffer abuf
+        (goto-char (point-max))
+        (insert string))
+
+      ;; cancel the timer each time we enter this filter
+      (when (timerp flush-timer)
+        (cancel-timer flush-timer)
+        (process-put proc 'flush-timer nil))
+
+      (unless last-time ;; don't flush for the first time
+        (setq last-time new-time)
+        (process-put proc 'flush-time new-time))
+
+      ;; flush periodically
+      (let ((fast-flush (or is-ready
+                            ;; for the sake of ess-eval-linewise
+                            (process-get proc 'sec-prompt))))
+        (if (or
+             ;; theoretically we should flush asynchronously in all cases but
+             ;; somewhat unexpectedly it introduces much more randomness during
+             ;; batch testing. TODO: flush directly for now and either remove or
+             ;; improve on the next refactoring iteration
+             fast-flush
+             (> (- new-time last-time) .5)
+             (bound-and-true-p edebug-mode)
+             ;; the flush is not getting called if the third party call
+             ;; accept-process-output in a loop (e.g. org-babel-execute-src-block)
+             (bound-and-true-p org-babel-current-src-block-location))
+            (ess--flush-accumulated-output proc)
+          ;; Setup new flush timer. Ideally also for fast-flush case in order to
+          ;; avoid detecting intermediate prompts as end-of-output prompts.
+          (let ((timeout (if fast-flush .01 .2)))
+            (process-put proc 'flush-timer
+                         (run-at-time timeout nil #'ess--flush-accumulated-output proc))))))
+
+    ;; WATCH
+    (when (and is-ready wbuff) ;; refresh only if the process is ready and wbuff exists, (not only in the debugger!!)
+      (ess-watch-refresh-buffer-visibly wbuff))
+
+    ;; JUMP to line if debug expression was matched
+    (when match-jump
+      (with-current-buffer dbuff              ;; insert string in *ess.dbg* buffer
+        (goto-char (point-max))
+        (insert (concat "|-" string "-|")))
+      (ess--dbg-goto-last-ref-and-mark dbuff is-iess))
+
+    ;; (with-current-buffer dbuff ;; un-comment to see the value of STRING just before debugger exists
+    ;;   (let ((inhibit-read-only t))
+    ;;     (goto-char (point-max))
+    ;;     (insert (concat " ---\n " string "\n ---"))
+    ;;     ))
+
+    ;; SKIP if needed
+    (when (and match-skip (not was-in-recover))
+      (process-send-string proc  "n\n"))
+
+    ;; EXIT the debugger
+    (when (and was-in-dbg
+               (not (or match-jump match-dbg))
+               (or is-ready match-selection))
+      (ess--dbg-deactivate-overlays)
+      (process-put proc 'dbg-active nil)
+      ;; (message "|<-- exited debugging -->|")
+      (when wbuff
+        (ess-watch-refresh-buffer-visibly wbuff)))
+
+    ;; ACTIVATE the debugger if entered for the first time
+    (when (and (not was-in-dbg)
+               (not match-selection)
+               (or match-jump match-dbg))
+      (unless is-iess
+        (ring-insert ess--dbg-forward-ring input-point))
+      (process-put proc 'dbg-active t)
+      (message
+       (ess--debug-keys-message-string))
+      (unless match-jump
+        ;; no source reference, simply show the inferior
+        (display-buffer pbuf)))
+
+    (when (and match-selection (not is-iess)) ;(and (not was-in-recover) match-selection)
+      (ess-electric-selection t))))
+
+
+(defvar ess-debug-minor-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "M-C") #'ess-debug-command-continue)
+    (define-key map [(control meta ?C)] #'ess-debug-command-continue-multi)
+    (define-key map (kbd "M-N") #'ess-debug-command-next)
+    (define-key map (kbd "M-S") #'ess-debug-command-step)
+    (define-key map (kbd "M-W") #'ess-debug-command-where)
+    (define-key map (kbd "M-F") #'ess-debug-command-finish)
+    (define-key map (kbd "M-H") #'ess-debug-command-help)
+    (define-key map (kbd "M-R") #'ess-debug-command-resume)
+    (define-key map [(control meta ?N)] #'ess-debug-command-next-multi)
+    (define-key map (kbd "M-Q") #'ess-debug-command-quit)
+    (define-key map (kbd "M-U") #'ess-debug-command-up)
+    map)
+  "Keymap active when ESS process is in debugging state.
+\\{ess-debug-minor-mode-map}")
+
+
+(define-minor-mode ess-debug-minor-mode
+  "Minor mode activated when ESS process is in debugging state."
+  :lighter nil
+  :keymap ess-debug-minor-mode-map)
+
+(defun ess--dbg-goto-last-ref-and-mark (dbuff &optional other-window)
+  "Open the most recent debug reference and set the necessary marks and overlays.
+It's called from `inferior-ess-tracebug-output-filter'. DBUFF
+must be the *ess.dbg* buffer associated with the process. If
+OTHER-WINDOW is non nil, attempt to open the location in a
+different window."
+  (let (t-debug-position ref)
+    (with-current-buffer dbuff
+      (setq ref (ess--dbg-get-next-ref -1 (point-max) ess--dbg-last-ref-marker
+                                       ess--dbg-regexp-reference)) ; sets point at the end of found ref
+      (when ref
+        (move-marker ess--dbg-last-ref-marker (line-end-position))
+        ;; each new step repositions the current-ref!
+        (move-marker ess--dbg-current-ref ess--dbg-last-ref-marker)))
+    (when ref
+      (let ((buf (apply #'ess--dbg-goto-ref other-window ref)))
+        (if buf
+            ;; if referenced buffer has been found, put overlays:
+            (with-current-buffer buf
+              (setq t-debug-position (copy-marker (line-beginning-position)))
+              (if (equal t-debug-position ess--dbg-current-debug-position)
+                  (progn ;; highlights the overlay for ess--dbg-blink-interval seconds
+                    (overlay-put ess--dbg-current-debug-overlay 'face 'ess--dbg-blink-same-ref-face)
+                    (run-with-timer ess-debug-blink-interval nil
+                                    (lambda ()
+                                      (overlay-put ess--dbg-current-debug-overlay 'face 'ess-debug-current-debug-line-face))))
+                ;; else
+                (ess--dbg-activate-overlays)))
+          ;;else, buffer is not found: highlight and give the corresponding message
+          (overlay-put ess--dbg-current-debug-overlay 'face 'ess--dbg-blink-ref-not-found-face)
+          (run-with-timer ess-debug-blink-interval nil
+                          (lambda ()
+                            (overlay-put ess--dbg-current-debug-overlay 'face 'ess-debug-current-debug-line-face)))
+          (message "Reference %s not found" (car ref)))))))
+
+(defun ess--dbg-goto-ref (other-window file line &optional col)
+  "Opens the reference given by FILE, LINE and COL.
+Try to open in a different window if OTHER-WINDOW is nil.  Return
+the buffer if found, or nil otherwise be found.
+`ess--dbg-find-buffer' is used to find the FILE and open the
+associated buffer. If FILE is nil return nil."
+  (let ((mrk (car (ess--dbg-create-ref-marker file line col)))
+        (lpn ess-local-process-name))
+    (when mrk
+      (let ((buf (marker-buffer mrk)))
+       (if (not other-window)
+           (pop-to-buffer-same-window buf)
+         (let ((this-frame (window-frame (get-buffer-window (current-buffer)))))
+           (display-buffer buf)
+           ;; simple save-frame-excursion
+           (unless (eq this-frame (window-frame (get-buffer-window buf t)))
+             (ess-select-frame-set-input-focus this-frame))))
+       ;; set or re-set to lpn as this is the process with debug session on
+       (with-current-buffer buf
+         (setq ess-local-process-name lpn)
+         (goto-char mrk)
+          (set-window-point (get-buffer-window buf) mrk))
+       buf))))
+
+;; temporary, hopefully org folks implement something similar
+(defvar org-babel-tangled-file nil)
+(declare-function org-babel-tangle-jump-to-org "ob-tangle.el")
+
+(defun ess--dbg-create-ref-marker (file line &optional col)
+  "Create markers to the reference given by FILE, LINE and COL.
+Return list of two markers MK-start and MK-end. MK-start is the
+position of error. Mk-end is the end of the line where error
+occurred. If buffer associated with FILE is not found, or line is
+nil, or TB-INDEX is not found return nil."
+  (if (stringp line) (setq line (string-to-number line)))
+  (if (stringp col) (setq col (string-to-number col)))
+  (let* ((srcref (gethash file ess--srcrefs))
+         (file (replace-regexp-in-string "^\n" "" ;; hack for gnu regexp
+                                         (or (car srcref) file)))
+         (tb-index (cadr srcref))
+         (buffer (ess--dbg-find-buffer file))
+         pos)
+    (when (and buffer line)
+      (save-excursion
+        (with-current-buffer buffer
+          (save-restriction
+            (widen) ;; how does this behave in narrowed buffers? tothink:
+            (goto-char 1)
+            (setq pos (point))
+            (when tb-index
+              (while (and (not (eq tb-index (get-text-property pos 'tb-index)))
+                          (setq pos (next-single-property-change pos 'tb-index)))))
+            (unless pos
+              ;; use beg position if index not found
+              (setq pos (nth 2 srcref)))
+            (when pos
+              (goto-char pos)
+              (forward-line (1- line))
+              (if col
+                  (goto-char (+ (line-beginning-position) col))
+                (back-to-indentation))
+              (when (bound-and-true-p org-babel-tangled-file)
+                (org-babel-tangle-jump-to-org))
+              (list (point-marker) (copy-marker (line-end-position))))))))))
+
+(defvar ess-r-package-library-paths)
+(defun ess--dbg-find-buffer (filename)
+  "Find a buffer for file FILENAME.
+If FILENAME is not found at all, ask the user where to find it if
+`ess--dbg-ask-for-file' is non-nil.  Search the directories in
+`ess-tracebug-search-path' and `ess-r-package-library-paths'."
+  (let ((dirs (append
+               (ess-r-package-source-dirs)
+               ess-r-package-library-paths
+               (cl-loop for d in (append ess-tracebug-search-path)
+                        append (ess-r-package--all-source-dirs d))))
+        (filematch (format "%s\\'" filename))
+        buffer name)
+    (setq dirs (delq nil (cons (with-ess-process-buffer t default-directory) dirs)))
+    ;; 1. The file name is absolute.  Use its explicit directory as
+    ;; the first in the search path, and strip it from FILENAME.
+    (when (and (null  buffer)
+               (file-name-absolute-p filename))
+      (setq filename (abbreviate-file-name (expand-file-name filename))
+            dirs (cons (file-name-directory filename) dirs)
+            filename (file-name-nondirectory filename)))
+    (or
+     ;; 2. Search the path.
+     (while (and (null buffer) dirs)
+       (let ((thisdir (pop dirs)))
+         (setq name (expand-file-name filename thisdir)
+               buffer (and (file-exists-p name)
+                           (find-file-noselect name)))))
+     buffer
+
+     ;; 3. search already open buffers for match (associated file might not even exist yet)
+     (cl-dolist (bf (buffer-list))
+       (with-current-buffer  bf
+         (when (and buffer-file-name
+                    (string-match filematch buffer-file-name))
+           (setq buffer bf)
+           (cl-return))))
+     buffer
+
+     ;; 4. Ask for file if not found (tothink: maybe remove this part?)
+     (when ess-debug-ask-for-file
+       (save-excursion            ;This save-excursion is probably not right.
+         (let* ((pop-up-windows t)
+                (name (read-file-name
+                       (format "Find next line in (default %s): "  filename)
+                       nil filename t nil))
+                (origname name))
+           (cond
+            ((not (file-exists-p name))
+             (message "Cannot find file `%s'" name)
+             (ding) (sit-for 2))
+            ((and (file-directory-p name)
+                  (not (file-exists-p
+                        (setq name (expand-file-name filename name)))))
+             (message "No `%s' in directory %s" filename origname)
+             (ding) (sit-for 2))
+            (t
+             (setq buffer (find-file-noselect name)))))))
+     buffer)))
+
+(defun ess--dbg-get-next-ref (n &optional pt BOUND REG nF nL nC)
+  "Move point to the next reference in the *ess.dbg* buffer.
+
+Must be called from *ess.dbg* buffer.
+It returns the reference in the form (file line col) /all strings/ ,
+or NIL if not found .  Prefix arg N says how many error messages
+to move forwards (or backwards, if negative).  Optional arg PT,
+if non-nil, specifies the value of point to start looking for the
+next message, default to (point).  BOUND is the limiting position
+of the search.  REG is the regular expression to search with.  nF
+- sub-expression of REG giving the `file'; defaults to 1.  nL -
+giving the `line'; defaults to 2.  nC - sub-expr giving the
+`column'; defaults to 3."
+  (unless ess--dbg-buf-p
+    (error "Not in *ess.dbg* buffer"))
+  (setq nF (or nF 1)
+        nL (or nL 2)
+        nC (or nC 3))
+  (or pt (setq pt (point)))
+  ;; (message "ess--dbg-last-ref-marker%s vs  pt%s vs point-max%s" ess--dbg-last-ref-marker pt (point-max))
+  (goto-char pt)
+  (if (search-forward-regexp REG BOUND t n)
+      (list (match-string nF) (match-string-no-properties nL) (match-string-no-properties nC))
+    nil))
+
+(defun ess--debug-keys-message-string (&optional map)
+  (let ((overriding-local-map (or map ess-debug-minor-mode-map)))
+    (substitute-command-keys
+     (mapconcat #'identity
+                '("(\\[ess-debug-command-continue])cont"
+                  "(\\[ess-debug-command-continue-multi])cont-multi"
+                  "(\\[ess-debug-command-next])next"
+                  "(\\[ess-debug-command-next-multi])next-multi"
+                  "(\\[ess-debug-command-up])up"
+                  "(\\[ess-debug-command-quit])quit")
+                " "))))
+
+(defun ess-electric-selection (&optional wait)
+  "Call commands defined in `ess-electric-selection-map'.
+Single-key input commands are those, which once executed do not
+require the prefix command for subsequent invocation.
+
+If WAIT is t, wait for next input and ignore the keystroke which
+triggered the command."
+  (interactive)
+  (ess--execute-electric-command ess-electric-selection-map
+                                 "Selection: " wait
+                                 (not (ess-process-get 'is-recover))))
+
+(defun ess-debug-command-digit (&optional ev)
+  "Digit commands in selection mode.
+If supplied, EV must be a proper key event or a string representing the digit."
+  (interactive)
+  (ess-force-buffer-current)
+  (unless (ess--dbg-is-recover-p)
+    (error "Recover is not active"))
+  (unless ev
+    (setq ev last-command-event))
+  (let* ((ev-char (if (stringp ev)
+                      ev
+                    (char-to-string (event-basic-type ev))))
+         (proc (get-process ess-current-process-name))
+         (mark-pos (marker-position (process-mark proc)))
+         (comint-prompt-read-only nil)
+         prompt  depth)
+    (with-current-buffer (process-buffer proc)
+      (goto-char mark-pos)
+      (save-excursion
+        (when (re-search-backward "\\(?: \\|^\\)\\([0-9]+\\):[^\t]+Selection:" ess--tb-last-input t)
+          (setq depth (string-to-number (match-string 1)))
+          (when (> depth 9)
+            (setq ev-char (ess-completing-read "Selection" (mapcar #'number-to-string
+                                                                   (number-sequence depth 0 -1))
+                                               nil t ev-char nil)))))
+      (setq prompt (delete-and-extract-region (line-beginning-position) mark-pos))
+      (insert (concat  prompt ev-char "\n"))
+      (ess-send-string proc ev-char)
+      (move-marker (process-mark proc) (max-char)))))
+
+(defun ess-debug-command-next ()
+  "Step next in debug mode.
+Equivalent to `n' at the R prompt."
+  (interactive)
+  (ess-force-buffer-current)
+  (unless (ess--dbg-is-active-p)
+    (error "Debugger is not active"))
+  (if (ess--dbg-is-recover-p)
+      (ess-send-string (ess-get-process) "0")
+    (ess-send-string (ess-get-process) "n")))
+
+(defun ess-debug-command-step ()
+      "Step into in debug mode.
+Equivalent to `s' at the R prompt."
+       (interactive)
+  (ess-force-buffer-current)
+  (unless (ess--dbg-is-active-p)
+    (error "Debugger is not active"))
+  (if (ess--dbg-is-recover-p)
+      (ess-send-string (ess-get-process) "0")
+    (ess-send-string (ess-get-process) "s")))
+
+(defun ess-debug-command-finish ()
+  "Step next in debug mode.
+Equivalent to `f' at the R prompt."
+  (interactive)
+  (ess-force-buffer-current)
+  (unless (ess--dbg-is-active-p)
+    (error "Debugger is not active"))
+  (if (ess--dbg-is-recover-p)
+      (progn (ess-send-string (ess-get-process) "0")
+       (ess-send-string (ess-get-process) "f"))
+    (ess-send-string (ess-get-process) "f")))
+
+
+(defun ess-debug-command-resume ()
+  "Step next in debug mode.
+Equivalent to `f' at the R prompt."
+  (interactive)
+  (ess-force-buffer-current)
+  (unless (ess--dbg-is-active-p)
+    (error "Debugger is not active"))
+  (if (ess--dbg-is-recover-p)
+      (progn (ess-send-string (ess-get-process) "0")
+       (ess-send-string (ess-get-process) "r"))
+    (ess-send-string (ess-get-process) "r")))
+
+(defun ess-debug-command-where ()
+  "Step next in debug mode.
+Equivalent to `where' at the R prompt."
+  (interactive)
+  (ess-force-buffer-current)
+  (unless (ess--dbg-is-active-p)
+    (error "Debugger is not active"))
+    (ess-send-string (ess-get-process) "where"))
+
+
+(defun ess-debug-command-help ()
+  "Step next in debug mode.
+Equivalent to `where' at the R prompt."
+  (interactive)
+  (ess-force-buffer-current)
+  (unless (ess--dbg-is-active-p)
+    (error "Debugger is not active"))
+    (ess-send-string (ess-get-process) "help"))
+
+(defun ess-debug-command-next-multi (&optional N)
+  "Ask for N and step (n) N times in debug mode."
+  (interactive)
+  (ess-force-buffer-current)
+  (unless (ess--dbg-is-active-p)
+    (error "Debugger is not active"))
+  (let ((N (or N (read-number "Number of steps: " 10)))
+        (ess--suppress-next-output? t))
+    (while (and (ess--dbg-is-active-p) (> N 0))
+      (ess-debug-command-next)
+      (ess-wait-for-process)
+      (setq N (1- N))))
+  (ess-debug-command-next))
+
+(defun ess-debug-command-continue-multi (&optional N)
+  "Ask for N, and continue (c) N times in debug mode."
+  (interactive)
+  (ess-force-buffer-current)
+  (unless (ess--dbg-is-active-p)
+    (error "Debugger is not active"))
+  (let ((N (or N (read-number "Number of continuations: " 10)))
+        (ess--suppress-next-output? t))
+    (while (and (ess--dbg-is-active-p) (> N 1))
+      (ess-debug-command-continue)
+      (ess-wait-for-process)
+      (setq N (1- N))))
+  (ess-debug-command-continue))
+
+(defun ess-debug-command-up ()
+  "Step up one call frame.."
+  (interactive)
+  (ess-force-buffer-current)
+  (unless (ess--dbg-is-active-p)
+    (error "Debugger is not active"))
+  (let ((up-cmd "try(browserSetDebug(), silent=T)\nc\n"))
+    (ess-send-string (ess-get-process) up-cmd)))
+
+;; (defun ess-debug-previous-error (&optional ev)
+;;   "Go to previous reference during the debug process.
+;; R doesn't support step backwards. This command just takes you  through
+;; debug history."
+;;   (interactive)
+;;   (previous-error))
+
+(defun ess-debug-command-quit ()
+  "Quits the browser/debug in R process.
+Equivalent of `Q' at the R prompt."
+  (interactive)
+  (ess-force-buffer-current)
+  (cond ((ess--dbg-is-recover-p)
+         (ess-send-string (ess-get-process) "0" t))
+        ;; if recover is called in a loop the following stalls Emacs
+        ;; (ess-wait-for-process proc nil 0.05)
+        ((ess--dbg-is-active-p)
+         (ess-send-string (ess-get-process) "Q" t))
+        (t
+         (error "Debugger is not active"))))
+
+(defun ess-debug-command-continue ()
+  "Continue the code execution.
+Equivalent of `c' at the R prompt."
+  (interactive)
+  (ess-force-buffer-current)
+  (cond ((ess--dbg-is-recover-p)
+         (ess-send-string (ess-get-process) "0"))
+        ((ess--dbg-is-active-p)
+         (ess-send-string (ess-get-process) "c"))
+        (t
+         (error "Debugger is not active"))))
+
+(defun ess-tracebug-set-last-input (&rest _args)
+  "Move `ess--tb-last-input' marker to the process mark.
+ARGS are ignored to allow using this function in process hooks."
+  (let* ((last-input-process (get-process ess-local-process-name))
+         (last-input-mark (copy-marker (process-mark last-input-process))))
+    (with-current-buffer (process-buffer last-input-process)
+      (when (local-variable-p 'ess--tb-last-input) ;; TB might not be active in all processes
+        (save-excursion
+          (setq ess--tb-last-input last-input-mark)
+          (goto-char last-input-mark)
+          (inferior-ess-move-last-input-overlay))))))
+
+;;;_ + BREAKPOINTS
+
+(defface ess-bp-fringe-inactive-face
+  '((((class color) (background light) (min-colors 88)) (:foreground "DimGray"))
+    (((class color) (background dark) (min-colors 88))  (:foreground "LightGray"))
+    (((background light) (min-colors 8))  (:foreground "blue"))
+    (((background dark) (min-colors 8))  (:foreground "cyan")))
+  "Face used to highlight inactive breakpoints."
+  :group 'ess-debug)
+
+(defface ess-bp-fringe-logger-face
+  '((((class color) (background light) (min-colors 88)) (:foreground "dark red"))
+    (((class color) (background dark) (min-colors 88))  (:foreground "tomato1"))
+    (((background light) (min-colors 8))  (:foreground "blue"))
+    (((background dark) (min-colors 8))  (:foreground "cyan")))
+  "Face used to highlight loggers."
+  :group 'ess-debug)
+
+(defface ess-bp-fringe-browser-face
+  '((((class color) (background light) (min-colors 88)) (:foreground "medium blue"))
+    (((class color) (background dark) (min-colors 88))  (:foreground "deep sky blue"))
+    (((background light) (min-colors 8))  (:foreground "blue"))
+    (((background dark) (min-colors 8))  (:foreground "cyan")))
+  "Face used to highlight `browser' breakpoints."
+  :group 'ess-debug)
+
+(defface ess-bp-fringe-recover-face
+  '((((class color) (background light) (min-colors 88)) (:foreground "dark magenta"))
+    (((class color) (background dark) (min-colors 88))  (:foreground "magenta"))
+    (((background light) (min-colors 8))  (:foreground "magenta"))
+    (((background dark) (min-colors 8))  (:foreground "magenta")))
+  "Face used to highlight `recover' breakpoints fringe."
+  :group 'ess-debug)
+
+(defun ess--bp-pipe-block-p ()
+  (save-excursion
+    (let ((inhibit-field-text-motion t))
+      (forward-line -1)
+      (end-of-line)
+      (looking-back "%>%[ \t]*" (line-beginning-position)))))
+
+(defun ess--bp-pipe-native-block-p ()
+  (save-excursion
+    (let ((inhibit-field-text-motion t))
+      (forward-line -1)
+      (end-of-line)
+      (looking-back "|>[ \t]*" (line-beginning-position)))))
+
+(defvar ess--bp-identifier 1)
+(defcustom ess-bp-type-spec-alist
+  '((pipe    ".ess_pipe_browser() %%>%%" "B %>%\n" filled-square ess-bp-fringe-browser-face ess--bp-pipe-block-p)
+    (pipe-native ".ess_pipe_browser() |>" "B |>\n" filled-square ess-bp-fringe-browser-face ess--bp-pipe-native-block-p)
+    (browser "browser(expr=is.null(.ESSBP.[[%s]]));" "B>\n" filled-square  ess-bp-fringe-browser-face)
+    (recover "recover()" "R>\n"   filled-square  ess-bp-fringe-recover-face))
+  "List of lists of breakpoint types.
+Each sublist  has five elements:
+1- symbol giving the name of specification
+2- R expression to be inserted (%s is substituted with unique identifier).
+3- string to be displayed instead of the expression
+4- fringe bitmap to use
+5- face for fringe and displayed string
+6- optional, a function which should return nil if this BP
+   doesn't apply to current context."
+  :group 'ess-debug
+  :type '(alist :key-type symbol
+                ;; FIXME: What's this `group'?  The values looks like strings!
+                ;; FIXME: The docstring talks about a 6th element (function)
+                ;; but it's missing here.
+                :value-type (group string string symbol face)))
+
+(defcustom ess-bp-inactive-spec
+  '(inactive     "##"    filled-square  ess-bp-fringe-inactive-face)
+  "List giving the inactive breakpoint specifications."
+  ;; List format is identical to that of the elements of
+  ;; `ess-bp-type-spec-alist' except that the second element giving
+  ;; the R expression is meaningless here." ;;fixme: second element is missing make it nil for consistency with all other specs
+  :group 'ess-debug
+  :type '(alist :key-type symbol
+                :value-type (group string string symbol face)))
+
+(defcustom ess-bp-conditional-spec
+  '(conditional     "browser(expr={%s})"  "CB[ %s ]>\n"  question-mark  ess-bp-fringe-browser-face)
+  "List giving the conditional breakpoint specifications.
+List format is identical to that of the elements of
+`ess-bp-type-spec-alist'.  User is asked for the conditional
+expression to be replaced instead of %s in the second and third
+elements of the specifications."
+  :group 'ess-debug
+  :type '(alist :key-type symbol
+                :value-type (group string string symbol face)))
+
+(defcustom ess-bp-logger-spec
+  '(logger     ".ess_log_eval('%s')"  "L[ \"%s\" ]>\n"  hollow-square  ess-bp-fringe-logger-face)
+  "List giving the loggers specifications.
+List format is identical to that of `ess-bp-type-spec-alist'."
+  :group 'ess-debug
+  :type '(alist :key-type symbol
+                :value-type (group string string symbol face)))
+
+
+(defun ess-bp-get-bp-specs (type &optional condition no-error)
+  "Get specs for TYPE."
+  (let ((spec-alist (cond
+                     ((eq type 'conditional)
+                      (let ((tl (copy-sequence  ess-bp-conditional-spec)))
+                        (when (eq (length condition) 0)
+                          (setq condition "TRUE"))
+                        (setcar (cdr tl) (format (cadr tl) condition))
+                        (setcar (cddr tl) (format (caddr tl) condition))
+                        (list tl)))
+                     ((eq type 'logger)
+                      (let ((tl (copy-sequence ess-bp-logger-spec)))
+                        (when (eq (length condition) 0)
+                          (setq condition "watchLog"))
+                        (setcar (cdr tl) (format (cadr tl) condition))
+                        (setcar (cddr tl) (format (caddr tl) condition))
+                        (list tl)))
+                     (t (copy-sequence ess-bp-type-spec-alist)))))
+    (or (assoc type spec-alist)
+        (if no-error
+            nil
+          (error "Undefined breakpoint type %s" type)))))
+
+(defun ess-bp-create (type &optional condition no-error)
+  "Set breakpoint for the current line.
+Returns the beginning position of the hidden text."
+  (let* ((bp-specs (ess-bp-get-bp-specs type condition no-error))
+         (init-pos (point-marker))
+         (fringe-bitmap (nth 3 bp-specs))
+         (fringe-face (nth 4 bp-specs))
+         (displ-string (nth 2 bp-specs))
+         (bp-id (format "\"@%s@\""
+                        (setq ess--bp-identifier (1+ ess--bp-identifier))))
+         (bp-command (concat  (format (nth 1 bp-specs) bp-id)
+                              "##:ess-bp-end:##\n"))
+         (dummy-string (format "##:ess-bp-start::%s@%s:##\n"  (car bp-specs) condition))
+         insertion-pos)
+    (when bp-specs
+      (set-marker init-pos (1+ init-pos))
+      (setq displ-string (propertize displ-string
+                                     'face fringe-face
+                                     'font-lock-face fringe-face))
+      (setq bp-command (propertize bp-command
+                                   'ess-bp t
+                                   'bp-id bp-id
+                                   'bp-active t
+                                   'cursor-intangible 'ess-bp
+                                   'rear-nonsticky '(cursor-intangible ess-bp bp-type)
+                                   'bp-type type
+                                   'bp-substring 'command
+                                   'display displ-string))
+      (setq dummy-string (propertize
+                          (ess-tracebug--propertize dummy-string fringe-bitmap fringe-face "*")
+                          'ess-bp t
+                          'cursor-intangible 'ess-bp
+                          'bp-type type
+                          'bp-substring 'dummy))
+      (ess-tracebug--set-left-margin)
+      (back-to-indentation)
+      (setq insertion-pos (point) )
+      (insert (concat   dummy-string bp-command))
+      (indent-for-tab-command)
+      (goto-char (1- init-pos))  ;; sort of save-excursion
+      insertion-pos)))
+
+(defun ess-bp-recreate-all ()
+  "Internal function to recreate all bp."
+  (save-excursion
+    (save-restriction
+      (with-silent-modifications
+        (cursor-intangible-mode)
+        (widen)
+        (goto-char (point-min))
+        (while (re-search-forward
+                "\\(##:ess-bp-start::\\(.*\\):##\n\\)\\(.+##:ess-bp-end:##\n\\)" nil t)
+          (let ((dum-beg (match-beginning 1))
+                (dum-end (match-end 1))
+                (comm-beg (match-beginning 3))
+                (comm-end (match-end 3))
+                (type (match-string 2))
+                (bp-command (match-string 3))
+                bp-id dum-props condition)
+            (when (string-match "^\\(\\w+\\)@\\(.*\\)\\'" type)
+              (setq condition (match-string 2 type))
+              (setq type (match-string 1 type)))
+            (setq bp-id
+                  (if (string-match "\"@[0-9]+@\"" bp-command)
+                      (match-string 0 bp-command)
+                    (setq ess--bp-identifier (1+ ess--bp-identifier))))
+            (setq type (intern type))
+            (let* ((bp-specs (ess-bp-get-bp-specs  type condition t))
+                   (displ-string (nth 2 bp-specs))
+                   (fringe-face (nth 4 bp-specs))
+                   (fringe-bitmap (nth 3 bp-specs)))
+              (when bp-specs
+                (setq displ-string (propertize displ-string
+                                               'face fringe-face
+                                               'font-lock-face fringe-face))
+                (add-text-properties comm-beg comm-end
+                                     (list 'ess-bp t
+                                           'bp-id bp-id
+                                           'cursor-intangible 'ess-bp
+                                           'rear-nonsticky '(cursor-intangible ess-bp bp-type)
+                                           'bp-type type
+                                           'bp-substring 'command
+                                           'display displ-string))
+                (setq dum-props
+                      (if window-system
+                          (list 'display (list 'left-fringe fringe-bitmap fringe-face))
+                        (list 'display (list '(margin left-margin)
+                                             (propertize "dummy"
+                                                         'font-lock-face fringe-face
+                                                         'face fringe-face)))))
+                (add-text-properties dum-beg dum-end
+                                     (append dum-props
+                                             (list 'ess-bp t
+                                                   'cursor-intangible 'ess-bp
+                                                   'bp-type type
+                                                   'bp-substring 'dummy)))
+                ;; (when comment-beg
+                ;;   (add-text-properties comment-beg comment-end
+                ;;                        (list 'ess-bp t
+                ;;                              'bp-id bp-id
+                ;;                              'cursor-intangible 'ess-bp
+                ;;                              'display (propertize (nth 1 ess-bp-inactive-spec) 'face fringe-face)
+                ;;                              'bp-type type
+                ;;                              'bp-substring 'comment)))
+                ))))))))
+
+(add-hook 'ess-r-mode-hook #'ess-bp-recreate-all)
+
+
+(defun ess-bp-get-bp-position-nearby ()
+  "Get nearby break points.
+Return the cons (beg . end) of breakpoint limit points closest to
+the current position. Only currently visible region of the buffer
+is searched. This command is intended for use in interactive
+commands like `ess-bp-toggle-state' and `ess-bp-kill'. Use
+`ess-bp-previous-position' in programs."
+  (interactive)
+  (let*  ((pos-end (if (get-char-property (1- (point)) 'ess-bp)
+                       (point)
+                     (previous-single-property-change (point) 'ess-bp nil (window-start))))
+          (pos-start (if (get-char-property (point) 'ess-bp) ;;check for bobp
+                         (point)
+                       (next-single-property-change (point) 'ess-bp nil (window-end))))
+          dist-up dist-down)
+    (unless (eq pos-end (window-start))
+      (setq dist-up (- (line-number-at-pos (point))
+                       (line-number-at-pos pos-end))))
+    (unless (eq pos-start (window-end))
+      (setq dist-down (- (line-number-at-pos pos-start)
+                         (line-number-at-pos (point)))))
+    (if (and dist-up dist-down)
+        (if (< dist-up dist-down)
+            (cons (previous-single-property-change pos-end 'ess-bp nil (window-start)) pos-end)
+          (cons pos-start (next-single-property-change pos-start 'ess-bp nil (window-end))))
+      (if dist-up
+          (cons (previous-single-property-change pos-end 'ess-bp nil (window-start)) pos-end)
+        (if dist-down
+            (cons pos-start (next-single-property-change pos-start 'ess-bp nil (window-end))))))))
+
+
+(defun ess-bp-previous-position ()
+  "Get previous breakpoints.
+Return the cons (beg . end) of breakpoint limit points closest
+to the current position, nil if not found."
+  (let* ( (pos-end (if (get-char-property (1- (point)) 'ess-bp)
+                       (point)
+                     (previous-single-property-change (point) 'ess-bp ))))
+    (if pos-end
+        (cons (previous-single-property-change pos-end 'ess-bp) pos-end))))
+
+(defun ess-bp-set ()
+  "Set a breakpoint."
+  (interactive)
+  (let* ((pos (ess-bp-get-bp-position-nearby))
+         (same-line (and pos
+                         (<=  (line-beginning-position) (cdr pos))
+                         (>= (line-end-position) (car pos))))
+         (types ess-bp-type-spec-alist)
+         (ev last-command-event)
+         (com-char  (event-basic-type ev))
+         bp-type)
+    (when same-line
+      ;; set bp-type to next type in types
+      (setq bp-type (get-text-property (car pos) 'bp-type))
+      (setq types (cdr (member (assq bp-type types) types))) ; nil if bp-type is last in the list
+      (when (null types)
+        (setq types ess-bp-type-spec-alist))
+      (ess-bp-kill)
+      (indent-for-tab-command))
+    ;; skip contextual bps
+    (while (and (nth 5 (car types))
+                (not (funcall (nth 5 (car types)))))
+      (pop types))
+    (setq bp-type (pop types))
+    (ess-bp-create (car bp-type))
+    (while  (eq (event-basic-type (setq ev (read-event (format "'%c' to cycle" com-char))))
+                com-char)
+      (if (null types) (setq types ess-bp-type-spec-alist))
+      (ess-bp-kill)
+      ;; skip contextual bps
+      (while (and (nth 5 (car types))
+                  (not (funcall (nth 5 (car types)))))
+        (pop types))
+      (setq bp-type (pop types))
+      (ess-bp-create (car bp-type))
+      (indent-for-tab-command))
+    (push ev unread-command-events)))
+
+
+(defun ess-bp-set-conditional (condition)
+  (interactive "sBreakpoint condition: ")
+  (ess-bp-create 'conditional condition)
+  (indent-for-tab-command))
+
+(defun ess-bp-set-logger (name)
+  (interactive "sLogger name : ")
+  (ess-bp-create 'logger name)
+  (indent-for-tab-command))
+
+(defun ess-bp-kill (&optional interactive?)
+  "Remove the breakpoint nearby."
+  (interactive "p")
+  (let ((pos (ess-bp-get-bp-position-nearby))
+        (init-pos (make-marker)))
+    (if (null pos)
+        (if interactive? (message "No breakpoints nearby"))
+      (if (eq (point) (line-end-position))
+          (goto-char (1- (point)))) ;; work-around for issue  3
+      (set-marker init-pos  (point))
+      (goto-char (car pos))
+      (delete-region (car pos) (cdr pos))
+      (indent-for-tab-command)
+      (goto-char init-pos)
+      (if (eq (point) (line-end-position)) (forward-char)))))
+
+(defun ess-bp-kill-all nil
+  "Delete all breakpoints in current buffer."
+  (interactive)
+  (let ((count 0)
+        (init-pos (make-marker))
+        pos)
+    (set-marker init-pos (1+ (point)))
+    (save-excursion   ;; needed if error
+      (goto-char (point-max))
+      (while (setq pos (ess-bp-previous-position))
+        (goto-char (car pos))
+        (delete-region (car pos) (cdr pos))
+        (indent-for-tab-command)
+        (setq count (1+ count)))
+      (if (eq count 1)
+          (message "Killed 1 breakpoint")
+        (message "Killed %d breakpoint(s)" count)))
+    (goto-char (1- init-pos))))
+
+
+(defun ess-bp-toggle-state ()
+  "Toggle the breakpoint between active and inactive states.
+
+For standard breakpoints, the effect of this command is
+immediate, that is you don't need to source your code and it
+works even in the process of debugging.
+
+For loggers, recover and conditional breakpoints this command
+just comments the breakpoint in the source file.
+
+If there is no active R session, this command triggers an error."
+  (interactive)
+  (unless (and ess-local-process-name
+               (get-process ess-local-process-name))
+    (error "No R session in this buffer"))
+  (save-excursion
+    (let ((pos (ess-bp-get-bp-position-nearby))
+          (fringe-face (nth 3 ess-bp-inactive-spec))
+          (cursor-sensor-inhibit 'ess-bp-toggle-state)
+          bp-id bp-specs beg-pos-command)
+      (if (null pos)
+          (message "No breakpoints in the visible region")
+        (goto-char (car pos))
+        (setq beg-pos-command (previous-single-property-change
+                               (cdr pos) 'bp-substring nil (car pos))
+              bp-id (get-char-property beg-pos-command 'bp-id))
+        (goto-char beg-pos-command)
+        (if (get-char-property beg-pos-command 'bp-active)
+            (progn
+              (put-text-property  (car pos) beg-pos-command ;; dummy display change
+                                  'display (list 'left-fringe (nth 2 ess-bp-inactive-spec) fringe-face))
+              (put-text-property beg-pos-command (cdr pos)
+                                 'bp-active nil)
+              (ess-command (format ".ESSBP.[[%s]] <- TRUE\n" bp-id)))
+          (setq bp-specs (assoc (get-text-property (point) 'bp-type) ess-bp-type-spec-alist))
+          (put-text-property beg-pos-command (cdr pos)
+                             'bp-active t)
+          (put-text-property  (car pos) beg-pos-command
+                              'display (list 'left-fringe (nth 3 bp-specs) (nth 4 bp-specs)))
+          (ess-command (format ".ESSBP.[[%s]] <- NULL\n" bp-id))
+          ;; (insert (propertize "##"
+          ;;                     'ess-bp t
+          ;;                     'cursor-intangible 'ess-bp
+          ;;                     'display (propertize (nth 1 ess-bp-inactive-spec) 'face fringe-face)
+          ;;                     'bp-type (get-char-property (point) 'bp-type)
+          ;;                     'bp-substring 'comment))
+          )))))
+
+
+(defun ess-bp-make-visible ()
+  "Make bp text visible."
+  (interactive)
+  (let ((pos (ess-bp-get-bp-position-nearby)))
+    (set-text-properties (car pos) (cdr pos) (list 'display nil))))
+
+
+
+(defun ess-bp-next nil
+  "Goto next breakpoint."
+  (interactive)
+  (when-let* ((bp-pos (next-single-property-change (point) 'ess-bp)))
+    (save-excursion
+      (goto-char bp-pos)
+      (when (get-text-property (1- (point)) 'ess-bp)
+        (setq bp-pos (next-single-property-change bp-pos 'ess-bp))))
+    (if bp-pos
+        (goto-char bp-pos)
+      (message "No breakpoints found"))))
+
+
+(defun ess-bp-previous nil
+  "Goto previous breakpoint."
+  (interactive)
+  (if-let* ((bp-pos (previous-single-property-change (point) 'ess-bp)))
+      (goto-char (or (previous-single-property-change bp-pos 'ess-bp)
+                     bp-pos))
+    (message "No breakpoints before the point found")))
+
+;;;_ + WATCH
+
+(defvar ess-watch-command
+  ;; assumes that every expression is a structure of length 1 as returned by parse.
+  ".ess_watch_eval()\n")
+
+(if (fboundp 'define-fringe-bitmap) ;;not clear to me why is this not bound in SSH session? - :TODO check
+    (define-fringe-bitmap 'current-watch-bar
+      [#b00001100] nil nil '(top t)))
+
+(defun ess-tracebug--set-left-margin ()
+  "Set the margin on non-X displays."
+  (unless window-system
+    (when (= left-margin-width 0)
+      (setq left-margin-width 1)
+      (set-window-buffer (selected-window) (current-buffer)))))
+
+(define-derived-mode ess-watch-mode special-mode "ESS watch"
+  "Major mode in `ess-watch' window."
+  :group 'ess-tracebug
+  (let ((cur-block (max 1 (ess-watch-block-at-point)))
+        (dummy-string
+         (ess-tracebug--propertize "|" 'current-watch-bar 'font-lock-keyword-face)))
+    (ess-tracebug--set-left-margin)
+    (setq-local revert-buffer-function #'ess-watch-revert-buffer)
+    (turn-on-font-lock)
+    (setq ess-watch-current-block-overlay
+          (make-overlay (point-min) (point-max)))
+    (overlay-put ess-watch-current-block-overlay 'line-prefix dummy-string)
+    (overlay-put ess-watch-current-block-overlay 'face 'ess-watch-current-block-face)
+    (ess-watch-set-current cur-block) ;;
+    (require 'face-remap)
+    ;; scale the font
+    (setq text-scale-mode-amount ess-watch-scale-amount)
+    (text-scale-mode)))
+
+(defun ess-watch ()
+  "Run `ess-watch-mode' on R objects.
+This is the trigger function.  See documentation of
+`ess-watch-mode' for more information."
+  (interactive)
+  (ess-force-buffer-current)
+  (let ((wbuf (get-buffer-create ess-watch-buffer))
+        (pname ess-local-process-name))
+    (pop-to-buffer wbuf
+                   ;; not strongly dedicated
+                   '(nil . ((dedicated . 1))))
+    (setq ess-local-process-name pname)
+    (ess-watch-mode)
+    ;; evals the ess-command and displays the buffer if not visible
+    (ess-watch-refresh-buffer-visibly wbuf)))
+
+
+(defun ess-watch-refresh-buffer-visibly (wbuf &optional sleep no-prompt-check)
+  "Eval `ess-watch-command' and direct the output into the WBUF.
+Call `ess-watch-buffer-show' to make the buffer visible, without
+selecting it. SLEEP and NO-PROMPT-CHECK get passed to `ess-command'.
+
+This function is used for refreshing the watch window after each step during
+the debugging."
+  ;; assumes that the ess-watch-mode is on!!
+  ;; particularly ess-watch-current-block-overlay is installed
+  (ess-watch-buffer-show wbuf) ;; if visible do nothing
+  (let ((pname ess-local-process-name)) ;; watch might be used from different dialects, need to reset
+    (with-current-buffer wbuf
+      (let ((curr-block (max 1 (ess-watch-block-at-point))) ;;can be 0 if
+            (inhibit-read-only t))
+        (when pname
+          (setq ess-local-process-name pname))
+        (ess-command  ess-watch-command wbuf sleep no-prompt-check)
+        ;; delete the ++++++> line  ;; not very reliable but works fine so far.
+        (goto-char (point-min))
+        (delete-region (line-beginning-position) (+ 1 (line-end-position)))
+        (ess-watch-set-current curr-block)
+        (set-window-point (get-buffer-window wbuf) (point))))))
+
+(defun ess-watch-buffer-show (buffer-or-name)
+  "Make watch buffer BUFFER-OR-NAME visible, and position accordingly.
+If already visible, do nothing.
+
+Currently the only positioning rule implemented is to split the R
+process window in half.  The behavior is controlled by
+`split-window-sensibly' with parameters `split-height-threshold'
+and `split-width-threshold' replaced by
+`ess-watch-height-threshold' and `ess-watch-width-threshold'
+respectively."
+  (interactive)
+  (unless (get-buffer-window ess-watch-buffer 'visible)
+    (save-selected-window
+      (ess-switch-to-ESS t)
+      (let* ((split-width-threshold (or ess-watch-width-threshold
+                                        split-width-threshold))
+             (split-height-threshold (or ess-watch-height-threshold
+                                         split-height-threshold))
+             (win (split-window-sensibly (selected-window))))
+        (if win
+            (set-window-buffer win buffer-or-name)
+          (display-buffer buffer-or-name) ;; resort to usual mechanism if could not split
+          )))))
+
+
+(defun ess-watch-revert-buffer (_ignore _noconfirm)
+  "Update the watch buffer.
+Arguments IGNORE and NOCONFIRM currently not used."
+  (ess-watch)
+  (message "Watch reverted"))
+
+
+(defface ess-watch-current-block-face
+  '((default (:inherit highlight)))
+  "Face used to highlight current watch block."
+  :group 'ess-debug)
+
+(defvar  ess-watch-start-block "@----"  ;; fixme: make defcustom and modify the injected command correspondingly
+  "String indicating the beginning of a block in watch buffer."
+  ;; :group 'ess-debug
+  ;; :type 'string
+  )
+
+(defvar ess-watch-start-expression "@---:"
+  "String indicating the beginning of an R expression in watch buffer."
+  ;; :group 'ess-debug
+  ;; :type 'string
+  )
+
+(defun ess-watch-block-limits-at-point ()
+  "Return start and end positions of the watch block."
+  (interactive)
+  (save-excursion
+    (let ((curr (point))
+          start-pos end-pos)
+      (end-of-line)
+      (setq start-pos
+            (if (re-search-backward ess-watch-start-block nil t )
+                (point)
+              (point-min)))
+      (goto-char curr)
+      (beginning-of-line)
+      (setq end-pos
+            (if (re-search-forward ess-watch-start-block nil t)
+                (match-beginning 0)
+              (point-max)))
+      (list start-pos end-pos))))
+
+(defun ess-watch-block-at-point ()
+  "Return the current block's order count, 0 if no block was found."
+  (save-excursion
+    (let ((cur-point (point))
+          (count 0))
+      (goto-char (point-min))
+      (while (re-search-forward ess-watch-start-block cur-point t)
+        (setq count (1+ count)))
+      count)))
+
+(defun ess-watch-set-current (nr)
+  "Move the overlay over the block with count NR in current watch buffer."
+  (goto-char (point-min))
+  (re-search-forward ess-watch-start-expression nil t nr)
+  (goto-char (match-end 0))
+  (apply #'move-overlay ess-watch-current-block-overlay (ess-watch-block-limits-at-point)))
+
+
+(defun ess-watch--make-alist ()
+  "Create an alist of expressions from the current watch buffer.
+Each element of assoc list is of the form (pos name expr) where
+pos is an unique integer identifying watch blocks by position,
+name is a string giving the name of expression block, expr is a
+string giving the actual R expression."
+  (interactive)
+  (save-excursion
+    (let* ((reg-name (concat "^" ess-watch-start-block " *\\(\\S-*\\).*$"))
+           (reg-expr (concat "^" ess-watch-start-expression "\\s-*\\(.*\\)$"))
+           (reg-all (concat "\\(" reg-name "\\)\n\\(" reg-expr "\\)"))
+           (pos 0) wal name expr)
+      (goto-char (point-min))
+      (while (re-search-forward reg-all nil t)
+        (setq pos  (+ 1 pos))
+        (setq name (match-string-no-properties 2))
+        (setq expr (match-string-no-properties 4))
+        (if (not (eq (string-to-number name) 0))  ;;if number of any kind set the name to ""
+            (setq name ""))
+        (setq wal
+              (append wal (list (list pos name expr)))))
+      wal)))
+
+(defun ess-watch--parse-assoc (al)
+  "Return a string command ready to be passed to R process.
+The command is of the form `assign(\".ess_watch_expressions\",
+list(a = parse(expr_a), b= parse(expr_b)), envir = .GlobalEnv)'.
+AL is an association list as return by `ess-watch--make-alist'"
+  (concat ".ess_watch_assign_expressions(list("
+          (mapconcat (lambda (el)
+                       (if (> (length  (cadr el) ) 0)
+                           (concat "`" (cadr el) "` = parse(text = '" (caddr el) "')")
+                         (concat "parse(text = '" (caddr el) "')")))
+                     al ", ")
+          "))\n"))
+
+(defun ess-watch--install-.ess_watch_expressions ()
+  ;; used whenever watches are added/deleted/modified from the watch
+  ;; buffer. this is the only way  to insert expressions into
+  ;; .ess_watch_expressions object in R. Assumes R watch being the current
+  ;; buffer, otherwise will most likely install empty list.
+  (interactive)
+  (process-send-string (ess-get-process ess-current-process-name)
+                       (ess-watch--parse-assoc (ess-watch--make-alist)))
+  ;;TODO: delete the prompt at the end of proc buffer TODO: defun ess-send-string!!
+  (sleep-for 0.05)  ;; need here, if ess-command is used immediately after,  for some weird reason the process buffer will not be changed
+  )
+
+
+(defun ess-watch-quit ()
+  "Quit (kill) the watch buffer.
+If watch buffer exists, it is displayed during the debug
+process. The only way to avoid the display, is to kill the
+buffer."
+  (interactive)
+  (kill-buffer) ;; dedicated, window is deleted unless not the only one
+  )
+
+;;;_  + MOTION
+(defun ess-watch-next-block (&optional n)
+  "Move the overlay over the next block.
+Optional N if supplied gives the number of steps forward `backward-char'."
+  (interactive "P")
+  (setq n (prefix-numeric-value n))
+  (goto-char (overlay-end ess-watch-current-block-overlay))
+  (unless (re-search-forward ess-watch-start-expression nil t n)
+    (goto-char (point-min)) ;;circular but always moves to start!
+    (re-search-forward ess-watch-start-expression nil t 1))
+  (apply #'move-overlay ess-watch-current-block-overlay (ess-watch-block-limits-at-point)))
+
+(defun ess-watch-previous-block (&optional n)
+  "Move the overlay over the previous block.
+Optional N if supplied gives the number of backward steps."
+  (interactive "P")
+  (setq n (prefix-numeric-value n))
+  (goto-char (overlay-start ess-watch-current-block-overlay))
+  (unless (re-search-backward ess-watch-start-expression nil t n)
+    (goto-char (point-max)) ;;circular but always moves to last!
+    (re-search-backward ess-watch-start-expression nil t 1))
+  (goto-char (match-end 0))
+  (apply #'move-overlay ess-watch-current-block-overlay (ess-watch-block-limits-at-point)))
+
+;;;_  + BLOCK MANIPULATION and EDITING
+(defun ess-watch-rename ()
+  "Rename the currently selected watch block."
+  (interactive)
+  (end-of-line)
+  (unless (re-search-backward ess-watch-start-block nil t)
+    (error "Can not find a watch block"))
+  (let ((reg-name (concat ess-watch-start-block " *\\(\\S-*\\).*$"))
+        name start end)
+    ;; (reg-expr (concat "^" ess-watch-start-expression "\\s-*\\(.*\\)$"))
+    ;; (reg-all (concat "\\(" reg-name "\\)\n\\(" reg-expr "\\)"))
+    ;; (pos 0) wal name expr)
+    (unless (re-search-forward reg-name (line-end-position) t)
+      (error "Can not find the name substring in the current watch block "))
+    (setq name (match-string-no-properties 1))
+    (setq start (match-beginning 1))
+    (setq end (match-end 1))
+    (goto-char start)
+    ;; TODO: highlight the name in R-watch here
+    (setq name (read-string (concat "New name (" name "): ") nil nil name) )
+    (setq buffer-read-only nil)
+    (delete-region start end)
+    (insert name)
+    (setq buffer-read-only t)
+    (ess-watch--install-.ess_watch_expressions)
+    (ess-watch-refresh-buffer-visibly (current-buffer))))
+
+(defun ess-watch-edit-expression ()
+  "Edit in the minibuffer the R expression from the current watch block."
+  (interactive)
+  (end-of-line)
+  (unless (re-search-backward ess-watch-start-block nil 1)
+    (error "Can not find a watch block"))
+  (let ((reg-expr (concat ess-watch-start-expression " *\\(.*\\)$"))
+        expr start end)
+    (unless (re-search-forward reg-expr nil t)
+      (error "Can not find an expression string in the watch block"))
+    (setq expr (match-string-no-properties 1))
+    (setq start (match-beginning 1))
+    (setq end (match-end 1))
+    (goto-char start)
+    ;; TODO: highlight the name in R-watch here
+    (setq expr (read-string  "New expression: " expr nil expr) )
+    (setq buffer-read-only nil)
+    (delete-region start end)
+    (insert expr)
+    (setq buffer-read-only t)
+    (ess-watch--install-.ess_watch_expressions)
+    (ess-watch-refresh-buffer-visibly (current-buffer))))
+
+(defun ess-watch-add ()
+  "Ask for new R expression and append to the current list of watch expressions."
+  (interactive)
+  (let (nr expr name)
+    (goto-char (point-max))
+    (setq nr (number-to-string (1+ (ess-watch-block-at-point))))
+    (setq name nr)
+    ;; (setq name (read-string (concat "Name (" nr "):") nil nil nr ))  ;;this one is quite annoying and not really needed than for logging
+    (setq expr (read-string "New expression: " nil nil "\"Empty watch!\""))
+    (setq buffer-read-only nil)
+    (insert (concat "\n" ess-watch-start-block " " name " -@\n" ess-watch-start-expression " " expr "\n"))
+    (setq buffer-read-only t)
+    (ess-watch--install-.ess_watch_expressions)))
+
+(defun ess-watch-insert ()
+  "Ask for new R expression and name and insert it in front of current watch block."
+  (interactive)
+  (let (nr expr name)
+    (setq nr (number-to-string (ess-watch-block-at-point)))
+    (setq name nr)
+    ;; (setq name (read-string (concat "Name (" nr "):") nil nil nr ))
+    (setq expr (read-string "New expression: " nil nil "\"Empty watch!\""))
+    (re-search-backward ess-watch-start-block nil 1) ;;point-min if not found
+    (setq buffer-read-only nil)
+    (insert (concat "\n" ess-watch-start-block " " name " -@\n" ess-watch-start-expression " " expr "\n"))
+    (setq buffer-read-only t)
+    (ess-watch--install-.ess_watch_expressions)))
+
+(defun ess-watch-move-up ()
+  "Move the current block up."
+  (interactive)
+  (let ((nr (ess-watch-block-at-point))
+        wbl)
+    (when (> nr 1)
+      (setq buffer-read-only nil)
+      (setq wbl (apply #'delete-and-extract-region  (ess-watch-block-limits-at-point)))
+      (re-search-backward ess-watch-start-block nil t 1) ;; current block was deleted, point is at the end of previous block
+      (insert wbl)
+      (ess-watch--install-.ess_watch_expressions)
+      (setq buffer-read-only t))))
+
+
+(defun ess-watch-move-down ()
+  "Move the current block down."
+  (interactive)
+  (let ((nr (ess-watch-block-at-point))
+        (nr-all (save-excursion (goto-char (point-max))
+                                (ess-watch-block-at-point)))
+        wbl)
+    (when (< nr nr-all)
+      (setq buffer-read-only nil)
+      (setq wbl (apply #'delete-and-extract-region  (ess-watch-block-limits-at-point)))
+      (end-of-line)
+      (when (re-search-forward ess-watch-start-block nil t 1) ;; current block was deleted, point is at the end of previous block or point-max
+        (goto-char (match-beginning 0)))
+      (insert wbl)
+      (ess-watch--install-.ess_watch_expressions)
+      (setq buffer-read-only t))))
+
+(defun ess-watch-kill ()
+  "Kill the current block."
+  (interactive)
+  (setq buffer-read-only nil)
+  (apply #'delete-region (ess-watch-block-limits-at-point))
+  (ess-watch--install-.ess_watch_expressions))
+
+;;;_ + Debug/Undebug at point
+(defun ess--dbg-get-signatures (method)
+  "Get signatures for the method METHOD."
+  (let ((tbuffer (get-buffer-create " *ess-command-output*")); initial space: disable-undo
+        signatures)
+    (save-excursion
+      (ess-if-verbose-write (format "ess-get-signatures*(%s).. " method))
+      (ess-command (concat "showMethods(\"" method "\")\n") tbuffer)
+      (message "%s" ess-local-process-name)
+      (message "%s" ess-current-process-name)
+      (ess-if-verbose-write " [ok] ..\n")
+      (set-buffer tbuffer)
+      (goto-char (point-min))
+      (if (not (re-search-forward "Function:" nil t))
+          (progn (ess-if-verbose-write "not seeing \"Function:\".. \n")
+                 (error (buffer-string))
+                 ;; (error "Cannot trace  method '%s' (Is it a primitive method which you have already traced?)" method)
+                 )
+        ;; (setq curr-point (point))
+        ;; (while (re-search-forward ", " nil t) ;replace all ", " with  ":" for better readability in completion buffers??
+        ;;   (replace-match ":"))
+        ;; (goto-char curr-point)
+        (while (re-search-forward "^.+$" nil t)
+          (setq signatures (cons (match-string-no-properties 0) signatures))))
+                                        ;      (kill-buffer tbuffer)
+      )
+    signatures))
+
+
+(defun ess-debug-flag-for-debugging ()
+  "Set the debugging flag on a function.
+Ask the user for a function and if it turns to be generic, ask
+for signature and trace it with browser tracer."
+  (interactive)
+  (ess-force-buffer-current "Process to use: ")
+  (let* ((tbuffer (get-buffer-create " *ess-command-output*")) ;; output buffer name is hard-coded in ess-inf.el
+         (pkg (ess-r-package-name))
+         (all-functions (ess-get-words-from-vector--foreground
+                         (if pkg
+                             (format ".ess_all_functions(c('%s'))\n" pkg)
+                           ".ess_all_functions()\n")))
+         (obj-at-point (ess-helpobjs-at-point--read-obj))
+         (default (and
+                   obj-at-point
+                   (let* ((reg (regexp-quote obj-at-point))
+                          (matches (cl-loop for el in all-functions
+                                            if (string-match reg el) collect el)))
+                     (car (sort matches (lambda (a b) (< (length a) (length b))))))))
+         (ufunc (ess-completing-read "Debug" all-functions
+                                     nil nil nil nil (or default obj-at-point)))
+         signature)
+    ;; FIXME: Most of the following logic should be in R
+    (if (ess-boolean-command (format "as.character(isGeneric('%s'))\n" ufunc))
+
+        ;; it's S4 generic:
+        (save-excursion
+          ;; ask for exact signature
+          (setq signature
+                (ess-completing-read (concat "Method for generic '" ufunc "'")
+                                     (ess--dbg-get-signatures ufunc) ;signal an error if not found
+                                     nil t nil nil "*default*"))
+          (if (equal signature "*default*")
+              ;;debug, the default ufunc
+              (ess-command (format "trace('%s', tracer = browser)\n" ufunc) tbuffer)
+            (ess-command (format "trace('%s', tracer = browser, signature = c('%s'))\n" ufunc signature) tbuffer))
+          (with-current-buffer tbuffer
+            ;; give appropriate message or error
+            (message "%s" (buffer-substring-no-properties (point-min) (point-max)))))
+
+      ;;else, not an S4 generic
+      (when (ess-boolean-command (format "as.character(.knownS3Generics['%s'])\n" ufunc))
+        ;; it's S3 generic:
+        (setq all-functions
+              (ess-get-words-from-vector
+               (format "local({gens<-methods('%s');as.character(gens[attr(gens, 'info')$visible])})\n" ufunc)))
+        (setq all-functions
+              ;; cannot debug non-visible methods
+              (delq nil (mapcar (lambda (el)
+                                  (if (not (char-equal ?* (aref el (1- (length el))))) el))
+                                all-functions)))
+        (setq ufunc (ess-completing-read (format "Method for S3 generic '%s'" ufunc)
+                                         (cons ufunc all-functions) nil t)))
+      (ess-command (format ".ess_dbg_flag_for_debuging('%s')\n" ufunc)))))
+
+
+(defun ess-debug-unflag-for-debugging ()
+  "Prompt for the debugged/traced function or method and undebug/untrace it."
+  (interactive)
+  (let ((tbuffer (get-buffer-create " *ess-command-output*")); initial space: disable-undo\
+        (debugged (ess-get-words-from-vector
+                   (if nil ;; FIXME: was checking `ess-developer-packages`
+                       (format ".ess_dbg_getTracedAndDebugged(c('%s'))\n"
+                               (mapconcat 'identity ess-developer-packages "', '"))
+                     ".ess_dbg_getTracedAndDebugged()\n")))
+        out-message fun def-val)
+    ;; (prin1 debugged)
+    (if (eq (length debugged) 0)
+        (setq out-message "No debugged or traced functions/methods found")
+      (setq def-val (if (eq (length debugged) 1)
+                        (car debugged)
+                      "*ALL*"))
+      (setq fun (ess-completing-read "Undebug" debugged nil t nil nil def-val))
+      (if (equal fun "*ALL*" )
+          (ess-command (concat ".ess_dbg_UndebugALL(c(\""
+                               (mapconcat #'identity debugged "\", \"")
+                               "\"))\n")
+                       tbuffer)
+        (ess-command (format ".ess_dbg_UntraceOrUndebug(\"%s\")\n" fun) tbuffer))
+      (with-current-buffer  tbuffer
+        (if (= (point-max) 1) ;; not reliable TODO:
+            (setq out-message (format  "Undebugged '%s' " fun))
+          (setq out-message (buffer-substring-no-properties (point-min) (point-max))) ;; untrace info or warning, or error occurred
+          )))
+    (message "%s" out-message)))
+
+;;;_ * Kludges and Fixes
+;;; delete-char and delete-backward-car do not delete whole intangible text
+(defun ess--tracebug-delete-char (n &rest _)
+  "When deleting an intangible char, delete the whole intangible region.
+Only do this when N is 1"
+  (when (and (ess-derived-mode-p)
+             (= n 1)
+             (get-text-property (point) 'cursor-intangible))
+    (kill-region (point) (or (next-single-property-change (point) 'cursor-intangible)
+                             (point-max)))
+    (indent-according-to-mode)))
+
+(advice-add 'delete-char :before-until #'ess--tracebug-delete-char)
+
+(defun ess--tracebug-delete-backward-char (n &rest _)
+  "When deleting an intangible char, delete the whole intangible region.
+Only do this when called interactively and N is 1"
+  (when (and (ess-derived-mode-p)
+             (= n 1)
+             (> (point) (point-min))
+             (get-text-property (1- (point)) 'cursor-intangible))
+    (kill-region (or (previous-single-property-change (point) 'cursor-intangible)
+                     (point-min))
+                 (point))))
+
+(advice-add 'delete-backward-char :before-until #'ess--tracebug-delete-backward-char)
+
+(provide 'ess-tracebug)
+
+;;; ess-tracebug.el ends here
diff --git a/elpa/ess-20260424.1544/ess-trns.el b/elpa/ess-20260424.1544/ess-trns.el
new file mode 100644 (file)
index 0000000..42a62e9
--- /dev/null
@@ -0,0 +1,232 @@
+;;; ess-trns.el --- Support for manipulating S transcript files  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1989-2020 Free Software Foundation, Inc.
+;; Author: David Smith <dsmithNOSPAMstats.adelaide.edu.au>
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; Code for dealing with ESS transcripts.
+
+;;; Code:
+
+\f ; Requires and autoloads
+
+(require 'ess-mode)
+(require 'ess-inf)
+(require 'comint)
+
+(declare-function ess-display-help-on-object "ess-help" (object &optional command))
+
+\f ; ess-transcript-mode
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;; In this section:
+;;;;
+;;;; * The major mode ess-transcript-mode
+;;;; * Commands for ess-transcript-mode
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defcustom ess-transcript-mode-hook nil
+  "Hook for customizing ESS transcript mode."
+  :group 'ess-hooks
+  :type 'hook)
+
+;;*;; Major mode definition
+(defvar ess-transcript-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "\C-c\C-s" #'ess-switch-process)
+    (define-key map "\C-c\C-r" #'ess-eval-region)
+    (define-key map "\C-c\M-r" #'ess-eval-region-and-go)
+    (define-key map "\C-c\C-k" #'ess-force-buffer-current)
+    (define-key map "\C-c\C-q" #'ess-quit)
+    (define-key map "\C-c\C-j" #'ess-transcript-send-command)
+    (define-key map "\C-c\M-j" #'ess-transcript-send-command-and-move)
+    (define-key map "\M-\C-a"  #'ess-goto-end-of-function-or-para)
+    (define-key map "\M-\C-e"  #'ess-goto-end-of-function-or-para)
+    (define-key map "\C-c\C-y" #'ess-switch-to-ESS)
+    (define-key map "\C-c\C-z" #'ess-switch-to-end-of-ESS)
+    (define-key map "\C-c\C-v" #'ess-display-help-on-object)
+    (define-key map "\C-c\C-d" #'ess-dump-object-into-edit-buffer)
+    (define-key map "\C-a"     #'comint-bol)
+    (define-key map "\M-\t"    #'comint-replace-by-expanded-filename)
+    (define-key map "\M-?"     #'comint-dynamic-list-completions)
+    (define-key map "\C-c\C-k" #'ess-request-a-process)
+    (define-key map "{"        #'skeleton-pair-insert-maybe)
+    (define-key map "}"        #'skeleton-pair-insert-maybe)
+    (define-key map "\e\C-h"   #'ess-mark-function-or-para)
+    (define-key map "\e\C-q"   #'ess-indent-exp)
+    (define-key map "\t"       #'ess-indent-command)
+    (define-key map "\C-c\C-p" #'comint-previous-prompt)
+    (define-key map "\C-c\C-n" #'comint-next-prompt)
+    (define-key map "\r"       #'ess-transcript-send-command-and-move)
+    (define-key map "\M-\r"    #'ess-transcript-send-command)
+    (define-key map "\C-c\r"   #'ess-transcript-copy-command)
+    (define-key map "\C-c\C-w" #'ess-transcript-DO-clean-region)
+    (define-key map "\C-c\M-c" #'ess-transcript-clean-buffer)
+    map)
+  "Keymap for `ess-transcript-mode'.")
+
+(easy-menu-define
+  ess-transcript-mode-menu ess-transcript-mode-map
+  "Menu for use in S transcript mode."
+  '("ESS-trans"
+    ["Describe"         describe-mode                   t]
+    ["About"           (ess-goto-info "Transcript Mode") t]
+    ["Send bug report"  ess-submit-bug-report           t]
+    "------"
+    ["Mark cmd group"   mark-paragraph          t]
+    ["Previous prompt"  comint-previous-prompt  t]
+    ["Next prompt"      comint-next-prompt      t]
+    "------"
+    ["Send and move" ess-transcript-send-command-and-move t]
+    ["Copy command"  ess-transcript-copy-command       t]
+    ["Send command"  ess-transcript-send-command       t]
+    ["Clean Region"  ess-transcript-DO-clean-region    t]
+    ["Clean Whole Buffer" ess-transcript-clean-buffer  t]
+    ["Switch S process" ess-switch-process             t]
+    ))
+
+;;;###autoload
+(define-derived-mode ess-transcript-mode ess-mode "ESS Transcript"
+  "Major mode for transcript files.
+
+Type \\[ess-transcript-send-command] to send a command in the
+transcript to the current inferior process. \\[ess-transcript-copy-command]
+copies the command but does not execute it, allowing you to edit it in
+the process buffer first.
+
+Type \\[ess-transcript-clean-region] to delete all outputs and prompts
+in the region, leaving only the commands."
+  :group 'ess
+  (setq buffer-read-only t
+        ess-local-process-name nil
+        mode-line-process '(" [" ess-local-process-name "]"))
+  ;; TODO: Set this more normally in various major modes
+  (unless inferior-ess-prompt ;; For S languages it is set in custom-alist
+    (setq inferior-ess-prompt
+          ;; Do not anchor to bol with `^'
+          (concat "\\("
+                  inferior-ess-primary-prompt
+                  "\\|"
+                  inferior-ess-secondary-prompt
+                  "\\)")))
+  (setq-local paragraph-start (concat "^" inferior-ess-prompt "\\|^\^L"))
+  (setq-local paragraph-separate "^\^L")
+  (setq-local comint-use-prompt-regexp t)
+  (setq-local comint-prompt-regexp (concat "^" inferior-ess-prompt))
+  (setq font-lock-defaults '(ess-build-font-lock-keywords
+                             nil nil ((?\. . "w") (?\_ . "w") (?' . ".")))))
+
+;;*;; Commands used in S transcript mode
+
+(defun ess-transcript-send-command ()
+  "Send the command at point in the transcript to the ESS process.
+The line should begin with a prompt.  The ESS process buffer is displayed if it
+is not already."
+  (interactive)
+  (let* ((proc (or ess-local-process-name
+                   (ess-request-a-process "Evaluate into which process? " t)))
+         (ess-buf (ess-get-process-buffer proc)))
+    (setq ess-local-process-name proc)
+    (if (get-buffer-window ess-buf) nil
+      (display-buffer ess-buf t))
+    (let ((input (inferior-ess-get-old-input)))
+      (with-current-buffer ess-buf
+        (goto-char (point-max))
+        (ess-eval-linewise input)))))
+
+(defun ess-transcript-send-command-and-move ()
+  "Send the command on this line, and move point to the next command."
+  (interactive)
+  (let* ((proc (or ess-local-process-name
+                   (ess-request-a-process "Evaluate into which process? " t)))
+         (ess-buf (ess-get-process-buffer proc)))
+    (setq ess-local-process-name proc)
+    (if (get-buffer-window ess-buf) nil
+      (display-buffer ess-buf t))
+    (let ((input (inferior-ess-get-old-input)))
+      (with-current-buffer ess-buf
+        (goto-char (point-max))
+        (ess-eval-linewise input nil nil nil 1))))
+  (comint-next-prompt 1))
+
+(defun ess-transcript-copy-command ()
+  "Copy the command at point to the command line of the ESS process."
+  (interactive)
+  (let* ((proc (or ess-local-process-name
+                   (ess-request-a-process "Evaluate into which process? " t)))
+         (ess-buf (process-buffer (get-process proc)))
+         (input (inferior-ess-get-old-input)))
+    (setq ess-local-process-name proc)
+    (if (get-buffer-window ess-buf) nil
+      (display-buffer ess-buf t))
+    (with-current-buffer ess-buf
+      (goto-char (point-max))
+      (insert input)))
+  (ess-switch-to-end-of-ESS))
+
+(defun ess-transcript-clean-region (beg end even-if-read-only)
+  "Strip the transcript in the region, leaving only (R/S/Lsp/..) commands.
+Deletes any lines not beginning with a prompt, and then removes the
+prompt from those lines that remain.  Prefix argument means to
+clean even if the buffer is \\[read-only]."
+  (interactive "r\nP")
+  (unless inferior-ess-prompt
+    (error "Cannot clean ESS transcript region in this mode!
+ That only works in ess-transcript-mode or inferior-ess-mode ('*R*' etc)."
+           ;; Maybe call ess-clean-region-in-new-transcript ?"))
+           ))
+  (let ((do-toggle (and buffer-read-only even-if-read-only))
+        (ess-prompt-rx (if inferior-ess-secondary-prompt
+                           (concat "^\\(\\("
+                                   inferior-ess-prompt
+                                   "\\)\\|\\("
+                                   inferior-ess-secondary-prompt
+                                   "\\)\\)")
+                         (concat "^" inferior-ess-prompt))))
+    (save-excursion
+      (if do-toggle (setq buffer-read-only nil))
+      (save-restriction
+        (deactivate-mark)
+        (narrow-to-region beg end)
+        (goto-char (point-min))
+        (delete-non-matching-lines ess-prompt-rx)
+        (goto-char (point-min))
+        ;; (replace-regexp  *  * ) :
+        (while (re-search-forward ess-prompt-rx nil t)
+          (replace-match "" nil nil)))
+
+      (if do-toggle (setq buffer-read-only t)))))
+
+(defun ess-transcript-DO-clean-region (beg end)
+  "Clean the current via \\[ess-transcript-clean-region] even if the buffer is read-only."
+  (interactive "r")
+  (ess-transcript-clean-region beg end 'In-ANY-case))
+
+(defun ess-transcript-clean-buffer ()
+  "Cleanup the whole buffer.
+Use point-min/max to obey `narrow-to-region'."
+  (interactive)
+  (ess-transcript-clean-region (point-min) (point-max) 'In-ANY-case))
+
+(provide 'ess-trns)
+
+;;; ess-trns.el ends here
diff --git a/elpa/ess-20260424.1544/ess-utils.el b/elpa/ess-20260424.1544/ess-utils.el
new file mode 100644 (file)
index 0000000..24cf280
--- /dev/null
@@ -0,0 +1,1144 @@
+;;; ess-utils.el --- General Emacs utility functions used by ESS  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1998-2022 Free Software Foundation, Inc.
+;; Author: Martin Maechler <maechlerNOSPAMstat.math.ethz.ch>
+;; Created: 9 Sept 1998
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+;; Various utilities for ESS.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'comint)
+(require 'project)
+(eval-when-compile
+  (require 'tramp))
+;; The only ESS file this file should depend on is ess-custom.el
+(require 'ess-custom)
+
+(defvar ac-modes)
+(declare-function ess-eval-linewise "ess-inf" (text &optional invisibly eob even-empty wait-last-prompt sleep-sec wait-sec))
+(declare-function color-lighten-name "color" (name percent))
+(declare-function tramp-dissect-file-name "tramp" (name &optional nodefault))
+;; The following declares can be removed once we drop Emacs 25
+(declare-function tramp-file-name-method "tramp")
+(declare-function tramp-file-name-user "tramp")
+(declare-function tramp-file-name-host "tramp")
+(declare-function tramp-file-name-localname "tramp")
+(declare-function tramp-file-name-hop "tramp")
+
+\f
+;;*;; elisp tools
+
+(defun ess-next-code-line (&optional arg skip-to-eob)
+  "Move ARG lines of code forward (backward if ARG is negative).
+If `ess-eval-empty' is non-nil, skip past all empty and comment
+lines. ARG is 1 by default. If ARG is 0 only comments are skipped
+forward. Don't skip the last empty and comment lines in the
+buffer unless SKIP-TO-EOB is non-nil. On success, return 0.
+Otherwise go as far as possible and return -1."
+  (interactive "p")
+  (if (or ess-eval-empty
+          (and (fboundp 'ess-roxy-entry-p)
+               (ess-roxy-entry-p)))
+      (forward-line arg)
+    (setq arg (or arg 1))
+    (beginning-of-line)
+    (let ((pos (point))
+          (inc (if (>= arg 0) 1 -1))
+          (cnt (if (= arg 0) 1 arg))
+          (out 0))
+      ;; when orig-arg == 0, we skip only comments
+      (while (and (/= cnt 0) (= out 0))
+        (unless (= arg 0)
+          (setq out (forward-line inc)))     ; out==0 means success
+        (comment-beginning)
+        (beginning-of-line)
+        (forward-comment (* inc (buffer-size))) ;; as suggested in info file
+        (if (or skip-to-eob
+                (not (looking-at ess-no-skip-regexp))) ;; don't go to eob or whatever
+            (setq cnt (- cnt inc))
+          (goto-char pos)
+          (setq cnt 0)
+          (forward-line inc)) ;; stop at next empty line
+        (setq pos (point)))
+      (goto-char pos)
+      out)))
+
+(defun ess-goto-line (line)
+  "Go to LINE in the widened buffer."
+  (save-restriction
+    (widen)
+    (goto-char (point-min))
+    (forward-line (1- line))))
+
+(defun ess-skip-thing (thing)
+  "Leave point at the end of THING.
+THING can be \\='function, \\='paragraph, or \\='line."
+  (cond
+   ((eql thing 'line) (goto-char (line-end-position)))
+   ((eql thing 'paragraph) (forward-paragraph))
+   ((eql thing 'function) (end-of-defun) (skip-chars-backward " \t\n"))))
+
+(defun ess-search-except (regexp &optional except backward)
+  "Search for a REGEXP and store as match 1.
+Optionally ignore strings that match EXCEPT. If BACKWARD is
+non-nil, search backward."
+  (let ((continue t) (exit nil))
+    (while continue
+      (if (or (and backward (search-backward-regexp regexp nil t))
+              (and (not backward) (search-forward-regexp regexp nil t)))
+          (progn
+            (setq exit (match-string 1))
+            (setq continue (and except (string-match except exit)))
+            (if continue (setq exit nil)))
+        ;;else
+        (setq continue nil)))
+    exit))
+
+(defun ess-save-and-set-local-variables ()
+  "If buffer was modified, save file and set Local Variables if defined.
+Return t if buffer was modified, nil otherwise."
+  (let ((ess-temp-return-value (buffer-modified-p)))
+    (save-buffer)
+    (hack-local-variables)
+    ess-temp-return-value))
+
+(defun ess-get-file-or-buffer (file-or-buffer)
+  "Return FILE-OR-BUFFER if it is a buffer.
+Otherwise return the buffer associated with the file which must
+be qualified by it's path; if the buffer does not exist, return
+nil."
+  (declare (side-effect-free t)
+           (obsolete nil "ESS 19.04"))
+  (if (bufferp file-or-buffer)
+      file-or-buffer
+    (find-buffer-visiting file-or-buffer)))
+
+(defun ess-file-content (file)
+  "Return the content of FILE as string."
+  (if (file-exists-p file)
+      (with-temp-buffer
+        (insert-file-contents-literally file)
+        (buffer-string))
+    (error "File '%s' does not exist" file)))
+
+(defun ess-uniq (list predicate)
+  "Uniquify LIST, stably, deleting elements using PREDICATE.
+Return the list with subsequent duplicate items removed by side effects.
+PREDICATE is called with an element of LIST and a list of elements from LIST,
+and should return the list of elements with occurrences of the element removed.
+This function will work even if LIST is unsorted.  See also `delete-dups'."
+  (declare (obsolete 'delete-dups "ESS 19.04"))
+  (let ((list list))
+    (while list
+      (setq list (setcdr list (funcall predicate (car list) (cdr list))))))
+  list)
+
+(define-obsolete-function-alias 'ess-uniq-list #'delete-dups "ESS 19.04")
+
+(defalias 'ess-flatten-list
+  ;; `flatten-tree' is a function in Emacs 27
+  (if (fboundp 'flatten-tree)
+      'flatten-tree
+    (lambda (list)
+      "Take the arguments and flatten them into one long LIST.
+Drops `nil' entries."
+      ;; Taken from lpr.el
+      ;; `lpr-flatten-list' is defined here (copied from "message.el" and
+      ;; enhanced to handle dotted pairs as well) until we can get some
+      ;; sensible autoloads, or `flatten-list' gets put somewhere decent.
+      (ess-flatten-list-1 list))))
+
+(defun ess-flatten-list-1 (list)
+  "Internal helper for `ess-flatten-list', which see for LIST."
+  (cond
+   ((null list) (list))
+   ((consp list)
+    (append (ess-flatten-list-1 (car list))
+            (ess-flatten-list-1 (cdr list))))
+   (t (list list))))
+
+(define-obsolete-function-alias 'ess-delete-blank-lines
+  #'delete-blank-lines "ESS 19.04")
+
+(define-obsolete-function-alias 'ess-line-to-list-of-words #'split-string "ESS 19.04")
+
+(defmacro ess--exit-protect (body &rest exit)
+  "Run EXIT when BODY exits early.
+Unlike `unwind-protect', the unwind forms only run in case of
+early exits. Unlike `condition-case', they run inconditionally,
+no matter the reason for exiting early (e.g. error or quit)."
+  (declare
+   (indent 1)
+   (debug (form &rest form)))
+  `(let ((--early-exit t))
+     (unwind-protect
+         (prog1 ,body (setq --early-exit nil))
+       (when --early-exit
+         ,@exit))))
+
+\f
+;;*;; System
+
+(defun ess-revert-wisely ()
+  "Revert from disk if file and buffer last modification times are different."
+  (interactive)
+  ;; whether or not a revert is needed, force load local variables
+  ;; for example, suppose that you change the local variables and then
+  ;; save the file, a revert is unneeded, but a force load is
+  (hack-local-variables)
+  (unless (verify-visited-file-modtime (current-buffer))
+    (progn
+      (let ((ess-temp-store-point (point)))
+        (revert-buffer t t)
+        (goto-char ess-temp-store-point))
+      t)))
+
+(define-obsolete-function-alias 'ess-find-exec #'ess-find-exec-completions "ESS 19.04")
+(defun ess-find-exec-completions (root)
+  "Given the ROOT of an executable file name, find all possible completions.
+Search for the executables in the variable `exec-path'."
+  (let (executables)
+    (dolist (dir exec-path)
+      (when (and (> (length dir) 0)
+                 (file-accessible-directory-p dir))
+        ;; the first test above excludes "" from exec-path, which can be
+        ;; problematic with Tramp.
+        (dolist (f (file-name-all-completions root dir))
+          (setq f (expand-file-name f dir))
+          (when (and (file-executable-p f)
+                     (not (backup-file-name-p f))
+                     (not (file-directory-p f)))
+            (push f executables)))))
+    executables))
+
+(defun ess-drop-non-directories (file-strings)
+  "Drop all entries in FILE-STRINGS that do not \"look like\" directories."
+  (ess-flatten-list (mapcar #'file-name-directory file-strings)))
+
+(defun ess--parent-dir (path n)
+  "Return Nth parent of PATH."
+  (let ((opath path))
+    (while (and path (> n 0))
+      (setq path (file-name-directory (directory-file-name opath)))
+      (if (equal path opath)
+          (setq path nil)
+        (setq opath path
+              n (1- n))))
+    path))
+
+\f
+;;*;; Interaction with inferiors
+
+(defmacro ess-when-new-input (time-var &rest body)
+  "BODY is evaluate only if the value of process variable TIME-VAR
+is bigger than the time of the last user input (stored in
+`last-eval' process variable). TIME-VAR is the name of the
+process variable which holds the access time. See the code for
+`ess-synchronize-dirs' and `ess-cache-search-list'.
+
+Returns nil when no current process, or process is busy, or
+time-var > last-eval. Otherwise, execute BODY and return the last
+value.
+
+If BODY is executed, set process variable TIME-VAR
+to (current-time).
+
+Variable  *proc*  is bound  to  the  current process  during  the
+evaluation of BODY.
+
+Should be used in `ess-idle-timer-functions' which call the
+process to avoid excessive requests."
+  (declare (indent 1) (debug t))
+  `(with-ess-process-buffer 'no-error
+     (let ((le (process-get *proc* 'last-eval))
+           (tv (process-get *proc* ',time-var)))
+       (when (and (or (null tv) (null le) (time-less-p tv le))
+                  (not (process-get *proc* 'busy)))
+         (let ((out (progn ,@body)))
+           (process-put *proc* ',time-var (current-time))
+           out)))))
+
+(defmacro with-ess-process-buffer (no-error &rest body)
+  "Execute BODY in the process buffer of `ess-current-process-name'.
+If NO-ERROR is t don't trigger error when there is not current
+process. Symbol *proc* is bound to the current process during the
+evaluation of BODY."
+  (declare (indent 1) (debug t))
+  `(let ((*proc* (and ess-local-process-name (get-process ess-local-process-name))))
+     (if *proc*
+         (with-current-buffer (process-buffer *proc*)
+           ,@body)
+       (unless ,no-error
+         (error "No current ESS process")))))
+
+\f
+;;*;; Emacs Integration
+
+(defun ess-derived-mode-p ()
+  "Non-nil if the current major mode is an ESS major mode."
+  (or (derived-mode-p 'ess-mode)
+      (derived-mode-p 'ess-julia-mode)))
+
+(defun ess--generate-eval-visibly-submenu (_menu)
+  '(["yes" (lambda () (interactive) (setq ess-eval-visibly t))
+     :style radio :enable t :selected (eq ess-eval-visibly t)]
+    ["nowait" (lambda () (interactive) (setq ess-eval-visibly 'nowait))
+     :style radio :enable t :selected (eq ess-eval-visibly 'nowait) ]
+    ["no" (lambda () (interactive) (setq ess-eval-visibly nil))
+     :style radio :enable t :selected (eq ess-eval-visibly nil) ]))
+
+;; Font Lock
+
+(defun ess--fl-keywords-values ()
+  "Return a cons (STANDARD-VALUE . CUSTOM-VALUE) of `ess-font-lock-keywords'."
+  (let ((sym ess-font-lock-keywords))
+    (if (and (symbolp sym)
+             (custom-variable-p sym))
+        (cons
+         (eval (car (get sym 'standard-value)) t)
+         (symbol-value sym))
+      (error "`ess-font-lock-keywords' must be a symbol of a custom variable"))))
+
+(defun ess--extract-fl-keywords ()
+  (let ((values (ess--fl-keywords-values)))
+    (mapcar (lambda (kv)
+              (let ((cust-kv (assoc (car kv) (cdr values))))
+                (when cust-kv
+                  (setcdr kv (cdr cust-kv))))
+              kv)
+            (copy-alist (car values)))))
+
+(defun ess-build-font-lock-keywords ()
+  "Retrieve `font-lock-keywords' from ess-[dialect]-font-lock-keywords.
+Merge the customized values of that variable on top of the
+standard values and return the new list. For this to work,
+`ess-font-lock-keywords' should be a name of the
+ess-[dialect]-font-lock-keywords variable."
+  (delq nil
+        (mapcar (lambda (c)
+                  (when (cdr c)
+                    (symbol-value (car c))))
+                (ess--extract-fl-keywords))))
+
+(defun ess-font-lock-toggle-keyword (keyword)
+  "Toggle KEYWORD font-lock."
+  (interactive
+   (list (intern (ess-completing-read
+                  "Keyword to toggle"
+                  (mapcar (lambda (el) (symbol-name (car el)))
+                          (car (ess--fl-keywords-values)))
+                  nil t))))
+  (let* ((values (ess--fl-keywords-values))
+         (kwd (cond
+               ;; already in custom values
+               ((assoc keyword (cdr values)))
+               ;; if keyword is not already in custom values (can happen if
+               ;; we add new keywords but the user has the old value saved in
+               ;; .emacs-custom.el)
+               ((let ((kwd (assoc keyword (car values)))
+                      (sym ess-font-lock-keywords))
+                  (when kwd
+                    (set sym (cons kwd (symbol-value sym)))
+                    kwd)))
+               (t (error "Invalid keyword %s" keyword)))))
+    (setcdr kwd (not (cdr kwd)))
+    (let ((mode major-mode)
+          (dialect ess-dialect))
+      ;; refresh font-lock defaults in all relevant buffers
+      (mapc (lambda (b)
+              (with-current-buffer b
+                (when (and (eq major-mode mode)
+                           (eq ess-dialect dialect))
+                  (font-lock-refresh-defaults))))
+            (buffer-list)))))
+
+(defun ess--generate-font-lock-submenu (_menu)
+  "Generate ESS font-lock submenu."
+  (append (mapcar (lambda (el)
+                    `[,(symbol-name (car el))
+                      (lambda () (interactive)
+                        (ess-font-lock-toggle-keyword ',(car el)))
+                      :style toggle
+                      :enable t
+                      :selected ,(cdr el)])
+                  (ess--extract-fl-keywords))
+          (list "-----"
+                ["Save to custom"
+                 (lambda () (interactive)
+                   (customize-save-variable ess-font-lock-keywords
+                                            (ess--extract-fl-keywords)))
+                 t])))
+
+(declare-function untrace-function "trace" ())
+(defvar ess--is-tracing nil)
+
+;;;###autoload
+(define-minor-mode ess-elisp-trace-mode
+  "Toggle tracing of ess-prefixed functions.
+Tracing is useful for debugging background ESS behaviour. When
+enabled, all functions prefixed in `ess-' and `inferior-ess' are
+instrumented with `trace-function'. Tracing is turned off by
+calling `untrace-function' on these functions."
+  :global t
+  :group 'ess
+  (let ((fns (append (all-completions "ess-" obarray)
+                     (all-completions "inferior-ess-" obarray)
+                     (list "update-ess-process-name-list"
+                           "forward-ess-r-expr"
+                           "forward-ess-r-sexp"
+                           "backward-ess-r-expr"
+                           "backward-ess-r-sexp"
+                           "company-ess-julia-objects"
+                           "run-ess-r"
+                           "run-ess-r-newest")))
+        (do (symbol-function (if ess-elisp-trace-mode
+                                 #'untrace-function
+                               #'trace-function))))
+    (dolist (fn fns)
+      (when (symbol-function (intern fn))
+        (funcall do (intern fn))))))
+
+\f
+;;*;; External modes
+
+;; Define these here for the byte compiler since ido dynamically
+;; let-binds them:
+(defvar ido-choice-list)
+(defvar ido-context-switch-command)
+(defvar ido-directory-too-big)
+(defvar ido-directory-nonreadable)
+(defvar ido-current-directory)
+(defvar ido-enable-flex-matching)
+(declare-function ido-choose-completion-string "ido")
+(declare-function ido-minibuffer-setup "ido")
+(declare-function ido-read-internal "ido" (item prompt hist &optional default require-match initial))
+
+(defun ess-completing-read (prompt collection &optional predicate
+                                   require-match initial-input hist def)
+  "Read a string in the minibuffer, with completion.
+Use `ido-completing-read' if IDO interface is present, or fall
+back on classical `completing-read' otherwise. Meaning of PROMPT,
+COLLECTION, PREDICATE, REQUIRE-MATCH, INITIAL-INPUT, HIST, and
+DEF is as in `completing-read'. PROMPT is automatically suffixed
+with ': ' and (default %s) when needed. If HIST is nil use
+`ess--completing-hist' as history. See also `ess-use-ido'."
+  (let ((use-ido (and ess-use-ido (require 'ido nil t))))
+    (setq hist (or hist 'ess--completing-hist))
+    (when (and def (not use-ido)) ;; ido places in front and highlights the default
+      (setq prompt (format "%s(default %s)" prompt def)))
+    (setq prompt (concat prompt ": "))
+    (if use-ido
+        (let ((reset-ido (and use-ido (not ido-mode))) ;people not using ido but having it)
+              (ido-current-directory nil)
+              (ido-directory-nonreadable nil)
+              (ido-directory-too-big nil)
+              (ido-context-switch-command 'ignore)
+              (ido-enable-flex-matching ess-ido-flex-matching) ;it's fast and useful, may be get into options
+              (ido-choice-list (copy-sequence collection)) ;ido removes the match (reported)
+              sel)
+          (unwind-protect
+              (progn
+                (add-hook 'minibuffer-setup-hook #'ido-minibuffer-setup)
+                (add-hook 'choose-completion-string-functions #'ido-choose-completion-string)
+                (setq sel (ido-read-internal 'list prompt hist def require-match initial-input))
+                (when hist  ;; ido does not push into hist the whole match if C-SPC or RET is used (reported)
+                  (unless (string= sel (car (symbol-value hist)))
+                    (set hist (cons sel  (symbol-value hist))))))
+            (when reset-ido
+              (remove-hook 'minibuffer-setup-hook #'ido-minibuffer-setup)
+              (remove-hook 'choose-completion-string-functions #'ido-choose-completion-string)))
+          sel)
+      ;; else usual completion
+      (completing-read prompt collection predicate require-match initial-input hist def))))
+
+(defun ess--setup-auto-complete (sources &optional inferior)
+  "Setup auto-complete depending on user settings.
+SOURCES gets added to `ac-sources', INFERIOR should be t for
+inferior buffers."
+  ;; auto-complete
+  (when (and (boundp 'ac-sources)
+             (if inferior
+                 (eq ess-use-auto-complete t)
+               ess-use-auto-complete))
+    (add-to-list 'ac-modes major-mode)
+    ;; files should be in front; ugly, but needed
+    (setq ac-sources
+          (delq 'ac-source-filename ac-sources))
+    (mapc (lambda (el) (add-to-list 'ac-sources el))
+          sources)
+    (add-to-list 'ac-sources 'ac-source-filename)))
+
+(defun ess--setup-company (sources &optional inferior)
+  "Setup company depending on user settings.
+SOURCES gets added to `company-backends', and when t, INFERIOR
+specifies inferior buffers."
+  ;; company
+  (when (and (boundp 'company-backends)
+             (if inferior
+                 (eq ess-use-company t)
+               ess-use-company))
+    (setq-local company-backends
+                (cl-copy-list (append sources company-backends)))
+    (delq 'company-capf company-backends)))
+
+(defun ess--setup-eldoc (fun)
+  "Setup support for eldoc.
+FUN is the function to return data for eldoc."
+  (when ess-use-eldoc
+    (if (not (boundp 'eldoc-documentation-functions))
+        ;; older versions of Eldoc included in Emacs 27 and previous
+        (add-function :before-until (local 'eldoc-documentation-function)
+                      fun)
+      ;; new eldoc, in Emacs 28+
+      (add-hook 'eldoc-documentation-functions fun nil t)
+      ;; Eldoc is on GNU ELPA so you can have new eldoc + Emacs 27.1
+      ;; or older, see bug#1130 and Emacs bug # 47388 for why we have
+      ;; to do this
+      (when (and (fboundp 'eldoc-documentation-default)
+                 (function-equal #'ignore eldoc-documentation-function))
+        (setq-local eldoc-documentation-function #'eldoc-documentation-default)))))
+
+(defmacro ess--execute-electric-command (map &optional prompt wait exit-form &rest args)
+  "Execute keys defined in MAP till a key is pressed which is not in MAP.
+Single-key input commands are those that once executed do not
+require the prefix command for subsequent invocation. Return the
+value of the lastly executed command. PROMPT is passed to
+`read-event'.
+
+If WAIT is t, wait for next input and ignore the keystroke which
+triggered the command.
+
+Each command in map should accept one at least one argument, the
+most recent event (as read by `read-event'). ARGS are the
+supplementary arguments passed to the commands.
+
+EXIT-FORM should be supplied for a more refined control of the
+read-even loop. The loop is exited when EXIT-FORM evaluates to
+t. See examples in the tracebug code."
+  ;;VS[09-06-2013]: check: it seems that set-temporary-overlay-map is designed
+  ;;for this type of things; see also repeat.el package.
+  `(let* ((ev last-command-event)
+          (command (lookup-key ,map (vector ev)))
+          out exit )
+     (if (not (or ,wait command))
+         (message "%s is undefined" (key-description (this-command-keys)))
+       (unless ,wait
+         (setq out (and command (funcall command ev ,@args))))
+       (while (and (not exit)
+                   (setq command
+                         (lookup-key ,map
+                                     (vector (setq ev (read-event ,prompt))))))
+         (setq out (funcall command ev ,@args))
+         (sleep-for .01)
+         (setq exit ,exit-form))
+       (unless exit ;; push only if an event triggered the exit
+         (push ev unread-command-events))
+       out)))
+
+(cl-defgeneric ess-build-tags-command ()
+  "Command passed to generate tags.
+If nil, `ess-build-tags-for-directory' uses the mode's imenu
+expression. Otherwise, it should be a string with two %s
+formats: one for directory and another for the output file."
+  nil)
+
+\f
+;;*;; Emacs itself
+
+(defun ess-yank-cleaned-commands ()
+  "Yank and strip the code, leaving only (R/S/Lsp/..) commands.
+Deletes any lines not beginning with a prompt, and then removes
+the prompt from those lines that remain. Invoke this command with
+\\[universal-argument] \\[universal-argument] \\<ess-mode-map>\\[yank]."
+  (setq yank-window-start (window-start))
+  (let ((beg (point)))
+    (push-mark beg)
+    (setq this-command t)
+    (insert-for-yank (current-kill 0))
+    (when (and (require 'ess-trns) (fboundp 'ess-transcript-clean-region))
+      (ess-transcript-clean-region beg (point) nil))
+    (if (eq (point) beg)
+        (message "No commands found"))
+    (if (eq this-command t)
+        (setq this-command 'yank))))
+
+(defun ess-yank (&optional arg)
+  "Variant of `yank' that optionally extracts commands from transcripts.
+When called with double prefix ARG (\\[universal-argument]
+\\[universal-argument]), calls `ess-transcript-clean-region'
+before yanking. See `ess-yank-cleaned-commands'."
+  (interactive "*P")
+  (if (equal '(16) arg)
+      (ess-yank-cleaned-commands)
+    (let* ((remapped (command-remapping 'yank (point)))
+           (command (cond ((eq remapped 'ess-yank) 'yank)
+                          ((null remapped) 'yank)
+                          (t remapped))))
+      (funcall command arg))))
+
+(put 'ess-yank 'delete-selection 'yank)
+
+(defun ess-build-tags-for-directory (dir tagfile)
+  "Ask for directory and tag file and build tags for current dialect.
+If the current language defines `ess-build-tags-command' use it
+and ask the subprocess to build the tags. Otherwise use imenu
+regexp and call find .. | etags .. in a shell command. You must
+have `find' and `etags' programs installed.
+
+Use M-. to navigate to a tag. \\[visit-tags-table] to
+append/replace the currently used tag table.
+
+If prefix is given, force tag generation based on imenu. Might be
+useful when different language files are also present in the
+directory (.cpp, .c etc)."
+  (interactive "DDirectory to tag:
+GTags file (default TAGS): ")
+  (when (or (eq (length (file-name-nondirectory tagfile)) 0)
+            (file-directory-p tagfile))
+    (setq tagfile (concat (file-name-as-directory tagfile) "TAGS")))
+  ;; Emacs find-tags doesn't play well with remote TAG files :(
+  (when (file-remote-p tagfile)
+    (require 'tramp)
+    (setq tagfile (with-parsed-tramp-file-name tagfile foo foo-localname)))
+  (when (file-remote-p dir)
+    (require 'tramp)
+    (setq dir (with-parsed-tramp-file-name dir foo foo-localname)))
+  (if (and (ess-build-tags-command) (null current-prefix-arg))
+      (ess-eval-linewise (format (ess-build-tags-command) dir tagfile))
+    ;; else generate from imenu
+    (unless imenu-generic-expression
+      (error "No ess-tag-command found, and no imenu-generic-expression defined"))
+    (let* ((find-cmd
+            (format "find %s -type f -size 1M \\( -regex \".*\\.\\(cpp\\|jl\\|[RsrSch]\\(nw\\)?\\)$\" \\)" dir))
+           (regs (delq nil (mapcar (lambda (l)
+                                     (if (string-match "'" (cadr l))
+                                         nil ;; remove for time being
+                                       (format "/%s/\\%d/"
+                                               (replace-regexp-in-string "/" "\\/" (nth 1 l) t)
+                                               (nth 2 l))))
+                                   imenu-generic-expression)))
+           (tags-cmd (format "etags -o %s --regex='%s' -" tagfile
+                             (mapconcat #'identity regs "' --regex='"))))
+      (message "Building tags: %s" tagfile)
+      (when (= 0 (shell-command (format "%s | %s" find-cmd tags-cmd)))
+        (message "Building tags .. ok!")))))
+
+\f
+;;*;; UI
+
+(defvar ess-current-region-overlay
+  (let ((overlay (make-overlay (point) (point))))
+    (overlay-put overlay 'face  'highlight)
+    overlay)
+  "The overlay for highlighting currently evaluated region or line.")
+
+(defun ess-blink-region (start end)
+  "Blink from START to END depending on option `ess-blink-region'."
+  (when ess-blink-region
+    (move-overlay ess-current-region-overlay start end)
+    (run-with-timer ess-blink-delay nil
+                    (lambda ()
+                      (delete-overlay ess-current-region-overlay)))))
+
+(defun ess-deactivate-mark ()
+  "Deactivate the mark, if active.
+If `evil-mode' is on, switch to `evil-normal-state'."
+  (if (and (bound-and-true-p evil-mode)
+           (fboundp 'evil-visual-state-p)
+           (evil-visual-state-p))
+      (when (fboundp 'evil-normal-state)
+        (evil-normal-state))
+    (when mark-active
+      (deactivate-mark))))
+
+;; SJE: 2009-01-30 -- this contribution from
+;; Erik Iverson <iversonNOSPAMbiostat.wisc.edu>
+
+(defun ess-tooltip-show-at-point (text xo yo)
+  "Show a tooltip displaying TEXT at (around) point.
+XO and YO are x- and y-offsets for the toolbar from point."
+  (let (
+        (fx (frame-parameter nil 'left))
+        (fy (frame-parameter nil 'top))
+        (fw (frame-pixel-width))
+        (fh (frame-pixel-height))
+        frame-left frame-top my-x-offset my-y-offset)
+    ;; The following comment was found before code looking much like that
+    ;; of frame-left and frame-top below in the file
+    ;; tooltip-help.el. I include it here for acknowledgment, and I did observe
+    ;; the same behavior with the Emacs window maximized under Windows XP.
+
+    ;; -----original comment--------
+    ;; handles the case where (frame-parameter nil 'top) or
+    ;; (frame-parameter nil 'left) return something like (+ -4).
+    ;; This was the case where e.g. Emacs window is maximized, at
+    ;; least on Windows XP. The handling code is "shamelessly
+    ;; stolen" from cedet/speedbar/dframe.el
+    ;; (contributed by Andrey Grigoriev)
+    (setq frame-left (if (not (consp fx))
+                         fx
+                       (if (eq (car fx) '-)
+                           (- (display-pixel-width) (car (cdr fx)) fw)
+                         (car (cdr fx)))))
+    (setq frame-top (if (not (consp fy))
+                        fy
+                      (if (eq (car fy) '-)
+                          (- (display-pixel-height) (car (cdr fy)) fh)
+                        (car (cdr fy)))))
+    ;; calculate the offset from point, use xo and yo to adjust to preference
+    (setq my-x-offset (+ (car(window-inside-pixel-edges))
+                         (car(posn-x-y (posn-at-point)))
+                         frame-left xo))
+    (setq my-y-offset (+ (cadr(window-inside-pixel-edges))
+                         (cdr(posn-x-y (posn-at-point)))
+                         frame-top yo))
+    (let ((tooltip-frame-parameters
+           (cons (cons 'top my-y-offset)
+                 (cons (cons 'left my-x-offset)
+                       tooltip-frame-parameters))))
+      (tooltip-show text))))
+
+(defun ess-select-frame-set-input-focus (frame)
+  "Select FRAME, raise it, and set input focus, if possible.
+Copied almost verbatim from gnus-utils.el (but with test for mac added)."
+  ;; The function `select-frame-set-input-focus' won't set
+  ;; the input focus under Emacs 21.2 and X window system.
+  ;;((fboundp 'select-frame-set-input-focus)
+  ;; (defalias 'gnus-select-frame-set-input-focus
+  ;;   'select-frame-set-input-focus)
+  ;; (select-frame-set-input-focus frame))
+  (raise-frame frame)
+  (select-frame frame)
+  (cond ((and
+          (memq window-system '(x mac))
+          (fboundp 'x-focus-frame))
+         (x-focus-frame frame))
+        ((and (eq window-system 'w32)
+              ;; silence byte compiler warnings about w32-fns
+              (fboundp 'w32-focus-frame))
+         (w32-focus-frame frame)))
+  (when focus-follows-mouse
+    (set-mouse-position frame (1- (frame-width frame)) 0)))
+
+(define-obsolete-function-alias 'ess-do-auto-fill #'do-auto-fill "ESS 19.04")
+
+\f
+;;*;; Syntax
+
+(defun ess-containing-sexp-position ()
+  "Return the `cadr' of `syntax-ppss'."
+  (cadr (syntax-ppss)))
+
+(defun ess-code-end-position ()
+  "Like (line-end-position) but stops at comments."
+  (save-excursion
+    (goto-char (1+ (line-end-position)))
+    (forward-comment -1)
+    (point)))
+
+;; FIXME: The following function pattern stuff is specific to R but is
+;; used throughout ESS
+(defvar ess-r-set-function-start
+  ;; [MGAR].. <=>  {setMethod(), set[Group]Generic(), setAs(), setReplaceMethod()}
+  ;; see also set-S4-exp in ess-r-function-pattern below
+  "^set[MGAR][GMa-z]+\\s-?(")
+
+(defvar ess-function-pattern nil ; in R set to ess-r-function-pattern
+  "Regexp to match the beginning of a function in S buffers.")
+
+(defvar ess-r-symbol-pattern
+  "\\(\\sw\\|\\s_\\)"
+  "The regular expression for matching an R symbol.")
+
+(defvar ess-r-name-pattern
+  (concat "\\(" ess-r-symbol-pattern "+\\|\\(`\\).+`\\)")
+  "The regular expression for matching a R name.")
+
+(defvar ess--r-s-function-pattern
+  (let* ((Q     "\\s\"")                    ; quote
+         (Sym-0 "\\(\\sw\\|\\s_\\)")        ; symbol
+         (Symb (concat Sym-0 "+"))
+         (xSymb "[^ \t\n\"']+") ;; (concat "\\[?\\[?" Sym-0 "*")); symbol / [ / [[ / [symbol / [[symbol
+         ;; FIXME: allow '%foo%' but only when quoted; don't allow [_0-9] at beg.
+         (space "\\(\\s-\\|\n\\)*")         ; white space
+
+         (S7-method (concat "method(" Symb "," space
+                            "\\(list(\\(" Symb ",?" space "\\)+)\\|" Symb
+                            "\\))"))
+
+         (part-1 (concat
+                  "\\(" ;;--------outer Either-------
+                  "\\(\\("          ; EITHER
+                  Q xSymb Q         ; any function name between quotes
+                  "\\)\\|\\("
+                  Symb ; (beginning of name) + ess-r-symbol-pattern
+                  "\\)\\|\\("       ; Add S7 method as a valid function name
+                  S7-method
+                  "\\)\\)"))        ; END EITHER OR
+
+         (set-S4-exp
+          (concat
+           "^set\\(As\\|Method\\|Generic\\|GroupGeneric\\|ReplaceMethod\\)(" ; S4 ...
+           Q xSymb Q "," space
+           ;; and now often `` signature(......), : ''
+           ".*" ;; <<< FIXME ???
+           ))
+
+         (part-2 (concat
+                  "\\|" ;;--------outer Or ---------
+                  set-S4-exp
+                  "\\)" ;;--------end outer Either/Or-------
+
+                  "\\(" space "\\s<.*\\s>\\)*"      ; whitespace, comment
+                  ;; FIXME: in principle we should skip 'definition *= *' here
+                  space "\\(function\\|\\\\\\)\\s-*(" ; whitespace, function keyword, parenthesis
+                  )))
+    `(,part-1 ,part-2))
+  "Partial regex for matching functions.
+
+Placeholder for use in constructing `ess-r-function-pattern' and
+`ess-s-function-pattern'.")
+
+(defvar ess-r-function-pattern
+  (concat (car ess--r-s-function-pattern)
+          "\\s-*\\(<-\\|=\\)" ; whitespace, assign
+          (nth 1 ess--r-s-function-pattern))
+  "The regular expression for matching the beginning of an R function.")
+
+(defvar ess-s-function-pattern
+  (concat (car ess--r-s-function-pattern)
+          "\\s-*\\(<-\\|_\\|=\\)" ; whitespace, assign (incl. "_")
+          (nth 1 ess--r-s-function-pattern))
+  "The regular expression for matching the beginning of an S function.")
+
+(defvar ess--fn-name-start-cache nil)
+
+(defun ess--fn-name-start ()
+  "Return (FN-NAME . START-POS).
+FN-NAME is a function name located before the pointer. START-POS
+is the position where FN-NAME starts. Store this cons in variable
+`ess--fn-name-start-cache'."
+  (save-excursion
+    (save-restriction
+      (let* ((proc (get-buffer-process (current-buffer)))
+             (mark (and proc (process-mark proc))))
+        (if (and mark (>= (point) mark))
+            (narrow-to-region mark (point)))
+        (and (fboundp 'ess-noweb-narrow-to-chunk)
+             (bound-and-true-p ess-noweb-mode)
+             (ess-noweb-narrow-to-chunk))
+        (unless (ess-inside-string-p)
+          (setq ess--fn-name-start-cache
+                (condition-case nil ;; check if it is inside a function
+                    (progn
+                      ;; for the sake of big buffers, look only 1000 chars back
+                      (narrow-to-region (max (point-min) (- (point) 1000)) (point))
+                      (up-list -1)
+                      (while (not (looking-at "("))
+                        (up-list -1))
+                      (let ((funname (symbol-name (ess-symbol-at-point))))
+                        (when (and funname
+                                   (not (member funname ess-S-non-functions)))
+                          (cons funname (- (point) (length funname))))))
+                  (error nil))))))))
+
+(defun ess-symbol-at-point ()
+  "Like `symbol-at-point' but consider fully qualified names.
+Fully qualified names include accessor symbols (like aaa$bbb and
+aaa@bbb in R)."
+  (with-syntax-table (or ess-mode-completion-syntax-table
+                         (syntax-table))
+    (symbol-at-point)))
+
+(defun ess-bounds-of-symbol ()
+  "Get bounds of symbol at point.
+Intended for completion."
+  (let ((bounds (with-syntax-table (or ess-mode-completion-syntax-table
+                                       (syntax-table))
+                  (bounds-of-thing-at-point 'symbol))))
+    (and bounds
+         (not (save-excursion
+                (goto-char (car bounds))
+                (looking-at "/\\|[.0-9]")))
+         bounds)))
+
+(defun ess-symbol-start ()
+  "Get initial position for objects completion.
+Symbols are fully qualified names that include accessor
+symbols (like aaa$bbb and aaa@bbb in R)."
+  (car (ess-bounds-of-symbol)))
+
+(defun ess-arg-start ()
+  "Get initial position for args completion."
+  (when (not (ess-inside-string-p))
+    (when (ess--fn-name-start)
+      (if (looking-back "[(,]+[ \t\n]*" nil)
+          (point)
+        (ess-symbol-start)))))
+
+(defun ess-inside-string-p (&optional pos)
+  "Return non-nil if POS is inside string.
+POS defaults to `point'."
+  (let ((pos (or pos (point))))
+    (nth 3 (syntax-ppss pos))))
+
+(defun ess-inside-comment-p (&optional pos)
+  "Return non-nil if POS is inside string.
+POS defaults to `point'."
+  (let ((pos (or pos (point))))
+    (nth 4 (syntax-ppss pos))))
+
+(defun ess-inside-string-or-comment-p (&optional pos)
+  "Return non-nil if POS is inside a string or comment.
+POS defaults to `point'."
+  (or (ess-inside-string-p pos)
+      (ess-inside-comment-p pos)))
+
+(defun ess-inside-brackets-p (&optional pos curly?)
+  "Return t if position POS is inside brackets.
+POS defaults to point if no value is given. If CURLY?? is non nil
+also return t if inside curly brackets."
+  (save-excursion
+    (let ((ppss (syntax-ppss pos))
+          (r nil))
+      (while (and (> (nth 0 ppss) 0)
+                  (not r))
+        (goto-char (nth 1 ppss))
+        (when (or (char-equal ?\[ (char-after))
+                  (and curly?
+                       (char-equal ?\{ (char-after))))
+          (setq r t))
+        (setq ppss (syntax-ppss)))
+      r)))
+
+\f
+;;*;; String manipulation
+
+(defun ess-quote-special-chars (string)
+  "Quote special characters in STRING."
+  (replace-regexp-in-string
+   "\"" "\\\\\\&"
+   (replace-regexp-in-string ;; replace backslashes
+    "\\\\" "\\\\" string nil t)))
+
+(defun ess-rep-regexp (regexp to-string &optional fixedcase literal verbose)
+  "Instead of (replace-regexp..) -- do NOT replace in strings or comments.
+If FIXEDCASE is non-nil, do *not* alter case of replacement text.
+If LITERAL   is non-nil, do *not* treat `\\' as special.
+If VERBOSE   is non-nil, (message ..) about replacements."
+  (let ((case-fold-search (and case-fold-search
+                               (not fixedcase))); t  <==> ignore case in search
+        (ppt (point)); previous point
+        (p))
+    (while (and (setq p (re-search-forward regexp nil t))
+                (< ppt p))
+      (setq ppt p)
+      (cond ((not (ess-inside-string-or-comment-p (1- p)))
+             (if verbose
+                 (let ((beg (match-beginning 0)))
+                   (message "buffer in (match-beg.,p)=(%d,%d) is '%s'"
+                            beg p (buffer-substring beg p))))
+             (replace-match to-string fixedcase literal))))))
+
+(defun ess-replace-regexp-dump-to-src (regexp to-string &optional dont-query verbose)
+  "Replace REGEXP matches from beginning of buffer with TO-STRING.
+If DONT-QUERY is non-nil, call `ess-rep-regexp' else call
+`query-replace-regexp'. VERBOSE can be passed to `ess-rep-regexp'."
+  (save-excursion
+    (goto-char (point-min))
+    (if dont-query
+        (ess-rep-regexp     regexp to-string nil nil verbose)
+      (query-replace-regexp regexp to-string nil))))
+
+(defun ess-space-around (word &optional from verbose)
+  "Replace-regexp .. ensuring space around all occurrences of WORD.
+Start at from FROM, which defaults to point."
+  (interactive "d\nP"); Defaults: point and prefix (C-u)
+  (save-excursion
+    (goto-char from)
+    (ess-rep-regexp (concat "\\([^ \t\n]\\)\\(\\<" word "\\>\\)")
+                    "\\1 \\2" nil nil verbose)
+    (goto-char from)
+    (ess-rep-regexp (concat "\\(\\<" word "\\>\\)\\([^ \t\n]\\)")
+                    "\\1 \\2" nil nil verbose)))
+
+(defun ess-time-string (&optional clock)
+  "Return a string for use as a timestamp, like \"13 Mar 1992\".
+Include hr:min if CLOCK is non-nil. Redefine to taste."
+  (declare (obsolete format-time-string "ESS 19.04"))
+  (format-time-string (concat "%e %b %Y" (if clock ", %H:%M"))))
+
+(defun ess-replace-in-string (str regexp newtext &optional literal)
+  "Replace all matches in STR for REGEXP with NEWTEXT string.
+Optional LITERAL non-nil means do a literal replacement.
+Otherwise treat \\ in NEWTEXT string as special:
+  \\& means substitute original matched text,
+  \\N means substitute match for \(...\) number N,
+  \\\\ means insert one \\."
+  (if (not (stringp str))
+      (error "(replace-in-string): First argument must be a string: %s" str))
+  (if (stringp newtext)
+      nil
+    (error "(replace-in-string): 3rd arg must be a string: %s"
+           newtext))
+  (let ((rtn-str "")
+        (start 0)
+        (special)
+        match prev-start)
+    (while (setq match (string-match regexp str start))
+      (setq prev-start start
+            start (match-end 0)
+            rtn-str
+            (concat
+             rtn-str
+             (substring str prev-start match)
+             (cond (literal newtext)
+                   (t (mapconcat
+                       (function
+                        (lambda (c)
+                          (if special
+                              (progn
+                                (setq special nil)
+                                (cond ((eq c ?\\) "\\")
+                                      ((eq c ?&)
+                                       (substring str
+                                                  (match-beginning 0)
+                                                  (match-end 0)))
+                                      ((and (>= c ?0) (<= c ?9))
+                                       (if (> c (+ ?0 (length
+                                                       (match-data))))
+                                           ;; Invalid match num
+                                           (error "(replace-in-string) Invalid match num: %c" c)
+                                         (setq c (- c ?0))
+                                         (substring str
+                                                    (match-beginning c)
+                                                    (match-end c))))
+                                      (t (char-to-string c))))
+                            (if (eq c ?\\) (progn (setq special t) nil)
+                              (char-to-string c)))))
+                       newtext ""))))))
+    (concat rtn-str (substring str start))))
+
+(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
+binary files!")
+
+;;; MM: Newer Emacsen now have  delete-trailing-whitespace
+;;; --  but no customization like  nuke-trailing-whitespace-p ..
+(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
+`ess-nuke-trailing-whitespace-p' is nil, this function is
+disabled. If t, unreservedly strip trailing whitespace. If not
+nil and not t, query for each instance."
+  (interactive)
+  (let ((bname (buffer-name)))
+    (cond ((or
+            (string= major-mode "rmail-mode")
+            (string= bname "RMAIL")
+            nil)); do nothing..
+          (t
+           (and (not buffer-read-only)
+                ess-nuke-trailing-whitespace-p
+                (save-match-data
+                  (save-excursion
+                    (save-restriction
+                      (widen)
+                      (goto-char (point-min))
+                      (cond ((eq ess-nuke-trailing-whitespace-p t)
+                             (while (re-search-forward "[ \t]+$" (point-max) t)
+                               (delete-region (match-beginning 0)
+                                              (match-end 0))))
+                            (t
+                             (query-replace-regexp "[ \t]+$" "")))))))))
+    ;; always return nil, in case this is on write-file-hooks.
+    nil))
+
+(defun ess--strip-final-newlines (string)
+  (replace-regexp-in-string "\n+$" "" string))
+
+\f
+;;*;; Debugging tools
+
+(defun ess-write-to-dribble-buffer (text)
+  "Write TEXT to `ess-dribble-buffer'."
+  (when (or ess-verbose ess-write-to-dribble)
+    (with-current-buffer (get-buffer-create ess-dribble-buffer)
+      (goto-char (point-max))
+      (insert-before-markers text))))
+
+(defun ess-if-verbose-write (text)
+  "Write TEXT to `ess-dribble-buffer' only if `ess-verbose' is non-nil."
+  (when ess-verbose (ess-write-to-dribble-buffer text)))
+
+(defun ess-kill-last-line ()
+  (save-excursion
+    (goto-char (point-max))
+    (forward-line -1)
+    (delete-region (line-end-position) (point-max))))
+
+(defun ess-sleep ()
+  "Put Emacs to sleep for `ess-sleep-for-shell' seconds (floats work)."
+  (sleep-for ess-sleep-for-shell))
+
+(defun ess-setq-vars-local (alist &optional buf)
+  "Set language variables from ALIST, in buffer BUF, if desired."
+  (when buf (set-buffer buf))
+  (mapc (lambda (pair)
+          (make-local-variable (car pair))
+          (set (car pair) (eval (cdr pair) t))
+          (when (bound-and-true-p ess--make-local-vars-permanent)
+            (put (car pair) 'permanent-local t))) ;; hack for Rnw
+        alist))
+
+(defmacro ess--alist (vars)
+  "Build a self-named alist from VARS.
+VARS must be a list of symbols."
+  (declare (debug 0))
+  `(list ,@(mapcar (lambda (var) `(cons ',var ,var)) vars)))
+
+(defvar ess-error-regexp   "^\\(Syntax error: .*\\) at line \\([0-9]*\\), file \\(.*\\)$"
+  "Regexp to search for errors.")
+
+(define-obsolete-function-alias 'ess-beginning-of-function #'beginning-of-defun "ESS 19.04")
+(define-obsolete-function-alias 'ess-end-of-function #'end-of-defun "ESS 19.04")
+
+(with-no-warnings
+  (defalias 'ess--project-root
+    ;; TODO: Remove once we drop support for Emacs 27
+    (if (and (fboundp 'project-root)
+             ;; Issues caused unless we confirm `project-roots' is obsolete, see bug#1052
+             (get 'project-roots 'byte-obsolete-info))
+        'project-root
+      (lambda (project) "See `project-roots'."
+        (car (project-roots project))))))
+
+(provide 'ess-utils)
+
+;;; ess-utils.el ends here
diff --git a/elpa/ess-20260424.1544/ess.el b/elpa/ess-20260424.1544/ess.el
new file mode 100644 (file)
index 0000000..8cf0a10
--- /dev/null
@@ -0,0 +1,237 @@
+;;; ess.el --- Emacs Speaks Statistics  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1997-2025 Free Software Foundation, Inc.
+
+;; Author: David Smith <dsmithNOSPAMstats.adelaide.edu.au>
+;;         A.J. Rossini <blindglobeNOSPAMgmail.com>
+;;         Richard M. Heiberger <rmhNOSPAMtemple.edu>
+;;         Kurt Hornik <Kurt.HornikNOSPAMR-project.org>
+;;         Martin Maechler <maechlerNOSPAMstat.math.ethz.ch>
+;;         Rodney A. Sparapani <rsparapaNOSPAMmcw.edu>
+;;         Stephen Eglen <stephenNOSPAMgnu.org>
+;;         Sebastian P. Luque <spluqueNOSPAMgmail.com>
+;;         Henning Redestig <henning.redNOSPAMgooglemail.com>
+;;         Vitalie Spinu <spinuvitNOSPAMgmail.com>
+;;         Lionel Henry <lionel.hryNOSPAMgmail.com>
+;;         J. Alexander Branham <alex.branhamNOSPAMgmail.com>
+;;
+;; Maintainer: ESS Core Team <ESS-coreNOSPAMr-project.org>
+;; Created: 7 Jan 1994
+;; Package-Version: 20260424.1544
+;; Package-Revision: bb84ad5717ea
+;; URL: https://ess.r-project.org/
+;; Package-Requires: ((emacs "25.1"))
+;; ESSR-Version: 1.8
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+;;
+;; Emacs Speaks Statistics (ESS) is a package designed to support editing of
+;; scripts and interaction with various statistical analysis programs such as R,
+;; S-Plus, SAS, Stata and OpenBUGS/JAGS. For more details please visit ESS home
+;; page at https://ess.r-project.org/
+
+;;; Code:
+
+(require 'ess-utils)
+(require 'cl-generic)
+(require 'lisp-mnt)
+(defvar reporter-prompt-for-summary-p)
+
+\f
+;; Versions
+
+(defconst ess-version (eval-when-compile
+                        (lm-version (or (and (boundp 'load-true-file-name)
+                                             load-true-file-name)
+                                        load-file-name
+                                        buffer-file-name)))
+  "Version of ESS currently loaded.")
+
+(defconst essr-version (eval-when-compile
+                         (lm-with-file (or (and (boundp 'load-true-file-name)
+                                                load-true-file-name)
+                                           load-file-name
+                                           buffer-file-name)
+                           (lm-header "ESSR-Version")))
+  "Version of ESSR package.")
+
+(defvar ess-revision nil
+  "The revision and date of ESS.
+Is set  by \\[ess-version-string].")
+
+;;;###autoload
+(defun ess-version ()
+  "Return a string with ESS version information."
+  (interactive)
+  (message (format "ess-version: %s (loaded from %s)"
+                   (ess-version-string)
+                   (file-name-directory ess-lisp-directory))))
+
+(defun ess-version-string ()
+  (let* ((ess-dir (file-name-directory ess-lisp-directory)) ; if(<from source>) the top-level 'ess/'
+         (is-release (file-exists-p (concat ess-etc-directory ".IS.RELEASE")))
+         (rel-string (if is-release "Released "))
+         (git-ref-fn (concat ess-dir ".git/HEAD"))
+         (git-ref (when (file-exists-p git-ref-fn)
+                    (with-current-buffer (find-file-noselect git-ref-fn)
+                      (goto-char (point-min))
+                      (when (re-search-forward "ref: \\(.*\\)\n" nil t)
+                        (match-string 1)))))
+         (git-fname (if git-ref
+                        (concat ess-dir ".git/" git-ref)
+                      ;; For release
+                      (concat ess-etc-directory "git-ref")))
+         (git-rev (when (file-exists-p git-fname)
+                    (with-current-buffer (find-file-noselect git-fname)
+                      (goto-char (point-min))
+                      (concat "git: "(buffer-substring
+                                      (point-min) (line-end-position))))))
+         (elpa-fname (concat ess-dir "ess-pkg.el"))
+         (elpa-rev (when (file-exists-p elpa-fname)
+                     ;; Get it from ELPA dir name, (probably won't work if installed manually)
+                     (concat "elpa: "
+                             (replace-regexp-in-string "ess-" ""
+                                                       (file-name-nondirectory
+                                                        (substring ess-dir 1 -1)))))))
+    ;; Set the "global" ess-revision:
+    (setq ess-revision (format "%s%s%s"
+                               (or rel-string "")
+                               (or git-rev "")
+                               (or elpa-rev "")))
+    (when (string= ess-revision "")
+      (setq ess-revision "<unknown>"))
+    (concat ess-version " [" ess-revision "]")))
+
+\f
+;;; Bug Reporting
+
+;;;###autoload
+(defun ess-submit-bug-report ()
+  "Submit a bug report to the ESS maintainers."
+  (interactive)
+  (let ((reporter-prompt-for-summary-p 't))
+    (reporter-submit-bug-report
+     "ess-helpNOSPAMr-project.org"
+     (concat "ess-mode " (ess-version-string))
+     (list 'ess-language
+           'ess-dialect
+           'ess-ask-for-ess-directory
+           'ess-ask-about-transfile
+           'default-directory
+           'ess-keep-dump-files
+           'ess-source-directory
+           'ess-use-ido
+           'ess-use-eldoc
+           'ess-use-tracebug
+           'ess-use-auto-complete
+           'ess-use-company
+           'ess-eval-visibly-p
+           'ess-can-eval-in-background
+           'ess-local-process-name)
+     nil
+     (lambda ()
+       ;;(goto-char (point-max))
+       (rfc822-goto-eoh)
+       (forward-line 1)
+       (insert "\n\n-------------------------------------------------------------\n")
+       (insert "This bug report will be sent to the ESS _help_ email list\n")
+       (insert ">>> _INSTEAD_ we strongly recommend you open an issue for this\n")
+       (insert "    at  https://github.com/emacs-ess/ESS/issues .\n\n")
+       (insert "If you still prefer to use the ESS help email, press C-c C-c to send your message.\n")
+       (insert "-------------------------------------------------------------\n\n")
+       (insert (with-current-buffer ess-dribble-buffer
+                 (goto-char (point-max))
+                 (forward-line -100)
+                 (buffer-substring-no-properties (point) (point-max))))))))
+
+
+\f
+;;; Timer
+
+(defcustom ess-idle-timer-interval 1
+  "Number of seconds to wait before running function in `ess-idle-timer-functions'."
+  :type '(integer)
+  :group 'ess)
+
+(defvar ess-idle-timer-functions nil
+  "A list of functions to run each `ess-idle-timer-interval' idle seconds.
+If your function calls the process, you better use
+`ess-when-new-input' to wrap your call. If you call the
+subprocess please respect `ess-can-eval-in-background' variable.
+
+These functions are run with `run-hooks'. Use `add-hook' to add
+symbols to this variable.
+
+Most likely you will need a local hook. Then you should specify
+the LOCAL argument to `add-hook' and initialize it in
+`ess-mode-hook' or `ess-post-run-hook', or one of the more
+specialized hooks `ess-r-post-run-hook',`ess-stata-post-run-hook'
+etc.")
+
+(defun ess--idle-timer-function nil
+  "Internal function executed by `ess--idle-timer'."
+  (run-hooks 'ess-idle-timer-functions))
+
+(require 'timer)
+(defvar ess--idle-timer
+  (run-with-idle-timer ess-idle-timer-interval 'repeat
+                       #'ess--idle-timer-function)
+  "Timer used to run `ess-idle-timer-functions'.")
+
+\f
+;;; Dispatch on ess-dialect
+;; Inspired by major-mode specializer in cl-generic.el
+
+;; FIXME: Implement a notion of derived dialects. major-mode specializer cannot
+;; be used here as we need same dialect in different major-modes.
+
+;; Two parts:
+;; 1) first define a specializer (ess-dialect= DIALECT) to match symbols
+;;    representing ess dialects.
+;; 2) then define a context-rewriter so you can write
+;;   `&context (ess-dialect "R")` rather than
+;;   `&context (ess-dialect (ess-dialect= "R"))`.
+
+(cl-generic-define-generalizer ess--generic-dialect-generalizer
+  95
+  (lambda (name &rest _) `(if (stringp ,name) (intern ,name)
+                            (if (symbolp ,name) ,name)))
+  (lambda (tag &rest _) `((ess-dialect= ,tag))))
+
+(cl-defmethod cl-generic-generalizers ((_specializer (head ess-dialect=)))
+  "Support for (ess-dialect DIALECT) context specializer."
+  (list ess--generic-dialect-generalizer))
+
+(cl-generic-define-context-rewriter ess-dialect (dialect)
+  `(ess-dialect (ess-dialect= ,(if (stringp dialect)
+                                   (intern dialect)
+                                 dialect))))
+
+;; (cl-defgeneric ess-print-dialect ()
+;;   (error "unknown dialect %s" ess-dialect))
+;; (cl-defmethod ess-print-dialect (&context (ess-dialect "R"))
+;;   (message "dialect: R"))
+;; (cl-defmethod ess-print-dialect (&context (ess-dialect "julia"))
+;;   (message "dialect: julia"))
+
+(provide 'ess)
+
+;;; ess.el ends here
diff --git a/elpa/ess-20260424.1544/ess.info b/elpa/ess-20260424.1544/ess.info
new file mode 100644 (file)
index 0000000..1e1bf00
--- /dev/null
@@ -0,0 +1,5089 @@
+This is ess.info, produced by makeinfo version 6.8 from ess.texi.
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* ESS: (ess). Emacs Speaks Statistics (R/S/S+, SAS, BUGS/NIMBLE and Stata).
+END-INFO-DIR-ENTRY
+
+ESS -- Emacs Speaks Statistics
+******************************
+
+\1f
+File: ess.info,  Node: Top,  Next: Introduction,  Up: (dir)
+
+ESS: Emacs Speaks Statistics
+****************************
+
+ESS version 26.01.0
+
+     by  A.J. Rossini,
+         R.M. Heiberger,
+         K. Hornik,
+         M. Maechler,
+         R.A. Sparapani,
+         S.J. Eglen,
+         S.P. Luque,
+         H. Redestig,
+         V. Spinu,
+         L. Henry,
+     and J.A. Branham.
+
+     Emacs Speaks Statistics (ESS) provides an intelligent, consistent
+     interface between the user and the software.  ESS interfaces with
+     R, SAS, S-PLUS, BUGS/NIMBLE and other statistical analysis packages
+     on GNU/Linux, other Unix-like systems such as macOS, and Microsoft
+     Windows.  ESS is itself a package within the Emacs text editor and
+     uses Emacs features to streamline the creation and use of
+     statistical software.  ESS knows the syntax and grammar of
+     statistical analysis packages and provides consistent display and
+     editing features based on that knowledge.  ESS assists in
+     interactive and batch execution of statements written in these
+     statistical analysis languages.
+
+   The source and documentation of ESS 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.
+
+   ESS 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 in
+the file COPYING in the same directory as this file for more details.
+
+* Menu:
+
+* Introduction::                Overview of features provided by this package
+* Installation::                Installing ESS on your system
+* Interactive ESS::             Interacting with statistical programs
+* Entering commands::           Interacting with the ESS process
+* Evaluating code::             Sending code to the ESS process
+* Transcript Mode::             Manipulating saved transcript files
+* Editing objects::             How to create/edit objects and functions
+* Help::                        Reading help files
+* Completion::                  Various completion mechanisms
+* Developing with ESS::         Tools for package development and debugging
+* Extras::                      Other ESS features for the S family
+* ESS for R::                   Overview of ESS features for the S family
+* ESS for SAS::
+* ESS for BUGS::
+* Mailing lists/bug reports::   How to get assistance with ESS
+* Customization::               Customizing ESS
+* Indices::
+
+\1f
+File: ess.info,  Node: Introduction,  Next: Installation,  Prev: Top,  Up: Top
+
+1 Introduction to ESS
+*********************
+
+ESS provides a generic interface, through Emacs, to statistical
+packages.  It currently supports R (and the rest of the S family), SAS,
+BUGS/NIMBLE, Stata, and Julia with the level of support roughly in that
+order.
+
+   Throughout this manual, _Emacs_ refers to _GNU Emacs_ by the Free
+Software Foundation.  Although previous versions of ESS supported other
+Emacsen, current versions only support GNU Emacs.
+
+   There are two main ways of interacting with ESS: through "regular"
+modes or "inferior" modes.  Regular modes act like normal Emacs major
+modes.  ESS major modes are displayed in the mode-line in the format
+'ESS[dialect]', where 'dialect' can take values such as 'R', 'SAS', or
+'S'.
+
+   ESS also provides easy access to an "inferior process," which is an
+Emacs buffer associated with a running process.  This can be an R
+session, for example.  These inferior processes are referred to as
+inferior ESS ('iESS'), and are shown in the modeline by 'iESS
+[dialect]'.
+
+   Currently, the documentation contains many references to ''R'' where
+actually any supported (statistics) language is meant, i.e., 'R' could
+also mean 'S' or 'SAS.'
+
+   For exclusively interactive users of R, ESS provides a number of
+features to make life easier.  There is an easy to use command history
+mechanism, including a quick prefix-search history.  To reduce typing,
+command-line completion is provided for all R objects and "hot keys" are
+provided for common R function calls.  Help files are easily accessible,
+and a paging mechanism is provided to view them.  Finally, an incidental
+(but very useful) side-effect of ESS is that a transcript of your
+session is kept for later saving or editing.
+
+   No special knowledge of Emacs is necessary when using R interactively
+under ESS.
+
+   For those that use R in the typical edit-test-revise cycle when
+writing R functions, ESS provides for editing of R functions in Emacs
+buffers.  Unlike the typical use of R where the editor is restarted
+every time an object is edited, ESS uses the current Emacs session for
+editing.  In practical terms, this means that you can edit more than one
+function at once, and that the ESS process is still available for use
+while editing.  Error checking is performed on functions loaded back
+into R, and a mechanism to jump directly to the error is provided.  ESS
+also provides for maintaining text versions of your R functions in
+specified source directories.
+
+* Menu:
+
+* Features::                    Why should I use ESS?
+* New features::
+* Credits::                     Authors of and contributors to ESS
+* Manual::                      How to read this manual
+
+\1f
+File: ess.info,  Node: Features,  Next: New features,  Up: Introduction
+
+1.1 Why should I use ESS?
+=========================
+
+Statistical packages are powerful software systems for manipulating and
+analyzing data, but their user interfaces often leave something to be
+desired: they offer weak editor functionality and they differ among
+themselves so markedly that you have to re-learn how to do those things
+for each package.  ESS is a package which is designed to make editing
+and interacting with statistical packages more uniform, user-friendly
+and give you the power of Emacs as well.
+
+   Additionally, both Emacs and ESS (and R) are free software designed
+to give users full control over their computer.  For more on what this
+means, visit <https://www.gnu.org/philosophy/free-sw.html>.
+
+* Menu:
+
+* Current Features::
+
+\1f
+File: ess.info,  Node: Current Features,  Up: Features
+
+1.1.1 Features Overview
+-----------------------
+
+   * Languages Supported:
+        * S family (R, S, and S+ AKA S-PLUS)
+        * SAS
+        * BUGS/JAGS
+        * Stata
+        * Julia
+   * Editing source code (S family, SAS, BUGS/JAGS, Stata, Julia)
+        * Syntactic indentation and highlighting of source code
+        * Partial evaluation of code
+        * Loading and error-checking of code
+        * Source code revision maintenance
+        * Batch execution (SAS, BUGS/JAGS)
+        * Use of imenu to provide links to appropriate functions
+   * Interacting with the process (S family, SAS, Stata, Julia)
+        * Command-line editing
+        * Searchable Command history
+        * Command-line completion of S family object names and file
+          names
+        * Quick access to object lists and search lists
+        * Transcript recording
+        * Interface to the help system
+   * Transcript manipulation (S family, Stata)
+        * Recording and saving transcript files
+        * Manipulating and editing saved transcripts
+        * Re-evaluating commands from transcript files
+   * Interaction with Help Pages and other Documentation (R)
+        * Fast Navigation
+        * Sending Examples to running ESS process.
+        * Fast Transfer to Further Help Pages
+   * Help File Editing (R)
+        * Syntactic indentation and highlighting of source code.
+        * Sending Examples to running ESS process.
+        * Previewing
+
+   For source code buffers, ESS offers several features:
+
+   * Support for multiple indentation styles R code *Note Indenting::.
+
+   * Facilities for loading and error-checking source files, including a
+     keystroke to jump straight to the position of an error in a source
+     file.  *Note Error Checking::.
+
+   * Source code revision maintenance, which allows you to keep historic
+     versions of R source files.  *Note Source Files::.
+
+   * Facilities for evaluating R code such as portions of source files,
+     or line-by-line evaluation of files (useful for debugging).  *Note
+     Evaluating code::.
+
+   ESS also provides features that make it easier to interact with
+inferior ESS (iESS) process (a connection between your buffer and the
+statistical package which is waiting for you to input commands).  These
+include:
+
+   * Command-line editing for fixing mistakes in commands before they
+     are entered.  *Note Command-line editing::.
+
+   * Searchable command history for recalling previously-submitted
+     commands.  *Note Command History::.
+
+   * Command-line completion of both object and file names for quick
+     entry.  *Note Completion::.
+
+   * Hot-keys for quick entry of commonly-used commands in 'R' such as
+     'objects()', and 'search()'.  *Note Hot keys::.
+
+   * Transcript recording for a complete record of all the actions in an
+     R session.  *Note Transcript::.
+
+   * Interface to the help system, with a specialized mode for viewing R
+     help files.  *Note Help::.
+
+   * Object editing.  ESS allows you to edit more than one function
+     simultaneously in dedicated Emacs buffers.  The ESS process may
+     continue to be used while functions are being edited.  *Note Edit
+     buffer::.
+
+   Finally, ESS provides features for re-submitting commands from saved
+transcript files, including:
+
+   * Evaluation of previously entered commands, stripping away
+     unnecessary prompts.  *Note Transcript resubmit::.
+
+\1f
+File: ess.info,  Node: New features,  Next: Credits,  Prev: Features,  Up: Introduction
+
+1.2 New features in ESS
+=======================
+
+Changes and New Features in 26.01.0:
+   * ESS[BUGS] is still relevant due to NIMBLE keeping the language
+     alive.  However, only syntax highlighting and key-presses will be
+     supported moving forward.  For example, the '<' key now generates
+     '<-' rather than the former '=' since equals is a valid character
+     in NIMBLE BUGS.
+
+   Changes and New Features in 25.01.0:
+
+   * polymode: In our transition from literate libraries (such as noweb
+     documented below with respect to 19.04), we now recommend the
+     polymode packages as a more suitable replacement.  Furthermore, we
+     suggest the related polymodes including poly-noweb, poly-markdown
+     and poly-R (installed in that order).  The package polymode itself,
+     as well as the polymodes packages, are all on MELPA rather than
+     ELPA. Therefore, you need to add MELPA to the list of installation
+     archives as follows.  '(add-to-list 'package-archives
+     '("melpa-stable" . "https://stable.melpa.org/packages/"))' for 'M-x
+     package-install'
+
+   * ESS[R]: The shorthand notation for lambda functions and the
+     question mark are now fontified as keywords.  Contributed by Maxime
+     Pettinger.
+
+   * ESS[SAS]: Developed new comprehensive lists of PROCs and functions
+     for syntax highlighting.  See 'etc/proc.sas' and 'etc/func.sas'.
+
+   Changes and New Features in 24.01.1:
+
+   * Revert a bug introduced with the 'ess-request-a-process' change
+
+   Changes and New Features in 24.01.0:
+
+   * fix docstring warnings in ess-custom
+
+   * :package-version is now set to "VERSION" in ess-custom.  By make
+     this is replaced with "24.01.0" (or similar).
+
+   * Better "collaboration" with org-mode.  Now 'ess-request-a-process'
+     obeys 'ess-gen-proc-buffer-name-function', thanks to Ihor
+     Radchenko.
+
+   Changes and New Features in 19.04 (unreleased):
+
+   * ESS[R]: When a background command is interrupted with C-g, ESS now
+     asks the user if they want to disable background evaluations
+     altogether.  This is a resiliency measure against cases where
+     background evals cause cascading errors or hangs.
+
+   * ESS[R]: Background commands now propagate errors to Emacs.
+
+   * ESS[R]: Background commands can now be disabled by process instad
+     of globally.  For instance when a process has failed to initialize
+     properly, background evals are disabled for that particular process
+     to avoid cascading errors.  Other processes may still use
+     background commands.
+
+   * ESS[R]: ESSR commands are now more robust when ESSR is not in
+     scope.  This can happen when using 'browser()' in an environment
+     that doesn't inherit from the search path.
+
+   * ESS[R]: Unexpected exits are now detected during startup.  In that
+     case an error is thrown with advice about how to recover.
+
+   * ESS[R]: 'options(width = )' is now set on startup based on the
+     width of the inferior window.
+
+   * ESS[R]: Add support for R projects and start R by default in the
+     project folder.
+
+   * ESS[R]: Backticked symbols in the process buffer are no longer
+     fontified as strings.
+
+   * ESS[R]: 'ess-command' now runs R code in a sandboxed environment.
+     Use '.ess.environment()' to inspect the current environment.
+
+   * ESS[R]: Added support for new syntax in R 4.0 and R 4.1.  This
+     concerns raw strings, lambda functions, and the pipe operator.
+
+   * ESS[R]: Highlight error locations in rlang style backtraces
+
+   * ESS[R]: Fixed issue that caused ESS-help to hang when usage blocks
+     include R comments (#1025).  Fix contributed by Bill Evans.
+
+   * ESS: New 'ess-elisp-trace-mode' minor mode.  Toggle it to start or
+     stop tracing all 'ess'-prefixed functions with 'trace-function'.
+     Tracing is useful for debugging background ESS behaviour.
+
+   * ESS[R]: 'ess-get-help-aliases-list' now caches the aliases on the R
+     side.  This should speed up help lookup when the search path has
+     changed and the aliases are read again.
+
+   * ESS: 'ess-command' now uses a default timeout of 30 seconds.  It
+     should normally be avoided with long-running tasks because it
+     causes Emacs to block while the command is running.  If the timeout
+     is reached, an error is thrown.  An interrupt is also sent to the
+     process in case of early exit.
+
+     This is a behaviour change: you will now have to explicitly opt in
+     blocking the whole Emacs UI for more than 30 seconds by supplying a
+     larger timeout (use 'most-positive-fixnum' for infinity).
+
+   * ESS: 'ess-wait-for-process' now returns nil if a timeout is
+     reached.
+
+   * ESS: 'ess-get-words-from-vector' gains a 'timeout' argument.
+
+   * ESS[R]: Fixed performance issue with argument completions.  The
+     help summary for the argument is no longer displayed in the echo
+     area.  This fixes delays and hangs (#1062).
+
+   * ESS[R]: 'ess-command' is now more robust and resilient to hangs and
+     custom prompts (#1043).  It also strips continuation prompts ('+'
+     prompts) automatically and reliably (#1116).
+
+   * ESS[R]: 'ess-command' now handles sinked consoles correctly.
+
+   * ESS[R]: 'ess-command' no longer changes '.Last.value'.  As a
+     result, background tasks like completions no longer affect the last
+     value binding (#1058).
+
+   * ESS[R]: Namespaced evaluation is disable in roxygen examples
+     (#1026).  Part of this change is that namespaced evaluation has
+     become a buffer-local rather than process-local setting (#1046).
+     This makes it possible to disable namespaced evaluation in specific
+     buffers or contexts.
+
+   * iESS: Inferior processes can now properly reuse frames (#987).
+     Fixed issue that caused the current buffer to be incorrectly
+     displayed in the new frame when 'display-buffer' is set to pop up
+     frames.
+
+   * ESS[R]: Better support for tramp.  Fixed package evaluation on
+     remote servers with Tramp (#950); process reloading (#1001); and an
+     evaluation issue (#1024).  These fixes were contributed by David
+     Pritchard.
+
+   * ESS[R]: Automatic offsetting of R process output is now disabled by
+     default because it produces undesirable output in some situations.
+     To re-enable, set 'inferior-ess-fix-misaligned-output' to t.
+
+   * ESS[R]: Improved 'xref' lookup ('M-.').  Function locations are now
+     always detected for package libraries listed in
+     'ess-r-package-library-paths'.
+
+   * ESS[R]: Evaluated lines starting with the Roxygen prefix are now
+     always stripped from the prefix, so they can be sent to the process
+     easily.  Previously, this was only the case inside the 'examples'
+     field.  Since roxygen is switching to R markdown, it becomes useful
+     to evaluate chunks of R outside examples.
+
+   * stata support is now obsolete since we were unable to elicit FSF
+     paperwork from some of the original authors: see the lisp/obsolete
+     sub-directory on the ESS github repo
+
+   * 'ess-set-working-directory' no longer changes the active directory
+     (as defined by the buffer-local variable 'default-directory') of
+     the buffer where the command is called.  Instead, the active
+     directory of the inferior buffer is updated to the new working
+     directory.
+
+   * The default of ess-eval-visibly is now ''nowait'.  With this change
+     you should no longer experience freezes while evaluating code.
+
+   * ESS[R]: There is a new menu entry for reloading the R process.  It
+     is otherwise bound to 'C-c C-e C-r'.  Reloading now reuses the same
+     process name and start arguments that were used to start the
+     process.
+
+   * iESS: Process runners now return the inferior buffer.  Note that
+     callers of inferior runners should not assume that the current
+     buffer has been set to the inferior buffer.  Instead, use
+     'with-current-buffer' with the return value of the inferior.
+
+   * iESS[SAS]: The SAS keymap was only set in iESS buffers called
+     '*SAS*'.  This is now fixed.
+
+   * ESS[R]: Fixed longstanding indentation issues involving '::' and
+     ':::' operators.
+
+   * Implement a more reliable check for the process busy state.
+     Background actions such as completion and directory synchronization
+     should not block the process and should not cause printing of the
+     extraneous output to the interpreter.
+
+   * Activate 'goto-address-mode' for url and email highlighting in
+     inferior buffers.
+
+   * 'smart-underscore' and 'ess-smart-S-assign-key' have been removed.
+     Users who liked the previous behavior (i.e.  underscore inserting
+     "<-") should bind 'ess-insert-assign' to the underscore in their
+     Emacs initialization file.  For example, '(define-key
+     ess-r-mode-map "_" #'ess-insert-assign)' and '(define-key
+     inferior-ess-r-mode-map "_" #'ess-insert-assign)' will activate it
+     in all ESS R buffers.
+
+   * ESS major modes are now defined using 'define-derived-mode'.  This
+     makes ESS major modes respect modern conventions such as having
+     <language>-mode-hook and <language>-mode-map.  Users are encouraged
+     to place customizations under the appropriate mode.
+
+   * New option ess-auto-width controls setting the width option on
+     window changes.  Users can change it to 'frame, 'window, or an
+     integer.  See the documentation for details.
+     'ess-auto-width-visible' controls visibility.
+
+   * ESS now respects 'display-buffer-alist'.  Users can now use
+     'display-buffer-alist' to manage how and where windows appear.  For
+     more information and examples, see *Note (ess)Controlling buffer
+     display::.
+
+   * 'ess-roxy-mode' can now be enabled in non-R buffers.  This is
+     primarily intended to support roxygen documentation for cpp
+     buffers.  Preview functionality is not supported outside R buffers.
+
+   * ESS[R]: DESCRIPTION files now open in 'conf-colon-mode'.
+
+   * 'ess-style' now has effects when set as a file or directory local
+     variable.
+
+   * 'ess-default-style' is now obsolete, use 'ess-style' instead.
+
+   * Options for 'ess-gen-proc-buffer-name-function' have been renamed.
+     ess-gen-proc-buffer-name:projectile-or-simple was renamed to
+     ess-gen-proc-buffer-name:project-or-simple and
+     ess-gen-proc-buffer-name:projectile-or-directory was renamed to
+     ess-gen-proc-buffer-name:project-or-directory.  As the name
+     suggests, these now rely on project.el (included with Emacs) rather
+     than projectile.el, which is a third-party package.
+
+   * Eldoc fully honors 'eldoc-echo-area-use-multiline-p'
+
+   * ESS[R]: 'ess-r-rhub-check-package' gained new 'RECOMMENDED'.
+
+   * ESS[R]: devtools commands ask about saving modified buffers before
+     running.  Users can disable the questioning with
+     'ess-save-silently'.
+
+   * ESS[R] help pages now provide links to other help topics.  This is
+     similar with what you would see with, for example
+     'options(help_type = ``html'')' but works with the plain-text
+     version as well.  This only works with 'options(useFancyQuotes =
+     TRUE)' (the default).
+
+   * 'ess-rdired' buffers now derive from tabulated-list-mode.  They
+     should look better and be a bit faster overall.  The size column
+     now displays object sizes in bytes.
+
+   * 'ess-rdired' buffers now auto-update.  The frequency is governed by
+     the new option 'ess-rdired-auto-update-interval'.
+
+   * ESS[R]: 'electric-layout-mode' is now supported.  This
+     automatically inserts a newline after an opening curly brace in R
+     buffers.  To enable it, customize 'ess-r-mode-hook'.
+
+   * ESS[R]: imenu now supports assignment with the equals sign.
+
+   * ESS[Rd]: Rd no longer writes abbrevs to user's abbrev file.
+
+   * ESS removed support for many unused languages.  This includes old
+     versions of S+, ARC, OMG, VST, and XLS.
+
+   * ess-r-runner-prefixes was modified to find R-4 and later.
+
+   * ESS no longer activates eldoc if the user has disabled
+     global-eldoc-mode.
+
+   The following have been made obsolete or removed, see their
+documentation for more detail:
+
+   * Libraries for literate data analysis are obsolete and not loaded by
+     default.  This includes 'ess-noweb', 'ess-swv', and related
+     functionality like 'Rnw-mode'.  Users are encouraged to switch to
+     one of several other packages that deal with these modes.  For
+     example, polymode <https://github.com/polymode/poly-R/>,
+     <https://polymode.github.io/>, or markdown-mode with edit-indirect
+     <https://jblevins.org/projects/markdown-mode>.
+
+   * Support for 'auto-complete' is obsolete.  The 'auto-complete'
+     package is unmaintained and so ESS support is now obsolete.  Users
+     are encouraged to switch to 'company-mode' instead.
+
+   * User options for controlling display of buffers.  This includes
+     'ess-show-buffer-action', 'inferior-ess-same-window',
+     'inferior-ess-own-frame', and 'inferior-ess-frame-alist'.  See
+     above about ESS respecting 'display-buffer-alist'.
+
+   * Variables 'ess-tab-always-indent' and 'ess-tab-complete-in-script'.
+     Use the Emacs-wide setting of 'tab-always-indent' instead.
+
+   * 'inferior-ess-*-start-file' variables.  All modes except Stata did
+     not respect customization of this variable.  In order to load a
+     file on startup, you should put a function on
+     'ess-*-post-run-hook'.
+
+   Bug Fixes in 18.10.3:
+   * More 'Makefile' fixes, notably installing '*.el's.
+
+   Bug Fixes in 18.10.2:
+   * ESS[R] Fix namespace evaluation in non-installed packages.
+     Evaluation is directed into GlobalEnv as originally intended.
+   * 'Makefile' fixes, notably for 'make install' and including full
+     docs in the tarballs.
+
+   Bug Fixes in 18.10.1:
+   * New functions 'ess-eval-line-visibly-and-step' ('C-c C-n' and
+     'ess-eval-region-or-line-visibly-and-step' ('C-RET') which behave
+     as the old versions of 'ess-eval-line-and-step' and
+     'ess-eval-region-or-line-and-step'.
+
+   Changes and New Features in 18.10:
+
+   * This is the last release to support Emacs older than 25.1.  Going
+     forward, only GNU Emacs 25.1 and newer will be supported.  Soon
+     after this release, support for older Emacs versions will be
+     dropped from the git master branch.  Note that MELPA uses the git
+     master branch to produce ESS snapshots, so if you are using Emacs <
+     25.1 from MELPA and are unable to upgrade, you should switch to
+     MELPA-stable.
+
+   * ESS now displays the language dialect in the mode-line.  So, for
+     example, R buffers will now show ESS[R] rather than ESS[S].
+
+   * The ESS manual has been updated and revised.
+
+   * The ESS initialization process has been further streamlined.  If
+     you update the autoloads (which installation from 'package-install'
+     does), you should not need to '(require 'ess-site)' at all, as
+     autoloads should automatically load ESS when it is needed (e.g.
+     the first time an R buffer is opened).  In order to defer loading
+     your ESS config, you may want to do something like
+     '(with-require-after-load "ess" <ess-config-here>)' in your Emacs
+     init file.  Users of the popular 'use-package' Emacs package can
+     now do '(use-package ess :defer t)' to take advantage of this
+     behavior.  For more information on this feature, see *Note
+     (ess)Activating and Loading ESS::.
+
+   * ESS now respects Emacs conventions for keybindings.  This means
+     that The 'C-c [letter]' bindings have been removed.  This affects
+     'C-c h', which was bound to 'ess-eval-line-and-step-invisibly' in
+     'sas-mode-local-map'; 'C-c f', which was bound to
+     'ess-insert-function-outline' in 'ess-add-MM-keys'; and 'C-c h',
+     which was bound to 'ess-handy-commands' in 'Rd-mode-map',
+     'ess-noweb-minor-mode-map', and 'ess-help-mode-map'
+
+   * Functions 'ess-eval-line-and-step' and
+     'ess-eval-region-or-line-and-step' now behave consistently with
+     other evaluation function inside a package.
+
+   * ESS[R]: 'ess-r-package-use-dir' now works with any mode.  This sets
+     the working directory to the root of the current package including
+     for example C or C++ files within '/src').
+
+   * ESS[R]: Long + + prompts in the inferior no longer offset output.
+
+   * ESS[R]: New option 'strip' for 'inferior-ess-replace-long+'.  This
+     strips the entire + + sequence.
+
+   * ESS modes now inherit from 'prog-mode'.  In the next release, ESS
+     modes will use 'define-derived-mode' so that each mode will have
+     (for example) its own hooks and keymaps.
+
+   * ESS[R]: Supports flymake in R buffers for Emacs 26 and newer.
+     Users need to install the 'lintr' package to use it.  Customizable
+     options include 'ess-use-flymake', 'ess-r-flymake-linters', and
+     'ess-r-flymake-lintr-cache'.
+
+   * ESS[R]: Gained support for xref in Emacs 25+ *Note (emacs)Xref::.
+
+   * ESS[R]: The startup screen is cleaner.  It also displays the
+     startup directory with an explicit 'setwd()'.
+
+   * ESS[R]: Changing the working directory is now always reflected in
+     the process buffer.
+
+   * ESS[R]: 'Makevars' files open with 'makefile-mode'.
+
+   * New variable 'ess-write-to-dribble'.  This allows users to disable
+     the dribble ('*ESS*') buffer if they wish.
+
+   * All of the '*-program-name' variables have been renamed to
+     '*-program'.  Users who previously customized e.g.
+     'inferior-ess-R-program-name' will need to update their
+     customization to 'inferior-ess-R-program'.  These variables are
+     treated as risky variables.
+
+   * 'ess-smart-S-assign' was renamed to 'ess-insert-assign'.  It
+     provides similar functionality but for any keybinding, not just
+     '_'.  For instance if you bind it to ';', repeated invocations
+     cycle through between assignment and inserting ';'.
+
+   * 'C-c C-=' is now bound to 'ess-cycle-assign' by default.  See the
+     documentation for details.  New user customization option
+     'ess-assign-list' controls which assignment operators are cycled.
+
+   * ESS[R] In remote sessions, the ESSR package is now fetched from
+     GitHub.
+
+   * Commands that send the region to the inferior process now deal with
+     rectangular regions.  See the documentation of 'ess-eval-region'
+     for details.  This only works on Emacs 25.1 and newer.
+
+   * ESS[R]: Improvements to interacting with iESS in non-R files.
+     Interaction with inferior process in non-R files within packages
+     (for instance C or C++ files) has been improved.  This is a work in
+     progress.
+
+   * ESS[R]: Changing the working directory is now always reflected in
+     the process buffer.
+
+   * ESS[JAGS]: *.jog and *.jmd files no longer automatically open in
+     JAGS mode.
+
+   Many improvements to fontification:
+
+   * Improved customization for faces.  ESS now provides custom faces
+     for (nearly) all faces used and places face customization options
+     into their own group.  Users can customize these options using 'M-x
+     customize-group RET ess-faces'.
+
+   * Many new keywords were added to 'ess-R-keywords' and
+     'ess-R-modifiers'.  See the documentation for details.
+
+   * ESS[R]: 'in' is now only fontified when inside a 'for' construct.
+     This avoids spurious fontification, especially in the output buffer
+     where 'in' is a common English word.
+
+   * ESS: Font-lock keywords are now generated lazily.  That means you
+     can now add or remove keywords from variables like 'ess-R-keywords'
+     in your Emacs configuration file after loading ESS (i.e.  in the
+     ':config' section for 'use-package' users).
+
+   * ESS[R]: Fontification of roxygen '@param' keywords now supports
+     comma-separated parameters.
+
+   * ESS[R]: Certain keywords are only fontified if followed by a
+     parenthesis.  Function-like keywords such as 'if ()' or 'stop()'
+     are no longer fontified as keyword if not followed by an opening
+     parenthesis.  The same holds for search path modifiers like
+     'library()' or 'require()'.
+
+   * ESS[R]: Fixed fontification toggling.  Especially certain syntactic
+     elements such as '%op%' operators and backquoted function
+     definitions.
+
+   * ESS[R]: 'ess-font-lock-toggle-keyword' can be called interactively.
+     This command asks with completion for a font-lock group to toggle.
+     This functionality is equivalent to the font-lock menu.
+
+   Notable bug fixes:
+
+   * 'prettify-symbols-mode' no longer breaks indentation.  This is
+     accomplished by having the pretty symbols occupy the same number of
+     characters as their non-pretty cousins.  You may customize the new
+     variable 'ess-r-prettify-symbols' to control this behavior.
+
+   * ESS: Inferior process buffers are now always displayed on startup.
+     Additionally, they don't hang Emacs on failures.
+
+   Obsolete libraries, functions, and variables:
+
+   * The 'ess-r-args.el' library has been obsoleted and will be removed
+     in the next release.  Use 'eldoc-mode' instead, which is on by
+     default.
+
+   * Functions and options dealing with the smart assign key are
+     obsolete.  The following functions have been made obsolete and will
+     be removed in the next release of ESS: 'ess-smart-S-assign',
+     'ess-toggle-S-assign', 'ess-toggle-S-assign-key',
+     'ess-disable-smart-S-assign'.
+
+     The variable 'ess-smart-S-assign-key' is now deprecated and will be
+     removed in the next release.  If you would like to continue using
+     '_' for inserting assign in future releases, please bind
+     'ess-insert-assign' in 'ess-mode-map' the normal way.
+
+   * ESS[S]: Variable 'ess-s-versions-list' is obsolete and ignored.
+     Use 'ess-s-versions' instead.  You may pass arguments by starting
+     the inferior process with the universal argument.
+
+   Changes and New Features in 17.11:
+
+   * The ESS initialization process has been streamlined.  You can now
+     load the R and Stata modes independently from the rest of ESS. Just
+     put '(require 'ess-r-mode)' or '(require 'ess-stata-mode)' in your
+     init file.  This is for experienced Emacs users as this requires
+     setting up autoloads for '.R' files manually.  We will keep
+     maintaining 'ess-site' for easy loading of all ESS features.
+
+   * Reloading and quitting the process is now more robust.  If no
+     process is attached, ESS now switches automatically to one
+     (prompting you for selection if there are several running).
+     Reloading and quitting will now work during a debug session or when
+     R is prompting for input (for instance after a crash).  Finally,
+     the window configuration is saved and restored after reloading to
+     prevent the buffer of the new process from capturing the cursor.
+
+   * ESS[R]: New command 'ess-r-package-use-dir'.  It sets the working
+     directory of the current process to the current package directory.
+
+   * ESS[R] Lookup for references in inferior buffers has been improved.
+     New variable 'ess-r-package-source-roots' contains package
+     sub-directories which are searched recursively during the file
+     lookup point.  Directories in 'ess-tracebug-search-path' are now
+     also searched recursively.
+
+   * ESS[R] Namespaced evaluation is now automatically enabled only in
+     the 'R/' directory.  This way ESS will not attempt to update
+     function definitions from a package if you are working from e.g.  a
+     test file.
+
+   Changes and New Features in 16.10:
+
+   * ESS[R]: Syntax highlighting is now more consistent.  Backquoted
+     names are not fontified as strings (since they really are
+     identifiers).  Furthermore they are now correctly recognized when
+     they are function definitions or function calls.
+   * ESS[R]: Backquoted names and '%op%' operators are recognized as
+     sexp.  This is useful for code navigation, e.g.  with 'C-M-f' and
+     'C-M-b'.
+   * ESS[R]: Integration of outline mode with roxygen examples fields.
+     You can use outline mode's code folding commands to fold the
+     examples field.  This is especially nice to use with well
+     documented packages with long examples set.  Set
+     'ess-roxy-fold-examples' to non-nil to automatically fold the
+     examples field when you open a buffer.
+   * ESS[R]: New experimental feature: syntax highlighting in roxygen
+     examples fields.  This is turned off by default.  Set
+     'ess-roxy-fontify-examples' to non-nil to try it out.
+   * ESS[R]: New package development command 'ess-r-devtools-ask' bound
+     to 'C-c C-w C-a'.  It asks with completion for any devtools command
+     that takes 'pkg' as argument.
+   * ESS[R]: New command 'C-c C-e C-r' to reload the inferior process.
+     Currently only implemented for R. The R method runs
+     'inferior-ess-r-reload-hook' on reloading.
+   * ESS[R]: 'ess-r-package-mode' is now activated in non-file buffers
+     as well.
+
+   Bug fixes in 16.10:
+   * ESS[R]: Fix broken (un)flagging for debugging inside packages
+   * ESS[R]: Fixes (and improvements) in Package development
+   * ESS[R]: Completion no longer produces '...=' inside 'list( )'.
+   * ESS[R]: Better debugging and tracing in packages.
+   * ESS[R]: Better detection of symbols at point.
+   * ESS[R]: No more spurious warnings on deletion of temporary files.
+   * ESS[julia]: help and completion work (better)
+   * ESS[julia]: available via 'ess-remote'
+
+   Changes and New Features in 16.04:
+
+   * ESS[R]: 'developer' functionality has been refactored.  The new
+     user interface consists of a single command
+     'ess-r-set-evaluation-env' bound by default to 'C-c C-t C-s'.  Once
+     an evaluation environment has been set with, all subsequent ESS
+     evaluation will source the code into that environment.  By default,
+     for file within R packages the evaluation environment is set to the
+     package environment.  Set 'ess-r-package-auto-set-evaluation-env'
+     to 'nil' to disable this.
+   * ESS[R]: New 'ess-r-package-mode' This development mode provides
+     features to make package development easier.  Currently, most of
+     the commands are based on the 'devtools' packages and are
+     accessible with 'C-c C-w' prefix.  See the documentation of
+     'ess-r-package-mode' function for all available commands.  With
+     'C-u' prefix each command asks for extra arguments to the
+     underlying devtools function.  This mode is automatically enabled
+     in all files within R packages and is indicated with '[pkg:NAME]'
+     in the mode-line.
+   * ESS[R]: Help lookup has been improved.  It is now possible to get
+     help for namespaced objects such as pkg::foobar.  Furthermore, ESS
+     recognizes more reliably when you change 'options('html_type')'.
+   * ESS[R]: New specialized breakpoints for debugging magrittr pipes
+   * ESS: ESS now implements a simple message passing interface to
+     communicate between ESS and inferior process.
+
+   Bug fixes in 16.04:
+   * ESS[R]: Roxygen blocks with backtics are now correctly filled
+   * ESS[R]: Don't skip breakpoints in magrittr's 'debug_pipe'
+   * ESS[R]: Error highlighting now understands 'testthat' type errors
+   * ESS[Julia]: Added getwd and setwd generic commands
+
+\1f
+File: ess.info,  Node: Credits,  Next: Manual,  Prev: New features,  Up: Introduction
+
+1.3 Authors of and contributors to ESS
+======================================
+
+The ESS environment is built on the open-source projects of many
+contributors, dating back to 1989 where Doug Bates and Ed Kademan wrote
+S-mode to edit S and Splus files in GNU Emacs.  Frank Ritter and Mike
+Meyer added features, creating version 2.  Meyer and David Smith made
+further contributions, creating version 3.  For version 4, David Smith
+provided significant enhancements to allow for powerful process
+interaction.
+
+   John Sall wrote GNU Emacs macros for SAS source code around 1990.
+Tom Cook added functions to submit jobs, review listing and log files,
+and produce basic views of a dataset, thus creating a SAS-mode which was
+distributed in 1994.
+
+   In 1994, A.J. Rossini extended S-mode to support XEmacs.  Together
+with extensions written by Martin Maechler, this became version 4.7 and
+supported S, Splus, and R. In 1995, Rossini extended SAS-mode to work
+with XEmacs.
+
+   In 1997, Rossini merged S-mode and SAS-mode into a single Emacs
+package for statistical programming; the product of this marriage was
+called ESS version 5.  Richard M. Heiberger designed the inferior mode
+for interactive SAS and SAS-mode was further integrated into ESS. Thomas
+Lumley's Stata mode, written around 1996, was also folded into ESS. More
+changes were made to support additional statistical languages,
+particularly XLispStat.
+
+   ESS initially worked only with Unix statistics packages that used
+standard-input and standard-output for both the command-line interface
+and batch processing.  ESS could not communicate with statistical
+packages that did not use this protocol.  This changed in 1998 when
+Brian Ripley demonstrated use of the Windows Dynamic Data Exchange (DDE)
+protocol with ESS. Heiberger then used DDE to provide interactive
+interfaces for Windows versions of Splus.  In 1999, Rodney A. Sparapani
+and Heiberger implemented SAS batch for ESS relying on files, rather
+than standard-input/standard-output, for Unix, Windows and Mac.  In
+2001, Sparapani added BUGS batch file processing to ESS for Unix and
+Windows.
+
+   * The multiple process code, and the idea for
+     'ess-eval-line-and-next-line' are by Rod Ball.
+
+   * Thanks to Doug Bates for many useful suggestions.
+
+   * Thanks to Martin Maechler for reporting and fixing bugs, providing
+     many useful comments and suggestions, and for maintaining the ESS
+     mailing lists.
+
+   * Thanks to Frank Ritter for updates, particularly the menu code, and
+     invaluable comments on the manual.
+
+   * Thanks to Ken'ichi Shibayama for his excellent indenting code, and
+     many comments and suggestions.
+
+   * Thanks to Aki Vehtari for adding interactive BUGS support.
+
+   * Thanks to Brendan Halpin for bug-fixes and updates to Stata-mode.
+
+   * Last, but definitely not least, thanks to the many ESS users and
+     contributors to the ESS mailing lists.
+
+   _ESS_ is being developed and currently maintained by
+
+   * A.J. Rossini (mailto:blindglobeNOSPAMgmail.com)
+   * Richard M. Heiberger (mailto:rmhNOSPAMtemple.edu)
+   * Kurt Hornik (mailto:Kurt.HornikNOSPAMR-project.org)
+   * Martin Maechler (mailto:maechlerNOSPAMstat.math.ethz.ch)
+   * Rodney A. Sparapani (mailto:rsparapaNOSPAMmcw.edu)
+   * Stephen Eglen (mailto:stephenNOSPAMgnu.org)
+   * Sebastian P. Luque (mailto:spluqueNOSPAMgmail.com)
+   * Henning Redestig (mailto:henning.redNOSPAMgooglemail.com)
+   * Vitalie Spinu (mailto:spinuvitNOSPAMgmail.com)
+   * Lionel Henry (mailto:lionel.hryNOSPAMgmail.com)
+   * J. Alexander Branham (mailto:alex.branhamNOSPAMgmail.com)
+
+\1f
+File: ess.info,  Node: Manual,  Prev: Credits,  Up: Introduction
+
+1.4 How to read this manual
+===========================
+
+If you need to install ESS, read *note Installation:: for details on
+what needs to be done before proceeding to the next chapter.  This
+section describes some of the basics of using Emacs.  If you are already
+familiar with basic Emacs functionality, skip this section.  You may
+also want to use the Emacs tutorial, accessible via 'C-h t'.
+
+   In this manual we use the standard notation used by Emacs for
+describing the keystrokes used to invoke certain commands.  'C-<chr>'
+means hold the CONTROL key while typing the character <chr>.  'M-<chr>'
+means hold the META key (usually ALT) down while typing <chr>.  If there
+is no META, EDIT or ALT key, instead press and release the ESC key and
+then type <chr>.
+
+   All ESS commands can be invoked by typing 'M-x command'.  Most of the
+useful commands are bound to keystrokes for ease of use.  Also, the most
+popular commands are also available through the Emacs menubar, and a
+small subset are provided on the toolbar.  Where possible, keybindings
+are similar to other modes in Emacs to strive for a consistent user
+interface within Emacs, regardless of the details of which programming
+language is being edited, or process being run.
+
+   Some commands, such as 'M-x R' can accept an optional 'prefix'
+argument.  To specify the prefix argument, you would type 'C-u' before
+giving the command.  For example, if you type 'C-u M-x R', you will be
+asked for command line options that you wish to invoke the R process
+with.
+
+   Emacs is a 'self-documenting' text editor.  This applies to ESS in
+two ways.  First, some documentation about each ESS command can be
+obtained by typing 'C-h f'.  For example, if you type 'C-h f
+ess-eval-region', documentation for that command will appear in a
+separate *Help* buffer.  Second, 'C-h m' pops up a complete list of
+keybindings available in each ESS mode and brief description of that
+mode.
+
+   Emacs is a versatile editor written in both C and a dialect of Lisp
+known as Elisp.  ESS is written in Elisp and benefits from the flexible
+nature of lisp.  In particular, many aspects of ESS behaviour can be
+changed by suitable customization of Lisp variables.  This manual
+mentions some of the most frequent variables.  A full list of them
+however is available by using the Custom facility within Emacs.  Type
+'M-x customize-group RET ess RET' to get started.  *note Customization::
+provides details of common user variables you can change to customize
+ESS to your taste, but it is recommended that you defer this section
+until you are more familiar with ESS.
+
+\1f
+File: ess.info,  Node: Installation,  Next: Interactive ESS,  Prev: Introduction,  Up: Top
+
+2 Installing ESS on your system
+*******************************
+
+ESS supports GNU Emacs versions 25.1 and newer.
+
+   ESS is most likely to work with current/recent versions of the
+following statistical packages: R/S-PLUS, SAS, Stata, OpenBUGS and JAGS.
+
+   To build the PDF documentation, you will need a version of TeX Live
+or texinfo that includes texi2dvi.
+
+   There are two main methods used for installing ESS. You may install
+from a third-party repository or from source code.  Once you install it,
+you must also activate or load ESS in each Emacs session, though
+installation from a third-party repository likely takes care of that for
+you.  See *note Activating and Loading ESS:: for more details.
+
+* Menu:
+
+* Installing from a third-party repository::
+* Installing from source::
+* Activating and Loading ESS::
+* Check Installation::
+
+\1f
+File: ess.info,  Node: Installing from a third-party repository,  Next: Installing from source
+
+2.1 Installing from a third-party repository
+============================================
+
+ESS is packaged by many third party repositories.  Many GNU/Linux
+distributions package it, usually with the name "emacs-ess" or similar.
+
+   ESS is also available through Milkypostman’s Emacs Lisp Package
+Archive (MELPA), a popular repository for Emacs packages.  Instructions
+on how to do so are found on MELPA's website (https://melpa.org/).
+MELPA also hosts MELPA-stable with stable ESS builds.  You may choose
+between MELPA with the latest and greatest features (and bugs) or
+MELPA-stable, which may lag a bit behind but should be more stable.
+
+   After installing, users should make sure ESS is activated or loaded
+in each Emacs session.  See *note Activating and Loading ESS::.
+Depending on install method, this may be taken care of automatically.
+
+\1f
+File: ess.info,  Node: Installing from source,  Next: Activating and Loading ESS,  Prev: Installing from a third-party repository
+
+2.2 Installing from source
+==========================
+
+Stable versions of ESS are available at the ESS web page
+(https://ess.r-project.org) as a .tgz file or .zip file.  ESS releases
+are GPG-signed, you should check the signature by downloading the
+accompanying '.sig' file and doing:
+
+     gpg --verify ess-18.10.tgz.sig
+
+   Alternatively, you may download the git repository.  ESS is currently
+hosted on GitHub: <https://github.com/emacs-ess/ESS>.  'git clone
+https://github.com/emacs-ess/ESS.git' will download it to a new
+directory 'ESS' in the current working directory.
+
+   We will refer to the location of the ESS source files as
+'/path/to/ESS/' hereafter.
+
+   After installing, users should make sure they activate or load ESS in
+each Emacs session, see *note Activating and Loading ESS::
+
+   Optionally, compile Elisp files, build the documentation, and the
+autoloads:
+     cd /path/to/ESS/
+     make
+   Without this step the documentation, reference card, and autoloads
+will not be available.  Uncompiled ESS will also run slower.
+
+   Optionally, you may make ESS available to all users of a machine by
+installing it site-wide.  To do so, run 'make install'.  You might need
+administrative privileges:
+
+     make install
+
+   The files are installed into '/usr/share/emacs' directory.  For this
+step to run correctly on macOS, you will need to adjust the 'PREFIX'
+path in 'Makeconf'.  The necessary code and instructions are commented
+in that file.
+
+\1f
+File: ess.info,  Node: Activating and Loading ESS,  Next: Check Installation,  Prev: Installing from source
+
+2.3 Activating and Loading ESS
+==============================
+
+After installing ESS, you must activate or load it each Emacs session.
+ESS can be autoloaded, and if you used a third-party repository (such as
+your Linux distribution or MELPA) to install, you can likely skip this
+section and proceed directly to *note Check Installation::
+
+   Otherwise, you may need to add the path to ESS to 'load-path' with:
+
+     (add-to-list 'load-path "/path/to/ESS/lisp")
+
+   You then need to decide whether to take advantage of deferred loading
+(which will result in a faster Emacs startup time) or require ESS when
+Emacs is loaded.  To autoload ESS when needed (note that if installed
+from source, you must have run 'make'):
+
+     (load "ess-autoloads")
+
+   To require ESS on startup, you can either put
+
+     (require 'ess-site)
+
+   or
+
+     (require 'ess-r-mode)
+
+   In your configuration file, depending on whether you want all ESS
+features or only R related features.
+
+\1f
+File: ess.info,  Node: Check Installation,  Prev: Activating and Loading ESS
+
+2.4 Check Installation
+======================
+
+Restart Emacs and check that ESS was loaded from a correct location with
+'M-x ess-version'.
+
+\1f
+File: ess.info,  Node: Interactive ESS,  Next: Entering commands,  Prev: Installation,  Up: Top
+
+3 Interacting with statistical programs
+***************************************
+
+As well as using ESS to edit your source files for statistical programs,
+you can use ESS to run these statistical programs.  In this chapter, we
+mostly will refer by example to running R from within Emacs.  The Emacs
+convention is to name such processes running under its control as
+'inferior processes'.  Some users find this terminology confusing; you
+may prefer to think of these as 'interactive processes.'  Either way, we
+use the term 'iESS' to refer to the Emacs mode used to interact with
+statistical programs.
+
+* Menu:
+
+* Starting up::
+* Multiple ESS processes::
+* ESS processes on Remote Computers::
+* Customizing startup::
+* Controlling buffer display::
+
+\1f
+File: ess.info,  Node: Starting up,  Next: Multiple ESS processes,  Up: Interactive ESS
+
+3.1 Starting an ESS process
+===========================
+
+To start an inferior R session on GNU/Linux, macOS, or Windows using the
+Cygwin bash shell, simply type 'M-x R RET'.  To start an R session on
+Windows when you use the MSDOS/powershell shell, simply type 'M-x
+S+6-msdos RET'.  R will then (by default) ask the question
+
+     R starting data directory?
+
+Enter the name of the directory you wish to have as the working
+directory (that is, the directory you wish to have 'getwd()' return if
+using R).
+
+   You will then be popped into a buffer named '*R*' which will be used
+for interacting with the ESS process, and you can start entering
+commands.
+
+\1f
+File: ess.info,  Node: Multiple ESS processes,  Next: ESS processes on Remote Computers,  Prev: Starting up,  Up: Interactive ESS
+
+3.2 Running more than one ESS process
+=====================================
+
+ESS allows you to run more than one iESS process simultaneously in the
+same session.  Each process has a name and a number; the initial process
+(process 1) is simply named 'R'.  If you call 'M-x R' again without
+killing the first R process, ESS will start a second R process with the
+name 'R:2'.  To have the first buffer named 'R:1', customize the option
+'ess-plain-first-buffername'.  With a prefix argument, 'C-u M-x R'
+allows for the specification of command line options.
+
+ -- User Option: ess-plain-first-buffername
+     If non-'nil', name the first iESS process [R]. Otherwise, name it
+     [R:1].
+
+   You can switch to any active ESS process with the command 'M-x
+ess-request-a-process'.  Just enter the name of the process you require;
+completion is provided over the names of all running processes.  This is
+a good command to consider binding to a global key.
+
+\1f
+File: ess.info,  Node: ESS processes on Remote Computers,  Next: Customizing startup,  Prev: Multiple ESS processes,  Up: Interactive ESS
+
+3.3 ESS processes on Remote Computers
+=====================================
+
+3.3.1 ESS and TRAMP
+-------------------
+
+ESS works with processes on remote computers as easily as with processes
+on the local machine.  The recommended way to access a statistical
+program on remote computer is to start it with *Note (tramp)Top::.
+
+   Start an ssh session using TRAMP with 'C-x C-f /ssh:user@host: RET'.
+Tramp should open a dired buffer in your remote home directory.  Now
+call your favorite ESS process ('R', 'Julia', 'stata' etc) as you would
+usually do on local machine: 'M-x R'.
+
+   Alternatively you can start your process normally ('M-x R').  When
+asked for starting directory, simply type '/ssh:user@host: RET'.  The R
+process will be started on the remote machine.
+
+   To simplify the process even further create a "config" file in your
+'.ssh/' folder and add an account.  For example if you use amazon EC2,
+it might look like following:
+
+   Host amazon
+      Hostname ec2-54-215-203-181.us-west-1.compute.amazonaws.com
+      User ubuntu
+      IdentityFile ~/.ssh/my_amazon_key.pem
+      ForwardX11 yes
+
+   With this configuration '/ssh:amazon:' is enough to start a
+connection.  The ForwardX11 is needed if you want to see the R graphic
+device showing on the current machine
+
+3.3.2 ESS-remote
+----------------
+
+TRAMP is the recommended way of starting a remote session.  The other
+way to start a remote ESS connection is through 'ess-remote'.
+
+  1. Start a new shell, telnet or ssh buffer and connect to the remote
+     computer (e.g.  use, 'M-x shell', 'M-x telnet' or 'M-x ssh'; ssh.el
+     is available at
+     <https://www.splode.com/~friedman/software/emacs-lisp/src/ssh.el>).
+
+  2. Start the ESS process on the remote machine, for example with one
+     of the commands 'R', 'Splus', or 'sas -stdio'.
+
+  3. Start 'M-x ess-remote'.  You will be prompted for a program name
+     with completion.  Choose one.  Your process is now known to ESS.
+     All the usual ESS commands ('C-c C-n' and its relatives) now work
+     with the R language processes.  For SAS you need to use a different
+     command 'C-c i' (that is a regular 'i', not a 'C-i') to send lines
+     from your 'myfile.sas' to the remote SAS process.  'C-c i' sends
+     lines over invisibly.  With ess-remote you get teletype
+     behavior--the data input, the log, and the listing all appear in
+     the same buffer.  To make this work, you need to end every PROC and
+     DATA step with a "RUN;" statement.  The "RUN;" statement is what
+     tells SAS that it should process the preceding input statements.
+
+  4. Graphics (interactive) on the remote machine.  If you run X11
+     (*Note X11::, X Windows) on both the local and remote machines then
+     you should be able to display the graphs locally by setting the
+     'DISPLAY' environment variable appropriately.  Windows users can
+     download 'xfree86' from cygwin.
+
+  5. Graphics (static) on the remote machine.  If you don't run the X
+     window system on the local machine, then you can write graphics to
+     a file on the remote machine, and display the file in a graphics
+     viewer on the local machine.  Most statistical software can write
+     one or more of postscript, GIF, or JPEG files.  Depending on the
+     versions of Emacs and the operating system that you are running,
+     Emacs itself may display '.gif' and '.jpg' files.  Otherwise, a
+     graphics file viewer will be needed.  Ghostscript/ghostview may be
+     downloaded to display '.ps' and '.eps' files.  Viewers for GIF and
+     JPEG are usually included with operating systems.  *Note
+     ESS(SAS)--Function keys for batch processing::, for more
+     information on using the F12 key for displaying graphics files with
+     SAS.
+
+   Should you or a colleague inadvertently start a statistical process
+in an ordinary '*shell*' buffer, the 'ess-remote' command can be used to
+convert it to an ESS buffer and allow you to use the ESS commands with
+it.
+
+\1f
+File: ess.info,  Node: Customizing startup,  Next: Controlling buffer display,  Prev: ESS processes on Remote Computers,  Up: Interactive ESS
+
+3.4 Changing the startup actions
+================================
+
+If you do not wish ESS to prompt for a starting directory when starting
+a new process, set the variable 'ess-ask-for-ess-directory' to 'nil'.
+In this case, the starting directory will be set using one of the
+following methods:
+
+  1. If the variable 'ess-directory-function' stores the name of a
+     function, the value returned by this function is used.  The default
+     for this variable is nil.
+
+  2. Otherwise, if the variable 'ess-directory' stores the name of a
+     directory (ending in a slash), this value is used.  The default for
+     this variable is nil.
+
+  3. Otherwise, the working directory of the current buffer is used.
+
+   If 'ess-ask-for-ess-directory' has a non-'nil' value (as it does by
+default) then the value determined by the above rules provides the
+default when prompting for the starting directory.  Incidentally,
+'ess-directory' is an ideal variable to set in 'ess-pre-run-hook'.
+
+   You may also customize 'ess-post-run-hook' and the dialect-specific
+'ess-*-post-run-hook' variables.  For example, you may want to use
+'ess-load-file' to load a file when ESS starts R:
+
+     (add-hook 'ess-r-post-run-hook (lambda () (ess-load-file "foo.R")))
+
+   If you like to keep a record of your R actions, set the variable
+'ess-ask-about-transfile' to 't', and you will be asked for a filename
+for the transcript before the ESS process starts.
+
+ -- User Option: ess-ask-about-transfile
+     If non-'nil', ask for a file name in which to save the session
+     transcript.
+
+   Enter the name of a file in which to save the transcript at the
+prompt.  If the file doesn't exist it will be created (for R, you likely
+want it to end in '.Rout').  If the file already exists the transcript
+will be appended to the file.  (Note: if you don't set this variable but
+you still want to save the transcript, you can still do it later --
+*note Saving transcripts::.)
+
+   Once these questions are answered (if they are asked at all) the
+inferior process itself is started.  If you need to pass any arguments
+to this program, they may be specified in the variable
+'inferior-S_PROGRAM_NAME-args'.  For example, if 'inferior-ess-program'
+is '"R"' then the variable to set is 'inferior-R-args'.  It is not
+normally necessary to pass arguments to the iESS program; in particular
+do not pass the '-e' option to 'Splus', since ESS provides its own
+command history mechanism.
+
+   ESS can set the width option of inferior processes automatically when
+the window configuration changes.  To do so, set 'ess-auto-width' to a
+non-nil value.  By default, the change will not be shown in the inferior
+buffer.  If you want it to be shown, set 'ess-auto-width-visible' to a
+non-nil value.
+
+\1f
+File: ess.info,  Node: Controlling buffer display,  Prev: Customizing startup,  Up: Interactive ESS
+
+3.5 Controlling buffer display
+==============================
+
+Users can control how buffers are displayed by customizing
+'display-buffer-alist', *Note (emacs)Window Choice::.  This section
+provides examples of how to achieve certain setups.
+
+   Users coming from RStudio may want the R process to appear at the
+bottom left of the frame, help buffers to appear at the bottom right,
+and ess-rdired buffers at the top right.  To achieve that, you could
+this.  Note that the order matters; '*R Dired*' would match '*R' if it
+came before in the alist.
+
+     (setq display-buffer-alist
+           `(("^\\*R Dired"
+              (display-buffer-reuse-window display-buffer-in-side-window)
+              (side . right)
+              (slot . -1)
+              (window-width . 0.33)
+              (reusable-frames . nil))
+             ("^\\*R"
+              (display-buffer-reuse-window display-buffer-at-bottom)
+              (window-width . 0.5)
+              (reusable-frames . nil))
+             ("^\\*Help"
+              (display-buffer-reuse-window display-buffer-in-side-window)
+              (side . right)
+              (slot . 1)
+              (window-width . 0.33)
+              (reusable-frames . nil))))
+
+   Some users prefer working with multiple frames where one frame has
+the source code and the other frame has the inferior process.  To
+achieve this, use this example.  For a detailed description of
+'reusable-frames', see *Note (elisp)Buffer Display Action Alists::.
+
+     (setq display-buffer-alist
+           '(("^\\*R"
+              (display-buffer-reuse-window display-buffer-pop-up-frame)
+              (reusable-frames . 0))))
+
+   Some users may want the process window to be dedicated to the process
+so that other buffers are not shown on top of that window.  *Note
+(elisp)Dedicated Windows::.  For example, this prevents help buffers
+from being displayed in the window showing the inferior R process.
+
+     (setq display-buffer-alist
+           '(("^\\*R"
+              nil
+              (dedicated . t))))
+
+   By default, ESS usually prefers splitting the frame into multiple
+windows so that you can work with both the R script and the R REPL
+visible at once.  If you want to override this behavior so that the
+script buffer and the process buffer share the same window, you can do
+so like this:
+
+     (setq display-buffer-alist
+           '(("^\\*R" . ((display-buffer-same-window) (inhibit-same-window . nil)))
+             ("\\.R$" . ((display-buffer-same-window) (inhibit-same-window . nil)))))
+
+\1f
+File: ess.info,  Node: Entering commands,  Next: Evaluating code,  Prev: Interactive ESS,  Up: Top
+
+4 Interacting with the ESS process
+**********************************
+
+The primary function of the ESS package is to provide an easy-to-use
+front end to the R interpreter.  This is achieved by running the R
+process from within an Emacs buffer, called hereafter _inferior_ buffer,
+which has an active 'inferior-ess-mode'.  The features of inferior R
+mode are similar to those provided by the standard Emacs shell mode
+(*note (emacs)Shell Mode::).  Command-line completion of R objects and a
+number of 'hot keys' for commonly-used R commands are also provided for
+ease of typing.
+
+* Menu:
+
+* Command-line editing::        Entering commands and fixing mistakes
+* Transcript::                  Manipulating the transcript
+* Command History::             Command History
+* History expansion::           References to historical commands
+* Hot keys::                    Hot keys for common commands
+* Statistical Process running in ESS?::
+* Emacsclient::                 Using emacsclient
+* Other::                       Other commands provided by inferior-ESS
+
+\1f
+File: ess.info,  Node: Command-line editing,  Next: Transcript,  Up: Entering commands
+
+4.1 Entering commands and fixing mistakes
+=========================================
+
+Sending a command to the ESS process is as simple as typing it in and
+pressing the <RETURN> key:
+
+ -- Command: inferior-ess-send-input
+     'RET' Send the command on the current line to the ESS process.
+
+   If you make a typing error before pressing 'RET' all the usual Emacs
+editing commands are available to correct it (*note Basic:
+(emacs)Basic.).  Once the command has been corrected you can press
+<RETURN> (even if the cursor is not at the end of the line) to send the
+corrected command to the ESS process.
+
+   Emacs provides some other commands which are useful for fixing
+mistakes:
+
+'C-c C-w'
+     'backward-kill-word' Deletes the previous word (such as an object
+     name) on the command line.
+
+'C-c C-u'
+     'comint-kill-input' Deletes everything from the prompt to point.
+     Use this to abandon a command you have not yet sent to the ESS
+     process.
+
+'C-a'
+     'comint-bol' Move to the beginning of the line, and then skip
+     forwards past the prompt, if any.
+
+   *Note (emacs)Shell Mode::, for other commands relevant to entering
+input.
+
+\1f
+File: ess.info,  Node: Transcript,  Next: Command History,  Prev: Command-line editing,  Up: Entering commands
+
+4.2 Manipulating the transcript
+===============================
+
+Most of the time, the cursor spends its time at the bottom of the ESS
+process buffer, entering commands.  However all the input and output
+from the current (and previous) ESS sessions is stored in the process
+buffer (we call this the transcript) and often we want to move back up
+through the buffer, to look at the output from previous commands for
+example.
+
+   Within the process buffer, a paragraph is defined as the prompt, the
+command after the prompt, and the output from the command.  Thus 'M-{'
+and 'M-}' move you backwards and forwards, respectively, through
+commands in the transcript.  A particularly useful command is 'M-h'
+('mark-paragraph') which will allow you to mark a command and its entire
+output (for deletion, perhaps).  For more information about paragraph
+commands, *note Paragraphs: (emacs)Paragraphs.
+
+   If an ESS process finishes and you restart it in the same process
+buffer, the output from the new ESS process appears after the output
+from the first ESS process separated by a form-feed ('^L') character.
+Thus pages in the ESS process buffer correspond to ESS sessions.  Thus,
+for example, you may use 'C-x [' and 'C-x ]' to move backward and
+forwards through ESS sessions in a single ESS process buffer.  For more
+information about page commands, *note Pages: (emacs)Pages.
+
+* Menu:
+
+* Last command::                Manipulating the output from the last command
+* Process buffer motion::       Viewing older commands
+* Transcript resubmit::         Re-submitting commands from the transcript
+* Saving transcripts::          Keeping a record of your R session
+
+\1f
+File: ess.info,  Node: Last command,  Next: Process buffer motion,  Up: Transcript
+
+4.2.1 Manipulating the output from the last command
+---------------------------------------------------
+
+Viewing the output of the command you have just entered is a common
+occurrence and ESS provides a number of facilities for doing this.
+Whenever a command produces output, it is possible that the window will
+scroll, leaving the next prompt near the middle of the window.  The
+first part of the command output may have scrolled off the top of the
+window, even though the entire output would fit in the window if the
+prompt were near the bottom of the window.  If this happens, you can use
+the following comint commands:
+
+   'comint-show-maximum-output' to move to the end of the buffer, and
+place cursor on bottom line of window to make more of the last output
+visible.  To make this happen automatically for all inputs, set the
+variable 'comint-scroll-to-bottom-on-input' to 't' or ''this'.  If the
+first part of the output is still not visible, use 'C-c C-r'
+('comint-show-output'), which moves cursor to the previous command line
+and places it at the top of the window.
+
+   Finally, if you want to discard the last command output altogether,
+use 'C-c C-o' ('comint-delete-output'), which deletes everything from
+the last command to the current prompt.  Use this command judiciously to
+keep your transcript to a more manageable size.
+
+\1f
+File: ess.info,  Node: Process buffer motion,  Next: Transcript resubmit,  Prev: Last command,  Up: Transcript
+
+4.2.2 Viewing older commands
+----------------------------
+
+If you want to view the output from more historic commands than the
+previous command, commands are also provided to move backwards and
+forwards through previously entered commands in the process buffer:
+
+'C-c C-p'
+     'comint-previous-prompt' Moves point to the preceding prompt in the
+     process buffer.
+
+'C-c C-n'
+     'comint-next-prompt' Moves point to the next prompt in the process
+     buffer.
+
+Note that these two commands are analogous to 'C-p' and 'C-n' but apply
+to command lines rather than text lines.  And just like 'C-p' and 'C-n',
+passing a prefix argument to these commands means to move to the ARG'th
+next (or previous) command.  (These commands are also discussed in *note
+Shell History Copying: (emacs)Shell History Copying.)
+
+   There are also two similar commands (not bound to any keys by
+default) which move to preceding or succeeding commands, but which first
+prompt for a regular expression (*note Syntax of Regular Expression:
+(emacs)Regexps.), and then moves to the next (previous) command matching
+the pattern.
+
+'comint-backward-matching-input regexp arg'
+'comint-forward-matching-input regexp arg'
+     Search backward (forward) through the transcript buffer for the
+     ARG'th previous (next) command matching REGEXP.  ARG is the prefix
+     argument; REGEXP is prompted for in the minibuffer.
+
+\1f
+File: ess.info,  Node: Transcript resubmit,  Next: Saving transcripts,  Prev: Process buffer motion,  Up: Transcript
+
+4.2.3 Re-submitting commands from the transcript
+------------------------------------------------
+
+When moving through the transcript, you may wish to re-execute some of
+the commands you find there.  ESS provides commands to do this; these
+commands may be used whenever the cursor is within a command line in the
+transcript (if the cursor is within some command _output_, an error is
+signaled).  Note all commands involve the <RETURN> key.
+
+'RET'
+     'inferior-ess-send-input' *Note Command-line editing::.
+
+'C-c RET'
+     'comint-copy-old-input' Copy the command under the cursor to the
+     current command line, but don't execute it.  Leaves the cursor on
+     the command line so that the copied command may be edited.
+
+   When the cursor is not after the current prompt, the <RETURN> key has
+a slightly different behavior than usual.  Pressing 'RET' on any line
+containing a command that you entered (i.e.  a line beginning with a
+prompt) sends that command to the ESS process once again.  If you wish
+to edit the command before executing it, use 'C-c RET' instead; it
+copies the command to the current prompt but does not execute it,
+allowing you to edit it before (re)submitting it.
+
+   These commands work even if the current line is a continuation line
+(i.e.  the prompt is '+' instead of '>') -- in this case all the lines
+that form the multi-line command are concatenated together and the
+resulting command is sent to the ESS process (currently this is the only
+way to resubmit a multi-line command to the ESS process in one go).  If
+the current line does not begin with a prompt, an error is signalled.
+This feature, coupled with the command-based motion commands described
+above, could be used as a primitive history mechanism.  ESS provides a
+more sophisticated mechanism, however, which is described in *note
+Command History::.
+
+\1f
+File: ess.info,  Node: Saving transcripts,  Prev: Transcript resubmit,  Up: Transcript
+
+4.2.4 Keeping a record of your R session
+----------------------------------------
+
+To keep a record of your R session in a disk file, use the Emacs command
+'C-x C-w' ('write-file') to attach a file to the ESS process buffer.
+The name of the process buffer will (probably) change to the name of the
+file, but this is not a problem.  You can still use R as usual; just
+remember to save the file before you quit Emacs with 'C-x C-s'.  You can
+make ESS prompt you for a filename in which to save the transcript every
+time you start R by setting the variable 'ess-ask-about-transfile' to
+'t'; *Note Customizing startup::.  For R files, naming transcript files
+'*.Rout' puts them in a special mode (ESS transcript mode -- *note
+Transcript Mode::) for editing transcript files which is automatically
+selected for files with this suffix.
+
+   R transcripts can get very large, so some judicious editing is
+appropriate if you are saving it in a file.  Use 'C-c C-o' whenever a
+command produces excessively long output (printing large arrays, for
+example).  Delete erroneous commands (and the resulting error messages
+or other output) by moving to the command (or its output) and typing
+'M-h C-w'.  Also, remember that 'C-c C-x' (and other hot keys) may be
+used for commands whose output you do not wish to appear in the
+transcript.  These suggestions are appropriate even if you are not
+saving your transcript to disk, since the larger the transcript, the
+more memory your Emacs process will use on the host machine.
+
+   You can use 'ess-transcript-clean-region' to strip output from a
+transcript, leaving only source code suitable for inclusion in files
+'source()'-able from R. *note Transcript Mode: Clean.
+
+\1f
+File: ess.info,  Node: Command History,  Next: History expansion,  Prev: Transcript,  Up: Entering commands
+
+4.3 Command History
+===================
+
+ESS provides easy-to-use facilities for re-executing or editing previous
+commands.  An input history of the last few commands is maintained (by
+default the last 500 commands are stored, although this can be changed
+by setting the variable 'comint-input-ring-size' in
+'inferior-ess-mode-hook'.)  The simplest history commands simply select
+the next and previous commands in the input history:
+
+'M-p'
+     'comint-previous-input' Select the previous command in the input
+     history.
+
+'M-n'
+     'comint-next-input' Select the next command in the input history.
+
+For example, pressing 'M-p' once will re-enter the last command into the
+process buffer after the prompt but does not send it to the ESS process,
+thus allowing editing or correction of the command before the ESS
+process sees it.  Once corrections have been made, press 'RET' to send
+the edited command to the ESS process.
+
+   If you want to select a particular command from the history by
+matching it against a regular expression (*note Syntax of Regular
+Expression: (emacs)Regexps.), to search for a particular variable name
+for example, these commands are also available:
+
+'M-r'
+     'comint-history-isearch-backward-regexp' Prompt for a regular
+     expression, and search backwards through the input history for a
+     command matching the expression.
+
+A common type of search is to find the last command that began with a
+particular sequence of characters; the following two commands provide an
+easy way to do this:
+
+'C-c M-r'
+     'comint-previous-matching-input-from-input' Select the previous
+     command in the history which matches the string typed so far.
+
+'C-c M-s'
+     'comint-next-matching-input-from-input' Select the next command in
+     the history which matches the string typed so far.
+
+Instead of prompting for a regular expression to match against, as they
+instead select commands starting with those characters already entered.
+For instance, if you wanted to re-execute the last 'attach()' command,
+you may only need to type 'att' and then 'C-c M-r' and 'RET'.
+
+   *Note Shell History Ring: (emacs)Shell Ring, for a more detailed
+discussion of the history mechanism, and do experiment with the 'In/Out'
+menu to explore the possibilities.
+
+   Many ESS users like to have even easier access to these, and
+recommend adding something like
+       (eval-after-load "comint"
+        '(progn
+           (define-key comint-mode-map [up]
+             'comint-previous-matching-input-from-input)
+           (define-key comint-mode-map [down]
+             'comint-next-matching-input-from-input)
+
+           ;; also recommended for ESS use --
+           (setq comint-move-point-for-output 'others)
+           ;; somewhat extreme, almost disabling writing in *R*, *shell* buffers above prompt:
+           (setq comint-scroll-to-bottom-on-input 'this)
+           ))
+   to your Emacs configuration file, where the last two settings are
+typically desirable for the situation where you work with a script (for
+example, 'code.R') and send code chunks to the process buffer (e.g.
+'*R*').  Note however that these settings influence all 'comint'-using
+Emacs modes, not just the ESS ones, and for that reason, these
+customization cannot be part of 'ESS' itself.
+
+* Menu:
+
+* Saving History::
+
+\1f
+File: ess.info,  Node: Saving History,  Up: Command History
+
+4.3.1 Saving the command history
+--------------------------------
+
+The 'ess-history-file' variable, which is 't' by default, together with
+'ess-history-directory', governs if and where the command history is
+saved and restored between sessions.  By default,
+'ess-history-directory' is 'nil', and the command history will be stored
+(as a file) in the same directory as the iESS process.
+
+   ESS users may work exclusively with script files rather than in a
+iESS session, and may not want to save any history files.  To do so:
+
+       (setq ess-history-file nil)
+
+or if you prefer only one global command history file:
+
+       (setq ess-history-directory "~/.R/")
+
+in your Emacs configuration file.
+
+\1f
+File: ess.info,  Node: History expansion,  Next: Hot keys,  Prev: Command History,  Up: Entering commands
+
+4.4 References to historical commands
+=====================================
+
+Instead of searching through the command history using the command
+described in the previous section, you can alternatively refer to a
+historical command directly using a notation very similar to that used
+in 'csh'.  History references are introduced by a '!' or '^' character
+and have meanings as follows:
+
+'!!'
+     The immediately previous command
+
+'!-N'
+     The Nth previous command
+
+'!text'
+     The last command beginning with the string 'text'
+
+'!?text'
+     The last command containing the string 'text'
+
+   In addition, you may follow the reference with a "word designator" to
+select particular "words" of the input.  A word is defined as a sequence
+of characters separated by whitespace.  (You can modify this definition
+by setting the value of 'comint-delimiter-argument-list' to a list of
+characters that are allowed to separate words and themselves form
+words.)  Words are numbered beginning with zero.  The word designator
+usually begins with a ':' (colon) character; however it may be omitted
+if the word reference begins with a '^', '$', '*' or '-'.  If the word
+is to be selected from the previous command, the second '!' character
+can be omitted from the event specification.  For instance, '!!:1' and
+'!:1' both refer to the first word of the previous command, while '!!$'
+and '!$' both refer to the last word in the previous command.  The
+format of word designators is as follows:
+
+'0'
+     The zeroth word (i.e.  the first one on the command line)
+
+'N'
+     The Nth word, where N is a number
+
+'^'
+     The first word (i.e.  the second one on the command line)
+
+'$'
+     The last word
+
+'X-Y'
+     A range of words; '-Y' abbreviates '0-Y'
+
+'*'
+     All the words except the zeroth word, or nothing if the command had
+     just one word (the zeroth)
+
+'X*'
+     Abbreviates X-$
+
+'X-'
+     Like 'X*', but omitting the last word
+
+   In addition, you may surround the entire reference except for the
+first '!' by braces to allow it to be followed by other (non-whitespace)
+characters (which will be appended to the expanded reference).
+
+   Finally, ESS also provides quick substitution; a reference like
+'^old^new^' means "the last command, but with the first occurrence of
+the string 'old' replaced with the string 'new'" (the last '^' is
+optional).  Similarly, '^old^' means "the last command, with the first
+occurrence of the string 'old' deleted" (again, the last '^' is
+optional).
+
+   To convert a history reference as described above to an input
+suitable for R, you need to "expand" the history reference, using the
+<TAB> key.  For this to work, the cursor must be preceded by a space
+(otherwise it would try to complete an object name) and not be within a
+string (otherwise it would try to complete a filename).  So to expand
+the history reference, type 'SPC TAB'.  This will convert the history
+reference into an R command from the history, which you can then edit or
+press <RET> to execute.
+
+   For example, to execute the last command that referenced the variable
+'data', type '!?data SPC TAB RET'.
+
+\1f
+File: ess.info,  Node: Hot keys,  Next: Statistical Process running in ESS?,  Prev: History expansion,  Up: Entering commands
+
+4.5 Hot keys for common commands
+================================
+
+ESS provides a number of commands for executing the commonly used
+functions.  These commands below are basically information-gaining
+commands (such as 'objects()' or 'search()') which tend to clutter up
+your transcript and for this reason some of the hot keys display their
+output in a temporary buffer instead of the process buffer by default.
+This behavior is controlled by the following option:
+
+ -- User Option: ess-execute-in-process-buffer
+     If non-'nil', means that these commands will produce their output
+     in the process buffer instead.
+
+   In any case, passing a prefix argument to the commands (with 'C-u')
+will reverse the meaning of 'ess-execute-in-process-buffer' for that
+command.  In other words, the output will be displayed in the process
+buffer if it usually goes to a temporary buffer, and vice-versa.  These
+are the hot keys that behave in this way:
+
+ -- Command: ess-execute-objects POSN
+     'C-c C-x' Sends the 'objects()' command to the ESS process.  A
+     prefix argument specifies the position on the search list (use a
+     negative argument to toggle 'ess-execute-in-process-buffer' as
+     well).  This is a quick way to see what objects are in your working
+     directory.  A prefix argument of 2 or more means get objects for
+     that position.  A negative prefix argument POSN gets the objects
+     for that position, as well as toggling
+     'ess-execute-in-process-buffer'.
+
+ -- Command: ess-execute-search INVERT
+     'C-c C-s' Sends the 'inferior-ess-search-list-command' command to
+     the 'ess-language' process; 'search()' in R. Prefix INVERT toggles
+     'ess-execute-in-process-buffer'.
+
+   'ess-execute' may seem pointless when you could just type the command
+in anyway, but it proves useful for 'spot' calculations which would
+otherwise clutter your transcript, or for evaluating an expression while
+partway through entering a command.  You can also use this command to
+generate new hot keys using the Emacs keyboard macro facilities; *note
+Keyboard Macros: (emacs)Keyboard Macros.
+
+   The following hot keys do not use 'ess-execute-in-process-buffer' to
+decide where to display the output -- they either always display in the
+process buffer or in a separate buffer, as indicated:
+
+ -- Command: ess-load-file FILENAME
+     'C-c M-l' Prompts for a file (FILENAME) to load into the ESS
+     process using 'source()'.  If there is an error during loading, you
+     can jump to the error in the file with the following function.
+
+ -- Command: ess-parse-errors ARG RESET
+     Visits next 'next-error' message and corresponding source code.  If
+     all the error messages parsed so far have been processed already,
+     the message buffer is checked for new ones.  A prefix ARG specifies
+     how many error messages to move; negative means move back to
+     previous error messages.  Just 'C-u' as a prefix means reparse the
+     error message buffer and start at the first error.  The RESET
+     argument specifies restarting from the beginning.
+
+     *Note Error Checking::, for more details.
+
+ -- Command: ess-display-help-on-object OBJECT COMMAND
+     'C-c C-v' Pops up a help buffer for an R object or function.  If
+     COMMAND is supplied, it is used instead of
+     'inferior-ess-help-command'.  See *note Help:: for more details.
+
+ -- Command: ess-quit
+     'C-c C-q' Issue an exiting command to the inferior process,
+     additionally also running 'ess-cleanup' for disposing of any
+     temporary buffers (such as help buffers and edit buffers) that may
+     have been created.  Use this command when you have finished your R
+     session instead of simply quitting at the inferior process prompt,
+     otherwise you will need to issue the command 'ess-cleanup'
+     explicitly to make sure that all the files that need to be saved
+     have been saved, and that all the temporary buffers have been
+     killed.
+
+\1f
+File: ess.info,  Node: Statistical Process running in ESS?,  Next: Emacsclient,  Prev: Hot keys,  Up: Entering commands
+
+4.6 Is the Statistical Process running under ESS?
+=================================================
+
+For the R languages (R, S, S-Plus) ESS sets an option in the current
+process that programs in the language can check to determine the
+environment in which they are currently running.
+
+   ESS sets 'options(STERM="iESS")' for R language processes running in
+an inferior 'iESS[S]' or 'iESS[R]' buffer.
+
+   ESS sets 'options(STERM="ddeESS")' for independent S-Plus for Windows
+processes running in the GUI and communicating with ESS via the DDE
+(Microsoft Dynamic Data Exchange) protocol through a 'ddeESS[S]' buffer.
+
+   Other values of 'options()$STERM' that we recommend are:
+
+   * 'length': Fixed length xterm or telnet window.
+   * 'scrollable': Unlimited length xterm or telnet window.
+   * 'server': S-Plus Stat Server.
+   * 'BATCH': BATCH.
+   * 'Rgui': R GUI.
+   * 'Commands': S-Plus GUI without DDE interface to ESS.
+
+   Additional values may be recommended in the future as new interaction
+protocols are created.  Unlike the values 'iESS' and 'ddeESS', ESS can't
+set these other values since the R language program is not under the
+control of ESS.
+
+\1f
+File: ess.info,  Node: Emacsclient,  Next: Other,  Prev: Statistical Process running in ESS?,  Up: Entering commands
+
+4.7 Using emacsclient
+=====================
+
+When starting R or S under Unix, ESS sets
+'options(editor="emacsclient")'.  Under Microsoft Windows, it will use
+gnuclient.exe rather than emacsclient, but the same principal applies.
+Within your R session, if you have a function called 'iterator', typing
+'fix(iterator)', will show that function in a temporary Emacs buffer.
+You can then correct the function.  When you kill the buffer, the
+definition of the function is updated.  Using 'edit()' rather than
+'fix()' means that the function is not updated.  Finally, the R function
+'page(x)' will also show a text representation of the object 'x' in a
+temporary Emacs buffer.
+
+\1f
+File: ess.info,  Node: Other,  Prev: Emacsclient,  Up: Entering commands
+
+4.8 Other commands provided by inferior-ESS
+===========================================
+
+The following commands are also available in the process buffer:
+
+ -- Command: comint-interrupt-subjob
+     'C-c C-c' Sends a Control-C signal to the iESS process.  This has
+     the effect of aborting the current command.
+
+ -- Command: ess-switch-to-inferior-or-script-buffer TOGGLE-EOB
+     'C-c C-z' When in process buffer, return to the most recent script
+     buffer.  When in a script buffer pop to the associated process
+     buffer.  Consecutive presses of 'C-z' switch between the script and
+     process buffers.
+
+     If TOGGLE-EOB is given, the value of
+     'ess-switch-to-end-of-proc-buffer' is toggled.
+
+ -- User Option: ess-switch-to-end-of-proc-buffer
+     If non-'nil', 'ess-switch-to-inferior-or-script-buffer' goes to end
+     of process buffer.
+
+   Other commands available in iESS modes are discussed in *note
+(emacs)Shell Mode::.
+
+\1f
+File: ess.info,  Node: Evaluating code,  Next: Transcript Mode,  Prev: Entering commands,  Up: Top
+
+5 Sending code to the ESS process
+*********************************
+
+Other commands are also available for evaluating portions of code in the
+R process.  These commands cause the selected code to be evaluated
+directly by the ESS process as if you had typed them in at the command
+line; the 'source()' function is not used.  You may choose whether both
+the commands and their output appear in the process buffer (as if you
+had typed in the commands yourself) or if the output alone is echoed.
+The behavior is controlled by the variable:
+
+ -- User Option: ess-eval-visibly
+     Non-'nil' means 'ess-eval-*' commands display commands and output
+     in the process buffer.  A value of 't' blocks Emacs while R is
+     busy.  A value of 'nowait' does not block Emacs but printing may be
+     slightly off.
+
+   Passing a prefix ('C-u') (in Elisp terms, the argument VIS) to any of
+the following commands, however, reverses the meaning of
+'ess-eval-visibly' for that command only -- for example 'C-u C-c C-j'
+evaluates the current line without showing the input in the iESS buffer.
+The default value of 'ess-eval-visibly' ('t') means that ESS calls block
+Emacs until they finish.  This may be undesirable, especially if
+commands take long to finish.  Users who want input to be displayed and
+Emacs not to be blocked can set 'ess-eval-visibly' to ''nowait'.  This
+sends the input to the iESS buffer but does not wait for the process to
+finish, ensuring Emacs is not blocked.
+
+   Primary commands for evaluating code are:
+
+ -- Command: ess-eval-region-or-line-and-step VIS
+     'C-<RET>' Sends the highlighted region or current line and step to
+     next line of code.
+
+ -- Command: ess-eval-region-or-function-or-paragraph VIS
+     'C-M-x' Sends the current selected region or function or paragraph.
+
+ -- Command: ess-eval-region-or-function-or-paragraph-and-step VIS
+     'C-c C-c' Like 'ess-eval-region-or-function-or-paragraph' but steps
+     to next line of code.
+
+   Other, not so often used, evaluation commands are:
+
+ -- Command: ess-eval-line VIS
+     'C-c C-j' Sends the current line to the ESS process.
+
+ -- Command: ess-eval-line-and-go VIS
+     'C-c M-j' Like 'ess-eval-line' but additionally switches point to
+     the ESS process.
+
+ -- Command: ess-eval-function VIS NO-ERROR
+     'C-c C-f' Sends the function containing point to the ESS process.
+
+ -- Command: ess-eval-function-and-go VIS
+     'C-c M-f' Like 'ess-eval-function' but additionally switches point
+     to the ESS process.
+
+ -- Command: ess-eval-region START END TOGGLE MESSAGE
+     'C-c C-r' Sends the current region to the ESS process.
+
+ -- Command: ess-eval-region-and-go START END VIS
+     'C-c M-r' Like 'ess-eval-region' but additionally switches point to
+     the ESS process.
+
+ -- Command: ess-eval-buffer VIS
+     'C-c C-b' Sends the current buffer to the ESS process.
+
+ -- Command: ess-eval-buffer-and-go VIS
+     'C-c M-b' Like 'ess-eval-buffer' but additionally switches point to
+     the ESS process.
+
+   All the above 'ess-eval-*' commands are useful for evaluating small
+amounts of code and observing the results in the process buffer for
+debugging purposes, or for generating transcripts from source files.
+When editing R functions, it is generally preferable to use 'C-c C-l' to
+update the function's value.  In particular, 'ess-eval-buffer' is now
+largely obsolete.
+
+   A useful way to work is to divide the frame into two windows; one
+containing the source code and the other containing the process buffer.
+If you wish to make the process buffer scroll automatically when the
+output reaches the bottom of the window, you will need to set the
+variable 'comint-move-point-for-output' to ''others' or 't'.
+
+\1f
+File: ess.info,  Node: Transcript Mode,  Next: Editing objects,  Prev: Evaluating code,  Up: Top
+
+6 Manipulating saved transcript files
+*************************************
+
+Inferior R mode records the transcript (the list of all commands
+executed, and their output) in the process buffer, which can be saved as
+a "transcript file", which should normally have the suffix '.Rout'.  The
+most obvious use for a transcript file is as a static record of the
+actions you have performed in a particular R session.  Sometimes,
+however, you may wish to re-execute commands recorded in the transcript
+file by submitting them to a running ESS process.  This is what
+Transcript Mode is for.
+
+   If you load file a with the suffix '.Rout' into Emacs, it is placed
+in R Transcript Mode.  Transcript Mode is similar to inferior R mode
+(*note Entering commands::): paragraphs are defined as a command and its
+output, and you can move though commands either with the paragraph
+commands or with 'C-c C-p' and 'C-c C-n'.
+
+* Menu:
+
+* Resubmit::                    Resubmitting commands from the transcript file
+* Clean::                       Cleaning transcript files
+
+\1f
+File: ess.info,  Node: Resubmit,  Next: Clean,  Up: Transcript Mode
+
+6.1 Resubmitting commands from the transcript file
+==================================================
+
+Three commands are provided to re-submit command lines from the
+transcript file to a running ESS process.  They are:
+
+ -- Command: ess-transcript-send-command
+     'M-RET' Sends the current command line to the ESS process, and
+     execute it.
+
+ -- Command: ess-transcript-copy-command
+     'C-c RET' Copy the current command to the ESS process, and switch
+     to it (ready to edit the copied command).
+
+ -- Command: ess-transcript-send-command-and-move
+     'RET' Sends the current command to the ESS process, and move to the
+     next command line.  This command is useful for submitting a series
+     of commands.
+
+Note that the first two commands are similar to those on the same keys
+in inferior R Mode.  In all three cases, the commands should be executed
+when the cursor is on a command line in the transcript; the prompt is
+automatically removed before the command is submitted.
+
+\1f
+File: ess.info,  Node: Clean,  Prev: Resubmit,  Up: Transcript Mode
+
+6.2 Cleaning transcript files
+=============================
+
+Yet another use for transcript files is to extract the command lines for
+inclusion in an R source file or function.  Transcript mode provides one
+command which does just this:
+
+ -- Command: ess-transcript-clean-region BEG END EVEN-IF-READ-ONLY
+     'C-c C-w' Strip the transcript in the region (given by BEG and
+     END), leaving only commands.  Deletes any lines not beginning with
+     a prompt, and then removes the prompt from those lines that remain.
+     Prefix argument EVEN-IF-READ-ONLY means to clean even if the buffer
+     is read-only.  Don't forget to remove any erroneous commands first!
+
+The remaining command lines may then be copied to a source file or edit
+buffer for inclusion in a function definition, or may be evaluated
+directly (*note Evaluating code::) using the code evaluation commands
+from R mode, also available in R Transcript Mode.
+
+\1f
+File: ess.info,  Node: Editing objects,  Next: Help,  Prev: Transcript Mode,  Up: Top
+
+7 Editing objects and functions
+*******************************
+
+ESS provides facilities for editing R objects within your Emacs session.
+Most editing is performed on R functions, although in theory you may
+edit datasets as well.  Edit buffers are always associated with files,
+although you may choose to make these files temporary if you wish.
+Alternatively, you may make use of a simple yet powerful mechanism for
+maintaining backups of text representations of R functions.
+Error-checking is performed when R code is loaded into the ESS process.
+
+* Menu:
+
+* Edit buffer::                 Edit objects in a specialized buffer
+* Loading::                     Loading source files into the ESS process
+* Error Checking::              Detecting errors in source files
+* Indenting::                   Indenting and formatting S code
+* Other edit buffer commands::  Commands for motion, completion and more
+* Source Files::                Maintaining R source files
+* Source Directories::          Names and locations of dump files
+
+\1f
+File: ess.info,  Node: Edit buffer,  Next: Loading,  Up: Editing objects
+
+7.1 Creating or modifying R objects
+===================================
+
+To edit an object, type
+
+ -- Command: ess-dump-object-into-edit-buffer OBJECT
+     'C-c C-e C-d' Edit an object in its own edit buffer.
+
+   from within the iESS process buffer ('*R*').  You will then be
+prompted for an object to edit: you may either type in the name of an
+existing object (for which completion is available using the 'TAB' key),
+or you may enter the name of a new object.  A buffer will be created
+containing the text representation of the requested object or, if you
+entered the name of a non-existent object at the prompt and the variable
+'ess-function-template' is non-'nil', you will be presented with a
+template defined by that variable, which defaults to a skeleton function
+construct.
+
+   You may then edit the function as required.  The edit buffer
+generated by 'ess-dump-object-into-edit-buffer' is placed in the 'ESS'
+major mode which provides a number of commands to facilitate editing R
+source code.  Commands are provided to intelligently indent R code,
+evaluate portions of R code and to move around R code constructs.
+
+   Note: when you dump a file with 'C-c C-e C-d', ESS first checks to
+see whether there already exists an edit buffer containing that object
+and, if so, pops you directly to that buffer.  If not, ESS next checks
+whether there is a file in the appropriate place with the appropriate
+name (*note Source Files::) and if so, reads in that file.  You can use
+this facility to return to an object you were editing in a previous
+session (and which possibly was never loaded to the R session).
+Finally, if both these tests fail, the ESS process is consulted and a
+'dump()' command issued.  If you want to force ESS to ask the ESS
+process for the object's definition (say, to reformat an unmodified
+buffer or to revert back to R's idea of the object's definition) pass a
+prefix argument to 'ess-dump-object-into-edit-buffer' by typing 'C-u C-c
+C-e C-d'.
+
+\1f
+File: ess.info,  Node: Loading,  Next: Error Checking,  Prev: Edit buffer,  Up: Editing objects
+
+7.2 Loading source files into the ESS process
+=============================================
+
+The best way to get information -- particularly function definitions --
+into R is to load them in as source file, using R's 'source' function.
+You have already seen how to create source files using 'C-c C-e C-d';
+ESS provides a complementary command for loading source files (even
+files not created with ESS!) into the ESS process, namely
+'ess-load-file' ('C-c M-l').  *note Hot keys::.
+
+After typing 'C-c M-l' you will prompt for the name of the file to load
+into R; usually this is the current buffer's file which is the default
+value (selected by simply pressing 'RET' at the prompt).  You will be
+asked to save the buffer first if it has been modified (this happens
+automatically if the buffer was generated with 'C-c C-e C-d').  The file
+will then be loaded, and if it loads successfully you will be returned
+to the ESS process.
+
+\1f
+File: ess.info,  Node: Error Checking,  Next: Indenting,  Prev: Loading,  Up: Editing objects
+
+7.3 Detecting errors in source files
+====================================
+
+If any errors occur when loading a file with 'C-c C-l', ESS will inform
+you of this fact.  In this case, you can jump directly to the line in
+the source file which caused the error by typing 'C-c `'
+('ess-parse-errors').  You will be returned to the offending file
+(loading it into a buffer if necessary) with point at the line S
+reported as containing the error.  You may then correct the error, and
+reload the file.  Note that none of the commands in an R source file
+will take effect if any part of the file contains errors.
+
+   Sometimes the error is not caused by a syntax error (loading a
+non-existent file for example).  In this case typing 'C-c `' will simply
+display a buffer containing S's error message.  You can force this
+behavior (and avoid jumping to the file when there _is_ a syntax error)
+by passing a prefix argument to 'ess-parse-errors' with 'C-u C-c `'.
+
+\1f
+File: ess.info,  Node: Indenting,  Next: Other edit buffer commands,  Prev: Error Checking,  Up: Editing objects
+
+7.4 Indenting and formatting R code
+===================================
+
+ESS provides a sophisticated mechanism for indenting R source code.
+Compound statements (delimited by '{' and '}') are indented relative to
+their enclosing block.  In addition, the braces have been electrified to
+automatically indent to the correct position when inserted, and
+optionally insert a newline at the appropriate place as well.  Lines
+which continue an incomplete expression are indented relative to the
+first line of the expression.  Function definitions, 'if' statements,
+calls to 'expression()' and loop constructs are all recognized and
+indented appropriately.  User variables are provided to control the
+amount of indentation in each case, and there are also a number of
+predefined indentation styles to choose from.
+
+   Comments are also handled specially by ESS, using an idea borrowed
+from the Emacs-Lisp indentation style.  By default, comments beginning
+with '###' are aligned to the beginning of the line.  Comments beginning
+with '##' are aligned to the current level of indentation for the block
+containing the comment.  Finally, comments beginning with '#' are
+aligned to a column on the right (the 40th column by default, but this
+value is controlled by the variable 'comment-column',) or just after the
+expression on the line containing the comment if it extends beyond the
+indentation column.  You turn off the default behavior by adding the
+line '(setq ess-indent-with-fancy-comments nil)' to your '.emacs' file.
+
+   ESS also supports roxygen2 entries which is R documentation
+maintained in the source code as comments *Note roxygen2::.
+
+   The indentation commands provided by ESS are:
+
+ -- Command: ess-indent-or-complete
+     'TAB' Indents the current line as R code.
+
+     Try to indent first, and if code is already properly indented,
+     complete instead.  In ess-mode, only tries completion if
+     'tab-always-indent' is ''complete'.  See also
+     'ess-first-tab-never-complete'.
+
+ -- User Option: ess-first-tab-never-complete
+     If non-'nil', 'TAB' never tries to complete in ess-mode.  The
+     default ''symbol' does not try to complete if the next char is a
+     valid symbol constituent.  There are more options, see the help
+     ('C-h v').
+
+ -- Command: ess-indent-exp
+     'TAB' Indents each line in the R (compound) expression which
+     follows point.  Very useful for beautifying your R code.
+
+ -- Command: ess-electric-brace
+     '{' '}' The braces automatically indent to the correct position
+     when typed.
+
+   The following Emacs command are also helpful:
+
+'RET'
+'LFD'
+     'newline-and-indent' Insert a newline, and indent the next line.
+     (Note that most keyboards nowadays do not have a <LINEFEED> key,
+     but <RET> and 'C-j' are equivalent.)
+
+'M-;'
+     'indent-dwim' Call the comment command you want (Do What I Mean).
+
+* Menu:
+
+* Styles:: Changing styles for indentation and alignment
+
+\1f
+File: ess.info,  Node: Styles,  Up: Indenting
+
+7.4.1 Changing styles for code indentation and alignment
+--------------------------------------------------------
+
+The combined value of twelve variables (4 of three groups
+'ess-indent-*', 'ess-offset-*' and 'ess-align-*') that control
+indentation are collectively termed a style.  ESS provides several
+styles covering the common styles of indentation: 'DEFAULT', 'OWN',
+'GNU', 'BSD', 'K&R', 'C++', 'RRR', 'RRR+', 'Rstudio', 'Rstudio-', and
+'CLB'.  The variable 'ess-style-alist' lists the value of each
+indentation variable per style (and its documentation contains more).
+
+ -- Command: ess-set-style
+     'C-c C-e C-s' (or 'C-c C-e s') sets the formatting style in this
+     buffer to be one of the predefined styles, see above.  The
+     'DEFAULT' style uses the default values for the indenting
+     variables; The 'OWN' style allows you to use your own private
+     values of the indentation variable, see below.
+
+ -- User Option: ess-style
+     The style to use.  See the variable 'ess-style-alist' for how these
+     groups (DEFAULT, OWN, GNU, RRR, ...) map onto different settings
+     for variables.  You can set this in your Emacs configuration file:
+
+          (setq ess-style 'C++)
+
+ -- User Option: ess-style-alist
+     Predefined formatting styles for ESS code.  Values for all groups,
+     except OWN, are fixed.  To change the value of variables in the OWN
+     group, customize the variable 'ess-own-style-list'.  The default
+     style in use is controlled by 'ess-style'.
+
+   The styles 'DEFAULT' and 'OWN' are initially identical.  If you wish
+to edit some of the default values, set 'ess-style' to ''OWN' and change
+'ess-own-style-list'.  *Note Customization::, for convenient ways to set
+both these variables.
+
+   If you prefer not to use the customization facility, you can change
+individual indentation variables within a hook, for example:
+
+     (defun myindent-ess-hook ()
+       (setq ess-indent-level 4))
+     (add-hook 'ess-mode-hook 'myindent-ess-hook)
+
+   In the rare case that you'd like to add an entire new indentation
+style of your own, copy the definition of 'ess-own-style-list' to a new
+variable and ensure that the last line of the ':set' declaration calls
+'ess-add-style' with a unique name for your style (e.g.  ''MINE').
+Finally, add '(setq ess-style 'MINE)' to use your new style.
+
+\1f
+File: ess.info,  Node: Other edit buffer commands,  Next: Source Files,  Prev: Indenting,  Up: Editing objects
+
+7.5 Commands for motion, completion and more
+============================================
+
+A number of commands are provided to move across function definitions in
+the edit buffer:
+
+ -- Command: ess-goto-beginning-of-function-or-para
+     'ESC C-a' aka 'C-M-a' If inside a function go to the beginning of
+     it, otherwise go to the beginning of paragraph.
+
+ -- Command: ess-goto-end-of-function-or-para
+     'ESC C-e' aka 'C-M-e' Move point to the end of the function
+     containing point.
+
+ -- Command: ess-mark-function
+     'ESC C-h' aka 'C-M-h' Place point at the beginning of the R
+     function containing point, and mark at the end.
+
+Don't forget the usual Emacs commands for moving over balanced
+expressions and parentheses: *Note Lists and Sexps: (Emacs)Lists.
+
+   Completion is provided in the edit buffer in a similar fashion to the
+process buffer: <TAB> first indents, and if there is nothing to indent,
+completes the object or file name; 'M-?' lists file completions.  See
+*Note Completion::, for more.
+
+   Finally, 'C-c C-z' ('ess-switch-to-inferior-or-script-buffer')
+returns you to the 'iESS' process buffer, if done from a script buffer,
+placing point at the end of the buffer.  If this is done from the 'iESS'
+process buffer, point is taken to the script buffer.
+
+   In addition many commands available in the process buffer are also
+available in the script buffer.  You can still read help files with 'C-c
+C-v', edit another function with 'C-c C-e C-d' and of course 'C-c C-l'
+can be used to load a source file into R.
+
+\1f
+File: ess.info,  Node: Source Files,  Next: Source Directories,  Prev: Other edit buffer commands,  Up: Editing objects
+
+7.6 Maintaining R source files
+==============================
+
+Every edit buffer in ESS is associated with a "dump file" on disk.  Dump
+files are created whenever you type 'C-c C-e C-d'
+('ess-dump-object-into-edit-buffer'), and may either be deleted after
+use, or kept as a backup file or as a means of keeping several versions
+of an R function.
+
+ -- User Option: ess-delete-dump-files
+     If non-'nil', dump files created with C-c C-e C-d are deleted
+     immediately after they are created by the ess-process.
+
+   Since immediately after R dumps an object's definition to a disk file
+the source code on disk corresponds exactly to R's idea of the object's
+definition, the disk file isn't needed; deleting it now has the
+advantage that if you _don't_ modify the file (say, because you just
+wanted to look at the definition of one of the standard R functions) the
+source dump file won't be left around when you kill the buffer.  Note
+that this variable only applies to files generated with R's 'dump'
+function; it doesn't apply to source files which already exist.  The
+default value is 't'.
+
+ -- User Option: ess-keep-dump-files
+     Variable controlling whether to delete dump files after a
+     successful load.  If 'nil': always delete.  If 'ask', confirm to
+     delete.  If 'check', confirm to delete, except for files created
+     with 'ess-dump-object-into-edit-buffer'.  Anything else, never
+     delete.  This variable only affects the behaviour of
+     'ess-load-file'.  Dump files are never deleted if an error occurs
+     during the load.
+
+   After an object has been successfully (without error) loaded back
+into R with 'C-c C-l', the disk file again corresponds exactly (well,
+almost -- see below) to R's record of the object's definition, and so
+some people prefer to delete the disk file rather than unnecessarily use
+up space.  This option allows you to do just that.
+
+   If the value of 'ess-keep-dump-files' is 't', dump files are never
+deleted after they are loaded.  Thus you can maintain a complete text
+record of the functions you have edited within ESS. Backup files are
+kept as usual, and so by using the Emacs numbered backup facility --
+*note Single or Numbered Backups: (emacs)Backup Names, you can keep a
+historic record of function definitions.  Another possibility is to
+maintain the files with a version-control system such as git *Note
+Version Control: (emacs)Version Control.  As long as a dump file exists
+in the appropriate place for a particular object, editing that object
+with 'C-c C-e C-d' finds that file for editing (unless a prefix argument
+is given) -- the ESS process is not consulted.  Thus you can keep
+comments _outside_ the function definition as a means of documentation
+that does not clutter the R object itself.  Another useful feature is
+that you may format the code in any fashion you please without R
+re-indenting the code every time you edit it.  These features are
+particularly useful for project-based work.
+
+   If the value of 'ess-keep-dump-files' is nil, the dump file is always
+silently deleted after a successful load with 'C-c C-l'.  While this is
+useful for files that were created with 'C-c C-e C-d' it also applies to
+any other file you load (say, a source file of function definitions),
+and so can be dangerous to use unless you are careful.  Note that since
+'ess-keep-dump-files' is buffer-local, you can make sure particular
+files are not deleted by setting it to 't' in the Local Variables
+section of the file *Note Local Variables in Files: (emacs)File
+Variables.
+
+   A safer option is to set 'ess-keep-dump-files' to 'ask'; this means
+that ESS will always ask for confirmation before deleting the file.
+Since this can get annoying if you always want to delete dump files
+created with 'C-c C-e C-d', but not any other files, setting
+'ess-keep-dump-files' to 'check' (the default value) will silently
+delete dump files created with 'C-c C-e C-d' in the current Emacs
+session, but query for any other file.  Note that in any case you will
+only be asked for confirmation once per file, and your answer is
+remembered for the rest of the Emacs session.
+
+   Note that in all cases, if an error (such as a syntax error) is
+detected while loading the file with 'C-c C-l', the dump file is _never_
+deleted.  This is so that you can edit the file in a new Emacs session
+if you happen to quit Emacs before correcting the error.
+
+   Dump buffers are always autosaved, regardless of the value of
+'ess-keep-dump-files'.
+
+\1f
+File: ess.info,  Node: Source Directories,  Prev: Source Files,  Up: Editing objects
+
+7.7 Names and locations of dump files
+=====================================
+
+Every dump file should be given a unique file name, usually the dumped
+object name with some additions.
+
+ -- User Option: ess-dump-filename-template
+     Template for filenames of dumped objects.  '%s' is replaced by the
+     object name.
+
+By default, dump file names are the user name, followed by '.' and the
+object and ending with '.R'.  Thus if user 'joe' dumps the object
+'myfun' the dump file will have name 'joe.myfun.R'.  The username part
+is included to avoid clashes when dumping into a publicly-writable
+directory, such as '/tmp'; you may wish to remove this part if you are
+dumping into a directory owned by you.
+
+   You may also specify the directory in which dump files are written:
+
+ -- User Option: ess-source-directory
+     Directory name (ending in a slash) where R dump files are to be
+     written.
+
+   By default, dump files are always written to '/tmp', which is fine
+when 'ess-keep-dump-files' is 'nil'.  If you are keeping dump files,
+then you will probably want to keep them somewhere in your home
+directory, say '~/R-source'.  This could be achieved by including the
+following line in your Emacs configuration file:
+     (setq ess-source-directory (expand-file-name "~/R-source/"))
+
+   If you would prefer to keep your dump files in separate directories
+depending on the value of some variable, ESS provides a facility for
+this also.  By setting 'ess-source-directory' to a lambda expression
+which evaluates to a directory name, you have a great deal of
+flexibility in selecting the directory for a particular source file to
+appear in.  The lambda expression is evaluated with the process buffer
+as the current buffer and so you can use the variables local to that
+buffer to make your choice.  For example, the following expression
+causes source files to be saved in the subdirectory 'Src' of the
+directory the ESS process was run in.
+
+     (setq ess-source-directory
+           (lambda ()
+              (concat ess-directory "Src/")))
+
+('ess-directory' is a buffer-local variable in process buffers which
+records the directory the ESS process was run from.)  This is useful if
+you keep your dump files and you often edit objects with the same name
+in different ESS processes.  Alternatively, if you often change your R
+working directory during an R session, you may like to keep dump files
+in some subdirectory of the directory pointed to by the first element of
+the current search list.  This way you can edit objects of the same name
+in different directories during the one R session:
+     (setq ess-source-directory
+        (lambda ()
+            (file-name-as-directory
+             (expand-file-name (concat
+                                (car ess-search-list)
+                                "/.Src")))))
+
+   If the directory generated by the lambda function does not exist but
+can be created, you will be asked whether you wish to create the
+directory.  If you choose not to, or the directory cannot be created,
+you will not be able to edit functions.
+
+\1f
+File: ess.info,  Node: Help,  Next: Completion,  Prev: Editing objects,  Up: Top
+
+8 Reading help files
+********************
+
+ESS provides an easy-to-use facility for reading R help files from
+within Emacs.  From within the ESS process buffer or any ESS edit
+buffer, typing 'C-c C-v' ('ess-display-help-on-object') will prompt you
+for the name of an object for which you would like documentation.
+Completion is provided over all objects which have help files.
+
+   If the requested object has documentation, you will be popped into a
+buffer (named '*help(OBJ-NAME)*') containing the help file.  This buffer
+is placed in a special ESS help mode which disables the usual editing
+commands but which provides a number of keys for paging through the help
+file.
+
+   Help commands:
+
+'?'
+     'ess-describe-help-mode' Pops up a help buffer with a list of the
+     commands available in R help mode.
+
+'h'
+     'ess-display-help-on-object' Pop up a help buffer for a different
+     object.
+
+   Paging commands:
+
+'DEL'
+     'scroll-down-command' Move one screen backwards through the help
+     file.
+
+'SPC'
+     'scroll-up-command' Move one screen forwards through the help file.
+
+'>'
+'<'
+     'end/beginning-of-buffer' Move to the end or beginning of the help
+     file, respectively.
+
+   Section-based motion commands:
+
+'n'
+'p'
+     'ess-skip-to-previous-section' and 'ess-skip-to-next-section' Move
+     to the next and previous section header in the help file,
+     respectively.  A section header consists of a number of capitalized
+     words, followed by a colon.
+
+   In addition, the 's' key followed by one of the following letters
+will jump to a particular section in the help file.  Note that the exact
+headings available and capitalization scheme may vary across languages.
+
+   You may use 's ?' to get the current list of active key bindings.
+
+'a'
+     Arguments:
+
+'b'
+     Background:
+
+'B'
+     Bugs:
+
+'d'
+     Description:
+
+'D'
+     Details:
+
+'e'
+     Examples:
+
+'n'
+     Note:
+
+'O'
+     Optional Arguments:
+
+'R'
+     Required Arguments:
+
+'r'
+     References:
+
+'s'
+     See Also:
+
+'S'
+     Side Effects:
+
+'u'
+     Usage:
+
+'v'
+     Value:
+
+'?'
+     Pops up a help buffer with a list of the defined section motion
+     keys.
+
+   Evaluation:
+
+'l'
+     'ess-eval-line-and-step' Evaluates the current line in the ESS
+     process, and moves to the next line.  Useful for running examples
+     in help files.
+
+'r'
+     'ess-eval-region' Send the contents of the current region to the
+     ESS process.  Useful for running examples in help files.
+
+   Quit commands:
+
+'q'
+     'ess-help-quit' Return to previously selected buffer, and bury the
+     help buffer.
+
+'k'
+     'kill-buffer' Return to previously selected buffer, and kills the
+     help buffer.
+
+'x'
+     'ess-kill-buffer-and-go' Return to the ESS process, killing this
+     help buffer.
+
+   Miscellaneous:
+
+'i'
+     'ess-display-index' Prompt for a package and display it's help
+     index.
+
+'v'
+     'ess-display-vignettes' Display all available vignettes.
+
+'w'
+     'ess-display-help-in-browser' Display current help page with the
+     web browser.
+
+'/'
+     'isearch-forward' Same as 'C-s'.
+
+   In addition, all of the ESS commands available in the edit buffers
+are also available in R help mode (*note Edit buffer::).  Of course, the
+usual (non-editing) Emacs commands are available, and for convenience
+the digits and <-> act as prefix arguments.
+
+   If a help buffer already exists for an object for which help is
+requested, that buffer is popped to immediately; the ESS process is not
+consulted at all.  If the contents of the help file have changed, you
+either need to kill the help buffer first, or pass a prefix argument
+(with 'C-u') to 'ess-display-help-on-object'.
+
+   Help buffers are marked as temporary buffers in ESS, and are deleted
+when 'ess-quit' or 'ess-cleanup' are called.
+
+   Help buffers normally appear in another window within the current
+frame.  If you wish help buffers to appear in their own frame (either
+one per help buffer, or one for all help buffers), you can customize the
+variable 'ess-help-own-frame'.
+
+   Help buffers are displayed by calling the function
+'ess-display-help'.  You can customize where these buffers are displayed
+by adding an entry in 'display-buffer-alist'; for examples, see *Note
+(ess)Controlling buffer display::.  Or by customizing the options
+'ess-help-own-frame', 'ess-help-frame-alist', and
+'ess-display-buffer-reuse-frame'.
+
+\1f
+File: ess.info,  Node: Completion,  Next: Developing with ESS,  Prev: Help,  Up: Top
+
+9 Completion
+************
+
+* Menu:
+
+* Object names::
+* Function arguments::
+* Minibuffer completion::
+* Company::
+* Icicles::
+
+\1f
+File: ess.info,  Node: Object names,  Next: Function arguments,  Up: Completion
+
+9.1 Completion of object names
+==============================
+
+The <TAB> key is for completion.  The value of the variable
+'ess-first-tab-never-complete' controls when completion is allowed to
+occur.  In 'ess-mode' <TAB> first tries to indent, and if there is
+nothing to indent, complete the object name instead.
+
+'TAB'
+     'comint-dynamic-complete' Complete the R object name or filename
+     before point.
+
+   When the cursor is just after a partially-completed object name,
+pressing <TAB> provides completion in a similar fashion to the rest of
+Emacs.  ESS maintains a list of all objects known to R at any given
+time, which basically consists of all objects (functions and datasets)
+in every attached directory listed by the 'search()' command along with
+the component objects of attached data frames
+
+   For example, consider three functions 'binomplot()', 'binom.test()'
+and 'binomial()'.  Typing 'bin TAB' will insert the characters 'om',
+completing the longest prefix ('binom') which distinguishes these three
+commands.  Pressing 'TAB' once more provides a list of the three
+commands which have this prefix, allowing you to add more characters
+(say, '.') which specify the function you desire.  After entering more
+characters pressing 'TAB' yet again will complete the object name up to
+uniqueness, etc.  If you just wish to see what completions exist without
+adding any extra characters, type 'M-?'.
+
+ -- Command: ess-complete-object-name
+     'M-?' List all possible completions of the object name at point.
+
+   ESS also provides completion over the components of named lists and
+environments (after '$'), S4 classes slots (after @), package and
+namespace objects (after :: and :::).
+
+   Completion is also provided over file names, which is particularly
+useful when using R functions such as 'get()' or 'scan()' which require
+fully expanded file names.
+
+   In the iESS buffer, if the cursor is not in a string and does not
+follow a (partial) object name, the <TAB> key has a third use: it
+expands history references.  *Note History expansion::.
+
+   Efficiency in completion is gained by maintaining a cache of objects
+currently known to R; when a new object becomes available or is deleted,
+only one component of the cache corresponding to the associated
+directory needs to be refreshed.  If ESS ever becomes confused about
+what objects are available for completion (such as when if refuses to
+complete an object you *know* is there), the command 'M-x ess-resynch'
+forces the _entire_ cache to be refreshed, which should fix the problem.
+
+\1f
+File: ess.info,  Node: Function arguments,  Next: Minibuffer completion,  Prev: Object names,  Up: Completion
+
+9.2 Completion of function arguments
+====================================
+
+When inside a function call (i.e.  following ''(''), 'TAB' completion
+also provides function arguments.  If function is a generic, completion
+will provide all the arguments of 'S3' methods known to 'R'.
+
+   In R versions newer than 2.14.1, ESS uses R's built-in completion
+engine and will honor its settings.  You may read about them by issuing
+'?rc.options' at the prompt.  For example, to have the equals sign for
+function arguments contain spaces on both sides (e.g.  'lm(for)'
+suggests 'formula = ' rather than 'formula='), you can adjust
+'funarg.suffix':
+
+     utils::rc.options(funarg.suffix = " = ")
+
+   A related functionality is *Note ESS ElDoc::, which displays function
+arguments in the echo area whenever the point is inside a function call.
+
+\1f
+File: ess.info,  Node: Minibuffer completion,  Next: Company,  Prev: Function arguments,  Up: Completion
+
+9.3 Minibuffer completion
+=========================
+
+ESS uses 'IDO' mechanism (part of default Emacs) for minibuffer
+completion if the 'ido' package is available and the value of
+'ess-use-ido' it 't' (the default).  The completion command
+'ess-completing-read' falls back on classic 'completion-read' interface
+if this feature is not available for whatever reason.
+
+\1f
+File: ess.info,  Node: Company,  Next: Icicles,  Prev: Minibuffer completion,  Up: Completion
+
+9.4 Company
+===========
+
+Another popular package for completion is company, short for complete
+anything.  ESS provides support for company out-of-the-box.  To disable
+company support, set 'ess-use-company' to 'nil'.  You can set it to
+''script-only' to only activate company in R scripts.
+
+\1f
+File: ess.info,  Node: Icicles,  Prev: Company,  Up: Completion
+
+9.5 Icicles
+===========
+
+Another option for comprehensively handling completion in Emacs is via
+Icicles (<https://www.emacswiki.org/emacs/Icicles>).  It allows users to
+have completions shown temporarily in the standard '*Completions*'
+buffer, and interactively select completion candidates using several
+methods.  As of version 2013.04.04, Icicles provides support for
+completion in ESS. Please consult Icicles documentation, which is easily
+accessible via 'customize-group Icicles', for more details on
+installation and customization options.
+
+   Once installed, Icicles can be activated by evaluating):
+
+     (require 'icicles)
+     (icy-mode 1)
+
+   Icicles can be toggled by typing 'M-x icy'.
+
+   When Icicles is on, 'TAB' offers completion, provided the conditions
+determined by 'ess-first-tab-never-complete' allow it.  Typing 'M-TAB'
+will attempt completion regardless.  Typing 'M-?' in 'ESS' or 'iESS'
+modes brings up the relevant completion candidates from which to choose.
+Minibuffer input filters the available candidates.  Use 'TAB' for prefix
+completion or 'S-TAB' for substring or regexp completion.  Use 'S-SPC'
+to match an additional pattern (repeatable).  You can cycle among the
+matching candidates, choosing with 'RET' or 'mouse-2'.
+
+\1f
+File: ess.info,  Node: Developing with ESS,  Next: Extras,  Prev: Completion,  Up: Top
+
+10 Developing with ESS
+**********************
+
+ESS provides several tools to help you with the development of your R
+packages:
+
+* Menu:
+
+* ESS tracebug::                Visual debugging, breakpoints, tracing, watch etc.
+* Editing documentation::       Tools to edit R documentation
+* Namespaced Evaluation::               Develop your packages on the fly
+
+\1f
+File: ess.info,  Node: ESS tracebug,  Next: Editing documentation,  Up: Developing with ESS
+
+10.1 ESS tracebug
+=================
+
+* Menu:
+
+* Getting started with tracebug:: Quick tutorial
+
+ESS 'tracebug' offers visual debugging, interactive error navigation,
+interactive backtrace, breakpoint manipulation, control over R error
+actions, watch window and interactive flagging/unflagging of functions
+for debugging.
+
+   'ess-tracebug' is on by default.  You can toggle it on and off with
+'M-x' 'ess-tracebug'.  To disable startup activation of 'ess-tracebug'
+set 'ess-use-tracebug' to nil.
+
+   Tracebug functionality can be found on 'ess-dev-map', bound to 'C-c
+C-t'.  Additionally, when subprocess is in a debugging state
+'ess-debug-minor-mode' is active and the following additional shortcuts
+are available:
+
+* Interactive Debugging (`ess-debug-minor-mode-map'):
+
+ M-C   . Continue                  . `ess-debug-command-continue'
+ M-C-C . Continue multi            . `ess-debug-command-continue-multi'
+ M-N   . Next step                 . `ess-debug-command-next'
+ M-C-N . Next step multi           . `ess-debug-command-next-multi'
+ M-U   . Up frame                  . `ess-debug-command-up'
+ M-Q   . Quit debugging            . `ess-debug-command-quit'
+
+
+   These are all the tracebug commands defined in 'ess-dev-map' ('C-c
+C-t ?' to show this table):
+
+
+* Breakpoints (`ess-dev-map'):
+
+ b   . Set BP (repeat to cycle BP type) . `ess-bp-set'
+ B   . Set conditional BP               . `ess-bp-set-conditional'
+ k   . Kill BP                          . `ess-bp-kil'
+ K   . Kill all BPs                     . `ess-bp-kill-all'
+ o   . Toggle BP state                  . `ess-bp-toggle-state'
+ l   . Set logger BP                    . `ess-bp-set-logger'
+ n   . Goto next BP                     . `ess-bp-next'
+ p   . Goto previous BP                 . `ess-bp-previous'
+
+  (C- prefixed equivalents are also defined)
+
+* Debugging (`ess-dev-map'):
+ `   . Show traceback                       . `ess-show-traceback' (also on C-c `)
+ ~   . Show callstack                       . `ess-show-call-stack' (also on C-c ~)
+ e   . Toggle error action (repeat to cycle). `ess-debug-toggle-error-action'
+ d   . Flag for debugging                   . `ess-debug-flag-for-debugging'
+ u   . Unflag for debugging                 . `ess-debug-unflag-for-debugging'
+ w   . Watch window                         . `ess-watch'
+
+  (C- prefixed equivalents are also defined)
+
+* Navigation to errors (general Emacs functionality):
+
+ C-x `, M-g n   . `next-error'
+ M-g p          . `previous-error'
+
+* Misc:
+
+?   . Show this help           . `ess-tracebug-show-help'
+
+
+   To configure how electric watch window splits the display see
+'ess-watch-width-threshold' and 'ess-watch-height-threshold' variables.
+
+   _Note:_ Currently, ess-tracebug does not detect some of R's debug
+related messages in non-English locales.  To set your R messages to
+English add the following line to your .Rprofile init file:
+
+   Sys.setlocale("LC_MESSAGES", "C")
+
+\1f
+File: ess.info,  Node: Getting started with tracebug,  Up: ESS tracebug
+
+10.1.1 Getting started with tracebug
+------------------------------------
+
+Consider a buffer with the following function:
+
+test <- function(x){
+  mean(x),
+}
+
+   Evaluating the function (e.g.  'C-c C-c') results in an error about
+an unexpected comma.  You can use 'next-error' (bound by default to 'C-x
+`', 'M-g n', and 'M-g M-n') to jump to the place where the error
+occurred.  Alternatively, use the mouse to click on the error to jump to
+where it occurred.
+
+   Correct the error by deleting the comma.  Now put point on 'mean' and
+set the breakpoint using 'C-c C-t b' ('ess-bp-set') and reevaluate the
+function.  Jump to the inferior buffer (possibly using 'C-c C-z') and
+evaluate 'test(1:10)'.  An interactive debug process starts, stopping at
+the breakpoint we just specified.  Here you can debug your function
+(what is 'x' at this point?).  Use 'M-N' to continue.
+
+   Let's replace our test function with one slightly more complicated:
+
+test <- function(x){
+  x <- x + 1
+  y <- mean(x)
+  x <- ifelse(x > 5, x, x - 100)
+  list(x, y)
+}
+
+   Try setting multiple breakpoints.  You can unset a breakpoint by
+killing it with 'C-c C-t k'.  You can set conditional breakpoints too.
+Try setting one by placing point on the line 'x <- x + 1' and doing 'C-c
+C-t B'.  ESS will ask for the condition.  Let's set it to
+'!is.numeric(x)'.  After re-evaluating 'test', try calling 'test(1:100)'
+and 'test('foo')'.
+
+   You can remove all breakpoints with 'C-c C-t K'.
+
+   You can flag a function for debugging (similar to calling
+'debug(test)' at R's prompt) by doing 'C-c C-t d'.  Try this yourself by
+putting point over 'test' and doing 'C-c C-t d'.
+
+   If an error occurs, you can get the complete call stack by doing 'C-c
+`' or 'C-c C-t `' ('ess-show-traceback').
+
+   Tracebug also offers a watch window where you can watch values of
+objects.  Open it with 'C-c C-t w' ('ess-watch').  Initially you aren't
+watching anything.  Add something with 'a' (e.g.  'a test').  The watch
+window displays what the object is at any given time and automatically
+updates.  Quit the watch window with 'q'.
+
+\1f
+File: ess.info,  Node: Editing documentation,  Next: Namespaced Evaluation,  Prev: ESS tracebug,  Up: Developing with ESS
+
+10.2 Editing documentation
+==========================
+
+ESS provides two ways of writing documentation for R objects.  Either
+using the standard R documentation system or using in-source
+documentation written as structured comment fields for use with the
+roxygen2 package.
+
+* Menu:
+
+* R documentation files::       Edit objects in a specialized buffer
+* roxygen2::                     Loading source files into the ESS process
+
+\1f
+File: ess.info,  Node: R documentation files,  Next: roxygen2,  Up: Editing documentation
+
+10.2.1 Editing R documentation (Rd) files
+-----------------------------------------
+
+R objects are documented in files written in the "R documentation"
+("Rd"), a simple markup language closely resembling (La)TeX, which can
+be processed into a variety of formats, including LaTeX, HTML, and plain
+text.  Rd format is described in section "Rd format" of the "Writing R
+Extensions" manual in the R distribution.  ESS has several features that
+facilitate editing Rd files.
+
+   Visiting an Rd file as characterized by its extension 'Rd' will
+activate Rd Mode, which provides several facilities for making editing R
+documentation files more convenient, by helping with indentation,
+insertions, even doing some of the typing for you (with Abbrev Mode),
+and by showing Rd keywords, strings, etc. in different faces (with Font
+Lock Mode).
+
+   In Rd mode, the following special Emacs commands can be used in
+addition to the standard Emacs commands.
+
+'C-h m'
+     Describe the features of Rd mode.
+
+'LFD'
+'RET'
+     Reindent the current line, insert a newline and indent the new line
+     ('reindent-then-newline-and-indent').  An abbrev before point is
+     expanded if 'abbrev-mode' is non-'nil'.
+
+'TAB'
+     Indent current line based on its contents and on previous lines.
+     ('indent-according-to-mode').
+
+'C-c C-e'
+     Insert a "skeleton" with Rd markup for at least all mandatory
+     entries in Rd files ('Rd-mode-insert-skeleton').  Note that many
+     users might prefer to use the R function 'prompt' on an existing R
+     object to generate a non-empty Rd "shell" documenting the object
+     (which already has all information filled in which can be obtained
+     from the object).
+
+'C-c C-f'
+     Insert "font" specifiers for some of the Rd markup commands markup
+     available for emphasizing or quoting text, including markup for
+     URLs and email addresses ('Rd-font').  'C-c C-f' is only a prefix;
+     see e.g. 'C-c C-f TAB' for the available bindings.  Note that
+     currently, not all of the Rd text markup as described in section
+     "Marking text" of "Writing R Extensions" can be accessed via 'C-c
+     C-f'.
+
+'C-c C-j'
+     Insert a suitably indented '\item{' on the next line
+     ('Rd-mode-insert-item').
+
+'C-c C-p'
+     Preview a plain text version ("help file", *note Help::) generated
+     from the Rd file ('Rd-preview-help').
+
+   In addition, when editing Rd files one can interact with a running R
+process in a similar way as when editing R language files.  For example,
+'C-c C-v' provides access to on-line help, and 'C-c C-n' sends the
+current line to the R process for evaluation.  This interaction is
+particularly useful when editing the examples in the Rd file.  See 'C-h
+m' for all available commands.
+
+   Rd mode also provides access to abbreviations for most of the Rd
+markup commands.  Type 'M-x list-abbrevs' with Abbrev mode turned on to
+list all available abbrevs.  Note that all Rd abbrevs start with a grave
+accent.
+
+   Rd mode can be customized via the following variables.
+
+ -- User Option: Rd-mode-hook
+     Hook to be run when Rd mode is entered.
+
+ -- User Option: Rd-indent-level
+     The indentation of Rd code with respect to containing blocks.
+     Default is 2.
+
+ -- User Option: Rd-to-help-command
+     The shell command used for converting Rd source to help text.
+     Default is 'R CMD Rd2txt'.
+
+   To automatically turn on the abbrev and font-lock features of Rd
+mode, add the following lines to one of your Emacs startup files:
+
+     (add-hook 'Rd-mode-hook
+               (lambda ()
+                (abbrev-mode 1)
+                (font-lock-mode 1)))
+
+\1f
+File: ess.info,  Node: roxygen2,  Prev: R documentation files,  Up: Editing documentation
+
+10.2.2 Editing roxygen2 documentation
+-------------------------------------
+
+The roxygen2 R package makes it possible to keep the intended contents
+for Rd files as structured comments in the R source files.  roxygen2 can
+then parse R files and generate appropriate Rd files from these
+comments, fill the usage fields as well as updating 'NAMESPACE' files.
+See the roxygen2 documentation found via <https://roxygen2.r-lib.org>
+for more information on its usage.  An example of an roxygen2 entry for
+a simple R function can look like this:
+
+     ##' Description of the function
+     ##'
+     ##' Further details about this function
+     ##' @title A title
+     ##' @param me all parameters must be listed and documented
+     ##' @return Description of the return value
+     ##' @author The author
+     myfun <- function(me)
+       cat("Hello", me, "\n")
+   The entry is immediately preceding the object to document and all
+lines start with the roxygen2 prefix string, in this case '##''.  ESS
+provides support to edit these documentation entries by providing line
+filling, navigation, template generation etc.  Syntax highlighting is
+provided.
+
+   roxygen2 is customized by the variables in the customization group
+"Ess Roxy".  Customizations include the roxygen2 prefix, use of folding
+to toggle visibility of roxygen2 entries and the roxygen2 template.
+
+   All ESS roxygen2 support is defined in 'ess-roxy.el' which is loaded
+by default in ESS. The following special Emacs commands are provided.
+
+ -- Command: ess-roxy-update-entry
+     'C-c C-o C-o' Generate a roxygen2 template or update the parameter
+     list in roxygen2 entry at point (or above the function at the
+     point).  Documented parameters that are not in the function are
+     placed last in the list, parameters that are not documented and not
+     in the definition are dropped.  Parameter descriptions are filled
+     if 'ess-roxy-fill-param-p' is non-nil.
+
+ -- Command: ess-roxy-toggle-roxy-region BEG END
+     'C-c C-o C-c' Toggle the presence of the leading roxygen2 string on
+     all lines in the marked region (between BEG and END.  Convenient
+     for transferring text to roxygen2 entries and to evaluate example
+     fields.
+
+ -- Command: ess-roxy-preview-Rd NAME-FILE
+     'C-c C-o C-r' Use the attached R process to parse the entry at
+     point to obtain the Rd code.  Convenient for previewing and
+     checking syntax.  When used with the prefix argument NAME-FILE,
+     i.e.  'C-u C-c C-e C-r', place the content in a buffer associated
+     with a Rd file with the same name as the documentation.  Requires
+     the roxygen2 package to be installed.
+
+ -- Command: ess-roxy-preview-HTML VISIT-INSTEAD-OF-OPEN
+     'C-c C-o C-t' Use the attached R process to parse the entry at to
+     generate HTML for the entry and open it in a browser.  When used
+     with the prefix argument VISIT-INSTEAD-OF-OPEN, i.e.  'C-u C-c C-e
+     C-t', visit the generated HTML file instead.  Requires the roxygen2
+     and tools packages to be installed.
+
+ -- Command: ess-roxy-previous-entry
+     'C-c C-o p' Go to start of the roxygen2 entry above point.
+
+ -- Command: ess-roxy-next-entry
+     'C-c C-o n' Go to end of the roxygen2 entry above point.
+
+ -- Command: ess-roxy-hide-all
+     'C-c C-o C-h' Use the hideshow mode to fold away the visibility of
+     all roxygen2 entries.  Hide-show support must be enabled for this
+     binding to get defined.
+
+   ESS also advises the following standard editing functions in order to
+make roxygen2 editing more intuitive:
+
+'TAB'
+     'ess-R-complete-object-name' Complete roxygen2 tag at point.  E.g.
+     doing 'TAB' when the point is at the end of '@par' completes to
+     '@param'.
+
+'M-h'
+     'mark-paragraph' If the transient mark mode is active, place mark
+     and point at start end end of the field at point and activate the
+     mark.
+
+'TAB'
+     'ess-indent-command' If hide-show support is enabled, fold away the
+     visibility of the roxygen2 entry at point.
+
+'M-q'
+     'fill-paragraph' Fill the roxygen2 field at point.
+
+'C-a'
+     'ess-roxy-move-beginning-of-line' Move to the point directly to the
+     right of the roxygen2 start string.  If already there, move to the
+     beginning of the line.
+
+'RET'
+     'newline-and-indent' Insert a new line and the roxygen2 prefix
+     string.
+
+\1f
+File: ess.info,  Node: Namespaced Evaluation,  Prev: Editing documentation,  Up: Developing with ESS
+
+10.3 Namespaced Evaluation
+==========================
+
+In non package files evaluation commands, *Note Evaluating code::, send
+portions of the current buffer environment ('R_GlobalEnv'.  When
+developing packages, ESS sends code to the corresponding package
+namespace and (for visible objects) into package environment (visible on
+search path).  All objects that are assigned are displayed in the
+minibuffer alongside the environment in which they are assigned.
+
+   Here is a short overview of how namespace and package environments
+work in R. All objects defined in a package 'foo' are stored in an
+environment called 'namespace:foo'.  Parent environment of
+'namespace:foo' is an environment 'imports:foo' which contains copies of
+all objects from other packages which 'foo' imports.  Parent environment
+of 'imports:foo' is the 'namespace:base'.  Parent environment of
+'namespace:base' is .GlobalEnv.  Thus functions and methods stored in
+'namespace:foo' see all the objects in .GlobalEnv unless shadowed by
+objects in 'imports:foo', 'namespace:base', or 'namespace:foo' itself.
+There is another environment associated with 'foo' - 'package:foo'.
+This environment stores *copies* of exported objects from
+'namespace:foo' and is placed on the search() path, i.e.  if 'foo' is
+loaded and if you start with .GlobalEnv and iteratively call
+parent.env() you will get eventually to 'package:foo'.  Thus all methods
+and functions defined in .GlobalEnv can "see" objects in 'package:foo'
+environment.  See also
+<https://cran.r-project.org/doc/manuals/R-ints.html#Namespaces>.
+
+   Occasionally you want to evaluate into a package from a non-package
+file, or the other way around, evaluate into 'GlobalEnv' from inside a
+package.  In such cases 'C-c C-t C-s' is your friend.
+
+ -- Command: ess-r-set-evaluation-env ARG
+     'C-c C-t C-s' Set or unset the current evaluation environment (a
+     package).
+
+\1f
+File: ess.info,  Node: Extras,  Next: ESS for R,  Prev: Developing with ESS,  Up: Top
+
+11 Other ESS features and tools
+*******************************
+
+ESS has a few extra features, which didn't fit anywhere else.
+* Menu:
+
+* ESS ElDoc::                   Display function arguments in minibuffer
+* ESS Flymake::                 On-the-fly syntax checking
+* Handy commands::              Usefully commands at your fingertips
+* Highlighting::                Syntactic highlighting of buffers
+* Parens::                      Parenthesis matching
+* Graphics::                    Using graphics with ESS
+* Imenu::                       Support for Imenu in ESS
+* Outline::                     Use outline-minor-mode in R scripts
+* Toolbar::                     Support for toolbar in ESS
+* Xref::                        Xref
+* Rdired::                      Directory editor for R objects
+* Package listing::             R object/package management and help utilities
+* Org::                         Interaction with Org mode
+* Sweave and AUCTeX::           Support for Sweave in ESS and AUCTeX
+
+\1f
+File: ess.info,  Node: ESS ElDoc,  Next: ESS Flymake,  Up: Extras
+
+11.1 ElDoc
+==========
+
+In 'ElDoc' mode, the echo area displays function's arguments at point.
+ElDoc is active by default in 'ess-mode' and 'inferior-ess-mode'
+buffers.  To activate it only in 'ess-mode' buffers, place the following
+into your init file:
+
+     (setq ess-use-eldoc 'script-only)
+
+ -- User Option: ess-use-eldoc
+     If 't', activate eldoc in ess-mode and inferior-ess-mode buffers.
+     If ''script-only' activate in ess-mode buffers only.  Set
+     'ess-use-eldoc' to 'nil' to stop using 'ElDoc' altogether.
+
+ -- User Option: ess-eldoc-show-on-symbol
+     This variable controls whether the help is shown only inside
+     function calls.  If set to 't', 'ElDoc' shows help string whenever
+     the point is on a symbol, otherwise (the default), shows only when
+     the point is in a function call, i.e.  after ''(''.
+
+ -- User Option: ess-eldoc-abbreviation-style
+     The variable determines how the doc string should be abbreviated to
+     fit into minibuffer.  Posible values are 'nil', 'mild', 'normal',
+     'strong' and 'aggressive'.  Please see the documentation of the
+     variable for more details.  The default filter is 'normal'.
+
+   Ess-eldoc also honors the value of 'eldoc-echo-area-use-multiline-p',
+which if set to 'nil', will cause the truncation of doc string
+indifferent of the value of 'ess-eldoc-abbreviation-style'.  This way
+you can combine different filter levels with the truncation.
+
+\1f
+File: ess.info,  Node: ESS Flymake,  Next: Handy commands,  Prev: ESS ElDoc,  Up: Extras
+
+11.2 Flymake
+============
+
+The minor mode 'flymake-mode' provides on-the-fly syntax checking.  ESS
+provides support for flymake in R-mode in Emacs versions 26 and newer.
+It is enabled by default, to disable it you may set 'ess-use-flymake' to
+'nil'.  In order to use it, you may need to install the 'lintr' R
+package, available from CRAN.
+
+ -- User Option: ess-use-flymake
+     When non-nil, use flymake.  If ''process', only use flymake when
+     the buffer has an inferior process running.
+
+ -- User Option: ess-r-flymake-linters
+     This variable describes the linters to use.  It can either be a
+     string with an R expression to be used as-is or a list of strings
+     where each element is passed to 'lintr::with_defaults'.  See the
+     help page for 'lintr::default_linters' for information on available
+     linters and their defaults.
+
+ -- User Option: ess-r-flymake-lintr-cache
+     When 't' (the default), lintr uses a cache.  Change to 'nil' to
+     disable lintr's caching mechanism.
+
+\1f
+File: ess.info,  Node: Handy commands,  Next: Highlighting,  Prev: ESS Flymake,  Up: Extras
+
+11.3 Handy commands
+===================
+
+ -- Command: ess-handy-commands
+     Request and execute a command from 'ess-handy-commands' list.
+
+ -- User Option: ess-handy-commands
+     An alist of custom ESS commands available for call by
+     'ess-handy-commands' and 'ess-smart-comma' function.
+
+     Currently contains:
+
+     change-directory
+          'ess-change-directory'
+     help-index
+          'ess-display-index'
+     help-object
+          'ess-display-help-on-object'
+     vignettes
+          'ess-display-vignettes'
+     objects[ls]
+          'ess-execute-objects'
+     search
+          'ess-execute-search'
+     set-width
+          'ess-execute-screen-options'
+     install.packages
+          'ess-install.packages'
+     library
+          'ess-library'
+     setRepos
+          'ess-setRepositories'
+     sos
+          'ess-sos'
+
+   Handy commands: 'ess-library', 'ess-install.packages', etc - ask for
+item with completion and execute the correspond command.  'ess-sos' is a
+interface to 'findFn' function in package 'sos'.  If package 'sos' is
+not found, ask user for interactive install.
+
+\1f
+File: ess.info,  Node: Highlighting,  Next: Parens,  Prev: Handy commands,  Up: Extras
+
+11.4 Syntactic highlighting of buffers
+======================================
+
+ESS provides Font-Lock (*note Using Multiple Typefaces: (emacs)Faces.)
+patterns for inferior R Mode, S Mode, and R Transcript Mode buffers.
+
+   The font-lock patterns are defined by the following variables, which
+you may modify if desired:
+
+ -- User Option: inferior-R-font-lock-keywords
+     Font-lock patterns for inferior *R* processes.  (There is a
+     corresponding 'inferior-S-font-lock-keywords' for *S* processes.)
+     The default value highlights prompts, inputs, assignments, output
+     messages, vector and matrix labels, and literals such as 'NA' and
+     'TRUE'.
+
+ -- User Option: ess-R-font-lock-keywords
+     Font-lock patterns for ESS R programming mode.  (There is a
+     corresponding 'ess-S-font-lock-keywords' for S buffers.)  The
+     default value highlights function names, literals, assignments,
+     source functions and reserved words.
+
+\1f
+File: ess.info,  Node: Parens,  Next: Graphics,  Prev: Highlighting,  Up: Extras
+
+11.5 Parenthesis matching
+=========================
+
+Emacs has facilities for highlighting the parenthesis matching the
+parenthesis at point.  This feature is very useful when trying to
+examine which parentheses match each other.  This highlighting also
+indicates when parentheses are not matching.  You may activate it
+putting this in your Emacs configuration file:
+
+     (show-paren-mode)
+
+\1f
+File: ess.info,  Node: Graphics,  Next: Imenu,  Prev: Parens,  Up: Extras
+
+11.6 Using graphics with ESS
+============================
+
+One of the main features of R is its ability to generate high-resolution
+graphics plots.  When using R in a windowing environment, no additional
+configuration is necessary; plots will be shown in a new (non-Emacs)
+window.
+
+   If not using a windowing environment or S, ESS provides a number of
+features for dealing with such plots.
+
+* Menu:
+
+* printer::                     The printer() graphics driver
+* X11::                         The X11() (and other X Windows based) driver
+* winjava::                     Java Graphics Device
+
+\1f
+File: ess.info,  Node: printer,  Next: X11,  Up: Graphics
+
+11.6.1 Using ESS with the 'printer()' driver
+--------------------------------------------
+
+This is the simplest (and least desirable) method of using graphics
+within ESS. S's 'printer()' device driver produces crude character based
+plots which can be contained within the ESS process buffer itself.  To
+start using character graphics, issue the S command
+     printer(width=79)
+   (the 'width=79' argument prevents Emacs line-wrapping at column 80 on
+an 80-column terminal.  Use a different value for a terminal with a
+different number of columns.)  Plotting commands do not generate
+graphics immediately, but are stored until the 'show()' command is
+issued, which displays the current figure.
+
+\1f
+File: ess.info,  Node: X11,  Next: winjava,  Prev: printer,  Up: Graphics
+
+11.6.2 Using ESS with windowing devices
+---------------------------------------
+
+Of course, the ideal way to use graphics with ESS is to use a windowing
+system.  Under X Windows, or X11, this requires that the DISPLAY
+environment variable be appropriately set.
+
+\1f
+File: ess.info,  Node: winjava,  Prev: X11,  Up: Graphics
+
+11.6.3 Java Graphics Device
+---------------------------
+
+S+6.1 and newer on Windows contains a java library that supports
+graphics.  Send the commands:
+
+     library(winjava)
+     java.graph()
+
+to start the graphics driver.  This allows you to use ESS for both
+interaction and graphics within S-PLUS. (Thanks to Tim Hesterberg for
+this information.)
+
+\1f
+File: ess.info,  Node: Imenu,  Next: Outline,  Prev: Graphics,  Up: Extras
+
+11.7 Imenu
+==========
+
+Imenu is an Emacs tool for providing mode-specific buffer indexes.  In
+some of the ESS editing modes (currently SAS and R), support for Imenu
+is provided.  For example, in R mode buffers, the menubar should display
+an item called "Imenu-R". Within this menubar you will then be offered
+bookmarks to particular parts of your source file (such as the starting
+point of each function definition).
+
+   Imenu works by searching your buffer for lines that match what ESS
+thinks is the beginning of a suitable entry, for example the beginning
+of a function definition.  To examine the regular expression that ESS
+uses, check the value of 'imenu-generic-expression'.  This value is set
+by various ESS variables such as 'ess-imenu-S-generic-expression'.
+
+\1f
+File: ess.info,  Node: Outline,  Next: Toolbar,  Prev: Imenu,  Up: Extras
+
+11.8 Outline navigation
+=======================
+
+R editing buffers integrate with 'outline-minor-mode'.  When you toggle
+the minor mode (for example via 'M-x outline-minor-mode' or by adding it
+to 'ess-r-mode-hook'), ESS assigns 'ess-r-outline-level' to
+'outline-level' and configures 'outline-regexp' according to
+'ess-r-outline-style' so that comment headings drive folding.  By
+default, outline support is disabled ('none'), but you can enable it by
+setting 'ess-r-outline-style' to 'RStudio' or 'Org-like'.  With the
+'RStudio' style, lines that begin with one or more '#', followed by text
+and a trailing marker of '----', '====', or '####', are treated as
+outline headings.  This matches the section markers convention adopted
+by RStudio.
+
+     # Setup ----
+     ## Data ----
+     ### Models ====
+     #### Helpers ####
+
+   The number of leading '#' characters sets the outline depth.  When
+using the RStudio outline style, 'ess-indent-with-fancy-comments' is
+automatically set to 'nil' locally in the buffer to prevent single-hash
+comments from being treated as right-margin comments with
+'comment-column' 40.  When switching back to a different outline style,
+the original local binding is restored; if the variable was not
+buffer-local, the current global default applies.
+
+   Use standard Outline commands (such as 'C-c  C-t') to cycle
+visibility once the minor mode is active.  To enable Outlining
+automatically, add it to the R mode hook:
+
+     (add-hook 'ess-r-mode-hook #'outline-minor-mode)
+
+ -- User Option: ess-r-outline-style
+     Select which outline convention 'ess-r-mode' should use.  The
+     default 'none' disables outline support to preserve backward
+     compatibility.  Set to 'RStudio' to recognise the comment rulers
+     shown above, or choose 'Org-like' to match the '### * Section'
+     pattern, inspired from org-mode:
+
+          ### * Setup
+          ### ** Data
+          ### *** Models
+          ### **** Helpers
+
+     You can switch styles via 'M-x ess-r-set-outline-style' or by
+     customizing this option.
+
+\1f
+File: ess.info,  Node: Toolbar,  Next: Xref,  Prev: Outline,  Up: Extras
+
+11.9 Toolbar
+============
+
+The R and S editing modes have support for a toolbar.  This toolbar
+provides icons to act as shortcuts for starting new S/R processes, or
+for evaluating regions of your source buffers.  The toolbar should be
+present if your Emacs can display images.  *Note Customization::, for
+ways to change the toolbar.
+
+\1f
+File: ess.info,  Node: Xref,  Next: Rdired,  Prev: Toolbar,  Up: Extras
+
+11.10 Xref
+==========
+
+Xref is an Emacs interface that supports finding "identifiers," usually
+function definitions in ESS's view.  ESS ships with support for Xref in
+Emacs versions 25.1 and higher.  For how to use this feature, see *Note
+(emacs)Xref::.
+
+\1f
+File: ess.info,  Node: Rdired,  Next: Package listing,  Prev: Xref,  Up: Extras
+
+11.11 Rdired
+============
+
+Ess-rdired provides a dired-like buffer for viewing, editing and
+plotting objects in your current R session.  If you are used to using
+the dired (directory editor) facility in Emacs, this mode gives you
+similar functionality for R objects.
+
+   Start an R session with 'M-x R' and then store a few variables, such
+as:
+
+     s <- sin(seq(from=0, to=8*pi, length=100))
+     x <- c(1, 4, 9)
+     y <- rnorm(20)
+     z <- TRUE
+
+   Then use 'M-x ess-rdired' to create a buffer listing the objects in
+your current environment and display it in a new window:
+                 mode length
+       s      numeric    100
+       x      numeric      3
+       y      numeric     20
+       z      logical      1
+
+   Type 'C-h m' or '?' to get a list of the keybindings for this mode.
+For example, with your point on the line of a variable, 'p' will plot
+the object, 'v' will view it, and 'd' will mark the object for deletion
+('x' will actually perform the deletion).
+
+\1f
+File: ess.info,  Node: Package listing,  Next: Org,  Prev: Rdired,  Up: Extras
+
+11.12 Package listing
+=====================
+
+ESS[R] provides several commands to list and manage packages and objects
+under the 'C-c C-.' keymap:
+
+ -- Command: ess-r-package-list-local-packages
+     'C-c C-. l' List all packages in all available libraries.
+
+ -- Command: ess-r-package-list-available-packages
+     'C-c C-. r' List available packages from repositories listed by
+     'getOptions(``repos'')' in the current R session.
+
+ -- Command: ess-r-package-update-packages LIB REPOS
+     'C-c C-. u' Update packages in a particular library LIB and
+     repository REPOS.
+
+ -- Command: ess-rutils-rm-all
+     'C-c C-. m' Remove all R objects.
+
+ -- Command: ess-rutils-load-workspace
+     'C-c C-. w' Load a workspace file into R.
+
+ -- Command: ess-rutils-save-workspace
+     'C-c C-. s' Save a workspace file.
+
+ -- Command: ess-change-directory
+     'C-c C-. d' Change the working directory for the current R session.
+
+ -- Command: ess-rutils-html-docs
+     'C-c C-. H' Use 'browse-url' to navigate R html documentation.
+
+   Functions for listing objects and packages ('ess-rutils-local-pkgs',
+'ess-rutils-repos-pkgs', and 'ess-rutils-objs') show results in a
+separate buffer and window, in 'ess-rutils-mode', providing useful key
+bindings in this mode (type '?' in this buffer for a description).
+
+\1f
+File: ess.info,  Node: Org,  Next: Sweave and AUCTeX,  Prev: Package listing,  Up: Extras
+
+11.13 Interaction with Org mode
+===============================
+
+Org-mode (<https://orgmode.org>) now supports reproducible research and
+literate programming in many languages (including R) - see chapter 15 of
+the Org manual
+(<https://orgmode.org/org.html#Working-with-Source-Code>).  For ESS
+users, this offers a document-based work environment within which to
+embed ESS usage.  R code lives in code blocks of an Org document, from
+which it can be edited in ess-mode, evaluated, extracted ("tangled") to
+pure code files.  The code can also be exported ("woven") with the
+surrounding text to several formats including HTML and LaTeX. Results of
+evaluation including figures can be captured in the Org document, and
+data can be passed from the Org document (e.g.  from a table) to the ESS
+R process.  (This section contributed by Dan Davison and Eric Schulte.)
+
+\1f
+File: ess.info,  Node: Sweave and AUCTeX,  Prev: Org,  Up: Extras
+
+11.14 Support for Sweave in ESS and AUCTeX
+==========================================
+
+Libraries for literate data analysis are obsolete and not loaded by
+default.  This includes 'ess-noweb', 'ess-swv', and related
+functionality like 'Rnw-mode'.  Users are encouraged to switch to one of
+several other packages that deal with these modes.  For example,
+polymode <https://github.com/polymode/poly-R/>,
+<https://polymode.github.io/>, or markdown-mode with edit-indirect
+<https://jblevins.org/projects/markdown-mode>.
+
+\1f
+File: ess.info,  Node: ESS for R,  Next: ESS for SAS,  Prev: Extras,  Up: Top
+
+12 Overview of ESS features for the S family
+********************************************
+
+* Menu:
+
+* ESS(R)--Editing files::
+* iESS(R)--Inferior ESS processes::
+* Philosophies for using ESS(R)::
+* Example ESS usage::
+
+\1f
+File: ess.info,  Node: ESS(R)--Editing files,  Next: iESS(R)--Inferior ESS processes,  Up: ESS for R
+
+12.1 ESS[R]-Editing files
+=========================
+
+ESS[R] mode should be automatically turned on when visiting a file
+ending with an R or S suffix (*.R, *.S, *.s, etc), which enables the
+features discussed previously.  Alternatively, type 'M-x R-mode' to put
+the current buffer into R mode.  However, one will have to start up an
+inferior process to take advantage of the interactive features.
+
+\1f
+File: ess.info,  Node: iESS(R)--Inferior ESS processes,  Next: Philosophies for using ESS(R),  Prev: ESS(R)--Editing files,  Up: ESS for R
+
+12.2 iESS[R]-Inferior ESS processes
+===================================
+
+To start up iESS mode for R, use:
+        M-x R
+        M-x S+3
+        M-x S4
+        M-x S+5
+        M-x S+6
+
+(for R, S-PLUS 3.x, S4, S+5, S+6 or S+7, respectively.  This assumes
+that you have access to each).
+
+   In the case that you wish to pass command line arguments to the
+starting R process, call it with the universal prefix.  To set command
+line arguments that apply to all future iESS sessions, set the variable
+'inferior-R-args'.
+
+   Note that R has some extremely useful command line arguments.  For
+example, '--vanilla' will ensure R starts up without loading in any init
+files.
+
+   If you have other versions of R or S available on the system, ESS is
+also able to start those versions.  How this exactly works depend on
+which OS you are using (details below).  The general principle,
+regardless of OS, is that ESS searches the paths listed in the variable
+'exec-path' for R binaries.  If ESS cannot find your R binaries, on Unix
+you can change the Unix environment variable 'PATH', as this variable is
+used to set 'exec-path'.
+
+   R on GNU/Linux systems and other Unix-like systems (macOS): If you
+have "R-3.6.3" on your 'exec-path', it can be started using 'M-x
+R-3.6.3'.  By default, ESS will find versions of R beginning "R-1",
+"R-2", ..., "R-7", "R-devel", or "R-patched".  If your versions of R are
+called other names, consider renaming them with a symbolic link or
+change the variable 'ess-r-runners-prefixes'.  To see which functions
+have been created for starting different versions of R, type 'M-x R-'
+and then hit [Tab].  These other versions of R can also be started from
+the "ESS->Start Process->Other" menu.
+
+   R on Windows systems: If you have "rw1081" on your 'exec-path', it
+can be started using 'M-x rw1081'.  By default, ESS will find versions
+of R located in directories parallel to the version of R in your 'PATH'.
+If your versions of R are called other names, you will need to change
+the variable 'ess-rterm-versions'.  To see which functions have been
+created for starting different versions of R, type 'M-x rw' and then hit
+[Tab].  These other versions of R can also be started from the
+"ESS->Start Process->Other" menu.
+
+   Once ESS has found these extra versions of R, it will then create a
+new function, called 'M-x run-ess-r-newest', which will call the newest
+version of R that it found.  (ESS examines the date in the first line of
+information from 'R --version' to determine which is newest.)
+
+\1f
+File: ess.info,  Node: Philosophies for using ESS(R),  Next: Example ESS usage,  Prev: iESS(R)--Inferior ESS processes,  Up: ESS for R
+
+12.3 Philosophies for using ESS[R]
+==================================
+
+There are two philosophies for using ESS. Most modern best practices
+prefer the first.  ESS is configured for the first, and this is what the
+manual focuses on.
+
+   1: The source code is real.  Objects are realizations of the source
+code.  Source for EVERY user modified object is placed in a particular
+directory or directories, for later editing and retrieval.
+
+   2: R objects are real.  Source code is a temporary realization of the
+objects.  Dumped buffers should not be saved.
+_We_strongly_discourage_this_approach_.  However, if you insist, add the
+following lines to your Emacs configuration file:
+     (setq ess-keep-dump-files nil)
+     (setq ess-delete-dump-files t)
+     (setq ess-mode-silently-save nil)
+
+\1f
+File: ess.info,  Node: Example ESS usage,  Prev: Philosophies for using ESS(R),  Up: ESS for R
+
+12.4 Example ESS usage
+======================
+
+Comments as to what should be happening are prefixed by "##".
+
+         ### Data Analysis Example
+
+         ## Open the file you want with
+         C-x C-f myfile.R
+
+         ## Edit as appropriate, then start and switch to an *R*
+         process buffer with
+         C-c C-z
+
+         ## A new buffer *R* will appear. R will have been started
+         ## in this buffer. The buffer is in iESS [R] mode.
+
+         ## Return to the script
+         C-z (or C-c C-z if you have pressed other keys in between)
+
+         ## Send current region (if active), or function, or paragraph at
+         point with
+         C-M-x
+
+         ## Send current region or function or paragraph and step with
+         C-c C-c
+
+         ## Send current line with
+         C-RET
+
+         ## or load the entire buffer with
+         C-c C-l
+
+         ## Save the revised myfile.R with
+         C-x C-s.
+
+         ## Save the entire *R* interaction buffer with
+         C-x C-s.
+
+         ## Search for documentation with
+         C-c C-d
+
+         ## Investigate available ESS commands with
+         C-c C-h
+
+         ## You will be prompted for a file name. The recommended name is
+         ## myfile.Rout. With this suffix, the file will be opened in
+         ## ess-transcript.
+
+
+\1f
+File: ess.info,  Node: ESS for SAS,  Next: ESS for BUGS,  Prev: ESS for R,  Up: Top
+
+13 ESS for SAS
+**************
+
+* Menu:
+
+* ESS(SAS)--Design philosophy::
+* ESS(SAS)--Editing files::
+* ESS(SAS)--TAB key::
+* ESS(SAS)--Batch SAS processes::
+* ESS(SAS)--Function keys for batch processing::
+* iESS(SAS)--Interactive SAS processes::
+* iESS(SAS)--Common problems::
+* ESS(SAS)--Graphics::
+* ESS(SAS)--Windows::
+ESS[SAS] was designed for use with SAS.  It is descended from emacs
+macros developed by John Sall for editing SAS programs and 'SAS-mode' by
+Tom Cook.  Those editing features and new advanced features are part of
+ESS[SAS].  The user interface of ESS[SAS] has similarities with ESS[S]
+and the SAS Display Manager.
+
+\1f
+File: ess.info,  Node: ESS(SAS)--Design philosophy,  Next: ESS(SAS)--Editing files,  Up: ESS for SAS
+
+13.1 ESS[SAS]-Design philosophy
+===============================
+
+ESS[SAS] was designed to aid the user in writing and maintaining SAS
+programs, such as 'FOO.sas'.  Both interactive and batch submission of
+SAS programs is supported.
+
+   ESS[SAS] was written with two primary goals.
+  1. The emacs text editor provides a powerful and flexible development
+     environment for programming languages.  These features are a boon
+     to all programmers and, with the help of ESS[SAS], to SAS users as
+     well.
+  2. Although a departure from SAS Display Manager, ESS[SAS] provides
+     similar key definitions to give novice ESS[SAS] users a head start.
+     Also, inconvenient SAS Display Manager features, like remote
+     submission and syntax highlighting, are provided transparently;
+     appealing to advanced ESS[SAS] users.
+
+\1f
+File: ess.info,  Node: ESS(SAS)--Editing files,  Next: ESS(SAS)--TAB key,  Prev: ESS(SAS)--Design philosophy,  Up: ESS for SAS
+
+13.2 ESS[SAS]-Editing files
+===========================
+
+ESS[SAS] is the mode for editing SAS language files.  This mode handles:
+
+   * proper indenting, generated by both <TAB> and <RET>.
+   * color and font choices based on syntax.
+   * ability to save and submit the file you are working on as a batch
+     SAS process with a single keypress and to continue editing while it
+     is runs in the background.
+   * capability of killing the batch SAS process through the '*shell*'
+     buffer or allow the SAS process to keep on running after you exit
+     emacs.
+   * single keypress navigation of '.sas', '.log' and '.lst' files
+     ('.log' and '.lst' files are refreshed with each keypress).
+   * ability to send the contents of an entire buffer, a highlighted
+     region, or a single line to an interactive SAS process.
+   * ability to switch between processes which would be the target of
+     the buffer (for the above).
+
+   ESS[SAS] is automatically turned on when editing a file with a '.sas'
+suffix (or other extension, if specified via 'auto-mode-alist').  The
+function keys can be enabled to use the same function keys that the SAS
+Display Manager does.  The interactive capabilities of ESS require you
+to start an inferior SAS process with 'M-x SAS' (*Note
+iESS(SAS)--Interactive SAS processes::.)
+
+   At this writing, the indenting and syntax highlighting are generally
+correct.  Known issues: for multiple line '*' or '%*' comments, only the
+first line is highlighted; for '.log' files, only the first line of a
+'NOTE:', 'WARNING:' or 'ERROR:' message is highlighted; unmatched
+single/double quotes in 'CARDS' data lines are *NOT* ignored; in an
+iterative 'DO' statement, 'TO' and 'BY' are not highlighted.
+
+\1f
+File: ess.info,  Node: ESS(SAS)--TAB key,  Next: ESS(SAS)--Batch SAS processes,  Prev: ESS(SAS)--Editing files,  Up: ESS for SAS
+
+13.3 ESS[SAS]-<TAB> key
+=======================
+
+Two options.  The <TAB> key is bound by default to 'sas-indent-line'.
+This function is used to syntactically indent SAS code so 'PROC' and
+'RUN' are in the left margin, other statements are indented
+'sas-indent-width' spaces from the margin, continuation lines are
+indented 'sas-indent-width' spaces in from the beginning column of that
+statement.  This is the type of functionality that emacs provides in
+most programming language modes.  This functionality is activated by
+placing the following line in your initialization file prior to a
+'require'/'load':
+     (setq ess-sas-edit-keys-toggle nil)
+
+   ESS provides an alternate behavior for <TAB> that makes it behave as
+it does in SAS Display Manager, i.e.  move the cursor to the next stop.
+The alternate behavior also provides a "TAB" backwards, 'C-<TAB>', that
+moves the cursor to the stop to the left and deletes any characters
+between them.  This functionality is obtained by placing the following
+line in your initialization file prior to a 'require'/'load':
+     (setq ess-sas-edit-keys-toggle t)
+   Under the alternate behavior, <TAB> is bound to 'M-x tab-to-tab-stop'
+and the stops are defined by 'ess-sas-tab-stop-list'.
+
+\1f
+File: ess.info,  Node: ESS(SAS)--Batch SAS processes,  Next: ESS(SAS)--Function keys for batch processing,  Prev: ESS(SAS)--TAB key,  Up: ESS for SAS
+
+13.4 ESS[SAS]-Batch SAS processes
+=================================
+
+Submission of a SAS batch job is dependent on your environment.
+'ess-sas-submit-method' is determined by your operating system and your
+shell.  It defaults to ''sh' unless you are running Windows or Mac
+Classic.  Under Windows, it will default to ''sh' if you are using a
+UNIX-imitating shell; otherwise ''ms-dos' for an MS-DOS shell.  On
+macOS, it will default to ''sh', but under Mac Classic, it defaults to
+''apple-script'.  You will also set this to ''sh' if the SAS batch job
+needs to run on a remote machine rather than your local machine.  This
+works transparently if you are editing the remote file via ange-ftp/EFS
+or tramp.  Note that 'ess-sas-shell-buffer-remote-init' is a Local
+Variable that defaults to '"ssh"' which will be used to open the buffer
+on the remote host and it is assumed that no password is necessary, i.e.
+you are using 'ssh-agent'/'ssh-add' or the equivalent (see the
+discussion about Local Variables below if you need to change the
+default).
+
+   However, if you are editing the file locally and transferring it back
+and forth with Kermit, you need some additional steps.  First, start
+Kermit locally before remotely logging in.  Open a local copy of the
+file with the 'ess-kermit-prefix' character prepended (the default is
+'"#"').  Execute the command 'M-x ess-kermit-get' which automatically
+brings the contents of the remote file into your local copy.  If you
+transfer files with Kermit manually in a '*shell*' buffer, then note
+that the Kermit escape sequence is 'C-q C-\ c' rather than 'C-\ c' which
+it would be in an ordinary terminal application, i.e.  not in an emacs
+buffer.  Lastly, note that the remote Kermit command is specified by
+'ess-kermit-command'.
+
+   The command used by the 'SUBMIT' function key (<F3> or <F8>) to
+submit a batch SAS job, whether local or remote, is
+'ess-sas-submit-command' which defaults to 'sas-program'.  'sas-program'
+is '"invoke SAS using program file"' for Mac Classic and '"sas"'
+otherwise.  However, you may have to alter 'ess-sas-submit-command' for
+a particular program, so it is defined as buffer-local.  Conveniently,
+it can be set at the end of the program:
+     endsas;
+     Local variables:
+     ess-sas-submit-command: "sas8"
+     End:
+
+   The command line is also made of 'ess-sas-submit-pre-command',
+'ess-sas-submit-post-command' and 'ess-sas-submit-command-options' (the
+last of which is also buffer-local).  Here are some examples for your
+'~/.emacs' or '~/.emacs.d/init.el' file (you may also use
+'M-x customize-variable'):
+     ;'sh default
+     (setq ess-sas-submit-pre-command "nohup")
+     ;'sh default
+     (setq ess-sas-submit-post-command "-rsasuser &")
+     ;'sh example
+     (setq-default ess-sas-submit-command "/usr/local/sas/sas")
+     ;'ms-dos default
+     (setq ess-sas-submit-pre-command "start")
+     ;'ms-dos default
+     (setq ess-sas-submit-post-command "-rsasuser -icon")
+     ;Windows example
+     (setq-default ess-sas-submit-command "c:/progra~1/sas/sas.exe")
+     ;Windows example
+     (setq-default ess-sas-submit-command "c:\\progra~1\\sas\\sas.exe")
+
+   There is a built-in delay before a batch SAS job is submitted when
+using a UNIX-imitating shell under Windows.  This is necessary in many
+cases since the shell might not be ready to receive a command.  This
+delay is currently set high enough so as not to be a problem.  But,
+there may be cases when it needs to be set higher, or could be set much
+lower to speed things up.  You can over-ride the default in your
+'~/.emacs' or '~/.emacs.d/init.el' file by:
+     (setq ess-sleep-for 0.2)
+
+   For example, '(setq ess-sas-global-unix-keys t)' keys shown, '(setq
+ess-sas-global-pc-keys t)' in parentheses; ESS[SAS] function keys are
+presented in the next section.  Open the file you want to work with
+'C-x C-f foo.sas'.  'FOO.sas' will be in ESS[SAS] mode.  Edit as
+appropriate, then save and submit the batch SAS job.
+     <F3> (<F8>)
+   The job runs in the '*shell*' buffer while you continue to edit
+'FOO.sas'.  If 'ess-sas-submit-method' is ''sh', then the message buffer
+will display the shell notification when the job is complete.  The ''sh'
+setting also allows you to terminate the SAS batch job before it is
+finished.
+     <F8> (<F3>)
+   Terminating a SAS batch in the '*shell*' buffer.
+     kill PID
+   You may want to visit the '.log' (whether the job is still running or
+it is finished) and check for error messages.  The '.log' will be
+refreshed and you will be placed in it's buffer.  You will be taken to
+the first error message, if any.
+     <F5> (<F6>)
+   Goto the next error message, if any.
+     <F5> (<F6>)
+   Now, 'refresh' the '.lst' and go to it's buffer.
+     <F6> (<F7>)
+   If you wish to make changes, go to the '.sas' file with.
+     <F4> (<F5>)
+   Make your editing changes and submit again.
+     <F3> (<F8>)
+
+\1f
+File: ess.info,  Node: ESS(SAS)--Function keys for batch processing,  Next: iESS(SAS)--Interactive SAS processes,  Prev: ESS(SAS)--Batch SAS processes,  Up: ESS for SAS
+
+13.5 ESS[SAS]-Function keys for batch processing
+================================================
+
+The setup of function keys for SAS batch processing is unavoidably
+complex, but the usage of function keys is simple.  There are five
+distinct options:
+
+   Option 1 (default).  Function keys in ESS[SAS] are not bound to Elisp
+commands.  This is in accordance with the GNU Elisp Coding Standards
+(GECS) which do not allow function keys to be bound so that they are
+available to the user.
+
+   Options 2-5.  Since GECS does not allow function keys to be bound by
+modes, these keys are often unused.  So, ESS[SAS] provides users with
+the option of binding Elisp commands to these keys.  Users who are
+familiar with SAS will, most likely, want to duplicate the function key
+capabilities of the SAS Display Manager.  There are four options (noted
+in parentheses).
+
+  a. SAS Display Manager has different function key definitions for UNIX
+     (2, 4) and Windows (3, 5); ESS[SAS] can use either.
+  b. The ESS[SAS] function key definitions can be active in all buffers
+     (global: 4, 5) or limited (local: 2, 3) only to buffers with files
+     that are associated with ESS[SAS] as specified in your
+     'auto-mode-alist'.
+
+   The distinction between local and global is subtle.  If you want the
+ESS[SAS] definitions to work when you are in the '*shell*' buffer or
+when editing files other than the file extensions that ESS[SAS]
+recognizes, you will most likely want to use the global definitions.  If
+you want your function keys to understand SAS batch commands when you
+are editing SAS files, and to behave normally when editing other files,
+then you will choose the local definitions.  The option can be chosen by
+the person installing ESS for a site or by an individual.
+
+  a. For a site installation or an individual, place *ONLY ONE* of the
+     following lines in your initialization file prior to a
+     'require'/'load'.  ESS[SAS] function keys are available in ESS[SAS]
+     if you choose either 2 or 3 and in all modes if you choose 4 or 5:
+          ;;2; (setq ess-sas-local-unix-keys t)
+          ;;3; (setq ess-sas-local-pc-keys t)
+          ;;4; (setq ess-sas-global-unix-keys t)
+          ;;5; (setq ess-sas-global-pc-keys t)
+
+     The names '-unix-' and '-pc-' have nothing to do with the operating
+     system that you are running.  Rather, they mimic the definitions
+     that the SAS Display Manager uses by default on those platforms.
+
+  b. If your site installation has configured the keys contrary to your
+     liking, then you must call the appropriate function.
+           (load "ess-site") ;; local-unix-keys
+           (ess-sas-global-pc-keys)
+
+   Finally, we get to what the function keys actually do.  You may
+recognize some of the nicknames as SAS Display Manager commands (they
+are in all capitals).
+
+UNIX     PC       Nickname
+<F2>     <F2>     'refresh'
+                  revert the current buffer with the file of the same name if the file is
+                  newer than the buffer
+<F3>     <F8>     'SUBMIT'
+                  save the current '.sas' file (which is either the '.sas' file in the
+                  current buffer or the '.sas' file associated with the '.lst' or '.log'
+                  file in the current buffer) and submit the file as a batch SAS job
+<F4>     <F5>     'PROGRAM'
+                  switch buffer to '.sas' file
+<F5>     <F6>     'LOG'
+                  switch buffer to '.log' file, 'refresh' and goto next error message, if
+                  any
+<F6>     <F7>     'OUTPUT'
+                  switch buffer to '.lst' file and 'refresh'
+<F7>     <F4>     'filetype-1'
+                  switch buffer to 'filetype-1' (defaults to '.txt') file and 'refresh'
+<F8>     <F3>     'shell'
+                  switch buffer to '*shell*'
+<F9>     <F9>     'VIEWTABLE'
+                  open an interactive 'PROC FSEDIT' session on the SAS dataset near point
+<F10>    <F10>    toggle-log
+                  toggle ESS[SAS] for '.log' files; useful for certain debugging situations
+<F11>    <F11>    'filetype-2'
+                  switch buffer to 'filetype-2' (defaults to '.dat') file and 'refresh'
+<F12>    <F12>    viewgraph
+                  open a 'GSASFILE' near point for viewing either in emacs or with an
+                  external viewer
+'C-<F1>' 'C-<F1>' rtf-portrait
+                  create an MS RTF portrait file from the current buffer with a file
+                  extension of '.rtf'
+'C-<F2>' 'C-<F2>' rtf-landscape
+                  create an MS RTF landscape file from the current buffer with a file
+                  extension of '.rtf'
+'C-<F3>' 'C-<F8>' submit-region
+                  write region to 'ess-temp.sas' and submit
+'C-<F5>' 'C-<F6>' append-to-log
+                  append 'ess-temp.log' to the current '.log' file
+'C-<F6>' 'C-<F7>' append-to-output
+                  append 'ess-temp.lst' to the current '.lst' file
+'C-<F9>' 'C-<F9>' 'INSIGHT'
+                  open an interactive 'PROC INSIGHT' session on the SAS dataset near point
+'C-<F10>''C-<F10>'toggle-listing
+                  toggle ESS[SAS] for '.lst' files; useful for toggling read-only
+
+   'SUBMIT', 'PROGRAM', 'LOG' and 'OUTPUT' need no further explanation
+since they mimic the SAS Display Manager commands and related function
+key definitions.  However, six other keys have been provided for
+convenience and are described below.
+
+   'shell' switches you to the '*shell*' buffer where you can interact
+with your operating system.  This is especially helpful if you would
+like to kill a SAS batch job.  You can specify a different buffer name
+to associate with a SAS batch job (besides '*shell*') with the
+buffer-local variable 'ess-sas-shell-buffer'.  This allows you to have
+multiple buffers running SAS batch jobs on multiple local/remote
+computers that may rely on different methods specified by the
+buffer-local variable 'ess-sas-submit-method'.
+
+   <F2> performs the 'refresh' operation on the current buffer.
+'refresh' compares the buffer's last modified date/time with the file's
+last modified date/time and replaces the buffer with the file if the
+file is newer.  This is the same operation that is automatically
+performed when 'LOG', 'OUTPUT', 'filetype-1' or <F11> are pressed.
+
+   'filetype-1' switches you to a file with the same file name as your
+'.sas' file, but with a different extension ('.txt' by default) and
+performs 'refresh'.  You can over-ride the default extension; for
+example in your '~/.emacs' or '~/.emacs.d/init.el' file:
+     (setq ess-sas-suffix-1 "csv") ; for example
+
+   <F9> will prompt you for the name of a permanent SAS dataset near
+point to be opened for viewing by 'PROC FSEDIT'.  You can control the
+SAS batch command-line with 'ess-sas-data-view-submit-options'.  For
+controlling the SAS batch commands, you have the global variables
+'ess-sas-data-view-libname' and 'ess-sas-data-view-fsview-command' as
+well as the buffer-local variable 'ess-sas-data-view-fsview-statement'.
+If you have your SAS 'LIBNAME' defined in '~/autoexec.sas', then the
+defaults for these variables should be sufficient.
+
+   Similarly, 'C-<F9>' will prompt you for the name of a permanent SAS
+dataset near point to be opened for viewing by 'PROC INSIGHT'.  You can
+control the SAS batch command-line with
+'ess-sas-data-view-submit-options'.  For controlling the SAS batch
+commands, you have the global variables 'ess-sas-data-view-libname' and
+'ess-sas-data-view-insight-command' as well as the buffer-local variable
+'ess-sas-data-view-insight-statement'.
+
+   <F10> toggles ESS[SAS] mode for '.log' files which is off by default
+(technically, it is 'SAS-log-mode', but it looks the same).  The syntax
+highlighting can be helpful in certain debugging situations, but large
+'.log' files may take a long time to highlight.
+
+   <F11> is the same as 'filetype-1' except it is '.dat' by default.
+
+   <F12> will prompt you for the name of a 'GSASFILE' near the point in
+'.log' to be opened for viewing either with emacs or with an external
+viewer.  Depending on your version of emacs and the operating system you
+are using, emacs may support '.gif' and '.jpg' files internally.  You
+may need to change the following variables for your own situation.
+'ess-sas-graph-view-suffix-regexp' is a regular expression of supported
+file types defined via file name extensions.
+'ess-sas-graph-view-viewer-default' is the default external viewer for
+your platform.  'ess-sas-graph-view-viewer-alist' is an alist of
+exceptions to the default; i.e.  file types and their associated viewers
+which will be used rather than the default viewer.
+     (setq ess-sas-graph-view-suffix-regexp (concat "[.]\\([eE]?[pP][sS]\\|"
+     "[pP][dD][fF]\\|[gG][iI][fF]\\|[jJ][pP][eE]?[gG]\\|"
+     "[tT][iI][fF][fF]?\\)")) ;; default
+     (setq ess-sas-graph-view-viewer-default "kodakimg") ;; Windows default
+     (setq ess-sas-graph-view-viewer-default "sdtimage") ;; Solaris default
+     (setq ess-sas-graph-view-viewer-alist
+       '(("[eE]?[pP][sS]" . "gv") ("[pP][dD][fF]" . "gv")) ;; default w/ gv
+
+   'C-<F2>' produces US landscape by default, however, it can produce A4
+landscape (first line for "global" key mapping, second for "local"):
+     (global-set-key [(control f2)] 'ess-sas-rtf-a4-landscape)
+     (define-key sas-mode-local-map [(control f2)] 'ess-sas-rtf-a4-landscape)
+
+\1f
+File: ess.info,  Node: iESS(SAS)--Interactive SAS processes,  Next: iESS(SAS)--Common problems,  Prev: ESS(SAS)--Function keys for batch processing,  Up: ESS for SAS
+
+13.6 iESS[SAS]-Interactive SAS processes
+========================================
+
+Inferior ESS (iESS) is the method for interfacing with interactive
+statistical processes (programs).  iESS[SAS] is what is needed for
+interactive SAS programming.  iESS[SAS] works best with the SAS
+command-line option settings '"-stdio -linesize 80 -noovp
+-nosyntaxcheck"' (the default of 'inferior-SAS-args').
+
+     '-stdio'
+                 required to make the redirection of stdio work
+     '-linesize 80'
+                 keeps output lines from folding on standard terminals
+     '-noovp'
+                 prevents error messages from printing 3 times
+     '-nosyntaxcheck'
+                 permits recovery after syntax errors
+
+   To start up iESS[SAS] mode, use:
+        M-x SAS
+
+   The '*SAS:1.log*' buffer in 'ESStr' mode corresponds to the file
+'FOO.log' in SAS batch usage and to the 'SAS: LOG' window in the SAS
+Display Manager.  All commands submitted to SAS, informative messages,
+warnings, and errors appear here.
+
+   The '*SAS:1.lst*' buffer in 'ESSlst' mode corresponds to the file
+'FOO.lst' in SAS batch usage and to the 'SAS: OUTPUT' window in the SAS
+Display Manager.  All printed output appears in this window.
+
+   The '*SAS:1*' buffer exists solely as a communications buffer.  The
+user should never use this buffer directly.  Files are edited in the
+'FOO.sas' buffer.  The 'C-c C-r' key in ESS[SAS] is the functional
+equivalent of bringing a file into the 'SAS: PROGRAM EDITOR' window
+followed by 'SUBMIT'.
+
+   For example, open the file you want to work with.
+     C-x C-f foo.sas
+   'FOO.sas' will be in ESS[SAS] mode.  Edit as appropriate, and then
+start up SAS with the cursor in the 'FOO.sas' buffer.
+     M-x SAS
+   Four buffers will appear on screen:
+Buffer         Mode              Description
+'FOO.sas'      'ESS[SAS]'        your source file
+'*SAS:1*'      'iESS[SAS:1]'     iESS communication buffer
+'*SAS:1.log*'  'Shell ESStr      SAS log information
+               []'
+'*SAS:1.lst*'  'Shell ESSlst     SAS listing information
+               []'
+   If you would prefer each of the four buffers to appear in its own
+individual frame, you can arrange for that.  Place the cursor in the
+buffer displaying 'FOO.sas'.  Enter the sequence 'C-c C-w'.  The cursor
+will normally be in buffer 'FOO.sas'.  If not, put it there and
+'C-x b FOO.sas'.
+
+   Send regions, lines, or the entire file contents to SAS (regions are
+most useful: a highlighted region will normally begin with the keywords
+'DATA' or 'PROC' and end with 'RUN;'), 'C-c C-r'.
+
+   Information appears in the log buffer, analysis results in the
+listing buffer.  In case of errors, make the corrections in the
+'FOO.sas' buffer and resubmit with another 'C-c C-r'.
+
+   At the end of the session you may save the log and listing buffers
+with the usual 'C-x C-s' commands.  You will be prompted for a file
+name.  Typically, the names 'FOO.log' and 'FOO.lst' will be used.  You
+will almost certainly want to edit the saved files before including them
+in a report.  The files are read-only by default.  You can make them
+writable by the emacs command 'C-x C-q'.
+
+   At the end of the session, the input file 'FOO.sas' will typically
+have been revised.  You can save it.  It can be used later as the
+beginning of another iESS[SAS] session.  It can also be used as a batch
+input file to SAS.
+
+   The '*SAS:1*' buffer is strictly for ESS use.  The user should never
+need to read it or write to it.  Refer to the '.lst' and '.log' buffers
+for monitoring output!
+
+   Troubleshooting: *Note iESS(SAS)--Common problems::.
+
+\1f
+File: ess.info,  Node: iESS(SAS)--Common problems,  Next: ESS(SAS)--Graphics,  Prev: iESS(SAS)--Interactive SAS processes,  Up: ESS for SAS
+
+13.7 iESS[SAS]-Common problems
+==============================
+
+  1. iESS[SAS] does not work on Windows.  In order to run SAS inside an
+     emacs buffer, it is necessary to start SAS with the '-stdio'
+     option.  SAS does not support the '-stdio' option on Windows.
+  2. If 'M-x SAS' gives errors upon startup, check the following:
+        * you are running Windows: see 1.
+        * 'ess-sas-sh-command' (from the ESS 'etc' directory) needs to
+          be executable; too check, type 'M-x dired'; if not, fix it as
+          follows, type 'M-:', then at the minibuffer prompt 'Eval:',
+          type '(set-file-modes "ess-sas-sh-command" 493)'.
+        * 'sas' isn't in your executable path; to verify, type 'M-:' and
+          at the minibuffer prompt 'Eval:', type '(executable-find
+          "sas")'
+  3. 'M-x SAS' starts SAS Display Manager.  Probably, the command 'sas'
+     on your system calls a shell script.  In that case you will need to
+     locate the real 'sas' executable and link to it.  You can execute
+     the UNIX command:
+          find / -name sas -print
+     Now place a soft link to the real 'sas' executable in your '~/bin'
+     directory, with for example
+          cd ~/bin
+          ln -s /usr/local/sas9/sas sas
+   Check your 'PATH' environment variable to confirm that '~/bin'
+appears before the directory in which the 'sas' shell script appears.
+
+\1f
+File: ess.info,  Node: ESS(SAS)--Graphics,  Next: ESS(SAS)--Windows,  Prev: iESS(SAS)--Common problems,  Up: ESS for SAS
+
+13.8 ESS[SAS]-Graphics
+======================
+
+Output from a SAS/GRAPH 'PROC' can be displayed in a SAS/GRAPH window
+for SAS batch on Windows or for both SAS batch and interactive with
+XWindows on UNIX.  If you need to create graphics files and view them
+with <F12>, then include the following (either in 'FOO.sas' or in
+'~/autoexec.sas'):
+     filename gsasfile 'graphics.ps';
+     goptions device=ps gsfname=gsasfile gsfmode=append;
+   'PROC PLOT' graphs can be viewed in the listing buffer.  You may wish
+to control the vertical spacing to allow the entire plot to be visible
+on screen, for example:
+     proc plot;
+         plot a*b / vpos=25;
+     run;
+
+\1f
+File: ess.info,  Node: ESS(SAS)--Windows,  Prev: ESS(SAS)--Graphics,  Up: ESS for SAS
+
+13.9 ESS[SAS]-Windows
+=====================
+
+   * iESS[SAS] does not work on Windows.  *Note iESS(SAS)--Common
+     problems::.
+
+   * ESS[SAS] mode for editing SAS language files works very well.
+     *Note ESS(SAS)--Editing files::.
+
+   * There are two execution options for SAS on Windows.  You can use
+     batch.  *Note ESS(SAS)--Batch SAS processes::.
+
+     Or you can mark regions with the mouse and submit the code with
+     'submit-region' or paste them into SAS Display Manager.
+
+\1f
+File: ess.info,  Node: ESS for BUGS,  Next: Mailing lists/bug reports,  Prev: ESS for SAS,  Up: Top
+
+14 ESS for BUGS
+***************
+
+ESS[BUGS] NIMBLE has re-vitalized the BUGS language.  All previous
+instances of BUGS such as OpenBUGS and JAGS are now deprecated.
+Therefore, ESS suppors BUGS syntax to allow for proper fontification of
+statements, distributions, functions, commands and comments in
+BUGS/NIMBLE model files.
+
+14.1 ESS[BUGS]-Model files
+==========================
+
+Model files with the '.bug' extension are edited in ESS[BUGS] mode.
+
+\1f
+File: ess.info,  Node: Mailing lists/bug reports,  Next: Customization,  Prev: ESS for BUGS,  Up: Top
+
+15 Bugs and Bug Reporting, Mailing Lists
+****************************************
+
+* Menu:
+
+* Bugs::
+* Reporting Bugs::
+* Mailing Lists::
+* Help with Emacs::
+
+\1f
+File: ess.info,  Node: Bugs,  Next: Reporting Bugs,  Up: Mailing lists/bug reports
+
+15.1 Bugs
+=========
+
+   * Commands like 'ess-display-help-on-object' and list completion
+     cannot be used while the user is entering a multi-line command.
+     The only real fix in this situation is to use another ESS process.
+
+   * The 'ess-eval-' commands can leave point in the ESS process buffer
+     in the wrong place when point is at the same position as the last
+     process output.  This proves difficult to fix, in general, as we
+     need to consider all _windows_ with 'window-point' at the right
+     place.
+
+   * It's possible to clear the modification flag (say, by saving the
+     buffer) with the edit buffer not having been loaded into S.
+
+   * Backup files can sometimes be left behind, even when
+     'ess-keep-dump-files' is 'nil'.
+
+   * Passing an incomplete S expression to 'ess-execute' causes ESS to
+     hang.
+
+   * The function-based commands don't always work as expected on
+     functions whose body is not a parenthesized or compound expression,
+     and don't even recognize anonymous functions (i.e.  functions not
+     assigned to any variable).
+
+   * Multi-line commands could be handled better by the command history
+     mechanism.
+
+   * Changes to the continuation prompt in R (e.g.  'options(continue =
+     " ")') are not automatically detected by ESS. Hence, for now, the
+     best thing is not to change the continuation prompt.  If you do
+     change the continuation prompt, you will need to change accordingly
+     the value of 'inferior-ess-secondary-prompt' in
+     'R-customize-alist'.
+
+\1f
+File: ess.info,  Node: Reporting Bugs,  Next: Mailing Lists,  Prev: Bugs,  Up: Mailing lists/bug reports
+
+15.2 Reporting Bugs
+===================
+
+Please post bug reports, suggestions etc.  on our github issue tracker
+(https://github.com/emacs-ess/ESS/issues); if not possible, e-mail them
+to <ESS-helpNOSPAMr-project.org>.
+
+   The easiest way to set this up, is within Emacs by typing
+
+   'M-x ess-submit-bug-report'
+
+   This also gives the maintainers valuable information about your
+installation which may help us to identify or even fix the bug.
+
+   If Emacs reports an error, backtraces can help us debug the problem.
+Type "M-x set-variable RET debug-on-error RET t RET". Then run the
+command that causes the error and you should see a *Backtrace* buffer
+containing debug information; send us that buffer.
+
+   Note that comments, suggestions, words of praise and large cash
+donations are also more than welcome.
+
+\1f
+File: ess.info,  Node: Mailing Lists,  Next: Help with Emacs,  Prev: Reporting Bugs,  Up: Mailing lists/bug reports
+
+15.3 Mailing Lists
+==================
+
+There is a mailing list for discussions and announcements relating to
+ESS. Join the list by sending an e-mail with "subscribe ess-help" (or
+"help") in the body to <ess-help-requestNOSPAMr-project.org>; contributions
+to the list may be mailed to <ess-helpNOSPAMr-project.org>.  Rest assured,
+this is a fairly low-volume mailing list.
+
+   The purposes of the mailing list include
+
+   * helping users of ESS to get along with it.
+   * discussing aspects of using ESS.
+   * suggestions for improvements.
+   * announcements of new releases of ESS.
+   * posting small patches to ESS.
+
+\1f
+File: ess.info,  Node: Help with Emacs,  Prev: Mailing Lists,  Up: Mailing lists/bug reports
+
+15.4 Help with Emacs
+====================
+
+Emacs is a complex editor with many abilities that we do not have space
+to describe here.  If you have problems with other features of Emacs
+(e.g.  printing), there are several sources to consult, including the
+Emacs FAQs (try 'M-x view-emacs-faq') and EmacsWiki
+(<https://www.emacswiki.org>).  Please consult them before asking on the
+mailing list about issues that are not specific to ESS.
+
+\1f
+File: ess.info,  Node: Customization,  Next: Indices,  Prev: Mailing lists/bug reports,  Up: Top
+
+Appendix A Customizing ESS
+**************************
+
+ESS can be easily customized to your taste simply by including the
+appropriate lines in your Emacs configuration file.  There are numerous
+variables which affect the behavior of ESS in certain situations which
+can be modified to your liking.  Keybindings may be set or changed to
+your preferences, and for per-buffer customizations hooks are also
+available.
+
+   Most of these variables can be viewed and set using the Custom
+facility within Emacs.  Type 'M-x customize-group RET ess RET' to see
+all the ESS variables that can be customized.  Variables are grouped by
+subject to make it easy to find related variables.
+
+\1f
+File: ess.info,  Node: Indices,  Prev: Customization,  Up: Top
+
+Indices
+*******
+
+* Menu:
+
+* Key index::
+* Function and program index::
+* Variable index::
+* Concept index::
+
+\1f
+File: ess.info,  Node: Key index,  Next: Function and program index,  Up: Indices
+
+Key index
+=========
+
+\0\b[index\0\b]
+* Menu:
+
+* ,:                                     Handy commands.       (line  6)
+* {:                                     Indenting.            (line 53)
+* }:                                     Indenting.            (line 53)
+* C-c C-. d:                             Package listing.      (line 30)
+* C-c C-. H:                             Package listing.      (line 33)
+* C-c C-. l:                             Package listing.      (line 10)
+* C-c C-. m:                             Package listing.      (line 21)
+* C-c C-. r:                             Package listing.      (line 13)
+* C-c C-. s:                             Package listing.      (line 27)
+* C-c C-. u:                             Package listing.      (line 17)
+* C-c C-. w:                             Package listing.      (line 24)
+* C-c C-b:                               Evaluating code.      (line 68)
+* C-c C-c:                               Other.                (line  9)
+* C-c C-c <1>:                           Evaluating code.      (line 41)
+* C-c C-e C-d:                           Edit buffer.          (line  9)
+* C-c C-e C-s:                           Styles.               (line 15)
+* C-c C-e s:                             Styles.               (line 15)
+* C-c C-f:                               Evaluating code.      (line 54)
+* C-c C-j:                               Evaluating code.      (line 47)
+* C-c C-o C-c:                           roxygen2.             (line 45)
+* C-c C-o C-h:                           roxygen2.             (line 72)
+* C-c C-o C-o:                           roxygen2.             (line 37)
+* C-c C-o C-r:                           roxygen2.             (line 51)
+* C-c C-o C-t:                           roxygen2.             (line 59)
+* C-c C-o n:                             roxygen2.             (line 69)
+* C-c C-o p:                             roxygen2.             (line 66)
+* C-c C-q:                               Hot keys.             (line 71)
+* C-C C-r:                               Evaluating code.      (line 61)
+* C-c C-s:                               Hot keys.             (line 34)
+* C-c C-t C-s:                           Namespaced Evaluation.
+                                                               (line 36)
+* C-c C-v:                               Hot keys.             (line 66)
+* C-c C-w:                               Clean.                (line 11)
+* C-c C-x:                               Hot keys.             (line 24)
+* C-c C-z:                               Other.                (line 13)
+* C-c M-b:                               Evaluating code.      (line 71)
+* C-c M-f:                               Evaluating code.      (line 57)
+* C-c M-j:                               Evaluating code.      (line 50)
+* C-c M-l:                               Hot keys.             (line 50)
+* C-c M-r:                               Evaluating code.      (line 64)
+* C-c RET:                               Resubmit.             (line 14)
+* C-c `:                                 Error Checking.       (line  9)
+* C-j:                                   Indenting.            (line 60)
+* C-M-a:                                 Other edit buffer commands.
+                                                               (line 10)
+* C-M-e:                                 Other edit buffer commands.
+                                                               (line 14)
+* C-M-h:                                 Other edit buffer commands.
+                                                               (line 18)
+* C-M-q:                                 Indenting.            (line 49)
+* C-M-x:                                 Evaluating code.      (line 38)
+* C-RET:                                 Evaluating code.      (line 34)
+* ESC C-a:                               Other edit buffer commands.
+                                                               (line 10)
+* ESC C-e:                               Other edit buffer commands.
+                                                               (line 14)
+* ESC C-h:                               Other edit buffer commands.
+                                                               (line 18)
+* ESC C-q:                               Indenting.            (line 49)
+* M-;:                                   Indenting.            (line 65)
+* M-?:                                   Object names.         (line 33)
+* M-C-q:                                 Indenting.            (line 49)
+* M-RET:                                 Resubmit.             (line 10)
+* RET:                                   Command-line editing. (line 10)
+* RET <1>:                               Resubmit.             (line 18)
+* TAB:                                   Indenting.            (line 35)
+
+\1f
+File: ess.info,  Node: Function and program index,  Next: Variable index,  Prev: Key index,  Up: Indices
+
+Function and program index
+==========================
+
+\0\b[index\0\b]
+* Menu:
+
+* backward-kill-word:                    Command-line editing.
+                                                              (line  22)
+* comint-backward-matching-input:        Process buffer motion.
+                                                              (line  31)
+* comint-bol:                            Command-line editing.
+                                                              (line  31)
+* comint-copy-old-input:                 Transcript resubmit. (line  16)
+* comint-delete-output:                  Last command.        (line  24)
+* comint-dynamic-complete:               Object names.        (line  12)
+* comint-forward-matching-input:         Process buffer motion.
+                                                              (line  32)
+* comint-history-isearch-backward-regexp: Command History.    (line  32)
+* comint-interrupt-subjob:               Other.               (line   8)
+* comint-kill-input:                     Command-line editing.
+                                                              (line  26)
+* comint-next-input:                     Command History.     (line  18)
+* comint-next-matching-input-from-input: Command History.     (line  45)
+* comint-next-prompt:                    Process buffer motion.
+                                                              (line  15)
+* comint-previous-input:                 Command History.     (line  14)
+* comint-previous-matching-input-from-input: Command History. (line  41)
+* comint-previous-prompt:                Process buffer motion.
+                                                              (line  11)
+* comint-show-output:                    Last command.        (line  20)
+* dump():                                Edit buffer.         (line  35)
+* ess-change-directory:                  Package listing.     (line  29)
+* ess-cleanup:                           Hot keys.            (line  71)
+* ess-cleanup <1>:                       Help.                (line 170)
+* ess-complete-object-name:              Object names.        (line  32)
+* ess-describe-help-mode:                Help.                (line  21)
+* ess-display-help-on-object:            Hot keys.            (line  65)
+* ess-display-help-on-object <1>:        Help.                (line   8)
+* ess-display-help-on-object <2>:        Help.                (line  25)
+* ess-dump-object-into-edit-buffer:      Edit buffer.         (line   8)
+* ess-electric-brace:                    Indenting.           (line  52)
+* ess-eval-buffer:                       Evaluating code.     (line  67)
+* ess-eval-buffer-and-go:                Evaluating code.     (line  70)
+* ess-eval-function:                     Evaluating code.     (line  53)
+* ess-eval-function-and-go:              Evaluating code.     (line  56)
+* ess-eval-line:                         Evaluating code.     (line  46)
+* ess-eval-line-and-go:                  Evaluating code.     (line  49)
+* ess-eval-line-and-step:                Help.                (line 106)
+* ess-eval-region:                       Evaluating code.     (line  60)
+* ess-eval-region <1>:                   Help.                (line 111)
+* ess-eval-region-and-go:                Evaluating code.     (line  63)
+* ess-eval-region-or-function-or-paragraph: Evaluating code.  (line  37)
+* ess-eval-region-or-function-or-paragraph-and-step: Evaluating code.
+                                                              (line  40)
+* ess-eval-region-or-line-and-step:      Evaluating code.     (line  33)
+* ess-execute-objects:                   Hot keys.            (line  23)
+* ess-execute-search:                    Hot keys.            (line  33)
+* ess-goto-beginning-of-function-or-para: Other edit buffer commands.
+                                                              (line   9)
+* ess-goto-end-of-function-or-para:      Other edit buffer commands.
+                                                              (line  13)
+* ess-handy-commands:                    Handy commands.      (line   6)
+* ess-handy-commands <1>:                Handy commands.      (line   6)
+* ess-indent-command:                    roxygen2.            (line  90)
+* ess-indent-exp:                        Indenting.           (line  48)
+* ess-indent-or-complete:                Indenting.           (line  34)
+* ess-load-file:                         Hot keys.            (line  49)
+* ess-load-file <1>:                     Loading.             (line  11)
+* ess-mark-function:                     Other edit buffer commands.
+                                                              (line  17)
+* ess-parse-errors:                      Hot keys.            (line  54)
+* ess-parse-errors <1>:                  Error Checking.      (line   9)
+* ess-quit:                              Hot keys.            (line  70)
+* ess-quit <1>:                          Help.                (line 170)
+* ess-R-complete-object-name:            roxygen2.            (line  80)
+* ess-r-outline-level:                   Outline.             (line   6)
+* ess-r-package-list-available-packages: Package listing.     (line  12)
+* ess-r-package-list-local-packages:     Package listing.     (line   9)
+* ess-r-package-update-packages:         Package listing.     (line  16)
+* ess-r-set-evaluation-env:              Namespaced Evaluation.
+                                                              (line  35)
+* ess-remote:                            ESS processes on Remote Computers.
+                                                              (line   9)
+* ess-request-a-process:                 Multiple ESS processes.
+                                                              (line  18)
+* ess-resynch:                           Object names.        (line  52)
+* ess-roxy-hide-all:                     roxygen2.            (line  71)
+* ess-roxy-move-beginning-of-line:       roxygen2.            (line  97)
+* ess-roxy-next-entry:                   roxygen2.            (line  68)
+* ess-roxy-preview-HTML:                 roxygen2.            (line  58)
+* ess-roxy-preview-Rd:                   roxygen2.            (line  50)
+* ess-roxy-previous-entry:               roxygen2.            (line  65)
+* ess-roxy-toggle-roxy-region:           roxygen2.            (line  44)
+* ess-roxy-update-entry:                 roxygen2.            (line  36)
+* ess-rutils-html-docs:                  Package listing.     (line  32)
+* ess-rutils-load-workspace:             Package listing.     (line  23)
+* ess-rutils-rm-all:                     Package listing.     (line  20)
+* ess-rutils-save-workspace:             Package listing.     (line  26)
+* ess-set-style:                         Styles.              (line  14)
+* ess-skip-to-help-section:              Help.                (line  55)
+* ess-skip-to-next-section:              Help.                (line  46)
+* ess-skip-to-previous-section:          Help.                (line  46)
+* ess-smart-comma:                       Handy commands.      (line   6)
+* ess-submit-bug-report:                 Reporting Bugs.      (line   6)
+* ess-switch-to-end-of-ESS:              Help.                (line 117)
+* ess-switch-to-inferior-or-script-buffer: Other.             (line  12)
+* ess-tracebug:                          ESS tracebug.        (line   6)
+* ess-transcript-clean-region:           Clean.               (line  10)
+* ess-transcript-copy-command:           Resubmit.            (line  13)
+* ess-transcript-send-command:           Resubmit.            (line   9)
+* ess-transcript-send-command-and-move:  Resubmit.            (line  17)
+* ess-use-ido, ess-completing-read:      Minibuffer completion.
+                                                              (line   6)
+* fill-paragraph:                        roxygen2.            (line  94)
+* getting started with tracebug:         Getting started with tracebug.
+                                                              (line   6)
+* inferior-ess-send-input:               Command-line editing.
+                                                              (line   9)
+* mark-paragraph:                        roxygen2.            (line  85)
+* newline-and-indent:                    roxygen2.            (line 102)
+* objects():                             Hot keys.            (line  24)
+* outline-minor-mode:                    Outline.             (line   6)
+* printer():                             printer.             (line  11)
+* q():                                   Hot keys.            (line  71)
+* R:                                     Starting up.         (line  11)
+* S:                                     Starting up.         (line  11)
+* search():                              Hot keys.            (line  34)
+* search() <1>:                          Object names.        (line  19)
+* source():                              Evaluating code.     (line  20)
+* source() <1>:                          Loading.             (line  11)
+* STERM:                                 Statistical Process running in ESS?.
+                                                              (line   6)
+
+\1f
+File: ess.info,  Node: Variable index,  Next: Concept index,  Prev: Function and program index,  Up: Indices
+
+Variable index
+==============
+
+\0\b[index\0\b]
+* Menu:
+
+* comint-delimiter-argument-list:        History expansion.    (line 28)
+* comint-input-ring-size:                Command History.      (line  9)
+* comment-column:                        Indenting.            (line 24)
+* ess-ask-about-transfile:               Customizing startup.  (line 36)
+* ess-ask-about-transfile <1>:           Saving transcripts.   (line 12)
+* ess-ask-for-ess-directory:             Customizing startup.  (line  7)
+* ess-ask-for-ess-directory <1>:         Customizing startup.  (line 21)
+* ess-auto-width:                        Customizing startup.  (line 56)
+* ess-auto-width-visible:                Customizing startup.  (line 56)
+* ess-delete-dump-files:                 Source Files.         (line 12)
+* ess-directory:                         Source Directories.   (line 48)
+* ess-dump-filename-template:            Source Directories.   (line  9)
+* ess-eldoc-abbreviation-style:          ESS ElDoc.            (line 24)
+* ess-eldoc-show-on-symbol:              ESS ElDoc.            (line 18)
+* ess-eval-visibly:                      Evaluating code.      (line 14)
+* ess-execute-in-process-buffer:         Hot keys.             (line 13)
+* ess-first-tab-never-complete:          Indenting.            (line 42)
+* ess-first-tab-never-complete <1>:      Object names.         (line  6)
+* ess-function-template:                 Edit buffer.          (line 17)
+* ess-handy-commands:                    Handy commands.       (line  6)
+* ess-handy-commands <1>:                Handy commands.       (line  9)
+* ess-indent-with-fancy-comments:        Indenting.            (line 28)
+* ess-keep-dump-files:                   Source Files.         (line 26)
+* ess-plain-first-buffername:            Multiple ESS processes.
+                                                               (line 14)
+* ess-post-run-hook:                     Customizing startup.  (line 26)
+* ess-pre-run-hook:                      Customizing startup.  (line 21)
+* ess-r-flymake-linters:                 ESS Flymake.          (line 16)
+* ess-r-flymake-lintr-cache:             ESS Flymake.          (line 23)
+* ess-R-font-lock-keywords:              Highlighting.         (line 19)
+* ess-r-outline-style:                   Outline.              (line  6)
+* ess-r-outline-style <1>:               Outline.              (line 37)
+* ess-search-list:                       Source Directories.   (line 62)
+* ess-source-directory:                  Source Directories.   (line 22)
+* ess-style:                             Styles.               (line 21)
+* ess-style-alist:                       Styles.               (line 28)
+* ess-switch-to-end-of-proc-buffer:      Other.                (line 21)
+* ess-use-eldoc:                         ESS ElDoc.            (line 13)
+* ess-use-flymake:                       ESS Flymake.          (line 12)
+* iESS program arguments:                Customizing startup.  (line 48)
+* inferior-ess-program:                  Customizing startup.  (line 48)
+* inferior-R-font-lock-keywords:         Highlighting.         (line 12)
+* Rd-indent-level:                       R documentation files.
+                                                               (line 78)
+* Rd-mode-hook:                          R documentation files.
+                                                               (line 75)
+* Rd-to-help-command:                    R documentation files.
+                                                               (line 82)
+
+\1f
+File: ess.info,  Node: Concept index,  Prev: Variable index,  Up: Indices
+
+Concept Index
+=============
+
+\0\b[index\0\b]
+* Menu:
+
+* aborting R commands:                   Other.               (line   9)
+* aborting S commands:                   Other.               (line   9)
+* arguments to R program:                Customizing startup. (line  51)
+* arguments to S program:                Customizing startup. (line  51)
+* authors:                               Credits.             (line   6)
+* autosaving:                            Source Files.        (line  83)
+* bug reports:                           Reporting Bugs.      (line   6)
+* bugs:                                  Bugs.                (line   6)
+* changing ESS processes:                Multiple ESS processes.
+                                                              (line   6)
+* cleaning up:                           Hot keys.            (line  71)
+* code folding:                          Outline.             (line   6)
+* comint:                                Credits.             (line   6)
+* command history:                       Command History.     (line   6)
+* command line arguments:                iESS(R)--Inferior ESS processes.
+                                                              (line  16)
+* command-line completion:               Object names.        (line   6)
+* command-line editing:                  Command-line editing.
+                                                              (line   6)
+* commands:                              Entering commands.   (line   6)
+* comments:                              Source Files.        (line  41)
+* comments in R:                         Indenting.           (line  18)
+* company:                               Company.             (line   6)
+* completion in edit buffer:             Other edit buffer commands.
+                                                              (line  24)
+* completion of object names:            Object names.        (line   6)
+* completion on file names:              Object names.        (line  39)
+* completion on lists:                   Object names.        (line  37)
+* completion, when prompted for object names: Edit buffer.    (line  14)
+* creating new objects:                  Edit buffer.         (line  14)
+* credits:                               Credits.             (line   6)
+* customization:                         Customization.       (line   6)
+* data frames:                           Object names.        (line  20)
+* deleting output:                       Last command.        (line  24)
+* directories:                           Starting up.         (line  11)
+* dump file directories:                 Source Directories.  (line  20)
+* dump file names:                       Source Directories.  (line   6)
+* dump files:                            Edit buffer.         (line  27)
+* dump files <1>:                        Source Files.        (line  10)
+* echoing commands when evaluating:      Evaluating code.     (line  20)
+* edit buffer:                           Edit buffer.         (line   6)
+* editing commands:                      Command History.     (line   6)
+* editing functions:                     Editing objects.     (line   6)
+* editing transcripts:                   Saving transcripts.  (line  18)
+* ElDoc:                                 ESS ElDoc.           (line   6)
+* emacsclient:                           Emacsclient.         (line   6)
+* entering commands:                     Entering commands.   (line   6)
+* errors:                                Error Checking.      (line   6)
+* ESS commands blocking Emacs:           Evaluating code.     (line  20)
+* ess developer:                         Namespaced Evaluation.
+                                                              (line   6)
+* ESS process buffer:                    Starting up.         (line  17)
+* ESS process directory:                 Starting up.         (line  11)
+* ESS tracebug:                          ESS tracebug.        (line   6)
+* ESS-elsewhere:                         ESS processes on Remote Computers.
+                                                              (line   9)
+* ess-roxy:                              roxygen2.            (line   6)
+* evaluating code with echoed commands:  Evaluating code.     (line  20)
+* evaluating R expressions:              Evaluating code.     (line  31)
+* evaluating S expressions:              Evaluating code.     (line  31)
+* finding function definitions:          Xref.                (line   6)
+* flymake:                               ESS Flymake.         (line   6)
+* font-lock mode:                        Highlighting.        (line   7)
+* formatting source code:                Indenting.           (line  32)
+* graphics:                              Graphics.            (line   6)
+* Handy commands:                        Handy commands.      (line   6)
+* help files:                            Help.                (line   6)
+* highlighting:                          Highlighting.        (line   7)
+* historic backups:                      Source Files.        (line  41)
+* hot keys:                              Hot keys.            (line  43)
+* icicles:                               Icicles.             (line   6)
+* IDO completions:                       Minibuffer completion.
+                                                              (line   6)
+* indenting:                             Indenting.           (line  32)
+* installation:                          Installation.        (line   6)
+* interactive use of R:                  Introduction.        (line  31)
+* interactive use of S:                  Introduction.        (line  31)
+* interrupting R commands:               Other.               (line   9)
+* interrupting S commands:               Other.               (line   9)
+* introduction:                          Introduction.        (line   6)
+* keyboard short cuts:                   Hot keys.            (line  43)
+* killing temporary buffers:             Hot keys.            (line  71)
+* killing the ESS process:               Hot keys.            (line  71)
+* lists, completion on:                  Object names.        (line  37)
+* motion in transcript mode:             Transcript Mode.     (line  17)
+* multi-line commands, resubmitting:     Transcript resubmit. (line  33)
+* multiple ESS processes:                Multiple ESS processes.
+                                                              (line   6)
+* multiple inferior processes:           Multiple ESS processes.
+                                                              (line   6)
+* multiple interactive processes:        Multiple ESS processes.
+                                                              (line   6)
+* new objects, creating:                 Edit buffer.         (line  14)
+* objects:                               Hot keys.            (line  24)
+* outline-minor-mode:                    Outline.             (line   6)
+* pages in the process buffer:           Transcript.          (line  24)
+* paging commands in help buffers:       Help.                (line  28)
+* paragraphs in the process buffer:      Transcript.          (line  13)
+* parsing errors:                        Error Checking.      (line   6)
+* process buffer:                        Starting up.         (line  17)
+* process names:                         Multiple ESS processes.
+                                                              (line   8)
+* programming in R:                      Introduction.        (line  43)
+* programming in S:                      Introduction.        (line  43)
+* project work in R:                     Source Files.        (line  41)
+* project work in S:                     Source Files.        (line  41)
+* quitting from ESS:                     Hot keys.            (line  71)
+* re-executing commands:                 Command History.     (line   6)
+* reading long command outputs:          Last command.        (line  19)
+* remote Computers:                      ESS processes on Remote Computers.
+                                                              (line   9)
+* reverting function definitions:        Edit buffer.         (line  27)
+* roxy:                                  roxygen2.            (line   6)
+* roxygen2:                              roxygen2.            (line   6)
+* running R:                             Starting up.         (line   6)
+* running S:                             Starting up.         (line   6)
+* S+elsewhere:                           ESS processes on Remote Computers.
+                                                              (line   9)
+* search list:                           Hot keys.            (line  34)
+* search list <1>:                       Source Directories.  (line  55)
+* sending input:                         Entering commands.   (line   6)
+* Space in function argument completion: Function arguments.  (line  10)
+* starting directory:                    Starting up.         (line  11)
+* starting ESS:                          Starting up.         (line   6)
+* STERM:                                 Statistical Process running in ESS?.
+                                                              (line   6)
+* temporary buffers:                     Help.                (line 169)
+* temporary buffers, killing:            Hot keys.            (line  71)
+* tracebug tutorial:                     Getting started with tracebug.
+                                                              (line   6)
+* tramp support:                         ESS processes on Remote Computers.
+                                                              (line   9)
+* transcript:                            Transcript.          (line   9)
+* transcript file:                       Customizing startup. (line  40)
+* transcript file names:                 Saving transcripts.  (line  13)
+* transcript mode motion:                Transcript Mode.     (line  17)
+* transcripts of R sessions:             Introduction.        (line  38)
+* transcripts of S sessions:             Introduction.        (line  38)
+* using ESS interactively:               Introduction.        (line  31)
+* using R interactively:                 Introduction.        (line  31)
+* using S interactively:                 Introduction.        (line  31)
+* winjava:                               winjava.             (line   6)
+* working directory:                     Starting up.         (line  11)
+* working directory <1>:                 Source Directories.  (line  55)
+* X Windows:                             X11.                 (line   6)
+* xref:                                  Xref.                (line   6)
+
+
+\1f
+Tag Table:
+Node: Top\7f270
+Node: Introduction\7f2893
+Node: Features\7f5649
+Node: Current Features\7f6475
+Node: New features\7f9926
+Node: Credits\7f37026
+Node: Manual\7f40643
+Node: Installation\7f43309
+Node: Installing from a third-party repository\7f44246
+Node: Installing from source\7f45193
+Node: Activating and Loading ESS\7f46785
+Node: Check Installation\7f47859
+Node: Interactive ESS\7f48079
+Node: Starting up\7f48924
+Node: Multiple ESS processes\7f49668
+Node: ESS processes on Remote Computers\7f50749
+Node: Customizing startup\7f54852
+Node: Controlling buffer display\7f57742
+Node: Entering commands\7f60363
+Node: Command-line editing\7f61521
+Node: Transcript\7f62754
+Node: Last command\7f64523
+Node: Process buffer motion\7f65949
+Node: Transcript resubmit\7f67452
+Node: Saving transcripts\7f69417
+Node: Command History\7f71207
+Node: Saving History\7f74616
+Node: History expansion\7f75377
+Node: Hot keys\7f78588
+Node: Statistical Process running in ESS?\7f82658
+Node: Emacsclient\7f83937
+Node: Other\7f84729
+Node: Evaluating code\7f85748
+Node: Transcript Mode\7f89544
+Node: Resubmit\7f90697
+Node: Clean\7f91760
+Node: Editing objects\7f92756
+Node: Edit buffer\7f93874
+Node: Loading\7f95920
+Node: Error Checking\7f96947
+Node: Indenting\7f97996
+Node: Styles\7f101040
+Node: Other edit buffer commands\7f103414
+Node: Source Files\7f105070
+Node: Source Directories\7f109674
+Node: Help\7f112827
+Node: Completion\7f117273
+Node: Object names\7f117488
+Node: Function arguments\7f120122
+Node: Minibuffer completion\7f121065
+Node: Company\7f121539
+Node: Icicles\7f121926
+Node: Developing with ESS\7f123246
+Node: ESS tracebug\7f123692
+Node: Getting started with tracebug\7f126699
+Node: Editing documentation\7f128857
+Node: R documentation files\7f129409
+Node: roxygen2\7f133112
+Node: Namespaced Evaluation\7f137523
+Node: Extras\7f139521
+Node: ESS ElDoc\7f140613
+Node: ESS Flymake\7f142109
+Node: Handy commands\7f143203
+Node: Highlighting\7f144400
+Node: Parens\7f145435
+Node: Graphics\7f145911
+Node: printer\7f146582
+Node: X11\7f147338
+Node: winjava\7f147677
+Node: Imenu\7f148089
+Node: Outline\7f148936
+Node: Toolbar\7f151061
+Node: Xref\7f151471
+Node: Rdired\7f151801
+Node: Package listing\7f152864
+Node: Org\7f154248
+Node: Sweave and AUCTeX\7f155202
+Node: ESS for R\7f155787
+Node: ESS(R)--Editing files\7f156087
+Node: iESS(R)--Inferior ESS processes\7f156588
+Node: Philosophies for using ESS(R)\7f159243
+Node: Example ESS usage\7f160170
+Node: ESS for SAS\7f161575
+Node: ESS(SAS)--Design philosophy\7f162298
+Node: ESS(SAS)--Editing files\7f163231
+Node: ESS(SAS)--TAB key\7f165085
+Node: ESS(SAS)--Batch SAS processes\7f166451
+Node: ESS(SAS)--Function keys for batch processing\7f171479
+Node: iESS(SAS)--Interactive SAS processes\7f180966
+Node: iESS(SAS)--Common problems\7f184720
+Node: ESS(SAS)--Graphics\7f186244
+Node: ESS(SAS)--Windows\7f187027
+Node: ESS for BUGS\7f187605
+Node: Mailing lists/bug reports\7f188157
+Node: Bugs\7f188421
+Node: Reporting Bugs\7f190045
+Node: Mailing Lists\7f190960
+Node: Help with Emacs\7f191687
+Node: Customization\7f192219
+Node: Indices\7f192993
+Node: Key index\7f193168
+Node: Function and program index\7f198081
+Node: Variable index\7f207355
+Node: Concept index\7f210989
+\1f
+End Tag Table
+
+\1f
+Local Variables:
+coding: utf-8
+End:
diff --git a/elpa/ess-20260424.1544/essd-els.el b/elpa/ess-20260424.1544/essd-els.el
new file mode 100644 (file)
index 0000000..67040a2
--- /dev/null
@@ -0,0 +1,183 @@
+;;; essd-els.el --- S-PLUS 3.x at another location customization  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1998-2022 Free Software Foundation, Inc.
+
+;; Author: Richard M. Heiberger <rmhNOSPAMtemple.edu>
+;; Created: December 1998
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; This file defines all the S-PLUS 3.x customizations for ess-mode.
+
+;;; Code:
+
+(require 'ess-r-mode)
+(require 'ess-sp6-d)
+(require 'ess-sas-d)
+(require 'ess-trns)
+(require 'ess-utils)
+(defvar ess-julia-customize-alist)
+
+;; Easily changeable in a user's .emacs
+(defvar S+elsewhere-dialect-name "S+6"
+  "Name of `dialect' for S-PLUS at another location.")
+
+(defvar S+elsewhere-start-args "-i"
+  "Arguments for `S+elsewhere-dialect-name'.")
+
+(defcustom inferior-ess-remote-pager nil
+  "Remote pager to use for reporting help files and similar things.
+The default value is nil."
+  :group 'ess-proc
+  :type '(choice (const nil) string))
+
+
+(defvar S+elsewhere-customize-alist
+  (append
+   '((ess-local-customize-alist         . S+elsewhere-customize-alist)
+     (ess-dialect                       . S+elsewhere-dialect-name)
+     (ess-object-name-db-file           . "ess-spelsewhere-namedb.el" )
+     (inferior-ess-program              . inferior-S-elsewhere-program)
+     (inferior-ess-help-command         . "help(\"%s\", pager=\"cat\", window=F)\n")
+     (ess-STERM  . "iESS")
+     )
+   S+common-cust-alist)
+  "Variables to customize for S+elsewhere.")
+
+(defun S+elsewhere (&optional _proc-name)
+  "Call \\='S-PLUS 3.x\\=', the \\='Real Thing\\='  from StatSci."
+  ;; git commit 104c4d7c56bc239ea245562763caa317bc3a1a84
+  (declare (obsolete ess-remote "2000"))
+  (ess-write-to-dribble-buffer
+   (format "\n(S+elsewhere): ess-dialect=%s, buf=%s\n" ess-dialect
+           (current-buffer)))
+  (let ((inf-buf (inferior-ess nil S+elsewhere-customize-alist)))
+    (when inferior-ess-language-start
+      (ess-eval-linewise inferior-ess-language-start))
+    inf-buf))
+
+(defun S+elsewhere-mode (&optional _proc-name)
+  "Major mode for editing S+3 source.  See `ess-mode' for more help."
+  (declare (obsolete ess-remote "2000"))
+  (setq-local ess-local-customize-alist S+elsewhere-customize-alist)
+  (ess-mode))
+
+;; This REALLY shouldn't need an editing mode.  Just a transcript and
+;; an inferior process handler.
+
+(defun ess-select-alist-dialect (&optional dialect)
+  "Query user for an ESS DIALECT and return the matching customize-alist."
+  (interactive)
+  (let* ((dialects '("R" "S+" "julia" "s3" "s4"
+                     "sp3" "sp4" "sqpe4" "sp5" "sqpe" "SAS"))
+         (dialect (or dialect
+                      (ess-completing-read "Dialect" dialects nil t))))
+    (cond
+     ((string= dialect "julia") (progn (require 'julia-mode)
+                                       ess-julia-customize-alist))
+     ((string= dialect "R")     ess-r-customize-alist)
+     ((string= dialect "SAS")   SAS-customize-alist)
+     (t                         S+elsewhere-customize-alist))))
+
+(defun ess-add-ess-process ()
+  "Execute this command from within a buffer running a process to add
+the process to `ess-process-name-alist' and to make it the
+`ess-current-process-name'.  This command will normally be run in a
+telnet buffer connected to another computer or in a shell or comint
+buffer on the local computer."
+  (interactive)
+  (let ((proc (get-buffer-process (buffer-name))))
+    (if (not proc)
+        (error "No process is associated with this buffer")
+      (set-process-filter proc #'inferior-ess-output-filter)
+      (setq ess-current-process-name (process-name proc))
+      (add-to-list 'ess-process-name-list
+                   (list ess-current-process-name)))))
+
+(defvar ess-remote nil
+  "Indicator, t in remote buffers.")
+
+;;;###autoload
+(defun ess-remote (&optional proc-name dialect)
+  "Execute this command from within a buffer running a process.
+It runs `ess-add-ess-process' to add the PROC-NAME to
+`ess-process-name-alist' and to make it the
+`ess-current-process-name'. It then prompts the user for an ESS
+language and sets the editing characteristics appropriately.
+
+To use this command, first start a process on a remote computer by
+manual use of telnet, rlogin, ssh, or some other protocol.  Start the
+relevant program (\"S\" or \"R\" or \"sas -stdio\") in that buffer.  Once
+you are talking to S or R or SAS, then do \\[ess-remote] to make
+the current buffer an inferior-ess buffer with the right behavior for
+the language you are currently working with.  With S and R, use C-c
+C-n to send lines over.  With SAS, use C-c i
+`ess-eval-line-and-step-invisibly' to send lines over invisibly.
+
+DIALECT is the desired ess-dialect. If nil, ask for dialect"
+
+  (interactive)
+  (ess-add-ess-process)
+  ;; Need to select a remote-customize-alist
+  (let ((customize-alist (ess-select-alist-dialect dialect)))
+    (ess-write-to-dribble-buffer
+     (format "\n(ESS-remote): ess-dialect=%s, buf=%s\n" ess-dialect
+             (current-buffer)))
+    (ess-setq-vars-local customize-alist)
+    (inferior-ess--set-major-mode ess-dialect)
+    (setq-local ess-remote t)
+    (setq ess-local-process-name (or proc-name ess-current-process-name))
+
+    (goto-char (point-max))
+
+    (when (equal ess-dialect "R")
+      ;; ugly fix for evn variable. What can we do :(
+      (ess-eval-linewise (format "options(pager='%s')\n"
+                                 (or inferior-ess-remote-pager inferior-ess-pager))
+                         nil nil nil 'wait)
+      (ess-r-load-ESSR))
+
+    (when (equal ess-dialect "S+")
+      (ess-command ess-S+--injected-code))
+
+    (when (equal ess-language "SAS")
+      (font-lock-mode 0)
+      (SAS-log-mode)
+      (shell-mode)
+      (setq buffer-read-only nil)
+      (font-lock-mode 1))
+
+    (ess-process-put 'funargs-cache (make-hash-table :test 'equal))
+    (ess-process-put 'funargs-pre-cache nil)
+    ;; auto-complete
+    (ess--setup-auto-complete ess-r-ac-sources t)
+    ;; company
+    (ess--setup-company ess-r-company-backends t)
+
+    (when inferior-ess-language-start
+      (ess-eval-linewise inferior-ess-language-start
+                         nil nil nil 'wait-prompt))))
+
+
+\f ; Provide package
+
+(provide 'essd-els)
+
+;;; essd-els.el ends here
diff --git a/elpa/ess-20260424.1544/etc/ESSR.rds b/elpa/ess-20260424.1544/etc/ESSR.rds
new file mode 100644 (file)
index 0000000..5203244
Binary files /dev/null and b/elpa/ess-20260424.1544/etc/ESSR.rds differ
diff --git a/elpa/ess-20260424.1544/etc/ESSR/BUILDESSR b/elpa/ess-20260424.1544/etc/ESSR/BUILDESSR
new file mode 100755 (executable)
index 0000000..248d660
--- /dev/null
@@ -0,0 +1,10 @@
+#!/usr/bin/env Rscript
+## -*- mode: R -*-
+## code to build ESSR environment.
+## Assume that current directory is etc/ESSR
+## run "./BUILDESSR" to create ../ESSR.rda
+
+## exactly as in inferior-ess-r-load-ESSR in ess-r-d.el
+source('./R/.load.R', local=TRUE)
+ESSR <- .ess.ESSR.load('./R/')
+saveRDS(ESSR, file = "../ESSR.rds")
diff --git a/elpa/ess-20260424.1544/etc/ESSR/LOADREMOTE b/elpa/ess-20260424.1544/etc/ESSR/LOADREMOTE
new file mode 100644 (file)
index 0000000..919ec33
--- /dev/null
@@ -0,0 +1,24 @@
+## -*- mode: R -*-
+## loading code which is first sent to R on remote sessions
+local({
+    ver <- '%s' ## <- passed from elisp
+    root <- '~/.config/ESSR'
+    if(!file.exists(root))
+        dir.create(root, recursive = TRUE)
+    ## cannot use sprintf here
+    essr_file <- file.path(root, paste('ESSRv', ver, '.rds', sep = ''))
+    tryCatch({
+        if(!file.exists(essr_file)) {
+            url <- paste('https://github.com/emacs-ess/ESS/raw/ESSRv', ver, '/etc/ESSR.rds', sep = '')
+            utils::download.file(url, essr_file)
+        }
+        ESSR <- readRDS(essr_file)
+        ESSR[[".ess.Rversion"]] <- ESSR[[".ess.getRversion"]]()
+        attach(ESSR)
+        print(TRUE)
+    },
+    error = function(e) {
+      print(e)
+      print(FALSE)
+    })
+})
diff --git a/elpa/ess-20260424.1544/etc/ESSR/R/.basic.R b/elpa/ess-20260424.1544/etc/ESSR/R/.basic.R
new file mode 100644 (file)
index 0000000..c7cba3b
--- /dev/null
@@ -0,0 +1,265 @@
+#### Essential functionality needed by ESS
+
+## Should work on *all* versions of R.
+## Do not use _ in names, nor :: , nor 1L etc, as they
+## cannot be parsed in old R versions
+
+.ess.getRversion <- function() {
+    if(exists("getRversion", mode="function")) getRversion()
+    else paste(R.version$major, R.version$minor, sep=".")
+}
+
+## loading ESSR.rda might fail, so re-assign here:
+.ess.Rversion <- .ess.getRversion()
+
+.ess.R.has.utils <- (.ess.Rversion >= "1.9.0")
+.ess.utils.name <- paste("package",
+                         if(.ess.Rversion >= "1.9.0") "utils" else "base",
+                         sep = ":")
+
+## Instead of modern  utils::help use one that works in R 1.0.0:
+.ess.findFUN   <- get("find", .ess.utils.name)
+
+
+### HELP
+.ess.help <- function(..., help.type = getOption("help_type")) {
+    if (is.null(help.type)) {
+        help.type <- "text"
+    }
+
+    ## - get("help", ..) searching in global env works with devtools redefines
+    ## - Redefining to .ess.help this way is necessary because
+    ##   utils:::print.help_files_with_topic (used internally when there's
+    ##   more than one a package) uses the quoted call
+    ##   MM: don't understand; more specifically?
+    ..help <- function(...) {
+        do.call(get("help", envir = .GlobalEnv), list(...))
+    }
+
+    if (.ess.Rversion > "2.10") {
+        ## Abbreviating help_type to avoid underscore
+        if(!is.null(getOption("warnPartialMatchArgs"))) {
+            op <- options(warnPartialMatchArgs = FALSE); on.exit(options(op))
+        }
+        ..help(..., help = help.type)
+    } else {
+        ..help(..., htmlhelp = help.type == "html")
+    }
+}
+
+.ess.getHelpAliases <- local({
+    readrds <- if (.ess.Rversion >= '2.13.0') readRDS else .readRDS
+    aliasesCache <- new.env()
+
+    getAliases <- function(file) {
+        cached <- aliasesCache[[file]]
+        if (!is.null(cached))
+            return(cached)
+
+        aliases <- tryCatch(
+            error = function(...) NULL,
+            if (file.exists(file))
+                names(readrds(file))
+            else
+                NULL
+        )
+
+        aliasesCache[[file]] <- aliases
+        aliases
+    }
+
+    function(reset = FALSE) {
+        if (reset)
+            aliasesCache <<- new.env()
+
+        rdsFiles <- paste(searchpaths(), "/help/aliases.rds", sep = "")
+        unlist(lapply(rdsFiles, getAliases), use.names = FALSE)
+    }
+})
+
+.ess.helpLinks <- function(topic, package) {
+    tryCatch(
+        warning = function(...) NULL,
+        error = function(...) NULL, # needs R >= 2.13.0
+        {
+            ast <- .ess.fetchParsedRd(topic, package)
+            .ess.findLinks(ast)
+        }
+    )
+}
+
+.ess.fetchParsedRd <- function(topic, package) {
+    path <- utils:::index.search(topic, find.package(package))
+    utils:::.getHelpFile(path)
+}
+
+.ess.findLinks <- function(x) {
+    links <- NULL
+    findLinksRec <- function(x) {
+        if (.ess.isRdLink(x)) {
+            ## Ignore `pkg` for now
+            links <<- c(links, .ess.getRdLink(x)[[2]])
+        } else if (is.list(x)) {
+            for (elt in x)
+                findLinksRec(elt)
+        }
+    }
+
+    findLinksRec(x)
+    links
+}
+
+.ess.isRdLink <- function(x) {
+    identical(attr(x, "Rd_tag"), "\\link")
+}
+
+## From `tools:::get_link()`
+.ess.getRdLink <- function(x) {
+    pkg <- ""
+    dest <- paste(unlist(x), collapse = "")
+
+    opt <- attr(x, "Rd_option")
+    if (!is.null(opt)) {
+        if (grepl("^=", opt, perl = TRUE, useBytes = TRUE)) {
+            dest <- sub("^=", "", opt)
+        } else if (grepl(":", opt, perl = TRUE, useBytes = TRUE)) {
+           dest <- sub("^[^:]*:", "", opt)
+            pkg <- sub(":.*", "", opt)
+        } else {
+            pkg <- as.character(opt)
+        }
+    }
+
+    c(pkg, dest)
+}
+
+### SOURCING
+.ess.eval <- function(string, visibly = TRUE, output = FALSE,
+                      max.deparse.length = 300,
+                      file = tempfile("ESS"), local = NULL)
+{
+    if (is.null(local)) {
+        local <- if (.ess.Rversion > '2.13') parent.frame() else FALSE
+    }
+
+    ## create FILE, put string into it. Then source.
+    ## arguments are like in source and .ess.source
+    cat(string, file = file)
+    ## The following on.exit infloops in R 3.3.0
+    ## https://github.com/emacs-ess/ESS/issues/334
+    ## https://bugs.r-project.org/bugzilla/show_bug.cgi?id=16971
+    ## So we are cleaning it in .ess.source instead.
+    ## on.exit(file.remove(file))
+    .ess.source(file, visibly = visibly, output = output,
+                max.deparse.length = max.deparse.length,
+                local = local, fake.source = TRUE)
+}
+
+.ess.strip.error <- function(msg, srcfile) {
+    pattern <- paste(srcfile, ":[0-9]+:[0-9]+: ", sep = "")
+    sub(pattern, "", msg)
+}
+
+.ess.file.remove <- function(file){
+    if (base::file.exists(file)) base::file.remove(file)
+    else FALSE
+}
+
+.ess.source <- function(file, visibly = TRUE, output = FALSE,
+                        max.deparse.length = 300, local = NULL,
+                        fake.source = FALSE, keep.source = TRUE,
+                        message.prefix = "") {
+    if (is.null(local)) {
+        local <- if (.ess.Rversion > "2.13")
+            parent.frame()
+        else FALSE
+    }
+
+    ss <-
+        if (.ess.Rversion >= "3.4")
+            base::source
+        else if (.ess.Rversion >= "2.8")
+            function(..., spaced) base::source(...)
+        else function(..., spaced, keep.source) base::source(...)
+
+    on.exit({
+        if (fake.source)
+            .ess.file.remove(file)
+    })
+
+    out <- ss(file, echo = visibly, local = local, print.eval = output, spaced = FALSE,
+              max.deparse.length = max.deparse.length, keep.source = keep.source)
+
+    if(!fake.source)
+        cat(sprintf("%sSourced file %s\n", message.prefix, file))
+
+    ## Return value for org-babel
+    invisible(out$value)
+}
+
+if(.ess.Rversion < "1.8")
+    ## (works for "1.7.2"): bquote() was new in 1.8.0
+    bquote <- function(expr, where=parent.frame()){
+        unquote <- function(e)
+            if (is.pairlist(e)) as.pairlist(lapply(e, unquote))
+            else if (length(e) <= 1) e
+            else if (e[[1]] == as.name(".")) eval(e[[2]], where)
+            else as.call(lapply(e, unquote))
+
+        unquote(substitute(expr))
+    }
+
+.ess.command <- function(expr, sentinel) {
+    ## It is possible that the REPL is marked as non-busy when the
+    ## output is sinked because prompts are not sinked. In that case,
+    ## redirect the sinked output temporarily to ESS.
+    sinked <- !identical(stdout(), getConnection(1))
+    if (sinked)
+        sink(getConnection(1))
+
+    on.exit({
+        writeLines(paste(sentinel, "-END", sep = ""))
+        if (sinked)
+            sink(NULL)
+    })
+
+    writeLines(paste(sentinel, "-START", sep = ""))
+
+    .ess.environment.state$env <- parent.frame()
+    on.exit(.ess.environment.state$env <- NULL, add = TRUE)
+
+
+    ## Don't interrupt `browser()` sessions (#1081)
+    restart <- function(...) {
+        if (!is.null(findRestart("browser")))
+            invokeRestart("browser")
+    }
+
+    ## Should be an exiting handler to be able to catch
+    ## stack overflow errors
+    rethrow <- function(cnd) {
+        stop('\1e\1eESSR::ERROR \"', conditionMessage(cnd), '\"\1e\1e')
+    }
+
+    out <- tryCatch(
+        error = rethrow,
+        withCallingHandlers(
+            interrupt = restart,
+            withVisible(expr)
+        )
+    )
+
+    ## Print result manually because we can't rely on auto-print
+    ## without changing the last value
+    if (out$visible)
+        print(out$value)
+
+    ## Keep `.Last.value` stable
+    invisible(.Last.value)
+}
+
+.ess.environment.state <- new.env(parent = emptyenv())
+
+.ess.environment <- function() {
+    .ess.environment.state$env
+}
diff --git a/elpa/ess-20260424.1544/etc/ESSR/R/.load.R b/elpa/ess-20260424.1544/etc/ESSR/R/.load.R
new file mode 100644 (file)
index 0000000..e6c0014
--- /dev/null
@@ -0,0 +1,96 @@
+## This file is sourced when R starts and `load.ESSR` is called. See
+## inferior-ess-r-load-ESSR--local.
+## Do not use _ in names, nor :: as they cannot be parsed in old R versions
+
+## obtain the R version number as a string
+.ess.ESSR.get.rver <- function() {
+    if(exists("getRversion", mode="function")) getRversion()
+    else paste(R.version$major, R.version$minor, sep=".")
+}
+
+## load .base.R and all other files into ESSR environment; then attach ESSR
+.ess.ESSR.load <- function(dir) {
+
+    if (Sys.getenv("ESSR_TEST_LOAD_ERROR") != "")
+        stop('Loading failed with a nice message.')
+
+    Rver <- .ess.ESSR.get.rver()
+    ESSR <- .ess.ESSR.create.env(Rver)
+    .ess.ESSR.source.files(ESSR, dir, Rver)
+    .ess.ESSR.attach.env(ESSR, Rver)
+
+    ## BUILDESSR needs this:
+    invisible(ESSR)
+}
+
+.ess.ESSR.create.env <- function(Rver) {
+
+    ESSR <-
+        if (Rver <= "1.3.0") ## really old library() revert order a bit
+            attach(NULL, name = "ESSR")
+        else if(length(nn <- names(formals(new.env))) && any(nn == "parent"))
+            new.env(parent =
+                        if (Rver >= "1.9.0") getNamespace("utils")
+                        else .BaseNamespaceEnv)
+        else
+            new.env()
+
+    assign(".ess.Rversion", Rver, envir = ESSR)
+
+    ## updated by make !!
+    VERSION <- "1.8"
+    assign(".ess.ESSRversion", VERSION, envir = ESSR)
+
+    ESSR
+}
+
+## attempt to source the files in the ESSR directory and place the resulting R
+## objects into ESSR environment; the updated version of the environment is
+## returned
+.ess.ESSR.source.files <- function(ESSR, dir, Rver) {
+
+    .source <-
+        if(any("keep.source" == names(formals(sys.source))))
+            sys.source
+        else
+            function(..., keep.source) sys.source(...)
+
+    ## .basic.R:
+    try(.source(paste(dir,'/.basic.R', sep = ""), envir = ESSR, keep.source = FALSE))
+
+    ## all others try(*) as it will fail in old R
+    if (Rver > "1.3.0") { # no sense if very old R
+        for (f in dir(dir, pattern='\\.R$', full.names=TRUE))
+            try(.source(f, envir = ESSR, keep.source = FALSE))
+    }
+
+    ESSR
+}
+
+
+## attach the ESSR environment to the search path
+.ess.ESSR.attach.env <- function(ESSR, Rver) {
+    if (Rver >= "2.4.0")
+        attach(ESSR)
+    else if (Rver > "1.3.0") { # borrow from older library()
+        e <- attach(NULL, name = "ESSR")
+        .Internal(lib.fixup(ESSR, e))
+    } else { # if old R, use as in that old library():
+        .Internal(lib.fixup(ESSR, .GlobalEnv))
+    }
+}
+
+
+## copy any ESSR R objects in the global environment into a newly created ESSR
+## environment; then remove the original objects and attach ESSR
+.ess.collect.ESSR.objects <- function() {
+
+    Rver <- .ess.ESSR.get.rver()
+    ESSR <- .ess.ESSR.create.env(Rver)
+    essr.nms <- grep('\\.(ess|ESS)', ls(.GlobalEnv, all.names = TRUE), value = TRUE)
+    for (nm in essr.nms) {
+        assign(nm, get(nm, pos = .GlobalEnv), envir = ESSR)
+    }
+    .ess.ESSR.attach.env(ESSR, Rver)
+    rm(list = essr.nms, pos = .GlobalEnv)
+}
diff --git a/elpa/ess-20260424.1544/etc/ESSR/R/completion.R b/elpa/ess-20260424.1544/etc/ESSR/R/completion.R
new file mode 100644 (file)
index 0000000..e50f9a3
--- /dev/null
@@ -0,0 +1,172 @@
+## Do *NOT* use  1L -- it gives  parse errors in historical versions of R
+
+## Try a setup working in as old R as possible.
+## ===>
+##    1)  do not use "_" in names!   --- seems impossible for the Millenials ..
+##    2)  use our own simplified definition of  '::' and ':::' ?
+##
+if(!exists("local"))
+    local <- function(expr, envir = environment()) { invisible(eval(expr, envir=envir)) }
+
+##' Robust version of
+##'    utils:::.addFunctionInfo(c = c("recursive", "use.names")) #  needed only for R <= 3.y.z
+local({
+    U <- asNamespace("utils"); fn <- ".addFunctionInfo"
+    EX <- exists(fn, envir=U)
+    if(EX && is.function(FN <- get(fn, envir=U))) {
+        FN(c = c("recursive", "use.names")); ##dbg: cat("Calling utils:::",fn,"(c = ...)\n")
+    }
+})
+
+\f
+.ess_eval <- function(str, env = globalenv()) {
+    ## don't remove; really need eval(parse(  here!!
+    tryCatch(eval(parse(text=str), envir = env),
+             error=function(e) NULL) ## also works for special objects containing @:$ etc
+}
+
+.ess_nonull <- function(x, default = "") {
+    if (is.null(x)) default
+    else x
+}
+
+## not needed for completion;   called from  (ess-r-xref--srcref *) in  ../../../lisp/ess-r-xref.el
+.ess_srcref <- function(name, pkg) {
+    if (!is.null(pkg) && requireNamespace(pkg)) {
+        env <- asNamespace(pkg)
+    } else {
+        env <- globalenv()
+    }
+    fn <- .ess_eval(name, env)
+    if (is.null(fn)) {
+        objs <- utils::getAnywhere(name)$objs
+        for (fn in objs) {
+            if(is.function(fn))
+                break
+        }
+    }
+    out <- "()\n"
+    if (is.function(fn) && !is.null(utils::getSrcref(fn))) {
+        file <- utils::getSrcFilename(fn, full.names = TRUE)
+        if (file != "") {
+            line <- .ess_nonull(utils::getSrcLocation(fn, "line"  ), 1)
+            col  <- .ess_nonull(utils::getSrcLocation(fn, "column"), 1)
+            out <- sprintf("(\"%s\" %d %d)\n", file, line, col - 1)
+        }
+    }
+    cat(out)
+}
+
+\f
+.ess_fn_pkg <- function(fn_name) {
+    objs <- utils::getAnywhere(fn_name)
+    print(sub("(package|namespace):", "", objs$where))
+}
+
+.ess_funargs <- function(funname) {
+    if(.ess.Rversion > '2.14.1') {
+        ## temporarily disable JIT compilation and errors
+        comp <- compiler::enableJIT(0)
+        op <- options(error=NULL)
+        on.exit({ options(op); compiler::enableJIT(comp) })
+    }
+    fun <- .ess_eval(funname)
+    if(is.function(fun)) {
+        special <- grepl('[:$@[]', funname)
+        args <- if(!special){
+                    fundef <- paste(funname, '.default',sep='')
+                    do.call('argsAnywhere', list(fundef))
+                }
+
+        if(is.null(args))
+            args <- args(fun)
+        if(is.null(args))
+            args <- do.call('argsAnywhere', list(funname))
+
+        fmls <- formals(args)
+        fmls_names <- names(fmls)
+        fmls <- gsub('\"', '\\\"',
+                     gsub("\\", "\\\\", as.character(fmls), fixed = TRUE),
+                     fixed=TRUE)
+        args_alist <-
+            sprintf("'(%s)",
+                    paste("(\"", fmls_names, "\" . \"", fmls, "\")",
+                          sep = '', collapse = ' '))
+        allargs <-
+            if (special) fmls_names
+            else tryCatch(gsub(' ?= ?', '', utils:::functionArgs(funname, ''), fixed = FALSE),
+                          error=function(e) NULL)
+        allargs <- sprintf("'(\"%s\")",
+                           paste(allargs, collapse = '\" "'))
+        envname <-
+            if (is.primitive(fun)) "base"
+            else environmentName(environment(fun))
+        if (envname == "R_GlobalEnv") envname <- ""
+        cat(sprintf('(list \"%s\" %s %s)\n',
+                    envname, args_alist, allargs))
+    }
+}
+
+\f
+## builds on R`s functionality in  src/library/utils/R/completion.R :
+.ess_get_completions <- function(string, end, suffix = " = ") {
+    oldopts <- utils::rc.options(funarg.suffix = suffix)
+    on.exit(utils::rc.options(oldopts))
+    sett <- utils::rc.settings
+    oldDots <- sett()[["dots"]]
+    on.exit(sett(dots=oldDots), add=TRUE)
+    sett(dots = FALSE)
+    if(.ess.Rversion > '2.14.1') {
+        comp <- compiler::enableJIT(0)
+        op <- options(error=NULL)
+        on.exit({ options(op); compiler::enableJIT(comp)}, add = TRUE)
+    }
+    utils:::.assignLinebuffer(string)
+    utils:::.assignEnd(end)
+    utils:::.guessTokenFromLine()
+    utils:::.completeToken()
+    c(get('token', envir=utils:::.CompletionEnv),
+      utils:::.retrieveCompletions())
+}
+
+.ess_arg_help <- function(arg, func) {
+    op <- options(error=NULL)
+    on.exit(options(op))
+    fguess <-
+        if(is.null(func)) get('fguess', envir=utils:::.CompletionEnv)
+        else func
+    findArgHelp <- function(fun, arg){
+        file <- help(fun, try.all.packages=FALSE)[[1]]
+        hlp <- utils:::.getHelpFile(file)
+        id <- grep('arguments', tools:::RdTags(hlp), fixed=TRUE)
+        if(length(id)){
+            arg_section <- hlp[[id[[1]]]]
+            items <- grep('item', tools:::RdTags(arg_section), fixed=TRUE)
+            ## cat('items:', items, fill=TRUE)
+            if(length(items)){
+                arg_section <- arg_section[items]
+                args <- unlist(lapply(arg_section,
+                                      function(el) paste(unlist(el[[1]][[1]], TRUE, FALSE), collapse='')))
+                fits <- grep(arg, args, fixed=TRUE)
+                ## cat('args', args, 'fits', fill=TRUE)
+                if(length(fits))
+                    paste(unlist(arg_section[[fits[1]]][[2]], TRUE, FALSE), collapse='')
+            }
+        }
+    }
+    funcs <- c(fguess, tryCatch(methods(fguess),
+                                warning= function(w) NULL,
+                                error  = function(e) NULL))
+    if(length(funcs) > 1 && length(pos <- grep('default', funcs))) {
+        funcs <- c(funcs[[pos[[1]]]], funcs[-pos[[1]]])
+    }
+    i <- 1; found <- FALSE
+    out <- 'No help found'
+    while(i <= length(funcs) && is.null(out <-
+                                            tryCatch(findArgHelp(funcs[[i]], arg),
+                                                     warning=function(w) {NULL},
+                                                     error=function(e) {NULL})
+                                        ))
+        i <- i + 1
+    cat('\n\n', as.character(out), '\n')
+}
diff --git a/elpa/ess-20260424.1544/etc/ESSR/R/debug.R b/elpa/ess-20260424.1544/etc/ESSR/R/debug.R
new file mode 100644 (file)
index 0000000..cb2580b
--- /dev/null
@@ -0,0 +1,230 @@
+### BREAKPOINTS
+.ESSBP. <- new.env()
+
+### DEBUG/UNDEBUG
+.ess_find_funcs <- function(env) {
+    objs <- ls(envir = env, all.names = TRUE)
+    if (length(objs) > 0)
+        objs <- objs[sapply(objs, exists, envir = env,
+                            mode = 'function', inherits = FALSE)]
+    objs
+}
+
+.ess_all_functions <- function(packages = c(), env = NULL) {
+    if(is.null(env))
+        env <- parent.frame()
+    empty <- emptyenv()
+    coll <- list()
+    for(p in packages){
+        ## package might not be attached
+        try(
+        {
+            objNS <- .ess_find_funcs(asNamespace(p))
+            objPKG <- .ess_find_funcs(as.environment(paste0('package:', p)))
+            objNS <- setdiff(objNS, objPKG)
+            if(length(objPKG))
+                coll[[length(coll) + 1]] <- paste0(p, ':::', objNS)
+        }, silent = TRUE)
+    }
+    while(!identical(empty, env)){
+        coll[[length(coll) + 1]] <- .ess_find_funcs(env)
+        env <- parent.env(env)
+    }
+    grep('^\\.ess', unlist(coll, use.names = FALSE),
+         invert = TRUE, value = TRUE)
+}
+
+\f
+.ess_dbg_flag_for_debuging <- function(fname){
+    all <- utils::getAnywhere(fname)
+    if(length(all$obj) == 0){
+        msg <- sprintf("No functions names '%s' found", fname)
+    } else {
+        msg <- sprintf("Flagged '%s' for debugging", fname)
+        tryCatch(lapply(all$obj, debug),
+                 error = function(e){
+                     msg <- paste0("Error: ", e$message)
+                 })
+    }
+    cat(msg)
+    .ess_mpi_message(msg)
+}
+
+.ess_dbg_getTracedAndDebugged <- function()
+{
+    packages <- base::.packages()
+    tr_state <- tracingState(FALSE)
+    on.exit(tracingState(tr_state))
+    generics <- methods::getGenerics()
+    all_traced <- c()
+    for(i in seq_along(generics)){
+        genf <- methods::getGeneric(generics[[i]],
+                                    package=generics@package[[i]])
+        if(!is.null(genf)){ ## might happen !! v.2.13
+            menv <- methods::getMethodsForDispatch(genf)
+            traced <- unlist(eapply(menv, is, 'traceable', all.names=TRUE))
+            if(length(traced) && any(traced))
+                all_traced <- c(paste(generics[[i]],':',
+                                      names(traced)[traced],sep=''), all_traced)
+            tfn <- getFunction(generics[[i]], mustFind=FALSE, where = .GlobalEnv)
+            if(!is.null(tfn ) && is(tfn,  'traceable')) # if the default is traced,  it does not appear in the menv :()
+                all_traced <- c(generics[[i]], all_traced)
+        }
+    }
+    debugged_pkg <- unlist(lapply(packages, function(pkgname){
+        ns <- asNamespace(pkgname)
+        funcs <- .ess_find_funcs(ns)
+        dbged <- funcs[unlist(lapply(funcs,
+                                     function(f){
+                                         isdebugged(get(f, envir = ns, inherits = FALSE))
+                                     }))]
+        if(length(dbged))
+            paste0(pkgname, ':::`', dbged, '`')
+    }))
+    env <- parent.frame()
+    ## traced function don't appear here. Not really needed and would affect performance.
+    all <- .ess_all_functions(packages = packages, env = env)
+    which_deb <- lapply(all, function(nm){
+        ## if isdebugged is called with string it doess find
+        tryCatch(isdebugged(get(nm, envir = env)),
+                 error = function(e) FALSE)
+        ## try(eval(substitute(isdebugged(nm), list(nm = as.name(nm)))), silent = T)
+    })
+    debugged <- all[which(unlist(which_deb, recursive=FALSE, use.names=FALSE))]
+    unique(c(debugged_pkg, debugged, all_traced))
+}
+
+\f
+.ess_dbg_UntraceOrUndebug <- function(name, env = parent.frame()) {
+    tr_state <- tracingState(FALSE)
+    on.exit(tracingState(tr_state))
+    if( grepl('::', name) ){
+        ## foo:::bar name
+        eval(parse(text = sprintf('undebug(%s)', name)))
+    }else{
+        ## name is a name of a function to be undebugged or has a form
+        ## name:Class1#Class2#Class3 for traced methods
+        name <- strsplit(name, ':', fixed = TRUE)[[1]]
+        if( length(name)>1 ){
+            ## a method
+            fun <- name[[1]]
+            sig <- strsplit(paste(name[-1], collapse=''), '#', fixed=TRUE)[[1]]
+            untrace(fun, signature = sig)
+        }else{
+            ## function
+            if( is(getFunction(name, where = parent.frame()), 'traceable') )
+                untrace(name)
+            else if(grepl(":", name))
+                undebug(name)
+            else
+                undebug(get(name, envir = env))
+        }}
+}
+
+.ess_dbg_UndebugALL <- function(funcs)
+{
+    tr_state <- tracingState(FALSE)
+    on.exit(tracingState(tr_state))
+    env <- parent.frame()
+    invisible(lapply(funcs, function( nm ) {
+        ## ugly tryCatch, but there might be several names pointing to the
+        ## same function, like foo:::bar and bar. An alternative would be
+        ## to call .ess_dbg_getTracedAndDebugged each time but that might
+        ## be ery slow
+        try(.ess_dbg_UntraceOrUndebug(nm, env = env), TRUE)
+    }))
+}
+
+\f
+### WATCH
+.ess_watch_expressions <- list()
+
+.ess_watch_eval <- function()
+{
+    env <- as.environment("ESSR")
+    exps <- get('.ess_watch_expressions', envir = env)
+    if(length(exps) == 0) {
+        ## using old style so this can be parsed by R 1.9.1 (e.g):
+        cat('\n# Watch list is empty!\n',
+            '# a       append new expression',
+            '# i       insert new expression',
+            '# k       kill',
+            '# e       edit the expression',
+            '# r       rename',
+            '# n/p     navigate',
+            '# u/d,U   move the expression up/down',
+            '# q       kill the buffer',
+            sep="\n")
+    } else {
+        .parent_frame <- parent.frame()
+        .essWEnames <- allNames(exps)
+        len0p <- !nzchar(.essWEnames)
+        .essWEnames[len0p] <- seq_along(len0p)[len0p]
+        oo <- options(width = 10000)
+        on.exit(options(oo))
+        for(i in seq_along(exps)) {
+            cat('\n@---- ', .essWEnames[[i]], ' ',
+                rep.int('-', max(0, 35 - nchar(.essWEnames[[i]]))), '-@\n', sep = '')
+            expr <- gsub(" +", " ", paste(deparse(exps[[i]][[1]]), collapse = " "))
+            cat(paste('@---:', expr), ' \n', sep = '')
+            tryCatch(print(eval(exps[[i]],
+                                envir = .parent_frame)),
+                     error = function(e) cat('Error:', e$message, '\n' ),
+                     warning = function(w) cat('warning: ', w$message, '\n' ))
+        }
+    }
+}
+
+\f
+.ess_watch_assign_expressions <- function(elist) {
+    assign(".ess_watch_expressions", elist, envir = as.environment("ESSR"))
+}
+
+.ess_log_eval <- function(log_name) {
+    env <- as.environment("ESSR")
+    if(!exists(log_name, envir = env, inherits = FALSE))
+        assign(log_name, list(), envir = env)
+    log <- get(log_name, envir = env, inherits = FALSE)
+    .essWEnames <- allNames(.ess_watch_expressions)
+    cur_log <- list()
+    .parent_frame <- parent.frame()
+    for(i in seq_along(.ess_watch_expressions)) {
+        capture.output( {
+            cur_log[[i]] <-
+                tryCatch(eval(.ess_watch_expressions[[i]]),
+                         envir = .parent_frame,
+                         error = function(e) paste('Error:', e$message, '\n'),
+                         warning = function(w) paste('warning: ', w$message, '\n'))
+            if(is.null(cur_log[i][[1]]))
+                cur_log[i] <- list(NULL)
+        })
+    }
+    names(cur_log) <- .essWEnames
+    assign(log_name, c(log, list(cur_log)), envir = env)
+    invisible(NULL)
+}
+
+\f
+.ess_package_attached <- function(pack_name){
+    as.logical(match(paste0("package:", pack_name), search()))
+}
+
+## magrittr debug_pipe
+.ess_pipe_browser <- function(x){
+    if(is.list(x))
+        evalq({
+            browser(skipCalls = 2)
+            x
+        }, envir = x)
+    else if(is.environment(x))
+        ## enclos argumentn has no effect for unclear reason, need to hack
+        eval(bquote({
+            x <- .(environment())
+            browser(skipCalls = 2)
+            x
+        }), envir = x)
+    else {
+        browser(skipCalls = 0)
+        x
+    }
+}
diff --git a/elpa/ess-20260424.1544/etc/ESSR/R/misc.R b/elpa/ess-20260424.1544/etc/ESSR/R/misc.R
new file mode 100644 (file)
index 0000000..b34970f
--- /dev/null
@@ -0,0 +1,182 @@
+.ess_weave <- function(command, file, encoding = NULL){
+    cmd_symb <- substitute(command)
+    if (grepl('knit|purl', deparse(cmd_symb))) require(knitr)
+    od <- getwd()
+    on.exit(setwd(od))
+    setwd(dirname(file))
+    frame <- parent.frame()
+    if (is.null(encoding))
+        eval(bquote(.(cmd_symb)(.(file))), envir = frame)
+    else
+        eval(bquote(.(cmd_symb)(.(file), encoding = .(encoding))), envir = frame)
+}
+
+.ess_knit <- function(file, output = NULL){
+    library(knitr)
+    frame <- parent.frame()
+    od <- getwd()
+    on.exit(setwd(od))
+    setwd(dirname(file))
+    ## this bquote is really needed for data.table := operator to work correctly
+    eval(bquote(knit(.(file), output = .(output))), envir = frame)
+}
+
+\f
+.ess_sweave <- function(file, output = NULL){
+    od <- getwd()
+    frame <- parent.frame()
+    on.exit(setwd(od))
+    setwd(dirname(file))
+    eval(bquote(Sweave(.(file), output = .(output))), envir = frame)
+}
+
+## Users might find it useful. So don't prefix with .ess.
+.ess_htsummary <- function(x, hlength = 4, tlength = 4, digits = 3) {
+    ## fixme: simplify and generalize
+    snames <- c("mean", "sd", "min", "max", "nlev", "NAs")
+    d <- " "
+    num_sumr <- function(x){
+        c(f(mean(x, na.rm = TRUE)),
+          f(sd(x, na.rm = TRUE)),
+          f(min(x, na.rm = TRUE)),
+          f(max(x, na.rm = TRUE)),
+          d,
+          f(sum(is.na(x), na.rm = TRUE)))
+    }
+    f <- function(x) format(x, digits = digits)
+
+    if (is.data.frame(x) | is.matrix(x)) {
+        if (nrow(x) <= tlength + hlength){
+            print(x)
+        } else {
+            if (is.matrix(x))
+                x <- data.frame(unclass(x))
+            ## conversion needed, to avoid problems with derived classes such
+            ## as data.table
+            h <- as.data.frame(head(x, hlength))
+            t <- as.data.frame(tail(x, tlength))
+            for (i in 1:ncol(x)) {
+                h[[i]] <- f(h[[i]])
+                t[[i]] <- f(t[[i]])
+            }
+            ## summaries
+            sumr <- sapply(x, function(c){
+                if (is.logical(c))
+                    ## treat logical as numeric; it's harmless
+                    c <- as.integer(c)
+                if (is.numeric(c))
+                    num_sumr(c)
+                else if (is.factor(c)) c(d, d, d, d, nlevels(c), sum(is.na(c)))
+                else rep.int(d, length(snames))
+            })
+            sumr <- as.data.frame(sumr)
+            row.names(sumr) <- snames
+            dots <- rep("...", ncol(x))
+            empty <- rep.int(" ", ncol(x))
+            lines <- rep.int(" ", ncol(x))
+            df <- rbind(h, ... = dots, t, `_____` = lines, sumr, ` ` = empty)
+            print(df)
+        }
+    } else {
+        cat("head(", hlength, "):\n", sep = "")
+        print(head(x, hlength))
+        if (length(x) > tlength + hlength){
+            cat("\ntail(", tlength, "):\n", sep = "")
+            print(tail(x, tlength))
+        }
+        cat("_____\n")
+        if (is.numeric(x) || is.logical(x))
+            print(structure(num_sumr(x), names = snames), quote = FALSE)
+        else if (is.factor(x)){
+            cat("NAs: ", sum(is.na(x), na.rm = TRUE), "\n")
+            cat("levels: \n")
+            print(levels(x))
+        }
+    }
+    invisible(NULL)
+}
+
+\f
+.ess_vignettes <- function(all=FALSE) {
+    vs <- unclass(browseVignettes(all = all))
+    vs <- vs[sapply(vs, length) > 0]
+
+    mat2elist <- function(mat) {
+        if (!is.null(dim(mat))){
+            apply(mat, 1, function(r)
+                sprintf("(list \"%s\")",
+                        paste0(gsub("\"", "\\\\\"",
+                                    as.vector(r[c("Title", "Dir", "PDF",
+                                                  "File", "R")])),
+                               collapse = "\" \"")))
+        }
+    }
+    cat("(list \n",
+        paste0(mapply(function(el, name) {
+            sprintf("(list \"%s\"  %s)",
+                    name, paste0(mat2elist(el), collapse = "\n"))
+        },
+        vs, names(vs)), collapse = "\n"), ")\n")
+}
+
+.ess_Rd2txt <- function(rd) {
+    fun <- tools::Rd2txt
+    if (length(formals(fun)["stages"]))# newer R version
+        fun(rd, stages = c("build", "install", "render"))
+    else
+        fun(rd)
+}
+
+## Hacked help.start() to use with ess-rutils.el
+.ess_help_start <- function(update=FALSE, remote=NULL) {
+    home <- if (is.null(remote)) {
+                port <- tools::startDynamicHelp(NA)
+                if (port > 0L) {
+                    if (update)
+                        make.packages.html(temp=TRUE)
+                    paste0("http://127.0.0.1:", port)
+                }
+                else stop(".ess_help_start() requires the HTTP server to be running",
+                          call.=FALSE)
+            } else remote
+    paste0(home, "/doc/html/index.html")
+}
+
+\f
+.ess.rdired <- function() {
+    cat('\n')
+
+    objs <- ls(envir = .GlobalEnv)
+    if (length(objs)==0) {
+        cat("No objects to view!\n")
+        return(invisible(NULL))
+    }
+
+    names(objs) <- objs
+    objs <- lapply(objs, get, envir = .GlobalEnv)
+
+    mode <- sapply(objs, data.class)
+    length <- sapply(objs, length)
+    size <- sapply(objs, function(obj) format(object.size(obj)))
+    rows <- sapply(objs,nrow)
+       # sapply returns a list rather than a vector if there are NULLs eg nrow returns NULL for non-dataframes.  
+       # check if list, replace NULLS with NA and convert to vector
+       if (is.list(rows)) {
+               rows[sapply(rows,is.null)] <- NA
+               rows <- unlist(rows)
+       }
+    
+    d <- data.frame(mode, length, rows, size)
+    
+    var.names <- row.names(d)
+    
+    ## If any names contain spaces, we need to quote around them.
+    quotes <- rep('', length(var.names))
+    spaces <- grep(' ', var.names)
+    if (any(spaces))
+        quotes[spaces] <- '\"'
+    var.names <- paste(quotes, var.names, quotes, sep = '')
+    row.names(d) <- paste('  ', var.names, sep = '')
+
+    print(d)
+}
diff --git a/elpa/ess-20260424.1544/etc/ESSR/R/mpi.R b/elpa/ess-20260424.1544/etc/ESSR/R/mpi.R
new file mode 100644 (file)
index 0000000..0ad5cfc
--- /dev/null
@@ -0,0 +1,28 @@
+## simple Message Parsing Interface
+
+.ess_mpi_send <- function(head, ...){
+    dots <- lapply(list(...), function(el) {
+        if (is.null(el)) "nil"
+        else if (is.logical(el)) {if (el) "t" else "nil"}
+        else as.character(el)
+    })
+    payload <- paste(dots, collapse = "\1e")
+    cat(sprintf("\e_%s\1e%s\e\\", head, payload))
+}
+
+.ess_mpi_message <- function(msg){
+    .ess_mpi_send("message", msg)
+}
+
+.ess_mpi_y_or_n <- function(prompt, callback = NULL){
+    .ess_mpi_send("y-or-n", prompt, callback)
+}
+
+.ess_mpi_eval <- function(expr, callback = NULL){
+    .ess_mpi_send("eval", expr, callback)
+}
+
+.ess_mpi_error <- function(msg) {
+    .ess_mpi_send("error", msg)
+}
+
diff --git a/elpa/ess-20260424.1544/etc/ESSR/R/ns-eval.R b/elpa/ess-20260424.1544/etc/ESSR/R/ns-eval.R
new file mode 100644 (file)
index 0000000..8dc4da8
--- /dev/null
@@ -0,0 +1,421 @@
+## NOTE ON S3 METHODS: New S3 methods are not automatically registered. You can
+## register them manually after you have inserted method_name.my_class into your
+## package environment using ess-developer, like follows:
+##
+##    registerS3method("method_name", "my_class", my_package:::method_name.my_class)
+##
+## If an S3 methods already exists in a package, ESS-developer will do the right
+## thing.
+
+## evaluate the STRING by saving into a file and calling .ess.ns_source
+.ess.ns_eval <- function(string, visibly, output, package,
+                         file = tempfile("ESSDev"), verbose = FALSE,
+                         fallback_env = NULL, local_env = parent.frame()) {
+    cat(string, file = file)
+    on.exit(.ess.file.remove(file))
+    .ess.ns_source(file, visibly, output, package = package,
+                   verbose = verbose, fake.source = TRUE,
+                   fallback_env = fallback_env, local_env = local_env)
+}
+
+\f
+##' Source FILE into an environment. After having a look at each new object in
+##' the environment, decide what to do with it. Handles plain objects,
+##' functions, existing S3 methods, S4 classes and methods.
+##' @param fallback_env environment to assign objects which don't exist in the
+##'     package namespace
+.ess.ns_source <- function(file, visibly, output, expr,
+                           package = "", verbose = FALSE,
+                           fake.source = FALSE,
+                           fallback_env = NULL,
+                           local_env = NULL) {
+    pname <- paste("package:", package, sep = "")
+    envpkg <- tryCatch(as.environment(pname), error = function(cond) NULL)
+
+    if (is.null(envpkg)) {
+        if (suppressWarnings(require(package, quietly = TRUE, character.only = TRUE))) {
+            envpkg <- tryCatch(as.environment(pname), error = function(cond) NULL)
+        } else {
+            ## no such package; source in current (local) user environment
+            return(.ess.source(file, visibly = visibly,
+                               output = output, local = local_env,
+                               fake.source = fake.source))
+        }
+    }
+
+    envns <- tryCatch(asNamespace(package), error = function(cond) NULL)
+    if (is.null(envns))
+        stop(gettextf("Can't find a namespace environment corresponding to package name '%s\"",
+                      package), domain = NA)
+
+    ## Here we know that both envns and envpkg exists and are environments
+    if (is.null(fallback_env))
+        fallback_env <- .ess.ns_insert_essenv(envns)
+
+    ## Get all Imports envs where we propagate objects
+    pkgEnvNames <- Filter(.ess.is_package, search())
+    packages <- lapply(pkgEnvNames, function(envName) substring(envName, 9))
+    importsEnvs <- lapply(packages, function(pkgName) parent.env(asNamespace(pkgName)))
+
+    ## Evaluate the FILE into new ENV
+    env <- .ess.ns_evalSource(file, visibly, output, substitute(expr), package, fake.source)
+    envPackage <- getPackageName(env, FALSE)
+    if (nzchar(envPackage) && envPackage != package)
+        warning(gettextf("Supplied package, %s, differs from package inferred from source, %s",
+                         sQuote(package), sQuote(envPackage)), domain = NA)
+
+    ## Get all sourced objects, methods and classes
+    allObjects <- objects(envir = env, all.names = TRUE)
+    allObjects <- allObjects[!(allObjects %in% c(".cacheOnAssign", ".packageName"))]
+    MetaPattern <- methods:::.TableMetaPattern()
+    ClassPattern <- methods:::.ClassMetaPattern()
+    allPlainObjects <- allObjects[!(grepl(MetaPattern, allObjects) |
+                                    grepl(ClassPattern, allObjects))]
+    allMethodTables <- allObjects[grepl(MetaPattern, allObjects)]
+    allClassDefs <- allObjects[grepl(ClassPattern, allObjects)]
+
+    ## PLAIN OBJECTS and FUNCTIONS:
+    funcNs <- funcPkg <- newFunc <- newNs <- newObjects <- newPkg <- objectsNs <- objectsPkg <- character()
+    dependentPkgs <- list()
+
+    for (this in allPlainObjects) {
+        thisEnv <- get(this, envir = env)
+        thisNs <- NULL
+
+        ## NS
+        if (exists(this, envir = envns, inherits = FALSE)){
+            thisNs <- get(this, envir = envns)
+            if(is.function(thisNs) || is.function(thisEnv)){
+                if(is.function(thisNs) && is.function(thisEnv)){
+                    if(.ess.differs(thisEnv, thisNs)){
+                        environment(thisEnv) <- environment(thisNs)
+                        .ess.assign(this, thisEnv, envns)
+                        funcNs <- c(funcNs, this)
+                        if(exists(".__S3MethodsTable__.", envir = envns, inherits = FALSE)){
+                            S3_table <- get(".__S3MethodsTable__.", envir = envns)
+                            if(exists(this, envir = S3_table, inherits = FALSE))
+                                .ess.assign(this, thisEnv, S3_table)
+                        }
+                    }
+                }else{
+                    newNs <- c(newNs, this)
+                }
+            }else{
+                if(!identical(thisEnv, thisNs)){
+                    .ess.assign(this, thisEnv, envns)
+                    objectsNs <- c(objectsNs, this)
+                }
+            }
+        }else{
+            newNs <- c(newNs, this)
+        }
+
+        ## PKG
+        if (exists(this, envir = envpkg, inherits = FALSE)){
+            thisPkg <- get(this, envir = envpkg)
+            if(is.function(thisPkg) || is.function(thisEnv)){
+                if(is.function(thisPkg) && is.function(thisEnv)){
+                    if(.ess.differs(thisPkg, thisEnv)){
+                        environment(thisEnv) <- environment(thisPkg)
+                        .ess.assign(this, thisEnv, envpkg)
+                        funcPkg <- c(funcPkg, this)
+                    }
+                }else{
+                    newPkg <- c(newPkg, this)
+                }
+            }else{
+                if(!identical(thisPkg, thisEnv)){
+                    .ess.assign(this, thisEnv, envpkg)
+                    objectsPkg <- c(objectsPkg, this)
+                }
+            }
+        }else{
+            newPkg <- c(newPkg, this)
+        }
+
+        if (!is.null(thisNs)) {
+            isDependent <- .ess.ns_propagate(thisEnv, this, importsEnvs)
+            newDeps <- stats::setNames(list(packages[isDependent]), this)
+            dependentPkgs <- c(dependentPkgs, newDeps)
+        }
+    }
+
+    ## deal with new plain objects and functions
+    for (this in intersect(newPkg, newNs)) {
+        thisEnv <- get(this, envir = env, inherits = FALSE)
+        if (exists(this, envir = fallback_env, inherits = FALSE)){
+            thisGl <- get(this, envir = fallback_env)
+            if (.ess.differs(thisEnv, thisGl)) {
+                if (is.function(thisEnv)) {
+                    environment(thisEnv) <- envns
+                    newFunc <- c(newFunc, this)
+                } else {
+                    newObjects <- c(newObjects, this)
+                }
+                .ess.assign(this, thisEnv, fallback_env)
+                if (.is.essenv(fallback_env))
+                    .ess.assign(this, thisEnv, .GlobalEnv)
+            }
+        } else {
+            if (is.function(thisEnv)) {
+                environment(thisEnv) <- envns
+                newFunc <- c(newFunc, this)
+            } else {
+                newObjects <- c(newObjects, this)
+            }
+            .ess.assign(this, thisEnv, fallback_env)
+            if (.is.essenv(fallback_env))
+                .ess.assign(this, thisEnv, .GlobalEnv)
+        }
+    }
+
+    if(length(funcNs))
+        objectsNs <- c(objectsNs, sprintf("FUN[%s]", paste(funcNs, collapse = ", ")))
+    if(length(funcPkg))
+        objectsPkg <- c(objectsPkg, sprintf("FUN[%s]", paste(funcPkg, collapse = ", ")))
+    if(length(newFunc))
+        newObjects <- c(newObjects, sprintf("FUN[%s]", paste(newFunc, collapse = ", ")))
+
+    ## CLASSES
+    classesPkg <- classesNs <- newClasses <- character()
+    for(this in allClassDefs){
+        newPkg <- newNs <- FALSE
+        thisEnv <- get(this, envir = env)
+        if(exists(this, envir = envpkg, inherits = FALSE)){
+            if(!.ess.identicalClass(thisEnv, get(this, envir = envpkg))){
+                .ess.assign(this, thisEnv, envir = envpkg)
+                classesPkg <- c(classesPkg, this)
+            }
+        }else{
+            newPkg <- TRUE
+        }
+        if(exists(this, envir = envns, inherits = FALSE)){
+            if(!.ess.identicalClass(thisEnv, get(this, envir = envns))){
+                .ess.assign(this, thisEnv, envir = envns)
+                classesNs <- c(classesNs, this)
+            }
+        }else{
+            newNs <- TRUE
+        }
+        if(newNs && newPkg){
+            if(exists(this, envir = fallback_env, inherits = FALSE)){
+                if(!.ess.identicalClass(thisEnv, get(this, envir = fallback_env))){
+                    .ess.assign(this, thisEnv, envir = fallback_env)
+                    newClasses <- c(newClasses, this)
+                }
+            }else{
+                .ess.assign(this, thisEnv, envir = fallback_env)
+                newClasses <- c(newClasses, this)
+            }
+        }
+    }
+    if(length(classesPkg))
+        objectsPkg <- gettextf("CLS[%s]", sub(ClassPattern, "", paste(classesPkg, collapse = ", ")))
+    if(length(classesNs))
+        objectsNs <- gettextf("CLS[%s]", sub(ClassPattern, "", paste(classesNs, collapse = ", ")))
+    if(length(newClasses))
+        newObjects <- gettextf("CLS[%s]", sub(ClassPattern, "", paste(newClasses, collapse = ", ")))
+
+    ## METHODS:
+    ## Method internals: For efficiency reasons setMethod() caches
+    ## method definition into a global table which you can get with
+    ## 'getMethodsForDispatch' function, and when a method is dispatched that
+    ## table is used. When ess-developer is used to source method definitions the
+    ## two copies of the functions are identical up to the environment. The
+    ## environment of the cached object has namespace:foo as it's parent but the
+    ## environment of the object in local table is precisely namespace:foo. This
+    ## does not cause any difference in evaluation.
+    methodNames <- allMethodTables
+    methods <- sub(methods:::.TableMetaPrefix(), "", methodNames)
+    methods <- sub(":.*", "", methods)
+    methodsNs <- newMethods <- character()
+    for (i in seq_along(methods)){
+        table <- methodNames[[i]]
+        tableEnv <- get(table,  envir = env)
+        if(exists(table,  envir = envns, inherits = FALSE)){
+            inserted <- .ess.ns_insertMethods(tableEnv, get(table, envir = envns), envns)
+            if(length(inserted))
+                methodsNs <- c(methodsNs,  gettextf("%s{%s}", methods[[i]], paste(inserted, collapse = ", ")))
+        }else if(exists(table,  envir = fallback_env, inherits = FALSE)){
+            inserted <- .ess.ns_insertMethods(tableEnv, get(table, envir = fallback_env), envns)
+            if(length(inserted))
+                newMethods <- c(newMethods,  gettextf("%s{%s}", methods[[i]], paste(inserted, collapse = ", ")))
+        }else{
+            .ess.assign(table, tableEnv, envir = fallback_env)
+            newMethods <- c(newMethods,  gettextf("%s{%s}", methods[[i]], paste(objects(envir = tableEnv, all.names = T), collapse = ", ")))
+        }
+    }
+    if(length(methodsNs))
+        objectsNs <- c(objectsNs, gettextf("METH[%s]", paste(methodsNs, collapse = ", ")))
+    if(length(newMethods))
+        newObjects <- c(newObjects, gettextf("METH[%s]", paste(newMethods, collapse = ", ")))
+
+    if (verbose) {
+        msgs <- unlist(list(
+            if(length(objectsPkg))
+                sprintf("PKG: %s", paste(objectsPkg, collapse = ", ")),
+            if(length(objectsNs))
+                sprintf("NS: %s", paste(objectsNs, collapse = ", ")),
+            if(length(dependentPkgs))
+                .ess.ns_format_deps(dependentPkgs),
+            if(length(newObjects)) {
+                env_name <- .ess.ns_env_name(fallback_env)
+                sprintf("%s: %s", env_name, paste(newObjects, collapse = ", "))
+            }))
+        if(length(msgs))
+            .ess_mpi_message(paste(msgs, collapse = "  "))
+
+    }
+
+    invisible(env)
+}
+
+\f
+.ess.ns_insertMethods <- function(tableEnv,  tablePkg, envns) {
+    inserted <- character()
+    for(m in ls(envir = tableEnv, all.names = T)){
+        if(exists(m, envir = tablePkg, inherits = FALSE)){
+            thisEnv <- get(m, envir = tableEnv)
+            thisPkg <- get(m, envir = tablePkg)
+            if(is(thisEnv, "MethodDefinition") && is(thisPkg, "MethodDefinition") &&
+               .ess.differs(thisEnv@.Data, thisPkg@.Data)){
+                environment(thisEnv@.Data) <- envns
+                ## environment of cached method in getMethodsForDispatch table is still env
+                ## not a problem as such,  but might confuse users
+                .ess.assign(m, thisEnv, tablePkg)
+                inserted <- c(inserted, m)
+            }}}
+    inserted
+}
+
+## our version of R's evalSource
+.ess.ns_evalSource <- function(file, visibly, output, expr, package = "",
+                               fake.source = FALSE) {
+    envns <- tryCatch(asNamespace(package), error = function(cond) NULL)
+    if(is.null(envns))
+        stop(gettextf("Package \"%s\" is not attached and no namespace found for it",
+                      package), domain = NA)
+    env <- new.env(parent = envns)
+    env[[".packageName"]] <- package
+    methods:::setCacheOnAssign(env, TRUE)
+    if (missing(file))
+        eval(expr, envir = env)
+    else  if (is(file, "character"))
+        for (f in file) {
+            .ess.source(f, local = env, visibly = visibly,
+                        output = output, keep.source = TRUE,
+                        max.deparse.length = 300,
+                        fake.source = fake.source,
+                        message.prefix = sprintf("[%s] ", package))
+        }
+    else stop(gettextf("Invalid file argument:  got an object of class \"%s\"",
+                       class(file)[[1]]), domain = NA)
+    env
+}
+
+\f
+.ess.assign <- function(x, value, envir) {
+    ## Cannot add bindings to locked environments
+    exists <- exists(x, envir = envir, inherits = FALSE)
+    if (exists && bindingIsLocked(x, envir)) {
+        unlockBinding(x, envir)
+        assign(x, value, envir = envir, inherits = FALSE)
+        op <- options(warn = -1)
+        on.exit(options(op))
+        lockBinding(x, envir)
+    } else if (exists || !environmentIsLocked(envir)) {
+        assign(x, value, envir = envir, inherits = FALSE)
+    } else {
+        warning(sprintf("Cannot assign `%s` in locked environment", x),
+                call. = FALSE)
+    }
+    invisible(NULL)
+}
+
+.ess.identicalClass <- function(cls1, cls2, printInfo = FALSE) {
+    slots1 <- slotNames(class(cls1))
+    slots2 <- slotNames(class(cls2))
+    if(identical(slots1, slots2)){
+        vK <- grep("versionKey", slots1)
+        if(length(vK))
+            slots1 <- slots2 <- slots1[-vK]
+        out <- sapply(slots1, function(nm) identical(slot(cls1, nm), slot(cls2, nm)))
+        if(printInfo) print(out)
+        all(out)
+    }
+}
+
+.ess.differs <- function(f1, f2) {
+    if (is.function(f1) && is.function(f2)){
+        !(identical(body(f1), body(f2)) && identical(args(f1), args(f2)))
+    }else
+        !identical(f1, f2)
+}
+
+\f
+.ess.is_package <- function(envName) {
+  isPkg <- identical(substring(envName, 0, 8), "package:")
+  isPkg && (envName != "package:base")
+}
+
+.ess.ns_propagate <- function(obj, name, importsEnvs) {
+  containsObj <- vapply(importsEnvs, logical(1), FUN = function(envs) {
+    name %in% names(envs)
+  })
+
+  lapply(importsEnvs[containsObj], .ess.assign,
+         x = name, value = obj)
+
+  containsObj
+}
+
+
+.ess.ns_format_deps <- function(dependentPkgs) {
+    pkgs <- unique(unlist(dependentPkgs, use.names = FALSE))
+
+    lapply(pkgs, function(pkg) {
+        isDep <- vapply(dependentPkgs, function(deps) pkg %in% deps, logical(1))
+        pkgDependentObjs <- names(dependentPkgs[isDep])
+        sprintf("DEP:%s [%s]   ", pkg, paste(pkgDependentObjs, collapse = ", "))
+    })
+}
+
+.ess.ns_env_name <- function(env) {
+    name <- environmentName(env)
+    name <-
+        if (name == "") "Local"
+        else if (grepl("^essenv:", name)) "NEW"
+        else name
+    name
+}
+
+\f
+.ess.ns_insert_essenv <- function(nsenv) {
+    if (is.character(nsenv))
+        nsenv <- asNamespace(nsenv)
+    stopifnot(isNamespace(nsenv))
+    if (identical(nsenv, .BaseNamespaceEnv))
+        return(.GlobalEnv)
+    essenv_name <- sprintf("essenv:%s", environmentName(nsenv))
+    nsenv_parent <- parent.env(nsenv)
+    if (environmentName(nsenv_parent) == essenv_name) {
+        return(nsenv_parent)
+    }
+    essenv <- new.env(parent = nsenv_parent)
+    essenv[[".__ESSENV__."]] <- TRUE
+    attr(essenv, "name") <- essenv_name
+    nssym <- ".__NAMESPACE__."
+    nssym_val <- get(nssym, envir = nsenv, inherits = FALSE)
+    unlockBinding(nssym, nsenv)
+    nsenv[[nssym]] <- NULL
+    on.exit({
+        nsenv[[nssym]] <- nssym_val
+        lockBinding(nssym, nsenv)
+    })
+    parent.env(nsenv) <- essenv
+    essenv
+}
+
+.is.essenv <- function(env) {
+    exists(".__ESSENV__.", envir = env, inherits = FALSE)
+}
diff --git a/elpa/ess-20260424.1544/etc/ESSR/R/pkg.R b/elpa/ess-20260424.1544/etc/ESSR/R/pkg.R
new file mode 100644 (file)
index 0000000..ebd0463
--- /dev/null
@@ -0,0 +1,26 @@
+
+.ess_keep <- function(.x, .f, ...) {
+  is_true <- vapply(.x, .f, logical(1), ...)
+  .x[is_true]
+}
+
+.ess_devtools_functions <- function() {
+  if (!requireNamespace("devtools")) {
+    .ess_mpi_error("devtools is not installed")
+    stop("internal error")
+  }
+  devtools_env <- asNamespace("devtools")
+  exports <- getNamespaceExports("devtools")
+  funs_exported <- as.list(devtools_env)[exports]
+
+  is_first_arg <- function(f, arg) {
+    args <- names(formals(f))
+    length(args) && args[[1]] == arg
+  }
+
+  funs_pkg <- .ess_keep(funs_exported, is.function)
+  funs_pkg <- .ess_keep(funs_pkg, is_first_arg, "pkg")
+  funs_names <- sort(names(funs_pkg))
+
+  funs_names
+}
diff --git a/elpa/ess-20260424.1544/etc/Makefile b/elpa/ess-20260424.1544/etc/Makefile
new file mode 100644 (file)
index 0000000..e2d2276
--- /dev/null
@@ -0,0 +1,52 @@
+### Makefile - for scripts and icons (./etc) of ESS distribution.
+###
+
+## Before making changes here, please take a look at Makeconf
+include ../Makeconf
+
+#ETCFILES = $(wildcard BACKBUG[S5].BAT backbug[s5] *.S sas-keys.*)
+#ETCFILES = ESSR.R ess-developer.R SVN-REVISION *.S sas-keys.* ess-sas-sh-command
+# ETCFILES_1 = *.S sas-keys.* ess-sas-sh-command *.jl
+ETCFILES_1 = ess-sas-sh-command *.jl
+isRELEASE=$(shell test -f .IS.RELEASE && echo 'yes')
+ifeq ($(isRELEASE),yes)
+  ETCFILES = .IS.RELEASE git-ref $(ETCFILES_1)
+else
+  ETCFILES =                     $(ETCFILES_1)
+endif
+
+#ICONS = $(wildcard icons/*.xpm)
+ICONS = icons/*.xpm
+
+ESSR_UTIL_FILES = ESSR/LOADREMOTE
+ESSR_CODE_FILES = ESSR/R/*.R ESSR/R/.*.R
+
+all:
+
+show-etc:
+       @echo $(ETCFILES)
+       ls -l $(ETCFILES)
+
+install :
+       $(INSTALLDIR) $(ETCDIR)/icons
+       $(INSTALLDIR) $(ETCDIR)/ESSR/R
+       $(INSTALL) $(ETCFILES) $(ETCDIR)
+       $(INSTALL) $(ICONS) $(ETCDIR)/icons
+       $(INSTALL) $(ESSR_UTIL_FILES) $(ETCDIR)/ESSR
+       $(INSTALL) $(ESSR_CODE_FILES) $(ETCDIR)/ESSR/R
+       chmod +x $(ETCDIR)/ess-sas-sh-command
+
+uninstall :
+       -cd $(ETCDIR) && $(UNINSTALL) $(ETCFILES)
+       -cd $(ETCDIR) && $(UNINSTALL) $(ICONS)
+       -cd $(ETCDIR) && $(UNINSTALL) $(ESSR_UTIL_FILES)
+       -cd $(ETCDIR) && $(UNINSTALL) $(ESSR_CODE_FILES)
+
+
+
+## 'clean'     shall remove *exactly* those things that are *not* in version control
+clean distclean:
+       rm -rf SVN-REVISION
+## 'distclean' removes also things in VC (svn, when they are remade by "make"):
+# distclean: clean
+#      rm -rf ESSR_*.tar.gz
diff --git a/elpa/ess-20260424.1544/etc/all.txt b/elpa/ess-20260424.1544/etc/all.txt
new file mode 100644 (file)
index 0000000..90ade3c
--- /dev/null
@@ -0,0 +1,1058 @@
+ACCESS
+ACECLUS
+SAS/STAT User’s Guide
+ADAPTIVEREG
+SAS/STAT User’s Guide
+AGGREGATION
+See SAS Risk Dimensions and SAS High-Performance Risk: Procedures Guide
+ANOM
+SAS/QC User’s Guide
+ANOVA
+SAS/STAT User’s Guide
+APPEND
+Base SAS Procedures Guide
+APPSRV
+SAS/IntrNet: Application Dispatcher
+ARIMA
+SAS/ETS User’s Guide
+ASSESS
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+ASTORE
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+AUTHLIB
+Base SAS Procedures Guide
+AUTOREG
+SAS/ETS User’s Guide
+B
+Procedure
+Location of Procedure Documentation
+BCHOICE
+SAS/STAT User’s Guide
+BGLIMM
+SAS/STAT User’s Guide
+BINNING
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+BNET
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+BOM
+SAS/OR User’s Guide: Bill of Material Processing
+BOOLRULE
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+BOXPLOT
+SAS/STAT User’s Guide
+BUILD
+SAS/AF Procedure Guide
+C
+Procedure
+Location of Procedure Documentation
+CALENDAR
+Base SAS Procedures Guide
+CALIS
+SAS/STAT User’s Guide
+CALLRFC
+SAS/ACCESS Interface to R/3: User’s Guide
+CANCORR
+SAS/STAT User’s Guide
+CANDISC
+SAS/STAT User’s Guide
+CAPABILITY
+SAS/QC User’s Guide
+CARDINALITY
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+CARIMA *Available starting with SAS Viya 3.4.
+SAS Econometrics: Econometrics Procedures
+CAS
+SAS Cloud Analytic Services: CASL Reference
+CASUTIL
+SAS Cloud Analytic Services: User’s Guide
+CATALOG
+Base SAS Procedures Guide
+CATALOG for UNIX
+SAS Companion for UNIX Environments
+CATALOG for Windows
+SAS Companion for Windows
+CATALOG for z/OS
+SAS Companion for z/OS
+CATMOD
+SAS/STAT User’s Guide
+CAUSALGRAPH
+SAS/STAT User’s Guide
+CAUSALMED
+SAS/STAT User’s Guide
+CAUSALTRT
+SAS/STAT User’s Guide
+CCDM
+SAS Econometrics: Econometrics Procedures
+CCOPULA
+SAS Econometrics: Econometrics Procedures
+CESM *Available starting with SAS Viya 3.4.
+SAS Econometrics: Econometrics Procedures
+CHART
+Base SAS Procedures Guide
+CIMPORT
+Base SAS Procedures Guide
+CIMPORT for UNIX
+SAS Companion for UNIX Environments
+CIMPORT for Windows
+SAS Companion for Windows
+CIMPORT for z/OS
+SAS Companion for z/OS
+CLP
+SAS Optimization: Mathematical Optimization Procedures
+CLP
+SAS/OR User’s Guide: Constraint Programming
+CLUSTER
+SAS/STAT User’s Guide
+CNTSELECT
+SAS Econometrics: Econometrics Procedures
+COMPARE
+Base SAS Procedures Guide
+COMPILE
+See SAS Risk Dimensions and SAS High-Performance Risk: Procedures Guide
+COMPUTAB
+SAS/ETS User’s Guide
+CONTENTS
+Base SAS Procedures Guide
+CONTENTS for UNIX
+SAS Companion for UNIX Environments
+CONTENTS for Windows
+SAS Companion for Windows
+CONTENTS for z/OS
+SAS Companion for z/OS
+CONVERT for UNIX
+SAS Companion for UNIX Environments
+CONVERT for Windows
+SAS Companion for Windows
+CONVERT for z/OS
+SAS Companion for z/OS
+COPULA
+See SAS/ETS User’s Guide
+COPY
+Base SAS Procedures Guide
+CORR
+Base SAS Procedures Guide: Statistical Procedures
+CORRELATION
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+CORRESP
+SAS/STAT User’s Guide
+COUNTREG
+SAS/ETS User’s Guide
+CPANEL
+SAS Econometrics: Econometrics Procedures
+CPM
+SAS/OR User’s Guide: Project Management
+CPORT
+Base SAS Procedures Guide
+CPORT for UNIX
+SAS Companion for UNIX Environments
+CPORT for Windows
+SAS Companion for Windows
+CPORT for z/OS
+SAS Companion for z/OS
+CQLIM
+SAS Econometrics: Econometrics Procedures
+CSPATIALREG
+SAS Econometrics: Econometrics Procedures
+CUSUM
+SAS/QC User’s Guide
+CV2VIEW
+SAS/ACCESS for Relational Databases: Reference
+D
+Procedure
+Location of Procedure Documentation
+DATEKEYS
+Base SAS Procedures Guide
+DATASETS
+Base SAS Procedures Guide
+DATASETS for UNIX
+SAS Companion for UNIX Environments
+DATASETS for Windows
+SAS Companion for Windows
+DATASETS for z/OS
+SAS Companion for z/OS
+DATASOURCE
+SAS/ETS User’s Guide
+DB2EXT for z/OS
+SAS/ACCESS for Relational Databases: Reference
+DB2UTIL for z/OS
+SAS/ACCESS for Relational Databases: Reference
+DBCSTAB
+SAS National Language Support (NLS): Reference Guide
+DBF for PC Files
+SAS/ACCESS Interface to PC Files: Reference
+DBF for z/OS
+SAS Companion for z/OS
+DBLOAD
+SAS/ACCESS for Relational Databases: Reference
+DBLOAD for PC Files
+SAS/ACCESS Interface to PC Files: Reference
+DBLOAD for SYSTEM 2000 (z/OS only)
+SAS/ACCESS Interface to SYSTEM 2000: Reference
+DELETE
+Base SAS Procedures Guide
+DFIL *Available starting with SAS Viya 3.5.
+SAS Visual Forecasting: Forecasting Procedures
+DIF for PC Files
+SAS/ACCESS Interface to PC Files: Reference
+DISCRIM
+SAS/STAT User’s Guide
+DISPLAY
+Base SAS Procedures Guide
+DISTANCE
+SAS/STAT User’s Guide
+DMSRVADM
+SAS Data Quality Server: Reference
+DMSRVDATASVC
+SAS Data Quality Server: Reference
+DMSRVPROCESSSVC
+SAS Data Quality Server: Reference
+DOCUMENT
+SAS Output Delivery System: Procedures Guide
+DOWNLOAD
+SAS/CONNECT User’s Guide
+DOWNLOAD
+SAS/CONNECT for SAS Viya: User’s Guide
+DQLOCLST
+SAS Data Quality Server: Reference
+DQMATCH
+SAS Data Quality Server: Reference
+DQSCHEME
+SAS Data Quality Server: Reference
+DS2
+Base SAS Procedures Guide
+DSTODS2
+Base SAS Procedures Guide
+DTREE
+SAS/OR User’s Guide: Project Management
+E
+Procedure
+Location of Procedure Documentation
+ECM *Available starting with SAS Viya 3.4.
+SAS Econometrics: Econometrics Procedures
+ENTROPY
+SAS/ETS User’s Guide
+ESM
+SAS/ETS User’s Guide
+EXPAND
+SAS/ETS User’s Guide
+EXPLODE
+SAS documentation on support.sas.com
+EXPORT
+Base SAS Procedures Guide
+EXPORT for PC Files
+SAS/ACCESS Interface to PC Files: Reference
+F
+Procedure
+Location of Procedure Documentation
+FACTEX
+SAS/QC User’s Guide
+FACTMAC
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+FACTOR
+SAS/STAT User’s Guide
+FASTCLUS
+SAS/STAT User’s Guide
+FASTKNN
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+FCMP
+Base SAS Procedures Guide
+FEDSQL
+Base SAS Procedures Guide
+FISM
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+FMM
+SAS/STAT User’s Guide
+FMTC2ITM
+Base SAS Procedures Guide
+FONTREG
+Base SAS Procedures Guide
+FONTREG for z/OS
+SAS Companion for z/OS
+FOREST
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+FORMAT
+Base SAS Procedures Guide
+FORMAT for z/OS
+SAS Companion for z/OS
+FORMS
+SAS documentation on support.sas.com
+FREQ
+Base SAS Procedure’s Guide: Statistical Procedures
+FREQ
+SAS/STAT User’s Guide
+FREQTAB
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+FSBROWSE
+SAS/FSP Procedures Guide
+FSEDIT
+SAS/FSP Procedures Guide
+FSLETTER
+SAS/FSP Procedures Guide
+FSLIST
+Base SAS Procedures Guide
+FSVIEW
+SAS/FSP Procedures Guide
+G
+Procedure
+Location of Procedure Documentation
+G3D
+SAS/GRAPH: Reference
+G3GRID
+SAS/GRAPH: Reference
+GA
+SAS/OR User’s Guide: Local Search Optimization
+GAM
+SAS/STAT User’s Guide
+GAMMOD
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+GAMPL
+SAS/STAT User’s Guide
+GAMSELECT *Available starting with SAS Viya 3.5.
+SAS Visual Statistics: Procedures
+GANNO
+SAS/GRAPH: Reference
+GANTT
+SAS/OR User’s Guide: Project Management
+GAREABAR
+SAS/GRAPH: Reference
+GBARLINE
+SAS/GRAPH: Reference
+GCHART
+SAS/GRAPH: Reference
+GCONTOUR
+SAS/GRAPH: Reference
+GDEVICE
+SAS/GRAPH: Reference
+GEE
+SAS/STAT User’s Guide
+GENSELECT
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+GENMOD
+SAS/STAT User’s Guide
+GEOCODE
+SAS/GRAPH and Base SAS: Mapping Reference
+GFONT
+SAS/GRAPH: Reference
+GINSIDE
+SAS/GRAPH and Base SAS: Mapping Reference
+GIS
+SAS/GIS: Spatial Data and Procedure Guide
+GKPI
+SAS/GRAPH: Reference
+GLIMMIX
+SAS/STAT User’s Guide
+GLM
+SAS/STAT User’s Guide
+GLMMOD
+SAS/STAT User’s Guide
+GLMPOWER
+SAS/STAT User’s Guide
+GLMSELECT
+SAS/STAT User’s Guide
+GMAP
+SAS/GRAPH and Base SAS: Mapping Reference
+GMM *Available starting with SAS Viya 3.4.
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+GOPTIONS
+SAS/GRAPH: Reference
+GPLOT
+SAS/GRAPH: Reference
+GPROJECT
+SAS/GRAPH and Base SAS: Mapping Reference
+GRADAR
+SAS/GRAPH: Reference
+GRADBOOST
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+GREDUCE
+SAS/GRAPH and Base SAS: Mapping Reference
+GREMOVE
+SAS/GRAPH: Reference
+GREPLAY
+SAS/GRAPH: Reference
+GROOVY
+Base SAS Procedures Guide
+GSLIDE
+SAS/GRAPH: Reference
+GTILE
+SAS/GRAPH: Reference
+GVARCLUS
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+H
+Procedure
+Location of Procedure Documentation
+HADOOP
+Base SAS Procedures Guide
+HDMD
+Base SAS Procedures Guide
+HMM
+SAS Econometrics: Econometrics Procedures
+HP4SCORE
+SAS Enterprise Miner: High-Performance Procedures
+HPBIN
+Base Procedures Guide: High-Performance Procedures
+HPBNET
+SAS Enterprise Miner: High-Performance Procedures
+HPBOOLRULE
+SAS Text Miner: High-Performance Procedures
+HPCANDISC
+SAS/STAT User's Guide: High-Performance Procedures
+HPCDM
+SAS/ETS User's Guide: High-Performance Procedures
+HPCLUS
+SAS Enterprise Miner: High-Performance Procedures
+HPCOPULA
+SAS/ETS User's Guide: High-Performance Procedures
+HPCORR
+Base Procedures Guide: High-Performance Procedures
+HPCOUNTREG
+SAS/ETS User's Guide: High-Performance Procedures
+HPDECIDE
+SAS Enterprise Miner: High-Performance Procedures
+HPDMDB
+Base Procedures Guide: High-Performance Procedures
+HPDS2
+Base Procedures Guide: High-Performance Procedures
+HPEXPORT
+See SAS Risk Dimensions and SAS High-Performance Risk: Procedures Guide
+HPF
+SAS Forecast Server Procedures: User's Guide
+HPFARIMASPEC
+SAS Forecast Server Procedures: User's Guide
+HPFDIAGNOSE
+SAS Forecast Server Procedures: User's Guide
+HPFENGINE
+SAS Forecast Server Procedures: User's Guide
+HPFESMSPEC
+SAS Forecast Server Procedures: User's Guide
+HPFEVENTS
+SAS Forecast Server Procedures: User's Guide
+HPFEXMSPEC
+SAS Forecast Server Procedures: User's Guide
+HPFIDMSPEC
+SAS Forecast Server Procedures: User's Guide
+HPFMM
+SAS/STAT User's Guide: High-Performance Procedures
+HPFOREST
+SAS Enterprise Miner: High-Performance Procedures
+HPFRECONCILE
+SAS Forecast Server Procedures: User's Guide
+HPFREPOSITORY (Experimental)
+SAS Forecast Server Procedures: User's Guide
+HPFSELECT
+SAS Forecast Server Procedures: User's Guide
+HPFTEMPRECON
+SAS Forecast Server Procedures: User's Guide
+HPFUCMSPEC
+SAS Forecast Server Procedures: User's Guide
+HPGENSELECT
+SAS/STAT User's Guide: High-Performance Procedures
+HPIMPUTE
+Base Procedures Guide: High-Performance Procedures
+HPLMIXED
+SAS/STAT User's Guide: High-Performance Procedures
+HPLOGISTIC
+SAS/STAT User's Guide: High-Performance Procedures
+HPMIXED
+SAS/STAT: User’s Guide
+HPNEURAL
+SAS Enterprise Miner: High-Performance Procedures
+HPNLMOD
+SAS/STAT User's Guide: High-Performance Procedures
+HPPANEL
+SAS/ETS User's Guide: High-Performance Procedures
+HPPLS
+SAS/STAT User's Guide: High-Performance Procedures
+HPPRINCOMP
+SAS/STAT User's Guide: High-Performance Procedures
+HPQUANTSELECT
+SAS/STAT User's Guide: High-Performance Procedures
+HPQLIM
+SAS/ETS User's Guide: High-Performance Procedures
+HPREDUCE
+SAS Enterprise Miner: High-Performance Procedures
+HPREG
+SAS/STAT User's Guide: High-Performance Procedures
+HPRISK
+See SAS Risk Dimensions and SAS High-Performance Risk: Procedures Guide
+HPSAMPLE
+Base Procedures Guide: High-Performance Procedures
+HPSEVERITY
+SAS/ETS User's Guide: High-Performance Procedures
+HPSPLIT
+SAS/STAT User's Guide: High-Performance Procedures
+HPSUMMARY
+Base Procedures Guide: High-Performance Procedures
+HPSVM
+SAS Enterprise Miner: High-Performance Procedures
+HPTMINE
+SAS Text Miner: High-Performance Procedures
+HPTMSCORE
+SAS Text Miner: High-Performance Procedures
+HTTP
+Base SAS Procedures Guide
+I
+Procedure
+Location of Procedure Documentation
+ICA *Available starting with SAS Viya 3.4.
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+ICLIFETEST
+SAS/STAT User’s Guide
+ICPHREG
+SAS/STAT User’s Guide
+IML
+SAS/IML User’s Guide
+IMPORT
+Base SAS Procedures Guide
+IMPORT for PC Files
+SAS/ACCESS Interface to PC Files: Reference
+IMSTAT (Analytics)
+SAS LASR Analytic Server: Reference Guide
+IMSTAT (Data and Server Management)
+SAS LASR Analytic Server: Reference Guide
+IMXFER
+SAS LASR Analytic Server: Reference Guide
+INBREED
+SAS/STAT User’s Guide
+INFOMAPS
+Base SAS Guide to Information Maps
+IOMOPERATE
+SAS Intelligence Platform: Application Server Administration Guide
+IRT
+SAS/STAT User’s Guide
+ISHIKAWA
+SAS/QC User’s Guide
+ITEMS
+SAS Companion for z/OS
+J
+Procedure
+Location of Procedure Documentation
+JAVAINFO
+Base SAS Procedures Guide
+JSON
+Base SAS Procedures Guide
+K
+Procedure
+Location of Procedure Documentation
+KCLUS
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+KDE
+SAS/STAT User’s Guide
+KPCA *Available starting with SAS Viya 3.5.
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+KRIGE2D
+SAS/STAT User’s Guide
+L
+Procedure
+Location of Procedure Documentation
+LASR
+SAS LASR Analytic Server: Reference Guide
+LATTICE
+SAS/STAT User’s Guide
+LIFEREG
+SAS/STAT User’s Guide
+LIFETEST
+SAS/STAT User’s Guide
+LMIXED *Available starting with SAS Viya 3.4.
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+LOAN
+SAS/ETS User’s Guide
+LOCALEDATA
+SAS National Language Support (NLS): Reference Guide
+LOESS
+SAS/STAT User’s Guide
+LOGISTIC
+SAS/STAT User’s Guide
+LOGSELECT
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+LUA
+Base SAS Procedures Guide
+M
+Procedure
+Location of Procedure Documentation
+MACONTROL
+SAS/QC User’s Guide
+MAPIMPORT
+SAS/GRAPH and Base SAS: Mapping Reference
+MBANALYSIS
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+MBC *Available starting with SAS Viya 3.4.
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+MCMC
+SAS/STAT User’s Guide
+MDC
+SAS/ETS User’s Guide
+MDDB
+See SAS/MDDB Server Help in SAS Help and Documentation
+MDS
+SAS/STAT User’s Guide
+MDSUMMARY
+SAS Cloud Analytic Services: User’s Guide
+MEANS
+Base SAS Procedures Guide
+METADATA
+SAS Language Interfaces to Metadata
+METALIB
+SAS Language Interfaces to Metadata
+METAOPERATE
+SAS Language Interfaces to Metadata
+MI
+SAS/STAT User’s Guide
+MIANALYZE
+SAS/STAT User’s Guide
+MIGRATE
+Base SAS Procedures Guide
+MIXED
+SAS/STAT User’s Guide
+MODECLUS
+SAS/STAT User’s Guide
+MODEL
+SAS/ETS User’s Guide
+MODELMATRIX *Available starting with SAS Viya 3.4.
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+MTLEARN *Available starting with SAS Viya 3.4.
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+MULTTEST
+SAS/STAT User’s Guide
+MVPDIAGNOSE
+SAS/QC User’s Guide
+MVPMODEL
+SAS/QC User’s Guide
+MVPMONITOR
+SAS/QC User’s Guide
+MWPCA
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+N
+Procedure
+Location of Procedure Documentation
+NESTED
+SAS/STAT User’s Guide
+NETDRAW
+SAS/OR User’s Guide: Project Management
+NETWORK
+SAS Visual Data Mining and Machine Learning: The NETWORK Procedure
+NLIN
+SAS/STAT User’s Guide
+NLMIXED
+SAS/STAT User’s Guide
+NLMOD
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+NMF *Available starting with SAS Viya 3.5.
+SAS Visual Statistics: Procedures
+NNET
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+NPAR1WAY
+SAS/STAT User’s Guide
+O
+Procedure
+Location of Procedure Documentation
+ODSLIST
+SAS Output Delivery System: Procedures Guide
+ODSTABLE
+SAS Output Delivery System: Procedures Guide
+ODSTEXT
+SAS Output Delivery System: Procedures Guide
+OLAP
+SAS OLAP Server: User’s Guide
+OLAPCONTENTS
+SAS OLAP Server: User’s Guide
+OLAPOPERATE
+SAS OLAP Server: User’s Guide
+OPERATE
+SAS/SHARE User’s Guide
+OPTEX
+SAS/QC User’s Guide
+OPTGRAPH
+SAS OPTGRAPH Procedure : Graph Algorithms and Network Analysis
+OPTIONS
+Base SAS Procedures Guide
+OPTIONS for UNIX
+SAS Companion for UNIX Environments
+OPTIONS for Windows
+SAS Companion for Windows
+OPTIONS for z/OS
+SAS Companion for z/OS
+OPTLOAD
+Base SAS Procedures Guide
+OPTLP
+SAS Optimization: Mathematical Optimization Procedures
+OPTLP
+SAS/OR User’s Guide: Mathematical Programming
+OPTLSO
+SAS/OR User’s Guide: Local Search Optimization
+OPTMILP
+SAS Optimization: Mathematical Optimization Procedures
+OPTMILP
+SAS/OR User’s Guide: Mathematical Programming
+OPTMODEL
+SAS Optimization: Mathematical Optimization Procedures
+OPTMODEL
+SAS/OR User’s Guide: Mathematical Programming
+OPTNET
+SAS/OR User’s Guide: Network Optimization Algorithms
+OPTNETWORK
+SAS Optimization: Network Optimization Procedures
+OPTQP
+SAS Optimization: Mathematical Optimization Procedures
+OPTQP
+SAS/OR User’s Guide: Mathematical Programming
+OPTSAVE
+Base SAS Procedures Guide
+ORTHOREG
+SAS/STAT User’s Guide
+P
+Procedure
+Location of Procedure Documentation
+PANEL
+SAS/ETS User’s Guide
+PARETO
+SAS/QC User’s Guide
+PARTITION
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+PCA
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+PDLREG
+SAS/ETS User’s Guide
+PDS Procedure for z/OS
+SAS Companion for z/OS
+PDSCOPY
+SAS Companion for z/OS
+PHREG
+SAS/STAT User’s Guide
+PHSELECT
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+PLAN
+SAS/STAT User’s Guide
+PLM
+SAS/STAT User’s Guide
+PLOT
+Base SAS Procedures Guide
+PLS
+SAS/STAT User’s Guide
+PLSMOD
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+PM
+SAS/OR User’s Guide: Project Management
+PMENU
+Base SAS Procedures Guide
+PMENU for UNIX
+SAS Companion for UNIX Environments
+PMENU for Windows
+SAS Companion for Windows
+PMENU for z/OS
+SAS Companion for z/OS
+POWER
+SAS/STAT User’s Guide
+PRESENV
+Base SAS Procedures Guide
+PRINCOMP
+SAS/STAT User’s Guide
+PRINQUAL
+SAS/STAT User’s Guide
+PRINT
+Base SAS Procedures Guide
+PRINT for z/OS
+SAS Companion for z/OS
+PRINTTO
+Base SAS Procedures Guide
+PRINTTO for UNIX
+SAS Companion for UNIX Environments
+PRINTTO for Windows
+SAS Companion for Windows
+PRINTTO for z/OS
+SAS Companion for z/OS
+PROBIT
+SAS/STAT User’s Guide
+PRODUCT_STATUS
+Base SAS Procedures Guide
+PROTO
+Base SAS Procedures Guide
+PRTDEF
+Base SAS Procedures Guide
+PRTEXP
+Base SAS Procedures Guide
+PSMATCH
+SAS/STAT User’s Guide
+PWENCODE
+Base SAS Procedures Guide
+Q
+Procedure
+Location of Procedure Documentation
+QDEVICE
+Base SAS Procedures Guide
+QLIM
+SAS/ETS User’s Guide
+QTRSELECT
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+QUANTLIFE
+SAS/STAT User’s Guide
+QUANTREG
+SAS/STAT User’s Guide
+QUANTSELECT
+SAS/STAT User’s Guide
+QUEST for SYSTEM 2000 (z/OS only)
+SAS/ACCESS Interface to SYSTEM 2000: Reference
+R
+Procedure
+Location of Procedure Documentation
+RANK
+Base SAS Procedures Guide
+RAREEVENTS
+SAS/QC User’s Guide
+RDC
+SAS Risk Dimensions and SAS High-Performance Risk: Procedures Guide
+RDPOOL
+SAS Risk Dimensions and SAS High-Performance Risk: Procedures Guide
+RDSEC
+SAS Risk Dimensions and SAS High-Performance Risk: Procedures Guide
+RECOMMEND
+SAS LASR Analytic Server: Reference Guide
+REG
+SAS/STAT User’s Guide
+REGSELECT
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+REGISTRY
+Base SAS Procedures Guide
+RELEASE
+SAS Companion for z/OS
+RELIABILITY
+SAS/QC User’s Guide
+REPORT
+Base SAS Procedures Guide
+RISK
+SAS Risk Dimensions and SAS High-Performance Risk: Procedures Guide
+RMSTREG
+SAS/STAT User’s Guide
+ROBUSTREG
+SAS/STAT User’s Guide
+RPCA
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+RSREG
+SAS/STAT User’s Guide
+S
+Procedure
+Location of Procedure Documentation
+S3
+Base SAS Procedures Guide
+SANDWICH *Available starting with SAS Viya 3.5.
+SAS Visual Statistics: Procedures
+SCAPROC
+Base SAS Procedures Guide
+SCORE
+SAS/STAT User’s Guide
+SCOREACCEL
+Base SAS Procedures Guide
+SEMISUPLEARN *Available starting with SAS Viya 3.4.
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+SEQDESIGN
+SAS/STAT User’s Guide
+SEQTEST
+SAS/STAT User’s Guide
+SERVER
+SAS/SHARE User’s Guide
+SEVERITY
+SAS/ETS User’s Guide
+SEVSELECT
+SAS Econometrics: Econometrics Procedures
+SGDESIGN
+SAS ODS Graphics: Procedures Guide
+SGMAP
+SAS/GRAPH and Base SAS: Mapping Reference
+SGPANEL
+SAS ODS Graphics: Procedures Guide
+SGPIE
+SAS ODS Graphics: Procedures Guide
+SGPLOT
+SAS ODS Graphics: Procedures Guide
+SGRENDER
+SAS ODS Graphics: Procedures Guide
+SGSCATTER
+SAS ODS Graphics: Procedures Guide
+SHEWHART
+SAS/QC User’s Guide
+SIM2D
+SAS/STAT User’s Guide
+SIMILARITY
+SAS/ETS User’s Guide
+SIMLIN
+SAS/ETS User’s Guide
+SIMNORMAL
+SAS/STAT User’s Guide
+SIMSYSTEM *Available starting with SAS Viya 3.5.
+SAS Visual Statistics: Procedures
+SMCALIB *Available starting with SAS Viya 3.4.
+SAS Visual Forecasting: Forecasting Procedures
+SMPROJECT *Available starting with SAS Viya 3.4.
+SAS Visual Forecasting: Forecasting Procedures
+SMSCORE *Available starting with SAS Viya 3.4.
+SAS Visual Forecasting: Forecasting Procedures
+SMSELECT *Available starting with SAS Viya 3.4.
+SAS Visual Forecasting: Forecasting Procedures
+SMSPEC *Available starting with SAS Viya 3.4.
+SAS Visual Forecasting: Forecasting Procedures
+SOAP
+Base SAS Procedures Guide
+SORT
+Base SAS Procedures Guide
+SORT for UNIX
+SAS Companion for UNIX Environments
+SORT for Windows
+SAS Companion for Windows
+SORT for z/OS
+SAS Companion for z/OS
+SOURCE
+SAS Companion for z/OS
+SPARSEML *Available starting with SAS Viya 3.5.
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+SPATIALREG
+SAS/ETS User’s Guide
+SPC
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+SPDO *Available starting with SAS 9.4 when SPD Server SAS client software is installed and in SAS Viya 3.4 and later.
+SAS Scalable Performance Data Server: Administrator’s Guide
+SPECTRA
+SAS/ETS User’s Guide
+SPP
+SAS/STAT User’s Guide
+SQL
+SAS SQL Procedure User’s Guide
+SQOOP
+Base SAS Procedures Guide
+SSM
+SAS/ETS User’s Guide
+STANDARD
+Base SAS Procedures Guide
+STATESPACE
+SAS/ETS User’s Guide
+STDIZE
+SAS/STAT User’s Guide
+STDRATE
+SAS/STAT User’s Guide
+STEPDISC
+SAS/STAT User’s Guide
+STP
+SAS Stored Processes: Developer’s Guide
+STREAM
+Base SAS Procedures Guide
+SUMMARY
+Base SAS Procedures Guide
+SURVEYFREQ
+SAS/STAT User’s Guide
+SURVEYIMPUTE
+SAS/STAT User’s Guide
+SURVEYLOGISTIC
+SAS/STAT User’s Guide
+SURVEYMEANS
+SAS/STAT User’s Guide
+SURVEYPHREG
+SAS/STAT User’s Guide
+SURVEYREG
+SAS/STAT User’s Guide
+SURVEYSELECT
+SAS/STAT User’s Guide
+SVDD
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+SVMACHINE
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+SYSLIN
+SAS/ETS User’s Guide
+T
+Procedure
+Location of Procedure Documentation
+TABULATE
+Base SAS Procedures Guide
+TAPECOPY
+SAS Companion for z/OS
+TAPELABEL
+SAS Companion for z/OS
+TEMPLATE: Crosstabulation Templates
+SAS Output Delivery System: Procedures Guide
+TEMPLATE: Managing Template Stores
+SAS Output Delivery System: Procedures Guide
+TEMPLATE: ODS Graphics
+SAS Output Delivery System: Procedures Guide
+TEMPLATE: Style Templates
+SAS Output Delivery System: Procedures Guide
+TEMPLATE: Tabular Templates
+SAS Output Delivery System: Procedures Guide
+TEMPLATE: Tagsets
+SAS Output Delivery System: Procedures Guide
+TEXTMINE
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+TIMEDATA
+SAS/ETS User’s Guide
+TIMEID
+SAS/ETS User’s Guide
+TIMEPLOT
+Base SAS Procedures Guide
+TIMESERIES
+SAS/ETS User’s Guide
+TMODEL
+SAS/ETS User’s Guide
+TMSCORE
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+TPSPLINE
+SAS/STAT User’s Guide
+TRANSPOSE
+Base SAS Procedures Guide
+TRANSREG
+SAS/STAT User’s Guide
+TRANTAB
+SAS National Language Support (NLS): Reference Guide
+TREE
+SAS/STAT User’s Guide
+TREESPLIT
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+TSCSREG
+SAS/ETS User’s Guide
+TSINFO *Available starting with SAS Viya 3.5.
+SAS Econometrics: Econometrics Procedures
+TSINFO
+SAS Visual Forecasting: Forecasting Procedures
+TSMODEL
+SAS Econometrics: Econometrics Procedures
+TSMODEL
+SAS Visual Forecasting: Forecasting Procedures
+TSNE *Available starting with SAS Viya 3.4.
+SAS Visual Data Mining and Machine Learning: Procedures Guide
+TSRECONCILE
+SAS Visual Forecasting: Forecasting Procedures
+TTEST
+SAS/STAT User’s Guide
+U
+Procedure
+Location of Procedure Documentation
+UCM
+SAS/ETS User’s Guide
+UNIVARIATE
+Base SAS Procedure’s Guide: Statistical Procedures
+UPLOAD
+SAS/CONNECT User’s Guide
+UPLOAD
+SAS/CONNECT for SAS Viya: User’s Guide
+V
+Procedure
+Location of Procedure Documentation
+VARCLUS
+SAS/STAT User’s Guide
+VARCOMP
+SAS/STAT User’s Guide
+VARIMPUTE
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+VARIOGRAM
+SAS/STAT User’s Guide
+VARMAX
+SAS/ETS User’s Guide
+VARREDUCE
+SAS Visual Data Mining and Machine Learning: Statistical Procedures
+VASMP
+SAS LASR Analytic Server: Reference Guide
+X
+Procedure
+Location of Procedure Documentation
+X11
+SAS/ETS User’s Guide
+X12
+SAS/ETS User’s Guide
+X13
+SAS/ETS User’s Guide
+XSL
diff --git a/elpa/ess-20260424.1544/etc/ess-julia.jl b/elpa/ess-20260424.1544/etc/ess-julia.jl
new file mode 100644 (file)
index 0000000..efa1ce0
--- /dev/null
@@ -0,0 +1,126 @@
+module ESS
+
+# These methods have been deprecated / moved
+macro current_module()
+    return VERSION >= v"0.7-" ? :(@__MODULE__) : :(current_module())
+end
+
+parse = VERSION >= v"0.7-" ? Base.Meta.parse : Base.parse
+function_module = VERSION >= v"0.7-" ? Base.parentmodule : Base.function_module
+
+function all_help_topics()
+    ## There are not clear topics anymore. Approximate those with a very general
+    ## apropos(" ")
+    Base.Docs.apropos(" ")
+end 
+
+function help(topic::AbstractString)
+    if (VERSION >= v"1.0-")
+        Core.eval(parentmodule(ESS), parse("@doc $topic"))
+    elseif  (VERSION >= v"0.4-")
+        Core.eval(@current_module(), parse("@doc $topic"))
+    else
+        Base.Help.help(topic)
+    end
+end    
+
+## modified version of function show(io::IO, m::Method)
+function fun_args(m::Method)
+    tv, decls, file, line = Base.arg_decl_parts(m)
+    io = VERSION >= v"0.7-" ? Base.stdout : STDOUT::IO # STDOUT is no longer in 1.0
+    if !isempty(tv)
+        Base.show_delim_array(io, tv, '{', ',', '}', false)
+    end
+    print(io, "(")
+    join(io, [escape_string(isempty(d[2]) ? d[1] : d[1]*"::"*d[2]) for d in decls],
+         ",", ",")    
+    Base.print(io, ")")
+end 
+
+## modified versionof show(io::IO, mt::MethodTable)
+function fun_args(f::Function)
+    mt = Base.MethodList(methods(f).mt)
+    mod = function_module(f)   # Base.function_module deprecated in 0.7
+    if mod == Main
+        mod = "nil"
+    end 
+    print("(list \"$mod\" nil '(")
+    for d in mt
+        print("\"")
+        ## method
+        fun_args(d)
+        print("\" ")
+    end
+    print("))")
+end
+
+function fun_args(s::AbstractString)
+    try
+        mod = VERSION >= v"1.0-" ?  parentmodule(ESS) : @current_module()
+        m = Core.eval(mod, parse(s))
+        if ! isa(m, String)
+            fun_args(m)
+        end
+    catch
+        print("(list nil nil nil)")
+    end
+end 
+
+function fun_args(t::DataType)
+    print("(list nil nil '(")
+    for d = fieldnames(t)
+        print("\"$d\" ")
+    end
+    print("))")
+end 
+
+\f
+### OBJECT COMPLETION
+# Must print an output of the form:
+# 
+# Cache                         Module
+# Write                         Module
+# add                           Function
+# free                          Function
+function components(m::Module)
+    for v in sort(names(m, all=true, imported=true))
+        s = string(v)
+        if !startswith(s, "#") && isdefined(m,v)
+            println(rpad(s, 30), summary(Core.eval(m,v)))
+        end
+    end
+end
+
+function components(t::DataType)
+    for v in sort(fieldnames(t))
+        println(rpad(string(v), 30), "field")
+    end
+end
+
+function components(v)
+    t = typeof(v)
+    if isa(t, DataType)
+        return components(t)
+    end
+end
+
+\f
+### MISC
+function main_modules(m::Module)
+    for nm in names(m)
+        if isdefined(m, nm)
+            mod = Core.eval(m, nm)
+            if isa(mod, Module)
+                print("\"$nm\" ")
+            end
+        end
+    end
+end
+
+if VERSION >= v"0.7-"
+    main_modules() = main_modules(Base.parentmodule(@current_module()))
+else
+    main_modules() = main_modules(@current_module())
+end
+
+end 
diff --git a/elpa/ess-20260424.1544/etc/ess-sas-sh-command b/elpa/ess-20260424.1544/etc/ess-sas-sh-command
new file mode 100755 (executable)
index 0000000..7c1d910
--- /dev/null
@@ -0,0 +1,76 @@
+#!/bin/sh
+
+### (C) 1997, Richard M. Heiberger.
+### 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/
+
+
+# For executing SAS, and running it in the proper manner for ESS
+# (feeding output back into appropriate ESS buffers).
+
+#echo $0 $@
+#sas </dev/tty 1>$1 2>$2 $3
+
+set -x
+stdout=$1
+stderr=$2
+shift 2
+set +x
+echo sas \</dev/tty 1\>$stdout 2\>$stderr $@
+sas </dev/tty 1>$stdout 2>$stderr $@
+
+## From the SAS online tech support:
+##
+## Redirecting the SAS Log and Output under UNIX. 
+## 
+## There are several ways of redirecting the SAS Log and Output under
+## UNIX.  
+## 
+## To redirect the SAS Log, follow one of these steps: 
+## 
+##    1.
+##          In the source code, place the following line: 
+## 
+##          proc printto log=stdout;
+## 
+##          to make a duplicate copy of the log in a file in addition
+##          to redirecting it to stdout, use this command to invoke
+##          SAS:  
+## 
+##          sas -altlog doit.log doit.sas
+## 
+##    2.Execute SAS in the background and use the UNIX 'tail' command
+##      to copy lines to stdout as they are added to the log. Use the 
+##      command: 
+## 
+##      sas doit.sas &; tail -f doit.log
+## 
+## To redirect the SAS Log and Output under the Korn shell, use the
+## following command:  
+## 
+## sas -stdio < doit.sas > doit.lst 2> doit.log
+## 
+## To redirect the SAS Log and Output under the C-Shell, use the
+## following command:   
+## 
+## (sas -stdio < doit.sas > doit.lst) >& doit.log
+
+## From WWW.SAS.COM:
+## How can I make SAS in batch mode behave like interactive SAS,
+## continue running my SAS job, and not enter syntax check mode when
+## it encounters an error?
+##
+## You can specify the NOSYNTAXCHECK option when you invoke your SAS
+## program.
diff --git a/elpa/ess-20260424.1544/etc/func.sas b/elpa/ess-20260424.1544/etc/func.sas
new file mode 100644 (file)
index 0000000..78d9e1e
--- /dev/null
@@ -0,0 +1,80 @@
+
+
+proc freq order=freq data=sashelp.vfunc;
+    tables source fnctype fncprod;
+run;
+
+/*
+title 'FNCPROD=B';
+proc print data=sashelp.vfunc;
+    where fncname>' ' & FNCPROD='B';
+run;
+
+title 'FNCPROD=X';
+proc print data=sashelp.vfunc;
+    where fncname>' ' & FNCPROD='X';
+run;
+
+title 'FNCPROD=T';
+proc print data=sashelp.vfunc;
+    where fncname>' ' & FNCPROD='T';
+run;
+
+title 'FNCPROD=I';
+proc print data=sashelp.vfunc;
+    where fncname>' ' & FNCPROD='I';
+run;
+
+    endsas;
+*/
+
+data vfunc;
+    set sashelp.vfunc end=last;
+    by fncname;
+    where fncname>' ' & (fncprod='X' | source=fncprod='B');
+    file "func.txt";
+
+    if _n_=1 then do;
+        put ";; SAS functions found in sashelp.vfunc where fncprod='X' | source=fncprod='B'";
+    end;
+    
+    if last.fncname;
+    
+    fncname=lowcase(fncname);
+
+    retain alpha 'abcdefghijklmnopqrstuvwxyz' prev 1;
+    
+    format fncname $quote32.;
+
+    i=indexc(alpha, substr(fncname, 1, 1));
+
+    if i>prev then do; 
+        prev=i;
+        put;
+    end;
+    
+    put fncname @;
+
+    if last then put;
+run;
+
+data vfunc;
+    set sashelp.vfunc end=last;
+    by fncname;
+    if last.fncname;
+
+    where fncname>' ' & (fncprod='X' | source=fncprod='B');
+    file "check-func.sas";
+
+    fncname=trim(lowcase(fncname))||'();';
+
+    put fncname;
+run;
+
+proc contents varnum;
+run;
+
+proc print;
+    var fncname;
+    format fncname $quote32.;
+run;
diff --git a/elpa/ess-20260424.1544/etc/proc.sas b/elpa/ess-20260424.1544/etc/proc.sas
new file mode 100644 (file)
index 0000000..dc2a2de
--- /dev/null
@@ -0,0 +1,80 @@
+
+/*
+all.txt scraped from
+<https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/allprodsproc/procedures.htm>;
+*/
+
+data proc;
+    length name $ 20;
+    infile 'all.txt';
+   
+    input name;
+
+    if length(name)>1 & name^='SAS';
+
+    if verify(name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ')=0;
+
+    name=lowcase(name);
+run;
+
+proc sort nodupkey data=proc;
+    by name;
+run;
+
+data proc;
+    set proc;
+    by name;
+*these PROCs are not present on my system: YMMV;
+*if it starts with HP, then it requires the high-performance products;
+    *where name not in:(
+        'aggregation', 'appsrv', 
+        'compile', 
+        'db2ext', 'db2util', 'dmsrvadm', 'dmsrvdatasvc', 'dmsrvprocesssvc',
+        'dqloclst', 'dqmatch', 'dqscheme', 
+        'gis', 
+        'hp',
+        'imstat', 'imxfer', 'items',
+        'lasr', 
+        'mddb', 
+        'optgraph',
+        'pds', 'pdscopy',
+        'quest', 
+        'rdc', 'rdpool', 'rdsec', 'recommend', 'release', 'risk',
+        'source',
+        'tapecopy', 'tapelabel',
+        'vasmp'
+        );
+run;
+
+proc print; 
+run;
+
+data proc;
+    set proc end=last;
+
+    file "proc.txt";
+
+    retain alpha 'abcdefghijklmnopqrstuvwxyz' prev 1;
+    
+    format name $quote32.;
+
+    i=indexc(alpha, substr(name, 1, 1));
+
+    if i>prev then do; 
+        prev=i;
+        put;
+    end;
+    
+    put name @;
+
+    if last then put;
+run;
+
+data proc;
+length name $ 35;
+    set proc end=last;
+format name;
+    file "check-proc.sas";
+    name='proc '||trim(name)||';run;quit;';
+    put name;
+run;
diff --git a/elpa/ess-20260424.1544/etc/proc.txt b/elpa/ess-20260424.1544/etc/proc.txt
new file mode 100644 (file)
index 0000000..9df1543
--- /dev/null
@@ -0,0 +1,23 @@
+"access" "aceclus" "adaptivereg" "aggregation" "anom" "anova" "append" "appsrv" "arima" "assess" "astore" "authlib" "autoreg"
+"bchoice" "bglimm" "binning" "bnet" "bom" "boolrule" "boxplot" "build"
+"calendar" "calis" "callrfc" "cancorr" "candisc" "capability" "cardinality" "carima" "cas" "casutil" "catalog" "catmod" "causalgraph" "causalmed" "causaltrt" "ccdm" "ccopula" "cesm" "chart" "cimport" "clp" "cluster" "cntselect" "compare" "compile" "computab" "contents" "convert" "copula" "copy" "corr" "correlation" "corresp" "countreg" "cpanel" "cpm" "cport" "cqlim" "cspatialreg" "cusum" "cv2view"
+"datasets" "datasource" "datekeys" "db2ext" "db2util" "dbcstab" "dbf" "dbload" "delete" "dfil" "dif" "discrim" "display" "distance" "dmsrvadm" "dmsrvdatasvc" "dmsrvprocesssvc" "document" "download" "dqloclst" "dqmatch" "dqscheme" "ds2" "dstods2" "dtree"
+"ecm" "entropy" "esm" "expand" "explode" "export"
+"factex" "factmac" "factor" "fastclus" "fastknn" "fcmp" "fedsql" "fism" "fmm" "fmtc2itm" "fontreg" "forest" "format" "forms" "freq" "freqtab" "fsbrowse" "fsedit" "fsletter" "fslist" "fsview"
+"g3d" "g3grid" "ga" "gam" "gammod" "gampl" "gamselect" "ganno" "gantt" "gareabar" "gbarline" "gchart" "gcontour" "gdevice" "gee" "genmod" "genselect" "geocode" "gfont" "ginside" "gis" "gkpi" "glimmix" "glm" "glmmod" "glmpower" "glmselect" "gmap" "gmm" "goptions" "gplot" "gproject" "gradar" "gradboost" "greduce" "gremove" "greplay" "groovy" "gslide" "gtile" "gvarclus"
+"hadoop" "hdmd" "hmm" "hp4score" "hpbin" "hpbnet" "hpboolrule" "hpcandisc" "hpcdm" "hpclus" "hpcopula" "hpcorr" "hpcountreg" "hpdecide" "hpdmdb" "hpds2" "hpexport" "hpf" "hpfarimaspec" "hpfdiagnose" "hpfengine" "hpfesmspec" "hpfevents" "hpfexmspec" "hpfidmspec" "hpfmm" "hpforest" "hpfreconcile" "hpfrepository" "hpfselect" "hpftemprecon" "hpfucmspec" "hpgenselect" "hpimpute" "hplmixed" "hplogistic" "hpmixed" "hpneural" "hpnlmod" "hppanel" "hppls" "hpprincomp" "hpqlim" "hpquantselect" "hpreduce" "hpreg" "hprisk" "hpsample" "hpseverity" "hpsplit" "hpsummary" "hpsvm" "hptmine" "hptmscore" "http"
+"ica" "iclifetest" "icphreg" "iml" "import" "imstat" "imxfer" "inbreed" "infomaps" "iomoperate" "irt" "ishikawa" "items"
+"javainfo" "json"
+"kclus" "kde" "kpca" "krige2d"
+"lasr" "lattice" "lifereg" "lifetest" "lmixed" "loan" "localedata" "loess" "logistic" "logselect" "lua"
+"macontrol" "mapimport" "mbanalysis" "mbc" "mcmc" "mdc" "mddb" "mds" "mdsummary" "means" "metadata" "metalib" "metaoperate" "mi" "mianalyze" "migrate" "mixed" "modeclus" "model" "modelmatrix" "mtlearn" "multtest" "mvpdiagnose" "mvpmodel" "mvpmonitor" "mwpca"
+"nested" "netdraw" "network" "nlin" "nlmixed" "nlmod" "nmf" "nnet" "npar1way"
+"odslist" "odstable" "odstext" "olap" "olapcontents" "olapoperate" "operate" "optex" "optgraph" "options" "optload" "optlp" "optlso" "optmilp" "optmodel" "optnet" "optnetwork" "optqp" "optsave" "orthoreg"
+"panel" "pareto" "partition" "pca" "pdlreg" "pds" "pdscopy" "phreg" "phselect" "plan" "plm" "plot" "pls" "plsmod" "pm" "pmenu" "power" "presenv" "princomp" "prinqual" "print" "printto" "probit" "proto" "prtdef" "prtexp" "psmatch" "pwencode"
+"qdevice" "qlim" "qtrselect" "quantlife" "quantreg" "quantselect" "quest"
+"rank" "rareevents" "rdc" "rdpool" "rdsec" "recommend" "reg" "registry" "regselect" "release" "reliability" "report" "risk" "rmstreg" "robustreg" "rpca" "rsreg"
+"s3" "sandwich" "scaproc" "score" "scoreaccel" "semisuplearn" "seqdesign" "seqtest" "server" "severity" "sevselect" "sgdesign" "sgmap" "sgpanel" "sgpie" "sgplot" "sgrender" "sgscatter" "shewhart" "sim2d" "similarity" "simlin" "simnormal" "simsystem" "smcalib" "smproject" "smscore" "smselect" "smspec" "soap" "sort" "source" "sparseml" "spatialreg" "spc" "spdo" "spectra" "spp" "sql" "sqoop" "ssm" "standard" "statespace" "stdize" "stdrate" "stepdisc" "stp" "stream" "summary" "surveyfreq" "surveyimpute" "surveylogistic" "surveymeans" "surveyphreg" "surveyreg" "surveyselect" "svdd" "svmachine" "syslin"
+"tabulate" "tapecopy" "tapelabel" "textmine" "timedata" "timeid" "timeplot" "timeseries" "tmodel" "tmscore" "tpspline" "transpose" "transreg" "trantab" "tree" "treesplit" "tscsreg" "tsinfo" "tsmodel" "tsne" "tsreconcile" "ttest"
+"ucm" "univariate" "upload"
+"varclus" "varcomp" "varimpute" "variogram" "varmax" "varreduce" "vasmp"
+"x11" "x12" "x13" "xsl"
diff --git a/elpa/ess-20260424.1544/obsolete/ess-eldoc.el b/elpa/ess-20260424.1544/obsolete/ess-eldoc.el
new file mode 100644 (file)
index 0000000..59f0c46
--- /dev/null
@@ -0,0 +1,173 @@
+;;; ess-eldoc.el --- Use eldoc to report R function names.  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1997-2022 Free Software Foundation, Inc.
+;; Author: Stephen Eglen
+;; Created: 2007-06-30
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;;;;; eldoc functionality has been moved into the core ;;;;;
+;;;;; this file has no effect and is left in ESS in order not to break
+;;;;; users configuration
+
+;; This is an initial attempt to use the emacs facility ELDOC in R
+;; buffers.  Eldoc is used in Emacs lisp buffers to show the function
+;; arglist and docstrings for variables.  To try it, view an emacs
+;; lisp buffer, and then do M-x turn-on-eldoc-mode, and move over
+;; function and variable names.
+
+;; This file extends eldoc to work in R buffers.  It currently uses
+;; Sven's ess-r-args.el file to retrieve args for a given R function
+;; (via ess-r-args-get).  Note that it works slightly different to
+;; Sven's code, in that you just need to have the point over the name
+;; of an R function, or inside its arguments list, for eldoc to show
+;; the arg list.
+
+;; To use this functionality, simply add
+;;
+;; (require 'ess-eldoc)
+;;
+;; to your .emacs file.  When you visit a R mode, eldoc will be turned
+;; on.  However, you will first need to associate the R buffer with an
+;; *R* process so that args can be looked up -- otherwise, eldoc will
+;; silently not report anything.  So, e.g. try:
+;; C-x C-f somefile.R
+;; M-x R   (so that somefile.R is associated with *R*)
+;; eldoc should then work.
+
+;; e.g. put the following rnorm() command in an R buffer.  The line
+;; underneath shows a key of what arg list will be shown as you move
+;; across the rnorm line.
+
+;; rnorm(n=100, mean=sqrt(20), sd=10)
+;; 1111111111111222223333333311444111
+;; 1: rnorm
+;; 2: mean
+;; 3: sqrt
+;; 4: sd
+;;
+
+;; Note that the arg list for rnorm() should be shown either when you
+;; are on the function name, or in the arg list.  However, since the
+;; 2nd and 3rd arguments are also function names, the arg lists of
+;; those function names are reported instead.  This might be seen as
+;; undesirable behaviour, in which case a solution would be to only
+;; look up the function name if it is followed by (.
+
+;; If you want to use this feature in *R* buffers, add the following
+;; to .emacs:
+;; (add-hook 'inferior-ess-mode-hook 'ess-use-eldoc)
+
+
+;; In the current version, I do not cache the arg list, but that was
+;; done in an earlier version, to save repeated calls to
+;; ess-r-args-get.
+
+;; This code has been tested only in Emacs 22.1.  It will not work on
+;; Emacs 21, because it needs the variable
+;; eldoc-documentation-function.
+
+;;;; VS [25-02-2012]: all these issues were at least partially addressed in the
+;;;; new implementation:
+
+;; Bug (in eldoc?): the arg list for legend() is too long to fit in
+;; minibuffer, and it seems that we see the last N lines of the arg
+;; list, rather than the first N lines.  It would be better to see the
+;; first N lines since the more important args come first.
+
+;; Doc issue: the eldoc vars (e.g. eldoc-echo-area-use-multiline-p)
+;; work only for elisp mode.
+
+;; Issue: You will probably see the message "Using process 'R'" flash;
+;; this is generated by `ess-request-a-process', and I'd like to avoid
+;; that appearing, non-interactively.
+
+;; If *R* is currently busy (e.g. processing Sys.sleep(999)), then the
+;; eldoc commands won't work; ess-command could be silenced in this
+;; regard perhaps with a new SILENT arg for example to prevent the
+;; call to (ess-error).
+
+
+;;; Code:
+
+;; ;; This could be done on buffer local basis.
+;; (setq ess-r-args-noargsmsg "")
+
+;; ;; following two defvars are not currently used.
+;; (defvar ess-eldoc-last-name nil
+;;   "Name of the last function looked up in eldoc.
+;; We remember this to see whether we need to look up documentation, or used
+;; the cached value in `ess-eldoc-last-args'.")
+
+;;  (defvar ess-eldoc-last-args nil
+;;   "Args list last looked up for eldoc.  Used as cache.")
+
+;; (defun ess-eldoc-2 ()
+;;   ;; simple, old version.
+;;   (interactive)
+;;   (ess-r-args-get (ess-read-object-name-default)))
+
+;; (defun ess-eldoc-1 ()
+;;   "Return the doc string, or nil.
+;; This is the first version; works only on function name, not within arg list."
+;;   (interactive)
+
+;;   ;; Possible ways to get the function at point.
+;;   ;;(setq name (thing-at-point 'sexp))
+;;   ;;(setq name (ess-read-object-name-default))
+;;   ;;(setq name (find-tag-default))
+
+;;   (if ess-current-process-name
+;;       (progn
+;;      (setq name (ess-guess-fun))             ;guess the word at point.
+;;      (if (equal (length name) 0)
+;;          nil
+;;        ;; else
+;;        (unless (equal name ess-eldoc-last-name)
+;;          ;; name is different to the last name we lookedup, so get
+;;          ;; new args from R and store them.
+;;          (setq ess-eldoc-last-args (ess-r-args-get name)
+;;                ess-eldoc-last-name name))
+;;        ess-eldoc-last-args))
+;;     ;; no ESS process current.
+;;     nil)
+;; )
+
+
+;; (defsubst ess-guess-fun ()
+;;   "Guess what the function at point is."
+;;   ;; Derived from Man-default-man-entry in man.el
+;;   (let (word)
+;;     (save-excursion
+;;       (skip-chars-backward "-a-zA-Z0-9._+:")
+;;       (let ((start (point)))
+;;      (skip-chars-forward "-a-zA-Z0-9._+:")
+;;      (setq word (buffer-substring-no-properties start (point)))))
+;;       word))
+
+(defun ess-use-eldoc ()
+  "Does nothing. Defined not to break old users' code."
+  (interactive))
+
+(provide 'ess-eldoc)
+
+;;; ess-eldoc.el ends here
diff --git a/elpa/ess-20260424.1544/obsolete/ess-font-lock.el b/elpa/ess-20260424.1544/obsolete/ess-font-lock.el
new file mode 100755 (executable)
index 0000000..0487b55
--- /dev/null
@@ -0,0 +1,150 @@
+;;; ess-font-lock.el --- font-lock color options  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2000-2022  Free Software Foundation, Inc.
+
+;; Author: Richard M. Heiberger <rmhNOSPAMtemple.edu>
+;; Created: 06 Feb 2000
+
+;; Keywords: languages, faces
+
+;; 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/
+
+;;; Commentary:
+
+;; provides syntax highlighting support.
+
+;;; Code:
+
+                                        ; Requires and autoloads
+
+(require 'font-lock)
+(require 'paren)
+
+;; FIXME: What is this doing here!?
+(if (fboundp 'show-paren-mode) (show-paren-mode 1))
+
+;;; Emacs 20.x notes:
+
+;; font-lock faces are defined in /emacs/emacs-20.5/lisp/font-lock.el
+;; The font-lock faces are applied to ESS buffers by
+;; ess-mode.el ess-inf.el ess-trns.el ess-custom.el
+;; The keywords for faces are defined in the ess[dl]*.el files.
+;; All faces can be looked at, under Emacs 20.x, with
+;;        [menu-bar] [Edit] [Text Properties] [Display Faces}
+
+(defun ess-font-lock-rmh ()
+  "Set font-lock colors to Richard Heiberger's usual choice."
+  ;; FIXME: Turn it into a Custom theme!
+  (interactive)
+
+  (set-foreground-color "Black")
+  (set-background-color "lightcyan")
+
+  (set-face-background 'mode-line "lightskyblue")
+  (set-face-foreground 'mode-line "midnightblue")
+
+  (set-face-foreground 'font-lock-comment-face "Firebrick")
+  (set-face-foreground 'font-lock-function-name-face "Blue")
+  (set-face-foreground 'font-lock-keyword-face "Purple")
+  (set-face-foreground 'font-lock-constant-face "Brown")
+  (set-face-foreground 'font-lock-string-face "VioletRed")
+  (set-face-foreground 'font-lock-type-face "Sienna")
+  (set-face-foreground 'font-lock-variable-name-face "Black"))
+
+(defun ess-font-lock-blue ()
+  "Set font-lock colors to Richard Heiberger's blue color scheme."
+  ;; FIXME: Turn it into a Custom theme!
+  (interactive)
+
+  (set-foreground-color "Black")
+  (set-background-color "LightBlue")
+
+  (set-face-foreground 'mode-line "LightBlue")
+  (set-face-background 'mode-line "DarkSlateBlue")
+
+  (set-face-foreground 'font-lock-comment-face "Firebrick")
+  (set-face-foreground 'font-lock-function-name-face "Blue")
+  (set-face-foreground 'font-lock-keyword-face "Purple")
+  (set-face-foreground 'font-lock-constant-face "Brown")
+  (set-face-foreground 'font-lock-string-face "VioletRed")
+  (set-face-foreground 'font-lock-type-face "Sienna")
+  (set-face-foreground 'font-lock-variable-name-face "Black"))
+
+(defun ess-font-lock-wheat ()
+  "Set font-lock colors to Richard Heiberger's wheat color scheme."
+  ;; FIXME: Turn it into a Custom theme!
+  (interactive)
+
+  (set-foreground-color "Black")
+  (set-background-color "Wheat")
+
+  (set-face-foreground 'mode-line "Wheat")
+  (set-face-background 'mode-line "Sienna")
+
+  (set-face-foreground 'font-lock-comment-face "Firebrick")
+  (set-face-foreground 'font-lock-function-name-face "Blue")
+  (set-face-foreground 'font-lock-keyword-face "Purple")
+  (set-face-foreground 'font-lock-constant-face "Brown")
+  (set-face-foreground 'font-lock-string-face "VioletRed")
+  (set-face-foreground 'font-lock-type-face "Sienna")
+  (set-face-foreground 'font-lock-variable-name-face "Black"))
+
+
+(defun ess-font-lock-bw ()
+  "Set font-lock colors to Richard Heiberger's black and white color scheme."
+  ;; FIXME: Turn it into a Custom theme!
+  (interactive)
+
+  (set-foreground-color "Black")
+  (set-background-color "white")
+
+  (set-face-foreground 'mode-line "gray10")
+  (set-face-background 'mode-line "gray90")
+
+  ;; modify-face is an interactive compiled Lisp function in `faces'.
+  ;; Sample usage:
+
+  ;;(modify-face FACE                        FOREGROUND BACKGROUND STIPPLE BOLD-P ITALIC-P UNDERLINE-P &optional INVERSE-P FRAME)
+
+  (modify-face 'mode-line                     "gray10"   "gray90"   nil     nil    t        nil       )
+  (modify-face 'font-lock-comment-face       "black"    "white"    nil     nil    t        nil       )
+  (modify-face 'font-lock-function-name-face "black"    "white"    nil     t      nil      nil       )
+  (modify-face 'font-lock-keyword-face       "black"    "white"    nil     nil    nil      t         )
+  (modify-face 'font-lock-constant-face      "black"    "white"    nil     t      nil      nil       )
+  (modify-face 'font-lock-string-face        "black"    "white"    nil     nil    t        t         )
+  (modify-face 'font-lock-type-face          "black"    "white"    nil     t      t        nil       )
+  (modify-face 'font-lock-variable-name-face "black"    "white"    nil     nil    nil      nil       )
+  (modify-face 'font-lock-builtin-face       "black"    "white"    nil     t      nil      nil       )
+  (modify-face 'font-lock-warning-face       "black"    "white"    nil     t      nil      nil       )
+  (modify-face 'show-paren-match-face        "gray20"   "gray80"   nil     t      nil      nil       )
+  (modify-face 'show-paren-mismatch-face     "white"    "gray40"   nil     t      t        nil       ))
+
+(defun ess-font-lock-db ()
+  "Set font-lock colors (leave fore-/back-ground alone) courtesy David Brahm <David.BrahmNOSPAMfmr.com>"
+  ;; FIXME: Turn it into a Custom theme!
+  (interactive)
+  (set-face-foreground 'font-lock-comment-face       "Firebrick")  ; #...    %...
+  (set-face-foreground 'font-lock-string-face        "SeaGreen")   ; "..."   "..."
+  (set-face-foreground 'font-lock-keyword-face       "MediumBlue") ; if      \end
+  (set-face-foreground 'font-lock-function-name-face "VioletRed")  ; talk<-  {center}
+  (set-face-foreground 'font-lock-variable-name-face "Blue")       ; xv
+  (set-face-foreground 'font-lock-type-face          "Goldenrod")  ; T,F       ?
+  (set-face-foreground 'font-lock-constant-face      "Magenta")    ; <-      {eq1}
+  )
+
+(provide 'ess-font-lock)
+
+;;; ess-font-lock.el ends here
diff --git a/elpa/ess-20260424.1544/obsolete/ess-jags-d.el b/elpa/ess-20260424.1544/obsolete/ess-jags-d.el
new file mode 100644 (file)
index 0000000..5700f33
--- /dev/null
@@ -0,0 +1,257 @@
+;;; ess-jags-d.el --- ESS[JAGS] dialect  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+;; Author: Rodney Sparapani
+;; Created: 13 March 2008
+;; Maintainer: ESS Core Team <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Code:
+
+(require 'ess-bugs-d)
+(require 'ess-utils)
+(require 'ess-inf)
+(require 'ess-mode)
+
+(defvar ess-jags-command "jags" "Default JAGS program in PATH.")
+(make-local-variable 'ess-jags-command)
+
+(defvar ess-jags-monitor '("") "Default list of variables to monitor.")
+(make-local-variable 'ess-jags-monitor)
+
+(defvar ess-jags-thin 1 "Default thinning parameter.")
+(make-local-variable 'ess-jags-thin)
+
+(defvar ess-jags-chains 1 "Default number of chains.")
+(make-local-variable 'ess-jags-chains)
+
+(defvar ess-jags-burnin 10000 "Default burn-in.")
+(make-local-variable 'ess-jags-burnin)
+
+(defvar ess-jags-update 10000 "Default number of updates after burnin.")
+(make-local-variable 'ess-jags-update)
+
+(defvar ess-jags-system t "Default whether JAGS recognizes the system command.")
+
+(defvar ess-jags-font-lock-keywords
+  (list
+   ;; .jag files
+   (cons "#.*\n"                        font-lock-comment-face)
+
+   (cons "^[ \t]*\\(model\\|var\\)\\>"
+         font-lock-keyword-face)
+
+   (cons (concat "\\<d\\(bern\\|beta\\|bin\\|cat\\|chisq\\|"
+                 "dexp\\|dirch\\|exp\\|\\(gen[.]\\)?gamma\\|hyper\\|"
+                 "interval\\|lnorm\\|logis\\|mnorm\\|mt\\|multi\\|"
+                 "negbin\\|norm\\(mix\\)?\\|par\\|pois\\|sum\\|t\\|"
+                 "unif\\|weib\\|wish\\)[ \t\n]*(")
+         font-lock-constant-face)
+
+   (cons (concat "\\<\\(abs\\|cos\\|dim\\|\\(i\\)?cloglog\\|equals\\|"
+                 "exp\\|for\\|inprod\\|interp[.]line\\|inverse\\|length\\|"
+                 "\\(i\\)?logit\\|logdet\\|logfact\\|loggam\\|max\\|mean\\|"
+                 "mexp\\|min\\|phi\\|pow\\|probit\\|prod\\|rank\\|round\\|"
+                 "sd\\|sin\\|sort\\|sqrt\\|step\\|sum\\|t\\|trunc\\|T\\)[ \t\n]*(")
+         font-lock-function-name-face)
+
+   ;; .jmd files
+   (cons (concat "\\<\\(adapt\\|cd\\|clear\\|coda\\|data\\|dir\\|"
+                 "exit\\|in\\(itialize\\)?\\|load\\|model\\|monitors\\|parameters\\|"
+                 "pwd\\|run\\|s\\(amplers\\|ystem\\)\\|to\\|update\\)[ \t\n]")
+         font-lock-keyword-face)
+
+   (cons "\\<\\(compile\\|monitor\\)[, \t\n]"
+         font-lock-keyword-face)
+
+   (cons "[, \t\n]\\(by\\|chain\\|nchains\\|stem\\|thin\\|type\\)[ \t\n]*("
+         font-lock-function-name-face)
+   )
+  "ESS[JAGS]: Font lock keywords."
+  )
+
+(defun ess-jags-switch-to-suffix (suffix &optional jags-chains jags-monitor jags-thin
+                                         jags-burnin jags-update)
+  "ESS[JAGS]: Switch to file with suffix."
+  (find-file (concat ess-bugs-file-dir ess-bugs-file-root suffix))
+
+  (if (equal 0 (buffer-size)) (progn
+                                (if (equal ".jag" suffix) (progn
+                                                            (insert "var ;\n")
+                                                            (insert "model {\n")
+                                                            (insert "    for (i in 1:N) {\n    \n")
+                                                            (insert "    }\n")
+                                                            (insert "}\n")
+                                                            (insert "#Local Variables" ":\n")
+                                                            (insert "#ess-jags-chains:1\n")
+                                                            (insert "#ess-jags-monitor:(\"\")\n")
+                                                            (insert "#ess-jags-thin:1\n")
+                                                            (insert "#ess-jags-burnin:10000\n")
+                                                            (insert "#ess-jags-update:10000\n")
+                                                            (insert "#End:\n")
+                                                            ))
+
+                                (if (equal ".jmd" suffix) (let
+                                                              ((ess-jags-temp-chains "") (ess-jags-temp-monitor "") (ess-jags-temp-chain ""))
+
+                                                            (if jags-chains (setq ess-jags-chains jags-chains))
+                                                            (if jags-monitor (setq ess-jags-monitor jags-monitor))
+                                                            (if jags-thin (setq ess-jags-thin jags-thin))
+
+                                                            (setq ess-jags-temp-chains
+                                                                  (concat "compile, nchains(" (format "%d" ess-jags-chains) ")\n"))
+
+                                                            (setq jags-chains ess-jags-chains)
+
+                                                            (while (< 0 jags-chains)
+                                                              (setq ess-jags-temp-chains
+                                                                    (concat ess-jags-temp-chains
+                                                                            "parameters ## \"" ess-bugs-file-root
+                                                                            ".##" (format "%d" jags-chains) "\", chain("
+                                                                            (format "%d" jags-chains) ")\n"))
+                                                              (setq jags-chains (- jags-chains 1)))
+
+                                                            (setq ess-jags-temp-monitor "")
+
+                                                            (while (and (listp ess-jags-monitor) (consp ess-jags-monitor))
+                                                              (if (not (string-equal "" (car ess-jags-monitor)))
+                                                                  (setq ess-jags-temp-monitor
+                                                                        (concat ess-jags-temp-monitor "monitor "
+                                                                                (car ess-jags-monitor) ", thin(" (format "%d" ess-jags-thin) ")\n")))
+                                                              (setq ess-jags-monitor (cdr ess-jags-monitor)))
+
+                                                            (insert "model in \"" ess-bugs-file-root ".jag\"\n")
+                                                            (insert "data in \"" ess-bugs-file-root ".jdt\"\n")
+                                                            (insert (ess-replace-in-string ess-jags-temp-chains "##" "in"))
+                                                            (insert "initialize\n")
+                                                            ;(insert "update " (format "%d" (* jags-thin jags-burnin)) "\n")
+                                                            (insert "update " (format "%d" jags-burnin) "\n")
+                                                            (insert ess-jags-temp-monitor)
+                                                            (insert "update " (format "%d" (* jags-thin jags-update)) "\n")
+                                                            (insert (ess-replace-in-string
+                                                                     (ess-replace-in-string ess-jags-temp-chains
+                                                                                            "compile, nchains([0-9]+)" "#") "##" "to"))
+                                                            (insert "coda "
+                                                                    ;(if ess-microsoft-p (if (w32-shell-dos-semantics) "*" "\\*") "\\*")
+                                                                    "*, stem(\"" ess-bugs-file-root "\")\n")
+
+                                                            (if ess-jags-system (progn
+                                                                                  (insert "system rm -f " ess-bugs-file-root ".ind\n")
+                                                                                  (insert "system ln -s " ess-bugs-file-root "index.txt " ess-bugs-file-root ".ind\n")
+
+                                                                                  (setq jags-chains ess-jags-chains)
+
+                                                                                  (while (< 0 jags-chains)
+                                                                                    (setq ess-jags-temp-chain (format "%d" jags-chains))
+
+                                        ;.txt not recognized by BOA and impractical to over-ride
+                                                                                    (insert "system rm -f " ess-bugs-file-root ess-jags-temp-chain ".out\n")
+                                                                                    (insert "system ln -s " ess-bugs-file-root "chain" ess-jags-temp-chain ".txt "
+                                                                                            ess-bugs-file-root ess-jags-temp-chain ".out\n")
+                                                                                    (setq jags-chains (- jags-chains 1)))))
+
+                                                            (insert "exit\n")
+                                                            (insert "Local Variables" ":\n")
+                                                            (insert "ess-jags-chains:" (format "%d" ess-jags-chains) "\n")
+                                                            (insert "ess-jags-command:\"jags\"\n")
+                                                            (insert "End:\n")
+                                                            ))
+                                ))
+  )
+
+(defun ess-jags-na-jmd (jags-command)
+  "ESS[JAGS]: Perform the Next-Action for .jmd."
+                                        ;(ess-save-and-set-local-variables)
+  (if (equal 0 (buffer-size)) (ess-jags-switch-to-suffix ".jmd")
+                                        ;else
+    (shell)
+    (ess-sleep)
+
+    (if (when (fboundp 'w32-shell-dos-semantics)
+          (w32-shell-dos-semantics))
+        (if (string-equal ":" (substring ess-bugs-file 1 2))
+            (progn
+              (insert (substring ess-bugs-file 0 2))
+              (comint-send-input)
+              )
+          )
+      )
+
+    (insert "cd \"" ess-bugs-file-dir "\"")
+    (comint-send-input)
+
+                                        ;    (let ((ess-jags-temp-chains ""))
+                                        ;
+                                        ;       (while (< 0 jags-chains)
+                                        ;           (setq ess-jags-temp-chains
+                                        ;               (concat (format "%d " jags-chains) ess-jags-temp-chains))
+                                        ;           (setq jags-chains (- jags-chains 1)))
+
+    (insert ess-bugs-batch-pre-command " " jags-command " "
+            ess-bugs-file-root ".jmd "
+
+            (if (or (equal shell-file-name "/bin/csh")
+                    (equal shell-file-name "/bin/tcsh")
+                    (equal shell-file-name "/bin/zsh")
+                    (equal shell-file-name "/bin/bash"))
+                (concat ">& " ess-bugs-file-root ".jog ")
+                                        ;else
+              "> " ess-bugs-file-root ".jog 2>&1 ")
+
+                                        ;               ;.txt not recognized by BOA and impractical to over-ride
+                                        ;               "&& (rm -f " ess-bugs-file-root ".ind; "
+                                        ;               "ln -s " ess-bugs-file-root "index.txt " ess-bugs-file-root ".ind; "
+                                        ;               "for i in " ess-jags-temp-chains "; do; "
+                                        ;               "rm -f " ess-bugs-file-root "$i.out; "
+                                        ;               "ln -s " ess-bugs-file-root "chain$i.txt " ess-bugs-file-root "$i.out; done) "
+
+            ess-bugs-batch-post-command)
+
+    (comint-send-input)
+    ))
+
+(defun ess-jags-na-bug ()
+  "ESS[JAGS]: Perform Next-Action for .jag"
+
+  (if (equal 0 (buffer-size)) (ess-jags-switch-to-suffix ".jag")
+                                        ;else
+    (ess-save-and-set-local-variables)
+    (ess-jags-switch-to-suffix ".jmd"
+                               ess-jags-chains ess-jags-monitor ess-jags-thin ess-jags-burnin ess-jags-update))
+  )
+
+;;;###autoload
+(define-derived-mode ess-jags-mode ess-bugs-mode "ESS[JAGS]"
+  "Major mode for JAGS."
+  (setq-local comment-start "#")
+  (setq font-lock-defaults '(ess-jags-font-lock-keywords nil t))
+  (setq ess-language "S") ; mimic S for ess-smart-underscore
+  (unless (and (fboundp 'w32-shell-dos-semantics)
+               (w32-shell-dos-semantics))
+    (add-hook 'comint-output-filter-functions #'ess-bugs-exit-notify-sh))
+  )
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.[Jj][Aa][Gg]\\'" . ess-jags-mode))
+
+(provide 'ess-jags-d)
+
+;;; ess-jags-d.el ends here
diff --git a/elpa/ess-20260424.1544/obsolete/ess-mouse.el b/elpa/ess-20260424.1544/obsolete/ess-mouse.el
new file mode 100644 (file)
index 0000000..6e6976d
--- /dev/null
@@ -0,0 +1,222 @@
+;;; ess-mouse.el --- Support for mouse- or cursor-sensitive actions  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2001-2022 Free Software Foundation, Inc.
+;; Author: Richard M. Heiberger <rmhNOSPAMtemple.edu>
+;; Created: 25 Mar 2001
+;; Maintainer: ESS-core <ESS-core@r-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; Support for mouse- or cursor-sensitive actions.  This is based on
+;; and uses mouseme.el.  mouseme.el only does mouse sensitivity.
+;; The new functions ess-mouse-me and ess-mouse-me-helper do similar
+;; things based on the cursor, not the mouse, and can be bound to a
+;; keystroke.
+
+;;; Code:
+
+\f ; Requires and autoloads
+
+;;*;; Requires
+(require 'mouseme)
+(require 'ess-trns)
+;;(if (or (equal window-system 'w32)
+;;      (equal window-system 'win32)
+;;      (equal window-system 'mswindows))
+;;    (require 'essiw32b))
+
+(defun ess-mouse-me ()
+  "Popup a menu of functions to run on selected string or region."
+  (interactive)
+  (ess-mouse-me-helper
+   (lambda (name)
+     (or (x-popup-menu (list '(0 0)
+                             (get-buffer-window (get-buffer (buffer-name))))
+                       (funcall mouse-me-build-menu-function name))
+         (error "No command to run")))))
+
+
+
+(defun ess-mouse-me-helper (func)
+  "Determine the string to use to process EVENT and call FUNC to get cmd."
+  (let (name sp sm mouse beg end cmd mmtype)
+    ;; temporarily goto where the event occurred, get the name clicked
+    ;; on and enough info to figure out what to do with it
+    (save-match-data
+      (save-excursion
+        (setq sp (point))               ; saved point
+        (setq sm (mark t))              ; saved mark
+;;;     (set-buffer (window-buffer (posn-window (event-start event))))
+;;;     (setq mouse (goto-char (posn-point (event-start event))))
+        (setq mouse (point))  ;; ess-mouse-me-helper
+        ;; if there is a region and point is inside it
+        ;; check for sm first incase (null (mark t))
+        ;; set name to either the thing they clicked on or region
+        (if (and sm
+                 (or (and transient-mark-mode mark-active)
+                     (eq last-command 'mouse-drag-region))
+                 (>= mouse (setq beg (min sp sm)))
+                 (<= mouse (setq end (max sp sm))))
+            (setq name (buffer-substring beg end))
+          (setq name (funcall mouse-me-get-string-function))
+          (if (listp name)
+              (setq beg (nth 1 name)
+                    end (nth 2 name)
+                    name (car name))
+            (goto-char mouse)
+            (while (not (looking-at (regexp-quote name)))
+              (backward-char 1))
+            (setq beg (point))
+            (setq end (search-forward name))))))
+    ;; check if name is null, meaning they clicked on no word
+    (if (or (null name)
+            (and (stringp name) (string= name "" )))
+        (error "No string to pass to function"))
+    ;; popup a menu to get a command to run
+    (setq cmd (funcall func name))
+    ;; run the command, eval'ing if it was a list
+    (if (listp cmd)
+        (setq cmd (eval cmd t)))
+    (setq mmtype (get cmd 'mouse-me-type))
+    (cond ((eq mmtype 'region)
+           (funcall cmd beg end))
+          ((eq mmtype 'string)
+           (funcall cmd name))
+          (t
+           (funcall cmd name)))))
+
+(defcustom ess-S-mouse-me-menu-commands-alist
+  '("S-Plus 4 and 6 GUI under Windows"
+    ("Edit.data"   . ess-mouse-me-Edit.data)
+    "----"
+    ("print"       . ess-mouse-me-print)
+    ("summary"     . ess-mouse-me-summary)
+    ("plot"        . ess-mouse-me-plot)
+    ("show"        . ess-mouse-me-show)
+    ("help"        . ess-display-help-on-object)
+    ("args"        . ess-mouse-me-args)
+    "----"
+    ("Browser on"  . ess-mouse-me-browser-on)
+    ("Browser off" . ess-mouse-me-browser-off))
+  "Command menu used by `mouse-me-build-menu'.
+A alist of elements where each element is either a cons cell or a string.
+If a cons cell the car is a string to be displayed in the menu and the
+cdr is either a function to call passing a string to, or a list which evals
+to a function to call passing a string to.  If the element is a string
+it makes a non-selectable element in the menu.  To make a separator line
+use a string consisting solely of hyphens.
+
+The function returned from this menu will be called with one string
+argument.  Or if the function has the symbol property `mouse-me-type'
+and if its value is the symbol `region' it will be called with the
+beginning and ending points of the selected string.  If the value is
+the symbol `string' it will be called with one string argument."
+  :type '(repeat sexp)
+  :group 'mouseme)
+
+
+(defun ess-mouse-me-Edit.data (string)
+  (ess-mouse-me-eval-expanded string "Edit.data(" ")" nil nil nil))
+
+(defun ess-mouse-me-print (string)
+  (ess-mouse-me-eval-expanded string "" "" nil nil t))
+(defun ess-mouse-me-summary (string)
+  (ess-mouse-me-eval-expanded string "summary(" ")" nil nil t))
+(defun ess-mouse-me-plot (string)
+  (ess-mouse-me-eval-expanded string "plot(" ")") nil nil nil)
+(defun ess-mouse-me-show (string)
+  (ess-mouse-me-eval-expanded string "show(" ")") nil nil nil)
+(defun ess-mouse-me-args (string)
+  (ess-mouse-me-eval-expanded string "args(" ")" nil nil t))
+
+(defun ess-mouse-me-browser-on (string)
+  (if (equal (substring ess-dialect 0 1) "R")
+      (ess-eval-linewise (concat "debug(" string ")"))
+    (ess-mouse-me-eval-expanded string "trace(" ", exit=browser)") nil nil nil))
+
+(defun ess-mouse-me-browser-off  (string)
+  (if (equal (substring ess-dialect 0 1) "R")
+      (ess-eval-linewise (concat "undebug(" string ")"))
+    (ess-mouse-me-eval-expanded string "untrace(" ")") nil nil nil))
+
+
+
+(defun ess-mouse-me-eval-expanded (string &optional head tail commands-buffer
+                                          _page value-returned)
+  "Send the expanded STRING to the inferior-ess process using `ess-command'
+after first concating the HEAD and TAIL.  Put answer in COMMANDS-BUFFER if
+specified, otherwise in \"tmp-buffer\".  In either
+case the buffer containing the answer is renamed to the value of the
+constructed command.  If PAGE is non-nil, expand
+the string one more time by embedding it in a \"page()\" command."
+  (interactive)
+  (let* (scommand
+         ;; page-scommand
+         (lproc-name ess-local-process-name)
+         (ess-mouse-customize-alist ess-local-customize-alist))
+    (if (not head) (setq head "summary("))
+    (if (not tail) (setq tail ")"))
+    (if (not commands-buffer) (setq commands-buffer
+                                    (get-buffer-create "tmp-buffer")))
+    (setq scommand (concat head string tail))
+
+    (ess-make-buffer-current)
+    (pop-to-buffer-same-window commands-buffer)
+    (ess-setq-vars-local (eval ess-mouse-customize-alist t) (current-buffer))
+    (setq ess-local-process-name lproc-name)
+    (ess-command (concat scommand "\n") commands-buffer)
+    (if (not value-returned) (pop-to-buffer-same-window (nth 1 (buffer-list))))
+    (if (not value-returned)
+        nil
+      (if ess-microsoft-p                      ;; there ought to be a filter
+          (while (search-forward "\r" nil t)   ;; function to keep the ^M
+            (replace-match "" nil t)))         ;; from showing up at all
+      (ess-transcript-mode)
+      (setq ess-local-process-name lproc-name)
+      (rename-buffer scommand))))
+
+
+\f ; Provide package
+
+(provide 'ess-mouse)
+
+
+
+;;;;;;;; STARTUP STUFF ;;;;;;;;;;;;
+
+(make-variable-buffer-local 'mouse-me-menu-commands)
+
+(defun ess-S-mouse-me-menu-commands ()
+  (if (equal ess-language "S")
+      (setq mouse-me-menu-commands ess-S-mouse-me-menu-commands-alist)))
+
+;;       (define-key ess-mode-map              [S-mouse-3] 'ess-mouse-me)
+;;       (define-key inferior-ess-mode-map     [S-mouse-3] 'ess-mouse-me)
+;;       (defun ess-S-mouse-me-ess-transcript-mode ()
+;;         (define-key ess-transcript-mode-map [S-mouse-3] 'ess-mouse-me))
+;;
+(add-hook 'ess-mode-hook            #'ess-S-mouse-me-menu-commands)
+(add-hook 'inferior-ess-mode-hook   #'ess-S-mouse-me-menu-commands)
+(add-hook 'ess-transcript-mode-hook #'ess-S-mouse-me-menu-commands)
+;; (add-hook 'ess-transcript-mode-hook 'ess-S-mouse-me-ess-transcript-mode)
+
+
+;;; ess-mouse.el ends here
diff --git a/elpa/ess-20260424.1544/obsolete/ess-r-a.el b/elpa/ess-20260424.1544/obsolete/ess-r-a.el
new file mode 100644 (file)
index 0000000..7872fba
--- /dev/null
@@ -0,0 +1,153 @@
+;;; ess-r-a.el -- Possible local customizations for R with ESS.  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1997-2022 Free Software Foundation, Inc.
+;; Author: A.J. Rossini <blindglobeNOSPAMgmail.com>
+;; Created: 17 November 1999
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; The purpose of this file is to demonstrate some of the extras that
+;; have been constructed for the ESS R mode; if they prove
+;; interesting, then they might be migrated to ess-r-mode, the primary
+;; ESS R mode tools.
+
+;;; Code:
+(require 'ess-inf)
+(require 'ess-r-mode)
+
+;; you can invoke ESS/R from emacs by typing
+;;      C-u M-x essr
+;; with vsize set to (for example) 40M, and nsize set to 600000.
+
+;; Undefined on non-apple devices
+(declare-function ns-do-applescript "nsfns.m" (script))
+(declare-function do-applescript "ess-r-a" (script))
+(unless (fboundp 'do-applescript)
+  (defalias 'do-applescript #'ns-do-applescript))
+
+(defalias 'essr
+  (read-kbd-macro
+   "C-u M-x R RET - - vsize = 40M SPC - - nsize = 600000 2*RET"))
+
+(defun ess-r-do-region (start end)
+  "Send from START to END to R via AppleScript."
+  (interactive "r\nP")
+  (message "Starting evaluation...")
+  (do-applescript (concat
+                   "try\n"
+                   "tell application \"R\"\n"
+                   "activate\n"
+                   "with timeout of 0 seconds\n"
+                   "cmd \"" (buffer-substring start end)
+                   "\"\n"
+                   "end timeout\n"
+                   "end tell\n"
+                   "end try\n"))
+  (message "Finished evaluation"))
+
+(defun ess-r-do-line ()
+  "Send the current line to R via AppleScript."
+  (interactive) ;; "r\nP")
+  (message "Starting evaluation...")
+  (save-excursion
+    (let ((end (point)))
+      (move-to-column 0)
+      (do-applescript (concat
+                       "try\n"
+                       "tell application \"R\"\n"
+                       "activate\n"
+                       "with timeout of 0 seconds\n"
+                       "cmd \"" (buffer-substring (point) end)
+                       "\"\n"
+                       "end timeout\n"
+                       "end tell\n"
+                       "end try\n"))))
+  (message "Finished evaluation"))
+
+(defun ess-r-var (beg end)
+  "Load the current region of numbers into an R variable.
+Prompts for a variable name. If none is given, it uses a default
+variable name, e. BEG and END denote the region in the current
+buffer to be sent."
+  (interactive "r")
+  (save-window-excursion
+    (let ((tmp-file (make-temp-file "ess-r-var"))
+          cmd
+          var)
+      (write-region beg end tmp-file)
+
+      ;; Decide on the variable name to use in R; could use completion.
+      (setq var (read-string "R Variable name (default e): "))
+      (if (equal var "")
+          (setq var "e"))
+
+      ;; Command to send to the R process.  Get R to delete the file
+      ;; rather than Emacs in case it takes R a long time to run the
+      ;; scan command.
+      (setq cmd (concat var " <- scan(\""  tmp-file "\"); "
+                        "unlink(\"" tmp-file "\")" ))
+
+      ;; Put the output from the scan command into the process buffer so
+      ;; the user has a record of it.
+      (ess-execute cmd 'buffer))))
+
+
+;;; Peter Dalgaard's code.
+;;; This needs to be cleaned and validated!
+
+(defun pd::set-up-demo ()
+  (run-ess-r)
+  (split-window-vertically 6)
+  (find-file "demos.R")
+
+  ;; Don't need to run this as a function -- ought to be fine if set
+  ;; just once.
+
+  (defun ajr::scroll-to-end::peterD (emacs)
+    "Goal: map prompt to bottom of the screen after every command.
+Alternatively, use the scroll-in-place package, not sure where that
+is)."
+    (interactive)
+    (other-buffer 1)
+    (if (= emacs "emacs")
+        (setq scroll-up-aggressively t)
+      (setq scroll-conservatively -4)) ;; <- change this
+    (other-buffer -1))
+
+  (defun show-max-other-window ()
+    (interactive)
+    (other-window 1)
+    (comint-show-maximum-output)
+    (other-window -1))
+
+  ;; call this once
+  ;; (ajr::scroll-to-end::peterD "emacs")
+
+  (global-set-key [f11] #'show-max-other-window)
+  (global-set-key [f12] #'ess-eval-line-visibly-and-step))
+
+
+\f ; Provide package
+
+(provide 'ess-r-a)
+
+;;; ess-r-a.el ends here
diff --git a/elpa/ess-20260424.1544/obsolete/mouseme.el b/elpa/ess-20260424.1544/obsolete/mouseme.el
new file mode 100644 (file)
index 0000000..82e7c61
--- /dev/null
@@ -0,0 +1,354 @@
+;;; mouseme.el --- mouse menu with commands that operate on strings  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1997-2022 by Free Software Foundation, Inc.
+
+;; Author: Howard Melman <howardNOSPAMsilverstream.com>
+;; Keywords: mouse, menu
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; This package provides a command `mouse-me' to be bound to a mouse
+;; button.  It pops up a menu of commands that operate on strings or a
+;; region.  The string passed to the selected command is the word or
+;; symbol clicked on (with surrounding quotes or other punctuation
+;; removed), or the region (if either it was just selected with the
+;; mouse or if it was active with `transient-mark-mode' on).  If the
+;; command accepts a region, the selected region (or the region of the
+;; word or symbol clicked on) will be passed to the command.
+
+;; The idea is that for any given string in a buffer you may want to
+;; do different things regardless of the mode of the buffer.  URLs
+;; now appear in email, news articles, comments in code, and in plain
+;; text.  You may want to visit that URL in a browser or you may just
+;; want to copy it to the kill-ring.  For an email address you might
+;; want to compose mail to it, finger it, look it up in bbdb, copy it to
+;; the kill ring.  For a word you may want to spell check it, copy it,
+;; change its case, grep for it, etc.  Mouse-me provides a menu to
+;; make this easy.
+
+;; The menu popped up is generated by calling the function in the
+;; variable `mouse-me-build-menu-function' which defaults to calling
+;; `mouse-me-build-menu' which builds the menu from the variable
+;; `mouse-me-menu-commands'.  See the documentation for these
+;; functions and variables for details.
+
+;; To install, add something like the following to your ~/.emacs:
+;;   (require 'mouseme)
+;;   (global-set-key [S-mouse-2] 'mouse-me)
+
+;;; Code:
+
+(require 'browse-url)
+(require 'thingatpt)
+
+(eval-when-compile (require 'compile))
+
+;;;; Variables
+
+(defgroup mouseme nil
+  "Popup menu of commands that work on strings."
+  :prefix "mouse-me-"
+  :group 'hypermedia)
+
+(defcustom mouse-me-get-string-function 'mouse-me-get-string
+  "Function used by `mouse-me' to get string when no region selected.
+The default is `mouse-me-get-string' but this variable may commonly
+be made buffer local and set to something more appropriate for
+a specific mode (e.g., `word-at-point').  The function will be called
+with no arguments and with point at where the mouse was clicked.
+It can return either the string or to be most efficient, a list of
+three elements: the string and the beginning and ending points of the
+string in the buffer."
+  :type 'function
+  :options '(mouse-me-get-string))
+
+(defcustom mouse-me-build-menu-function 'mouse-me-build-menu
+  "Function used by `mouse-me' to build the popup menu.
+The default is `mouse-me-build-menu' but this variable may commonly
+be made buffer local and set to something more appropriate for
+a specific mode.  The function will be called with one argument,
+the string selected, as returned by `mouse-me-get-string-function'."
+  :type 'function
+  :options '(mouse-me-build-menu))
+
+(defvar mouse-me-grep-use-extension 't
+  "If non-nil `mouse-me-grep' grep's in files with current file's extension.")
+
+(defcustom mouse-me-menu-commands
+  '(("Copy" . kill-new)
+    ("Kill" . kill-region)
+    ("Capitalize" . capitalize-region)
+    ("Lowercase" . downcase-region)
+    ("Uppercase" . upcase-region)
+    ("ISpell" . ispell-region)
+    "----"
+    ("Browse URL" . browse-url)
+    ("Dired" . dired)
+    ("Execute File" . mouse-me-execute)
+    ("Mail to" . compose-mail)
+    ("Finger" . mouse-me-finger)
+    ("BBDB Lookup" . mouse-me-bbdb)
+    "----"
+    ("Imenu" . imenu)
+    ("Find Tag" . find-tag)
+    ("Grep" . mouse-me-grep)
+    ("Find-Grep" . mouse-me-find-grep)
+    "----"
+    ("Apropos" . apropos)
+    ("Describe Function" . mouse-me-describe-function)
+    ("Describe Variable" . mouse-me-describe-variable)
+    ("Command Info" . mouse-me-emacs-command-info)
+    ("Man Page" . (if (fboundp 'woman) 'woman 'man))
+    ("Profile Function" . mouse-me-elp-instrument-function))
+  "Command menu used by `mouse-me-build-menu'.
+A list of elements where each element is either a cons cell or a string.
+If a cons cell the car is a string to be displayed in the menu and the
+cdr is either a function to call passing a string to, or a list which evals
+to a function to call passing a string to.  If the element is a string
+it makes a non-selectable element in the menu.  To make a separator line
+use a string consisting solely of hyphens.
+
+The function returned from this menu will be called with one string
+argument.  Or if the function has the symbol property `mouse-me-type'
+and if its value is the symbol `region' it will be called with the
+beginning and ending points of the selected string.  If the value is
+the symbol `string' it will be called with one string argument."
+  :type '(repeat sexp))
+
+(put 'kill-region 'mouse-me-type 'region)
+(put 'ispell-region 'mouse-me-type 'region)
+(put 'capitalize-region 'mouse-me-type 'region)
+(put 'downcase-region 'mouse-me-type 'region)
+(put 'upcase-region 'mouse-me-type 'region)
+
+;;;; Commands
+
+;;;###autoload
+(defun mouse-me (event)
+  "Popup a menu of functions to run on selected string or region."
+  (interactive "e")
+  (mouse-me-helper event (lambda (name)
+                           (or (x-popup-menu event (funcall mouse-me-build-menu-function name))
+                               (error "No command to run")))))
+
+;;;; Exposed Functions
+
+;; Some tests:
+;; <URL:http://foo.bar.com/sss/ss.html>
+;; <http://foo.bar.com/sss/ss.html>
+;; http://foo.bar.com/sss/ss.html
+;; http://www.ditherdog.com/howard/
+;; mailto:howardNOSPAMsilverstream.com
+;; howardNOSPAMsilverstream.com
+;; <howardNOSPAMsilverstream.com>
+;; import com.sssw.srv.agents.AgentsRsrc;
+;; public AgoHttpRequestEvent(Object o, String db, Request r)
+;; <DIV><A href=3D"http://www.amazon.com/exec/obidos/ASIN/156592391X"><IMG =
+;; <A HREF="http://www.suntimes.com/ebert/ebert.html">
+;; d:\howard\elisp\spoon
+;; \howard\elisp\spoon
+;; \\absolut\howard\elisp\spoon
+;; //absolut/d/Howard/Specs/servlet-2.1.pdf
+;; \\absolut\d\Howard\Specs\servlet-2.1.pdf
+;; gnuserv-frame.
+
+(defun mouse-me-get-string ()
+  "Return a string from the buffer of text surrounding point.
+Returns a list of three elements, the string and the beginning and
+ending positions of the string in the buffer in that order."
+  (save-match-data
+    (save-excursion
+      (let ((start (point)) beg end str)
+        (skip-syntax-forward "^ >()\"")
+        (setq end (point))
+        (goto-char start)
+        (skip-syntax-backward "^ >()\"")
+        (setq beg (point))
+        (setq str (buffer-substring-no-properties beg end))
+        ;; remove junk from the beginning
+        (if (string-match "^\\([][\"'`.,?:;!@#$%^&*()_+={}|<>-]+\\)" str)
+            (setq str (substring str (match-end 1))
+                  beg (+ beg (match-end 1))))
+        ;; remove URL: from the front, it's common in email
+        (if (string-match "^\\(URL:\\)" str)
+            (setq str (substring str (match-end 1))
+                  beg (+ beg (match-end 1))))
+        ;; remove junk from the end
+        (if (string-match "\\([][\"'.,?:;!@#$%^&*()_+={}|<>-]+\\)$" str)
+            (setq end (- end (length (match-string 1 str))) ; must set end first
+                  str (substring str 0 (match-beginning 1))))
+        (list str beg end)))))
+
+(defun mouse-me-build-menu (name)
+  "Return a menu tailored for NAME for `mouse-me' from `mouse-me-menu-commands'."
+  (list "Mouse Me" (cons "Mouse Me"
+                         (append (list (cons
+                                        (if (< (length name) 65)
+                                            name
+                                          "...Long String...")
+                                        'kill-new)
+                                       "---")
+                                 mouse-me-menu-commands))))
+
+;;;; Commands for the menu
+
+(defun mouse-me-emacs-command-info (string)
+  "Look in Emacs info for command named STRING."
+  (interactive "sCommand: ")
+  (let ((s (intern-soft string)))
+    (if (and s (commandp s))
+        (Info-goto-emacs-command-node s)
+      (error "No command named `%s'" string))))
+
+(defun mouse-me-describe-function (string)
+  "Describe function named STRING."
+  (interactive "sFunction: ")
+  (let ((s (intern-soft string)))
+    (if (and s (fboundp s))
+        (describe-function s)
+      (error "No function named `%s'" string))))
+
+(defun mouse-me-describe-variable (string)
+  "Desribe variable named STRING."
+  (interactive "sVariable: ")
+  (let ((s (intern-soft string)))
+    (if (and s (boundp s))
+        (describe-variable s)
+      (error "No variable named `%s'" string))))
+
+(defun mouse-me-elp-instrument-function (string)
+  "Instrument Lisp function named STRING."
+  (interactive "sFunction: ")
+  (let ((s (intern-soft string)))
+    (if (and s (fboundp s))
+        (elp-instrument-function s)
+      (error "Must be the name of an existing Lisp function"))))
+
+(defun mouse-me-execute (string)
+  "Execute STRING as a filename."
+  (interactive "sFile: ")
+  (if (fboundp 'w32-shell-execute)
+      (w32-shell-execute "open" (convert-standard-filename string))
+    (message "This function currently working only in W32.")))
+
+
+(defun mouse-me-bbdb (string)
+  "Lookup STRING in bbdb."
+  (interactive "sBBDB Lookup: ")
+  (if (fboundp 'bbdb)
+      (bbdb string nil)
+    (error "BBDB not loaded")))
+
+(defun mouse-me-finger (string)
+  "Finger a STRING mail address."
+  (interactive "sFinger: ")
+  (save-match-data
+    (if (string-match "\\(.*\\)@\\([-.a-zA-Z0-9]+\\)$" string)
+        (finger (match-string 1 string) (match-string 2 string))
+      (error "Not in user@host form: %s" string))))
+
+(defun mouse-me-grep (string)
+  "Grep for a STRING."
+  (interactive "sGrep: ")
+  (require 'compile)
+  (grep-compute-defaults)
+  (let ((ext (mouse-me-buffer-file-extension)))
+    (grep (concat grep-command string
+                  (if mouse-me-grep-use-extension
+                      (if ext
+                          (concat " *" ext)
+                        " *"))))))
+
+(defun mouse-me-find-grep (string)
+  "Grep for a STRING."
+  (interactive "sGrep: ")
+  (grep-compute-defaults)
+  (let ((reg grep-find-command)
+        (ext (mouse-me-buffer-file-extension)))
+    (if (string-match "\\(^.+-type f \\)\\(.+$\\)" reg)
+        (setq reg (concat (match-string 1 reg)
+                          (if mouse-me-grep-use-extension
+                              (concat "-name \"*" ext "\" "))
+                          (match-string 2 reg))))
+    (grep-find (concat reg string))))
+
+;;;; Internal Functions
+
+(defun mouse-me-buffer-file-extension ()
+  "Return the extension of the current buffer's filename or nil.
+Returned extension is a string beginning with a period."
+  (let* ((bfn (buffer-file-name))
+         (filename (and bfn (file-name-sans-versions bfn)))
+         (index (and filename (string-match "\\.[^.]*$" filename))))
+    (if index
+        (substring filename index)
+      "")))
+
+(defun mouse-me-helper (event func)
+  "Determine the string to use to process EVENT and call FUNC to get cmd."
+  (let (name sp sm mouse beg end cmd mmtype)
+    ;; temporarily goto where the event occurred, get the name clicked
+    ;; on and enough info to figure out what to do with it
+    (save-match-data
+      (save-excursion
+        (setq sp (point))               ; saved point
+        (setq sm (mark t))              ; saved mark
+        (set-buffer (window-buffer (posn-window (event-start event))))
+        (setq mouse (goto-char (posn-point (event-start event))))
+        ;; if there is a region and point is inside it
+        ;; check for sm first incase (null (mark t))
+        ;; set name to either the thing they clicked on or region
+        (if (and sm
+                 (or (and transient-mark-mode mark-active)
+                     (eq last-command 'mouse-drag-region))
+                 (>= mouse (setq beg (min sp sm)))
+                 (<= mouse (setq end (max sp sm))))
+            (setq name (buffer-substring beg end))
+          (setq name (funcall mouse-me-get-string-function))
+          (if (listp name)
+              (setq beg (nth 1 name)
+                    end (nth 2 name)
+                    name (car name))
+            (goto-char mouse)
+            (while (not (looking-at (regexp-quote name)))
+              (backward-char 1))
+            (setq beg (point))
+            (setq end (search-forward name))))))
+    ;; check if name is null, meaning they clicked on no word
+    (if (or (null name)
+            (and (stringp name) (string= name "" )))
+        (error "No string to pass to function"))
+    ;; popup a menu to get a command to run
+    (setq cmd (funcall func))
+    ;; run the command, eval'ing if it was a list
+    (if (listp cmd)
+        (setq cmd (eval cmd t)))
+    (setq mmtype (get cmd 'mouse-me-type))
+    (cond ((eq mmtype 'region)
+           (funcall cmd beg end))
+          ((eq mmtype 'string)
+           (funcall cmd name))
+          (t
+           (funcall cmd name)))))
+
+(provide 'mouseme)
+
+;;; mouseme.el ends here
diff --git a/elpa/ess-20260424.1544/obsolete/msdos.el b/elpa/ess-20260424.1544/obsolete/msdos.el
new file mode 100644 (file)
index 0000000..f3e1d9a
--- /dev/null
@@ -0,0 +1,163 @@
+;;; msdos.el --- Run an MS-DOS shell in an NTemacs buffer with bash as the shell  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1999-2022 Free Software Foundation, Inc.
+;; Author: Richard M. Heiberger <rmhNOSPAMtemple.edu>
+;; Created: February 1999
+;; Maintainer: ESS-core <ESS-coreNOSPAMr-project.org>
+
+;; This file is part of GNU Emacs.
+
+;;; License:
+;;
+;; This program 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 3 of the License, or
+;; (at your option) any later version.
+;;
+;; This program 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see
+;; <http://www.gnu.org/licenses/>
+
+;;; Commentary:
+
+;; The file msdos.el in the next mail message opens an *msdos* buffer
+;; in shell-mode and msdos-minor-mode.  When cmdproxy.exe/command.com
+;; is the Emacs shell, then this gets various setting right that M-x
+;; shell currently misses.  The function M-x msdos-minor-mode could be
+;; automatically run by Emacs in shell-mode in that case.
+
+;; When bash is the Emacs shell, msdos.el still opens a
+;; cmdproxy.exe/command.com shell in the buffer *msdos*.  There are
+;; occasions when it is necessary to run DOS character-based programs
+;; in an Emacs window.
+
+;; I followed the suggestion by AndrewI to look at M-x shell and modify
+;; it.  It turns out not to have been trivial.
+
+;;; Code:
+
+(require 'shell); and hence 'comint
+
+;;; Customization and Buffer Variables
+
+(defcustom explicit-msdos-shell-file-name "cmdproxy.exe"
+  "*If non-nil, is file name to use for explicitly requested msdos
+inferior shell."
+  :type '(choice (const :tag "None" nil) file)
+  :group 'shell)
+
+(defcustom explicit-msdos-comspec-file-name
+  (if (w32-using-nt)
+      "cmd.exe"
+    "command.com")
+  "*If non-nil, is file name to use for explicitly requested COMSPEC
+environment variable."
+  :type '(choice (const :tag "None" nil) file)
+  :group 'shell)
+
+(defvar-local msdos-minor-mode nil
+  "Non-nil if using msdos-minor mode as a minor mode of some other mode.")
+
+(defun msdos ()
+  "Run an inferior msdos shell, with I/O through buffer *msdos*.
+This function is intended to be used in an Ntemacs session in which
+bash is the primary shell.  But sometimes an MSDOS window, within emacs,
+is also needed.
+
+If buffer exists but shell process is not running, make new shell.
+If buffer exists and shell process is running, just switch to buffer `*msdos*'.
+Program used comes from variable `explicit-msdos-shell-file-name'.
+If a file `~/.emacs_SHELLNAME' exists, it is given as initial input
+ (Note that this may lose due to a timing error if the shell
+  discards input when it starts up.)
+The buffer is put in Shell mode, giving commands for sending input
+and controlling the subjobs of the shell.  See `shell-mode'.
+See also the variable `shell-prompt-pattern'.
+
+The buffer is put into \\[msdos-minor-mode].  See `msdos-minor-mode'.
+
+The COMSPEC environment variable in the inferior shell, but not in the emacs
+process, is set to `explicit-msdos-comspec-file-name'.
+The SHELL environment variable in the inferior shell, but not in the emacs
+process, is set to `explicit-msdos-shell-file-name'.
+
+The shell file name (sans directories) is used to make a symbol name
+such as `explicit-csh-args'.  If that symbol is a variable,
+its value is used as a list of arguments when invoking the shell.
+
+\(Type \\[describe-mode] in the shell buffer for a list of commands.)"
+  (interactive)
+  (if (not (comint-check-proc "*msdos*"))
+      (let* ((prog explicit-msdos-shell-file-name)
+             (name (file-name-nondirectory prog))
+             (startfile (concat "~/.emacs_" name))
+             (xargs-name (intern-soft (concat "explicit-" name "-args")))
+             shell-buffer
+             (comspec (getenv "COMSPEC"))
+             (shell (getenv "SHELL"))
+             )
+        (save-excursion
+          (setenv "COMSPEC" explicit-msdos-comspec-file-name)
+          (setenv "SHELL" explicit-msdos-shell-file-name)
+          (set-buffer (apply #'make-comint "msdos" prog
+                             (if (and xargs-name (boundp xargs-name))
+                                 (symbol-value xargs-name))
+                             (if (file-exists-p startfile)
+                                 (concat "/k " startfile))))
+          (setenv "COMSPEC" comspec)
+          (setenv "SHELL" shell)
+          (setq shell-buffer (current-buffer))
+          (shell-mode)
+          (msdos-minor-mode)
+          (sleep-for 4) ; need to wait, else working too fast!
+                      ;;; The `exit' warning should precede the "c:\" prompt.
+                      ;;; If not, then increase the sleep-for time!
+          (goto-char (point-min))
+          (insert
+           "Remember to exit this buffer with `exit'.  If you kill the
+buffer without exiting, you may not be able to shut down Windows cleanly.")
+          (goto-char (point-max)))
+        (pop-to-buffer shell-buffer))
+    (pop-to-buffer "*msdos*")))
+
+
+(defun msdos-minor-mode ()
+  "Minor mode for running msdos in a shell-mode buffer:
+a. Uses \\[set-buffer-process-coding-system] to set the coding system
+to `'raw-text-dos'.  The DOS C-m C-l end-of-line is critical.  The
+shell freezes without it.
+
+b. The variable `comint-completion-addsuffix' is set to `\\' for directories.
+
+c. Prevents echoing of commands.
+
+d. strips ctrl-m from output.
+"
+  (interactive)
+  (setq msdos-minor-mode t)
+  (set (make-local-variable 'comint-completion-addsuffix) '("\\" . " "))
+  (setq comint-process-echoes t)
+  (add-hook 'comint-output-filter-functions #'shell-strip-ctrl-m nil t)
+  (set-process-coding-system (get-buffer-process (current-buffer)) 'raw-text-dos 'raw-text-dos)
+  ;; buffer-process-coding-system is critical.
+  )
+
+;; Install ourselves:
+
+
+(put 'msdos-minor-mode 'permanent-local t)
+(or (assq 'msdos-minor-mode minor-mode-alist)
+    (setq minor-mode-alist
+          (append minor-mode-alist
+                  (list '(msdos-minor-mode " msdos")))))
+
+;; Provide ourselves:
+
+(provide 'msdos)
+
+;;; msdos.el ends here