Finding: Silverbullet's lua `query[[ ]]` string allow direct variable interpolation!

Just realized that in silverbullet flavour lua you can do direct variable interpolation inside a [[]] block. Found when I was playing around with the widgets from the following widget example in the doc.

function widgets.linkedTasks(pageName)
  pageName = pageName or editor.getCurrentPage()
  local tasks = query[[
    from index.tag "task"
    where not _.done
      and string.find(_.name, "[[" .. pageName .. "]]", 1, true)
  ]]
  local md = ""
  if #tasks > 0 then
    md = "### Linked Tasks\n"
       .. template.each(tasks, templates.taskItem)
  else
    md = ""
  end
  return widget.new {
    markdown = md
  }
end

This string.find() inside the [[]] string block is not a standard lua behavior if I understood correclty, which is pretty cool and confusing at the same time.

:wink: You never know what magic zef has left inside his lua interpreter.

2 Likes

This only works in queries as the Lua-expression is part of the query string.
So it’s not really interpolated, but it is interpreted when the query is executed.

This, for example, wouldn’t work:

local name = "Parent/Child"
local pageName = "Child"
local myString = [[ Found: string.find(name, "[[" .. pageName .. "]]", 1, true) ]]

Nevertheless, still a very useful feature of the Lua Integrated Queries! :slight_smile:

Yes this is correct. This is a feature of integrated query language which is not part of Lua itself (although syntactically it’s compatible). This can indeed be a bit confusing.

Initially I was confused by your use of the term “string interpolation”. Generally this is referring to the ability to “escape” out of a string literal and inject some expression value. Like in JS with the backtick syntax (and there is a Space Lua API that also has this but let me not confuse you more).

This is not that, although it may look similar. I can elaborate more later when I have more time.

There is nothing special about string.find or [[ there. The only surprising thing may be that you can refer to the pageName variable that is part of the local function scope. That may seem surprising because this whole query block looks like a string (but isn’t).