commit d4a7aa11c282358e1882b390a1a9dc94275b34d6
parent aaee8a145ba14b69d99adc04c37f806a3f5c8ed6
Author: Lou Woell <lou.woell@posteo.de>
Date: Sun, 14 Sep 2025 02:10:07 +0200
[haredoc.el] Navigation for haredoc-mode
Diffstat:
| M | haredoc.el | | | 91 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------- |
1 file changed, 75 insertions(+), 16 deletions(-)
diff --git a/haredoc.el b/haredoc.el
@@ -40,6 +40,9 @@
(defconst haredoc-helperbindir (f-dirname (macroexp-file-name)))
(defconst haredoc-helperbin (concat haredoc-helperbindir "/harehelper"))
+(defconst haredoc-symbol-regex "\\**\\(\\(\\(\\sw\\|\\s_\\)+::\\)*\\(\\sw\\|\\s_\\)+\\)")
+(defconst haredoc-decl-regex "^\\(fn\\|type\\|def\\|const\\|let\\) ")
+
(defun haredoc/root-dir ()
(interactive)
(if-let ((p (project-current nil)))
@@ -57,8 +60,7 @@
(let ((id (if (use-region-p) ;; Use region or the current word
(buffer-substring-no-properties (region-beginning)
(region-end))
- (thing-at-point-looking-at
- "\\**\\(\\(\\(\\sw\\|\\s_\\)+::\\)*\\(\\sw\\|\\s_\\)+\\)")
+ (thing-at-point-looking-at haredoc-symbol-regex)
(match-string 1))))
;; resolve identifier
(car (process-lines haredoc-helperbin "-p" (haredoc/root-dir)
@@ -67,7 +69,11 @@
(define-button-type 'haredoc
'action #'haredoc/button-action
- 'help-echo (purecopy "mouse-2, RET: describe this"))
+ 'help-echo (purecopy "mouse-1, RET: describe this"))
+
+(define-button-type 'haredoc-module
+ 'action #'(lambda (x) (haredoc/widen))
+ 'help-echo (purecopy "mouse-1, RET: describe module"))
(define-button-type 'haredoc-back
'action #'haredoc/back
@@ -98,6 +104,8 @@
(put 'haredoc-forward-stack 'permanent-local t)
(defvar-local haredoc-stack-item nil)
(put 'haredoc-stack-item 'permanent-local t)
+(defvar-local haredoc-namespace nil)
+(put 'haredoc-namespace 'permanent-local t)
(defun haredoc/back (&optional args)
(interactive)
@@ -122,7 +130,6 @@ the results in a new buffer."
(let* ((current-word (string-trim-right (or sign (haredoc/read-module))
"::"))
(components (string-split current-word "::" t))
- (cmps (length components))
(location (haredoc/get-location current-word))
(location (string-split location ":" t))
(path (nth 0 location))
@@ -138,26 +145,40 @@ the results in a new buffer."
(setq haredoc-stack-item current-word)
(let ((inhibit-read-only t))
(with-current-buffer buffer
+ (setq haredoc-namespace namespace)
(erase-buffer)
;; 'display-buffer-same-window nil
- (insert "\033[1;4m" current-word "\033[0m\n\n")
+ (insert "\033[1;4m" current-word "\033[0m")
+ (ensure-empty-lines 1)
+
(with-environment-variables
(("HAREPATH" (car (process-lines haredoc-helperbin
"-p" (haredoc/root-dir)
"-P"))))
(call-process "haredoc" nil t nil "-a" "-F" "tty" current-word))
+
(ansi-color-apply-on-region (point-min) (point-max))
+
(save-excursion
(goto-char (point-min))
(while (re-search-forward "\\[\\[\\(.*?\\)\\]\\]" nil t)
(haredoc/make-button 1 namespace)))
- (ensure-empty-lines 2)
- (when haredoc-backward-stack
- (insert-text-button "[back]" :type 'haredoc-back)
- (insert "\t"))
- (when haredoc-forward-stack
- (insert-text-button "[forw]" :type 'haredoc-forw))
+
+ (save-excursion
+ (when (or (not module?) haredoc-backward-stack haredoc-forward-stack)
+ (ensure-empty-lines 2)
+ (when haredoc-backward-stack
+ (insert-text-button "[back]" :type 'haredoc-back)
+ (insert "\t"))
+ (when (not module?)
+ (insert-text-button "[module]" :type 'haredoc-module)
+ (insert "\t"))
+ (when haredoc-forward-stack
+ (insert-text-button "[forw]" :type 'haredoc-forw))
+ (insert "\n")))
+
(haredoc-mode)
+ (goto-char (point-min))
(display-buffer buffer)))))
;;;###autoload
@@ -176,9 +197,9 @@ the results in a new buffer."
"locate" name))))
;;;###autoload
-(defun haredoc/goto-defintion ()
+(defun haredoc/goto-defintion (&optional name)
(interactive)
- (when-let* ((name (haredoc/identifier-at-point))
+ (when-let* ((name (or name (haredoc/identifier-at-point)))
(loc (haredoc/get-location name))
(loc (split-string loc ":"))
(file (nth 0 loc))
@@ -190,10 +211,48 @@ the results in a new buffer."
(forward-char col)
(forward-to-word))))
-(define-derived-mode haredoc-mode help-mode "🐇")
+(defun haredoc/next-decl ()
+ (interactive)
+ (forward-line 1)
+ (re-search-forward haredoc-decl-regex)
+ (goto-char (match-end 0)))
-(define-key haredoc-mode-map (kbd "b") 'haredoc/back)
-(define-key haredoc-mode-map (kbd "f") 'haredoc/forward)
+(defun haredoc/prev-decl ()
+ (interactive)
+ (forward-line -1)
+ (re-search-backward haredoc-decl-regex)
+ (goto-char (match-end 0)))
+
+(defun haredoc/widen ()
+ (interactive)
+ (haredoc haredoc-namespace))
+
+(defun haredoc/get-symbol-apt ()
+ (let ((re (string-join (list haredoc-decl-regex
+ haredoc-symbol-regex))))
+ (thing-at-point-looking-at re)
+ (string-join (list haredoc-namespace (match-string 2)) "::")))
+
+(defun haredoc/narrow ()
+ (interactive)
+ (haredoc (haredoc/get-symbol-apt)))
+
+(defun haredoc/goto-src ()
+ (interactive)
+ (when (derived-mode-p 'haredoc-mode)
+ (haredoc/goto-defintion (haredoc/get-symbol-apt))))
+
+(defvar haredoc-mode-map
+ (define-keymap
+ "s" 'haredoc/goto-src
+ "b" 'haredoc/back
+ "f" 'haredoc/forward
+ "n" 'haredoc/next-decl
+ "p" 'haredoc/prev-decl
+ "N" 'haredoc/narrow
+ "w" 'haredoc/widen))
+
+(define-derived-mode haredoc-mode help-mode "🐇")
(provide 'haredoc)
;;; haredoc.el ends here