Skip to content

Commit

Permalink
feat: add actions for loaded scopes window
Browse files Browse the repository at this point in the history
  • Loading branch information
Calvin Bochulak authored and Calvin Bochulak committed Mar 1, 2024
1 parent 143d24d commit a0fb01d
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 25 deletions.
44 changes: 31 additions & 13 deletions lua/grapple.lua
Original file line number Diff line number Diff line change
Expand Up @@ -316,23 +316,34 @@ end

---Clear all tags for a given scope
---By default, uses the current scope
---@param opts? { scope?: string }
---@param opts? { scope?: string, id?: string }
function Grapple.reset(opts)
local App = require("grapple.app")

opts = opts or {}

local app = App.get()
local scope, err = app.scope_manager:get_resolved(opts.scope or app.settings.scope)
if not scope then
---@diagnostic disable-next-line: param-type-mismatch
return vim.notify(err, vim.log.levels.ERROR)

---@type string
local id
if opts.id then
id = opts.id
else
local scope, err = app.scope_manager:get_resolved(opts.scope or app.settings.scope)
if not scope then
---@diagnostic disable-next-line: param-type-mismatch
return vim.notify(err, vim.log.levels.ERROR)
end

id = scope.id
end

---@diagnostic disable-next-line: redefined-local
local err = app.tag_manager:reset(scope.id)
if not id then
return vim.notify(string.format("must provide a valid scope or id: %s", vim.inspect(opts)))
end

local err = app.tag_manager:reset(id)
if err then
---@diagnostic disable-next-line: param-type-mismatch
vim.notify(err, vim.log.levels.ERROR)
end
end
Expand All @@ -351,13 +362,13 @@ function Grapple.use_scope(scope)
local App = require("grapple.app")
local app = App.get()

local scope, err = app.scope_manager:get(scope)
if not scope then
local resolved, err = app.scope_manager:get(scope)
if not resolved then
---@diagnostic disable-next-line: param-type-mismatch
return vim.notify(err, vim.log.levels.ERROR)
end

app.settings:update({ scope = scope.name })
app.settings:update({ scope = resolved.name })
end

---@param scope? string
Expand Down Expand Up @@ -387,15 +398,22 @@ end

---Open a floating window populated with all tags for a given scope
---By default, uses the current scope
---@param opts? { scope?: string }
---@param opts? { scope?: string, id?: string }
function Grapple.open_tags(opts)
local App = require("grapple.app")
local TagContent = require("grapple.tag_content")

opts = opts or {}

local app = App.get()
local scope, err = app.scope_manager:get_resolved(opts.scope or app.settings.scope)

local scope, err
if opts.id then
scope, err = app.scope_manager:lookup(opts.id)
else
scope, err = app.scope_manager:get_resolved(opts.scope or app.settings.scope)
end

if not scope then
---@diagnostic disable-next-line: param-type-mismatch
return vim.notify(err, vim.log.levels.ERROR)
Expand Down
14 changes: 14 additions & 0 deletions lua/grapple/container_actions.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
local ScopeActions = {}

---@class grapple.action.container_options
---
---User-provided information
---@field id? string

---@param opts grapple.action.container_options
---@return string? error
function ScopeActions.select(opts)
require("grapple").open_tags({ id = opts.id })
end

return ScopeActions
6 changes: 3 additions & 3 deletions lua/grapple/container_content.lua
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function ContainerContent:entities()
---@param cont_a grapple.tag_container
---@param cont_b grapple.tag_container
local function by_name(cont_a, cont_b)
return string.lower(cont_a.name) < string.lower(cont_b.name)
return string.lower(cont_a.id) < string.lower(cont_b.id)
end

local containers = vim.tbl_values(self.tag_manager.containers)
Expand All @@ -79,14 +79,14 @@ function ContainerContent:create_entry(container, index)
local id = string.format("/%03d", index)

-- In compliance with "grapple" syntax
local line = string.format("%s %s", id, container.name)
local line = string.format("%s %s", id, container.id)
local min_col = assert(string.find(line, "%s")) -- width of id

