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:
Mharedoc.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