Closed ModProg closed 1 year ago
I somewhat implemented this as a widget, but due to there not being local variables it is not very readable:
(defwidget select_ranged [map value]
(box
(for entry in map
(literal :visible {
(matches(entry[0], "\\d+\\.\\.\\d+") && search(entry[0], "\\d+")[0] <= value && search(entry[0], "\\d+")[1] > value) ||
(matches(entry[0], "\\d+\\.\\.=\\d+") && search(entry[0], "\\d+")[0] <= value && search(entry[0], "\\d+")[1] >= value) ||
(matches(entry[0], "\\d+\\.\\.$") && search(entry[0], "\\d+")[0] <= value) ||
(matches(entry[0], "^\\.\\.\\d+") && search(entry[0], "\\d+")[1] > value) ||
(matches(entry[0], "^\\.\\.=\\d+") && search(entry[0], "\\d+")[1] >= value)}
:content {entry[1]}))))
I somewhat implemented this as a widget, but due to there not being local variables it is not very readable:
(defwidget select_ranged [map value] (box (for entry in map (literal :visible { (matches(entry[0], "\\d+\\.\\.\\d+") && search(entry[0], "\\d+")[0] <= value && search(entry[0], "\\d+")[1] > value) || (matches(entry[0], "\\d+\\.\\.=\\d+") && search(entry[0], "\\d+")[0] <= value && search(entry[0], "\\d+")[1] >= value) || (matches(entry[0], "\\d+\\.\\.$") && search(entry[0], "\\d+")[0] <= value) || (matches(entry[0], "^\\.\\.\\d+") && search(entry[0], "\\d+")[1] > value) || (matches(entry[0], "^\\.\\.=\\d+") && search(entry[0], "\\d+")[1] >= value)} :content {entry[1]}))))
This implementation doesn't actually work, due to #624
Actual working solution I'm using for now:
(defwidget select_ranged [map value ?template]
(box
(for entry in map
(literal :visible {
(matches(entry[0], "-?\\d+\\.\\.-?\\d+") && (search(entry[0], "-?\\d+")[0] == "null" ? 0 : search(entry[0], "-?\\d+")[0]) <= value && (search(entry[0], "-?\\d+")[1] == "null" ? 0 : search(entry[0], "-?\\d+")[1]) > value) ||
(matches(entry[0], "-?\\d+\\.\\.=-?\\d+") && (search(entry[0], "-?\\d+")[0] == "null" ? 0 : search(entry[0], "-?\\d+")[0]) <= value && (search(entry[0], "-?\\d+")[1] == "null" ? 0 : search(entry[0], "-?\\d+")[1]) >= value) ||
(matches(entry[0], "-?\\d+\\.\\.$") && (search(entry[0], "-?\\d+")[0] == "null" ? 0 : search(entry[0], "-?\\d+")[0]) <= value) ||
(matches(entry[0], "^\\.\\.-?\\d+") && (search(entry[0], "-?\\d+")[0] == "null" ? 0 : search(entry[0], "-?\\d+")[0]) > value) ||
(matches(entry[0], "^\\.\\.=-?\\d+") && (search(entry[0], "-?\\d+")[0] == "null" ? 0 : search(entry[0], "-?\\d+")[0]) >= value)}
:content {template == ""? entry[1] : replace(template, "\\{}", entry[1])}))))
The template is there as it is not a function but a widget and I therefor cannot wrap the returned value in another widget otherwise.
I implemented a proof of concept here: https://github.com/elkowar/eww/pull/628
This could be extended to support non-numeric ranges/values as well. I imagine a set of conditions that could work like so:
start?..(=?end)?
a range (open, exclusive/inclusive) proposed syntax matches rusts(==|(<|>)=?) value
compares the input as lhs using the operator to the value
(maybe allow both orders, i.e. value <=
as well)/regex/
compares the input to the regexcondition_a (&&|\|\|) condition_b
matches if the combined condition is true()
parenthesis can be used for precedenceAlternative syntaxes
[start,end]
, [start,end_exclusive)
, [start, end_exclusive[
or start - end
{} > 5
to mark where to place the compared valuematches("regex")
,
for and, and ;
for orI like this idea! In the long run, i wonder if it would make sense to have a case {x} of {pattern} => {value} {pattern} {value} ...
syntax.
I like this idea! In the long run, i wonder if it would make sense to have a
case {x} of {pattern} => {value} {pattern} {value} ...
syntax.
Would be interesting to consider syntax options. I tried to do this without adding a new language feature, but having actual syntax for this would maybe also help for readability.
Rust-like match would also be an option
match value {
== "value" => smth,
/regex/ => smth,
0..=10 => smth
}
This kind of plays into a bigger problem I have with the current simplexpr syntax and language... I kinda of really want to have lambdas, but simultaneously feel like it's already grown wayyy further than I should have let it, and adding higher order functions would make it even worse. I get that this sort of feature would be useful, but,... I'll be very careful adding any sort of magic syntax like this, for now, in hopes of finding a good general solution in the future
Yeah that's why I proposed the purely string based function that would not be adding a new syntax to the simpleexpr language.
I now added a function jq
that allows jq-style json processing, and should also support the string processing functionality there, through the slice operation .[2:10]
Description of the requested feature
A function that can take a json array and select the first matching entry.
I could imagine two things, a generic one that would be more useful but would also definitly increase complexity by quite a lot, maybe too much (would require something closure like):
More narrow solution and still quite powerful, take an array of tuples with the first being the range and the second being the returned value: An example of a Wi-Fi strength visualization. It will select the first entry where the range contains
wifi_strength
.Proposed configuration syntax
Add a new function to expressions
range_select
that takes an array and a value.The value is a number. The array contains tuples, with the first entry being a
Range
expression and the second being an arbitrary value that will be returned (array, object, string, ...).My proposed syntax for Range is Rusts:
start_inclusive..end_exclusive
andstart_inclusive..=end_exclusive
, with both ends being optional to create an open range, matching any value higher or lower than the specified limit, or any value if no limits are specified.There are also other possible range syntaxes
[start,end]
,[start,end_exclusive)
,[start, end_exclusive[
orstart - end
or we could even use<2
,4<=
for open ranges, I'm not fixated on one, as long as open ranges and exclusive ranges are supported.Additional context
It is currently possible to implement something like this, but it requires using a bunch of
?
expressions, which make it very complex and hard to read.An example of the current syntax: https://dharmx.is-a.dev/eww-powermenu/#battery