Allow command predicates to manage parameters passed to the commands

When a command is performed with parameters, those are now passed to the
predicate.
The predicate can then return, after the validity boolean, any other
value that will then be passed to the actual command.
If the predicate only returns the validity boolean, the original
parameters are passed through to the actual command.

This allows predicates to manipulate the received parameters, and allows
them to pass the result of an expensive computation to the actual
command, which won't have to recalculate it.

String and table predicates will now also return `core.active_view`.
This commit is contained in:
Guldoman
2022-08-16 22:13:16 +02:00
parent 6ccc5f6dde
commit cf29a6a45f
13 changed files with 223 additions and 233 deletions
+4 -3
View File
@@ -621,12 +621,13 @@ end
-- Commands
--
local function predicate()
return get_active_view() and #suggestions > 0
local active_docview = get_active_view()
return active_docview and #suggestions > 0, active_docview
end
command.add(predicate, {
["autocomplete:complete"] = function()
local doc = core.active_view.doc
["autocomplete:complete"] = function(dv)
local doc = dv.doc
local line, col = doc:get_selection()
local item = suggestions[suggestions_idx]
local text = item.text
+2 -2
View File
@@ -33,8 +33,8 @@ function RootView:draw(...)
end
command.add("core.docview!", {
["context:show"] = function()
menu:show(core.active_view.position.x, core.active_view.position.y)
["context:show"] = function(dv)
menu:show(dv.position.x, dv.position.y)
end
})
+4 -4
View File
@@ -299,10 +299,10 @@ local function set_indent_type(doc, type)
doc.indent_info = cache[doc]
end
local function set_indent_type_command()
local function set_indent_type_command(dv)
core.command_view:enter("Specify indent style for this file", {
submit = function(value)
local doc = core.active_view.doc
local doc = dv.doc
value = value:lower()
set_indent_type(doc, value == "tabs" and "hard" or "soft")
end,
@@ -327,11 +327,11 @@ local function set_indent_size(doc, size)
doc.indent_info = cache[doc]
end
local function set_indent_size_command()
local function set_indent_size_command(dv)
core.command_view:enter("Specify indent size for current file", {
submit = function(value)
value = math.floor(tonumber(value))
local doc = core.active_view.doc
local doc = dv.doc
set_indent_size(doc, value)
end,
validate = function(value)
+2 -2
View File
@@ -19,8 +19,8 @@ end
command.add("core.docview", {
["quote:quote"] = function()
core.active_view.doc:replace(function(text)
["quote:quote"] = function(dv)
dv.doc:replace(function(text)
return '"' .. text:gsub("[\0-\31\\\"]", replace) .. '"'
end)
end,
+2 -2
View File
@@ -25,8 +25,8 @@ end
command.add("core.docview", {
["reflow:reflow"] = function()
local doc = core.active_view.doc
["reflow:reflow"] = function(dv)
local doc = dv.doc
doc:replace(function(text)
local prefix_set = "[^%w\n%[%](){}`'\"]*"
+3 -3
View File
@@ -41,17 +41,17 @@ end
command.add("core.docview", {
["tabularize:tabularize"] = function()
["tabularize:tabularize"] = function(dv)
core.command_view:enter("Tabularize On Delimiter", {
submit = function(delim)
if delim == "" then delim = " " end
local doc = core.active_view.doc
local doc = dv.doc
local line1, col1, line2, col2, swap = doc:get_selection(true)
line1, col1 = doc:position_offset(line1, col1, translate.start_of_line)
line2, col2 = doc:position_offset(line2, col2, translate.end_of_line)
doc:set_selection(line1, col1, line2, col2, swap)
doc:replace(function(text)
local lines = gmatch_to_array(text, "[^\n]*\n?")
tabularize_lines(lines, delim)
+17 -19
View File
@@ -679,16 +679,16 @@ local function treeitem() return view.hovered_item or view.selected_item end
command.add(
function()
return treeitem() ~= nil
local item = treeitem()
return item ~= nil
and (
core.active_view == view or core.active_view == menu
or (view.toolbar and core.active_view == view.toolbar)
-- sometimes the context menu is shown on top of statusbar
or core.active_view == core.status_view
)
), item
end, {
["treeview:delete"] = function()
local item = treeitem()
["treeview:delete"] = function(item)
local filename = item.abs_filename
local relfilename = item.filename
if item.dir_name ~= core.project_dir then
@@ -732,9 +732,11 @@ command.add(
})
command.add(function() return treeitem() ~= nil end, {
["treeview:rename"] = function()
command.add(function()
local item = treeitem()
return item ~= nil, item
end, {
["treeview:rename"] = function(item)
local old_filename = item.filename
local old_abs_filename = item.abs_filename
core.command_view:enter("Rename", {
@@ -764,9 +766,8 @@ command.add(function() return treeitem() ~= nil end, {
})
end,
["treeview:new-file"] = function()
["treeview:new-file"] = function(item)
local text
local item = treeitem()
if not is_project_folder(item.abs_filename) then
text = item.filename .. PATHSEP
end
@@ -787,9 +788,8 @@ command.add(function() return treeitem() ~= nil end, {
})
end,
["treeview:new-folder"] = function()
["treeview:new-folder"] = function(item)
local text
local item = treeitem()
if not is_project_folder(item.abs_filename) then
text = item.filename .. PATHSEP
end
@@ -806,15 +806,13 @@ command.add(function() return treeitem() ~= nil end, {
})
end,
["treeview:open-in-system"] = function()
local hovered_item = treeitem()
["treeview:open-in-system"] = function(item)
if PLATFORM == "Windows" then
system.exec(string.format("start \"\" %q", hovered_item.abs_filename))
system.exec(string.format("start \"\" %q", item.abs_filename))
elseif string.find(PLATFORM, "Mac") then
system.exec(string.format("open %q", hovered_item.abs_filename))
system.exec(string.format("open %q", item.abs_filename))
elseif PLATFORM == "Linux" or string.find(PLATFORM, "BSD") then
system.exec(string.format("xdg-open %q", hovered_item.abs_filename))
system.exec(string.format("xdg-open %q", item.abs_filename))
end
end
})
@@ -823,10 +821,10 @@ command.add(function()
local item = treeitem()
return item
and not is_primary_project_folder(item.abs_filename)
and is_project_folder(item.abs_filename)
and is_project_folder(item.abs_filename), item
end, {
["treeview:remove-project-directory"] = function()
core.remove_project_directory(treeitem().dir_name)
["treeview:remove-project-directory"] = function(item)
core.remove_project_directory(item.dir_name)
end,
})
+2 -2
View File
@@ -24,8 +24,8 @@ end
command.add("core.docview", {
["trim-whitespace:trim-trailing-whitespace"] = function()
trim_trailing_whitespace(core.active_view.doc)
["trim-whitespace:trim-trailing-whitespace"] = function(dv)
trim_trailing_whitespace(dv.doc)
end,
})