mirror of
https://github.com/SqrtMinusOne/biome.git
synced 2025-12-11 14:53:02 +03:00
basic UI and gradient formatting works
This commit is contained in:
parent
eb240166ac
commit
f60e6c047b
4 changed files with 115 additions and 25 deletions
|
|
@ -68,7 +68,7 @@ QUERY is a form as defined by `biome-query-current'."
|
||||||
(cons
|
(cons
|
||||||
(car item)
|
(car item)
|
||||||
(cond
|
(cond
|
||||||
((listp (cdr item)) (mapconcat #'identity (cdr item) ","))
|
((listp (cdr item)) (mapconcat #'identity (reverse (cdr item)) ","))
|
||||||
(t (cdr item)))))))
|
(t (cdr item)))))))
|
||||||
(alist-get :params query)))
|
(alist-get :params query)))
|
||||||
|
|
||||||
|
|
@ -114,7 +114,7 @@ QUERY is a form as defined by `biome-query-current'."
|
||||||
"Get data from Open Meteo API.
|
"Get data from Open Meteo API.
|
||||||
|
|
||||||
QUERY is a form as defined by `biome-query-current'. CALLBACK is
|
QUERY is a form as defined by `biome-query-current'. CALLBACK is
|
||||||
called with the data as its only argument."
|
called with QUERY and the data returned by the API as arguments."
|
||||||
(let ((url (alist-get (alist-get :name query)
|
(let ((url (alist-get (alist-get :name query)
|
||||||
biome-api-urls nil nil #'equal)))
|
biome-api-urls nil nil #'equal)))
|
||||||
(request url
|
(request url
|
||||||
|
|
@ -123,7 +123,7 @@ called with the data as its only argument."
|
||||||
:parser #'json-read
|
:parser #'json-read
|
||||||
:success (cl-function
|
:success (cl-function
|
||||||
(lambda (&key data &allow-other-keys)
|
(lambda (&key data &allow-other-keys)
|
||||||
(funcall callback data)))
|
(funcall callback (copy-tree query) data)))
|
||||||
:error
|
:error
|
||||||
(cl-function (lambda (&key error-thrown response &allow-other-keys)
|
(cl-function (lambda (&key error-thrown response &allow-other-keys)
|
||||||
(biome-api--show-error error-thrown response))))))
|
(biome-api--show-error error-thrown response))))))
|
||||||
|
|
|
||||||
|
|
@ -26,29 +26,77 @@
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
(require 'cl-lib)
|
(require 'cl-lib)
|
||||||
(require 'biome-query)
|
(require 'ct)
|
||||||
|
(require 'seq)
|
||||||
(require 'tabulated-list)
|
(require 'tabulated-list)
|
||||||
|
(require 'biome-query)
|
||||||
|
|
||||||
(defcustom biome-grid-display-units t
|
(defcustom biome-grid-display-units t
|
||||||
"Display units in the grid."
|
"Display units in the grid."
|
||||||
:type 'boolean
|
:type 'boolean
|
||||||
:group 'biome)
|
:group 'biome)
|
||||||
|
|
||||||
|
(defcustom biome-grid-format-units
|
||||||
|
'(("°C" . (gradient
|
||||||
|
(-40 . "#ae64a0")
|
||||||
|
(-30 . "#9488d2")
|
||||||
|
(-15 . "#90cfd2")
|
||||||
|
(-5 . "#66adbb")
|
||||||
|
(5 . "#508c40")
|
||||||
|
(15 . "#aba10e")
|
||||||
|
(25 . "#f39506")
|
||||||
|
(35 . "#bf4112")
|
||||||
|
(40 . "#8a2b0a"))))
|
||||||
|
"Format units in the grid."
|
||||||
|
:group 'biome)
|
||||||
|
|
||||||
|
(defvar biome-grid-mode-map
|
||||||
|
(let ((keymap (make-sparse-keymap)))
|
||||||
|
(define-key keymap (kbd "q") #'quit-window)
|
||||||
|
(when (fboundp 'evil-define-key*)
|
||||||
|
(evil-define-key* 'normal keymap
|
||||||
|
"q" #'quit-window))
|
||||||
|
keymap)
|
||||||
|
"Keymap for `biome-api-error-mode'.")
|
||||||
|
|
||||||
(define-derived-mode biome-grid-mode tabulated-list-mode "Biome Grid"
|
(define-derived-mode biome-grid-mode tabulated-list-mode "Biome Grid"
|
||||||
"Major mode for displaying biome results."
|
"Major mode for displaying biome results.")
|
||||||
(setq-local truncate-lines t))
|
|
||||||
|
|
||||||
(defun biome-grid--format-entries (entries unit)
|
(defun biome-grid--blend-colors (c1 c2 val)
|
||||||
(mapcar
|
"Blend colors C1 and C2 by VAL.
|
||||||
(lambda (entry)
|
|
||||||
(if (stringp entry)
|
|
||||||
entry
|
|
||||||
(prin1-to-string entry)))
|
|
||||||
entries))
|
|
||||||
|
|
||||||
(defun biome-grid--get-width (entries col-name)
|
C1 and C2 are hex RGS strings, VAL is a number between 0 and 1."
|
||||||
(cl-loop for entry in (cons col-name entries)
|
(let ((color1 (ct-get-rgb c1))
|
||||||
maximize (length entry)))
|
(color2 (ct-get-rgb c2)))
|
||||||
|
(apply #'ct-make-rgb
|
||||||
|
(cl-loop for v1 in color1
|
||||||
|
for v2 in color2
|
||||||
|
collect (+ (* (- 1 val) v1) (* val v2))))))
|
||||||
|
|
||||||
|
(defun biome-grid--format-gradient (value def col-width)
|
||||||
|
(let* ((background-color
|
||||||
|
(cl-loop for (border1 . color1) in def
|
||||||
|
for (border2 . color2) in (cdr def)
|
||||||
|
if (< value border1) return color1
|
||||||
|
if (and (>= value border1) (<= value border2))
|
||||||
|
return (biome-grid--blend-colors
|
||||||
|
color1 color2 (/ (- value border1) (- border2 border1)))
|
||||||
|
finally return color2))
|
||||||
|
(foreground-color (if (ct-light-p background-color 65) "#000000" "#ffffff")))
|
||||||
|
(propertize
|
||||||
|
(format (format "%%%ds" col-width) value)
|
||||||
|
'face `(:background ,background-color :foreground ,foreground-color))))
|
||||||
|
|
||||||
|
(defun biome-grid--format-entries (entries unit col-width)
|
||||||
|
(let ((format-def (alist-get unit biome-grid-format-units nil nil #'equal)))
|
||||||
|
(mapcar
|
||||||
|
(lambda (entry)
|
||||||
|
(cond
|
||||||
|
((stringp entry) entry)
|
||||||
|
((eq (car-safe format-def) 'gradient)
|
||||||
|
(biome-grid--format-gradient entry (cdr format-def) col-width))
|
||||||
|
(t (prin1-to-string entry))))
|
||||||
|
entries)))
|
||||||
|
|
||||||
(defun biome-grid--set-list (query results)
|
(defun biome-grid--set-list (query results)
|
||||||
(let* ((group (intern (alist-get :group query)))
|
(let* ((group (intern (alist-get :group query)))
|
||||||
|
|
@ -56,13 +104,16 @@
|
||||||
(var-names (biome-query--get-var-names-cache))
|
(var-names (biome-query--get-var-names-cache))
|
||||||
all-entries columns)
|
all-entries columns)
|
||||||
(cl-loop for (key . values) in (alist-get group results)
|
(cl-loop for (key . values) in (alist-get group results)
|
||||||
for unit = (alist-get key (alist-get group-units results))
|
for unit = (replace-regexp-in-string
|
||||||
|
(regexp-quote "%") "%%"
|
||||||
|
(alist-get key (alist-get group-units results)))
|
||||||
for var-name = (biome-query--get-header (symbol-name key) var-names)
|
for var-name = (biome-query--get-header (symbol-name key) var-names)
|
||||||
for col-name = (if biome-grid-display-units
|
for col-name = (if biome-grid-display-units
|
||||||
(format "%s (%s)" var-name unit)
|
(format "%s (%s)" var-name unit)
|
||||||
var-name)
|
var-name)
|
||||||
for entries = (biome-grid--format-entries values unit)
|
for col-width = (cl-loop for entry in (cons col-name entries)
|
||||||
for col-width = (biome-grid--get-width entries col-name)
|
maximize (+ 0 (length entry)))
|
||||||
|
for entries = (biome-grid--format-entries values unit col-width)
|
||||||
do (push (list col-name col-width nil) columns)
|
do (push (list col-name col-width nil) columns)
|
||||||
do (push entries all-entries))
|
do (push entries all-entries))
|
||||||
(setq-local
|
(setq-local
|
||||||
|
|
@ -82,11 +133,13 @@
|
||||||
|
|
||||||
(defun biome-grid (query results)
|
(defun biome-grid (query results)
|
||||||
"Display RESULTS in a grid."
|
"Display RESULTS in a grid."
|
||||||
|
(setq my/test results)
|
||||||
(let ((buf (generate-new-buffer "*biome-grid*")))
|
(let ((buf (generate-new-buffer "*biome-grid*")))
|
||||||
(with-current-buffer buf
|
(with-current-buffer buf
|
||||||
(biome-grid--set-list query results)
|
(biome-grid--set-list query results)
|
||||||
(biome-grid-mode))
|
(biome-grid-mode)
|
||||||
(display-buffer buf #'display-buffer-same-window)))
|
(toggle-truncate-lines 1))
|
||||||
|
(switch-to-buffer buf)))
|
||||||
|
|
||||||
(provide 'biome-grid)
|
(provide 'biome-grid)
|
||||||
;;; biome-grid.el ends here
|
;;; biome-grid.el ends here
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,8 @@ value will be inserted."
|
||||||
:group 'biome)
|
:group 'biome)
|
||||||
|
|
||||||
(defcustom biome-query-coords '(("Helsinki, Finland" 60.16952 24.93545)
|
(defcustom biome-query-coords '(("Helsinki, Finland" 60.16952 24.93545)
|
||||||
("Berlin, Germany" 52.52437 13.41053))
|
("Berlin, Germany" 52.52437 13.41053)
|
||||||
|
("Dubai, UAE" 25.0657 55.17128))
|
||||||
"List of locations with their coordinates.
|
"List of locations with their coordinates.
|
||||||
|
|
||||||
The format is: (name latitude longitude)."
|
The format is: (name latitude longitude)."
|
||||||
|
|
@ -99,6 +100,9 @@ case, the value is a list of variable names available in the group.")
|
||||||
(defvar biome-query--var-names-cache nil
|
(defvar biome-query--var-names-cache nil
|
||||||
"Cache for variable names.")
|
"Cache for variable names.")
|
||||||
|
|
||||||
|
(defvar biome-query--callback nil
|
||||||
|
"Call this with the selected query.")
|
||||||
|
|
||||||
;; TODO delete this
|
;; TODO delete this
|
||||||
(setq biome-query--layout-cache (make-hash-table :test 'equal))
|
(setq biome-query--layout-cache (make-hash-table :test 'equal))
|
||||||
|
|
||||||
|
|
@ -880,6 +884,13 @@ SUFFIXES is a list of suffix definitions."
|
||||||
(:group . ,(caar (biome-query--section-groups biome-query--current-section)))
|
(:group . ,(caar (biome-query--section-groups biome-query--current-section)))
|
||||||
(:params . nil)))))
|
(:params . nil)))))
|
||||||
|
|
||||||
|
(defun biome-query--on-return ()
|
||||||
|
"Process the query made by `biome-query'."
|
||||||
|
(interactive)
|
||||||
|
(unless biome-query--callback
|
||||||
|
(user-error "Biome-query--callback is not set"))
|
||||||
|
(funcall biome-query--callback biome-query-current))
|
||||||
|
|
||||||
(transient-define-prefix biome-query--section (section &optional parents)
|
(transient-define-prefix biome-query--section (section &optional parents)
|
||||||
"Render transient for SECTION.
|
"Render transient for SECTION.
|
||||||
|
|
||||||
|
|
@ -897,6 +908,7 @@ SECTION is a form as defined in `biome-api-parse--page'."
|
||||||
(biome-query--section-layout section parents)
|
(biome-query--section-layout section parents)
|
||||||
`(["Actions"
|
`(["Actions"
|
||||||
:class transient-row
|
:class transient-row
|
||||||
|
("RET" "Run" biome-query--on-return)
|
||||||
("q" "Up" transient-quit-one)
|
("q" "Up" transient-quit-one)
|
||||||
("Q" "Quit" transient-quit-all)
|
("Q" "Quit" transient-quit-all)
|
||||||
,(unless parents
|
,(unless parents
|
||||||
|
|
@ -906,7 +918,7 @@ SECTION is a form as defined in `biome-api-parse--page'."
|
||||||
(:parents . ,parents))))
|
(:parents . ,parents))))
|
||||||
(put 'biome-query-section 'transient--layout nil)))
|
(put 'biome-query-section 'transient--layout nil)))
|
||||||
|
|
||||||
(transient-define-prefix biome-query ()
|
(transient-define-prefix biome-query (callback)
|
||||||
["Open Meteo Data"
|
["Open Meteo Data"
|
||||||
:setup-children
|
:setup-children
|
||||||
(lambda (_)
|
(lambda (_)
|
||||||
|
|
@ -925,7 +937,12 @@ SECTION is a form as defined in `biome-api-parse--page'."
|
||||||
(biome-query--section ',params))
|
(biome-query--section ',params))
|
||||||
:transient transient--do-replace))))]
|
:transient transient--do-replace))))]
|
||||||
["Actions"
|
["Actions"
|
||||||
("q" "Quit" transient-quit-one)])
|
("q" "Quit" transient-quit-one)]
|
||||||
|
(interactive (list nil))
|
||||||
|
(unless callback
|
||||||
|
(error "Callback is not set. Run M-x `biome' instead"))
|
||||||
|
(setq biome-query--callback callback)
|
||||||
|
(transient-setup 'biome-query))
|
||||||
|
|
||||||
(provide 'biome-query)
|
(provide 'biome-query)
|
||||||
;;; biome-query.el ends here
|
;;; biome-query.el ends here
|
||||||
|
|
|
||||||
22
biome.el
22
biome.el
|
|
@ -5,7 +5,7 @@
|
||||||
;; Author: Korytov Pavel <thexcloud@gmail.com>
|
;; Author: Korytov Pavel <thexcloud@gmail.com>
|
||||||
;; Maintainer: Korytov Pavel <thexcloud@gmail.com>
|
;; Maintainer: Korytov Pavel <thexcloud@gmail.com>
|
||||||
;; Version: 0.1.0
|
;; Version: 0.1.0
|
||||||
;; Package-Requires: ((emacs "27.1"))
|
;; Package-Requires: ((emacs "27.1") (transient "0.3.7") (ct "0.2") (request "0.3.3") (compat "29.1.4.1"))
|
||||||
;; Homepage: https://github.com/SqrtMinusOne/biome
|
;; Homepage: https://github.com/SqrtMinusOne/biome
|
||||||
|
|
||||||
;; This file is NOT part of GNU Emacs.
|
;; This file is NOT part of GNU Emacs.
|
||||||
|
|
@ -28,9 +28,29 @@
|
||||||
;; TODO
|
;; TODO
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
(require 'biome-api)
|
||||||
|
(require 'biome-query)
|
||||||
|
(require 'biome-grid)
|
||||||
|
|
||||||
(defgroup biome nil
|
(defgroup biome nil
|
||||||
"Bountiful Interface to Open Meteo for Emacs."
|
"Bountiful Interface to Open Meteo for Emacs."
|
||||||
:group 'applications)
|
:group 'applications)
|
||||||
|
|
||||||
|
(defcustom biome-frontend #'biome-grid
|
||||||
|
"The frontend to use for displaying the data.
|
||||||
|
|
||||||
|
This has to be a function that receives two arguments: query (as
|
||||||
|
defined by `biome-query-current' and the response of the open-meteo
|
||||||
|
API."
|
||||||
|
:type 'function
|
||||||
|
:group 'biome)
|
||||||
|
|
||||||
|
(defun biome ()
|
||||||
|
"Bountiful Interface to Open Meteo for Emacs."
|
||||||
|
(interactive)
|
||||||
|
(biome-query
|
||||||
|
(lambda (query)
|
||||||
|
(biome-api-get query biome-frontend))))
|
||||||
|
|
||||||
(provide 'biome)
|
(provide 'biome)
|
||||||
;;; biome.el ends here
|
;;; biome.el ends here
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue