ESS: 从在ESS[R]下输入的命令或脚本中检索命令历史记录

4

在使用ESS[R]时,如果以劣质模式进行操作,您可以使用C-c C-p检索最近的命令输出,该快捷键将光标移动到上一条命令输出。或者,您也可以使用C-up,它基本上会从劣质进程中复制最近输入的命令(类似于readline的工作方式)。我更喜欢使用C-up方法,但不幸的是,它无法检索使用任何ess-eval命令从脚本输入的命令。是否有方法可以获取C-up功能,以便检索在劣质模式和ess-eval中输入的命令?

2个回答

3

你的解决方案对单行命令有效,但需要进行一些小调整才能处理多行语句:

(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)

这可以让您向上移动到先前的命令; 以下功能使您能够再次向下移动,因此您可以上下移动以找到所需的命令:

(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)

谢谢!值得一提的是,这两种解决方案都可能无法在旧版本的ESS上运行,即使在最新版本(14.9)中,对于多行命令的重复调用也无法正常工作(这可能是当前版本ESS中的一个错误)。请参见https://stat.ethz.ch/pipermail/ess-help/2014-December/010373.html。 - Manuel Morales
谢谢!优秀的解决方案。 但是,这并没有解决搜索先前执行命令的问题。例如,comint-history-isearch-backward-regexp(M-r)只能搜索comint历史记录。为什么ess不将评估的命令放入comint历史记录中呢? - dk.

1

看起来并没有内置函数可以做到这一点,所以我编写了下面的函数。本质上,此函数自动化了使用按键C-c C-p将光标移动到R进程缓冲区中的上一个命令,然后使用C-c RET将该命令复制到提示符以进行编辑的过程。

(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)

1
你可以通过(define-key comint-mode-map [C-up] 'ess-readline)将其绑定到C-up。 - Heather Turner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接