ESS: retrieving command history from commands entered in ESS[R] inferior mode or script

1.2k Views Asked by At

When using ESS[R] in inferior mode I can retrieve the most recent command output using C-c C-p which moves the cursor to the previous command output. Alternatively I can use C-up which essentially copies the most recently entered command from the inferior process (similar to how readline works). I prefer the C-up approach but unfortunately it does not retrieve commands that were entered from a script using any of the ess-eval commads. Is there to get the functionality of C-up for commands entered in both inferior mode and by ess-eval?

2

There are 2 best solutions below

2
On BEST ANSWER

Your solution works fine for single line commands, but needs a small tweak to handle multi-line statements:

(defun ess-readline ()
  "Move to previous command entered from script *or* R-process and copy 
   to prompt for execution or editing"
  (interactive)
  ;; See how many times function was called
  (if (eq last-command 'ess-readline)
      (setq ess-readline-count (1+ ess-readline-count))
    (setq ess-readline-count 1))
  ;; Move to prompt and delete current input
  (comint-goto-process-mark)
  (end-of-buffer nil) ;; tweak here
  (comint-kill-input)
  ;; Copy n'th command in history where n = ess-readline-count
  (comint-previous-prompt ess-readline-count)
  (comint-copy-old-input)
  ;; Below is needed to update counter for sequential calls
  (setq this-command 'ess-readline)
)
(global-set-key (kbd "\C-cp") 'ess-readline)

This enables you to move up through the previous commands; the following function enables you to move back down again, so you can go up and down to find the command you're after:

(defun ess-readnextline ()
  "Move to next command after the one currently copied to prompt and copy 
   to prompt for execution or editing"
  (interactive)
  ;; Move to prompt and delete current input
  (comint-goto-process-mark)
  (end-of-buffer nil)
  (comint-kill-input)
  ;; Copy (n - 1)'th command in history where n = ess-readline-count
  (setq ess-readline-count (max 0 (1- ess-readline-count)))
  (when (> ess-readline-count 0)
      (comint-previous-prompt ess-readline-count)
  (comint-copy-old-input))
  ;; Update counter for sequential calls
  (setq this-command 'ess-readline)
)
(global-set-key (kbd "\C-cn") 'ess-readnextline)
1
On

It doesn't seem that there is any built in function to do this so I wrote the function below. Essentially this function automates the process of using the keystokes C-c C-p to move the cursor to a previous command in the R-process buffer followed by C-c RET to copy that command to the prompt for editing

(defun ess-readline ()
  "Move to previous command entered from script *or* R-process and copy 
   to prompt for execution or editing"
  (interactive)
  ;; See how many times function was called
  (if (eq last-command 'ess-readline)
      (setq ess-readline-count (1+ ess-readline-count))
    (setq ess-readline-count 1))
  ;; Move to end of buffer and delete current input
  (end-of-buffer nil)
  (comint-kill-input)
  ;; Copy n'th command in history where n = ess-readline-count
  (comint-previous-prompt ess-readline-count)
  (comint-copy-old-input)
  ;; Below is needed to update counter for sequential calls
  (setq this-command 'ess-readline)
)
(global-set-key (kbd "\C-cp") 'ess-readline)