notesy::events
What happens in notesy, as it happens. A script subscribes to the events it wants, one by one or a whole kind at once, and its handler is called for each, one at a time, in order.
rustuse notesy::{events, log, Event};
pub fn ready() {
events::on(Event::NoteSaved, |event| log::info(`saved ${event.path}`));
events::on(Event::AnyNote, |event| log::info(event.name));
}
| Function | What it does |
|---|---|
events::on(event, handler) |
Calls handler(event) for every event event covers: one of Event's below. |
events::off(event) |
Forgets every handler added for it. |
Event is notesy's list of what a script can hear, so a name that's wrong
doesn't compile, and an editor that knows Rune can offer the rest. (A name
as text, "note.saved" or "note.*", still works too, checked as the
script runs.)
Hearing about notes takes the notes.read permission: every note and vault
event, and Event::SecondInstance, need it. Subscribing to one without it
doesn't stop the script; the refusal goes to its log and the handler never
runs.
#Events
Every event reaches the handler as an object with its name (the text
form) and the fields below. Paths are relative to the vault, with /
between folders.
Event:: |
name |
Fields | When | Needs |
|---|---|---|---|---|
AppReady |
app.ready |
notesy is up, with its plugins loaded | ||
SecondInstance |
app.second_instance |
args (list of strings), cwd |
notesy was started again while running; that start's arguments and folder | notes.read |
VaultOpened |
vault.opened |
name_of_vault |
a vault was opened | notes.read |
NoteOpened |
note.opened |
path |
a note was opened in a tab | notes.read |
NoteClosed |
note.closed |
path |
a note's tab was closed | notes.read |
NoteChanged |
note.changed |
path |
its text changed; a few times a second at most while typing | notes.read |
NoteSaved |
note.saved |
path |
it was saved | notes.read |
NoteCreated |
note.created |
path |
a new note | notes.read |
NoteRenamed |
note.renamed |
from, to |
it was renamed or moved | notes.read |
NoteDeleted |
note.deleted |
path |
it was deleted | notes.read |
ThemeChanged |
theme.changed |
id, dark (bool) |
the theme changed | |
CommandRan |
command.ran |
id |
a command ran: its id, like plugin.you.saves.sync |
|
SidebarItem |
sidebar.item |
section, item |
an item in one of its sidebar sections was clicked: section is the key it gave sections::add, item the item's id. Only the plugin whose section it is hears it. |
And each kind at once:
Event:: |
Covers |
|---|---|
AnyApp |
app.ready and app.second_instance (app.*) |
AnyVault |
vault.opened (vault.*) |
AnyNote |
every note. event (note.*) |
Each event object also has its kind, an Event, to match on:
rustuse notesy::{events, log, Event};
pub fn ready() {
events::on(Event::AnyNote, |event| {
match event.kind {
Event::NoteSaved => log::info(`saved ${event.path}`),
Event::NoteDeleted => log::info(`gone: ${event.path}`),
_ => {}
}
});
}
#Its own events
A big plugin's parts can talk without calling each other: a channel of its own carries events from one part to every part listening. Needs nothing.
rustuse notesy::{events, log};
pub fn ready() {
let sync = events::channel("sync");
sync.on(|done| log::info(`${done.notes} notes synced`));
sync.emit(#{ notes: 12 });
}
| Function | What it does |
|---|---|
events::channel(name) |
One of its own channels, by a name of its own (lowercase letters, digits, -, _, .). |
channel.on(handler) |
handler(value) for everything emitted on it. |
channel.emit(value) |
Sends value, plain data (numbers, text, lists and objects of those), to its handlers: after what's running now, in the order it was sent. |
channel.off() |
Forgets every handler on it. |
A channel is its plugin's alone: no other plugin hears it. At most 1,024
events wait on its channels at once; past that, emit is an error.
#Other plugins
Plugins talk to each other only when both say so. One shares, under names
of its own, with the plugins.share permission; one that wants to hear it
names it in its plugin.toml ([plugins] hears = ["ana.sync"], see
plugin.toml), which asks the user for that
too. When they approve it they see what each plugin it hears can do, and a
plugin that hears one that's since been allowed more stops until they look
again.
rustuse notesy::events;
// In Sync, which has plugins.share.
pub fn ready() {
let synced = events::share("synced");
synced.emit(#{ notes: 12, at: "2026-09-12" });
}
rustuse notesy::{events, log};
// In Board, whose plugin.toml has [plugins] hears = ["ana.sync"].
pub fn ready() {
events::from("ana.sync", "synced").on(|done| log::info(`Sync did ${done.notes} notes`));
}
| Function | What it does |
|---|---|
events::share(name) |
What it shares under name (lowercase letters, digits, -, _, .). Needs plugins.share. |
share.emit(value) |
Sends value, plain data, to every running plugin that hears it, after what's running there now. At most 20 a second, of 64 KB each; past that, emit is an error. |
events::from(plugin, name) |
What plugin shares under name: one its [plugins] hears names. |
heard.on(handler) |
handler(value) for everything it shares under that name. |
heard.off() |
Forgets every handler on it. |
A plugin that isn't running hears nothing, and nothing's kept for one that starts later.
#Ordering and dropping
Events wait in a queue for each plugin: up to 512. A plugin that falls that far behind loses the oldest (its log says how many), never a lifecycle call (Scripts).
Every page
- Overview
- plugin.toml: Every field of plugin.toml
- Permissions: What a plugin can ask for, when notesy asks, and what changes it
- Scripts: How a script runs: its lifecycle, events, limits and errors
- Packing and installing: Making, checking, signing, packing and installing
- notesy::log: Lines for its log on the Plugins page
- notesy::events: Hearing what happens, and every event
- notesy::commands: Adding commands, and running notesy's
- notesy::store: Keeping its own data
- notesy::settings: Reading its settings
- notesy::secrets: Keys and tokens, in the system keychain
- notesy::notes: Reading and changing the vault's notes
- notesy::editor: The note in front
- notesy::files: A folder of its own
- notesy::links: Opening pages in the browser
- notesy::clipboard: Copying and pasting
- notesy::view: What panels, tabs and sections show
- notesy::panels and notesy::views: Adding side panels and tabs
- notesy::sections: Sidebar sections
- notesy::menus: Items in notesy's right-click menus
- notesy::status: Status bar items
- notesy::notices: Notices
- notesy::dialogs: Asking in a dialog, notesy's kinds or its own
- notesy::cards: Its part of the tree's hover cards
- notesy::boards: Boards' cards and arrows, and kinds of card of its own
- notesy::blocks: Drawing its fenced blocks
- notesy::icons: Drawing its own icons
- notesy::net: Requests to the sites it names
- notesy::accounts: Signing in to a service
- notesy::json: Reading and writing JSON
- notesy::toml: Reading and writing TOML
- notesy::yaml: Reading and writing YAML, and a note's front matter
- notesy::time: Now, written in the user's time zone, dates read, how long ago
- notesy::math: Trigonometry and the like, for drawing
- Names: Icon, Color, Tone, Side, Method, Command, Menu, Sidebar, Event: Notesy's names as enums
- notesy::preview: Its own screens for notesy preview
- notesy::perf: Timing its own work
- notesy::tex: Math macros for every note's formulas