Klimi's new dotfiles with stow.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1861 lines
77 KiB

преди 5 години
  1. ;;; haskell-doc.el --- show function types in echo area -*- coding: utf-8; lexical-binding: t -*-
  2. ;; Copyright © 2004, 2005, 2006, 2007, 2009, 2016 Free Software Foundation, Inc.
  3. ;; Copyright © 1997 Hans-Wolfgang Loidl
  4. ;; 2016 Arthur Fayzrakhmanov
  5. ;; Author: Hans-Wolfgang Loidl <hwloidl@dcs.glasgow.ac.uk>
  6. ;; Temporary Maintainer and Hacker: Graeme E Moss <gem@cs.york.ac.uk>
  7. ;; Keywords: extensions, minor mode, language mode, Haskell
  8. ;; Created: 1997-06-17
  9. ;; URL: http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/CONTRIB/haskell-modes/emacs/haskell-doc.el?rev=HEAD
  10. ;; This file is not part of GNU Emacs.
  11. ;; This program is free software; you can redistribute it and/or modify
  12. ;; it under the terms of the GNU General Public License as published by
  13. ;; the Free Software Foundation; either version 3, or (at your option)
  14. ;; any later version.
  15. ;; This program is distributed in the hope that it will be useful,
  16. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. ;; GNU General Public License for more details.
  19. ;; You should have received a copy of the GNU General Public License
  20. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. ;;; Commentary:
  22. ;; This program shows the type of the Haskell function under the cursor in the
  23. ;; minibuffer. It acts as a kind of "Emacs background process", by regularly
  24. ;; checking the word under the cursor and matching it against a list of
  25. ;; prelude, library, local and global functions.
  26. ;; This program was inspired by the `eldoc.el' package by Noah Friedman.
  27. ;; Installation:
  28. ;; Depending on the major mode you use for your Haskell programs add
  29. ;; one of the following to your .emacs:
  30. ;;
  31. ;; (add-hook 'haskell-mode-hook 'haskell-doc-mode)
  32. ;; Customisation:
  33. ;; You can control what exactly is shown by setting the following variables to
  34. ;; either t or nil:
  35. ;; `haskell-doc-show-global-types' (default: nil)
  36. ;; `haskell-doc-show-reserved' (default: t)
  37. ;; `haskell-doc-show-prelude' (default: t)
  38. ;; `haskell-doc-show-strategy' (default: t)
  39. ;; `haskell-doc-show-user-defined' (default: t)
  40. ;; If you want to define your own strings for some identifiers define an
  41. ;; alist of (ID . STRING) and set `haskell-doc-show-user-defined' to t.
  42. ;; E.g:
  43. ;;
  44. ;; (setq haskell-doc-show-user-defined t)
  45. ;; (setq haskell-doc-user-defined-ids
  46. ;; (list
  47. ;; '("main" . "just another pathetic main function")
  48. ;; '("foo" . "a very dummy name")
  49. ;; '("bar" . "another dummy name")))
  50. ;; The following two variables are useful to make the type fit on one line:
  51. ;; If `haskell-doc-chop-off-context' is non-nil the context part of the type
  52. ;; of a local fct will be eliminated (default: t).
  53. ;; If `haskell-doc-chop-off-fctname' is non-nil the function name is not
  54. ;; shown together with the type (default: nil).
  55. ;; Internals:
  56. ;; `haskell-doc-mode' is implemented as a minor-mode. So, you can combine it
  57. ;; with any other mode. To enable it just type
  58. ;; M-x haskell-doc-mode
  59. ;; These are the names of the functions that can be called directly by the
  60. ;; user (with keybindings in `haskell-mode'):
  61. ;; `haskell-doc-mode' ... toggle haskell-doc-mode; with prefix turn it on
  62. ;; unconditionally if the prefix is greater 0 otherwise
  63. ;; turn it off
  64. ;; Key: CTRL-c CTRL-o (CTRL-u CTRL-c CTRL-o)
  65. ;; `haskell-doc-ask-mouse-for-type' ... show the type of the id under the mouse
  66. ;; Key: C-S-M-mouse-3
  67. ;; `haskell-doc-show-reserved' ... toggle echoing of reserved id's types
  68. ;; `haskell-doc-show-prelude' ... toggle echoing of prelude id's types
  69. ;; `haskell-doc-show-strategy' ... toggle echoing of strategy id's types
  70. ;; `haskell-doc-show-user-defined' ... toggle echoing of user def id's types
  71. ;; `haskell-doc-check-active' ... check whether haskell-doc is active;
  72. ;; Key: CTRL-c ESC-/
  73. ;; ToDo:
  74. ;; - Fix byte-compile problems in `haskell-doc-prelude-types' for getArgs etc
  75. ;; - Write a parser for .hi files. Read library interfaces via this parser.
  76. ;; - Indicate kind of object with colours
  77. ;; - Handle multi-line types
  78. ;; - Encode i-am-fct info in the alist of ids and types.
  79. ;; Bugs:
  80. ;; - Some prelude fcts aren't displayed properly. This might be due to a
  81. ;; name clash of Haskell and Elisp functions (e.g. length) which
  82. ;; confuses Emacs when reading `haskell-doc-prelude-types'
  83. ;;; Changelog:
  84. ;; $Log: haskell-doc.el,v $
  85. ;; Revision 1.31 2015/07/23 10:34:20 ankhers
  86. ;; (turn-on-haskell-doc-mode): marked obsolete
  87. ;; (turn-on-haskell-doc): marked obsolete
  88. ;; other packages have been moving away from (turn-on-haskell-*)
  89. ;;
  90. ;; Revision 1.30 2009/02/02 21:00:33 monnier
  91. ;; (haskell-doc-imported-list): Don't add current buffer
  92. ;; to the imported file list if it is not (yet?) visiting a file.
  93. ;;
  94. ;; Revision 1.29 2007-12-12 04:04:19 monnier
  95. ;; (haskell-doc-in-code-p): New function.
  96. ;; (haskell-doc-show-type): Use it.
  97. ;;
  98. ;; Revision 1.28 2007/08/30 03:10:08 monnier
  99. ;; Comment/docs fixes.
  100. ;;
  101. ;; Revision 1.27 2007/07/30 17:36:50 monnier
  102. ;; (displayed-month): Remove declaration since it's not used here.
  103. ;;
  104. ;; Revision 1.26 2007/02/10 06:28:55 monnier
  105. ;; (haskell-doc-get-current-word): Remove.
  106. ;; Change all refs to it, to use haskell-ident-at-point instead.
  107. ;;
  108. ;; Revision 1.25 2007/02/09 21:53:42 monnier
  109. ;; (haskell-doc-get-current-word): Correctly distinguish
  110. ;; variable identifiers and infix identifiers.
  111. ;; (haskell-doc-rescan-files): Avoid switch-to-buffer.
  112. ;; (haskell-doc-imported-list): Operate on current buffer.
  113. ;; (haskell-doc-make-global-fct-index): Adjust call.
  114. ;;
  115. ;; Revision 1.24 2006/11/20 20:18:24 monnier
  116. ;; (haskell-doc-mode-print-current-symbol-info): Fix thinko.
  117. ;;
  118. ;; Revision 1.23 2006/10/20 03:12:31 monnier
  119. ;; Drop post-command-idle-hook in favor of run-with-idle-timer.
  120. ;; (haskell-doc-timer, haskell-doc-buffers): New vars.
  121. ;; (haskell-doc-mode): Use them.
  122. ;; (haskell-doc-check-active): Update the check.
  123. ;; (haskell-doc-mode-print-current-symbol-info): Remove the interactive spec.
  124. ;; Don't sit-for unless it's really needed.
  125. ;;
  126. ;; Revision 1.22 2006/09/20 18:42:35 monnier
  127. ;; Doc fix.
  128. ;;
  129. ;; Revision 1.21 2005/11/21 21:48:52 monnier
  130. ;; * haskell-doc.el (haskell-doc-extract-types): Get labelled data working.
  131. ;; (haskell-doc-prelude-types): Update via auto-generation.
  132. ;;
  133. ;; * haskell-doc.el (haskell-doc-extract-types): Get it partly working.
  134. ;; (haskell-doc-fetch-lib-urls): Don't use a literal if we apply
  135. ;; `nreverse' on it later on.
  136. ;; (haskell-doc-prelude-types): Update some parts by auto-generation.
  137. ;; (haskell-doc-grab, haskell-doc-string-nub-ws): Simplify.
  138. ;;
  139. ;; * haskell-doc.el (haskell-doc-maintainer, haskell-doc-varlist)
  140. ;; (haskell-doc-submit-bug-report, haskell-doc-ftp-site)
  141. ;; (haskell-doc-visit-home): Remove.
  142. ;; (haskell-doc-reserved-ids, haskell-doc-fetch-lib-urls)
  143. ;; (haskell-doc-extract-and-insert-types): New funs.
  144. ;; (haskell-doc-reserved-ids): Fix type of `map'.
  145. ;;
  146. ;; Revision 1.20 2005/11/21 21:27:57 monnier
  147. ;; (haskell-doc-extract-types): Get labelled data working.
  148. ;; (haskell-doc-prelude-types): Update via auto-generation.
  149. ;;
  150. ;; Revision 1.19 2005/11/21 20:44:13 monnier
  151. ;; (haskell-doc-extract-types): Get it partly working.
  152. ;; (haskell-doc-fetch-lib-urls): Don't use a literal if we apply
  153. ;; `nreverse' on it later on.
  154. ;; (haskell-doc-prelude-types): Update some parts by auto-generation.
  155. ;; (haskell-doc-grab, haskell-doc-string-nub-ws): Simplify.
  156. ;;
  157. ;; Revision 1.18 2005/11/21 18:02:15 monnier
  158. ;; (haskell-doc-maintainer, haskell-doc-varlist)
  159. ;; (haskell-doc-submit-bug-report, haskell-doc-ftp-site)
  160. ;; (haskell-doc-visit-home): Remove.
  161. ;; (haskell-doc-reserved-ids, haskell-doc-fetch-lib-urls)
  162. ;; (haskell-doc-extract-and-insert-types): New funs.
  163. ;; (haskell-doc-reserved-ids): Fix type of `map'.
  164. ;;
  165. ;; Revision 1.17 2005/11/20 23:55:09 monnier
  166. ;; Add coding cookie.
  167. ;;
  168. ;; Revision 1.16 2005/11/07 01:28:16 monnier
  169. ;; (haskell-doc-xemacs-p, haskell-doc-emacs-p)
  170. ;; (haskell-doc-message): Remove.
  171. ;; (haskell-doc-is-id-char-at): Remove.
  172. ;; (haskell-doc-get-current-word): Rewrite.
  173. ;;
  174. ;; Revision 1.15 2005/11/04 17:11:12 monnier
  175. ;; Add arch-tag.
  176. ;;
  177. ;; Revision 1.14 2005/08/24 11:36:32 monnier
  178. ;; (haskell-doc-message): Paren typo.
  179. ;;
  180. ;; Revision 1.13 2005/08/23 19:23:27 monnier
  181. ;; (haskell-doc-show-type): Assume that the availability
  182. ;; of display-message won't change at runtime.
  183. ;;
  184. ;; Revision 1.12 2005/07/18 21:04:14 monnier
  185. ;; (haskell-doc-message): Remove.
  186. ;; (haskell-doc-show-type): inline it. Do nothing for if there's no doc to show.
  187. ;;
  188. ;; Revision 1.11 2004/12/10 17:33:18 monnier
  189. ;; (haskell-doc-minor-mode-string): Make it dynamic.
  190. ;; (haskell-doc-install-keymap): Remove conflicting C-c C-o binding.
  191. ;; (haskell-doc-mode): Make a nil arg turn the mode ON.
  192. ;; (turn-on-haskell-doc-mode): Make it an alias for haskell-doc-mode.
  193. ;; (haskell-doc-mode): Don't touch haskell-doc-minor-mode-string.
  194. ;; (haskell-doc-show-global-types): Don't touch
  195. ;; haskell-doc-minor-mode-string. Call haskell-doc-make-global-fct-index.
  196. ;; (haskell-doc-check-active): Fix message.
  197. ;; (define-key-after): Don't define.
  198. ;; (haskell-doc-install-keymap): Check existence of define-key-after.
  199. ;;
  200. ;; Revision 1.10 2004/11/25 23:03:23 monnier
  201. ;; (haskell-doc-sym-doc): Make even the last char bold.
  202. ;;
  203. ;; Revision 1.9 2004/11/24 22:14:36 monnier
  204. ;; (haskell-doc-install-keymap): Don't blindly assume there's a Hugs menu.
  205. ;;
  206. ;; Revision 1.8 2004/11/22 10:45:35 simonmar
  207. ;; Fix type of getLine
  208. ;;
  209. ;; Revision 1.7 2004/10/14 22:27:47 monnier
  210. ;; (turn-off-haskell-doc-mode, haskell-doc-current-info): Don't autoload.
  211. ;;
  212. ;; Revision 1.6 2004/10/13 22:45:22 monnier
  213. ;; (haskell-doc): New group.
  214. ;; (haskell-doc-show-reserved, haskell-doc-show-prelude)
  215. ;; (haskell-doc-show-strategy, haskell-doc-show-user-defined)
  216. ;; (haskell-doc-chop-off-context, haskell-doc-chop-off-fctname):
  217. ;; Make them custom vars.
  218. ;; (haskell-doc-keymap): Declare and fill it right there.
  219. ;; (haskell-doc-mode): Simplify.
  220. ;; (haskell-doc-toggle-var): Make it into what it was supposed to be.
  221. ;; (haskell-doc-mode-print-current-symbol-info): Simplify.
  222. ;; (haskell-doc-current-info): New autoloaded function.
  223. ;; (haskell-doc-sym-doc): New fun extracted from haskell-doc-show-type.
  224. ;; (haskell-doc-show-type): Use it.
  225. ;; (haskell-doc-wrapped-type-p): Remove unused var `lim'.
  226. ;; (haskell-doc-forward-sexp-safe, haskell-doc-current-symbol): Remove. Unused.
  227. ;; (haskell-doc-visit-home): Don't require ange-ftp, it's autoloaded.
  228. ;; (haskell-doc-install-keymap): Simplify.
  229. ;;
  230. ;; Revision 1.5 2003/01/09 11:56:26 simonmar
  231. ;; Patches from Ville Skyttä <scop@xemacs.org>, the XEmacs maintainer of
  232. ;; the haskell-mode:
  233. ;;
  234. ;; - Make the auto-mode-alist modifications autoload-only.
  235. ;;
  236. ;; Revision 1.4 2002/10/14 09:55:03 simonmar
  237. ;; Patch to update the Prelude/libraries function names and to remove
  238. ;; support for older versions of Haskell.
  239. ;;
  240. ;; Submitted by: Anders Lau Olsen <alauo@mip.sdu.dk>
  241. ;;
  242. ;; Revision 1.3 2002/04/30 09:34:37 rrt
  243. ;; Remove supporting Haskell 1.4 and 1.2 from the ToDo list. It's Far Too Late.
  244. ;;
  245. ;; Add (require 'imenu). Thanks to N. Y. Kwok.
  246. ;;
  247. ;; Revision 1.2 2002/04/23 14:45:10 simonmar
  248. ;; Tweaks to the doc strings and support for customization, from
  249. ;; Ville Skyttä <scop@xemacs.org>.
  250. ;;
  251. ;; Revision 1.1 2001/07/19 16:17:36 rrt
  252. ;; Add the current version of the Moss/Thorn/Marlow Emacs mode, along with its
  253. ;; web pages and sample files. This is now the preferred mode, and the
  254. ;; haskell.org pages are being changed to reflect that. Also includes the new
  255. ;; GHCi mode from Chris Webb.
  256. ;;
  257. ;; Revision 1.6 1998/12/10 16:27:25 hwloidl
  258. ;; Minor changes ("Doc" as modeline string, mouse-3 moved to C-S-M-mouse-3)
  259. ;;
  260. ;; Revision 1.5 1998/09/24 14:25:46 gem
  261. ;; Fixed minor compatibility bugs with Haskell mode of Moss&Thorn.
  262. ;; Disabled M-/ binding.
  263. ;;
  264. ;; Revision 1.4 1997/11/12 23:51:19 hwloidl
  265. ;; Fixed start-up problem under emacs-19.34.
  266. ;; Added support for wrapped (multi-line) types and 2 vars to control the
  267. ;; behaviour with long fct types
  268. ;;
  269. ;; Revision 1.3 1997/11/03 00:48:03 hwloidl
  270. ;; Major revision for first release.
  271. ;; Added alists for showing prelude fcts, haskell syntax, and strategies
  272. ;; Added mouse interface to show type under mouse
  273. ;; Fixed bug which causes demon to fall over
  274. ;; Works now with hugs-mode and haskell-mode under emacs 19.34,20 and xemacs 19.15
  275. ;;
  276. ;;; Code:
  277. (require 'haskell-mode)
  278. (require 'haskell-process)
  279. (require 'haskell)
  280. (require 'haskell-utils)
  281. (require 'inf-haskell)
  282. (require 'imenu)
  283. (require 'eldoc)
  284. ;;;###autoload
  285. (defgroup haskell-doc nil
  286. "Show Haskell function types in echo area."
  287. :group 'haskell
  288. :prefix "haskell-doc-")
  289. (defvar-local haskell-doc-mode nil
  290. "*If non-nil, show the type of the function near point or a related comment.
  291. If the identifier near point is a Haskell keyword and the variable
  292. `haskell-doc-show-reserved' is non-nil show a one line summary
  293. of the syntax.
  294. If the identifier near point is a Prelude or one of the standard library
  295. functions and `haskell-doc-show-prelude' is non-nil show its type.
  296. If the identifier near point is local \(i.e. defined in this module\) check
  297. the `imenu' list of functions for the type. This obviously requires that
  298. your language mode uses `imenu'.
  299. If the identifier near point is global \(i.e. defined in an imported module\)
  300. and the variable `haskell-doc-show-global-types' is non-nil show the type of its
  301. function.
  302. If the identifier near point is a standard strategy or a function, type related
  303. related to strategies and `haskell-doc-show-strategy' is non-nil show the type
  304. of the function. Strategies are special to the parallel execution of Haskell.
  305. If you're not interested in that just turn it off.
  306. If the identifier near point is a user defined function that occurs as key
  307. in the alist `haskell-doc-user-defined-ids' and the variable
  308. `haskell-doc-show-user-defined' is non-nil show the type of the function.
  309. This variable is buffer-local.")
  310. (defvar haskell-doc-mode-hook nil
  311. "Hook invoked when entering `haskell-doc-mode'.")
  312. (defvar-local haskell-doc-index nil
  313. "Variable holding an alist matching file names to fct-type alists.
  314. The function `haskell-doc-make-global-fct-index' rebuilds this variables
  315. \(similar to an `imenu' rescan\).
  316. This variable is buffer-local.")
  317. (defcustom haskell-doc-show-global-types nil
  318. "If non-nil, search for the types of global functions by loading the files.
  319. This variable is buffer-local."
  320. :group 'haskell-doc
  321. :type 'boolean)
  322. (make-variable-buffer-local 'haskell-doc-show-global-types)
  323. (defcustom haskell-doc-show-reserved t
  324. "If non-nil, show a documentation string for reserved ids.
  325. This variable is buffer-local."
  326. :group 'haskell-doc
  327. :type 'boolean)
  328. (make-variable-buffer-local 'haskell-doc-show-reserved)
  329. (defcustom haskell-doc-show-prelude t
  330. "If non-nil, show a documentation string for prelude functions.
  331. This variable is buffer-local."
  332. :group 'haskell-doc
  333. :type 'boolean)
  334. (make-variable-buffer-local 'haskell-doc-show-prelude)
  335. (defcustom haskell-doc-show-strategy t
  336. "If non-nil, show a documentation string for strategies.
  337. This variable is buffer-local."
  338. :group 'haskell-doc
  339. :type 'boolean)
  340. (make-variable-buffer-local 'haskell-doc-show-strategy)
  341. (defcustom haskell-doc-show-user-defined t
  342. "If non-nil, show a documentation string for user defined ids.
  343. This variable is buffer-local."
  344. :group 'haskell-doc
  345. :type 'boolean)
  346. (make-variable-buffer-local 'haskell-doc-show-user-defined)
  347. (defcustom haskell-doc-chop-off-context t
  348. "If non-nil eliminate the context part in a Haskell type."
  349. :group 'haskell-doc
  350. :type 'boolean)
  351. (defcustom haskell-doc-chop-off-fctname nil
  352. "If non-nil omit the function name and show only the type."
  353. :group 'haskell-doc
  354. :type 'boolean)
  355. (defcustom haskell-doc-use-inf-haskell nil
  356. "If non-nil use inf-haskell.el to get type and kind information."
  357. :group 'haskell-doc
  358. :type 'boolean)
  359. (defvar haskell-doc-search-distance 40 ; distance in characters
  360. "*How far to search when looking for the type declaration of fct under cursor.")
  361. (defvar haskell-doc-idle-delay 0.50
  362. "*Number of seconds of idle time to wait before printing.
  363. If user input arrives before this interval of time has elapsed after the
  364. last input, no documentation will be printed.
  365. If this variable is set to 0, no idle time is required.")
  366. (defvar haskell-doc-argument-case 'identity ; 'upcase
  367. "Case in which to display argument names of functions, as a symbol.
  368. This has two preferred values: `upcase' or `downcase'.
  369. Actually, any name of a function which takes a string as an argument and
  370. returns another string is acceptable.")
  371. (defvar haskell-doc-mode-message-commands nil
  372. "*Obarray of command names where it is appropriate to print in the echo area.
  373. This is not done for all commands since some print their own
  374. messages in the echo area, and these functions would instantly overwrite
  375. them. But `self-insert-command' as well as most motion commands are good
  376. candidates.
  377. It is probably best to manipulate this data structure with the commands
  378. `haskell-doc-add-command' and `haskell-doc-remove-command'.")
  379. ;;(cond ((null haskell-doc-mode-message-commands)
  380. ;; ;; If you increase the number of buckets, keep it a prime number.
  381. ;; (setq haskell-doc-mode-message-commands (make-vector 31 0))
  382. ;; (let ((list '("self-insert-command"
  383. ;; "next-" "previous-"
  384. ;; "forward-" "backward-"
  385. ;; "beginning-of-" "end-of-"
  386. ;; "goto-"
  387. ;; "recenter"
  388. ;; "scroll-"))
  389. ;; (syms nil))
  390. ;; (while list
  391. ;; (setq syms (all-completions (car list) obarray 'fboundp))
  392. ;; (setq list (cdr list))
  393. ;; (while syms
  394. ;; (set (intern (car syms) haskell-doc-mode-message-commands) t)
  395. ;; (setq syms (cdr syms)))))))
  396. ;; Bookkeeping; the car contains the last symbol read from the buffer.
  397. ;; The cdr contains the string last displayed in the echo area, so it can
  398. ;; be printed again if necessary without reconsing.
  399. (defvar haskell-doc-last-data '(nil . nil))
  400. (defvar haskell-doc-minor-mode-string
  401. '(haskell-doc-show-global-types " DOC" " Doc")
  402. "*String to display in mode line when Haskell-Doc Mode is enabled.")
  403. (defvar haskell-doc-reserved-ids
  404. '(("case" . "case exp of { alts [;] }")
  405. ("class" . "class [context =>] simpleclass [where { cbody [;] }]")
  406. ("data" . "data [context =>] simpletype = constrs [deriving]")
  407. ("default" . "default (type1 , ... , typen)")
  408. ("deriving" . "deriving (dclass | (dclass1, ... , dclassn))") ; used with data or newtype
  409. ("do" . "do { stmts [;] } stmts -> exp [; stmts] | pat <- exp ; stmts | let decllist ; stmts")
  410. ("else" . "if exp then exp else exp")
  411. ("if" . "if exp then exp else exp")
  412. ("import" . "import [qualified] modid [as modid] [impspec]")
  413. ("in" . "let decllist in exp")
  414. ("infix" . "infix [digit] ops")
  415. ("infixl" . "infixl [digit] ops")
  416. ("infixr" . "infixr [digit] ops")
  417. ("instance" . "instance [context =>] qtycls inst [where { valdefs [;] }]")
  418. ("let" . "let { decl; ...; decl [;] } in exp")
  419. ("module" . "module modid [exports] where body")
  420. ("newtype" . "newtype [context =>] simpletype = con atype [deriving]")
  421. ("of" . "case exp of { alts [;] }")
  422. ("then" . "if exp then exp else exp")
  423. ("type" . "type simpletype = type")
  424. ("where" . "exp where { decl; ...; decl [;] }") ; check that ; see also class, instance, module
  425. ("as" . "import [qualified] modid [as modid] [impspec]")
  426. ("qualified" . "import [qualified] modid [as modid] [impspec]")
  427. ("hiding" . "hiding ( import1 , ... , importn [ , ] )")
  428. ("family" . "(type family type [kind] [= type_fam_equations]) | (data family type [kind])"))
  429. "An alist of reserved identifiers.
  430. Each element is of the form (ID . DOC) where both ID and DOC are strings.
  431. DOC should be a concise single-line string describing the construct in which
  432. the keyword is used.")
  433. (defun haskell-doc-extract-types (url)
  434. (with-temp-buffer
  435. (insert-file-contents url)
  436. (goto-char (point-min))
  437. (while (search-forward "&nbsp;" nil t) (replace-match " " t t))
  438. ;; First, focus on the actual code, removing the surrounding HTML text.
  439. (goto-char (point-min))
  440. (let ((last (point-min))
  441. (modules nil))
  442. (while (re-search-forward "^module +\\([[:alnum:]]+\\)" nil t)
  443. (let ((module (match-string 1)))
  444. (if (member module modules)
  445. ;; The library nodes of the HTML doc contain modules twice:
  446. ;; once at the top, with only type declarations, and once at
  447. ;; the bottom with an actual sample implementation which may
  448. ;; include declaration of non-exported values.
  449. ;; We're now at this second occurrence is the implementation
  450. ;; which should thus be ignored.
  451. nil
  452. (push module modules)
  453. (delete-region last (point))
  454. (search-forward "</tt>")
  455. ;; Some of the blocks of code are split.
  456. (while (looking-at "\\(<[^<>]+>[ \t\n]*\\)*<tt>")
  457. (goto-char (match-end 0))
  458. (search-forward "</tt>"))
  459. (setq last (point)))))
  460. (delete-region last (point-max))
  461. ;; Then process the HTML encoding to get back to pure ASCII.
  462. (goto-char (point-min))
  463. (while (search-forward "<br>" nil t) (replace-match "\n" t t))
  464. ;; (goto-char (point-min))
  465. ;; (while (re-search-forward "<[^<>]+>" nil t) (replace-match "" t t))
  466. (goto-char (point-min))
  467. (while (search-forward "&gt;" nil t) (replace-match ">" t t))
  468. (goto-char (point-min))
  469. (while (search-forward "&lt;" nil t) (replace-match "<" t t))
  470. (goto-char (point-min))
  471. (while (search-forward "&amp;" nil t) (replace-match "&" t t))
  472. (goto-char (point-min))
  473. (if (re-search-forward "&[a-z]+;" nil t)
  474. (error "Unexpected charref %s" (match-string 0)))
  475. ;; Remove TABS.
  476. (goto-char (point-min))
  477. (while (search-forward "\t" nil t) (replace-match " " t t))
  478. ;; Finally, extract the actual data.
  479. (goto-char (point-min))
  480. (let* ((elems nil)
  481. (space-re "[ \t\n]*\\(?:--.*\n[ \t\n]*\\)*")
  482. (comma-re (concat " *," space-re))
  483. ;; A list of identifiers. We have to be careful to weed out
  484. ;; entries like "ratPrec = 7 :: Int". Also ignore entries
  485. ;; which start with a < since they're actually in the HTML text
  486. ;; part. And the list may be spread over several lines, cut
  487. ;; after a comma.
  488. (idlist-re
  489. (concat "\\([^< \t\n][^ \t\n]*"
  490. "\\(?:" comma-re "[^ \t\n]+\\)*\\)"))
  491. ;; A type. A few types are spread over 2 lines,
  492. ;; cut after the "=>", so we have to handle these as well.
  493. (type-re "\\(.*[^\n>]\\(?:>[ \t\n]+.*[^\n>]\\)*\\) *$")
  494. ;; A decl of a list of values, possibly indented.
  495. (val-decl-re
  496. (concat "^\\( +\\)?" idlist-re "[ \t\n]*::[ \t\n]*" type-re))
  497. (re (concat
  498. ;; 3 possibilities: a class decl, a data decl, or val decl.
  499. ;; First, let's match a class decl.
  500. "^class \\(?:.*=>\\)? *\\(.*[^ \t\n]\\)[ \t\n]*where"
  501. ;; Or a value decl:
  502. "\\|" val-decl-re
  503. "\\|" ;; Or a data decl. We only handle single-arm
  504. ;; datatypes with labels.
  505. "^data +\\([[:alnum:]][[:alnum:] ]*[[:alnum:]]\\)"
  506. " *=.*{\\([^}]+\\)}"
  507. ))
  508. (re-class (concat "^[^ \t\n]\\|" re))
  509. curclass)
  510. (while (re-search-forward (if curclass re-class re) nil t)
  511. (cond
  512. ;; A class decl.
  513. ((match-end 1) (setq curclass (match-string 1)))
  514. ;; A value decl.
  515. ((match-end 4)
  516. (let ((type (match-string 4))
  517. (vars (match-string 3))
  518. (indented (match-end 2)))
  519. (if (string-match "[ \t\n][ \t\n]+" type)
  520. (setq type (replace-match " " t t type)))
  521. (if (string-match " *\\(--.*\\)?\\'" type)
  522. (setq type (substring type 0 (match-beginning 0))))
  523. (if indented
  524. (if curclass
  525. (if (string-match "\\`\\(.*[^ \t\n]\\) *=> *" type)
  526. (let ((classes (match-string 1 type)))
  527. (setq type (substring type (match-end 0)))
  528. (if (string-match "\\`(.*)\\'" classes)
  529. (setq classes (substring classes 1 -1)))
  530. (setq type (concat "(" curclass ", " classes
  531. ") => " type)))
  532. (setq type (concat curclass " => " type)))
  533. ;; It's actually not an error: just a type annotation on
  534. ;; some local variable.
  535. ;; (error "Indentation outside a class in %s: %s"
  536. ;; module vars)
  537. nil)
  538. (setq curclass nil))
  539. (dolist (var (split-string vars comma-re t))
  540. (if (string-match "(.*)" var) (setq var (substring var 1 -1)))
  541. (push (cons var type) elems))))
  542. ;; A datatype decl.
  543. ((match-end 5)
  544. (setq curclass nil)
  545. (let ((name (match-string 5)))
  546. (save-excursion
  547. (save-restriction
  548. (narrow-to-region (match-beginning 6) (match-end 6))
  549. (goto-char (point-min))
  550. (while (re-search-forward val-decl-re nil t)
  551. (let ((vars (match-string 2))
  552. (type (match-string 3)))
  553. (if (string-match "[ \t\n][ \t\n]+" type)
  554. (setq type (replace-match " " t t type)))
  555. (if (string-match " *\\(--.*\\)?\\'" type)
  556. (setq type (substring type 0 (match-beginning 0))))
  557. (if (string-match ",\\'" type)
  558. (setq type (substring type 0 -1)))
  559. (setq type (concat name " -> " type))
  560. (dolist (var (split-string vars comma-re t))
  561. (if (string-match "(.*)" var)
  562. (setq var (substring var 1 -1)))
  563. (push (cons var type) elems))))))))
  564. ;; The end of a class declaration.
  565. (t (setq curclass nil) (beginning-of-line))))
  566. (cons (car (last modules)) elems)))))
  567. (defun haskell-doc-fetch-lib-urls (base-url)
  568. (with-temp-buffer
  569. (insert-file-contents base-url)
  570. (goto-char (point-min))
  571. (search-forward "Part II: Libraries")
  572. (delete-region (point-min) (point))
  573. (search-forward "</table>")
  574. (delete-region (point) (point-max))
  575. (goto-char (point-min))
  576. (let ((libs (list "standard-prelude.html")))
  577. (while (re-search-forward "<a href=\"\\([^\"]+\\)\">" nil t)
  578. (push (match-string 1) libs))
  579. (mapcar (lambda (s) (expand-file-name s (file-name-directory base-url)))
  580. (nreverse libs)))))
  581. (defun haskell-doc-extract-and-insert-types (url)
  582. "Fetch the types from the online doc and insert them at point.
  583. URL is the URL of the online doc."
  584. (interactive (if current-prefix-arg
  585. (read-file-name "URL: ")
  586. (list "http://www.haskell.org/onlinereport/")))
  587. (let ((urls (haskell-doc-fetch-lib-urls url)))
  588. (dolist (url urls)
  589. (let ((data (haskell-doc-extract-types url)))
  590. (insert ";; " (pop data)) (indent-according-to-mode) (newline)
  591. (dolist (elem (sort data (lambda (x y) (string-lessp (car x) (car y)))))
  592. (prin1 elem (current-buffer))
  593. (indent-according-to-mode) (newline))))))
  594. (defvar haskell-doc-prelude-types
  595. ;; This list was auto generated by `haskell-doc-extract-and-insert-types'.
  596. '(
  597. ;; Prelude
  598. ("!!" . "[a] -> Int -> a")
  599. ("$" . "(a -> b) -> a -> b")
  600. ("$!" . "(a -> b) -> a -> b")
  601. ("&&" . "Bool -> Bool -> Bool")
  602. ("*" . "Num a => a -> a -> a")
  603. ("**" . "Floating a => a -> a -> a")
  604. ("+" . "Num a => a -> a -> a")
  605. ("++" . "[a] -> [a] -> [a]")
  606. ("-" . "Num a => a -> a -> a")
  607. ("." . "(b -> c) -> (a -> b) -> a -> c")
  608. ("/" . "Fractional a => a -> a -> a")
  609. ("/=" . "Eq a => a -> a -> Bool")
  610. ("<" . "Ord a => a -> a -> Bool")
  611. ("<=" . "Ord a => a -> a -> Bool")
  612. ("=<<" . "Monad m => (a -> m b) -> m a -> m b")
  613. ("==" . "Eq a => a -> a -> Bool")
  614. (">" . "Ord a => a -> a -> Bool")
  615. (">=" . "Ord a => a -> a -> Bool")
  616. (">>" . "Monad m => m a -> m b -> m b")
  617. (">>=" . "Monad m => m a -> (a -> m b) -> m b")
  618. ("^" . "(Num a, Integral b) => a -> b -> a")
  619. ("^^" . "(Fractional a, Integral b) => a -> b -> a")
  620. ("abs" . "Num a => a -> a")
  621. ("acos" . "Floating a => a -> a")
  622. ("acosh" . "Floating a => a -> a")
  623. ("all" . "(a -> Bool) -> [a] -> Bool")
  624. ("and" . "[Bool] -> Bool")
  625. ("any" . "(a -> Bool) -> [a] -> Bool")
  626. ("appendFile" . "FilePath -> String -> IO ()")
  627. ("asTypeOf" . "a -> a -> a")
  628. ("asin" . "Floating a => a -> a")
  629. ("asinh" . "Floating a => a -> a")
  630. ("atan" . "Floating a => a -> a")
  631. ("atan2" . "RealFloat a => a -> a -> a")
  632. ("atanh" . "Floating a => a -> a")
  633. ("break" . "(a -> Bool) -> [a] -> ([a],[a])")
  634. ("catch" . "IO a -> (IOError -> IO a) -> IO a")
  635. ("ceiling" . "(RealFrac a, Integral b) => a -> b")
  636. ("compare" . "Ord a => a -> a -> Ordering")
  637. ("concat" . "[[a]] -> [a]")
  638. ("concatMap" . "(a -> [b]) -> [a] -> [b]")
  639. ("const" . "a -> b -> a")
  640. ("cos" . "Floating a => a -> a")
  641. ("cosh" . "Floating a => a -> a")
  642. ("curry" . "((a, b) -> c) -> a -> b -> c")
  643. ("cycle" . "[a] -> [a]")
  644. ("decodeFloat" . "RealFloat a => a -> (Integer,Int)")
  645. ("div" . "Integral a => a -> a -> a")
  646. ("divMod" . "Integral a => a -> a -> (a,a)")
  647. ("drop" . "Int -> [a] -> [a]")
  648. ("dropWhile" . "(a -> Bool) -> [a] -> [a]")
  649. ("either" . "(a -> c) -> (b -> c) -> Either a b -> c")
  650. ("elem" . "(Eq a) => a -> [a] -> Bool")
  651. ("encodeFloat" . "RealFloat a => Integer -> Int -> a")
  652. ("enumFrom" . "Enum a => a -> [a]")
  653. ("enumFromThen" . "Enum a => a -> a -> [a]")
  654. ("enumFromThenTo" . "Enum a => a -> a -> a -> [a]")
  655. ("enumFromTo" . "Enum a => a -> a -> [a]")
  656. ("error" . "String -> a")
  657. ("even" . "(Integral a) => a -> Bool")
  658. ("exp" . "Floating a => a -> a")
  659. ("exponent" . "RealFloat a => a -> Int")
  660. ("fail" . "Monad m => String -> m a")
  661. ("filter" . "(a -> Bool) -> [a] -> [a]")
  662. ("flip" . "(a -> b -> c) -> b -> a -> c")
  663. ("floatDigits" . "RealFloat a => a -> Int")
  664. ("floatRadix" . "RealFloat a => a -> Integer")
  665. ("floatRange" . "RealFloat a => a -> (Int,Int)")
  666. ("floor" . "(RealFrac a, Integral b) => a -> b")
  667. ("fmap" . "Functor f => (a -> b) -> f a -> f b")
  668. ("foldl" . "(a -> b -> a) -> a -> [b] -> a")
  669. ("foldl1" . "(a -> a -> a) -> [a] -> a")
  670. ("foldr" . "(a -> b -> b) -> b -> [a] -> b")
  671. ("foldr1" . "(a -> a -> a) -> [a] -> a")
  672. ("fromEnum" . "Enum a => a -> Int")
  673. ("fromInteger" . "Num a => Integer -> a")
  674. ("fromIntegral" . "(Integral a, Num b) => a -> b")
  675. ("fromRational" . "Fractional a => Rational -> a")
  676. ("fst" . "(a,b) -> a")
  677. ("gcd" . "(Integral a) => a -> a -> a")
  678. ("getChar" . "IO Char")
  679. ("getContents" . "IO String")
  680. ("getLine" . "IO String")
  681. ("head" . "[a] -> a")
  682. ("id" . "a -> a")
  683. ("init" . "[a] -> [a]")
  684. ("interact" . "(String -> String) -> IO ()")
  685. ("ioError" . "IOError -> IO a")
  686. ("isDenormalized" . "RealFloat a => a -> Bool")
  687. ("isIEEE" . "RealFloat a => a -> Bool")
  688. ("isInfinite" . "RealFloat a => a -> Bool")
  689. ("isNaN" . "RealFloat a => a -> Bool")
  690. ("isNegativeZero" . "RealFloat a => a -> Bool")
  691. ("iterate" . "(a -> a) -> a -> [a]")
  692. ("last" . "[a] -> a")
  693. ("lcm" . "(Integral a) => a -> a -> a")
  694. ("length" . "[a] -> Int")
  695. ("lex" . "ReadS String")
  696. ("lines" . "String -> [String]")
  697. ("log" . "Floating a => a -> a")
  698. ("logBase" . "Floating a => a -> a -> a")
  699. ("lookup" . "(Eq a) => a -> [(a,b)] -> Maybe b")
  700. ("map" . "(a -> b) -> [a] -> [b]")
  701. ("mapM" . "Monad m => (a -> m b) -> [a] -> m [b]")
  702. ("mapM_" . "Monad m => (a -> m b) -> [a] -> m ()")
  703. ("max" . "Ord a => a -> a -> a")
  704. ("maxBound" . "Bounded a => a")
  705. ("maximum" . "(Ord a) => [a] -> a")
  706. ("maybe" . "b -> (a -> b) -> Maybe a -> b")
  707. ("min" . "Ord a => a -> a -> a")
  708. ("minBound" . "Bounded a => a")
  709. ("minimum" . "(Ord a) => [a] -> a")
  710. ("mod" . "Integral a => a -> a -> a")
  711. ("negate" . "Num a => a -> a")
  712. ("not" . "Bool -> Bool")
  713. ("notElem" . "(Eq a) => a -> [a] -> Bool")
  714. ("null" . "[a] -> Bool")
  715. ("numericEnumFrom" . "(Fractional a) => a -> [a]")
  716. ("numericEnumFromThen" . "(Fractional a) => a -> a -> [a]")
  717. ("numericEnumFromThenTo" . "(Fractional a, Ord a) => a -> a -> a -> [a]")
  718. ("numericEnumFromTo" . "(Fractional a, Ord a) => a -> a -> [a]")
  719. ("odd" . "(Integral a) => a -> Bool")
  720. ("or" . "[Bool] -> Bool")
  721. ("otherwise" . "Bool")
  722. ("pi" . "Floating a => a")
  723. ("pred" . "Enum a => a -> a")
  724. ("print" . "Show a => a -> IO ()")
  725. ("product" . "(Num a) => [a] -> a")
  726. ("properFraction" . "(RealFrac a, Integral b) => a -> (b,a)")
  727. ("putChar" . "Char -> IO ()")
  728. ("putStr" . "String -> IO ()")
  729. ("putStrLn" . "String -> IO ()")
  730. ("quot" . "Integral a => a -> a -> a")
  731. ("quotRem" . "Integral a => a -> a -> (a,a)")
  732. ("read" . "(Read a) => String -> a")
  733. ("readFile" . "FilePath -> IO String")
  734. ("readIO" . "Read a => String -> IO a")
  735. ("readList" . "Read a => ReadS [a]")
  736. ("readLn" . "Read a => IO a")
  737. ("readParen" . "Bool -> ReadS a -> ReadS a")
  738. ("reads" . "(Read a) => ReadS a")
  739. ("readsPrec" . "Read a => Int -> ReadS a")
  740. ("realToFrac" . "(Real a, Fractional b) => a -> b")
  741. ("recip" . "Fractional a => a -> a")
  742. ("rem" . "Integral a => a -> a -> a")
  743. ("repeat" . "a -> [a]")
  744. ("replicate" . "Int -> a -> [a]")
  745. ("return" . "Monad m => a -> m a")
  746. ("reverse" . "[a] -> [a]")
  747. ("round" . "(RealFrac a, Integral b) => a -> b")
  748. ("scaleFloat" . "RealFloat a => Int -> a -> a")
  749. ("scanl" . "(a -> b -> a) -> a -> [b] -> [a]")
  750. ("scanl1" . "(a -> a -> a) -> [a] -> [a]")
  751. ("scanr" . "(a -> b -> b) -> b -> [a] -> [b]")
  752. ("scanr1" . "(a -> a -> a) -> [a] -> [a]")
  753. ("seq" . "a -> b -> b")
  754. ("sequence" . "Monad m => [m a] -> m [a]")
  755. ("sequence_" . "Monad m => [m a] -> m ()")
  756. ("show" . "Show a => a -> String")
  757. ("showChar" . "Char -> ShowS")
  758. ("showList" . "Show a => [a] -> ShowS")
  759. ("showParen" . "Bool -> ShowS -> ShowS")
  760. ("showString" . "String -> ShowS")
  761. ("shows" . "(Show a) => a -> ShowS")
  762. ("showsPrec" . "Show a => Int -> a -> ShowS")
  763. ("significand" . "RealFloat a => a -> a")
  764. ("signum" . "Num a => a -> a")
  765. ("sin" . "Floating a => a -> a")
  766. ("sinh" . "Floating a => a -> a")
  767. ("snd" . "(a,b) -> b")
  768. ("span" . "(a -> Bool) -> [a] -> ([a],[a])")
  769. ("splitAt" . "Int -> [a] -> ([a],[a])")
  770. ("sqrt" . "Floating a => a -> a")
  771. ("subtract" . "(Num a) => a -> a -> a")
  772. ("succ" . "Enum a => a -> a")
  773. ("sum" . "(Num a) => [a] -> a")
  774. ("tail" . "[a] -> [a]")
  775. ("take" . "Int -> [a] -> [a]")
  776. ("takeWhile" . "(a -> Bool) -> [a] -> [a]")
  777. ("tan" . "Floating a => a -> a")
  778. ("tanh" . "Floating a => a -> a")
  779. ("toEnum" . "Enum a => Int -> a")
  780. ("toInteger" . "Integral a => a -> Integer")
  781. ("toRational" . "Real a => a -> Rational")
  782. ("truncate" . "(RealFrac a, Integral b) => a -> b")
  783. ("uncurry" . "(a -> b -> c) -> ((a, b) -> c)")
  784. ("undefined" . "a")
  785. ("unlines" . "[String] -> String")
  786. ("until" . "(a -> Bool) -> (a -> a) -> a -> a")
  787. ("unwords" . "[String] -> String")
  788. ("unzip" . "[(a,b)] -> ([a],[b])")
  789. ("unzip3" . "[(a,b,c)] -> ([a],[b],[c])")
  790. ("userError" . "String -> IOError")
  791. ("words" . "String -> [String]")
  792. ("writeFile" . "FilePath -> String -> IO ()")
  793. ("zip" . "[a] -> [b] -> [(a,b)]")
  794. ("zip3" . "[a] -> [b] -> [c] -> [(a,b,c)]")
  795. ("zipWith" . "(a->b->c) -> [a]->[b]->[c]")
  796. ("zipWith3" . "(a->b->c->d) -> [a]->[b]->[c]->[d]")
  797. ("||" . "Bool -> Bool -> Bool")
  798. ;; Ratio
  799. ("%" . "(Integral a) => a -> a -> Ratio a")
  800. ("approxRational" . "(RealFrac a) => a -> a -> Rational")
  801. ("denominator" . "(Integral a) => Ratio a -> a")
  802. ("numerator" . "(Integral a) => Ratio a -> a")
  803. ;; Complex
  804. ("cis" . "(RealFloat a) => a -> Complex a")
  805. ("conjugate" . "(RealFloat a) => Complex a -> Complex a")
  806. ("imagPart" . "(RealFloat a) => Complex a -> a")
  807. ("magnitude" . "(RealFloat a) => Complex a -> a")
  808. ("mkPolar" . "(RealFloat a) => a -> a -> Complex a")
  809. ("phase" . "(RealFloat a) => Complex a -> a")
  810. ("polar" . "(RealFloat a) => Complex a -> (a,a)")
  811. ("realPart" . "(RealFloat a) => Complex a -> a")
  812. ;; Numeric
  813. ("floatToDigits" . "(RealFloat a) => Integer -> a -> ([Int], Int)")
  814. ("fromRat" . "(RealFloat a) => Rational -> a")
  815. ("lexDigits" . "ReadS String")
  816. ("readDec" . "(Integral a) => ReadS a")
  817. ("readFloat" . "(RealFrac a) => ReadS a")
  818. ("readHex" . "(Integral a) => ReadS a")
  819. ("readInt" . "(Integral a) => a -> (Char -> Bool) -> (Char -> Int) -> ReadS a")
  820. ("readOct" . "(Integral a) => ReadS a")
  821. ("readSigned" . "(Real a) => ReadS a -> ReadS a")
  822. ("showEFloat" . "(RealFloat a) => Maybe Int -> a -> ShowS")
  823. ("showFFloat" . "(RealFloat a) => Maybe Int -> a -> ShowS")
  824. ("showFloat" . "(RealFloat a) => a -> ShowS")
  825. ("showGFloat" . "(RealFloat a) => Maybe Int -> a -> ShowS")
  826. ("showHex" . "Integral a => a -> ShowS")
  827. ("showInt" . "Integral a => a -> ShowS")
  828. ("showIntAtBase" . "Integral a => a -> (Int -> Char) -> a -> ShowS")
  829. ("showOct" . "Integral a => a -> ShowS")
  830. ("showSigned" . "(Real a) => (a -> ShowS) -> Int -> a -> ShowS")
  831. ;; Ix
  832. ("inRange" . "Ix a => (a,a) -> a -> Bool")
  833. ("index" . "Ix a => (a,a) -> a -> Int")
  834. ("range" . "Ix a => (a,a) -> [a]")
  835. ("rangeSize" . "Ix a => (a,a) -> Int")
  836. ;; Array
  837. ("!" . "(Ix a) => Array a b -> a -> b")
  838. ("//" . "(Ix a) => Array a b -> [(a,b)] -> Array a b")
  839. ("accum" . "(Ix a) => (b -> c -> b) -> Array a b -> [(a,c)]")
  840. ("accumArray" . "(Ix a) => (b -> c -> b) -> b -> (a,a) -> [(a,c)]")
  841. ("array" . "(Ix a) => (a,a) -> [(a,b)] -> Array a b")
  842. ("assocs" . "(Ix a) => Array a b -> [(a,b)]")
  843. ("bounds" . "(Ix a) => Array a b -> (a,a)")
  844. ("elems" . "(Ix a) => Array a b -> [b]")
  845. ("indices" . "(Ix a) => Array a b -> [a]")
  846. ("ixmap" . "(Ix a, Ix b) => (a,a) -> (a -> b) -> Array b c")
  847. ("listArray" . "(Ix a) => (a,a) -> [b] -> Array a b")
  848. ;; List
  849. ("\\\\" . "Eq a => [a] -> [a] -> [a]")
  850. ("delete" . "Eq a => a -> [a] -> [a]")
  851. ("deleteBy" . "(a -> a -> Bool) -> a -> [a] -> [a]")
  852. ("deleteFirstsBy" . "(a -> a -> Bool) -> [a] -> [a] -> [a]")
  853. ("elemIndex" . "Eq a => a -> [a] -> Maybe Int")
  854. ("elemIndices" . "Eq a => a -> [a] -> [Int]")
  855. ("find" . "(a -> Bool) -> [a] -> Maybe a")
  856. ("findIndex" . "(a -> Bool) -> [a] -> Maybe Int")
  857. ("findIndices" . "(a -> Bool) -> [a] -> [Int]")
  858. ("genericDrop" . "Integral a => a -> [b] -> [b]")
  859. ("genericIndex" . "Integral a => [b] -> a -> b")
  860. ("genericLength" . "Integral a => [b] -> a")
  861. ("genericReplicate" . "Integral a => a -> b -> [b]")
  862. ("genericSplitAt" . "Integral a => a -> [b] -> ([b],[b])")
  863. ("genericTake" . "Integral a => a -> [b] -> [b]")
  864. ("group" . "Eq a => [a] -> [[a]]")
  865. ("groupBy" . "(a -> a -> Bool) -> [a] -> [[a]]")
  866. ("inits" . "[a] -> [[a]]")
  867. ("insert" . "Ord a => a -> [a] -> [a]")
  868. ("insertBy" . "(a -> a -> Ordering) -> a -> [a] -> [a]")
  869. ("intersect" . "Eq a => [a] -> [a] -> [a]")
  870. ("intersectBy" . "(a -> a -> Bool) -> [a] -> [a] -> [a]")
  871. ("intersperse" . "a -> [a] -> [a]")
  872. ("isPrefixOf" . "Eq a => [a] -> [a] -> Bool")
  873. ("isSuffixOf" . "Eq a => [a] -> [a] -> Bool")
  874. ("mapAccumL" . "(a -> b -> (a, c)) -> a -> [b] -> (a, [c])")
  875. ("mapAccumR" . "(a -> b -> (a, c)) -> a -> [b] -> (a, [c])")
  876. ("maximumBy" . "(a -> a -> Ordering) -> [a] -> a")
  877. ("minimumBy" . "(a -> a -> Ordering) -> [a] -> a")
  878. ("nub" . "Eq a => [a] -> [a]")
  879. ("nubBy" . "(a -> a -> Bool) -> [a] -> [a]")
  880. ("partition" . "(a -> Bool) -> [a] -> ([a],[a])")
  881. ("sort" . "Ord a => [a] -> [a]")
  882. ("sortBy" . "(a -> a -> Ordering) -> [a] -> [a]")
  883. ("tails" . "[a] -> [[a]]")
  884. ("transpose" . "[[a]] -> [[a]]")
  885. ("unfoldr" . "(b -> Maybe (a,b)) -> b -> [a]")
  886. ("union" . "Eq a => [a] -> [a] -> [a]")
  887. ("unionBy" . "(a -> a -> Bool) -> [a] -> [a] -> [a]")
  888. ("unzip4" . "[(a,b,c,d)] -> ([a],[b],[c],[d])")
  889. ("unzip5" . "[(a,b,c,d,e)] -> ([a],[b],[c],[d],[e])")
  890. ("unzip6" . "[(a,b,c,d,e,f)] -> ([a],[b],[c],[d],[e],[f])")
  891. ("unzip7" . "[(a,b,c,d,e,f,g)] -> ([a],[b],[c],[d],[e],[f],[g])")
  892. ("zip4" . "[a] -> [b] -> [c] -> [d] -> [(a,b,c,d)]")
  893. ("zip5" . "[a] -> [b] -> [c] -> [d] -> [e] -> [(a,b,c,d,e)]")
  894. ("zip6" . "[a] -> [b] -> [c] -> [d] -> [e] -> [f]")
  895. ("zip7" . "[a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g]")
  896. ("zipWith4" . "(a->b->c->d->e) -> [a]->[b]->[c]->[d]->[e]")
  897. ("zipWith5" . "(a->b->c->d->e->f) ->")
  898. ("zipWith6" . "(a->b->c->d->e->f->g) -> [a]->[b]->[c]->[d]->[e]->[f]->[g]")
  899. ("zipWith7" . "(a->b->c->d->e->f->g->h) -> [a]->[b]->[c]->[d]->[e]->[f]->[g]->[h]")
  900. ;; Maybe
  901. ("catMaybes" . "[Maybe a] -> [a]")
  902. ("fromJust" . "Maybe a -> a")
  903. ("fromMaybe" . "a -> Maybe a -> a")
  904. ("isJust" . "Maybe a -> Bool")
  905. ("isNothing" . "Maybe a -> Bool")
  906. ("listToMaybe" . "[a] -> Maybe a")
  907. ("mapMaybe" . "(a -> Maybe b) -> [a] -> [b]")
  908. ("maybeToList" . "Maybe a -> [a]")
  909. ;; Char
  910. ("chr" . "Int -> Char")
  911. ("digitToInt" . "Char -> Int")
  912. ("intToDigit" . "Int -> Char")
  913. ("isAlpha" . "Char -> Bool")
  914. ("isAlphaNum" . "Char -> Bool")
  915. ("isAscii" . "Char -> Bool")
  916. ("isControl" . "Char -> Bool")
  917. ("isDigit" . "Char -> Bool")
  918. ("isHexDigit" . "Char -> Bool")
  919. ("isLatin1" . "Char -> Bool")
  920. ("isLower" . "Char -> Bool")
  921. ("isOctDigit" . "Char -> Bool")
  922. ("isPrint" . "Char -> Bool")
  923. ("isSpace" . "Char -> Bool")
  924. ("isUpper" . "Char -> Bool")
  925. ("lexLitChar" . "ReadS String")
  926. ("ord" . "Char -> Int")
  927. ("readLitChar" . "ReadS Char")
  928. ("showLitChar" . "Char -> ShowS")
  929. ("toLower" . "Char -> Char")
  930. ("toUpper" . "Char -> Char")
  931. ;; Monad
  932. ("ap" . "Monad m => m (a -> b) -> m a -> m b")
  933. ("filterM" . "Monad m => (a -> m Bool) -> [a] -> m [a]")
  934. ("foldM" . "Monad m => (a -> b -> m a) -> a -> [b] -> m a")
  935. ("guard" . "MonadPlus m => Bool -> m ()")
  936. ("join" . "Monad m => m (m a) -> m a")
  937. ("liftM" . "Monad m => (a -> b) -> (m a -> m b)")
  938. ("liftM2" . "Monad m => (a -> b -> c) -> (m a -> m b -> m c)")
  939. ("liftM3" . "Monad m => (a -> b -> c -> d) -> (m a -> m b -> m c -> m d)")
  940. ("liftM4" . "Monad m => (a -> b -> c -> d -> e) -> (m a -> m b -> m c -> m d -> m e)")
  941. ("liftM5" . "Monad m => (a -> b -> c -> d -> e -> f) -> (m a -> m b -> m c -> m d -> m e -> m f)")
  942. ("mapAndUnzipM" . "Monad m => (a -> m (b,c)) -> [a] -> m ([b], [c])")
  943. ("mplus" . "MonadPlus m => m a -> m a -> m a")
  944. ("msum" . "MonadPlus m => [m a] -> m a")
  945. ("mzero" . "MonadPlus m => m a")
  946. ("unless" . "Monad m => Bool -> m () -> m ()")
  947. ("when" . "Monad m => Bool -> m () -> m ()")
  948. ("zipWithM" . "Monad m => (a -> b -> m c) -> [a] -> [b] -> m [c]")
  949. ("zipWithM_" . "Monad m => (a -> b -> m c) -> [a] -> [b] -> m ()")
  950. ;; IO
  951. ("bracket" . "IO a -> (a -> IO b) -> (a -> IO c) -> IO c")
  952. ("bracket_" . "IO a -> (a -> IO b) -> IO c -> IO c")
  953. ("hClose" . "Handle -> IO ()")
  954. ("hFileSize" . "Handle -> IO Integer")
  955. ("hFlush" . "Handle -> IO ()")
  956. ("hGetBuffering" . "Handle -> IO BufferMode")
  957. ("hGetChar" . "Handle -> IO Char")
  958. ("hGetContents" . "Handle -> IO String")
  959. ("hGetLine" . "Handle -> IO String")
  960. ("hGetPosn" . "Handle -> IO HandlePosn")
  961. ("hIsClosed" . "Handle -> IO Bool")
  962. ("hIsEOF" . "Handle -> IO Bool")
  963. ("hIsOpen" . "Handle -> IO Bool")
  964. ("hIsReadable" . "Handle -> IO Bool")
  965. ("hIsSeekable" . "Handle -> IO Bool")
  966. ("hIsWritable" . "Handle -> IO Bool")
  967. ("hLookAhead" . "Handle -> IO Char")
  968. ("hPrint" . "Show a => Handle -> a -> IO ()")
  969. ("hPutChar" . "Handle -> Char -> IO ()")
  970. ("hPutStr" . "Handle -> String -> IO ()")
  971. ("hPutStrLn" . "Handle -> String -> IO ()")
  972. ("hReady" . "Handle -> IO Bool")
  973. ("hSeek" . "Handle -> SeekMode -> Integer -> IO ()")
  974. ("hSetBuffering" . "Handle -> BufferMode -> IO ()")
  975. ("hSetPosn" . "HandlePosn -> IO ()")
  976. ("hWaitForInput" . "Handle -> Int -> IO Bool")
  977. ("ioeGetErrorString" . "IOError -> String")
  978. ("ioeGetFileName" . "IOError -> Maybe FilePath")
  979. ("ioeGetHandle" . "IOError -> Maybe Handle")
  980. ("isAlreadyExistsError" . "IOError -> Bool")
  981. ("isAlreadyInUseError" . "IOError -> Bool")
  982. ("isDoesNotExistError" . "IOError -> Bool")
  983. ("isEOF" . "IO Bool")
  984. ("isEOFError" . "IOError -> Bool")
  985. ("isFullError" . "IOError -> Bool")
  986. ("isIllegalOperation" . "IOError -> Bool")
  987. ("isPermissionError" . "IOError -> Bool")
  988. ("isUserError" . "IOError -> Bool")
  989. ("openFile" . "FilePath -> IOMode -> IO Handle")
  990. ("stderr" . "Handle")
  991. ("stdin" . "Handle")
  992. ("stdout" . "Handle")
  993. ("try" . "IO a -> IO (Either IOError a)")
  994. ;; Directory
  995. ("createDirectory" . "FilePath -> IO ()")
  996. ("doesDirectoryExist" . "FilePath -> IO Bool")
  997. ("doesFileExist" . "FilePath -> IO Bool")
  998. ("executable" . "Permissions -> Bool")
  999. ("getCurrentDirectory" . "IO FilePath")
  1000. ("getDirectoryContents" . "FilePath -> IO [FilePath]")
  1001. ("getModificationTime" . "FilePath -> IO ClockTime")
  1002. ("getPermissions" . "FilePath -> IO Permissions")
  1003. ("readable" . "Permissions -> Bool")
  1004. ("removeDirectory" . "FilePath -> IO ()")
  1005. ("removeFile" . "FilePath -> IO ()")
  1006. ("renameDirectory" . "FilePath -> FilePath -> IO ()")
  1007. ("renameFile" . "FilePath -> FilePath -> IO ()")
  1008. ("searchable" . "Permissions -> Bool")
  1009. ("setCurrentDirectory" . "FilePath -> IO ()")
  1010. ("setPermissions" . "FilePath -> Permissions -> IO ()")
  1011. ("writable" . "Permissions -> Bool")
  1012. ;; System
  1013. ("exitFailure" . "IO a")
  1014. ("exitWith" . "ExitCode -> IO a")
  1015. ("getArgs" . "IO [String]")
  1016. ("getEnv" . "String -> IO String")
  1017. ("getProgName" . "IO String")
  1018. ("system" . "String -> IO ExitCode")
  1019. ;; Time
  1020. ("addToClockTime" . "TimeDiff -> ClockTime -> ClockTime")
  1021. ("calendarTimeToString" . "CalendarTime -> String")
  1022. ("ctDay" . "CalendarTime -> Int")
  1023. ("ctHour" . "CalendarTime -> Int")
  1024. ("ctIsDST" . "CalendarTime -> Bool")
  1025. ("ctMin" . "CalendarTime -> Int")
  1026. ("ctMonth" . "CalendarTime -> Month")
  1027. ("ctPicosec" . "CalendarTime -> Integer")
  1028. ("ctSec" . "CalendarTime -> Int")
  1029. ("ctTZ" . "CalendarTime -> Int")
  1030. ("ctTZName" . "CalendarTime -> String")
  1031. ("ctWDay" . "CalendarTime -> Day")
  1032. ("ctYDay" . "CalendarTime -> Int")
  1033. ("ctYear" . "CalendarTime -> Int")
  1034. ("diffClockTimes" . "ClockTime -> ClockTime -> TimeDiff")
  1035. ("formatCalendarTime" . "TimeLocale -> String -> CalendarTime -> String")
  1036. ("getClockTime" . "IO ClockTime")
  1037. ("tdDay" . "TimeDiff -> Int")
  1038. ("tdHour" . "TimeDiff -> Int")
  1039. ("tdMin" . "TimeDiff -> Int")
  1040. ("tdMonth" . "TimeDiff -> Int")
  1041. ("tdPicosec" . "TimeDiff -> Integer")
  1042. ("tdSec" . "TimeDiff -> Int")
  1043. ("tdYear" . "TimeDiff -> Int")
  1044. ("toCalendarTime" . "ClockTime -> IO CalendarTime")
  1045. ("toClockTime" . "CalendarTime -> ClockTime")
  1046. ("toUTCTime" . "ClockTime -> CalendarTime")
  1047. ;; Locale
  1048. ("amPm" . "TimeLocale -> (String, String)")
  1049. ("dateFmt" . "TimeLocale -> String")
  1050. ("dateTimeFmt" . "TimeLocale -> String")
  1051. ("defaultTimeLocale" . "TimeLocale")
  1052. ("months" . "TimeLocale -> [(String, String)]")
  1053. ("time12Fmt" . "TimeLocale -> String")
  1054. ("timeFmt" . "TimeLocale -> String")
  1055. ("wDays" . "TimeLocale -> [(String, String)]")
  1056. ;; CPUTime
  1057. ("cpuTimePrecision" . "Integer")
  1058. ("getCPUTime" . "IO Integer")
  1059. ;; Random
  1060. ("genRange" . "RandomGen g => g -> (Int, Int)")
  1061. ("getStdGen" . "IO StdGen")
  1062. ("getStdRandom" . "(StdGen -> (a, StdGen)) -> IO a")
  1063. ("mkStdGen" . "Int -> StdGen")
  1064. ("newStdGen" . "IO StdGen")
  1065. ("next" . "RandomGen g => g -> (Int, g)")
  1066. ("random" . "(Random a, RandomGen g) => g -> (a, g)")
  1067. ("randomIO" . "Random a => IO a")
  1068. ("randomR" . "(Random a, RandomGen g) => (a, a) -> g -> (a, g)")
  1069. ("randomRIO" . "Random a => (a,a) -> IO a")
  1070. ("randomRs" . "(Random a, RandomGen g) => (a, a) -> g -> [a]")
  1071. ("randoms" . "(Random a, RandomGen g) => g -> [a]")
  1072. ("setStdGen" . "StdGen -> IO ()")
  1073. ("split" . "RandomGen g => g -> (g, g)")
  1074. )
  1075. "Alist of prelude functions and their types.")
  1076. (defvar haskell-doc-strategy-ids
  1077. (list
  1078. '("par" . "Done -> Done -> Done ; [infixr 0]")
  1079. '("seq" . "Done -> Done -> Done ; [infixr 1]")
  1080. '("using" . "a -> Strategy a -> a ; [infixl 0]")
  1081. '("demanding" . "a -> Done -> a ; [infixl 0]")
  1082. '("sparking" . "a -> Done -> a ; [infixl 0]")
  1083. '(">||" . "Done -> Done -> Done ; [infixr 2]")
  1084. '(">|" . "Done -> Done -> Done ; [infixr 3]")
  1085. '("$||" . "(a -> b) -> Strategy a -> a -> b ; [infixl 6]")
  1086. '("$|" . "(a -> b) -> Strategy a -> a -> b ; [infixl 6]")
  1087. '(".|" . "(b -> c) -> Strategy b -> (a -> b) -> (a -> c) ; [infixl 9]")
  1088. '(".||" . "(b -> c) -> Strategy b -> (a -> b) -> (a -> c) ; [infixl 9]")
  1089. '("-|" . "(a -> b) -> Strategy b -> (b -> c) -> (a -> c) ; [infixl 9]")
  1090. '("-||" . "(a -> b) -> Strategy b -> (b -> c) -> (a -> c) ; [infixl 9]")
  1091. '("Done" . "type Done = ()")
  1092. '("Strategy" . "type Strategy a = a -> Done")
  1093. '("r0" . "Strategy a")
  1094. '("rwhnf" . "Eval a => Strategy a")
  1095. '("rnf" . "Strategy a")
  1096. '("NFData" . "class Eval a => NFData a where rnf :: Strategy a")
  1097. '("NFDataIntegral" ."class (NFData a, Integral a) => NFDataIntegral a")
  1098. '("NFDataOrd" . "class (NFData a, Ord a) => NFDataOrd a")
  1099. '("markStrat" . "Int -> Strategy a -> Strategy a")
  1100. '("seqPair" . "Strategy a -> Strategy b -> Strategy (a,b)")
  1101. '("parPair" . "Strategy a -> Strategy b -> Strategy (a,b)")
  1102. '("seqTriple" . "Strategy a -> Strategy b -> Strategy c -> Strategy (a,b,c)")
  1103. '("parTriple" . "Strategy a -> Strategy b -> Strategy c -> Strategy (a,b,c)")
  1104. '("parList" . "Strategy a -> Strategy [a]")
  1105. '("parListN" . "(Integral b) => b -> Strategy a -> Strategy [a]")
  1106. '("parListNth" . "Int -> Strategy a -> Strategy [a]")
  1107. '("parListChunk" . "Int -> Strategy a -> Strategy [a]")
  1108. '("parMap" . "Strategy b -> (a -> b) -> [a] -> [b]")
  1109. '("parFlatMap" . "Strategy [b] -> (a -> [b]) -> [a] -> [b]")
  1110. '("parZipWith" . "Strategy c -> (a -> b -> c) -> [a] -> [b] -> [c]")
  1111. '("seqList" . "Strategy a -> Strategy [a]")
  1112. '("seqListN" . "(Integral a) => a -> Strategy b -> Strategy [b]")
  1113. '("seqListNth" . "Int -> Strategy b -> Strategy [b]")
  1114. '("parBuffer" . "Int -> Strategy a -> [a] -> [a]")
  1115. '("seqArr" . "(Ix b) => Strategy a -> Strategy (Array b a)")
  1116. '("parArr" . "(Ix b) => Strategy a -> Strategy (Array b a)")
  1117. '("fstPairFstList" . "(NFData a) => Strategy [(a,b)]")
  1118. '("force" . "(NFData a) => a -> a ")
  1119. '("sforce" . "(NFData a) => a -> b -> b")
  1120. )
  1121. "Alist of strategy functions and their types as defined in Strategies.lhs.")
  1122. (defvar haskell-doc-user-defined-ids nil
  1123. "Alist of functions and strings defined by the user.")
  1124. (defsubst haskell-doc-is-of (fn types)
  1125. "Check whether FN is one of the functions in the alist TYPES and return the type."
  1126. (assoc fn types) )
  1127. ;; Put this minor mode on the global minor-mode-alist.
  1128. (or (assq 'haskell-doc-mode (default-value 'minor-mode-alist))
  1129. (setq-default minor-mode-alist
  1130. (append (default-value 'minor-mode-alist)
  1131. '((haskell-doc-mode haskell-doc-minor-mode-string)))))
  1132. (defvar haskell-doc-keymap
  1133. (let ((map (make-sparse-keymap)))
  1134. (define-key map [visit]
  1135. '("Visit FTP home site" . haskell-doc-visit-home))
  1136. (define-key map [submit]
  1137. '("Submit bug report" . haskell-doc-submit-bug-report))
  1138. (define-key map [dummy] '("---" . nil))
  1139. (define-key map [make-index]
  1140. '("Make global fct index" . haskell-doc-make-global-fct-index))
  1141. (define-key map [global-types-on]
  1142. '("Toggle display of global types" . haskell-doc-show-global-types))
  1143. (define-key map [strategy-on]
  1144. '("Toggle display of strategy ids" . haskell-doc-show-strategy))
  1145. (define-key map [user-defined-on]
  1146. '("Toggle display of user defined ids" . haskell-doc-show-user-defined))
  1147. (define-key map [prelude-on]
  1148. '("Toggle display of prelude functions" . haskell-doc-show-prelude))
  1149. (define-key map [reserved-ids-on]
  1150. '("Toggle display of reserved ids" . haskell-doc-show-reserved))
  1151. (define-key map [haskell-doc-on]
  1152. '("Toggle haskell-doc mode" . haskell-doc-mode))
  1153. map))
  1154. (defun haskell-doc-install-keymap ()
  1155. "Install a menu for `haskell-doc-mode' as a submenu of \"Hugs\"."
  1156. (interactive)
  1157. ;; Add the menu to the hugs menu as last entry.
  1158. (let ((hugsmap (lookup-key (current-local-map) [menu-bar Hugs])))
  1159. (if (not (or (featurep 'xemacs) ; XEmacs has problems here
  1160. (not (keymapp hugsmap))
  1161. (lookup-key hugsmap [haskell-doc])))
  1162. (if (functionp 'define-key-after)
  1163. (define-key-after hugsmap [haskell-doc]
  1164. (cons "Haskell-doc" haskell-doc-keymap)
  1165. [Haskell-doc mode]))))
  1166. ;; Add shortcuts for these commands.
  1167. (local-set-key "\C-c\e/" 'haskell-doc-check-active)
  1168. ;; Conflicts with the binding of haskell-insert-otherwise.
  1169. ;; (local-set-key "\C-c\C-o" 'haskell-doc-mode)
  1170. (local-set-key [(control shift meta mouse-3)]
  1171. 'haskell-doc-ask-mouse-for-type))
  1172. (defvar haskell-doc-timer nil)
  1173. (defvar haskell-doc-buffers nil)
  1174. ;;;###autoload
  1175. (defun haskell-doc-mode (&optional arg)
  1176. "Enter `haskell-doc-mode' for showing fct types in the echo area.
  1177. See variable docstring."
  1178. (interactive (list (or current-prefix-arg 'toggle)))
  1179. (setq haskell-doc-mode
  1180. (cond
  1181. ((eq arg 'toggle) (not haskell-doc-mode))
  1182. (arg (> (prefix-numeric-value arg) 0))
  1183. (t)))
  1184. ;; First, unconditionally turn the mode OFF.
  1185. (setq haskell-doc-buffers (delq (current-buffer) haskell-doc-buffers))
  1186. ;; Refresh the buffers list.
  1187. (dolist (buf haskell-doc-buffers)
  1188. (unless (and (buffer-live-p buf)
  1189. (with-current-buffer buf haskell-doc-mode))
  1190. (setq haskell-doc-buffers (delq buf haskell-doc-buffers))))
  1191. ;; Turn off the idle timer (or idle post-command-hook).
  1192. (when (and haskell-doc-timer (null haskell-doc-buffers))
  1193. (cancel-timer haskell-doc-timer)
  1194. (setq haskell-doc-timer nil))
  1195. (remove-hook 'post-command-hook
  1196. 'haskell-doc-mode-print-current-symbol-info 'local)
  1197. (when haskell-doc-mode
  1198. ;; Turning the mode ON.
  1199. (push (current-buffer) haskell-doc-buffers)
  1200. (if (fboundp 'run-with-idle-timer)
  1201. (unless haskell-doc-timer
  1202. (setq haskell-doc-timer
  1203. (run-with-idle-timer
  1204. haskell-doc-idle-delay t
  1205. 'haskell-doc-mode-print-current-symbol-info)))
  1206. (add-hook 'post-command-hook
  1207. 'haskell-doc-mode-print-current-symbol-info nil 'local))
  1208. (and haskell-doc-show-global-types
  1209. (haskell-doc-make-global-fct-index)) ; build type index for global fcts
  1210. (haskell-doc-install-keymap)
  1211. (run-hooks 'haskell-doc-mode-hook))
  1212. (and (called-interactively-p 'any)
  1213. (message "haskell-doc-mode is %s"
  1214. (if haskell-doc-mode "enabled" "disabled")))
  1215. haskell-doc-mode)
  1216. (defmacro haskell-doc-toggle-var (id prefix)
  1217. ;; toggle variable or set it based on prefix value
  1218. `(setq ,id
  1219. (if ,prefix
  1220. (>= (prefix-numeric-value ,prefix) 0)
  1221. (not ,id))) )
  1222. (defun haskell-doc-show-global-types (&optional prefix)
  1223. "Turn on global types information in `haskell-doc-mode'."
  1224. (interactive "P")
  1225. (haskell-doc-toggle-var haskell-doc-show-global-types prefix)
  1226. (if haskell-doc-show-global-types
  1227. (haskell-doc-make-global-fct-index)))
  1228. (defun haskell-doc-show-reserved (&optional prefix)
  1229. "Toggle the automatic display of a doc string for reserved ids."
  1230. (interactive "P")
  1231. (haskell-doc-toggle-var haskell-doc-show-reserved prefix))
  1232. (defun haskell-doc-show-prelude (&optional prefix)
  1233. "Toggle the automatic display of a doc string for reserved ids."
  1234. (interactive "P")
  1235. (haskell-doc-toggle-var haskell-doc-show-prelude prefix))
  1236. (defun haskell-doc-show-strategy (&optional prefix)
  1237. "Toggle the automatic display of a doc string for strategy ids."
  1238. (interactive "P")
  1239. (haskell-doc-toggle-var haskell-doc-show-strategy prefix))
  1240. (defun haskell-doc-show-user-defined (&optional prefix)
  1241. "Toggle the automatic display of a doc string for user defined ids."
  1242. (interactive "P")
  1243. (haskell-doc-toggle-var haskell-doc-show-user-defined prefix))
  1244. ;;;###autoload
  1245. (defalias 'turn-on-haskell-doc-mode 'haskell-doc-mode)
  1246. (make-obsolete 'turn-on-haskell-doc-mode
  1247. 'haskell-doc-mode
  1248. "2015-07-23")
  1249. ;;;###autoload
  1250. (defalias 'turn-on-haskell-doc 'haskell-doc-mode)
  1251. (make-obsolete 'turn-on-haskell-doc
  1252. 'haskell-doc-mode
  1253. "2015-07-23")
  1254. (defalias 'turn-off-haskell-doc-mode 'turn-off-haskell-doc)
  1255. (defun turn-off-haskell-doc ()
  1256. "Unequivocally turn off `haskell-doc-mode' (which see)."
  1257. (haskell-doc-mode 0))
  1258. (defun haskell-doc-check-active ()
  1259. "Check whether the print function is hooked in.
  1260. Should be the same as the value of `haskell-doc-mode' but alas currently it
  1261. is not."
  1262. (interactive)
  1263. (message "%s"
  1264. (if (or (and haskell-doc-mode haskell-doc-timer)
  1265. (memq 'haskell-doc-mode-print-current-symbol-info
  1266. post-command-hook))
  1267. "haskell-doc is ACTIVE"
  1268. (substitute-command-keys
  1269. "haskell-doc is not ACTIVE \(Use \\[haskell-doc-mode] to turn it on\)"))))
  1270. ;; This is the function hooked into the elisp command engine
  1271. (defun haskell-doc-mode-print-current-symbol-info ()
  1272. "Print the type of the symbol under the cursor.
  1273. This function is run by an idle timer to print the type
  1274. automatically if `haskell-doc-mode' is turned on."
  1275. (and haskell-doc-mode
  1276. (haskell-doc-in-code-p)
  1277. (not haskell-mode-interactive-prompt-state)
  1278. (not (eobp))
  1279. (not executing-kbd-macro)
  1280. ;; Having this mode operate in the minibuffer makes it impossible to
  1281. ;; see what you're doing.
  1282. (not (eq (selected-window) (minibuffer-window)))
  1283. ;; not in string or comment
  1284. ;; take a nap, if run straight from post-command-hook.
  1285. (if (fboundp 'run-with-idle-timer) t
  1286. (sit-for haskell-doc-idle-delay))
  1287. ;; good morning! read the word under the cursor for breakfast
  1288. (haskell-doc-show-type)))
  1289. ;; ;; ToDo: find surrounding fct
  1290. ;; (cond ((eq current-symbol current-fnsym)
  1291. ;; (haskell-doc-show-type current-fnsym))
  1292. ;; (t
  1293. ;; (or nil ; (haskell-doc-print-var-docstring current-symbol)
  1294. ;; (haskell-doc-show-type current-fnsym)))))))
  1295. ;;;###autoload
  1296. (defun haskell-doc-current-info ()
  1297. "Return the info about symbol at point.
  1298. Meant for `eldoc-documentation-function'."
  1299. ;; There are a number of possible documentation functions.
  1300. ;; Some of them are asynchronous.
  1301. (when (haskell-doc-in-code-p)
  1302. (let ((msg (or
  1303. (haskell-doc-current-info--interaction)
  1304. (haskell-doc-sym-doc (haskell-ident-at-point)))))
  1305. (unless (symbolp msg) msg))))
  1306. (defun haskell-doc-ask-mouse-for-type (event)
  1307. "Read the identifier under the mouse and echo its type.
  1308. This uses the same underlying function `haskell-doc-show-type' as the hooked
  1309. function. Only the user interface is different."
  1310. (interactive "e")
  1311. (save-excursion
  1312. (select-window (posn-window (event-end event)))
  1313. (goto-char (posn-point (event-end event)))
  1314. (haskell-doc-show-type)))
  1315. (defun haskell-doc-in-code-p ()
  1316. "A predicate indicating suitable case to show docs."
  1317. (not (or (and (eq haskell-literate 'bird)
  1318. ;; Copied from haskell-indent-bolp.
  1319. (<= (current-column) 2)
  1320. (eq (char-after (line-beginning-position)) ?\>))
  1321. (nth 8 (syntax-ppss)))))
  1322. ;;;###autoload
  1323. (defun haskell-doc-show-type (&optional sym)
  1324. "Show the type of the function near point or given symbol SYM.
  1325. For the function under point, show the type in the echo area.
  1326. This information is extracted from the `haskell-doc-prelude-types' alist
  1327. of prelude functions and their types, or from the local functions in the
  1328. current buffer."
  1329. (interactive)
  1330. (unless sym (setq sym (haskell-ident-at-point)))
  1331. ;; if printed before do not print it again
  1332. (unless (string= sym (car haskell-doc-last-data))
  1333. (let ((doc (or (haskell-doc-current-info--interaction t)
  1334. (haskell-doc-sym-doc sym))))
  1335. (when (and doc (haskell-doc-in-code-p))
  1336. ;; In Emacs 19.29 and later, and XEmacs 19.13 and later, all
  1337. ;; messages are recorded in a log. Do not put haskell-doc messages
  1338. ;; in that log since they are legion.
  1339. (let ((message-log-max nil))
  1340. (message "%s" doc))))))
  1341. (defvar haskell-doc-current-info--interaction-last nil
  1342. "Async message stack.
  1343. If non-nil, a previous eldoc message from an async call, that
  1344. hasn't been displayed yet.")
  1345. (defun haskell-doc-current-info--interaction (&optional sync)
  1346. "Asynchronous call to `haskell-process-get-type'.
  1347. Suitable for use in the eldoc function `haskell-doc-current-info'.
  1348. If SYNC is non-nil, the call will be synchronous instead, and
  1349. instead of calling `eldoc-print-current-symbol-info', the result
  1350. will be returned directly."
  1351. ;; Return nil if nothing is available, or 'async if something might
  1352. ;; be available, but asynchronously later. This will call
  1353. ;; `eldoc-print-current-symbol-info' later.
  1354. (when (haskell-doc-in-code-p)
  1355. ;; do nothing when inside string or comment
  1356. (let (sym prev-message)
  1357. (cond
  1358. ((setq prev-message haskell-doc-current-info--interaction-last)
  1359. (setq haskell-doc-current-info--interaction-last nil)
  1360. (cdr prev-message))
  1361. ((setq sym
  1362. (if (use-region-p)
  1363. (buffer-substring-no-properties
  1364. (region-beginning) (region-end))
  1365. (haskell-ident-at-point)))
  1366. (if sync
  1367. (haskell-process-get-type sym #'identity t)
  1368. (haskell-process-get-type
  1369. sym (lambda (response)
  1370. (setq haskell-doc-current-info--interaction-last
  1371. (cons 'async response))
  1372. (eldoc-print-current-symbol-info)))))))))
  1373. (defun haskell-process-get-type (expr-string &optional callback sync)
  1374. "Asynchronously get the type of a given string.
  1375. EXPR-STRING should be an expression passed to :type in ghci.
  1376. CALLBACK will be called with a formatted type string.
  1377. If SYNC is non-nil, make the call synchronously instead."
  1378. (unless callback (setq callback (lambda (response) (message "%s" response))))
  1379. (let ((process (and (haskell-session-maybe)
  1380. (haskell-session-process (haskell-session-maybe))))
  1381. ;; Avoid passing bad strings to ghci
  1382. (expr-okay
  1383. (and (not (string-match-p "\\`[[:space:]]*\\'" expr-string))
  1384. (not (string-match-p "\n" expr-string))))
  1385. (ghci-command (concat ":type " expr-string))
  1386. (process-response
  1387. (lambda (response)
  1388. ;; Responses with empty first line are likely errors
  1389. (if (string-match-p (rx string-start line-end) response)
  1390. (setq response nil)
  1391. ;; Remove a newline at the end
  1392. (setq response (replace-regexp-in-string "\n\\'" "" response))
  1393. ;; Propertize for eldoc
  1394. (save-match-data
  1395. (when (string-match " :: " response)
  1396. ;; Highlight type
  1397. (let ((name (substring response 0 (match-end 0)))
  1398. (type (propertize
  1399. (substring response (match-end 0))
  1400. 'face 'eldoc-highlight-function-argument)))
  1401. (setq response (concat name type)))))
  1402. (when haskell-doc-prettify-types
  1403. (dolist (re '(("::" . "") ("=>" . "") ("->" . "")))
  1404. (setq response
  1405. (replace-regexp-in-string (car re) (cdr re) response))))
  1406. response))))
  1407. (when (and process expr-okay)
  1408. (if sync
  1409. (let ((response (haskell-process-queue-sync-request process ghci-command)))
  1410. (funcall callback (funcall process-response response)))
  1411. (haskell-process-queue-command
  1412. process
  1413. (make-haskell-command
  1414. :go (lambda (_) (haskell-process-send-string process ghci-command))
  1415. :complete
  1416. (lambda (_ response)
  1417. (funcall callback (funcall process-response response)))))
  1418. 'async))))
  1419. (defun haskell-doc-sym-doc (sym)
  1420. "Show the type of given symbol SYM.
  1421. For the function under point, show the type in the echo area.
  1422. This information is extracted from the `haskell-doc-prelude-types' alist
  1423. of prelude functions and their types, or from the local functions in the
  1424. current buffer.
  1425. If `haskell-doc-use-inf-haskell' is non-nil, this function will consult
  1426. the inferior Haskell process for type/kind information, rather than using
  1427. the haskell-doc database."
  1428. (if haskell-doc-use-inf-haskell
  1429. (unless (or (null sym) (string= "" sym))
  1430. (let* ((message-log-max nil)
  1431. (result (ignore-errors
  1432. (unwind-protect
  1433. (inferior-haskell-type sym)
  1434. (message "")))))
  1435. (if (and result (string-match " :: " result))
  1436. result
  1437. (setq result (unwind-protect
  1438. (inferior-haskell-kind sym)
  1439. (message "")))
  1440. (and result (string-match " :: " result) result))))
  1441. (let ((i-am-prelude nil)
  1442. (i-am-fct nil)
  1443. (type nil)
  1444. (is-reserved (haskell-doc-is-of sym haskell-doc-reserved-ids))
  1445. (is-prelude (haskell-doc-is-of sym haskell-doc-prelude-types))
  1446. (is-strategy (haskell-doc-is-of sym haskell-doc-strategy-ids))
  1447. (is-user-defined (haskell-doc-is-of sym haskell-doc-user-defined-ids)))
  1448. (cond
  1449. ;; if reserved id (i.e. Haskell keyword
  1450. ((and haskell-doc-show-reserved
  1451. is-reserved)
  1452. (setq type (cdr is-reserved))
  1453. (setcdr haskell-doc-last-data type))
  1454. ;; if built-in function get type from docstring
  1455. ((and (not (null haskell-doc-show-prelude))
  1456. is-prelude)
  1457. (setq type (cdr is-prelude)) ; (cdr (assoc sym haskell-doc-prelude-types)))
  1458. (if (= 2 (length type)) ; horrible hack to remove bad formatting
  1459. (setq type (car (cdr type))))
  1460. (setq i-am-prelude t)
  1461. (setq i-am-fct t)
  1462. (setcdr haskell-doc-last-data type))
  1463. ((and haskell-doc-show-strategy
  1464. is-strategy)
  1465. (setq i-am-fct t)
  1466. (setq type (cdr is-strategy))
  1467. (setcdr haskell-doc-last-data type))
  1468. ((and haskell-doc-show-user-defined
  1469. is-user-defined)
  1470. ;; (setq i-am-fct t)
  1471. (setq type (cdr is-user-defined))
  1472. (setcdr haskell-doc-last-data type))
  1473. (t
  1474. (let ( (x (haskell-doc-get-and-format-fct-type sym)) )
  1475. (if (null x)
  1476. (setcdr haskell-doc-last-data nil) ; if not found reset last data
  1477. (setq type (car x))
  1478. (setq i-am-fct (string= "Variables" (cdr x)))
  1479. (if (and haskell-doc-show-global-types (null type))
  1480. (setq type (haskell-doc-get-global-fct-type sym)))
  1481. (setcdr haskell-doc-last-data type)))) )
  1482. ;; ToDo: encode i-am-fct info into alist of types
  1483. (and type
  1484. ;; drop `::' if it's not a fct
  1485. (let ( (str (cond ((and i-am-fct (not haskell-doc-chop-off-fctname))
  1486. (format "%s :: %s" sym type))
  1487. (t
  1488. (format "%s" type)))) )
  1489. (if i-am-prelude
  1490. (add-text-properties 0 (length str) '(face bold) str))
  1491. str)))))
  1492. ;; ToDo: define your own notion of `near' to find surrounding fct
  1493. ;;(defun haskell-doc-fnsym-in-current-sexp ()
  1494. ;; (let* ((p (point))
  1495. ;; (sym (progn
  1496. ;; (forward-word -1)
  1497. ;; (while (and (forward-word -1) ; (haskell-doc-forward-sexp-safe -1)
  1498. ;; (> (point) (point-min))))
  1499. ;; (cond ((or (= (point) (point-min))
  1500. ;; (memq (or (char-after (point)) 0)
  1501. ;; '(?\( ?\"))
  1502. ;; ;; If we hit a quotation mark before a paren, we
  1503. ;; ;; are inside a specific string, not a list of
  1504. ;; ;; symbols.
  1505. ;; (eq (or (char-after (1- (point))) 0) ?\"))
  1506. ;; nil)
  1507. ;; (t (condition-case nil
  1508. ;; (read (current-buffer))
  1509. ;; (error nil)))))))
  1510. ;; (goto-char p)
  1511. ;; (if sym
  1512. ;; (format "%s" sym)
  1513. ;; sym)))
  1514. ;; (and (symbolp sym)
  1515. ;; sym)))
  1516. ;; ToDo: handle open brackets to decide if it's a wrapped type
  1517. (defun haskell-doc-grab-line (fct-and-pos)
  1518. "Get the type of an \(FCT POSITION\) pair from the current buffer."
  1519. ;; (if (null fct-and-pos)
  1520. ;; "" ; fn is not a local fct
  1521. (let ( (str ""))
  1522. (goto-char (cdr fct-and-pos))
  1523. (beginning-of-line)
  1524. ;; search for start of type (phsp give better bound?)
  1525. (if (null (search-forward "::" (+ (point) haskell-doc-search-distance) t))
  1526. ""
  1527. (setq str (haskell-doc-grab)) ; leaves point at end of line
  1528. (while (haskell-doc-wrapped-type-p) ; while in a multi-line type expr
  1529. (forward-line 1)
  1530. (beginning-of-line)
  1531. (skip-chars-forward " \t")
  1532. (setq str (concat str (haskell-doc-grab))))
  1533. (haskell-doc-string-nub-ws ; squeeze string
  1534. (if haskell-doc-chop-off-context ; no context
  1535. (haskell-doc-chop-off-context str)
  1536. str)))))
  1537. ;; (concat (car fct-and-pos) "::" (haskell-doc-string-nub-ws str))))
  1538. (defun haskell-doc-wrapped-type-p ()
  1539. "Check whether the type under the cursor is wrapped over several lines.
  1540. The cursor must be at the end of a line, which contains the type.
  1541. Currently, only the following is checked:
  1542. If this line ends with a `->' or the next starts with an `->' it is a
  1543. multi-line type \(same for `=>'\).
  1544. `--' comments are ignored.
  1545. ToDo: Check for matching parenthesis!."
  1546. (save-excursion
  1547. (let ( (here (point))
  1548. (lim (progn (beginning-of-line) (point)))
  1549. ;; (foo "")
  1550. (res nil)
  1551. )
  1552. (goto-char here)
  1553. (search-backward "--" lim t) ; skip over `--' comment
  1554. (skip-chars-backward " \t")
  1555. (if (bolp) ; skip empty lines
  1556. (progn
  1557. (forward-line 1)
  1558. (end-of-line)
  1559. (setq res (haskell-doc-wrapped-type-p)))
  1560. (forward-char -1)
  1561. ;; (setq foo (concat foo (char-to-string (preceding-char)) (char-to-string (following-char))))
  1562. (if (or (and (or (char-equal (preceding-char) ?-) (char-equal (preceding-char) ?=))
  1563. (char-equal (following-char) ?>)) ; (or -!> =!>
  1564. (char-equal (following-char) ?,)) ; !,)
  1565. (setq res t)
  1566. (forward-line)
  1567. (let ((here (point)))
  1568. (goto-char here)
  1569. (skip-chars-forward " \t")
  1570. (if (looking-at "--") ; it is a comment line
  1571. (progn
  1572. (forward-line 1)
  1573. (end-of-line)
  1574. (setq res (haskell-doc-wrapped-type-p)))
  1575. (forward-char 1)
  1576. ;; (setq foo (concat foo (char-to-string (preceding-char)) (char-to-string (following-char))))
  1577. ;; (message "|%s|" foo)
  1578. (if (and (or (char-equal (preceding-char) ?-) (char-equal (preceding-char) ?=))
  1579. (char-equal (following-char) ?>)) ; -!> or =!>
  1580. (setq res t))))))
  1581. res)))
  1582. (defun haskell-doc-grab ()
  1583. "Return the text from point to the end of the line, chopping off comments.
  1584. Leaves point at end of line."
  1585. (let ((str (buffer-substring-no-properties
  1586. (point) (progn (end-of-line) (point)))))
  1587. (if (string-match "--" str)
  1588. (substring str 0 (match-beginning 0))
  1589. str)))
  1590. (defun haskell-doc-string-nub-ws (str)
  1591. "Replace all sequences of whitespace in STR by just one space.
  1592. ToDo: Also eliminate leading and trailing whitespace."
  1593. (let ((i -1))
  1594. (while (setq i (string-match " [ \t\n]+\\|[\t\n]+" str (1+ i)))
  1595. (setq str (replace-match " " t t str)))
  1596. str))
  1597. (defun haskell-doc-chop-off-context (str)
  1598. "Eliminate the context in a type represented by the string STR."
  1599. (let ((i (string-match "=>" str)) )
  1600. (if (null i)
  1601. str
  1602. (substring str (+ i 2)))))
  1603. (defun haskell-doc-get-imenu-info (obj kind)
  1604. "Return a string describing OBJ of KIND \(Variables, Types, Data\)."
  1605. (cond
  1606. ((eq major-mode 'haskell-mode)
  1607. (let* ((imenu-info-alist (cdr (assoc kind imenu--index-alist)))
  1608. ;; (names (mapcar 'car imenu-info-alist))
  1609. (x (assoc obj imenu-info-alist)))
  1610. (when x (haskell-doc-grab-line x))))
  1611. (t ;; (error "Cannot get local functions in %s mode, sorry" major-mode)))
  1612. nil)))
  1613. ;; ToDo:
  1614. ;; - modular way of defining a mapping of module name to file
  1615. ;; - use a path to search for file (not just current directory)
  1616. (defun haskell-doc-imported-list ()
  1617. "Return a list of the imported modules in current buffer."
  1618. (interactive "fName of outer `include' file: ") ; (buffer-file-name))
  1619. ;; Don't add current buffer to the imported file list if it is not (yet?)
  1620. ;; visiting a file since it leads to errors further down.
  1621. (let ((imported-file-list (and buffer-file-name (list buffer-file-name))))
  1622. (widen)
  1623. (goto-char (point-min))
  1624. (while (re-search-forward "^\\s-*import\\s-+\\([^ \t\n]+\\)" nil t)
  1625. (let ((basename (match-string 1)))
  1626. (dolist (ext '(".hs" ".lhs"))
  1627. (let ((file (concat basename ext)))
  1628. (if (file-exists-p file)
  1629. (push file imported-file-list))))))
  1630. (nreverse imported-file-list)
  1631. ;;(message imported-file-list)
  1632. ))
  1633. ;; ToDo: generalise this to "Types" etc (not just "Variables")
  1634. (defun haskell-doc-rescan-files (filelist)
  1635. "Do an `imenu' rescan on every file in FILELIST and return the fct-list.
  1636. This function switches to and potentially loads many buffers."
  1637. (save-current-buffer
  1638. (mapcar (lambda (f)
  1639. (set-buffer (find-file-noselect f))
  1640. (imenu--make-index-alist t)
  1641. (cons f
  1642. (mapcar (lambda (x)
  1643. `(,(car x) . ,(haskell-doc-grab-line x)))
  1644. (cdr (assoc "Variables" imenu--index-alist)))))
  1645. filelist)))
  1646. (defun haskell-doc-make-global-fct-index ()
  1647. "Scan imported files for types of global fcts and update `haskell-doc-index'."
  1648. (interactive)
  1649. (setq haskell-doc-index
  1650. (haskell-doc-rescan-files (haskell-doc-imported-list))))
  1651. ;; ToDo: use a separate munge-type function to format type concisely
  1652. (defun haskell-doc-get-global-fct-type (&optional sym)
  1653. "Get type for function symbol SYM by examining `haskell-doc-index'."
  1654. (interactive) ; "fName of outer `include' file: \nsFct:")
  1655. (save-excursion
  1656. ;; (switch-to-buffer "*scratch*")
  1657. ;; (goto-char (point-max))
  1658. ;; ;; Produces a list of fct-type alists
  1659. ;; (if (null sym)
  1660. ;; (setq sym (progn (forward-word -1) (read (current-buffer)))))
  1661. (or sym
  1662. (current-word))
  1663. (let* ( (fn sym) ; (format "%s" sym))
  1664. (fal haskell-doc-index)
  1665. (res "") )
  1666. (while (not (null fal))
  1667. (let* ( (l (car fal))
  1668. (f (car l))
  1669. (x (assoc fn (cdr l))) )
  1670. (if (not (null x))
  1671. (let* ( (ty (cdr x)) ; the type as string
  1672. (idx (string-match "::" ty))
  1673. (str (if (null idx)
  1674. ty
  1675. (substring ty (+ idx 2)))) )
  1676. (setq res (format "[%s] %s" f str))))
  1677. (setq fal (cdr fal))))
  1678. res))) ; (message res)) )
  1679. (defun haskell-doc-get-and-format-fct-type (fn)
  1680. "Get the type and kind of FN by checking local and global functions."
  1681. (save-excursion
  1682. (save-match-data
  1683. (let ((docstring "")
  1684. (doc nil)
  1685. )
  1686. ;; is it a local function?
  1687. (setq docstring (haskell-doc-get-imenu-info fn "Variables"))
  1688. (if (not (null docstring))
  1689. ;; (string-match (format "^%s\\s-+::\\s-+\\(.*\\)$" fn) docstring))
  1690. (setq doc `(,docstring . "Variables"))) ; `(,(match-string 1 docstring) . "Variables") ))
  1691. ;; is it a type declaration?
  1692. (setq docstring (haskell-doc-get-imenu-info fn "Types"))
  1693. (if (not (null docstring))
  1694. ;; (string-match (format "^\\s-*type\\s-+%s.*$" fn) docstring))
  1695. (setq doc `(,docstring . "Types"))) ; `(,(match-string 0 docstring) . "Types")) )
  1696. (if (not (null docstring))
  1697. ;; (string-match (format "^\\s-*data.*%s.*$" fn) docstring))
  1698. (setq doc `(,docstring . "Data"))) ; (setq doc `(,(match-string 0 docstring) . "Data")) )
  1699. ;; return the result
  1700. doc ))))
  1701. (defun inferior-haskell-kind (sym)
  1702. "Find the kind of SYM with `:kind' ghci feature."
  1703. (inferior-haskell-get-result (format ":kind %s" sym)))
  1704. (defun inferior-haskell-type (sym)
  1705. "Find the type of SYM with `:type' ghci feature."
  1706. (inferior-haskell-get-result (format ":type (%s)" sym)))
  1707. (provide 'haskell-doc)
  1708. ;;; haskell-doc.el ends here