1 ;;; ess-trns.el --- Support for manipulating S transcript files
3 ;; Copyright (C) 1989--1994 Bates, Kademan, Ritter and Smith
4 ;; Copyright (C) 1997--2004 A.J. Rossini, Rich M. Heiberger, Martin
5 ;; Maechler, Kurt Hornik, Rodney Sparapani, and Stephen Eglen.
7 ;; Original Author: David Smith <dsmith@stats.adelaide.edu.au>
8 ;; Maintainers: ESS-core <ESS-core@stat.math.ethz.ch>
10 ;; This file is part of ESS
12 ;; This file is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
17 ;; This file is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING. If not, write to
24 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
28 ;; Code for dealing with ESS transcripts.
32 \f ; Requires and autoloads
40 (autoload 'ess-eval-region "ess-inf" "[autoload]" t)
41 (autoload 'ess-eval-region-and-go "ess-inf" "[autoload]" t)
42 (autoload 'ess-eval-function "ess-inf" "[autoload]" t)
43 (autoload 'ess-eval-function-and-go "ess-inf" "[autoload]" t)
44 (autoload 'ess-eval-line "ess-inf" "[autoload]" t)
45 (autoload 'ess-eval-line-and-go "ess-inf" "[autoload]" t)
46 (autoload 'ess-eval-line-and-step "ess-inf" "[autoload]" t)
48 (autoload 'comint-previous-prompt "comint" "[autoload]" t)
49 (autoload 'comint-next-prompt "comint" "[autoload]" t)
51 (autoload 'ess-load-file "ess-inf" "[autoload]" t)
52 (autoload 'ess-request-a-process "ess-inf" "(autoload)" nil)
53 (autoload 'get-ess-buffer "ess-inf" "(autoload)" nil)
54 (autoload 'ess-switch-to-ESS "ess-inf" "(autoload)" nil)
55 (autoload 'ess-switch-to-end-of-ESS "ess-inf" "(autoload)" nil)
56 (autoload 'ess-eval-linewise "ess-inf" "(autoload)" nil)
57 (autoload 'inferior-ess-get-old-input "ess-inf" "(autoload)" nil)
59 \f ; ess-transcript-mode
60 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
63 ;;;; * The major mode ess-transcript-mode
64 ;;;; * Commands for ess-transcript-mode
65 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
67 ;;*;; Major mode definition
68 (defvar ess-transcript-mode-map nil "Keymap for `ess-transcript-mode'.")
69 (if ess-transcript-mode-map
72 (cond ((featurep 'xemacs)
74 (setq ess-transcript-mode-map (make-keymap))
75 (set-keymap-parent ess-transcript-mode-map text-mode-map))
76 ((not (featurep 'xemacs))
78 (setq ess-transcript-mode-map (make-sparse-keymap))))
80 (define-key ess-transcript-mode-map "\C-c\C-s" 'ess-switch-process)
81 (define-key ess-transcript-mode-map "\C-c\C-r" 'ess-eval-region)
82 (define-key ess-transcript-mode-map "\C-c\M-r" 'ess-eval-region-and-go)
83 ;; (define-key ess-transcript-mode-map "\M-\C-x" 'ess-eval-function)
84 ;; (define-key ess-transcript-mode-map "\C-c\M-f" 'ess-eval-function-and-go)
85 ;; (define-key ess-transcript-mode-map "\C-c\C-j" 'ess-eval-line)
86 ;; (define-key ess-transcript-mode-map "\C-c\M-j" 'ess-eval-line-and-go)
88 (define-key ess-transcript-mode-map "\C-c\C-k" 'ess-force-buffer-current)
89 (define-key ess-transcript-mode-map "\C-c\C-q" 'ess-quit)
91 (define-key ess-transcript-mode-map "\C-c\C-j" 'ess-transcript-send-command)
92 (define-key ess-transcript-mode-map "\C-c\M-j" 'ess-transcript-send-command-and-move)
93 (define-key ess-transcript-mode-map "\M-\C-a" 'ess-beginning-of-function)
94 (define-key ess-transcript-mode-map "\M-\C-e" 'ess-end-of-function)
95 (define-key ess-transcript-mode-map "\C-c\C-y" 'ess-switch-to-ESS)
96 (define-key ess-transcript-mode-map "\C-c\C-z" 'ess-switch-to-end-of-ESS)
97 (define-key ess-transcript-mode-map "\C-c\C-v" 'ess-display-help-on-object)
98 (define-key ess-transcript-mode-map "\C-c\C-d" 'ess-dump-object-into-edit-buffer)
99 (define-key ess-transcript-mode-map "\C-c\C-t" 'ess-execute-in-tb)
100 (define-key ess-transcript-mode-map "\C-c\t" 'ess-complete-object-name)
101 (define-key ess-transcript-mode-map "\C-a" 'comint-bol)
102 (define-key ess-transcript-mode-map "\M-\t" 'comint-replace-by-expanded-filename)
103 (define-key ess-transcript-mode-map "\M-?" 'comint-dynamic-list-completions)
104 (define-key ess-transcript-mode-map "\C-c\C-k" 'ess-request-a-process)
105 (define-key ess-transcript-mode-map "{" 'ess-electric-brace)
106 (define-key ess-transcript-mode-map "}" 'ess-electric-brace)
107 (define-key ess-transcript-mode-map "\e\C-h" 'ess-mark-function)
108 (define-key ess-transcript-mode-map "\e\C-q" 'ess-indent-exp)
109 (define-key ess-transcript-mode-map "\177" 'backward-delete-char-untabify)
110 (define-key ess-transcript-mode-map "\t" 'ess-indent-command)
112 (define-key ess-transcript-mode-map "\C-c\C-p" 'comint-previous-prompt)
113 (define-key ess-transcript-mode-map "\C-c\C-n" 'comint-next-prompt)
114 ;; (define-key ess-transcript-mode-map "\C-c\C-n" 'ess-eval-line-and-step)
116 (define-key ess-transcript-mode-map "\r" 'ess-transcript-send-command-and-move)
117 (define-key ess-transcript-mode-map "\M-\r" 'ess-transcript-send-command)
118 (define-key ess-transcript-mode-map "\C-c\r" 'ess-transcript-copy-command)
119 (define-key ess-transcript-mode-map "\C-c\C-w" 'ess-transcript-clean-region))
122 ess-transcript-mode-menu ess-transcript-mode-map
123 "Menu for use in S transcript mode."
125 ["What is this? (beta)" ess-mouse-me t]
126 ["Describe" describe-mode t]
127 ["About" (ess-goto-info "Transcript Mode") t]
128 ["Send bug report" ess-submit-bug-report t]
130 ["Mark cmd group" mark-paragraph t]
131 ["Previous prompt" comint-previous-prompt t]
132 ["Next prompt" comint-next-prompt t]
134 ["Send and move" ess-transcript-send-command-and-move t]
135 ["Copy command" ess-transcript-copy-command t]
136 ["Send command" ess-transcript-send-command t]
137 ["Clean Region" ess-transcript-DO-clean-region t]))
141 (if (not (string-match "XEmacs" emacs-version))
143 (if (featurep 'ess-trans)
144 (define-key ess-transcript-mode-map [menu-bar ess-trans]
145 (cons "ess-trans" ess-transcript-mode-menu))
146 (eval-after-load "ess-trans"
147 '(define-key ess-transcript-mode-map
150 ess-transcript-mode-menu))))))
152 (defun ess-transcript-mode-xemacs-menu ()
153 "Hook to install `ess-transcript-mode' menu for XEmacs (w/ easymenu)."
154 (if 'ess-transcript-mode
155 (easy-menu-add ess-transcript-mode-menu)
156 (easy-menu-remove ess-transcript-mode-menu)))
158 (if (string-match "XEmacs" emacs-version)
159 (add-hook 'ess-transcript-mode-hook 'ess-transcript-mode-xemacs-menu))
161 (defun ess-transcript-mode (alist &optional proc)
162 "Major mode for manipulating {ESS} transcript files.
164 Type \\[ess-transcript-send-command] to send a command in the
165 transcript to the current S process. \\[ess-transcript-copy-command]
166 copies the command but does not execute it, allowing you to edit it in
167 the process buffer first.
169 Type \\[ess-transcript-clean-region] to delete all outputs and prompts
170 in the region, leaving only the S commands. Other keybindings are:
172 \\{ess-transcript-mode-map}"
175 (kill-all-local-variables)
176 (toggle-read-only t) ;; to protect the buffer.
177 (ess-setq-vars-local alist); (current-buffer))
178 (setq major-mode 'ess-transcript-mode)
179 (setq mode-name "ESS Transcript")
180 (use-local-map ess-transcript-mode-map)
181 (set-syntax-table ess-mode-syntax-table)
182 (setq mode-line-process
183 '(" [" ess-local-process-name "]"))
184 (make-local-variable 'ess-local-process-name)
185 (setq ess-local-process-name nil)
186 (make-local-variable 'paragraph-start)
187 (setq paragraph-start (concat "^" inferior-ess-primary-prompt "\\|^\^L"))
188 (make-local-variable 'paragraph-separate)
189 (setq paragraph-separate "^\^L")
190 (setq inferior-ess-prompt
191 ;; Do not anchor to bol with `^' ; (copied from ess-inf.el)
193 inferior-ess-primary-prompt
195 inferior-ess-secondary-prompt
197 (make-local-variable 'comint-prompt-regexp)
198 (setq comint-prompt-regexp (concat "^" inferior-ess-prompt))
201 (make-local-variable 'font-lock-defaults)
202 (setq font-lock-defaults
203 '(inferior-ess-font-lock-keywords nil nil ((?' . "."))))
205 ;;; Keep <tabs> out of the code.
206 (make-local-variable 'indent-tabs-mode)
207 (setq indent-tabs-mode nil)
209 (run-hooks 'ess-transcript-mode-hook))
211 ;;*;; Commands used in S transcript mode
213 (defun ess-transcript-send-command ()
214 "Send the command at point in the transcript to the ESS process.
215 The line should begin with a prompt. The ESS process buffer is displayed if it
218 (let* ((proc (or ess-local-process-name
219 (ess-request-a-process "Evaluate into which process? " t)))
220 (ess-buf (get-ess-buffer proc)))
221 (setq ess-local-process-name proc)
222 (if (get-buffer-window ess-buf) nil
223 (display-buffer ess-buf t))
224 (let ((input (inferior-ess-get-old-input)))
227 (goto-char (point-max))
228 (ess-eval-linewise input)))))
230 (defun ess-transcript-send-command-and-move ()
231 "Send the command on this line, and move point to the next command."
233 (ess-transcript-send-command)
234 (goto-char ess-temp-point)
235 (comint-next-prompt 1))
237 (defun ess-transcript-copy-command ()
238 "Copy the command at point to the command line of the ESS process."
240 (let* ((proc (or ess-local-process-name
241 (ess-request-a-process "Evaluate into which process? " t)))
242 (ess-buf (process-buffer (get-process proc)))
243 (input (inferior-ess-get-old-input)))
244 (setq ess-local-process-name proc)
245 (if (get-buffer-window ess-buf) nil
246 (display-buffer ess-buf t))
249 (goto-char (point-max))
251 (ess-switch-to-end-of-ESS))
253 (defun ess-transcript-clean-region (beg end even-if-read-only)
254 "Strip the transcript in the region, leaving only (R/S/Lsp/..) commands.
255 Deletes any lines not beginning with a prompt, and then removes the
256 prompt from those lines that remain. Prefix argument means to use
257 \\[toggle-read-only] to clean even if the buffer is \\[read-only]."
259 (let ((do-toggle (and buffer-read-only even-if-read-only)))
261 (if do-toggle (toggle-read-only 0))
264 (narrow-to-region beg end)
265 (goto-char (point-min))
266 (delete-non-matching-lines (concat "^" inferior-ess-prompt))
267 (goto-char (point-min))
268 (replace-regexp (concat "^" inferior-ess-prompt) ""))
269 (if do-toggle (toggle-read-only 1)))))
271 (defun ess-transcript-DO-clean-region (beg end)
272 "Clean the current via \\[ess-transcript-clean-region] even if the buffer is read-only."
274 (ess-transcript-clean-region beg end 'In-ANY-case))
276 \f ; Local variables section
278 ;;; This file is automatically placed in Outline minor mode.
279 ;;; The file is structured as follows:
282 ;;; Subsections: ;;;*;;;
283 ;;; Components: defuns, defvars, defconsts
284 ;;; Random code beginning with a ;;;;* comment
288 ;;; mode: outline-minor
289 ;;; outline-regexp: "\^L\\|\\`;\\|;;\\*\\|;;;\\*\\|(def[cvu]\\|(setq\\|;;;;\\*"
292 ;;; ess-trans.el ends here