commit 20b884ab7a79f5e47fe9dcc45da8e0223bf996a4
parent 7b8aba83ffd2763604ea5abbbae1c4fc352de889
Author: Lou Woell <lou.woell@posteo.de>
Date: Fri, 26 Sep 2025 03:37:32 +0200
[haredoc.el] Improve documentation
- Add package description.
- Add docstrings to most symbols.
- Update TODOs.
Diffstat:
| M | haredoc.el | | | 97 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------- |
1 file changed, 77 insertions(+), 20 deletions(-)
diff --git a/haredoc.el b/haredoc.el
@@ -23,11 +23,20 @@
;;; Commentary:
-;; Better emacs integration for hare.
+;; `haredoc.el' provides an emacs interface for `haredoc' using harehelper. The
+;; main entry points are `haredoc/goto-definition', `haredoc' and
+;; `haredoc/describe-thing-at-point'.
+
+;; To enable the default keymap in hare-mode, add `haredoc-nav-mode' to your
+;; `hare-mode-hook':
+
+;; (add-hook 'hare-mode-hook #'haredoc-nav-mode)
;;; TODO:
-;; - make references in docs clickable links
+;; - melpa compatible setup
+;; - imenu integration
+;; - MAYBE: proper xref integration
;;; Code:
@@ -37,14 +46,22 @@
(require 'thingatpt)
(require 'ansi-color)
-(defconst haredoc-helperbindir (f-dirname (macroexp-file-name)))
-(defconst haredoc-helperbin (concat haredoc-helperbindir "/harehelper"))
+(defconst haredoc-helperbindir (f-dirname (macroexp-file-name))
+ "Default directory for `haredoc-helperbin'. Defaults to directory
+containing this file.")
+
+(defcustom haredoc-helperbin (concat haredoc-helperbindir "/harehelper")
+ "Location of the harehelper executable."
+ :type 'file
+ :group 'haredoc)
-(defconst haredoc-symbol-regex "[\\*&]*\\(\\(\\(\\sw\\|\\s_\\)+::\\)*\\(\\sw\\|\\s_\\)+\\)")
+(defconst haredoc-symbol-regex "[\\*&]*\\(\\(\\(\\sw\\|\\s_\\)+::\\)*\\(\\sw\\|\\s_\\)+\\)"
+ "Regex matching hare identifiers. Explixcitely ignores leading * and &.")
(defconst haredoc-decl-regex "^\\(fn\\|type\\|def\\|const\\|let\\) ")
(defconst haredoc-link-regex "\\[\\[\\(.*?\\)\\]\\]" )
(defun haredoc/root-dir ()
+ "Return root directory of current project or \".\""
(interactive)
(if-let ((p (project-current nil)))
(project-root p)
@@ -55,9 +72,12 @@
(process-lines haredoc-helperbin "-p" (haredoc/root-dir) "list-modules"))
(defun haredoc/read-module (&optional init)
+ "Ask user to pick from a list of installed hare modules."
(completing-read "Pick Module: " (haredoc/get-modules) nil nil init))
(defun haredoc/identifier-at-point ()
+ "Return hare identifier of the form foo::bar at point, using
+`haredoc-symbol-regex'."
(let ((id (if (use-region-p) ;; Use region or the current word
(buffer-substring-no-properties (region-beginning)
(region-end))
@@ -99,20 +119,40 @@
:module module
:args (match-string match-number)))
-(defvar-local haredoc-backward-stack '())
+;; State variables for haredoc history.
+(defvar-local haredoc-backward-stack '()
+ "Stack for `haredoc/back'.")
(put 'haredoc-backward-stack 'permanent-local t)
-(defvar-local haredoc-forward-stack '())
+(defvar-local haredoc-forward-stack '()
+ "Stack for `haredoc/forward'.")
(put 'haredoc-forward-stack 'permanent-local t)
-(defvar-local haredoc-stack-item nil)
+(defvar-local haredoc-stack-item nil
+ "State variable for `haredoc/back' and `haredoc/forward'.")
(put 'haredoc-stack-item 'permanent-local t)
-(defvar-local haredoc-current-ns nil)
+
+(defvar-local haredoc-current-ns nil
+ "Namespace of the hare documentation shown in current `haredoc-mode'
+buffer.
+
+If currently showing documentation for a module, this is set to the
+module name. See also `haredoc-parent-ns'.")
(put 'haredoc-current-ns 'permanent-local t)
-(defvar-local haredoc-current-path nil)
+
+(defvar-local haredoc-current-path nil
+ "Hare identifier that produced the documentation currently shown in
+`haredoc-mode' buffer.")
(put 'haredoc-current-path 'permanent-local t)
-(defvar-local haredoc-parent-ns nil)
+
+(defvar-local haredoc-parent-ns nil
+ "Parent namespace of the hare documentation shown in the current
+`haredoc-mode' buffer.
+
+For everything but modules this will be equal to `haredoc-current-ns'.")
(put 'haredoc-parent-ns 'permanent-local t)
(defun haredoc/back (&optional args)
+ "Go to previously shown hare documentation in current `haredoc-mode'
+buffer. See also `haredoc/forward'."
(interactive)
(when-let ((item (pop haredoc-backward-stack)))
(push haredoc-stack-item haredoc-forward-stack)
@@ -120,17 +160,17 @@
(haredoc item)))
(defun haredoc/forward (&optional args)
+ "Inverse of `haredoc/back'."
(interactive)
(when-let ((item (pop haredoc-forward-stack)))
(push haredoc-stack-item haredoc-backward-stack)
(setq haredoc-stack-item nil)
(haredoc item)))
-;; Shows haredoc for the selected or word.
;;;###autoload
(defun haredoc (&optional sign)
- "Run haredoc with the current word under the cursor and display
-the results in a new buffer."
+ "Run haredoc with hare identifier SIGN and present result in help buffer.
+If SIGN is nil, ask user."
(interactive)
(let* ((id (or sign (haredoc/read-module)))
(components (string-split id "::" t))
@@ -185,15 +225,19 @@ the results in a new buffer."
(goto-char (point-min))
(haredoc-mode)
- (display-buffer buffer)
- ))))
+ (display-buffer buffer)))))
;;;###autoload
(defun haredoc/describe-thing-at-point ()
+ "Show documentation for hare identifier at point via `haredoc'."
(interactive)
(haredoc (haredoc/identifier-at-point)))
(defun haredoc/get-location (name)
+ "Get the location of the declaration of hare identifier NAME by calling
+the executable at `haredoc-helperbin'.
+
+Return value is a string \"/path/to/file.ha:line:column\"."
(catch 'exit
(car (process-lines-handling-status
haredoc-helperbin
@@ -205,6 +249,9 @@ the results in a new buffer."
;;;###autoload
(defun haredoc/goto-defintion (&optional name)
+ "Go to definition of hare identifier NAME.
+
+See `haredoc/identifier-at-point' and `haredoc/get-location'."
(interactive)
(when-let* ((name (or name (haredoc/identifier-at-point)))
(loc (haredoc/get-location name))
@@ -219,35 +266,42 @@ the results in a new buffer."
(forward-to-word))))
(defun haredoc/next-decl ()
+ "In `haredoc-mode' buffer, jump to next declaration."
(interactive)
(forward-line 1)
(re-search-forward haredoc-decl-regex)
(goto-char (match-end 0)))
(defun haredoc/prev-decl ()
+ "In `haredoc-mode' buffer, jump to previous declaration."
(interactive)
(forward-line -1)
(re-search-backward haredoc-decl-regex)
(goto-char (match-end 0)))
(defun haredoc/widen ()
+ "In `haredoc-mode' buffer, show documentation for namespace containing
+currently documented identifier."
(interactive)
(haredoc haredoc-parent-ns))
-(defun haredoc/get-symbol-apt ()
+(defun haredoc/get-decl-apt ()
(let ((re (string-join (list haredoc-decl-regex
haredoc-symbol-regex))))
(thing-at-point-looking-at re)
(string-join (list haredoc-current-ns (match-string 2)) "::")))
(defun haredoc/narrow ()
+ "In `haredoc-mode' buffer, narrow documentation to documentation of
+declaration at point."
(interactive)
- (haredoc (haredoc/get-symbol-apt)))
+ (haredoc (haredoc/get-decl-apt)))
(defun haredoc/goto-src ()
+ "In `haredoc-mode' buffer, jump to source code of declaration at point."
(interactive)
(when (derived-mode-p 'haredoc-mode)
- (haredoc/goto-defintion (haredoc/get-symbol-apt))))
+ (haredoc/goto-defintion (haredoc/get-decl-apt))))
(defvar-keymap haredoc-map
"C-c C-h" 'haredoc
@@ -257,7 +311,8 @@ the results in a new buffer."
;;;###autoload
(define-minor-mode haredoc-nav-mode
"Enable navigation of hare symbols and easy access to haredoc pages."
- :keymap haredoc-map)
+ :keymap haredoc-map
+ :group 'haredoc)
(defvar-keymap haredoc-mode-map
"s" 'haredoc/goto-src
@@ -269,6 +324,8 @@ the results in a new buffer."
"w" 'haredoc/widen)
(define-derived-mode haredoc-mode help-mode "🐇"
+ "Major mode for navigating hare documentation."
+ :group 'haredoc
(setq header-line-format `((:propertize ,haredoc-current-path face bold))))
(provide 'haredoc)