2019-12-28 12:16:32 +01:00
|
|
|
local core = require "core"
|
|
|
|
local command = {}
|
|
|
|
|
|
|
|
command.map = {}
|
|
|
|
|
|
|
|
local always_true = function() return true end
|
|
|
|
|
|
|
|
|
2022-05-13 04:15:29 +02:00
|
|
|
---Used iternally by command.add, statusview, and contextmenu to generate a
|
|
|
|
---function with a condition to evaluate returning the boolean result of this
|
|
|
|
---evaluation.
|
|
|
|
---
|
|
|
|
---If a string predicate is given it is treated as a require import that should
|
2022-05-15 22:10:57 +02:00
|
|
|
---return a valid object which is checked against the current active view,
|
|
|
|
---eg: "core.docview" will match any view that inherits from DocView. Appending
|
|
|
|
---a `!` at the end of the string means we want to match the given object
|
|
|
|
---from the import strcitly eg: "core.docview!" only DocView is matched.
|
|
|
|
---A function that returns a boolean can be used instead to perform a custom
|
|
|
|
---evaluation, setting to nil means always evaluates to true.
|
2022-05-13 04:15:29 +02:00
|
|
|
---
|
|
|
|
---@param predicate string | table | function
|
|
|
|
---@return function
|
|
|
|
function command.generate_predicate(predicate)
|
2019-12-28 12:16:32 +01:00
|
|
|
predicate = predicate or always_true
|
2022-05-15 22:10:57 +02:00
|
|
|
local strict = false
|
2019-12-28 12:16:32 +01:00
|
|
|
if type(predicate) == "string" then
|
2022-05-15 22:10:57 +02:00
|
|
|
if predicate:match("!$") then
|
|
|
|
strict = true
|
|
|
|
predicate = predicate:gsub("!$", "")
|
|
|
|
end
|
2019-12-28 12:16:32 +01:00
|
|
|
predicate = require(predicate)
|
|
|
|
end
|
|
|
|
if type(predicate) == "table" then
|
|
|
|
local class = predicate
|
2022-05-15 22:10:57 +02:00
|
|
|
if not strict then
|
|
|
|
predicate = function() return core.active_view:extends(class) end
|
|
|
|
else
|
|
|
|
predicate = function() return core.active_view:is(class) end
|
|
|
|
end
|
2019-12-28 12:16:32 +01:00
|
|
|
end
|
2022-05-13 04:15:29 +02:00
|
|
|
return predicate
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function command.add(predicate, map)
|
|
|
|
predicate = command.generate_predicate(predicate)
|
2019-12-28 12:16:32 +01:00
|
|
|
for name, fn in pairs(map) do
|
|
|
|
assert(not command.map[name], "command already exists: " .. name)
|
|
|
|
command.map[name] = { predicate = predicate, perform = fn }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local function capitalize_first(str)
|
|
|
|
return str:sub(1, 1):upper() .. str:sub(2)
|
|
|
|
end
|
|
|
|
|
|
|
|
function command.prettify_name(name)
|
|
|
|
return name:gsub(":", ": "):gsub("-", " "):gsub("%S+", capitalize_first)
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function command.get_all_valid()
|
|
|
|
local res = {}
|
|
|
|
for name, cmd in pairs(command.map) do
|
|
|
|
if cmd.predicate() then
|
|
|
|
table.insert(res, name)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return res
|
|
|
|
end
|
|
|
|
|
2021-11-24 03:03:38 +01:00
|
|
|
function command.is_valid(name, ...)
|
|
|
|
return command.map[name] and command.map[name].predicate(...)
|
|
|
|
end
|
2019-12-28 12:16:32 +01:00
|
|
|
|
2021-10-06 00:22:43 +02:00
|
|
|
local function perform(name, ...)
|
2019-12-28 12:16:32 +01:00
|
|
|
local cmd = command.map[name]
|
2021-10-06 00:22:43 +02:00
|
|
|
if cmd and cmd.predicate(...) then
|
|
|
|
cmd.perform(...)
|
2019-12-28 12:16:32 +01:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function command.perform(...)
|
|
|
|
local ok, res = core.try(perform, ...)
|
|
|
|
return not ok or res
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function command.add_defaults()
|
2021-06-10 02:13:23 +02:00
|
|
|
local reg = {
|
|
|
|
"core", "root", "command", "doc", "findreplace",
|
2022-03-10 14:34:46 +01:00
|
|
|
"files", "drawwhitespace", "dialog", "log", "statusbar"
|
2021-06-10 02:13:23 +02:00
|
|
|
}
|
2019-12-28 12:16:32 +01:00
|
|
|
for _, name in ipairs(reg) do
|
|
|
|
require("core.commands." .. name)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
return command
|