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-14 01:56:58 +02:00
parent 6ccc5f6dde
commit cf29a6a45f
No known key found for this signature in database
GPG Key ID: EA928C8BDA1A8825
13 changed files with 223 additions and 233 deletions

View File

@ -33,9 +33,9 @@ function command.generate_predicate(predicate)
if type(predicate) == "table" then
local class = predicate
if not strict then
predicate = function() return core.active_view:extends(class) end
predicate = function(...) return core.active_view:extends(class), core.active_view, ... end
else
predicate = function() return core.active_view:is(class) end
predicate = function(...) return core.active_view:is(class), core.active_view, ... end
end
end
return predicate
@ -76,8 +76,16 @@ end
local function perform(name, ...)
local cmd = command.map[name]
if cmd and cmd.predicate(...) then
cmd.perform(...)
if not cmd then return false end
local res = { cmd.predicate(...) }
if table.remove(res, 1) then
if #res > 0 then
-- send values returned from predicate
cmd.perform(table.unpack(res))
else
-- send original parameters
cmd.perform(...)
end
return true
end
return false

View File

@ -2,23 +2,23 @@ local core = require "core"
local command = require "core.command"
command.add("core.commandview", {
["command:submit"] = function()
core.active_view:submit()
["command:submit"] = function(active_view)
active_view:submit()
end,
["command:complete"] = function()
core.active_view:complete()
["command:complete"] = function(active_view)
active_view:complete()
end,
["command:escape"] = function()
core.active_view:exit()
["command:escape"] = function(active_view)
active_view:exit()
end,
["command:select-previous"] = function()
core.active_view:move_suggestion_idx(1)
["command:select-previous"] = function(active_view)
active_view:move_suggestion_idx(1)
end,
["command:select-next"] = function()
core.active_view:move_suggestion_idx(-1)
["command:select-next"] = function(active_view)
active_view:move_suggestion_idx(-1)
end,
})

View File

@ -3,30 +3,25 @@ local command = require "core.command"
local common = require "core.common"
command.add("core.nagview", {
["dialog:previous-entry"] = function()
local v = core.active_view
["dialog:previous-entry"] = function(v)
local hover = v.hovered_item or 1
v:change_hovered(hover == 1 and #v.options or hover - 1)
end,
["dialog:next-entry"] = function()
local v = core.active_view
["dialog:next-entry"] = function(v)
local hover = v.hovered_item or 1
v:change_hovered(hover == #v.options and 1 or hover + 1)
end,
["dialog:select-yes"] = function()
local v = core.active_view
["dialog:select-yes"] = function(v)
if v ~= core.nag_view then return end
v:change_hovered(common.find_index(v.options, "default_yes"))
command.perform "dialog:select"
end,
["dialog:select-no"] = function()
local v = core.active_view
["dialog:select-no"] = function(v)
if v ~= core.nag_view then return end
v:change_hovered(common.find_index(v.options, "default_no"))
command.perform "dialog:select"
end,
["dialog:select"] = function()
local v = core.active_view
["dialog:select"] = function(v)
if v.hovered_item then
v.on_selected(v.options[v.hovered_item])
v:next()

View File

@ -89,13 +89,13 @@ local function split_cursor(direction)
core.blink_reset()
end
local function set_cursor(x, y, snap_type)
local line, col = dv():resolve_screen_position(x, y)
doc():set_selection(line, col, line, col)
local function set_cursor(dv, x, y, snap_type)
local line, col = dv:resolve_screen_position(x, y)
dv.doc:set_selection(line, col, line, col)
if snap_type == "word" or snap_type == "lines" then
command.perform("doc:select-" .. snap_type)
end
dv().mouse_selecting = { line, col, snap_type }
dv.mouse_selecting = { line, col, snap_type }
core.blink_reset()
end
@ -178,9 +178,9 @@ local function block_comment(comment, line1, col1, line2, col2)
end
local commands = {
["doc:select-none"] = function()
local line, col = doc():get_selection()
doc():set_selection(line, col)
["doc:select-none"] = function(dv)
local line, col = dv.doc:get_selection()
dv.doc:set_selection(line, col)
end,
["doc:cut"] = function()
@ -191,15 +191,15 @@ local commands = {
cut_or_copy(false)
end,
["doc:undo"] = function()
doc():undo()
["doc:undo"] = function(dv)
dv.doc:undo()
end,
["doc:redo"] = function()
doc():redo()
["doc:redo"] = function(dv)
dv.doc:redo()
end,
["doc:paste"] = function()
["doc:paste"] = function(dv)
local clipboard = system.get_clipboard()
-- If the clipboard has changed since our last look, use that instead
local external_paste = core.cursor_clipboard["full"] ~= clipboard
@ -208,8 +208,8 @@ local commands = {
core.cursor_clipboard_whole_line = {}
end
local value, whole_line
for idx, line1, col1, line2, col2 in doc():get_selections() do
if #core.cursor_clipboard_whole_line == (#doc().selections/4) then
for idx, line1, col1, line2, col2 in dv.doc:get_selections() do
if #core.cursor_clipboard_whole_line == (#dv.doc.selections/4) then
value = core.cursor_clipboard[idx]
whole_line = core.cursor_clipboard_whole_line[idx] == true
else
@ -217,172 +217,172 @@ local commands = {
whole_line = not external_paste and clipboard:find("\n") ~= nil
end
if whole_line then
doc():insert(line1, 1, value:gsub("\r", ""))
dv.doc:insert(line1, 1, value:gsub("\r", ""))
if col1 == 1 then
doc():move_to_cursor(idx, #value)
dv.doc:move_to_cursor(idx, #value)
end
else
doc():text_input(value:gsub("\r", ""), idx)
dv.doc:text_input(value:gsub("\r", ""), idx)
end
end
end,
["doc:newline"] = function()
for idx, line, col in doc():get_selections(false, true) do
local indent = doc().lines[line]:match("^[\t ]*")
["doc:newline"] = function(dv)
for idx, line, col in dv.doc:get_selections(false, true) do
local indent = dv.doc.lines[line]:match("^[\t ]*")
if col <= #indent then
indent = indent:sub(#indent + 2 - col)
end
-- Remove current line if it contains only whitespace
if doc().lines[line]:match("^%s+$") then
doc():remove(line, 1, line, math.huge)
if dv.doc.lines[line]:match("^%s+$") then
dv.doc:remove(line, 1, line, math.huge)
end
doc():text_input("\n" .. indent, idx)
dv.doc:text_input("\n" .. indent, idx)
end
end,
["doc:newline-below"] = function()
for idx, line in doc():get_selections(false, true) do
local indent = doc().lines[line]:match("^[\t ]*")
doc():insert(line, math.huge, "\n" .. indent)
doc():set_selections(idx, line + 1, math.huge)
["doc:newline-below"] = function(dv)
for idx, line in dv.doc:get_selections(false, true) do
local indent = dv.doc.lines[line]:match("^[\t ]*")
dv.doc:insert(line, math.huge, "\n" .. indent)
dv.doc:set_selections(idx, line + 1, math.huge)
end
end,
["doc:newline-above"] = function()
for idx, line in doc():get_selections(false, true) do
local indent = doc().lines[line]:match("^[\t ]*")
doc():insert(line, 1, indent .. "\n")
doc():set_selections(idx, line, math.huge)
["doc:newline-above"] = function(dv)
for idx, line in dv.doc:get_selections(false, true) do
local indent = dv.doc.lines[line]:match("^[\t ]*")
dv.doc:insert(line, 1, indent .. "\n")
dv.doc:set_selections(idx, line, math.huge)
end
end,
["doc:delete"] = function()
for idx, line1, col1, line2, col2 in doc():get_selections() do
if line1 == line2 and col1 == col2 and doc().lines[line1]:find("^%s*$", col1) then
doc():remove(line1, col1, line1, math.huge)
["doc:delete"] = function(dv)
for idx, line1, col1, line2, col2 in dv.doc:get_selections() do
if line1 == line2 and col1 == col2 and dv.doc.lines[line1]:find("^%s*$", col1) then
dv.doc:remove(line1, col1, line1, math.huge)
end
doc():delete_to_cursor(idx, translate.next_char)
dv.doc:delete_to_cursor(idx, translate.next_char)
end
end,
["doc:backspace"] = function()
local _, indent_size = doc():get_indent_info()
for idx, line1, col1, line2, col2 in doc():get_selections() do
["doc:backspace"] = function(dv)
local _, indent_size = dv.doc:get_indent_info()
for idx, line1, col1, line2, col2 in dv.doc:get_selections() do
if line1 == line2 and col1 == col2 then
local text = doc():get_text(line1, 1, line1, col1)
local text = dv.doc:get_text(line1, 1, line1, col1)
if #text >= indent_size and text:find("^ *$") then
doc():delete_to_cursor(idx, 0, -indent_size)
dv.doc:delete_to_cursor(idx, 0, -indent_size)
return
end
end
doc():delete_to_cursor(idx, translate.previous_char)
dv.doc:delete_to_cursor(idx, translate.previous_char)
end
end,
["doc:select-all"] = function()
doc():set_selection(1, 1, math.huge, math.huge)
["doc:select-all"] = function(dv)
dv.doc:set_selection(1, 1, math.huge, math.huge)
-- avoid triggering DocView:scroll_to_make_visible
dv().last_line1 = 1
dv().last_col1 = 1
dv().last_line2 = #doc().lines
dv().last_col2 = #doc().lines[#doc().lines]
dv.last_line1 = 1
dv.last_col1 = 1
dv.last_line2 = #dv.doc.lines
dv.last_col2 = #dv.doc.lines[#dv.doc.lines]
end,
["doc:select-lines"] = function()
for idx, line1, _, line2 in doc():get_selections(true) do
["doc:select-lines"] = function(dv)
for idx, line1, _, line2 in dv.doc:get_selections(true) do
append_line_if_last_line(line2)
doc():set_selections(idx, line1, 1, line2 + 1, 1)
dv.doc:set_selections(idx, line1, 1, line2 + 1, 1)
end
end,
["doc:select-word"] = function()
for idx, line1, col1 in doc():get_selections(true) do
local line1, col1 = translate.start_of_word(doc(), line1, col1)
local line2, col2 = translate.end_of_word(doc(), line1, col1)
doc():set_selections(idx, line2, col2, line1, col1)
["doc:select-word"] = function(dv)
for idx, line1, col1 in dv.doc:get_selections(true) do
local line1, col1 = translate.start_of_word(dv.doc, line1, col1)
local line2, col2 = translate.end_of_word(dv.doc, line1, col1)
dv.doc:set_selections(idx, line2, col2, line1, col1)
end
end,
["doc:join-lines"] = function()
for idx, line1, col1, line2, col2 in doc():get_selections(true) do
["doc:join-lines"] = function(dv)
for idx, line1, col1, line2, col2 in dv.doc:get_selections(true) do
if line1 == line2 then line2 = line2 + 1 end
local text = doc():get_text(line1, 1, line2, math.huge)
local text = dv.doc:get_text(line1, 1, line2, math.huge)
text = text:gsub("(.-)\n[\t ]*", function(x)
return x:find("^%s*$") and x or x .. " "
end)
doc():insert(line1, 1, text)
doc():remove(line1, #text + 1, line2, math.huge)
dv.doc:insert(line1, 1, text)
dv.doc:remove(line1, #text + 1, line2, math.huge)
if line1 ~= line2 or col1 ~= col2 then
doc():set_selections(idx, line1, math.huge)
dv.doc:set_selections(idx, line1, math.huge)
end
end
end,
["doc:indent"] = function()
["doc:indent"] = function(dv)
for idx, line1, col1, line2, col2 in doc_multiline_selections(true) do
local l1, c1, l2, c2 = doc():indent_text(false, line1, col1, line2, col2)
local l1, c1, l2, c2 = dv.doc:indent_text(false, line1, col1, line2, col2)
if l1 then
doc():set_selections(idx, l1, c1, l2, c2)
dv.doc:set_selections(idx, l1, c1, l2, c2)
end
end
end,
["doc:unindent"] = function()
["doc:unindent"] = function(dv)
for idx, line1, col1, line2, col2 in doc_multiline_selections(true) do
local l1, c1, l2, c2 = doc():indent_text(true, line1, col1, line2, col2)
local l1, c1, l2, c2 = dv.doc:indent_text(true, line1, col1, line2, col2)
if l1 then
doc():set_selections(idx, l1, c1, l2, c2)
dv.doc:set_selections(idx, l1, c1, l2, c2)
end
end
end,
["doc:duplicate-lines"] = function()
["doc:duplicate-lines"] = function(dv)
for idx, line1, col1, line2, col2 in doc_multiline_selections(true) do
append_line_if_last_line(line2)
local text = doc():get_text(line1, 1, line2 + 1, 1)
doc():insert(line2 + 1, 1, text)
dv.doc:insert(line2 + 1, 1, text)
local n = line2 - line1 + 1
doc():set_selections(idx, line1 + n, col1, line2 + n, col2)
dv.doc:set_selections(idx, line1 + n, col1, line2 + n, col2)
end
end,
["doc:delete-lines"] = function()
["doc:delete-lines"] = function(dv)
for idx, line1, col1, line2, col2 in doc_multiline_selections(true) do
append_line_if_last_line(line2)
doc():remove(line1, 1, line2 + 1, 1)
doc():set_selections(idx, line1, col1)
dv.doc:remove(line1, 1, line2 + 1, 1)
dv.doc:set_selections(idx, line1, col1)
end
end,
["doc:move-lines-up"] = function()
["doc:move-lines-up"] = function(dv)
for idx, line1, col1, line2, col2 in doc_multiline_selections(true) do
append_line_if_last_line(line2)
if line1 > 1 then
local text = doc().lines[line1 - 1]
doc():insert(line2 + 1, 1, text)
doc():remove(line1 - 1, 1, line1, 1)
doc():set_selections(idx, line1 - 1, col1, line2 - 1, col2)
dv.doc:insert(line2 + 1, 1, text)
dv.doc:remove(line1 - 1, 1, line1, 1)
dv.doc:set_selections(idx, line1 - 1, col1, line2 - 1, col2)
end
end
end,
["doc:move-lines-down"] = function()
["doc:move-lines-down"] = function(dv)
for idx, line1, col1, line2, col2 in doc_multiline_selections(true) do
append_line_if_last_line(line2 + 1)
if line2 < #doc().lines then
local text = doc().lines[line2 + 1]
doc():remove(line2 + 1, 1, line2 + 2, 1)
doc():insert(line1, 1, text)
doc():set_selections(idx, line1 + 1, col1, line2 + 1, col2)
if line2 < #dv.doc.lines then
local text = dv.doc.lines[line2 + 1]
dv.doc:remove(line2 + 1, 1, line2 + 2, 1)
dv.doc:insert(line1, 1, text)
dv.doc:set_selections(idx, line1 + 1, col1, line2 + 1, col2)
end
end
end,
["doc:toggle-block-comments"] = function()
local comment = doc().syntax.block_comment
["doc:toggle-block-comments"] = function(dv)
local comment = dv.doc.syntax.block_comment
if not comment then
if doc().syntax.comment then
if dv.doc.syntax.comment then
command.perform "doc:toggle-line-comments"
end
return
@ -392,32 +392,30 @@ local commands = {
-- if nothing is selected, toggle the whole line
if line1 == line2 and col1 == col2 then
col1 = 1
col2 = #doc().lines[line2]
col2 = #dv.doc.lines[line2]
end
doc():set_selections(idx, block_comment(comment, line1, col1, line2, col2))
dv.doc:set_selections(idx, block_comment(comment, line1, col1, line2, col2))
end
end,
["doc:toggle-line-comments"] = function()
local comment = doc().syntax.comment or doc().syntax.block_comment
["doc:toggle-line-comments"] = function(dv)
local comment = dv.doc.syntax.comment or dv.doc.syntax.block_comment
if comment then
for idx, line1, col1, line2, col2 in doc_multiline_selections(true) do
doc():set_selections(idx, line_comment(comment, line1, col1, line2, col2))
dv.doc:set_selections(idx, line_comment(comment, line1, col1, line2, col2))
end
end
end,
["doc:upper-case"] = function()
doc():replace(string.uupper)
["doc:upper-case"] = function(dv)
dv.doc:replace(string.uupper)
end,
["doc:lower-case"] = function()
doc():replace(string.ulower)
["doc:lower-case"] = function(dv)
dv.doc:replace(string.ulower)
end,
["doc:go-to-line"] = function()
local dv = dv()
["doc:go-to-line"] = function(dv)
local items
local function init_items()
if items then return end
@ -448,15 +446,15 @@ local commands = {
})
end,
["doc:toggle-line-ending"] = function()
doc().crlf = not doc().crlf
["doc:toggle-line-ending"] = function(dv)
dv.doc.crlf = not dv.doc.crlf
end,
["doc:save-as"] = function()
["doc:save-as"] = function(dv)
local last_doc = core.last_active_view and core.last_active_view.doc
local text
if doc().filename then
text = doc().filename
if dv.doc.filename then
text = dv.doc.filename
elseif last_doc and last_doc.filename then
local dirname, filename = core.last_active_view.doc.abs_filename:match("(.*)[/\\](.+)$")
text = core.normalize_to_project_dir(dirname) .. PATHSEP
@ -472,20 +470,20 @@ local commands = {
})
end,
["doc:save"] = function()
if doc().filename then
["doc:save"] = function(dv)
if dv.doc.filename then
save()
else
command.perform("doc:save-as")
end
end,
["doc:reload"] = function()
doc():reload()
["doc:reload"] = function(dv)
dv.doc:reload()
end,
["file:rename"] = function()
local old_filename = doc().filename
["file:rename"] = function(dv)
local old_filename = dv.doc.filename
if not old_filename then
core.error("Cannot rename unsaved doc")
return
@ -506,13 +504,13 @@ local commands = {
end,
["file:delete"] = function()
local filename = doc().abs_filename
["file:delete"] = function(dv)
local filename = dv.doc.abs_filename
if not filename then
core.error("Cannot remove unsaved doc")
return
end
for i,docview in ipairs(core.get_views_referencing_doc(doc())) do
for i,docview in ipairs(core.get_views_referencing_doc(dv.doc)) do
local node = core.root_view.root_node:get_node_for_view(docview)
node:close_view(core.root_view.root_node, docview)
end
@ -520,56 +518,57 @@ local commands = {
core.log("Removed \"%s\"", filename)
end,
["doc:select-to-cursor"] = function(x, y, clicks)
["doc:select-to-cursor"] = function(dv, x, y, clicks)
local line1, col1 = select(3, doc():get_selection())
local line2, col2 = dv():resolve_screen_position(x, y)
dv().mouse_selecting = { line1, col1, nil }
doc():set_selection(line2, col2, line1, col1)
local line2, col2 = dv:resolve_screen_position(x, y)
dv.mouse_selecting = { line1, col1, nil }
dv.doc:set_selection(line2, col2, line1, col1)
end,
["doc:create-cursor-previous-line"] = function()
["doc:create-cursor-previous-line"] = function(dv)
split_cursor(-1)
doc():merge_cursors()
dv.doc:merge_cursors()
end,
["doc:create-cursor-next-line"] = function()
["doc:create-cursor-next-line"] = function(dv)
split_cursor(1)
doc():merge_cursors()
dv.doc:merge_cursors()
end
}
command.add(function(x, y)
if x == nil or y == nil or not doc() then return false end
local x1,y1,x2,y2 = dv().position.x, dv().position.y, dv().position.x + dv().size.x, dv().position.y + dv().size.y
return x >= x1 + dv():get_gutter_width() and x < x2 and y >= y1 and y < y2
if x == nil or y == nil or not core.active_view:is(DocView) then return false end
local dv = core.active_view
local x1,y1,x2,y2 = dv.position.x, dv.position.y, dv.position.x + dv.size.x, dv.position.y + dv.size.y
return x >= x1 + dv:get_gutter_width() and x < x2 and y >= y1 and y < y2, dv, x, y
end, {
["doc:set-cursor"] = function(x, y)
set_cursor(x, y, "set")
["doc:set-cursor"] = function(dv, x, y)
set_cursor(dv, x, y, "set")
end,
["doc:set-cursor-word"] = function(x, y)
set_cursor(x, y, "word")
["doc:set-cursor-word"] = function(dv, x, y)
set_cursor(dv, x, y, "word")
end,
["doc:set-cursor-line"] = function(x, y, clicks)
set_cursor(x, y, "lines")
["doc:set-cursor-line"] = function(dv, x, y, clicks)
set_cursor(dv, x, y, "lines")
end,
["doc:split-cursor"] = function(x, y, clicks)
local line, col = dv():resolve_screen_position(x, y)
["doc:split-cursor"] = function(dv, x, y, clicks)
local line, col = dv:resolve_screen_position(x, y)
local removal_target = nil
for idx, line1, col1 in doc():get_selections(true) do
for idx, line1, col1 in dv.doc:get_selections(true) do
if line1 == line and col1 == col and #doc().selections > 4 then
removal_target = idx
end
end
if removal_target then
doc():remove_selection(removal_target)
dv.doc:remove_selection(removal_target)
else
doc():add_selection(line, col, line, col)
dv.doc:add_selection(line, col, line, col)
end
dv().mouse_selecting = { line, col, "set" }
dv.mouse_selecting = { line, col, "set" }
end
})
@ -594,27 +593,27 @@ local translations = {
}
for name, obj in pairs(translations) do
commands["doc:move-to-" .. name] = function() doc():move_to(obj[name:gsub("-", "_")], dv()) end
commands["doc:select-to-" .. name] = function() doc():select_to(obj[name:gsub("-", "_")], dv()) end
commands["doc:delete-to-" .. name] = function() doc():delete_to(obj[name:gsub("-", "_")], dv()) end
commands["doc:move-to-" .. name] = function(dv) dv.doc:move_to(obj[name:gsub("-", "_")], dv) end
commands["doc:select-to-" .. name] = function(dv) dv.doc:select_to(obj[name:gsub("-", "_")], dv) end
commands["doc:delete-to-" .. name] = function(dv) dv.doc:delete_to(obj[name:gsub("-", "_")], dv) end
end
commands["doc:move-to-previous-char"] = function()
for idx, line1, col1, line2, col2 in doc():get_selections(true) do
commands["doc:move-to-previous-char"] = function(dv)
for idx, line1, col1, line2, col2 in dv.doc:get_selections(true) do
if line1 ~= line2 or col1 ~= col2 then
doc():set_selections(idx, line1, col1)
dv.doc:set_selections(idx, line1, col1)
else
doc():move_to_cursor(idx, translate.previous_char)
dv.doc:move_to_cursor(idx, translate.previous_char)
end
end
end
commands["doc:move-to-next-char"] = function()
for idx, line1, col1, line2, col2 in doc():get_selections(true) do
commands["doc:move-to-next-char"] = function(dv)
for idx, line1, col1, line2, col2 in dv.doc:get_selections(true) do
if line1 ~= line2 or col1 ~= col2 then
doc():set_selections(idx, line2, col2)
dv.doc:set_selections(idx, line2, col2)
else
doc():move_to_cursor(idx, translate.next_char)
dv.doc:move_to_cursor(idx, translate.next_char)
end
end
end

View File

@ -7,13 +7,11 @@ local config = require "core.config"
local t = {
["root:close"] = function()
local node = core.root_view:get_active_node()
["root:close"] = function(node)
node:close_active_view(core.root_view.root_node)
end,
["root:close-or-quit"] = function()
local node = core.root_view:get_active_node()
["root:close-or-quit"] = function(node)
if node and (not node:is_empty() or not node.is_primary_node) then
node:close_active_view(core.root_view.root_node)
else
@ -31,24 +29,21 @@ local t = {
core.confirm_close_docs(docs, core.root_view.close_all_docviews, core.root_view, true)
end,
["root:switch-to-previous-tab"] = function()
local node = core.root_view:get_active_node()
["root:switch-to-previous-tab"] = function(node)
local idx = node:get_view_idx(core.active_view)
idx = idx - 1
if idx < 1 then idx = #node.views end
node:set_active_view(node.views[idx])
end,
["root:switch-to-next-tab"] = function()
local node = core.root_view:get_active_node()
["root:switch-to-next-tab"] = function(node)
local idx = node:get_view_idx(core.active_view)
idx = idx + 1
if idx > #node.views then idx = 1 end
node:set_active_view(node.views[idx])
end,
["root:move-tab-left"] = function()
local node = core.root_view:get_active_node()
["root:move-tab-left"] = function(node)
local idx = node:get_view_idx(core.active_view)
if idx > 1 then
table.remove(node.views, idx)
@ -56,8 +51,7 @@ local t = {
end
end,
["root:move-tab-right"] = function()
local node = core.root_view:get_active_node()
["root:move-tab-right"] = function(node)
local idx = node:get_view_idx(core.active_view)
if idx < #node.views then
table.remove(node.views, idx)
@ -65,15 +59,13 @@ local t = {
end
end,
["root:shrink"] = function()
local node = core.root_view:get_active_node()
["root:shrink"] = function(node)
local parent = node:get_parent_node(core.root_view.root_node)
local n = (parent.a == node) and -0.1 or 0.1
parent.divider = common.clamp(parent.divider + n, 0.1, 0.9)
end,
["root:grow"] = function()
local node = core.root_view:get_active_node()
["root:grow"] = function(node)
local parent = node:get_parent_node(core.root_view.root_node)
local n = (parent.a == node) and 0.1 or -0.1
parent.divider = common.clamp(parent.divider + n, 0.1, 0.9)
@ -82,8 +74,7 @@ local t = {
for i = 1, 9 do
t["root:switch-to-tab-" .. i] = function()
local node = core.root_view:get_active_node()
t["root:switch-to-tab-" .. i] = function(node)
local view = node.views[i]
if view then
node:set_active_view(view)
@ -93,8 +84,7 @@ end
for _, dir in ipairs { "left", "right", "up", "down" } do
t["root:split-" .. dir] = function()
local node = core.root_view:get_active_node()
t["root:split-" .. dir] = function(node)
local av = node.active_view
node:split(dir)
if av:is(DocView) then
@ -102,8 +92,7 @@ for _, dir in ipairs { "left", "right", "up", "down" } do
end
end
t["root:switch-to-" .. dir] = function()
local node = core.root_view:get_active_node()
t["root:switch-to-" .. dir] = function(node)
local x, y
if dir == "left" or dir == "right" then
y = node.position.y + node.size.y / 2
@ -123,7 +112,7 @@ end
command.add(function()
local node = core.root_view:get_active_node()
local sx, sy = node:get_locked_size()
return not sx and not sy
return not sx and not sy, node
end, t)
command.add(nil, {

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

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
})

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)

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,

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%[%](){}`'\"]*"

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)

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,
})

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,
})