From fd0a433f59ddcd6c6d1f8de83db2da1079b93868 Mon Sep 17 00:00:00 2001 From: jgmdev Date: Thu, 12 May 2022 20:33:01 -0400 Subject: [PATCH 1/2] object: made is() stricter and added extends() Currently some plugins had/have issues with predicates that check if active view is a docview to perform certain operations like draw in the case of minimap or lineguide. Since is() was checking the entire inheritance tree it was returning true for views that inherit from the same parent, which caused CommandView to be matched along DocView, etc... This change does the following to solve the issue: * Make Object:is() only match the top level parent of the object which is more in line with what one would expect from a method named 'is'. * Introduces Object:extends() which keeps the same functionality that Object:is() offered before. --- data/core/object.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/data/core/object.lua b/data/core/object.lua index 0941ce5d..a57ac9e8 100644 --- a/data/core/object.lua +++ b/data/core/object.lua @@ -21,6 +21,14 @@ end function Object:is(T) + if getmetatable(self) == T then + return true + end + return false +end + + +function Object:extends(T) local mt = getmetatable(self) while mt do if mt == T then From 59d91087e9b1ff3990f2d5543432531ee11ae5b0 Mon Sep 17 00:00:00 2001 From: jgmdev Date: Thu, 12 May 2022 22:15:29 -0400 Subject: [PATCH 2/2] adjust and consolidate duplicated predicate code --- data/core/command.lua | 22 ++++++++++++++++++++-- data/core/contextmenu.lua | 9 +-------- data/core/statusview.lua | 17 +++-------------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/data/core/command.lua b/data/core/command.lua index bdc1ed34..39582de3 100644 --- a/data/core/command.lua +++ b/data/core/command.lua @@ -6,15 +6,33 @@ command.map = {} local always_true = function() return true end -function command.add(predicate, map) +---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 +---return a valid object which is checked against the current active view, the +---sames applies if a table is given. A function that returns a boolean can be +---used instead to perform a custom evaluation, setting to nil means always +---evaluates to true. +--- +---@param predicate string | table | function +---@return function +function command.generate_predicate(predicate) predicate = predicate or always_true if type(predicate) == "string" then predicate = require(predicate) end if type(predicate) == "table" then local class = predicate - predicate = function() return core.active_view:is(class) end + predicate = function() return core.active_view:extends(class) end end + return predicate +end + + +function command.add(predicate, map) + predicate = command.generate_predicate(predicate) for name, fn in pairs(map) do assert(not command.map[name], "command already exists: " .. name) command.map[name] = { predicate = predicate, perform = fn } diff --git a/data/core/contextmenu.lua b/data/core/contextmenu.lua index b1a69d6d..94ef61f8 100644 --- a/data/core/contextmenu.lua +++ b/data/core/contextmenu.lua @@ -39,14 +39,7 @@ local function get_item_size(item) end function ContextMenu:register(predicate, items) - if type(predicate) == "string" then - predicate = require(predicate) - end - if type(predicate) == "table" then - local class = predicate - predicate = function() return core.active_view:is(class) end - end - + predicate = command.generate_predicate(predicate) local width, height = 0, 0 --precalculate the size of context menu for i, item in ipairs(items) do if item ~= DIVIDER then diff --git a/data/core/statusview.lua b/data/core/statusview.lua index b1a45385..542522c7 100644 --- a/data/core/statusview.lua +++ b/data/core/statusview.lua @@ -113,9 +113,6 @@ function StatusView.Item:hide() self.visible = false end ---Show the item on the status bar. function StatusView.Item:show() self.visible = true end ----Function assiged by default when user provides a nil predicate. -local function predicate_always_true() return true end - ---A condition to evaluate if the item should be displayed. If a string ---is given it is treated as a require import that should return a valid object ---which is checked against the current active view, the sames applies if a @@ -123,15 +120,7 @@ local function predicate_always_true() return true end ---perform a custom evaluation, setting to nil means always evaluates to true. ---@param predicate string | table | StatusView.Item.predicate function StatusView.Item:set_predicate(predicate) - predicate = predicate or predicate_always_true - if type(predicate) == "string" then - predicate = require(predicate) - end - if type(predicate) == "table" then - local class = predicate - predicate = function() return core.active_view:is(class) end - end - self.predicate = predicate + self.predicate = command.generate_predicate(predicate) end @@ -655,14 +644,14 @@ local function merge_deprecated_items(destination, items, alignment) local position = alignment == StatusView.Item.LEFT and "left" or "right" local item_start = StatusView.Item( - predicate_always_true, + nil, "deprecated:"..position.."-start", alignment ) item_start.get_item = items_start local item_end = StatusView.Item( - predicate_always_true, + nil, "deprecated:"..position.."-end", alignment )