---@type grapple.window.entry
local entry = {
---@class grapple.scope_content.data
data = {
name = container.name,
id = container.id,
},

line = line,
Expand Down
16 changes: 15 additions & 1 deletion lua/grapple/scope_manager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ local Scope = require("grapple.scope")
---@field tag_manager grapple.tag_manager
---@field cache grapple.cache
---@field scopes table<string, grapple.scope>
---@field resolved_lookup table<string, grapple.resolved_scope>
local ScopeManager = {}
ScopeManager.__index = ScopeManager

Expand All @@ -15,6 +16,7 @@ function ScopeManager:new(tag_manager, cache)
tag_manager = tag_manager,
cache = cache,
scopes = {},
resolved_lookup = {},
}, self)
end

Expand All @@ -26,12 +28,23 @@ end
---@return grapple.scope | nil, string? error
function ScopeManager:get(name)
if not self:exists(name) then
return nil, string.format("Could not find scope %s", name)
return nil, string.format("could not find scope: %s", name)
end

return self.scopes[name], nil
end

---@param id string
---@return grapple.resolved_scope | nil, string? error
function ScopeManager:lookup(id)
local resolved = self.resolved_lookup[id]
if not resolved then
return nil, string.format("could not find resolved scope for id: %s", id)
end

return self.resolved_lookup[id], nil
end

---@param name string scope name
---@return grapple.resolved_scope | nil, string? error
function ScopeManager:get_resolved(name)
Expand All @@ -52,6 +65,7 @@ function ScopeManager:get_resolved(name)
end

self.cache:store(name, resolved)
self.resolved_lookup[resolved.id] = resolved

return resolved
end
Expand Down
16 changes: 14 additions & 2 deletions lua/grapple/settings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ local DEFAULT_SETTINGS = {
local entry = window:current_entry()
local name = entry.data.name

local err = window:perform(ScopeActions.select, { name = entry.data.name })
local err = window:perform(ScopeActions.select, { name = name })
if err then
return vim.notify(err, vim.log.levels.ERROR)
end
Expand All @@ -223,7 +223,19 @@ local DEFAULT_SETTINGS = {

---Not user documented
---@type grapple.hook_fn
loaded_hook = function(window) end,
loaded_hook = function(window)
local ContainerActions = require("grapple.container_actions")

window:map("n", "<cr>", function()
local entry = window:current_entry()
local id = entry.data.id

local err = window:perform(ContainerActions.select, { id = id })
if err then
return vim.notify(err, vim.log.levels.ERROR)
end
end, { desc = "" })
end,

---Additional window options for Grapple windows
---@type grapple.vim.win_opts
Expand Down
12 changes: 6 additions & 6 deletions lua/grapple/tag_container.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ local Tag = require("grapple.tag")
---@field index integer

---@class grapple.tag_container
---@field name string
---@field id string
---@field tags grapple.tag[]
---@field paths_index table<string, grapple.tag>
---@field names_index table<string, grapple.tag>
local TagContainer = {}
TagContainer.__index = TagContainer

---@param name string
---@param id string
---@return grapple.tag_container
function TagContainer:new(name)
function TagContainer:new(id)
return setmetatable({
name = name,
id = id,
tags = {},
paths_index = {},
names_index = {},
Expand Down Expand Up @@ -219,7 +219,7 @@ function TagContainer:into_table()

---@class grapple.tag.container.format
return {
name = self.name,
id = self.id,
tags = vim.tbl_map(into_table, self.tags),
}
end
Expand All @@ -228,7 +228,7 @@ end
---@param tbl grapple.tag.container.format
---@return grapple.tag_container | nil, string? error
function TagContainer.from_table(tbl)
local container = TagContainer:new(tbl.name)
local container = TagContainer:new(tbl.id)

for _, tag_tbl in ipairs(tbl.tags) do
local tag, err = Tag.from_table(tag_tbl)
Expand Down

0 comments on commit a0fb01d

Please sign in to comment.