1 ;;; ess-trns.el --- Support for manipulating S transcript files
3 ;; Copyright (C) 1989--1994 Bates, Kademan, Ritter and Smith
4 ;; Copyright (C) 1997--2005 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
]
138 ["Switch S process" ess-switch-process t
]
141 (unless (featurep 'xemacs
)
142 (if (featurep 'ess-trans
)
143 (define-key ess-transcript-mode-map
[menu-bar ess-trans
]
144 (cons "ess-trans" ess-transcript-mode-menu
))
145 (eval-after-load "ess-trans"
146 '(define-key ess-transcript-mode-map
149 ess-transcript-mode-menu
)))))
151 (when (featurep 'xemacs
)
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 (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))
263 (unless 'xemacs-p
;; does not exist in xemacs:
265 (narrow-to-region beg end
)
266 (goto-char (point-min))
267 (delete-non-matching-lines (concat "^" inferior-ess-prompt
))
268 (goto-char (point-min))
269 (replace-regexp (concat "^" inferior-ess-prompt
) ""))
270 (if do-toggle
(toggle-read-only 1)))))
272 (defun ess-transcript-DO-clean-region (beg end
)
273 "Clean the current via \\[ess-transcript-clean-region] even if the buffer is read-only."
275 (ess-transcript-clean-region beg end
'In-ANY-case
))
277 (defun ess-transcript-clean-buffer ()
278 "Cleanup the whole buffer.
279 Use point-min/max to obey narrow-to-region."
281 (ess-transcript-clean-region (point-min) (point-max) 'In-ANY-case
))
283 \f ; Local variables section
285 ;;; This file is automatically placed in Outline minor mode.
286 ;;; The file is structured as follows:
289 ;;; Subsections: ;;;*;;;
290 ;;; Components: defuns, defvars, defconsts
291 ;;; Random code beginning with a ;;;;* comment
295 ;;; mode: outline-minor
296 ;;; outline-regexp: "\^L\\|\\`;\\|;;\\*\\|;;;\\*\\|(def[cvu]\\|(setq\\|;;;;\\*"
299 ;;; ess-trans.el ends here