summaryrefslogtreecommitdiff
path: root/.config/emacs/modules/mm-humanwave.el
blob: 178f7a874e5e36d37638b177d0ed8223d11e846e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
;;; mm-humanwave.el --- Humanwave extras  -*- lexical-binding: t; -*-

^L
;;; Query the Backend

(defvar mm--humanwave-query-history nil
  "History for endpoints given to `mm-humanwave-query'.")

(defun mm-humanwave-query (endpoint &optional method)
  "Query and display the result of an HTTP reqiest on ENDPOINT.
If METHOD is nil, a GET request is performed."
  (interactive
   (let* ((query (read-string (format-prompt "Query" nil)
                              (car-safe mm--humanwave-query-history)
                              'mm--humanwave-query-history))
          (parts (string-split (string-trim query) " " :omit-nulls)))
     (when (length> parts 2)
       (user-error "Queries must be of the form `METHOD ENDPOINT' or `ENDPOINT'."))
     (nreverse parts)))
  (let* ((project-root (project-root (project-current :maybe-prompt)))
         (qry-path (expand-file-name "qry" project-root))
         extras)
    (unless (file-executable-p qry-path)
      (user-error "No `qry' executable found in the project root"))
    (let ((output-buffer (get-buffer-create "*Query Response*")))
      (with-current-buffer output-buffer
        (delete-region (point-min) (point-max))
        (call-process qry-path nil t nil
                      (string-trim endpoint) "-X" (or method "GET"))
        (unless (eq major-mode 'json-ts-mode)
          (json-ts-mode))
        (goto-char (point-min)))
      (display-buffer output-buffer))))

(keymap-set project-prefix-map "q" #'mm-humanwave-query)

^L
;;; IMenu Support for Handlers

(defvar mm-humanwave-handler--regexp
  (rx bol
      (* blank)
      (or "if" "elif")
      (* blank)
      (or "topic" "schedule")
      (* blank)
      "=="
      (* blank)
      (or (seq ?\' (* (not ?\')) ?\')
          (seq ?\" (* (not ?\")) ?\"))
      (* blank)
      ?:
      (* blank)
      eol))

(defun mm-humanwave-handler-topic-imenu-index ()
  (let ((tree-index (when (fboundp 'treesit-simple-imenu--generic-function)
                      (treesit-simple-imenu--generic-function
                       treesit-simple-imenu-settings)))
        (topic-index '()))
    (save-excursion
      (goto-char (point-min))
      (while (re-search-forward mm-humanwave-handler--regexp nil :noerror)
        (let ((label (match-string 0))
              (pos (match-beginning 0)))
          (push (cons (format "Topic: %s" (string-trim label)) pos) topic-index))))
    (append (nreverse topic-index) tree-index)))

(defun mm-humanwave-handler-topic-imenu-setup ()
  "Setup custom imenu index for `python-ts-mode'."
  (when (and (string-match-p "handlers?" (or (buffer-file-name) ""))
             (derived-mode-p #'python-ts-mode))
    (setq-local imenu-create-index-function
                #'mm-humanwave-handler-topic-imenu-index)))

(add-hook 'after-change-major-mode-hook
          #'mm-humanwave-handler-topic-imenu-setup)

(provide 'mm-humanwave)