Skip to content

Commit

Permalink
refactoring, event parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
clpi committed Dec 29, 2024
1 parent 4cc953e commit 5306296
Show file tree
Hide file tree
Showing 70 changed files with 1,988 additions and 2,638 deletions.
2 changes: 1 addition & 1 deletion book/lua/module/examples/barebones.lua
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ J.data = {
J.config = {

---@brief The default directory you might want to specify for Jupyter notebooks to be stored in.
---@brief You may also wish to leverage the required "workspace" module to allow users to specify both
---@brief You may also wish to leverage the dep "workspace" module to allow users to specify both
---@brief a specific workspace tey would like to associate with Jupyter notebooks, as well as a default
---@brief relative directory within that workspace.
---
Expand Down
2 changes: 1 addition & 1 deletion book/lua/module/examples/basic.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ local M = mod.create("user.mod", {
M.setup = function()
return {
requires = {
---@brief required modules
---@brief dep modules
--- modules from builtin or custom
--- modules that can be loaded in (same as
--- if calling `require 'module'`) as a dependency
Expand Down
4 changes: 2 additions & 2 deletions book/src/modules/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ J.data = {
J.config = {

---@brief The default directory you might want to specify for Jupyter notebooks to be stored in.
---@brief You may also wish to leverage the required "workspace" module to allow users to specify both
---@brief You may also wish to leverage the dep "workspace" module to allow users to specify both
---@brief a specific workspace tey would like to associate with Jupyter notebooks, as well as a default
---@brief relative directory within that workspace.
---
Expand Down Expand Up @@ -153,7 +153,7 @@ local M = mod.create("user.example", {
M.setup = function()
return {
requires = {
---@brief required modules
---@brief dep modules
--- modules from builtin or custom
--- modules that can be loaded in (same as
--- if calling `require 'module'`) as a dependency
Expand Down
2 changes: 1 addition & 1 deletion book/src/modules/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ local M = mod.create("user.example", {
M.setup = function()
return {
requires = {
---@brief required modules
---@brief dep modules
--- modules from builtin or custom
--- modules that can be loaded in (same as
--- if calling `require 'module'`) as a dependency
Expand Down
3 changes: 2 additions & 1 deletion lua/down.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Down.default = {
-- ['data.log'] = {},
['lsp'] = {},
['cmd'] = {},
['data.link'] = {},
['link'] = {},
-- ['cmd.back'] = {},
-- ['data.history'] = {},
['tool.telescope'] = {},
Expand Down Expand Up @@ -59,6 +59,7 @@ end

function Down:post_load()
for _, l in pairs(self.mod.mods) do
self.event.load_cb(l)
l.post_load()
end
end
Expand Down
11 changes: 4 additions & 7 deletions lua/down/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,8 @@ end
local Config = {
--- Start in dev mode
dev = false,
log = {},
log_config = {
level = 'trace',
lvl = 0,
},

---@type down.log.Config
log = require 'down.util.log'.config,
workspace = {
default = vim.fn.getcwd(0),
},
Expand Down Expand Up @@ -100,7 +96,8 @@ function Config.setup(self, user, default, ...)
if self.started or not user or vim.tbl_isempty(user) then
return false
end
self.log = log.new(self.log_config, true)
log.new(self.log, false)
log.info("Config.setup: Log started")
user = vim.tbl_deep_extend('force', user, default)
self.user = vim.tbl_deep_extend('force', self.user, user)
if self.user.hook then
Expand Down
113 changes: 62 additions & 51 deletions lua/down/event/init.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
local log = require 'down.util.log'

---@type down.Event
---@class down.Event
local Event = {
topic = '',
type = '',
id = '',
ref = '',
split = {},
body = nil,
Expand All @@ -29,7 +28,7 @@ local Event = {
buf = vim.api.nvim_get_current_buf(),
win = vim.api.nvim_get_current_win(),
dir = vim.fn.getcwd(),
scope = "global"
scope = 'global',
},
}

Expand All @@ -38,35 +37,38 @@ local Event = {
local Cb = {
---@type table<string, { [1]: fun(event: down.Event, content: table|any), [2]?: fun(event: down.Event): boolean }>
cb = {},
}

---@type table<string, down.Event>
events = {},
}

--- @param ty? string
--- @return { [1]: fun(event: down.Event, content: table|any)> }
function Event:get_cb(ty)
return Cb.cb[ty or self.type]
return Cb.cb[ty or self.id]
end

--- Triggers a new callback to execute whenever an event of the requested type is executed.
--- @param self down.Event | string
--- @param cb fun(event: down.Event, content: table|any) The function to call whenever our event gets triggered.
--- @param filt? fun(event: down.Event): boolean # A filtering function to test if a certain event meets our expectations.
function Event.callback(self, cb, filt)
local ty = (self and self.type) or self
local ty = (self and self.id) or self
Cb.cb[ty] = Cb.cb[ty] or {}
table.insert(Cb.cb[ty], { cb, filt })
end

--- @param cb? fun(event: down.Event, content: table|any)
function Event:set_callback(cb)
Cb.cb[self.type] = Cb.cb[self.type] or {}
Cb.cb[self.type]:insert(cb)
function Event.set_callback(self, cb)
Cb.cb[self.id] = Cb.cb[self.id] or {}
table.insert(Cb.cb[self.id], cb)
end

--- Used internally by down to call all C with an event.
--- @param self down.Event
function Event.handle(self)
local cbentry = Cb.cb[self.type]
log.trace("Event.handle: Handling ", self.id)
local cbentry = Cb.cb[self.id]
if cbentry then
for _, cb in ipairs(cbentry) do
if not cb[2] or cb[2](self) then
Expand All @@ -76,22 +78,31 @@ function Event.handle(self)
end
end

---@type fun(module: down.Mod.Mod, name: string): down.Event
function Event.load_cb(m)
for hk, ht in pairs(m.handle) do
for ck, ct in pairs(ht) do
if type(ct) == 'function' then
Event.callback(Event.define(m, ck), ct)
end
end
end
end

---@type fun(module: down.Mod.Mod, name: string, body?: any): down.Event
---@return down.Event
Event.define = function(module, name)
local mn = ""
Event.define = function(module, name, body)
local mn = ''
if type(module) == 'table' then
mn = module.name
mn = module.id
elseif type(module) == 'string' then
mn = module
end
local type = mn .. '.events.' .. name
local id = mn .. '.events.' .. name
return { ---@type down.Event
topic = type,
type = type,
id = id,
ref = mn,
split = Event.split_type(type) or {},
body = module,
split = Event.split_id(id) or {},
body = body or module,
broadcast = true,
position = vim.api.nvim_win_get_cursor(0),
file = vim.fn.expand('%:p'),
Expand All @@ -104,59 +115,56 @@ Event.define = function(module, name)
}
end

--- @param type string The full path of a init event
--- @param id string The full path of a init event
--- @return string[]?
function Event.split_type(type)
local start_str, end_str = type:find('%.events%.')
local split_event_type = { type:sub(0, start_str - 1), type:sub(end_str + 1) }
if #split_event_type ~= 2 then
log.warn('Invalid type name:' .. type)
function Event.split_id(id)
local sa, sb = id:find('%.events%.')
local sp_id = { id:sub(0, sa - 1), id:sub(sb + 1) }
if #sp_id ~= 2 then
log.warn('Invalid type name:' .. id)
return
end
return split_event_type
return sp_id
end

--- Returns an event template defined in `init.events`.
--- @param m down.Mod.Mod A reference to the init invoking the function
--- @param type string A full path to a valid event type (e.g. `init.events.some_event`)
--- @param id string A full path to a valid event type (e.g. `init.events.some_event`)
--- @return down.Event?
function Event.get_template(m, type)
local split = Event.split_type(type)
function Event.get_event(m, id)
local split = Event.split_id(id)
if not split then
log.warn('Unable to get event template for event' .. type .. 'and init' .. m.name)
log.warn('Unable to get event template for event' .. id .. 'and init' .. m.id)
return
end

log.trace('Returning' .. split[2] .. 'for init' .. split[1])
return m.events[split[2]]
end

--- Returns a copy of the event template provided by a init.
--- @param m down.Mod.Mod A reference to the init invoking the function
--- @param type string A full path to a valid .vent type (e.g. `init.events.some_event`)
--- @param id string A full path to a valid .vent type (e.g. `init.events.some_event`)
--- @param body table|any? The body of the event, can be anything from a string to a table to whatever you please.
--- @param ev? table The original event data.
--- @return down.Event? # New event.
function Event.new(m, type, body, ev)
local split = Event.split_type(type)
local event_template = Event.get_template(m or { name = '' }, type)
function Event.new(m, id, body, ev)
local event_template = Event.get_event(m or { id = m.id }, id)
if not event_template then
log.warn('Unable to create event of type' .. type .. '. Returning nil...')
log.warn('Unable to create event of type' .. id .. '. Returning nil...')
return
end
local mn = vim.deepcopy(event_template)
mn.type = type
mn.id = id
mn.body = body
mn.ref = m.name
mn.split = assert(split)
mn.ref = m.id
mn.split = assert(Event.split_id(id))
mn.file = vim.fn.expand('%:t') --[[@as string]]
mn.dir = vim.fn.expand('%:p:h') --[[@as string]]
mn.buf = ev and ev.buf or vim.api.nvim_get_current_buf()
mn.win = vim.api.nvim_get_current_win()
mn.position = vim.api.nvim_win_get_cursor(mn.win)
mn.mode = vim.api.nvim_get_mode()
mn.line = vim.api.nvim_buf_get_lines(mn.buf, mn.position[1] - 1, mn.position[1], true)[1]
mn.ref = m.name
mn.broadcast = true
return mn
end
Expand All @@ -166,17 +174,20 @@ end
--- @param self down.Event
function Event.broadcast_to(self, mods)
if not self.split then
log.error('Unable to broadcast event of type' .. self.type .. '- invalid event name')
log.error('Unable to broadcast event of type' .. self.id .. '- invalid event name')
return
end
Event.handle(self)
for _, cm in pairs(mods or {}) do
if cm.subscribed and cm.subscribed[self.split[1]] then
local evt = cm.subscribed[self.split[1]][self.split[2]]
if evt ~= nil and evt == true then
cm.handle(self)
for mid, cm in pairs(mods or {}) do
if cm.handle and cm.handle[self.split[1]] then
local evt = cm.handle[self.split[1]][self.split[2]]
if evt == nil or type(evt) == 'nil' then
goto broadcastcontinue
elseif type(evt) == 'function' then
evt(self)
end
end
::broadcastcontinue::
end
end

Expand All @@ -186,10 +197,10 @@ end
function Event.send(self, recv)
self.broadcast = false
Event.handle(self)
if recv.subscribed and recv.subscribed[self.split[1]] then
local evt = recv.subscribed[self.split[1]][self.split[2]]
if evt ~= nil and evt == true then
recv.handle(self)
if recv.handle and recv.handle[self.split[1]] then
local evt = recv.handle[self.split[1]][self.split[2]]
if evt ~= nil and type(evt) == 'function' then
evt(self)
end
end
end
Expand Down
Loading

0 comments on commit 5306296

Please sign in to comment.