~ubuntu-branches/ubuntu/natty/ess/natty

« back to all changes in this revision

Viewing changes to lisp/ess-help.el

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2006-04-28 16:27:11 UTC
  • mfrom: (1.3.1 upstream) (4 dapper)
  • mto: (3.2.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 5.
  • Revision ID: james.westby@ubuntu.com-20060428162711-32tne8d9mve35uyn
* New upstream release
* Add tetex-extra to build-depends, Closes: #363080, Closes: #358327. 
* Apply xemacs key binding fix, Closes: #343234.
* Comment out svn references in refcard.tex, as Debian does not have
  svn.sty at the moment.
* Add ess-intro-graphs.pdf and refcard.pdf to docs

Show diffs side-by-side

added added

removed removed

Lines of Context:
63
63
(autoload 'ess-search-list              "ess-inf" "(autoload)" nil)
64
64
(autoload 'ess-get-object-list          "ess-inf" "(autoload)" nil)
65
65
 
 
66
(autoload 'ess-ddeclient-p              "ess-inf" "(autoload)" nil)
 
67
 
 
68
(autoload 'ess-display-help-on-object-ddeclient "ess-dde" "(autoload)" nil)
 
69
 
 
70
 
66
71
 ; ess-help-mode
67
72
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
68
73
;;;; In this section:
73
78
 
74
79
(defun ess-help-bogus-buffer-p (buffer &optional nr-first return-match debug)
75
80
  "Return non-nil if  BUFFER  looks like a bogus ESS help buffer.
76
 
 Return pair of (match-beg. match-end) when optional RETURN-MATCH is non-nil.
77
 
 Utility used in \\[ess-display-help-on-object]."
 
81
NR-FIRST is the number of characters at the start of the buffer
 
82
to examine when deciding if the buffer if bogus.  If nil, the
 
83
first 120 characters of the buffer are searched.  Return pair
 
84
of (match-beg. match-end) when optional RETURN-MATCH is non-nil.
 
85
Utility used in \\[ess-display-help-on-object]."
 
86
 
 
87
  ;; search in first nr-first (default 120) chars only
 
88
  (if (not nr-first) (setq nr-first 120))
 
89
 
78
90
  (let* ((searching nil)
79
91
         (buffer-ok (bufferp buffer))
80
92
         (res
85
97
                    (ess-write-to-dribble-buffer
86
98
                     (format "(ess-help-bogus-buffer-p %s)" (buffer-name))))
87
99
 
88
 
                (let ((PM (point-min)))
 
100
                (let
 
101
                    ((PM (point-min))
 
102
                     (case-fold-search t) )
89
103
                  (or  ;; evaluate up to first non-nil (or end):
90
104
                   (< (- (point-max) PM) 80); buffer less than 80 chars
91
105
                   (not (setq searching t))
92
 
                   (not (setq case-fold-search t))
93
 
                   ;; search in first nr-first (default 120) chars only
94
 
                   (and nil (if (not nr-first) (setq nr-first 120)))
95
106
                   (progn (goto-char PM) ;; R:
96
107
                          (re-search-forward "Error in help"    nr-first t))
97
 
                   (progn (goto-char PM) ;; R with help.try.all.packages = TRUE:
98
 
                          (re-search-forward "topic \`.*\' is not in any loaded"
99
 
                                             nr-first t))
100
108
                   (progn (goto-char PM) ;; S-plus 5.1 :
101
109
                          (re-search-forward "^cat: .*--"       nr-first t))
102
110
                   (progn (goto-char PM) ;; S version 3 ; R :
112
120
      ;; else
113
121
      res)))
114
122
 
115
 
;;*;; Access function for displaying help
116
 
 
117
123
(defun ess-display-help-on-object (object)
118
124
  "Display documentation for OBJECT in another window.
119
125
If prefix arg is given, forces a query of the  ESS process for the help
120
126
file.  Otherwise just pops to an existing buffer if it exists.
121
 
Uses the variable `inferior-ess-help-command' for the actual help command."
122
 
  (interactive (ess-find-help-file "Help on: "))
123
 
  (let* ((hb-name (concat "*help["
124
 
                          ess-current-process-name
125
 
                          "](" object ")*"))
126
 
         (old-hb-p      (get-buffer hb-name))
127
 
         (curr-win-mode major-mode)
128
 
         (tbuffer       (get-buffer-create hb-name))
129
 
         (curr-help-command             inferior-ess-help-command)
130
 
         ;;-- pass the buffer-local 'ess-help-sec-..'  to the ess-help buffer:
131
 
         (curr-help-sec-regex           ess-help-sec-regex)
132
 
         (curr-help-sec-keys-alist      ess-help-sec-keys-alist)
133
 
         (curr-help-syntax-table        (syntax-table))
134
 
         (alist         ess-local-customize-alist))
135
 
 
136
 
    (set-buffer tbuffer)
137
 
    (ess-setq-vars-local (eval alist))
138
 
    (setq ess-help-sec-regex      curr-help-sec-regex)
139
 
    (setq ess-help-sec-keys-alist curr-help-sec-keys-alist)
140
 
    ;; see above, do same for inferior-ess-help-command... (i.e. remove
141
 
    ;; hack, restore old code :-).
142
 
 
143
 
    (if (or (not old-hb-p)
144
 
            current-prefix-arg
145
 
            (ess-help-bogus-buffer-p old-hb-p nil nil 'debug)
146
 
            )
147
 
 
148
 
        ;; Ask the corresponding ESS process for the help file:
149
 
        (progn
150
 
          (if buffer-read-only (setq buffer-read-only nil))
151
 
          (delete-region (point-min) (point-max))
152
 
          (ess-help-mode)
153
 
          (setq ess-local-process-name ess-current-process-name)
154
 
          (ess-command (format curr-help-command object) tbuffer)
155
 
          ;; was inferior-ess-help-command
156
 
 
157
 
          (ess-help-underline)
158
 
          ;; Stata is clean, so we get a big BARF from this.
159
 
          (if (not (string= ess-language "STA"))
160
 
              (ess-nuke-help-bs))
161
 
 
162
 
          (goto-char (point-min))))
163
 
 
164
 
    (save-excursion
165
 
      (let ((PM (point-min))
166
 
            (nodocs (ess-help-bogus-buffer-p (current-buffer) nil 'give-match))
167
 
            )
168
 
        (goto-char PM)
169
 
        (if (and nodocs
170
 
                 ess-help-kill-bogus-buffers)
171
 
            (progn
172
 
              (if (not (listp nodocs))
173
 
                  (setq nodocs (list PM (point-max))))
174
 
              (ess-write-to-dribble-buffer
175
 
               (format "(ess-help: error-buffer '%s' nodocs (%d %d)\n"
176
 
                       (buffer-name) (car nodocs) (cadr nodocs)))
177
 
              ;; Avoid using 'message here -- may be %'s in string
178
 
              ;;(princ (buffer-substring (car nodocs) (cadr nodocs)) t)
179
 
              ;; MM [3/2000]: why avoid?  Yes, I *do* want message:
180
 
              (message "%s" (buffer-substring (car nodocs) (cadr nodocs)))
181
 
              ;; ^^^ fixme : remove new lines from the above {and abbrev.}
182
 
              (ding)
183
 
              (kill-buffer tbuffer))
184
 
 
185
 
          ;; else : show it
186
 
 
187
 
          ;;dbg (ess-write-to-dribble-buffer
188
 
          ;;dbg  (format "(ess-help '%s' before switch-to..\n" hb-name)
189
 
          (let ((special-display-regexps
190
 
                 (if ess-help-own-frame '(".") nil))
191
 
                (special-display-frame-alist ess-help-frame-alist)
192
 
                (special-display-function
193
 
                 (if (eq ess-help-own-frame 'one)
194
 
                     'ess-help-own-frame
195
 
                   special-display-function)))
196
 
            (if (eq curr-win-mode 'ess-help-mode)
197
 
                (if ess-help-own-frame
198
 
                    (pop-to-buffer tbuffer)
199
 
                  (switch-to-buffer tbuffer))
200
 
              (ess-display-temp-buffer tbuffer)))
201
 
          (if curr-help-syntax-table
202
 
              (set-syntax-table curr-help-syntax-table))
203
 
          (set-buffer-modified-p 'nil)
204
 
          (toggle-read-only t))))))
 
127
Uses the variable `inferior-ess-help-command' for the actual help command.
 
128
Prompts for the object name based on the cursor location for all cases
 
129
except the S-Plus GUI.  With S-Plus on Windows (both GUI and in an inferior
 
130
emacs buffer) the GUI help window is used."
 
131
  (interactive 
 
132
   (if (ess-ddeclient-p)
 
133
       (list (read-string "Help on: "))
 
134
     (ess-find-help-file "Help on: ")))
 
135
 
 
136
  (if (or (ess-ddeclient-p)
 
137
          (equal inferior-ess-help-filetype "chm"))
 
138
      (if (ess-ddeclient-p)
 
139
          (ess-display-help-on-object-ddeclient object) ;; ddeclient version
 
140
        (ess-eval-linewise (concat "help(" object ")"))) ;; "chm" version
 
141
 
 
142
    ;; else: "normal", non-DDE behavior:
 
143
    (let* ((hb-name (concat "*help["
 
144
                            ess-current-process-name
 
145
                            "](" object ")*"))
 
146
           (old-hb-p    (get-buffer hb-name))
 
147
           (curr-win-mode major-mode)
 
148
           (tbuffer     (get-buffer-create hb-name))
 
149
           (curr-help-command           inferior-ess-help-command)
 
150
           ;;-- pass the buffer-local 'ess-help-sec-..'  to the ess-help buffer:
 
151
           (curr-help-sec-regex         ess-help-sec-regex)
 
152
           (curr-help-sec-keys-alist    ess-help-sec-keys-alist)
 
153
           (curr-help-syntax-table      (syntax-table))
 
154
           (curr-help-filetype          inferior-ess-help-filetype)
 
155
           (alist               ess-local-customize-alist))
 
156
 
 
157
      (set-buffer tbuffer)
 
158
      (ess-setq-vars-local (eval alist))
 
159
      (setq ess-help-sec-regex    curr-help-sec-regex)
 
160
      (setq ess-help-sec-keys-alist curr-help-sec-keys-alist)
 
161
      (setq inferior-ess-help-filetype curr-help-filetype)
 
162
      ;; see above, do same for inferior-ess-help-command... (i.e. remove
 
163
      ;; hack, restore old code :-).
 
164
 
 
165
      (if (or (not old-hb-p)
 
166
              current-prefix-arg
 
167
              (ess-help-bogus-buffer-p old-hb-p nil nil 'debug)
 
168
              )
 
169
 
 
170
          ;; Ask the corresponding ESS process for the help file:
 
171
          (progn
 
172
            (if buffer-read-only (setq buffer-read-only nil))
 
173
            (delete-region (point-min) (point-max))
 
174
            (ess-help-mode)
 
175
            (setq ess-local-process-name ess-current-process-name)
 
176
            (ess-command (format curr-help-command object) tbuffer)
 
177
            ;; was inferior-ess-help-command
 
178
 
 
179
            (ess-help-underline)
 
180
            ;; Stata is clean, so we get a big BARF from this.
 
181
            (if (not (string= ess-language "STA"))
 
182
                (ess-nuke-help-bs))
 
183
 
 
184
            (goto-char (point-min))))
 
185
 
 
186
      (save-excursion
 
187
        (let ((PM (point-min))
 
188
              (nodocs
 
189
               (ess-help-bogus-buffer-p (current-buffer) nil 'give-match )))
 
190
          (goto-char PM)
 
191
          (if (and nodocs
 
192
                   ess-help-kill-bogus-buffers)
 
193
              (progn
 
194
                (if (not (listp nodocs))
 
195
                    (setq nodocs (list PM (point-max))))
 
196
                (ess-write-to-dribble-buffer
 
197
                 (format "(ess-help: error-buffer '%s' nodocs (%d %d)\n"
 
198
                         (buffer-name) (car nodocs) (cadr nodocs)))
 
199
                ;; Avoid using 'message here -- may be %'s in string
 
200
                ;;(princ (buffer-substring (car nodocs) (cadr nodocs)) t)
 
201
                ;; MM [3/2000]: why avoid?  Yes, I *do* want message:
 
202
                (message "%s" (buffer-substring (car nodocs) (cadr nodocs)))
 
203
                ;; ^^^ fixme : remove new lines from the above {and abbrev.}
 
204
                (ding)
 
205
                (kill-buffer tbuffer))
 
206
 
 
207
            ;; else : show the help buffer.
 
208
 
 
209
            ;; Check if this buffer describes where help can be found in
 
210
            ;; various packages. (R only).  This is a kind of bogus help
 
211
            ;; buffer, but it should not be killed immediately even if
 
212
            ;; ess-help-kill-bogus-buffers is t.
 
213
 
 
214
            ;; e.g. if within R, the user does:
 
215
 
 
216
            ;; > options("help.try.all.packages" = TRUE)
 
217
 
 
218
            ;; > ?rlm
 
219
 
 
220
            ;; then a list of packages for where ?rlm is defined is
 
221
            ;; shown.  (In this case, rlm is in package MASS).  This
 
222
            ;; help buffer is then renamed *help[R](rlm in packages)* so
 
223
            ;; that after MASS is loaded, ?rlm will then show
 
224
            ;; *help[R](rlm)*
 
225
 
 
226
            (if (equal inferior-ess-program inferior-R-program-name)
 
227
                ;; this code should be used only for R processes.
 
228
                (save-excursion
 
229
                  (goto-char (point-min))
 
230
                  (if (looking-at "Help for topic")
 
231
                      (let
 
232
                          ( (newbuf
 
233
                             (concat "*help[" ess-current-process-name
 
234
                                     "](" object " in packages)*")))
 
235
                        ;; if NEWBUF already exists, remove it.
 
236
                        (if (get-buffer newbuf)
 
237
                            (kill-buffer newbuf))
 
238
                        (rename-buffer  newbuf)))))
 
239
 
 
240
            ;;dbg (ess-write-to-dribble-buffer
 
241
            ;;dbg        (format "(ess-help '%s' before switch-to..\n" hb-name)
 
242
            (let ((special-display-regexps
 
243
                   (if ess-help-own-frame '(".") nil))
 
244
                  (special-display-frame-alist ess-help-frame-alist)
 
245
                  (special-display-function
 
246
                   (if (eq ess-help-own-frame 'one)
 
247
                       'ess-help-own-frame
 
248
                     special-display-function)))
 
249
              (if (eq curr-win-mode 'ess-help-mode)
 
250
                  (if ess-help-own-frame
 
251
                      (pop-to-buffer tbuffer)
 
252
                    (switch-to-buffer tbuffer))
 
253
                (ess-display-temp-buffer tbuffer)))
 
254
            (if curr-help-syntax-table
 
255
                (set-syntax-table curr-help-syntax-table))
 
256
            (set-buffer-modified-p 'nil)
 
257
            (toggle-read-only t)))))))
205
258
 
206
259
(defvar ess-help-frame nil
207
260
  "Stores the frame used for displaying R help buffers.")
242
295
 
243
296
 
244
297
(defvar ess-help-sec-map nil "Sub-keymap for ESS help mode.")
245
 
(if ess-help-sec-map
246
 
    nil
247
 
  (setq ess-help-sec-map (make-sparse-keymap))
248
 
  (mapcar '(lambda (key)
249
 
            (define-key ess-help-sec-map (char-to-string key)
250
 
              'ess-skip-to-help-section))
251
 
            (mapcar 'car ess-help-sec-keys-alist))
252
 
  (define-key ess-help-sec-map "?" 'ess-describe-sec-map)
253
 
  (define-key ess-help-sec-map ">" 'end-of-buffer)
254
 
  (define-key ess-help-sec-map "<" 'beginning-of-buffer)
255
 
)
 
298
;; this breaks "s ?" rather than to fix any (unbroken !) thing:
 
299
;; (make-variable-buffer-local 'ess-help-sec-map)
256
300
 
257
301
(defvar ess-help-mode-map nil "Keymap for ESS help mode.")
258
302
(if ess-help-mode-map
261
305
  (suppress-keymap ess-help-mode-map)   ; suppress all usual "printing" characters
262
306
  (define-key ess-help-mode-map " " 'scroll-up)
263
307
  (define-key ess-help-mode-map "b" 'scroll-down)
 
308
  (define-key ess-help-mode-map "\177" 'scroll-down) ; DEL
264
309
  (define-key ess-help-mode-map "q" 'ess-switch-to-end-of-ESS)
265
310
  (define-key ess-help-mode-map "\C-m" 'next-line)
266
 
  (define-key ess-help-mode-map "\177" 'scroll-down) ; DEL
267
 
  (define-key ess-help-mode-map "s" ess-help-sec-map)
 
311
  ;; (define-key ess-help-mode-map "s" ess-help-sec-map)
268
312
  (define-key ess-help-mode-map "h" 'ess-display-help-on-object)
269
313
;; TODO: `electric mouse-2'
270
314
;; (define-key ess-help-mode-map [mouse-2] 'ess-display-help-on-object)
271
315
  (define-key ess-help-mode-map "l" 'ess-eval-line-and-step)
272
316
  (define-key ess-help-mode-map "r" 'ess-eval-region-and-go)
 
317
  (define-key ess-help-mode-map "f" 'ess-eval-function-or-paragraph-and-step)
273
318
  (define-key ess-help-mode-map "n" 'ess-skip-to-next-section)
274
319
  (define-key ess-help-mode-map "p" 'ess-skip-to-previous-section)
275
320
  (define-key ess-help-mode-map "/" 'isearch-forward)
278
323
  (define-key ess-help-mode-map "x" 'ess-kill-buffer-and-go)
279
324
  (define-key ess-help-mode-map "k" 'kill-buffer)
280
325
  (define-key ess-help-mode-map "?" 'ess-describe-help-mode)
281
 
  ;;-- those should be "inherited" from ess-mode-map :
 
326
  ;;-- those should be "inherited" from ess-mode-map ( ./ess-mode.el )
282
327
  (define-key ess-help-mode-map "\C-c\C-s" 'ess-switch-process)
283
328
  (define-key ess-help-mode-map "\C-c\C-r" 'ess-eval-region)
284
329
  (define-key ess-help-mode-map "\C-c\M-r" 'ess-eval-region-and-go)
298
343
;; One reason for the following menu is to <TEACH> the user about key strokes
299
344
(defvar ess-help-mode-menu
300
345
  (list "ESS-help"
 
346
        ["Search Forward"               isearch-forward t]
301
347
        ["Next Section"                 ess-skip-to-next-section t]
302
348
        ["Previous Section"             ess-skip-to-previous-section t]
303
 
        ["Search Forwards"              isearch-forward t]
304
349
        ["Help on Section Skipping"     ess-describe-sec-map t]
305
350
        ["Beginning of Buffer"          beginning-of-buffer t]
306
351
        ["End of Buffer"                end-of-buffer t]
308
353
        ["Help on ..."                  ess-display-help-on-object t]
309
354
        "-"
310
355
        ["Eval Line"                    ess-eval-line-and-step t]
 
356
        ["Eval Paragraph & step"        ess-eval-paragraph-and-step t]
311
357
        ["Eval Region & Go"             ess-eval-region-and-go t]
312
358
        ["Switch to ESS Process"        ess-switch-to-ESS t]
 
359
        ["Switch to End of ESS Proc."   ess-switch-to-end-of-ESS t]
 
360
        ["Switch _the_ Process"         ess-switch-process t]
313
361
        "-"
314
362
        ["Describe ESS-help Mode"       ess-describe-help-mode t]
315
363
        "-"
316
364
        ["Kill Buffer"                  kill-buffer t]
317
365
        ["Kill Buffer & Go"             ess-kill-buffer-and-go t]
318
 
        ["Back to end of ESS Pr."       ess-switch-to-end-of-ESS t]
319
366
        )
320
367
  "Menu used in ess-help mode.")
321
368
 
346
393
                    "Menu keymap for ess-help mode." ess-help-mode-menu)
347
394
  (easy-menu-add ess-help-mode-menu-map ess-help-mode-map)
348
395
 
 
396
  ;; Add the keys for navigating among sections; this is done
 
397
  ;; dynamically since different languages (e.g. S vs R) have different
 
398
  ;; section headings.
 
399
 
 
400
  (setq ess-help-sec-map (make-sparse-keymap))
 
401
  (mapcar '(lambda (key)
 
402
            (define-key ess-help-sec-map (char-to-string key)
 
403
              'ess-skip-to-help-section))
 
404
            (mapcar 'car ess-help-sec-keys-alist))
 
405
  (define-key ess-help-sec-map "?" 'ess-describe-sec-map)
 
406
  (define-key ess-help-sec-map ">" 'end-of-buffer)
 
407
  (define-key ess-help-sec-map "<" 'beginning-of-buffer)
 
408
  (define-key ess-help-mode-map "s" ess-help-sec-map)
 
409
 
349
410
  (run-hooks 'ess-help-mode-hook))
350
411
 
351
412
;;*;; User commands defined in ESS help mode
395
456
(defun ess-describe-sec-map nil
396
457
  "Display help for the `s' key."
397
458
  (interactive)
398
 
  (describe-function 'ess-skip-to-help-section)
399
 
  (save-excursion
400
 
    (set-buffer "*Help*")
401
 
    (toggle-read-only nil)
402
 
    (goto-char (point-max))
403
 
    (insert "\n\nCurrently defined keys are:
 
459
  (let ((keys-alist ess-help-sec-keys-alist))
 
460
    (describe-function 'ess-skip-to-help-section)
 
461
    (save-excursion
 
462
      (set-buffer "*Help*")
 
463
      (toggle-read-only nil)
 
464
      (goto-char (point-max))
 
465
      (insert "\n\nCurrently defined keys are:
404
466
 
405
467
Keystroke    Section
406
468
---------    -------\n")
407
 
    (mapcar '(lambda (cs) (insert "    "
408
 
                                  (car cs)
409
 
                                  "        "
410
 
                                  (cdr cs) "\n"))
411
 
            ess-help-sec-keys-alist)
412
 
    (insert "\nFull list of key definitions:\n"
413
 
            (substitute-command-keys
414
 
             "\\{ess-help-sec-map}"))))
 
469
      (mapcar '(lambda (cs) (insert "    "
 
470
                                    (car cs)
 
471
                                    "      "
 
472
                                    (cdr cs) "\n"))
 
473
              keys-alist)
 
474
      (insert "\nFull list of key definitions:\n"
 
475
              (substitute-command-keys
 
476
               "\\{ess-help-sec-map}")))))
415
477
 
416
478
(defun ess-read-helpobj-name-default (olist)
417
479
  ;;; Returns the object name at point, or else the name of the
466
528
                                 (ess-search-list))))))
467
529
 
468
530
(defun ess-nuke-help-bs ()
469
 
  (interactive "*")
470
 
;;; This function is a modification of nuke-nroff-bs in man.el from the
471
 
;;; standard emacs 18 lisp library.
 
531
  "Remove ASCII underlining and overstriking performed by ^H codes."
 
532
  ;; This function is a modification of nuke-nroff-bs in man.el from the
 
533
  ;; standard emacs 18 lisp library.
472
534
  ;; Nuke underlining and overstriking (only by the same letter)
473
535
  (goto-char (point-min))
474
536
  (while (search-forward "\b" nil t)
493
555
  (delete-region (point-min) (point)))
494
556
 
495
557
(defun ess-help-underline ()
496
 
  "Replace ^_H codes with underline face."
 
558
  "Replace _^H codes with underline face."
497
559
  (save-excursion
498
560
    (goto-char (point-min))
499
561
    (while (search-forward "_" nil t)
528
590
           'ess-keep-dump-files
529
591
           'ess-source-directory)
530
592
     nil
531
 
     (lambda () (goto-char (point-max)) (insert-buffer "*ESS*")))))
 
593
     (lambda () (goto-char (point-max)) (insert-buffer-substring "*ESS*")))))
532
594
 
533
595
 
534
596
;;; Provide