(ess-r-args-get): Do not use zap-to-char within defun,
[ess.git] / lisp / ess-trns.el
blob4d1975dc80b0e831a9325ac728b429531e962c4d
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)
15 ;; any later version.
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.
26 ;;; Commentary:
28 ;; Code for dealing with ESS transcripts.
30 ;;; Code:
32 \f ; Requires and autoloads
34 (require 'ess)
36 (eval-when-compile
37 (require 'comint)
38 (require 'ess-inf))
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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
61 ;;;; In this section:
62 ;;;;
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
70 nil
72 (cond ((featurep 'xemacs)
73 ;; Code for XEmacs
74 (setq ess-transcript-mode-map (make-keymap))
75 (set-keymap-parent ess-transcript-mode-map text-mode-map))
76 ((not (featurep 'xemacs))
77 ;; Code for GNU Emacs
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))
121 (easy-menu-define
122 ess-transcript-mode-menu ess-transcript-mode-map
123 "Menu for use in S transcript mode."
124 '("ESS-trans"
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]
129 "------"
130 ["Mark cmd group" mark-paragraph t]
131 ["Previous prompt" comint-previous-prompt t]
132 ["Next prompt" comint-next-prompt t]
133 "------"
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
147 [menu-bar ess-trans]
148 (cons "ess-trans"
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}"
173 (interactive)
174 (require 'ess-inf)
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)
192 (concat "\\("
193 inferior-ess-primary-prompt
194 "\\|"
195 inferior-ess-secondary-prompt
196 "\\)"))
197 (make-local-variable 'comint-prompt-regexp)
198 (setq comint-prompt-regexp (concat "^" inferior-ess-prompt))
200 ;; font-lock support
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
216 is not already."
217 (interactive)
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)))
225 (save-excursion
226 (set-buffer ess-buf)
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."
232 (interactive)
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."
239 (interactive)
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))
247 (save-excursion
248 (set-buffer ess-buf)
249 (goto-char (point-max))
250 (insert input)))
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]."
258 (interactive "r\nP")
259 (let ((do-toggle (and buffer-read-only even-if-read-only)))
260 (save-excursion
261 (if do-toggle (toggle-read-only 0))
262 (save-restriction
263 (unless 'xemacs-p ;; does not exist in xemacs:
264 (deactivate-mark))
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."
274 (interactive "r")
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."
280 (interactive)
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:
287 ;;; Chapters: ^L ;
288 ;;; Sections: ;;*;;
289 ;;; Subsections: ;;;*;;;
290 ;;; Components: defuns, defvars, defconsts
291 ;;; Random code beginning with a ;;;;* comment
293 ;;; Local variables:
294 ;;; mode: emacs-lisp
295 ;;; mode: outline-minor
296 ;;; outline-regexp: "\^L\\|\\`;\\|;;\\*\\|;;;\\*\\|(def[cvu]\\|(setq\\|;;;;\\*"
297 ;;; End:
299 ;;; ess-trans.el ends here