Klimi's new dotfiles with stow.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

235 lines
9.4 KiB

4 years ago
  1. ;;; ess-trns.el --- Support for manipulating S transcript files -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 1989--1994 Bates, Kademan, Ritter and Smith
  3. ;; Copyright (C) 1997--2010 A.J. Rossini, Richard M. Heiberger, Martin
  4. ;; Maechler, Kurt Hornik, Rodney Sparapani, and Stephen Eglen.
  5. ;; Copyright (C) 2011--2012 A.J. Rossini, Richard M. Heiberger, Martin Maechler,
  6. ;; Kurt Hornik, Rodney Sparapani, Stephen Eglen and Vitalie Spinu.
  7. ;; Author: David Smith <dsmith@stats.adelaide.edu.au>
  8. ;; Maintainer: ESS-core <ESS-core@r-project.org>
  9. ;; This file is part of ESS
  10. ;; This file is free software; you can redistribute it and/or modify
  11. ;; it under the terms of the GNU General Public License as published by
  12. ;; the Free Software Foundation; either version 2, or (at your option)
  13. ;; any later version.
  14. ;; This file is distributed in the hope that it will be useful,
  15. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. ;; GNU General Public License for more details.
  18. ;; A copy of the GNU General Public License is available at
  19. ;; https://www.r-project.org/Licenses/
  20. ;;; Commentary:
  21. ;; Code for dealing with ESS transcripts.
  22. ;;; Code:
  23. ; Requires and autoloads
  24. (require 'ess-mode)
  25. (require 'ess-inf)
  26. (require 'comint)
  27. (declare-function ess-display-help-on-object "ess-help" (object &optional command))
  28. ; ess-transcript-mode
  29. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  30. ;;;; In this section:
  31. ;;;;
  32. ;;;; * The major mode ess-transcript-mode
  33. ;;;; * Commands for ess-transcript-mode
  34. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  35. (defcustom ess-transcript-mode-hook nil
  36. "Hook for customizing ESS transcript mode."
  37. :group 'ess-hooks
  38. :type 'hook)
  39. ;;*;; Major mode definition
  40. (defvar ess-transcript-mode-map
  41. (let ((map (make-sparse-keymap)))
  42. (define-key map "\C-c\C-s" #'ess-switch-process)
  43. (define-key map "\C-c\C-r" #'ess-eval-region)
  44. (define-key map "\C-c\M-r" #'ess-eval-region-and-go)
  45. (define-key map "\C-c\C-k" #'ess-force-buffer-current)
  46. (define-key map "\C-c\C-q" #'ess-quit)
  47. (define-key map "\C-c\C-j" #'ess-transcript-send-command)
  48. (define-key map "\C-c\M-j" #'ess-transcript-send-command-and-move)
  49. (define-key map "\M-\C-a" #'ess-goto-end-of-function-or-para)
  50. (define-key map "\M-\C-e" #'ess-goto-end-of-function-or-para)
  51. (define-key map "\C-c\C-y" #'ess-switch-to-ESS)
  52. (define-key map "\C-c\C-z" #'ess-switch-to-end-of-ESS)
  53. (define-key map "\C-c\C-v" #'ess-display-help-on-object)
  54. (define-key map "\C-c\C-d" #'ess-dump-object-into-edit-buffer)
  55. (define-key map "\C-a" #'comint-bol)
  56. (define-key map "\M-\t" #'comint-replace-by-expanded-filename)
  57. (define-key map "\M-?" #'comint-dynamic-list-completions)
  58. (define-key map "\C-c\C-k" #'ess-request-a-process)
  59. (define-key map "{" #'skeleton-pair-insert-maybe)
  60. (define-key map "}" #'skeleton-pair-insert-maybe)
  61. (define-key map "\e\C-h" #'ess-mark-function-or-para)
  62. (define-key map "\e\C-q" #'ess-indent-exp)
  63. (define-key map "\t" #'ess-indent-command)
  64. (define-key map "\C-c\C-p" #'comint-previous-prompt)
  65. (define-key map "\C-c\C-n" #'comint-next-prompt)
  66. (define-key map "\r" #'ess-transcript-send-command-and-move)
  67. (define-key map "\M-\r" #'ess-transcript-send-command)
  68. (define-key map "\C-c\r" #'ess-transcript-copy-command)
  69. (define-key map "\C-c\C-w" #'ess-transcript-DO-clean-region)
  70. (define-key map "\C-c\M-c" #'ess-transcript-clean-buffer)
  71. map)
  72. "Keymap for `ess-transcript-mode'.")
  73. (easy-menu-define
  74. ess-transcript-mode-menu ess-transcript-mode-map
  75. "Menu for use in S transcript mode."
  76. '("ESS-trans"
  77. ["Describe" describe-mode t]
  78. ["About" (ess-goto-info "Transcript Mode") t]
  79. ["Send bug report" ess-submit-bug-report t]
  80. "------"
  81. ["Mark cmd group" mark-paragraph t]
  82. ["Previous prompt" comint-previous-prompt t]
  83. ["Next prompt" comint-next-prompt t]
  84. "------"
  85. ["Send and move" ess-transcript-send-command-and-move t]
  86. ["Copy command" ess-transcript-copy-command t]
  87. ["Send command" ess-transcript-send-command t]
  88. ["Clean Region" ess-transcript-DO-clean-region t]
  89. ["Clean Whole Buffer" ess-transcript-clean-buffer t]
  90. ["Switch S process" ess-switch-process t]
  91. ))
  92. ;;;###autoload
  93. (define-derived-mode ess-transcript-mode ess-mode "ESS Transcript"
  94. "Major mode for transcript files.
  95. Type \\[ess-transcript-send-command] to send a command in the
  96. transcript to the current inferior process. \\[ess-transcript-copy-command]
  97. copies the command but does not execute it, allowing you to edit it in
  98. the process buffer first.
  99. Type \\[ess-transcript-clean-region] to delete all outputs and prompts
  100. in the region, leaving only the commands."
  101. :group 'ess
  102. (setq buffer-read-only t
  103. ess-local-process-name nil
  104. mode-line-process '(" [" ess-local-process-name "]"))
  105. ;; TODO: Set this more normally in various major modes
  106. (unless inferior-ess-prompt ;; For S languages it is set in custom-alist
  107. (setq inferior-ess-prompt
  108. ;; Do not anchor to bol with `^'
  109. (concat "\\("
  110. inferior-ess-primary-prompt
  111. "\\|"
  112. inferior-ess-secondary-prompt
  113. "\\)")))
  114. (setq-local paragraph-start (concat "^" inferior-ess-prompt "\\|^\^L"))
  115. (setq-local paragraph-separate "^\^L")
  116. (setq-local comint-use-prompt-regexp t)
  117. (setq-local comint-prompt-regexp (concat "^" inferior-ess-prompt))
  118. (setq font-lock-defaults '(ess-build-font-lock-keywords
  119. nil nil ((?\. . "w") (?\_ . "w") (?' . ".")))))
  120. ;;*;; Commands used in S transcript mode
  121. (defun ess-transcript-send-command ()
  122. "Send the command at point in the transcript to the ESS process.
  123. The line should begin with a prompt. The ESS process buffer is displayed if it
  124. is not already."
  125. (interactive)
  126. (let* ((proc (or ess-local-process-name
  127. (ess-request-a-process "Evaluate into which process? " t)))
  128. (ess-buf (ess-get-process-buffer proc)))
  129. (setq ess-local-process-name proc)
  130. (if (get-buffer-window ess-buf) nil
  131. (display-buffer ess-buf t))
  132. (let ((input (inferior-ess-get-old-input)))
  133. (with-current-buffer ess-buf
  134. (goto-char (point-max))
  135. (ess-eval-linewise input)))))
  136. (defun ess-transcript-send-command-and-move ()
  137. "Send the command on this line, and move point to the next command."
  138. (interactive)
  139. (let* ((proc (or ess-local-process-name
  140. (ess-request-a-process "Evaluate into which process? " t)))
  141. (ess-buf (ess-get-process-buffer proc)))
  142. (setq ess-local-process-name proc)
  143. (if (get-buffer-window ess-buf) nil
  144. (display-buffer ess-buf t))
  145. (let ((input (inferior-ess-get-old-input)))
  146. (with-current-buffer ess-buf
  147. (goto-char (point-max))
  148. (ess-eval-linewise input nil nil nil 1))))
  149. (comint-next-prompt 1))
  150. (defun ess-transcript-copy-command ()
  151. "Copy the command at point to the command line of the ESS process."
  152. (interactive)
  153. (let* ((proc (or ess-local-process-name
  154. (ess-request-a-process "Evaluate into which process? " t)))
  155. (ess-buf (process-buffer (get-process proc)))
  156. (input (inferior-ess-get-old-input)))
  157. (setq ess-local-process-name proc)
  158. (if (get-buffer-window ess-buf) nil
  159. (display-buffer ess-buf t))
  160. (with-current-buffer ess-buf
  161. (goto-char (point-max))
  162. (insert input)))
  163. (ess-switch-to-end-of-ESS))
  164. (defun ess-transcript-clean-region (beg end even-if-read-only)
  165. "Strip the transcript in the region, leaving only (R/S/Lsp/..) commands.
  166. Deletes any lines not beginning with a prompt, and then removes the
  167. prompt from those lines that remain. Prefix argument means to
  168. clean even if the buffer is \\[read-only]."
  169. (interactive "r\nP")
  170. (unless inferior-ess-prompt
  171. (error "Cannot clean ESS transcript region in this mode!
  172. That only works in ess-transcript-mode or inferior-ess-mode ('*R*' etc)."
  173. ;; Maybe call ess-clean-region-in-new-transcript ?"))
  174. ))
  175. (let ((do-toggle (and buffer-read-only even-if-read-only))
  176. (ess-prompt-rx (if inferior-ess-secondary-prompt
  177. (concat "^\\(\\("
  178. inferior-ess-prompt
  179. "\\)\\|\\("
  180. inferior-ess-secondary-prompt
  181. "\\)\\)")
  182. (concat "^" inferior-ess-prompt))))
  183. (save-excursion
  184. (if do-toggle (setq buffer-read-only nil))
  185. (save-restriction
  186. (deactivate-mark)
  187. (narrow-to-region beg end)
  188. (goto-char (point-min))
  189. (delete-non-matching-lines ess-prompt-rx)
  190. (goto-char (point-min))
  191. ;; (replace-regexp * * ) :
  192. (while (re-search-forward ess-prompt-rx nil t)
  193. (replace-match "" nil nil)))
  194. (if do-toggle (setq buffer-read-only t)))))
  195. (defun ess-transcript-DO-clean-region (beg end)
  196. "Clean the current via \\[ess-transcript-clean-region] even if the buffer is read-only."
  197. (interactive "r")
  198. (ess-transcript-clean-region beg end 'In-ANY-case))
  199. (defun ess-transcript-clean-buffer ()
  200. "Cleanup the whole buffer.
  201. Use point-min/max to obey `narrow-to-region'."
  202. (interactive)
  203. (ess-transcript-clean-region (point-min) (point-max) 'In-ANY-case))
  204. (provide 'ess-trns)
  205. ;;; ess-trns.el ends here