mirror of
https://github.com/SqrtMinusOne/biome.git
synced 2025-12-10 14:35:13 +03:00
biome-query: infix spam :'-(
This commit is contained in:
parent
648cb287f6
commit
1bc7a354ee
1 changed files with 169 additions and 37 deletions
206
biome-query.el
206
biome-query.el
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
;;; Code:
|
||||
(require 'biome-api-data)
|
||||
(require 'font-lock)
|
||||
(require 'compat)
|
||||
(require 'transient)
|
||||
|
||||
|
|
@ -51,12 +52,17 @@ have to be displayed separately.")
|
|||
It is an alist with the following keys:
|
||||
- `:name' - name of the root section.
|
||||
- `:kind' - name of the group (see `biome-query-groups').
|
||||
- `:parameters' - alist with parameters, where the key is either nil
|
||||
(for global parameters) or the value of `:param' key of the
|
||||
corresponding section.
|
||||
- `:params' - alist with parameters, where the key is either nil (for
|
||||
global parameters) or the value of `:param' key of the corresponding
|
||||
section.
|
||||
In the former case, the value is an alist with values; in the latter
|
||||
case, the value is a list of variable names available in the group.")
|
||||
|
||||
(defvar biome-query--layout-cache (make-hash-table :test 'equal)
|
||||
"Cache for dynamic transient layout.")
|
||||
|
||||
(setq biome-query--layout-cache (make-hash-table :test 'equal))
|
||||
|
||||
(defclass biome-query--transient-report (transient-suffix)
|
||||
((transient :initform t))
|
||||
"A transient class to display the current report.")
|
||||
|
|
@ -73,6 +79,89 @@ It is an alist with the following keys:
|
|||
:class 'biome-query--transient-report
|
||||
:key "~~1")
|
||||
|
||||
(defclass biome-query--transient-path (transient-suffix)
|
||||
((transient :initform t))
|
||||
"A transient class to display the current path.")
|
||||
|
||||
(cl-defmethod transient-init-value ((_ biome-query--transient-path))
|
||||
"A dummy method for `biome-query--transient-report'."
|
||||
nil)
|
||||
|
||||
(cl-defmethod transient-format ((_ biome-query--transient-path))
|
||||
"Format the current path."
|
||||
(let* ((scope (oref (or transient--prefix
|
||||
transient-current-prefix)
|
||||
scope))
|
||||
(parents (alist-get :parents scope))
|
||||
(section (alist-get :section scope)))
|
||||
(concat
|
||||
(cl-loop for parent in (reverse parents)
|
||||
concat (propertize
|
||||
(alist-get :name parent)
|
||||
'face 'font-lock-variable-name-face)
|
||||
concat " > ")
|
||||
(propertize
|
||||
(alist-get :name section)
|
||||
'face 'transient-heading))))
|
||||
|
||||
(transient-define-infix biome-query--transient-path-infix ()
|
||||
:class 'biome-query--transient-path
|
||||
:key "~~1")
|
||||
|
||||
(defclass biome-query--transient-switch-variable (transient-argument)
|
||||
((name :initarg :name)
|
||||
(param :initarg :param :initform nil))
|
||||
"A transient class to display a switch.")
|
||||
|
||||
(cl-defmethod transient-init-value ((obj biome-query--transient-switch-variable))
|
||||
(oset obj value
|
||||
(not
|
||||
(null
|
||||
(member
|
||||
(oref obj name)
|
||||
(if-let ((param (oref obj param)))
|
||||
(cdr
|
||||
(assoc
|
||||
param
|
||||
(alist-get :params biome-query-current)))
|
||||
(alist-get :params biome-query-current)))))))
|
||||
|
||||
(defmacro biome-query--update-list (item list-place add)
|
||||
`(setf ,list-place
|
||||
(if ,add
|
||||
(cons ,item ,list-place)
|
||||
(delete ,item ,list-place))))
|
||||
|
||||
(cl-defmethod transient-infix-read ((obj biome-query--transient-switch-variable))
|
||||
"Toggle the switch on or off."
|
||||
(setq my/test obj)
|
||||
(let ((new-value (not (oref obj value)))
|
||||
(param (oref obj param))
|
||||
(name (oref obj name)))
|
||||
(if param
|
||||
(biome-query--update-list
|
||||
name (alist-get param (alist-get :params biome-query-current) nil nil #'equal)
|
||||
new-value)
|
||||
(biome-query--update-list
|
||||
name (alist-get :params biome-query-current nil nil #'equal)
|
||||
new-value))
|
||||
new-value))
|
||||
|
||||
(cl-defmethod transient-format ((obj biome-query--transient-switch-variable))
|
||||
"Return a string generated using OBJ's `format'.
|
||||
%k is formatted using `transient-format-key'.
|
||||
%d is formatted using `transient-format-description'.
|
||||
%v is formatted using `transient-format-value'."
|
||||
(concat
|
||||
(string-pad (transient-format-key obj) 6)
|
||||
(transient-format-description obj)
|
||||
(when (oref obj value)
|
||||
(propertize " (+)" 'face 'transient-argument))))
|
||||
|
||||
(transient-define-infix biome-query--transient-switch-variable-infix ()
|
||||
:class 'biome-query--transient-switch-variable
|
||||
:key "~~1")
|
||||
|
||||
(defun biome-query--cartesian-product (a b)
|
||||
"Compute the Cartesian product of A and B."
|
||||
(mapcan
|
||||
|
|
@ -159,28 +248,51 @@ NAMES is a list of strings."
|
|||
do (puthash name key keys-by-name)))
|
||||
keys-by-name))
|
||||
|
||||
(defun biome-query--section-fields-children (fields keys)
|
||||
(defun biome-query--section-fields-children (fields keys parents cache-key)
|
||||
"Get transient laoyut for FIELDS.
|
||||
|
||||
FIELDS is a list of fields as defined in `biome-api-parse--page'.
|
||||
KEYS is the result of `biome-query--unique-keys'."
|
||||
KEYS is the result of `biome-query--unique-keys'. PARENTS is a list
|
||||
of parent sections."
|
||||
(when fields
|
||||
`(["Fields"
|
||||
:class transient-columns
|
||||
,@(thread-last
|
||||
fields
|
||||
(seq-map-indexed
|
||||
(lambda (field idx) (cons field (/ idx biome-query-max-fields-in-row))))
|
||||
(seq-group-by #'cdr)
|
||||
(mapcar (lambda (group)
|
||||
(apply #'vector
|
||||
(mapcar
|
||||
(lambda (el)
|
||||
(let* ((field (car el))
|
||||
(name (alist-get :name (cdr field))))
|
||||
;; TODO
|
||||
(list (gethash name keys) name #'transient-quit-one)))
|
||||
(cdr group))))))])))
|
||||
(let ((param (seq-some (lambda (s) (alist-get :param s)) parents))
|
||||
(infix-name (concat "biome-query--transient-" cache-key "-")))
|
||||
(cl-loop
|
||||
for field in fields
|
||||
for field-api-key = (car field)
|
||||
for name = (alist-get :name (cdr field))
|
||||
for key = (gethash name keys)
|
||||
for type = (alist-get :type (cdr field))
|
||||
for infix-symbol = (intern (concat infix-name field-api-key))
|
||||
do (eval (pcase type
|
||||
('checkbox
|
||||
`(transient-define-infix ,infix-symbol ()
|
||||
:class 'biome-query--transient-switch-variable
|
||||
:key ,key
|
||||
:description ,name
|
||||
:argument ,name
|
||||
:name ,name
|
||||
:param ,param))
|
||||
(_
|
||||
`(transient-define-infix ,infix-symbol ()
|
||||
:key ,key
|
||||
:name ,name)))))
|
||||
`(["Fields"
|
||||
:class transient-columns
|
||||
,@(thread-last
|
||||
fields
|
||||
(seq-map-indexed
|
||||
(lambda (field idx) (cons field (/ idx biome-query-max-fields-in-row))))
|
||||
(seq-group-by #'cdr)
|
||||
(mapcar
|
||||
(lambda (group)
|
||||
(apply
|
||||
#'vector
|
||||
(mapcar
|
||||
(lambda (el)
|
||||
(let* ((field-api-key (caar el)))
|
||||
(list (intern (concat infix-name field-api-key)))))
|
||||
(cdr group))))))]))))
|
||||
|
||||
(defun biome-query--section-sections-children (sections keys parents)
|
||||
"Get transient layout for SECTIONS.
|
||||
|
|
@ -201,21 +313,43 @@ list of parent sections."
|
|||
:transient transient--do-replace))
|
||||
sections)])))
|
||||
|
||||
(defmacro biome-query--with-layout-cache (cache-key &rest body)
|
||||
"Cache layout for CACHE-KEY.
|
||||
|
||||
BODY is the body of the macro."
|
||||
(declare (indent 1))
|
||||
`(let ((layout (gethash ,cache-key biome-query--layout-cache)))
|
||||
(if layout
|
||||
layout
|
||||
(let* ((cache-key ,cache-key)
|
||||
(layout (progn ,@body)))
|
||||
(puthash ,cache-key layout biome-query--layout-cache)
|
||||
layout))))
|
||||
|
||||
(defun biome-query--section-layout (section parents)
|
||||
"Get transient layout for SECTION.
|
||||
|
||||
SECTION is a form as defined by `biome-api-parse--page'. PARENTS
|
||||
is a list of parent sections."
|
||||
(let* ((sections (or (alist-get :children section)
|
||||
(alist-get :sections section)))
|
||||
(fields (alist-get :fields section))
|
||||
(keys (biome-query--unique-keys
|
||||
(append
|
||||
(mapcar (lambda (s) (alist-get :name s)) sections)
|
||||
(mapcar (lambda (s) (alist-get :name (cdr s))) fields)))))
|
||||
(append
|
||||
(biome-query--section-fields-children fields keys)
|
||||
(biome-query--section-sections-children sections keys (cons section parents)))))
|
||||
(biome-query--with-layout-cache
|
||||
(string-join
|
||||
(mapcar
|
||||
(lambda (s) (string-replace " " "-" s))
|
||||
(cons
|
||||
(alist-get :name section)
|
||||
(mapcar (lambda (s) (alist-get :name s)) parents)))
|
||||
"-")
|
||||
(let* ((sections (or (alist-get :children section)
|
||||
(alist-get :sections section)))
|
||||
(fields (alist-get :fields section))
|
||||
(keys (biome-query--unique-keys
|
||||
(append
|
||||
(mapcar (lambda (s) (alist-get :name s)) sections)
|
||||
(mapcar (lambda (s) (alist-get :name (cdr s))) fields))))
|
||||
(parents (cons section parents)))
|
||||
(append
|
||||
(biome-query--section-fields-children fields keys parents cache-key)
|
||||
(biome-query--section-sections-children sections keys parents)))))
|
||||
|
||||
(defun biome-query--transient-prepare-layout (name suffixes)
|
||||
"Prepare dynamic transient layout for NAME.
|
||||
|
|
@ -234,13 +368,11 @@ SECTION is a form as defined in `biome-api-parse--page'."
|
|||
(interactive (list nil))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(setq my/test section)
|
||||
(biome-query--prepare-layout
|
||||
'biome-query--section
|
||||
(append
|
||||
'([:description
|
||||
(lambda () (alist-get :name (car (oref transient--prefix scope))))
|
||||
(biome-query--transient-report-infix)])
|
||||
'([(biome-query--transient-path-infix)])
|
||||
'([(biome-query--transient-report-infix)])
|
||||
(biome-query--section-layout section parents)
|
||||
'(["Actions"
|
||||
:class transient-row
|
||||
|
|
@ -249,7 +381,7 @@ SECTION is a form as defined in `biome-api-parse--page'."
|
|||
(transient-setup 'biome-query--section nil nil :scope
|
||||
`((:section . ,section)
|
||||
(:parents . ,parents))))
|
||||
(put 'biome-query-section 'transient--layout nil)))
|
||||
(put 'biome-query-section 'transient--layout nil)))
|
||||
|
||||
(transient-define-prefix biome-query ()
|
||||
["Open Meteo Data"
|
||||
|
|
@ -268,7 +400,7 @@ SECTION is a form as defined in `biome-api-parse--page'."
|
|||
(setq biome-query-current
|
||||
'((:name . ,name)
|
||||
(:kind . nil)
|
||||
(:parameters . nil))))
|
||||
(:params . nil))))
|
||||
(biome-query--section ',params))
|
||||
:transient transient--do-replace))))]
|
||||
["Actions"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue