ESS[SAS]: somebody forgot about the SUM statement (probably me)
[ess.git] / lisp / ess-toolbar.el
blob7e28e5f67864fe12f626c76fe319b778d5f14c85
1 ;;; ess-toolbar.el --- Support for a toolbar in ESS.
3 ;; Copyright (C) 1997--2004 A.J. Rossini, Rich M. Heiberger, Martin
4 ;; Maechler, Kurt Hornik, Rodney Sparapani, and Stephen Eglen.
6 ;; Original Author: Stephen Eglen
7 ;; Created: 06 May 2004
8 ;; Maintainers: ESS-core <ESS-core@stat.math.ethz.ch>
10 ;; This file is part of ESS
12 ;; GPL --> see beginning of ./ess-site.el
14 ;;; Commentary:
16 ;;; This code adds a toolbar to ESS modes for editing R and S code.
17 ;;; Support can be added for other modes (e.g. STATA), just ask!
18 ;;;
19 ;;; This code is experimental, and runs best on Emacs 21 and XEmacs
20 ;;; 21. It has been tested only on Linux machines. All feedback
21 ;;; appreciated.
22 ;;;
23 ;;; If your emacs can support images, the ESS toolbar should be loaded.
24 ;;;
25 ;;; If you see a toolbar, but no icons, check out the value of
26 ;;; ess-icon-directory.
27 ;;;
28 ;;; The toolbar can be customized in several ways. To see options, do:
29 ;;; M-x customize-group RET ess-toolbar RET
30 ;;; If you change any of the variables, you _may_ need to restart Emacs
31 ;;; to see any effect. See also the documentation for ess-toolbar-items
32 ;;; if you wish to change its value.
33 ;;;
34 ;;; Technical issues.
35 ;; Emacs vs XEmacs.
36 ;; Of course, Emacs and XEmacs have different interfaces and handle
37 ;; the toolbars in different ways. The code here is rough, but
38 ;; hopefully soon a compatibility toolbar library will be released
39 ;; that will make the toolbar code more portable. So, for now the
40 ;; code should be regarded as proof of concept.
42 ;; Also, I think the CVS GNU Emacs now has tool-bar support for the
43 ;; Mac OS X.
45 ;;; Code:
47 (defgroup ess-toolbar nil
48 "ESS: toolbar support."
49 :group 'ess
50 :link '(emacs-commentary-link :tag "Commentary" "ess-toolbar.el")
51 :prefix "ess-")
53 (defcustom ess-use-toolbar
54 (if (featurep 'xemacs)
55 (memq (device-type) '(x gtk mswindows))
56 (and (fboundp 'display-images-p) (display-images-p)))
57 "*Non-nil means ESS should support the toolbar.
58 Currently works only under Emacs 21 and maybe XEmacs 21.4."
59 :group 'ess-toolbar
60 :type 'boolean)
63 (defcustom ess-toolbar-own-icons nil
64 "*Non-nil means that we only put our toolbar entries in ESS.
65 Otherwise we get standard toolbar as well as ESS entries.
66 Under Emacs, the standard toolbar items are copied from the default toolbar.
67 Under XEmacs, the items stored in `ess-toolbar-xemacs-general' are added."
68 :group 'ess-toolbar
69 :type 'boolean)
71 (defcustom ess-toolbar-global nil
72 "*Non-nil means that the ESS toolbar is available in all emacs buffers.
73 Otherwise, the ESS toolbar is present only in R/S mode buffers.
74 For beginners, this is probably better set to a non-nil value."
75 :group 'ess-toolbar
76 :type 'boolean)
78 (defcustom ess-toolbar-items
79 '( (R "startr" "Start R process")
80 (S "spluslogo" "Start S process")
81 (ess-eval-line-and-step "rline" "Eval line & step")
82 (ess-eval-region "rregion" "Eval region")
83 (ess-load-file "rbuffer" "Load file")
84 (ess-eval-function "rfunction" "Eval function")
85 (ess-switch-to-ESS "switch_ess" "Switch to ESS buffer"))
86 "Items to be added to the ESS toolbar.
87 Each list element has three items:
88 1. the name of the function to run
89 2. the icon to be used (without .xpm extension)
90 3. the tooltip doc string (XEmacs only; Emacs gets doc string from menu items.
92 General toolbar items are also added to the ESS toolbar
93 iff `ess-toolbar-own-icons' is nil.
95 Setting this variable with setq doesn't take effect once you have
96 loaded ess-site, unless you follow it by a call to
97 `ess-make-toolbar' afterwards. Instead, change its value using
98 Custom, and then on all new ESS buffers you should see the
99 toolbar has changed."
100 :group 'ess-toolbar
101 :set (lambda (symbol value)
102 (set-default symbol value)
103 (if (fboundp 'ess-make-toolbar)
104 (ess-make-toolbar)))
105 :type '(repeat (list (function :tag "Function to run")
106 (string :tag "Icon")
107 (string :tag "Tooltip"))))
109 (defvar ess-icon-directory
110 (expand-file-name (concat (file-name-as-directory ess-etc-directory) "icons"))
111 "*Location for ESS icons.
112 This variable should be set automatically by the ESS install process.
113 Icons should be found in ESS/etc/icons/ directory.
114 If `ess-icon-directory' is invalid, please report a bug.")
116 (unless (file-directory-p ess-icon-directory)
117 (ess-write-to-dribble-buffer
118 "`ess-icon-directory' does not exist; using `ess-etc-directory'.\n")
119 (setq ess-icon-directory ess-etc-directory))
121 (defvar ess-toolbar nil
122 "Toolbar items to be added to ESS editing buffers.")
124 (defun ess-make-toolbar ()
125 "Make the ESS toolbar."
126 (if (featurep 'xemacs)
127 (ess-make-toolbar-xemacs)
128 ;; Under Emacs, only worth building the toolbar if tool-bar-map is
129 ;; available. e.g. when running Emacs within a terminal, tool-bar-map
130 ;; is not available, so no need to make the tool-bar.
131 (if (boundp 'tool-bar-map)
132 (ess-make-toolbar-emacs))))
134 (defun ess-make-toolbar-emacs ()
135 "Make the ESS toolbar under Emacs."
136 (setq ess-toolbar
137 (if (or ess-toolbar-own-icons (null tool-bar-map))
138 (make-sparse-keymap)
139 (copy-keymap tool-bar-map)))
140 (let ((tool-bar-map ess-toolbar)
141 (load-path (list ess-icon-directory)))
143 ;; icons are found by examining load-path; hence by temporarily setting
144 ;; load-path to our icons directory, they will be found.
145 (mapc 'ess-add-icon-emacs ess-toolbar-items)))
147 (defun ess-add-icon-emacs (x)
148 "Add an ESS item to the Emacs toolbar."
149 ;; By using tool-bar-add-item-from-menu instead of tool-bar-add-item
150 ;; we get the tooltips "for free" from ess-mode-map.
151 (tool-bar-add-item-from-menu (car x) (cadr x) ess-mode-map))
153 (defun ess-add-icon-xemacs (x)
154 "Return a 4-vector containing the spec for an ESS toolbar entry in XEmacs."
155 (vector
156 (toolbar-make-button-list
157 (expand-file-name (concat (cadr x) ".xpm") ess-icon-directory))
158 (car x) ;function
160 (nth 2 x) ;doc string
163 (defvar ess-toolbar-xemacs-general
164 (list
165 [toolbar-file-icon toolbar-open t "Open a file"]
166 [toolbar-disk-icon toolbar-save t "Save buffer"]
167 [toolbar-printer-icon generic-print-buffer t "Print buffer"]
168 [toolbar-cut-icon toolbar-cut t "Kill region"]
169 [toolbar-copy-icon toolbar-copy t "Copy region"]
170 [toolbar-paste-icon toolbar-paste t "Paste from clipboard"]
171 [toolbar-undo-icon toolbar-undo t "Undo edit"]
172 [toolbar-replace-icon toolbar-replace t "Search & Replace"]
173 [:style 3d]
175 "General Xemacs icons to be added iff `ess-toolbar-own-icons' is non-nil.
176 These toolbar items were taken from the list that John Fox's code provided.
177 Each vector is of length four specifying: 1 - icon; 2 - function to call;
178 3 - whether to activate; 4 - doc string.")
180 (defun ess-make-toolbar-xemacs ()
181 "Set up the ESS toolbar for XEmacs."
182 (setq ess-toolbar
183 (append (if ess-toolbar-own-icons nil ess-toolbar-xemacs-general)
184 (mapcar 'ess-add-icon-xemacs ess-toolbar-items)))
187 (defun ess-add-toolbar ()
188 "Add the ESS toolbar to a particular mode.
189 The toolbar is added iff `ess-toolbar-global' is nil, else the toolbar
190 is added globally when ess-toolbar.el is loaded."
191 (if (and ess-toolbar (not ess-toolbar-global))
192 (if (featurep 'xemacs)
193 (set-specifier default-toolbar ess-toolbar (current-buffer))
194 ;; Support for Emacs
195 (set (make-local-variable 'tool-bar-map) ess-toolbar))))
197 ;; Make the toolbars. Each toolbar is hopefully made only when this file
198 ;; is loaded; we don't need it to be remade every time.
199 (if ess-use-toolbar
200 (progn
201 (ess-make-toolbar)
202 ;; After making the toolbar, if ESS toolbar is needed globally,
203 ;; add it here.
204 (if ess-toolbar-global
205 (if (featurep 'xemacs)
206 ;; Xemacs
207 (progn
208 (set-specifier default-toolbar ess-toolbar)
209 (ess-write-to-dribble-buffer "Creating global XEmacs toolbar"))
210 ;; Emacs
211 (setq tool-bar-map ess-toolbar)
212 (ess-write-to-dribble-buffer "Creating global Emacs toolbar"))
215 ;; Check for toolbar support - needed iff ess-use-toolbar is non-nil.
217 ;; XEmacs test for image support, adapted from vm-version.el:
218 (and (featurep 'xemacs) (memq (device-type) '(x gtk mswindows)))
220 ;; Emacs support for images:
221 (and (fboundp 'display-images-p) (display-images-p))
222 ;; if above tests failed, give a warning.
223 (progn
224 (message "Toolbar support for ESS not available in this emacs.")
225 ;; Not sure if we want to delay startup of ESS.
226 ;;(sit-for 2)
230 (provide 'ess-toolbar)