texi-docstring-magic-geiser.el 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. ;; texi-docstring-magic-geiser.el --- geiser docstrins to texi -*- lexical-binding: t; -*-
  2. ;;
  3. ;; Copyright (C) 1998 David Aspinall
  4. ;; Copyright (C) 2018 Jelle Licht <jlicht@fsfe.org>
  5. ;; Author: Jelle Licht <jlicht@fsfe.org>
  6. ;; URL: https://github.com/emacs-evil/evil-collection
  7. ;; Package-Requires: ((emacs "25.2") (geiser "0.10"))
  8. ;; Keywords: geiser, docstring
  9. (require 'texi-docstring-magic)
  10. (require 'geiser-doc)
  11. (require 'geiser-repl)
  12. (require 'geiser-impl)
  13. ;;
  14. ;; (defun geiser-repl--connection ()
  15. ;; (or (geiser-repl--connection*)
  16. ;; (error "No Geiser REPL for this buffer (try M-x run-geiser)")))
  17. (defconst texi-docstring-magic-comment-geiser
  18. "@c TEXI DOCSTRING MAGIC:GEISER:"
  19. "Magic string in a texi buffer expanded into @deffn.")
  20. (defconst texi-docstring-magic-comment-geiser-impl
  21. "\\(\\w+\\):")
  22. (defun unwrap (geiser-result)
  23. (pcase geiser-result
  24. (`"#<unspecified>" nil)
  25. (`(("signature" ,_ ("args" ,arglist))
  26. ("docstring" . ,docstring))
  27. (list arglist docstring))
  28. (_ nil)))
  29. (defvar geiser-buffer-curr nil)
  30. ;;;###autoload
  31. (defun get-geiser-buffer (&optional ask impl)
  32. "Retrieve running or new Geiser REPL.
  33. With prefix argument, ask for which one if more than one is running.
  34. If no REPL is running, execute `run-geiser' to start a fresh one."
  35. (interactive "P")
  36. (let* ((impl (or impl geiser-impl--implementation))
  37. (in-repl (eq major-mode 'geiser-repl-mode))
  38. (in-live-repl (and in-repl (get-buffer-process (current-buffer))))
  39. (repl (unless ask
  40. (if impl
  41. (geiser-repl--repl/impl impl)
  42. (or geiser-repl--repl (car geiser-repl--repls))))))
  43. (cond (in-live-repl
  44. (current-buffer))
  45. (repl
  46. repl)
  47. (impl (run-geiser impl))
  48. (t (call-interactively 'run-geiser))
  49. )))
  50. ;;;###autoload
  51. (defun geiser/register-buffer ()
  52. (interactive)
  53. (setq geiser-buffer-curr
  54. (or (get-geiser-buffer)
  55. (current-buffer))))
  56. (defun texi-docstring-magic-geiser-def (symbol)
  57. (when geiser-buffer-curr
  58. (with-current-buffer geiser-buffer-curr
  59. (let ((x (geiser-doc--get-docstring symbol 'guile)))
  60. (unwrap x)))))
  61. (defun geiser/def->docstring (def)
  62. (pcase def
  63. (`(,arglist ,(and (pred stringp) docstring)) docstring)
  64. (_ nil)))
  65. (defun geiser/def->argsyms (def)
  66. (pcase def
  67. (`(,arglist ,_ )
  68. (apply #'append (mapcar 'cdr arglist)))
  69. (_ nil)))
  70. (defun wrap-arg (arg)
  71. arg
  72. ;; (concat "@var{" arg "}")
  73. )
  74. (defun texi-docstring-magic-texi-geiser (symbol impl &optional noerror)
  75. (let* ((function symbol)
  76. (name (symbol-name function))
  77. (def (texi-docstring-magic-geiser-def function))
  78. (docstring (or (geiser/def->docstring def)
  79. "Not documented."))
  80. (argsyms (geiser/def->argsyms def))
  81. (args (mapcar #'symbol-name argsyms)))
  82. (texi-docstring-magic-texi "fn" "{Scheme Procedure}" name docstring (mapcar 'wrap-arg args))))
  83. ;; @c GEISER TEXI DOCSTRING MAGIC: gt
  84. ;;;###autoload
  85. (defun texi-docstring-magic-geiser (&optional noerror)
  86. "Update all texi docstring magic annotations in buffer.
  87. With prefix arg, no errors on unknown symbols. (This results in
  88. @def .. @end being deleted if not known)."
  89. (interactive "P")
  90. (save-excursion
  91. (goto-char (point-min))
  92. (let ((magic (concat "^"
  93. (regexp-quote texi-docstring-magic-comment-geiser)
  94. texi-docstring-magic-comment-geiser-impl
  95. "\\s-*\\(\\(\\w\\|\\-\\)+\\)[ \t]*$"))
  96. p
  97. symbol
  98. impl
  99. deleted)
  100. (while (re-search-forward magic nil t)
  101. (setq impl (intern (match-string 1)))
  102. (setq symbol (intern (match-string 2)))
  103. (forward-line)
  104. (setq p (point))
  105. ;; delete any whitespace following magic comment
  106. (skip-chars-forward " \n\t")
  107. (delete-region p (point))
  108. ;; If comment already followed by an environment, delete it.
  109. (if (and
  110. (looking-at "@def\\(\\w+\\)\\s-")
  111. (search-forward (concat "@end def" (match-string 1)) nil t))
  112. (progn
  113. (forward-line)
  114. (delete-region p (point))
  115. (setq deleted t)))
  116. (insert
  117. (texi-docstring-magic-texi-geiser symbol impl noerror))
  118. (unless deleted
  119. ;; Follow newly inserted @def with a single blank.
  120. (insert "\n"))))))
  121. (provide 'texi-docstring-magic-geiser)