1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
|
;;; ess-rlib.el --- browse contents of R packages.
;; Stephen Eglen, GPL applies.
;;
;; Primitive browswing facilities for the list of packages, and
;; the functions within a package. Use RET or mouse-2 to click on a
;; link and see either contents of a package or the function.
;;
;; To use, simply start a R session, eval this buffer,
;; then, in the R buffer, do
;; source("ess-rlib.R")
;; to load the changes to the data() and print.libraryIQR() functions.
;;
;; Then do M-x
;; ess-rpackage or use C-x C-e at end of one of following lines:
;;
;; (ess-rpackage "ctest")
;; okay
;;
;; (ess-rpackage "foreign")
;; okay, but fails on "S3 read functions"
;;
;; (ess-rpackage "eda")
;; shows help for lib, but won't show individual files unless package
;; has been loaded. How to show help without loading the package first?
;; (ess-rpackage "ts")
;; not so good, due to regexp failure!
;; (ess-rpackage "base")
;; (ess-rpackage "mva")
;; one problem, near end of buffer.
;; Presumably, adding link markup to the output from library() command
;; would help here so that only functions will get converted into
;; links. This would be more robust than using regexps.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; (ess-rdata)
;; This command will browse the output of the data() command, using
;; the extra markup of data names. Output goes to the *ess-rdata*
;; buffer. It currently just converts the data names into links
;; (highlight with mouse; underline), but no action is made on the
;; links. Kurt suggested before making e.g. ? bring up help on that
;; data topic, and RET to load the package.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun ess-rpackage (package)
"View functions within the package named PACKAGE. The package must
have already been loaded; if the package is not loaded, the functions
in it can still be viewed, but the help for those functions cannot be
viewed. This function is therefore currently restricted to show
contents for loaded packages only. This calls an extra R funcition named
funs.for.package()."
(interactive (let ()
(list
(completing-read "Package name: "
(mapcar 'list
(ess-rpackage-list))))))
(let (beg str (all t))
(setq str (concat "funs.for.package('"
package
"')\n"))
(ess-execute str nil "ess-rlib")
(pop-to-buffer "*ess-rlib*")
(goto-char (point-min))
(while (re-search-forward "^[^ ]" nil t)
(beginning-of-line)
(setq beg (point))
(re-search-forward "\\s-")
(add-text-properties beg (1- (point))
'(face underline
mouse-face highlight
help-xref function))
))
;; End of mark up, so add some text to the top of buffer.
(goto-char (point-min))
(insert "Functions in package " package ":\n\n")
(goto-char (point-min))
(ess-rpackage-mode)
)
(defun ess-rpackage-list ()
"Return list of packages currently loaded."
(save-window-excursion
(ess-execute "cat(.packages(), '\\n')")
(pop-to-buffer "*ess-output*")
(cdr (reverse
(split-string (buffer-substring (point-min) (point-max)) " ")))))
(defun ess-rpackage-1 (lib)
"View help available for a topic. Lib should either be blank or
name of a package. It currently uses regexps to guess which parts of
the output are function and package names. This mostly works, but for
a classic failure, see output from viewing the base package.
Old version."
(interactive "sPackage name (leave blank for lib list): ")
;; todo: would it be worth getting completion for package list?
(let (beg str (all t))
(setq str
(if (equal lib "")
"library()"
(setq all nil)
(concat "library(help="
lib
")\n")))
(ess-execute str nil "ess-rlib")
(pop-to-buffer "*ess-rlib*")
(if all
(ess-markup-libnames)
(re-search-forward "^Index:")
(while (re-search-forward "^[^ ]+ " nil t)
(beginning-of-line)
(setq beg (point))
(re-search-forward "[ \t]")
(add-text-properties beg (1- (point))
'( face underline
mouse-face highlight
help-xref function))
(end-of-line)
))
;; end of mark up
(goto-char (point-min))
(ess-rpackage-mode)
)
)
(defun ess-markup-libnames ()
"Markup the output from library() command."
(goto-char (point-min))
(while (re-search-forward "^\\\\package{" nil t)
(delete-region (point) (progn (beginning-of-line) (point)))
(setq beg (point))
(search-forward "}")
(delete-backward-char 1)
(add-text-properties beg (point)
'(face underline
mouse-face highlight
help-xref library))
(end-of-line)))
(defun ess-markup-libnames-old ()
"Markup the output from library() command."
(goto-char (point-min))
(while (re-search-forward "^[^ ]+ " nil t)
(beginning-of-line)
(if (not (looking-at "Packages in library"))
(progn
(setq beg (point))
(re-search-forward "[ \t]")
(add-text-properties beg (1- (point))
'(face underline
mouse-face highlight
help-xref library))))
(end-of-line)
))
;;; Set up the major mode for viewing.
(define-derived-mode ess-rpackage-mode
text-mode "Rlib"
"Major mode for browsing package contents.
\\{ess-rpackage-mode-map}"
(setq case-fold-search nil))
;; define the keys.
(if (featurep 'xemacs)
(define-key ess-rpackage-mode-map [button2] 'ess-rpackage-mouse-view)
(define-key ess-rpackage-mode-map [mouse-2] 'ess-rpackage-mouse-view)
)
(define-key ess-rpackage-mode-map [return] 'ess-rpackage-show-help)
(define-key ess-rpackage-mode-map "\t" 'help-next-ref)
(if (featurep 'xemacs)
(define-key ess-rpackage-mode-map [iso-left-tab] 'help-previous-ref)
(define-key ess-rpackage-mode-map [<S-iso-lefttab>] 'help-previous-ref))
(defun ess-rpackage-show-help ()
"Show ESS help for item on current line."
(interactive)
(let
(beg fn type)
(save-excursion
(beginning-of-line)
(setq beg (point))
(if (looking-at "[ \t\n]")
(message "No function on this line.")
(setq type (get-text-property (point) 'help-xref))
(re-search-forward "\\s-")
(setq fn (buffer-substring-no-properties beg (1- (point))))
(if (equal type 'function)
(ess-display-help-on-object fn)
(ess-rpackage fn))))))
(defun ess-rpackage-mouse-view (event)
"In rdired, visit the object on the line you click on."
;; copied from ess-rdired.
(interactive "e")
(let (window pos)
(save-excursion
(if (featurep 'xemacs)
;; XEmacs
(setq window (event-window event)
pos (event-point event))
;; Emacs
(setq window (posn-window (event-end event))
pos (posn-point (event-end event))))
(if (not (windowp window))
(error "No file chosen"))
(set-buffer (window-buffer window))
(goto-char pos)
(ess-rpackage-show-help))))
(defun ess-rdata ()
"Show the data currently available. Currently the links are not
active -- nothing is set up to handle either pressing RET or mouse-2
over a data name. Kurt suggested maybe `?' on a data item lists its
help, and RET to load the data set?"
(interactive)
(let (beg str (all t))
(setq str "data()")
(ess-execute str nil "ess-rdata")
(pop-to-buffer "*ess-rdata*")
;; Now mark up the buffer.
(goto-char (point-min))
(while (re-search-forward "^\\\\data{" nil t)
(delete-region (point) (progn (beginning-of-line) (point)))
(setq beg (point))
(search-forward "}")
(delete-backward-char 1)
(add-text-properties beg (point)
'(face underline
mouse-face highlight
help-xref library))
(end-of-line)))
(goto-char (point-min))
)
|