update of packages

This commit is contained in:
2023-11-04 19:26:41 +01:00
parent e162a12b58
commit 3b54a3236d
726 changed files with 297673 additions and 34585 deletions

View File

@@ -1,6 +1,6 @@
;;; ess-inf.el --- Support for running S as an inferior Emacs process -*- lexical-binding: t; -*-
;; Copyright (C) 1989-2022 Free Software Foundation, Inc.
;; Copyright (C) 1989-2023 Free Software Foundation, Inc.
;; Author: David Smith <dsmith@stats.adelaide.edu.au>
;; Created: 7 Jan 1994
@@ -103,7 +103,8 @@ been initialized."
(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))))
(alist-get 'ess-mode-syntax-table ess-local-customize-alist))
t))
(inferior-ess-mode)))))
;;*;; Process handling
@@ -129,6 +130,11 @@ If `ess-plain-first-buffername', then initial process is number-free."
(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
@@ -160,7 +166,7 @@ This may be useful for debugging."
;; 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))))
(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
@@ -202,15 +208,14 @@ This may be useful for debugging."
(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))
(when ess-setwd-command
(ess-set-working-directory default-directory))
(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 3): waiting for process after hook")
(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)
@@ -288,7 +293,6 @@ Default depends on the ESS language/dialect and hence made buffer local")
BEG and END signify the bounds, VERBOSE gets passed to
`font-lock-default-fontify-region'."
(let* ((buffer-undo-list t)
(inhibit-point-motion-hooks t)
(font-lock-dont-widen t)
(font-lock-extend-region-functions nil)
(pos1 beg)
@@ -356,14 +360,13 @@ defined. If no project directory has been found, use
;; 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")
#'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")
#'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 (and ess-local-process-name
(get-process ess-local-process-name)))))
(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)))
@@ -478,10 +481,16 @@ inserted in the process buffer instead of the command buffer."
(process-put proc 'busy nil))))
(defun ess--delimiter-start-re (delim)
(concat "\\(" delim "-START$\\)"))
(concat "\\(" delim "-START\r*$\\)"))
(defun ess--delimiter-end-re (delim)
(concat "\\(" delim "-END\\)"))
(concat "\\(" delim "-END\r*\\)"))
(defun ess--delimiter-error-start-re ()
"ESSR::ERROR \\(\"\\)")
(defun ess--delimiter-error-end-re ()
"\\(\"\\)")
(defun inferior-ess-mark-as-busy (proc)
"Put PROC's busy value to t."
@@ -518,8 +527,9 @@ inserted in the process buffer instead of the command buffer."
--> 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 <--
--> string:%s\n"
(or filter "NORMAL-FILTER")
--> 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)
@@ -529,6 +539,8 @@ inserted in the process buffer instead of the command buffer."
(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))))
@@ -608,8 +620,8 @@ process-less buffer because it was created with
(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)
(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)))
@@ -640,7 +652,9 @@ 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)))
(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)))
@@ -668,7 +682,7 @@ local ESS vars like `ess-local-process-name'."
(,dialect ess-dialect)
(,alist ess-local-customize-alist))
(with-current-buffer ,buffer
(ess-setq-vars-local (eval ,alist))
(ess-setq-vars-local (eval ,alist t))
(setq ess-local-process-name ,lpn)
(setq ess-dialect ,dialect)
,@body))))
@@ -754,10 +768,8 @@ Returns the name of the process, or nil if the current buffer has none."
"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'"
(and (or proc ess-local-process-name)
(let ((proc (or proc (get-process ess-local-process-name))))
(and (processp proc)
(process-live-p proc)))))
(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.
@@ -830,8 +842,10 @@ to `ess-completing-read'."
'ess-dialect
(process-buffer (get-process
(car pname-list))))))))
;; try to start "the appropriate" process, don't show the buffer
;; 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
@@ -857,6 +871,8 @@ to `ess-completing-read'."
;; 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))))))
@@ -866,7 +882,12 @@ to `ess-completing-read'."
(let ((proc-buf (ess-get-process-buffer proc)))
(if noswitch
(display-buffer proc-buf)
(pop-to-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)
@@ -900,26 +921,50 @@ it was successfully forced, throws an error otherwise."
(interactive)
(ess-force-buffer-current "Process to use: " 'force nil 'ask-if-1))
(defun ess-get-next-available-process (&optional dialect ignore-busy)
(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."
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 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)))
(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
@@ -1049,38 +1094,42 @@ Returns nil if TIMEOUT was reached, non-nil otherwise."
(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))
(early-exit t))
(cmd-delim (process-get proc 'cmd-output-delimiter)))
(when (buffer-live-p cmd-buf)
(unwind-protect
(ess--exit-protect
(progn
(with-current-buffer cmd-buf
(goto-char (point-max))
(insert string))
(when-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)))
(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)))))))
(setq early-exit nil))
(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.
(when early-exit
(process-put proc 'busy nil)
(funcall (process-get proc 'cmd-restore-function)))))))
(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.
@@ -1154,7 +1203,7 @@ Hide all the junk output in temporary buffer."
;; 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)
(set-process-filter proc #'inferior-ess-ordinary-filter)
(interrupt-process proc)
(when cb
(ess-if-verbose-write "executing interruption callback ... ")
@@ -1286,19 +1335,6 @@ This handles Tramp when working on a remote."
(user-error "ESS process not ready. Finish your command before trying again")))
proc)
(defvar-local ess-format-command-alist nil
"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.")
(defvar inferior-ess--output-delimiter-count 0)
(defun inferior-ess--output-delimiter ()
(setq inferior-ess--output-delimiter-count (1+ inferior-ess--output-delimiter-count))
@@ -1345,71 +1381,112 @@ wrapping the code into:
(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)))
(use-delimiter (alist-get 'use-delimiter ess-format-command-alist))
(rich-cmd (if-let ((cmd-fun (alist-get 'fun ess-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 ..)" cmd))
(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
(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))
(when early-exit
;; Protect process interruption from further quits
(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")
(process-put proc 'cmd-output-delimiter nil))
(goto-char (point-max))
(ess--interrupt proc)))))))
(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 ()
@@ -1680,7 +1757,7 @@ Prefix arg VIS toggles visibility of ess-code as for
(setq msg (format "Eval function: %s"
(if (looking-at add-log-current-defun-header-regexp)
(match-string 1)
(buffer-substring (point) (point-at-eol)))))
(buffer-substring (point) (line-end-position)))))
(setq beg (point))
(end-of-defun)
(setq end (point))
@@ -1696,7 +1773,7 @@ Prefix arg VIS toggles visibility of ess-code as for
Prefix arg VIS toggles visibility of ess-code as for `ess-eval-region'."
(interactive "P")
(let ((start-pos (point)))
(if (= (point-at-bol) (point-min))
(if (= (line-beginning-position) (point-min))
(ess-next-code-line 0)
;; Evaluation is forward oriented
(forward-line -1)
@@ -1787,8 +1864,8 @@ input will fail."
"Send the current line to the inferior ESS process.
VIS has same meaning as for `ess-eval-region'."
(interactive "P")
(let* ((beg (point-at-bol))
(end (point-at-eol))
(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)))
@@ -1832,7 +1909,8 @@ 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")
(define-obsolete-function-alias 'ess-eval-line-and-step-invisibly
#'ess-eval-line-invisibly-and-step "18.10")
;;;*;;; Evaluate and switch to S
@@ -2013,9 +2091,10 @@ node `(ess)Top'. If you accidentally suspend your process, use
"]: %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)
(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)
@@ -2149,13 +2228,13 @@ If in the output field, goes to the beginning of previous input."
(if (looking-at inferior-ess-prompt) ; cust.var, might not include sec-prompt
(progn
(comint-skip-prompt)
(setq command (buffer-substring-no-properties (point) (point-at-eol)))
(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 (point-at-eol) t)
(re-search-forward inferior-ess-secondary-prompt (line-end-position) t)
(setq command (concat command "\n"
(buffer-substring-no-properties (point) (point-at-eol))))))
(buffer-substring-no-properties (point) (line-end-position))))))
(forward-line -1)
command)
(message "No command at this point")
@@ -2167,6 +2246,17 @@ If in the output field, goes to the beginning of previous input."
(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)))))
;;;*;;; Hot key commands
@@ -2220,6 +2310,8 @@ 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)))
@@ -2227,6 +2319,12 @@ in `ess-r-post-run-hook' or `ess-S+-post-run-hook'."
(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
@@ -2650,7 +2748,7 @@ name that contains :,$ or @."
(goto-char (point-min))
(when (re-search-forward "(list" nil t)
(goto-char (match-beginning 0))
(setq args (ignore-errors (eval (read (current-buffer)))))
(setq args (ignore-errors (eval (read (current-buffer)) t)))
(when args
(setcar args (cons (car args) (current-time)))))
;; push even if nil
@@ -2911,8 +3009,8 @@ P-STRING is the prompt string."
(car ess--handy-history))))
(call-interactively
(cdr (assoc (ess-completing-read "Execute"
(sort (mapcar 'car commands)
'string-lessp)
(sort (mapcar #'car commands)
#'string-lessp)
nil t nil 'ess--handy-history hist)
commands)))))
@@ -2955,9 +3053,9 @@ NO-ERROR prevents errors when this has not been implemented for
(unless no-error
(error "Not implemented for dialect %s" ess-dialect))))
(defalias 'ess-change-directory 'ess-set-working-directory)
(defalias 'ess-change-directory #'ess-set-working-directory)
(define-obsolete-function-alias
'ess-use-dir 'ess-set-working-directory "ESS 18.10")
'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.
@@ -2978,7 +3076,7 @@ NO-ERROR prevents errors when this has not been implemented for
(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
(when (and (ess-can-eval-in-background)
ess-getwd-command
(inferior-ess-available-p))
(ess-when-new-input last-sync-dirs
@@ -3018,7 +3116,7 @@ path, and can be a remote path"
(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
(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))