Skip to content

Utility function to handle empty query results and templates #1386

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 12, 2025

Conversation

Maarrk
Copy link
Contributor

@Maarrk Maarrk commented May 8, 2025

More general implementation of #1359

This also documents current workaround for #1343

@zefhemel
Copy link
Collaborator

zefhemel commented May 8, 2025

Hmm. Need to think if the bug isn't really the incompatibility with Lua here. Not sure if we should double down on this being useful.

I'd rather make this lua constituent otherwise we're just asking for future trouble.

Copy link
Contributor

@wbhouston wbhouston left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will be a nice change! I added some minor comments.

@@ -127,10 +129,17 @@ There's a magic `_CTX` global variable available from which you can access usefu
# Lua implementation notes
Space Lua is intended to be a more or less complete implementation of [Lua 5.4](https://www.lua.org/manual/5.4/). However, a few features are (still) missing:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the lead in here should be more inclusive of the following headers. Maybe:

Here are some of the expected differences and planned and not planned features:

* _ENV (planned)
* Full metatable support (only partial now, planned)
## Differences
* empty table `{}` tests false, while in [Lua 5.4](https://www.lua.org/manual/5.4/manual.html#3.3.4) "All values different from **nil** nad **false** test true". However this has a really nice interaction with empty [[Space Lua/Lua Integrated Query|query]] results
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo on nad in the docs quote.

## Planned
* _ENV
* Full [metatable](https://www.lua.org/manual/5.4/manual.html#2.4) support (only partial now)
* Complete [[API/string]] API (some patterns in `gmatch` don’t work correctly)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a section to [[API/string]] about how Lua patterns and Space Lua patterns have some key differences, not just for gmatch. What do you think about removing:

(some patterns in gmatch don’t work correctly)

and adding a bullet to the Differences section above, maybe:

  • lua patterns are translated to Javascript regex, so there are some [[API/string|key differences]].

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably same comment applies as the empty table truthiness. See link in #1284, maybe we can actually get 100% compatibility?

@Maarrk
Copy link
Contributor Author

Maarrk commented May 8, 2025

Hmm. Need to think if the bug isn't really the incompatibility with Lua here. Not sure if we should double down on this being useful.

I'd rather make this lua constituent otherwise we're just asking for future trouble.

Essentially we would like to have some behavior like ?? operator. A Lua-compatible solution would be to add a function that checks for truthiness in a different way, appropriate for content:

```space-lua
function some(value)
  if type(value) == "table" then
    -- if next(value) == nil then return nil end
    -- The above is supposed to work, but let's use pairs in this example:
    for k, v in pairs(value) do
      return value
    end
    return nil
  end
  if value == "" then return nil end
  return value
end
```

${some(1) or "*no result*"}
${some(0) or "*no result*"}
${some("text") or "*no result*"}
${some("") or "*no result*"}
${some({}) or "*no result*"}
${some({1, 2}) or "*no result*"}
${some({[2]=1})}
${some({foo="bar"}) or "*no result*"}

image

I'll keep in mind that we're aiming for full Lua compatibility. Then a fully Lua-compatible way would be ${some(query[[ ... ]]) or "No results"}. I'd say to suggest this use in the documentation, this should be always available. I'm happy to add something like this to standard library, but I'd like a comment from @zefhemel on the name. I went with some(), because this pattern reminded me of Some in Rust, and its unwrap_or method. But there ought to be some monadic wisdom to name it better 😝


Yet another conformant solution could be to use metatables to override an operation on the query result. By setting our custom method for __bxor we'd have syntax like:

${query[[ ... ]] ~ "no results"}

I don't have a strong opinion on which operator to use, I went with XOR because "only one of the inputs is true"

This would be completely normal Lua, and even shorter syntax than now (by 1 character xD). I'm not worried about making query function inconsistent with expectations, since it already has special parsing rules, but it may confuse new users as to what ~ operator does. On the other hand, maybe them knowing about metatables is helpful for their own scripts?

Bonus: Maybe this would be a path for composing queries together using some other overridable operators? Like ${query[[ ]] .. query[[ ]]} to make them into a single table with columns and rows from both...

@Maarrk Maarrk marked this pull request as draft May 8, 2025 14:17
@zefhemel
Copy link
Collaborator

zefhemel commented May 8, 2025

I like the some name and approach. I wouldn't do weird metatable operator hacks (for now). I think being as Lua-y as reasonable is a good way to bring people in and to also allow them to use gained skills in other Lua environments.

Moved documentation for 'each' function to non-standard section.
@Maarrk Maarrk changed the title Describe more Lua FAQ: template escaping and empty query results Utility function to handle empty query results and templates May 10, 2025
@Maarrk Maarrk marked this pull request as ready for review May 10, 2025 21:12
@Maarrk
Copy link
Contributor Author

Maarrk commented May 10, 2025

The scope has changed a bit, but I thought that it's better to just reorganize this PR to keep the discussion about possible options.

I think this is a more elegant solution, are we OK to remove #1359? Everyone is supposed to know this is unstable version, and I don't recall any changelog or forum talk about that feature.

@zefhemel
Copy link
Collaborator

Very nice. I like this solution. And indeed I hope/assume people will not have used the extra template.each argument yet, and if so they'll figure it out 😄

@zefhemel zefhemel merged commit f2f4937 into silverbulletmd:main May 12, 2025
1 check passed
@Maarrk Maarrk deleted the pr-lua-faq branch May 15, 2025 16:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants