Skip to content

Commit

Permalink
Fix match, can_match error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
notomo committed Jun 25, 2023
1 parent 3863f34 commit 1e7a227
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 17 deletions.
29 changes: 25 additions & 4 deletions lua/gesture/command.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,19 @@ function M.draw(raw_opts)
end

local ctx = state:action_context()
local can_match = state.matcher:can_match(ctx)
local nowait_gesture = can_match and state.matcher:nowait_match(ctx) or nil

local can_match, can_match_err = state.matcher:can_match(ctx)
if can_match_err then
state:close()
require("gesture.vendor.misclib.message").error(can_match_err)
end

local nowait_gesture, nowait_err = state.matcher:nowait_match(ctx, can_match)
if nowait_err then
state:close()
require("gesture.vendor.misclib.message").error(nowait_err)
end

if nowait_gesture then
state:close()
local err = nowait_gesture:execute(ctx)
Expand All @@ -33,7 +44,12 @@ function M.draw(raw_opts)
return
end

local gesture = can_match and state.matcher:match(ctx) or nil
local gesture, match_err = state.matcher:match(ctx, can_match)
if match_err then
state:close()
require("gesture.vendor.misclib.message").error(match_err)
end

state.view:render_input(ctx.inputs, gesture, can_match, opts.show_board)
end

Expand All @@ -53,7 +69,12 @@ function M.finish()

local ctx = state:action_context()
state:close()
local gesture = state.matcher:match(ctx)

local gesture, match_err = state.matcher:match(ctx, true)
if match_err then
require("gesture.vendor.misclib.message").error(match_err)
end

if gesture then
local err = gesture:execute(ctx)
if err then
Expand Down
28 changes: 23 additions & 5 deletions lua/gesture/core/gesture_info.lua
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,27 @@ function GestureInfo.new(info)
local input_defs
local strs
local match
local can_match
local equals
if info.match then
strs = nil
match = info.match
match = function(ctx)
return can_match(ctx) and info.match(ctx)
end
equals = function(g)
return name == g.name
end
else
input_defs = require("gesture.core.input_definitions").new(info.inputs or {})
strs = input_defs:strings()
match = function(ctx)
return input_defs:match(ctx.inputs)
return can_match(ctx) and input_defs:match(ctx.inputs)
end
equals = function(g)
return input_defs:equals(g._input_defs)
end
end

local can_match
if info.can_match then
can_match = info.can_match
elseif info.match then
Expand All @@ -69,12 +71,12 @@ function GestureInfo.new(info)

local tbl = {
name = name,
match = match,
can_match = can_match,
equals = equals,
nowait = info.nowait or false,
buffer = bufnr,
strs = strs,
_match = match,
_can_match = can_match,
_action = action,
_input_defs = input_defs,
}
Expand All @@ -89,4 +91,20 @@ function GestureInfo.execute(self, ctx)
return nil
end

function GestureInfo.match(self, ctx)
local ok, result = pcall(self._match, ctx)
if not ok then
return false, result
end
return result, nil
end

function GestureInfo.can_match(self, ctx)
local ok, result = pcall(self._can_match, ctx)
if not ok then
return false, result
end
return result, nil
end

return GestureInfo
20 changes: 16 additions & 4 deletions lua/gesture/core/gesture_map.lua
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ function GestureMap.match(self, bufnr, ctx, nowait)
make_key(nil, nowait, input_strs),
}
for _, key in ipairs(keys) do
local gesture = self:_match(key, ctx)
local gesture, err = self:_match(key, ctx)
if err then
return nil, err
end
if gesture then
return gesture
end
Expand Down Expand Up @@ -87,7 +90,10 @@ function GestureMap.can_match(self, bufnr, ctx)
},
}
for _, key_pair in ipairs(key_pairs) do
local matched = self:_can_match(key_pair[1], key_pair[2], ctx)
local matched, err = self:_can_match(key_pair[1], key_pair[2], ctx)
if err then
return false, err
end
if matched then
return matched
end
Expand All @@ -99,8 +105,14 @@ end
function GestureMap._can_match(self, nowait_key, key, ctx)
for k, gestures in pairs(self._map) do
local key_matched = vim.startswith(k, nowait_key) or vim.startswith(k, key)
if key_matched and gestures:can_match(ctx) then
return true
if key_matched then
local ok, err = gestures:can_match(ctx)
if err then
return false, err
end
if ok then
return true
end
end
end
return false
Expand Down
12 changes: 10 additions & 2 deletions lua/gesture/core/gestures.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ end

function Gestures.can_match(self, ctx)
for _, gesture in ipairs(self._gestures) do
if gesture.can_match(ctx) then
local ok, err = gesture:can_match(ctx)
if err then
return false, err
end
if ok then
return true
end
end
Expand All @@ -27,7 +31,11 @@ end

function Gestures.match(self, ctx)
for _, gesture in ipairs(self._gestures) do
if gesture.can_match(ctx) and gesture.match(ctx) then
local ok, err = gesture:match(ctx)
if err then
return nil, err
end
if ok then
return gesture
end
end
Expand Down
10 changes: 8 additions & 2 deletions lua/gesture/core/matcher.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,17 @@ function Matcher.new(bufnr)
return setmetatable(tbl, Matcher)
end

function Matcher.nowait_match(self, ctx)
function Matcher.nowait_match(self, ctx, can_match)
if not can_match then
return nil
end
return self._gesture_map:match(self._bufnr, ctx, true)
end

function Matcher.match(self, ctx)
function Matcher.match(self, ctx, can_match)
if not can_match then
return nil
end
return self._gesture_map:match(self._bufnr, ctx, false)
end

Expand Down
58 changes: 58 additions & 0 deletions spec/lua/gesture/init_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,39 @@ describe("gesture.draw()", function()

assert.no.shown_in_view("RIGHT")
end)

it("cleanups on match error", function()
gesture.register({
match = function()
error("match error")
end,
action = "",
})

local ok, err = pcall(function()
gesture.draw()
end)
assert.is_false(ok)
assert.match("match error", err)
assert.window_count(1)
end)

it("cleanups on can_match error", function()
gesture.register({
inputs = { gesture.down() },
can_match = function()
error("can_match error")
end,
action = "",
})

local ok, err = pcall(function()
gesture.draw()
end)
assert.is_false(ok)
assert.match("can_match error", err)
assert.window_count(1)
end)
end)

describe("gesture.finish()", function()
Expand All @@ -575,6 +608,31 @@ describe("gesture.finish()", function()
assert.is_false(called)
end)

it("raises error if match raises error", function()
local for_finish = false
gesture.register({
match = function()
if not for_finish then
return nil
end
error("match error")
end,
can_match = function()
return true
end,
action = "",
})

gesture.draw()

local ok, err = pcall(function()
for_finish = true
gesture.finish()
end)
assert.is_false(ok)
assert.match("match error", err)
end)

it("raises error if action raises error", function()
gesture.register({
inputs = { gesture.down() },
Expand Down

0 comments on commit 1e7a227

Please sign in to comment.