Skip to content

Commit 5e85367

Browse files
committed
feat: add scope priority
1 parent a274117 commit 5e85367

File tree

3 files changed

+66
-25
lines changed

3 files changed

+66
-25
lines changed

lua/grapple/settings.lua

+57-18
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,13 @@ local DEFAULT_SETTINGS = {
5757

5858
---@class grapple.scope_definition
5959
---@field name string
60-
---@field force? boolean
6160
---@field desc? string
61+
---@field force? boolean
6262
---@field fallback? string name of scope to fall back on
6363
---@field cache? grapple.cache.options | boolean
64+
---@field priority? integer
65+
---@field hidden? boolean
66+
---@field delete? boolean
6467
---@field resolver grapple.scope_resolver
6568

6669
---Default scopes provided by Grapple
@@ -483,32 +486,68 @@ end
483486
---@return grapple.scope_definition[]
484487
---@diagnostic disable-next-line: assign-type-mismatch
485488
function Settings:scopes()
486-
-- HACK: Define the order so that fallbacks are defined first
487-
local default_order = {
488-
"global",
489-
"cwd",
490-
"git",
491-
"git_branch",
492-
"lsp",
493-
}
494-
489+
---@type grapple.scope_definition[]
495490
local scopes = {}
496491

497-
for _, name in ipairs(default_order) do
498-
local definition = self.inner.default_scopes[name]
492+
-- Lookup table of whether a scope is used as a fallback
493+
---@type table<string, boolean>
494+
local fallback_lookup = {}
495+
496+
-- Add default scopes
497+
for name, definition in pairs(self.inner.default_scopes) do
499498
if definition == false then
500-
table.insert(scopes, { name = name, delete = true })
501-
elseif type(definition) == "table" then
502-
table.insert(scopes, self.inner.default_scopes[name])
503-
else
504-
error(string.format("invalid default scope: %s", vim.inspect(definition)))
499+
definition = { delete = true }
505500
end
501+
502+
definition = vim.tbl_extend("keep", definition, {
503+
name = name,
504+
desc = "",
505+
})
506+
507+
assert(type(definition.name) == "string")
508+
509+
table.insert(scopes, definition)
506510
end
507511

508-
for _, definition in ipairs(self.inner.scopes) do
512+
-- Add user-defined scopes
513+
for name, definition in pairs(self.inner.scopes) do
514+
definition = vim.tbl_extend("keep", definition, {
515+
name = name,
516+
desc = "",
517+
})
518+
519+
assert(type(definition.name) == "string")
520+
521+
if definition.fallback then
522+
fallback_lookup[definition.fallback] = true
523+
end
524+
509525
table.insert(scopes, definition)
510526
end
511527

528+
-- Prioritize scope loading
529+
for _, scope in ipairs(scopes) do
530+
if scope.priority then
531+
-- Skip. Already given an explicit priority
532+
elseif not scope.fallback then
533+
scope.priority = 1000
534+
elseif fallback_lookup[scope.name] then
535+
scope.priority = 100
536+
else
537+
scope.priority = 1
538+
end
539+
end
540+
541+
local function by_priority(scope_a, scope_b)
542+
if scope_a.priority == scope_b.priority then
543+
return string.lower(scope_a.name) < string.lower(scope_b.name)
544+
else
545+
return scope_a.priority > scope_b.priority
546+
end
547+
end
548+
549+
table.sort(scopes, by_priority)
550+
512551
return scopes
513552
end
514553

tests/grapple/app_spec.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ describe("App", function()
88
app:update()
99
local names = vim.tbl_keys(app.scope_manager.scopes)
1010
table.sort(names, Util.as_lower)
11-
assert.same({ "cwd", "git", "git_branch", "global", "lsp" }, names)
11+
assert.same({ "cwd", "git", "git_branch", "global", "lsp", "static" }, names)
1212
end)
1313
end)
1414
end)

tests/grapple/settings_spec.lua

+8-6
Original file line numberDiff line numberDiff line change
@@ -38,35 +38,37 @@ describe("Settings", function()
3838
end)
3939

4040
describe(".scopes", function()
41-
it("has the correct scopes default", function()
41+
it("has the correct scope defaults in priority order", function()
4242
local settings = Settings:new()
4343
-- stylua: ignore
4444
local names = vim.tbl_map(function(def) return def.name end, settings:scopes())
45-
assert.same({ "global", "cwd", "git", "git_branch", "lsp" }, names)
45+
assert.same({ "cwd", "global", "static", "git", "git_branch", "lsp" }, names)
4646
end)
4747

4848
it("merges default and user-defined scopes", function()
4949
local settings = Settings:new()
50-
settings:update({ scopes = { { name = "test" } } })
50+
settings:update({ scopes = { test = {} } })
5151
-- stylua: ignore
5252
local names = vim.tbl_map(function(def) return def.name end, settings:scopes())
53-
assert.same({ "global", "cwd", "git", "git_branch", "lsp", "test" }, names)
53+
assert.same({ "cwd", "global", "static", "test", "git", "git_branch", "lsp" }, names)
5454
end)
5555

5656
it("overrides default scope definitions", function()
5757
local settings = Settings:new()
5858
settings:update({ default_scopes = { global = { name = "bob" } } })
5959
-- stylua: ignore
6060
local names = vim.tbl_map(function(def) return def.name end, settings:scopes())
61-
assert.same({ "bob", "cwd", "git", "git_branch", "lsp" }, names)
61+
assert.same({ "bob", "cwd", "static", "git", "git_branch", "lsp" }, names)
6262
end)
6363

6464
it("marks default scopes to be deleted", function()
6565
local settings = Settings:new()
6666
settings:update({ default_scopes = { cwd = false } })
6767
-- stylua: ignore
6868
local deleted = vim.tbl_filter(function(def) return def.delete end, settings:scopes())
69-
assert.same({ { name = "cwd", delete = true } }, deleted)
69+
assert.same(1, #deleted)
70+
assert.same("cwd", deleted[1].name)
71+
assert.same(true, deleted[1].delete)
7072
end)
7173
end)
7274
end)

0 commit comments

Comments
 (0)