update packages

This commit is contained in:
2021-01-08 19:32:30 +01:00
parent ce8f24d28a
commit f5649dceab
467 changed files with 26642 additions and 22487 deletions

View File

@@ -332,12 +332,12 @@ name. Abbreviation is performed by `abbreviate-file-name'. See
(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.
PROJECT-ROOT is directory name returned by `project-roots'. If no
PROJECT-ROOT is directory name returned by `ess-project-root'. 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 (car (project-roots p))))
(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)))
@@ -345,12 +345,12 @@ project directory has been found use
(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 `project-roots' if
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 (car (project-roots p))))
(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)))
@@ -407,6 +407,24 @@ Return non-nil if the process is in a ready (not busy) state."
(string-match (concat "\\(" inferior-ess-secondary-prompt "\\)\\'") string)))
ready))
(defun inferior-ess--set-status-sentinel (proc output-buf sentinel)
(with-current-buffer output-buf
(save-excursion
(save-match-data
;; The only assumption is that the prompt finishes with "> "
(goto-char (- (point-max) 2))
(when (looking-at inferior-ess-primary-prompt)
(goto-char (point-min))
(when (re-search-forward (inferior-ess--sentinel-start-re sentinel) nil t)
(delete-region (match-beginning 0) (1+ (match-end 0))))
(when (re-search-forward (concat "^\\(" sentinel "-END[\n\r]+\\)") nil t)
(delete-region (match-beginning 0) (match-end 0))
(process-put proc 'busy nil)
(process-put proc 'ess-output-sentinel nil)))))))
(defun inferior-ess--sentinel-start-re (sentinel)
(concat "^\\(" sentinel "-START$\\)"))
(defun inferior-ess-mark-as-busy (proc)
"Put PROC's busy value to t."
(process-put proc 'busy t)
@@ -719,26 +737,35 @@ LANGUAGE is ignored."
(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."
(interactive
(list "Switch to which ESS process? " current-prefix-arg))
; prefix sets 'noswitch
(ess-write-to-dribble-buffer "ess-request-a-process: {beginning}\n")
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)
(setq 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" "XLS" "ViSta")))))
(let* ((pname-list (delq nil ;; keep only those matching dialect
(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
(append
(mapcar (lambda (lproc)
(and (equal ess-dialect
@@ -752,56 +779,47 @@ Returns the name of the selected process."
(when (assoc ess-local-process-name ess-process-name-list)
(list ess-local-process-name)))))
(num-processes (length pname-list))
(auto-started?))
(if (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
(progn
(ess-write-to-dribble-buffer
(concat " ... request-a-process:\n "
(format
"major mode %s; current buff: %s; ess-language: %s, ess-dialect: %s\n"
major-mode (current-buffer) ess-language ess-dialect)))
(ess-start-process-specific ess-language ess-dialect)
(ess-write-to-dribble-buffer
(format " ... request-a-process: buf=%s\n" (current-buffer)))
(setq num-processes 1
pname-list (car ess-process-name-list)
auto-started? t)))
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--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))
(proc
pname-list)))
(setq proc
(if (or auto-started?
(and (not ask-if-1) (= 1 num-processes)))
(progn
(message "using process '%s'" (car proc-buffers))
(car pname-list))
;; else
(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))
(when message
(setq message (replace-regexp-in-string ": +\\'" "" message))) ;; <- why is this here??
;; 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 (equal buf "*new*")
(progn
(ess-start-process-specific ess-language ess-dialect) ;; switches to proc-buff
(caar ess-process-name-list))
(process-name (get-buffer-process buf))
))
)))
(if noswitch
(pop-to-buffer (current-buffer)) ;; VS: this is weird, but is necessary
(pop-to-buffer (buffer-name (process-buffer (get-process proc)))))
proc)))
(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--with-no-pop-to-buffer
(ess-start-process-specific ess-language ess-dialect))
(caar ess-process-name-list))))))
(unless noswitch
(pop-to-buffer (ess-get-process-buffer proc)))
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.
@@ -900,9 +918,10 @@ toggled."
(message "Found no buffers for `ess-dialect' %s associated with process %s"
dialect proc-name)))
(ess-switch-to-ESS eob))
(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))))
(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)
@@ -956,7 +975,9 @@ 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."
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))
@@ -977,14 +998,20 @@ non-nil stop waiting for output after TIMEOUT seconds."
(redisplay 'force))
(setq elapsed (- (float-time) start-time))
(when (> elapsed .3)
(setq wait .3))))))
(setq wait .3))))
(< elapsed timeout)))
(defun inferior-ess-ordinary-filter (proc string)
(inferior-ess--set-status proc string)
(ess--if-verbose-write-process-state proc string "ordinary-filter")
(inferior-ess-run-callback proc string)
(with-current-buffer (process-buffer proc)
(insert string)))
(let ((sentinel (process-get proc 'ess-output-sentinel)))
(unless sentinel
(inferior-ess--set-status proc string)
(inferior-ess-run-callback proc string))
(ess--if-verbose-write-process-state proc string "ordinary-filter")
(with-current-buffer (process-buffer proc)
(insert string))
(when sentinel
(inferior-ess--set-status-sentinel proc (process-buffer proc) sentinel)
(inferior-ess-run-callback proc string))))
(defvar ess-presend-filter-functions nil
"List of functions to call before sending the input string to the process.
@@ -1191,16 +1218,45 @@ This handles Tramp when working on a remote."
(user-error "ESS process not ready. Finish your command before trying again")))
proc)
(defun ess-command (cmd &optional out-buffer _sleep no-prompt-check wait proc force-redisplay)
(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-sentinel' : Whether to wait for an output sentinel. If
non-nil, `fun' should get the `output-sentinel' 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-sentinel-count 0)
(defun inferior-ess--output-sentinel ()
(setq inferior-ess--output-sentinel-count (1+ inferior-ess--output-sentinel-count))
(format "ess-output-sentinel%s" inferior-ess--output-sentinel-count))
;; NOTE: We might want to switch to somethig 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.
SLEEP is deprecated and no longer has any effect. WAIT and
FORCE-REDISPLAY are as in `ess-wait-for-process' and are passed
to `ess-wait-for-process'.
`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 1
second. 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
@@ -1219,47 +1275,78 @@ wrapping the code into:
;; Set `inhibit-quit' to t to avoid dumping R output to the
;; process buffer if `ess-command' gets interrupted for some
;; reason. See bugs #794 and #842
(inhibit-quit t))
(inhibit-quit t)
(sentinel (inferior-ess--output-sentinel))
(timeout (or timeout 1)))
(with-current-buffer (process-buffer proc)
(let ((primary-prompt inferior-ess-primary-prompt)
(let ((proc-alist (ess--alist (ess-local-process-name
inferior-ess-primary-prompt)))
(oldpb (process-buffer proc))
(oldpf (process-filter proc))
(oldpm (marker-position (process-mark proc))))
(oldpm (marker-position (process-mark proc)))
(use-sentinel (alist-get 'use-sentinel 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-sentinel sentinel))
cmd))
(early-exit t))
(ess-if-verbose-write (format "(ess-command %s ..)" cmd))
;; Swap the process buffer with the output buffer before
;; sending the command
(unwind-protect
(progn
(when use-sentinel
(process-put proc 'ess-output-sentinel sentinel))
(set-process-buffer proc out-buffer)
(set-process-filter proc 'inferior-ess-ordinary-filter)
(with-current-buffer out-buffer
(setq inferior-ess-primary-prompt primary-prompt)
(ess-setq-vars-local proc-alist)
(setq buffer-read-only nil)
(erase-buffer)
(set-marker (process-mark proc) (point-min))
(inferior-ess-mark-as-busy proc)
(process-send-string proc cmd)
(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!
(ess-wait-for-process proc nil wait force-redisplay)
;; Should (almost) never be incomplete unless the message
;; contains "> " and was accidentally split by the process
;; right there.
(while (eq :incomplete (ess-mpi-handle-messages (current-buffer)))
(ess-wait-for-process proc nil wait force-redisplay))
;; Remove prompt
;; If output is cat(..)ed this deletes the output
(unless (ess-wait-for-process proc nil wait force-redisplay timeout)
(error "Timeout during background ESS command '%s'"
(ess--strip-final-newlines cmd)))
;; Remove prompt. If output is cat(..)ed without a
;; final newline, this deletes the last line of output.
(goto-char (point-max))
(delete-region (point-at-bol) (point-max)))
(ess-if-verbose-write " .. ok{ess-command}")))
(ess-if-verbose-write " .. exiting{ess-command}\n")
(delete-region (point-at-bol) (point-max))))
(setq early-exit nil))
;; Restore the process buffer in its previous state
(when early-exit
(with-current-buffer out-buffer
(goto-char (point-min))
(when (and use-sentinel
(not (re-search-forward
(inferior-ess--sentinel-start-re sentinel)
nil t)))
;; CMD probably failed to parse if the start sentinel
;; can't be found in the output. Disable the sentinel
;; before interrupt to avoid a freeze.
(process-put proc 'ess-output-sentinel nil))
(goto-char (point-max))
(ess-interrupt)))
(process-put proc 'ess-output-sentinel nil)
(set-process-buffer proc oldpb)
(set-process-filter proc oldpf)
(set-marker (process-mark proc) oldpm))))
out-buffer))
;; 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.
@@ -1357,40 +1444,38 @@ similar to `load-library' Emacs function."
;;*;; Evaluating lines, paragraphs, regions, and buffers.
(defun ess-eval-linewise
(text &optional invisibly eob even-empty wait-last-prompt sleep-sec wait-sec)
(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 go to end of 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
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
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."
(unless (numberp wait-sec)
(setq wait-sec 0.001))
(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}
(sprocess (ess-get-process ess-current-process-name))
(sbuffer (process-buffer sprocess))
(win (get-buffer-window sbuffer t)))
(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 sprocess text)))
(with-current-buffer sbuffer
(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 sprocess)))
(if (stringp invisibly)
(insert-before-markers (concat "*** " invisibly " ***\n")))
(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))
@@ -1401,26 +1486,30 @@ TEXT."
"\n"
(concat (substring text 0 pos) "\n"))))
(setq text (substring text (min (length text) (1+ pos))))
(goto-char (marker-position (process-mark sprocess)))
(if win (set-window-point win (process-mark sprocess)))
(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 sprocess) (point)))
(inferior-ess-mark-as-busy sprocess)
(process-send-string sprocess 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 sprocess t wait-sec)))
(if eob (with-temp-buffer (buffer-name sbuffer)))
(goto-char (marker-position (process-mark sprocess)))
(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))))))
(if (numberp sleep-sec)
(sleep-for sleep-sec)))
(when (numberp sleep-sec)
(sleep-for sleep-sec)))
;;;*;;; Evaluate only
@@ -2173,18 +2262,18 @@ method, see `ess-quit--override'."
This sends an interrupt and quits a debugging session."
(interactive)
(inferior-ess-force)
(let ((proc (ess-get-process)))
(let ((proc (ess-get-process))
(timeout 1))
;; Interrupt current task before reloading. Useful if the process is
;; prompting for input, for instance in R in case of a crash
(interrupt-process proc comint-ptyp)
;; Workaround for Windows terminals
(unless (memq system-type '(gnu/linux darwin))
(process-send-string nil "\n"))
(ess-wait-for-process proc)
;; Quit debugging session before reloading
(when (ess-debug-active-p)
(ess-debug-command-quit)
(ess-wait-for-process proc))))
(unless (ess-wait-for-process proc nil nil nil timeout)
(error "Timeout while interrupting process"))
(with-current-buffer (process-buffer proc)
(goto-char (process-mark proc)))))
(defun ess-abort ()
"Kill the ESS process, without executing .Last or terminating devices.
@@ -2240,12 +2329,16 @@ START-ARGS gets passed to the dialect-specific
(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-directory-function nil)
(ess-startup-directory (ess-get-working-directory))
(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)
@@ -2342,11 +2435,13 @@ non-nil, don't return objects in first positon (.GlobalEnv)."
(setq i (1+ i)))
(setq ess-object-list (delete-dups result))))))
(defun ess-get-words-from-vector (command &optional no-prompt-check wait proc)
(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, and PROC are passed to `ess-command'.
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});
@@ -2365,7 +2460,7 @@ print(out, max=1e6) })\n\"."
"\\( \\|$\\)"; space or end
))
words)
(ess-command command tbuffer 'sleep no-prompt-check wait proc)
(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)
@@ -2377,6 +2472,10 @@ print(out, max=1e6) })\n\"."
(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."
@@ -2800,8 +2899,9 @@ To be used in `ess-idle-timer-functions'."
(inferior-ess-available-p))
(ess-when-new-input last-sync-dirs
(ess-if-verbose-write "\n(ess-synchronize-dirs)\n")
(setq default-directory
(car (ess-get-words-from-vector ess-getwd-command)))
(let ((lpath (car (ess-get-words-from-vector ess-getwd-command))))
(setq default-directory
(ess--derive-connection-path default-directory lpath)))
default-directory)))
(defun ess-dirs ()
@@ -2810,9 +2910,19 @@ To be used in `ess-idle-timer-functions'."
;; default-directory and subprocess working directory are
;; synchronized automatically.
(interactive)
(let ((dir (car (ess-get-words-from-vector "getwd()\n"))))
(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 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 ()