ESS: извлечение истории команд из команд, введенных в подчиненном режиме или сценарии ESS[R]

При использовании ESS[R] в подчиненном режиме я могу получить самый последний вывод команды, используя C-c C-p, который перемещает курсор к предыдущему выводу команды. В качестве альтернативы я могу использовать C-up, который по сути копирует последнюю введенную команду из подчиненного процесса (аналогично тому, как работает readline). Я предпочитаю подход C-up, но, к сожалению, он не извлекает команды, которые были введены из сценария с использованием любой из команд ess-eval. Можно ли получить функциональность C-up для команд, введенных как в подчиненном режиме, так и с помощью ess-eval?


person Manuel Morales    schedule 05.12.2014    source источник


Ответы (2)


Ваше решение отлично работает для однострочных команд, но требует небольшой настройки для обработки многострочных операторов:

(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)
person Heather Turner    schedule 12.12.2014
comment
Благодарю вас! Также стоит отметить, что ни одно из решений не может работать в более старых версиях ESS, и даже в самой новой версии (14.9) это не будет работать при повторных вызовах многострочной команды (это может быть ошибкой в ​​текущей версии ESS). ). См. stat.ethz.ch/pipermail/ess-help/2014. -декабрь/010373.html - person Manuel Morales; 12.12.2014
comment
Благодарю вас! Отличное решение. Это не решает проблему поиска по ранее выполненным командам. Например, comint-history-isearch-backward-regexp (M-r) выполняет поиск только в истории comint. Почему ess не помещает оцененную команду в историю comint? - person dk.; 07.10.2020

Кажется, что для этого нет встроенной функции, поэтому я написал функцию ниже. По сути, эта функция автоматизирует процесс использования клавиш 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)
person Manuel Morales    schedule 10.12.2014
comment
Вы можете привязать это к C-up через (define-key comint-mode-map [C-up] 'ess-readline) - person Heather Turner; 11.12.2014