# Why Lua is cool

**URL:** https://community.silverbullet.md/t/why-lua-is-cool/2018
**Category:** Lua
**Created:** [March 21, 2025, 4:10pm UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018 "2025-03-21T16:10:37Z")
**Posts on this page:** 19
**Page:** 1

<div class="post-metadata">

### Author: ![zef](https://community.silverbullet.md/user_avatar/community.silverbullet.md/zef/32/7_2.png) [@zef](https://community.silverbullet.md/u/zef)
#### Post date: [March 21, 2025, 4:10pm UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/1 "2025-03-21T16:10:37Z")

</div>

Not production ready but here’s the essence of the [Git plug](http://github.com/silverbulletmd/silverbullet-git) reimplemented in Lua:

````auto
```space-lua
git = {}

function git.commit(message)
  message = message or "Snapshot"
  print "Comitting..."
  shell.run("git", {"add", "./*"})
  shell.run("git", {"commit", "-a", "-m", message})
end

function git.sync()
  git.commit()
  print "Pulling..."
  shell.run("git", {"pull"})
  print "Pushing..."
  shell.run("git", {"push"})
end

command.define {
  name = "Git: Commit",
  run = function()
    local message = editor.prompt "Commit message:"
    git.commit(message)
  end
}

command.define {
  name = "Git: Sync",
  run = function()
    git.sync()
    editor.flashNotification "Done!"
  end
}
```

````

Isn’t that beautiful? (The answer is “Yes”)

---

<div class="post-metadata">

### Author: ![dklawren](https://community.silverbullet.md/user_avatar/community.silverbullet.md/dklawren/32/14_2.png) [@dklawren](https://community.silverbullet.md/u/dklawren)
#### Post date: [March 21, 2025, 4:16pm UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/2 "2025-03-21T16:16:01Z")

</div>

Will the Lua support eventually have a way to do the autocommit portion every 5 mins as well? Is there some sort of internal timer event that the Lua code could add a listener for?

---

<div class="post-metadata">

### Author: ![zef](https://community.silverbullet.md/user_avatar/community.silverbullet.md/zef/32/7_2.png) [@zef](https://community.silverbullet.md/u/zef)
#### Post date: [March 21, 2025, 4:17pm UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/3 "2025-03-21T16:17:30Z")

</div>

Yeah, this is next on my list for exactly this use case 😉 I have to figure out an API for this.

---

<div class="post-metadata">

### Author: ![zef](https://community.silverbullet.md/user_avatar/community.silverbullet.md/zef/32/7_2.png) [@zef](https://community.silverbullet.md/u/zef)
#### Post date: [March 21, 2025, 4:22pm UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/4 "2025-03-21T16:22:30Z")

</div>

What do you think about simply having a `cron:second` event that triggers every second (obviously)? It’s then possible to build fancier abstractions on top of that (like a proper cron scheduler).

---

<div class="post-metadata">

### Author: ![LumenYoung](https://community.silverbullet.md/user_avatar/community.silverbullet.md/lumenyoung/32/368_2.png) [@LumenYoung](https://community.silverbullet.md/u/LumenYoung)
#### Post date: [March 21, 2025, 4:26pm UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/5 "2025-03-21T16:26:55Z")

</div>

Ah, the beautiful Lua…

saved me the headache trying to understand the obscure javascript syntax. Another neovim user arrives at his comfort zone. 🥳

---

<div class="post-metadata">

### Author: ![zef](https://community.silverbullet.md/user_avatar/community.silverbullet.md/zef/32/7_2.png) [@zef](https://community.silverbullet.md/u/zef)
#### Post date: [March 21, 2025, 4:35pm UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/6 "2025-03-21T16:35:47Z")

</div>

This stuff will only make it to the `v2` branch, but:

```auto
local secondsPassed = 0
event.listen {
  name = "cron:secondPassed",
  run = function()
    secondsPassed = secondsPassed + 1
    if secondsPassed % 60 == 20 then
      print "Comittin' time"
      git.sync()
    end
  end
}

```

---

<div class="post-metadata">

### Author: ![dklawren](https://community.silverbullet.md/user_avatar/community.silverbullet.md/dklawren/32/14_2.png) [@dklawren](https://community.silverbullet.md/u/dklawren)
#### Post date: [March 21, 2025, 4:53pm UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/7 "2025-03-21T16:53:33Z")

</div>

Sounds good. Seems secondsPassed could grow to some large number if one doesn’t ‘System: Reload’ or reindex from time to time but maybe that is a non-issue.

---

<div class="post-metadata">

### Author: ![zef](https://community.silverbullet.md/user_avatar/community.silverbullet.md/zef/32/7_2.png) [@zef](https://community.silverbullet.md/u/zef)
#### Post date: [March 21, 2025, 5:19pm UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/8 "2025-03-21T17:19:06Z")

</div>

Well that was just an example. You can always reset the counter every minute 😆

---

<div class="post-metadata">

### Author: ![dklawren](https://community.silverbullet.md/user_avatar/community.silverbullet.md/dklawren/32/14_2.png) [@dklawren](https://community.silverbullet.md/u/dklawren)
#### Post date: [March 21, 2025, 6:47pm UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/9 "2025-03-21T18:47:13Z")

</div>

Duh. Should have thought of that 🙂

---

<div class="post-metadata">

### Author: ![janssen-io](https://community.silverbullet.md/user_avatar/community.silverbullet.md/janssen-io/32/1155_2.png) [@janssen-io](https://community.silverbullet.md/u/janssen-io)
#### Post date: [March 21, 2025, 8:43pm UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/10 "2025-03-21T20:43:05Z")

</div>

You could also just look at the local time and see if it’s a multiple of _x_ 🙂

Why keep a timer if you already have a clock 😃 Unless the time since first load is important of course. But then you could also just store that and subtract it from the clock.

---

<div class="post-metadata">

### Author: ![justyns](https://community.silverbullet.md/user_avatar/community.silverbullet.md/justyns/32/132_2.png) [@justyns](https://community.silverbullet.md/u/justyns)
#### Post date: [March 23, 2025, 12:00am UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/11 "2025-03-23T00:00:19Z")

</div>

It is pretty cool, I was able to whip up a quick “stream llm chat to editor” lua script with working streaming.

```lua
local openaiLib = js.import("https://esm.sh/openai@4.89.0")
local openaiClient = js.new(openaiLib.OpenAI, {apiKey=apiKey, dangerouslyAllowBrowser=true})

function streamCompletionIntoEditor2(messages)
  local startPos = string.len(editor.getText())
  local resp = openaiClient.chat.completions.create({
    model = "gpt-4o",
    stream = true,
    messages = js.tojs(messages)})
  local fullResponse = "\n **Assistant** : "
  editor.insertAtPos(fullResponse, startPos)
  for value in js.eachIterable(resp) do
    local newDelta = value.choices[1].delta.content
    if newDelta ~= "" and newDelta ~= nil then
      editor.insertAtPos(newDelta, startPos + string.len(fullResponse))
      fullResponse = fullResponse + newDelta
    end
  end
  editor.insertAtPos("\n **User** : ", startPos + string.len(fullResponse))
  editor.moveCursor(startPos + string.len(fullResponse) + string.len("\n **User** : "), true)
end

```

Definitely missing features (and cheating by using an external lib), but I wasn’t expecting it to be so easy either 🙂

---

<div class="post-metadata">

### Author: ![zef](https://community.silverbullet.md/user_avatar/community.silverbullet.md/zef/32/7_2.png) [@zef](https://community.silverbullet.md/u/zef)
#### Post date: [March 23, 2025, 3:14pm UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/12 "2025-03-23T15:14:21Z")

</div>

@justyns I have been building something very similar as a toy thing to stress test Lua. Will share it later. I also implemented (streaming chat) and a few other nice things.

---

<div class="post-metadata">

### Author: ![zef](https://community.silverbullet.md/user_avatar/community.silverbullet.md/zef/32/7_2.png) [@zef](https://community.silverbullet.md/u/zef)
#### Post date: [March 31, 2025, 5:55pm UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/13 "2025-03-31T17:55:15Z")

</div>

Ok, finally posted it: [silverbullet-assistant.md · GitHub](https://gist.github.com/zefhemel/62ae5957d8e91d3d32c54bb5d33a0e6e)

Still very much WIP but you get the idea.

---

<div class="post-metadata">

### Author: ![username\_smusername](https://community.silverbullet.md/letter_avatar_proxy/v4/letter/u/b3f665/32.png) [@username\_smusername](https://community.silverbullet.md/u/username_smusername)
#### Post date: [April 1, 2025, 9:18am UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/14 "2025-04-01T09:18:46Z")

</div>

I’m a little late to the party, but maybe there could be an API callback function

```auto
function setCallback(who: function, when: number)

```

Sort of thing? The _every 5 minute_ function could be a simple:

1. Call git.sync
2. Call setCallback(me, 60\*5)

---

<div class="post-metadata">

### Author: ![zef](https://community.silverbullet.md/user_avatar/community.silverbullet.md/zef/32/7_2.png) [@zef](https://community.silverbullet.md/u/zef)
#### Post date: [April 1, 2025, 10:44am UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/15 "2025-04-01T10:44:16Z")

</div>

This would effectively be the same as listening to the `cron:secondPassed` event (which now exists on #v2) and doing a little math on it, right?

---

<div class="post-metadata">

### Author: ![username\_smusername](https://community.silverbullet.md/letter_avatar_proxy/v4/letter/u/b3f665/32.png) [@username\_smusername](https://community.silverbullet.md/u/username_smusername)
#### Post date: [April 2, 2025, 9:33am UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/16 "2025-04-02T09:33:05Z")

</div>

Assuming that listening to `cron:secondPassed` causes a callback every second, no I was thinking more of SilverBullet’s plug manager or someone having a list of who wants to be called and when, allowing for just one callback that runs every second instead of one per plug.

But I guess my idea trades off fewer per second function calls for a single point of failure.

And that’s assuming I’ve not wildly misunderstood `cron:secondPassed`’s behaviour

---

<div class="post-metadata">

### Author: ![indadev](https://community.silverbullet.md/user_avatar/community.silverbullet.md/indadev/32/1233_2.png) [@indadev](https://community.silverbullet.md/u/indadev)
#### Post date: [April 15, 2025, 12:35pm UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/17 "2025-04-15T12:35:52Z")

</div>

First thanks for silvrbullet I really like 😃  
One question about the event, what happens when I close silverbullet, the events are launching while is closed? or is only working when the client is open?

I was want to do something that is launched in cron when silverbullet is closed.  
I wanted to do:  
Each morning read a list of objects generate a promt feed to an AI and sent a email/telebran bot message or something like that.

Thanks

---

<div class="post-metadata">

### Author: ![zef](https://community.silverbullet.md/user_avatar/community.silverbullet.md/zef/32/7_2.png) [@zef](https://community.silverbullet.md/u/zef)
#### Post date: [April 15, 2025, 2:51pm UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/18 "2025-04-15T14:51:41Z")

</div>

Events only trigger when the client is open and active (browsers even stop scheduling events, or at least delay them when a tab or window isn’t active). At least this is how it works in Sync mode and in #v2, no real way around that. In v1, since Lua code also runs on the server, your client doesn’t need to be active.

---

<div class="post-metadata">

### Author: ![indadev](https://community.silverbullet.md/user_avatar/community.silverbullet.md/indadev/32/1233_2.png) [@indadev](https://community.silverbullet.md/u/indadev)
#### Post date: [April 15, 2025, 9:04pm UTC](https://community.silverbullet.md/t/why-lua-is-cool/2018/19 "2025-04-15T21:04:28Z")

</div>

I thought so, thanks a lot anyway
