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.

216 regels
7.3 KiB

4 jaren geleden
  1. (require 'slime)
  2. (require 'eldoc)
  3. (require 'cl-lib)
  4. (require 'slime-parse)
  5. (define-slime-contrib slime-autodoc
  6. "Show fancy arglist in echo area."
  7. (:license "GPL")
  8. (:authors "Luke Gorrie <luke@bluetail.com>"
  9. "Lawrence Mitchell <wence@gmx.li>"
  10. "Matthias Koeppe <mkoeppe@mail.math.uni-magdeburg.de>"
  11. "Tobias C. Rittweiler <tcr@freebits.de>")
  12. (:slime-dependencies slime-parse)
  13. (:swank-dependencies swank-arglists)
  14. (:on-load (slime-autodoc--enable))
  15. (:on-unload (slime-autodoc--disable)))
  16. (defcustom slime-autodoc-accuracy-depth 10
  17. "Number of paren levels that autodoc takes into account for
  18. context-sensitive arglist display (local functions. etc)"
  19. :type 'integer
  20. :group 'slime-ui)
  21. ;;;###autoload
  22. (defcustom slime-autodoc-mode-string (purecopy " adoc")
  23. "String to display in mode line when Autodoc Mode is enabled; nil for none."
  24. :type '(choice string (const :tag "None" nil))
  25. :group 'slime-ui)
  26. (defun slime-arglist (name)
  27. "Show the argument list for NAME."
  28. (interactive (list (slime-read-symbol-name "Arglist of: " t)))
  29. (let ((arglist (slime-retrieve-arglist name)))
  30. (if (eq arglist :not-available)
  31. (error "Arglist not available")
  32. (message "%s" (slime-autodoc--fontify arglist)))))
  33. ;; used also in slime-c-p-c.el.
  34. (defun slime-retrieve-arglist (name)
  35. (let ((name (cl-etypecase name
  36. (string name)
  37. (symbol (symbol-name name)))))
  38. (car (slime-eval `(swank:autodoc '(,name ,slime-cursor-marker))))))
  39. (defun slime-autodoc-manually ()
  40. "Like autodoc informtion forcing multiline display."
  41. (interactive)
  42. (let ((doc (slime-autodoc t)))
  43. (cond (doc (eldoc-message doc))
  44. (t (eldoc-message nil)))))
  45. ;; Must call eldoc-add-command otherwise (eldoc-display-message-p)
  46. ;; returns nil and eldoc clears the echo area instead.
  47. (eldoc-add-command 'slime-autodoc-manually)
  48. (defun slime-autodoc-space (n)
  49. "Like `slime-space' but nicer."
  50. (interactive "p")
  51. (self-insert-command n)
  52. (let ((doc (slime-autodoc)))
  53. (when doc
  54. (eldoc-message doc))))
  55. (eldoc-add-command 'slime-autodoc-space)
  56. ;;;; Autodoc cache
  57. (defvar slime-autodoc--cache-last-context nil)
  58. (defvar slime-autodoc--cache-last-autodoc nil)
  59. (defun slime-autodoc--cache-get (context)
  60. "Return the cached autodoc documentation for `context', or nil."
  61. (and (equal context slime-autodoc--cache-last-context)
  62. slime-autodoc--cache-last-autodoc))
  63. (defun slime-autodoc--cache-put (context autodoc)
  64. "Update the autodoc cache for CONTEXT with AUTODOC."
  65. (setq slime-autodoc--cache-last-context context)
  66. (setq slime-autodoc--cache-last-autodoc autodoc))
  67. ;;;; Formatting autodoc
  68. (defsubst slime-autodoc--canonicalize-whitespace (string)
  69. (replace-regexp-in-string "[ \n\t]+" " " string))
  70. (defun slime-autodoc--format (doc multilinep)
  71. (let ((doc (slime-autodoc--fontify doc)))
  72. (cond (multilinep doc)
  73. (t (slime-oneliner (slime-autodoc--canonicalize-whitespace doc))))))
  74. (defun slime-autodoc--fontify (string)
  75. "Fontify STRING as `font-lock-mode' does in Lisp mode."
  76. (with-current-buffer (get-buffer-create (slime-buffer-name :fontify 'hidden))
  77. (erase-buffer)
  78. (unless (eq major-mode 'lisp-mode)
  79. ;; Just calling (lisp-mode) will turn slime-mode on in that buffer,
  80. ;; which may interfere with this function
  81. (setq major-mode 'lisp-mode)
  82. (lisp-mode-variables t))
  83. (insert string)
  84. (let ((font-lock-verbose nil))
  85. (font-lock-fontify-buffer))
  86. (goto-char (point-min))
  87. (when (re-search-forward "===> \\(\\(.\\|\n\\)*\\) <===" nil t)
  88. (let ((highlight (match-string 1)))
  89. ;; Can't use (replace-match highlight) here -- broken in Emacs 21
  90. (delete-region (match-beginning 0) (match-end 0))
  91. (slime-insert-propertized '(face eldoc-highlight-function-argument) highlight)))
  92. (buffer-substring (point-min) (point-max))))
  93. (define-obsolete-function-alias 'slime-fontify-string
  94. 'slime-autodoc--fontify
  95. "SLIME 2.10")
  96. ;;;; Autodocs (automatic context-sensitive help)
  97. (defun slime-autodoc (&optional force-multiline)
  98. "Returns the cached arglist information as string, or nil.
  99. If it's not in the cache, the cache will be updated asynchronously."
  100. (save-excursion
  101. (save-match-data
  102. (let ((context (slime-autodoc--parse-context)))
  103. (when context
  104. (let* ((cached (slime-autodoc--cache-get context))
  105. (multilinep (or force-multiline
  106. eldoc-echo-area-use-multiline-p)))
  107. (cond (cached (slime-autodoc--format cached multilinep))
  108. (t
  109. (when (slime-background-activities-enabled-p)
  110. (slime-autodoc--async context multilinep))
  111. nil))))))))
  112. ;; Return the context around point that can be passed to
  113. ;; swank:autodoc. nil is returned if nothing reasonable could be
  114. ;; found.
  115. (defun slime-autodoc--parse-context ()
  116. (and (slime-autodoc--parsing-safe-p)
  117. (let ((levels slime-autodoc-accuracy-depth))
  118. (slime-parse-form-upto-point levels))))
  119. (defun slime-autodoc--parsing-safe-p ()
  120. (cond ((fboundp 'slime-repl-inside-string-or-comment-p)
  121. (not (slime-repl-inside-string-or-comment-p)))
  122. (t
  123. (not (slime-inside-string-or-comment-p)))))
  124. (defun slime-autodoc--async (context multilinep)
  125. (slime-eval-async
  126. `(swank:autodoc ',context ;; FIXME: misuse of quote
  127. :print-right-margin ,(window-width (minibuffer-window)))
  128. (slime-curry #'slime-autodoc--async% context multilinep)))
  129. (defun slime-autodoc--async% (context multilinep doc)
  130. (cl-destructuring-bind (doc &optional cache-p) doc
  131. (unless (eq doc :not-available)
  132. (when cache-p
  133. (slime-autodoc--cache-put context doc))
  134. ;; Now that we've got our information,
  135. ;; get it to the user ASAP.
  136. (when (eldoc-display-message-p)
  137. (eldoc-message (slime-autodoc--format doc multilinep))))))
  138. ;;; Minor mode definition
  139. ;; Compute the prefix for slime-doc-map, usually this is C-c C-d.
  140. (defun slime-autodoc--doc-map-prefix ()
  141. (concat
  142. (car (rassoc '(slime-prefix-map) slime-parent-bindings))
  143. (car (rassoc '(slime-doc-map) slime-prefix-bindings))))
  144. (define-minor-mode slime-autodoc-mode
  145. "Toggle echo area display of Lisp objects at point."
  146. :lighter slime-autodoc-mode-string
  147. :keymap (let ((prefix (slime-autodoc--doc-map-prefix)))
  148. `((,(concat prefix "A") . slime-autodoc-manually)
  149. (,(concat prefix (kbd "C-A")) . slime-autodoc-manually)
  150. (,(kbd "SPC") . slime-autodoc-space)))
  151. (set (make-local-variable 'eldoc-documentation-function) 'slime-autodoc)
  152. (set (make-local-variable 'eldoc-minor-mode-string) nil)
  153. (setq slime-autodoc-mode (eldoc-mode arg))
  154. (when (called-interactively-p 'interactive)
  155. (message "Slime autodoc mode %s."
  156. (if slime-autodoc-mode "enabled" "disabled"))))
  157. ;;; Noise to enable/disable slime-autodoc-mode
  158. (defun slime-autodoc--on () (slime-autodoc-mode 1))
  159. (defun slime-autodoc--off () (slime-autodoc-mode 0))
  160. (defvar slime-autodoc--relevant-hooks
  161. '(slime-mode-hook slime-repl-mode-hook sldb-mode-hook))
  162. (defun slime-autodoc--enable ()
  163. (dolist (h slime-autodoc--relevant-hooks)
  164. (add-hook h 'slime-autodoc--on))
  165. (dolist (b (buffer-list))
  166. (with-current-buffer b
  167. (when slime-mode
  168. (slime-autodoc--on)))))
  169. (defun slime-autodoc--disable ()
  170. (dolist (h slime-autodoc--relevant-hooks)
  171. (remove-hook h 'slime-autodoc--on))
  172. (dolist (b (buffer-list))
  173. (with-current-buffer b
  174. (when slime-autodoc-mode
  175. (slime-autodoc--off)))))
  176. (provide 'slime-autodoc)