Skip to content

Commit

Permalink
refactor: make statusline generally available, not just lualine
Browse files Browse the repository at this point in the history
  • Loading branch information
cbochs committed Mar 19, 2024
1 parent 38efa7e commit 0795b55
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 78 deletions.
42 changes: 40 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,45 @@ Then use this command to see the grapple tags for the project in a telescope win

A statusline component can be easily added to show whether a buffer is tagged.

**[lualine.nvim](https://github.com/nvim-lualine/lualine.nvim) statusline**
**API**:

- `require("grapple").statusline(opts)`

**`opts?`**: `grapple.statusline.options` (default: `settings.statusline`)

- **`icon`**: `string` (default: `"󰛢"`)
- **`active`**: `string` (default: `[%s]`)
- **`inactive`**: `string` (default: `" %s"`)
- **`include_icon`**: `boolean` (default: `true`)

**Also available**:

- `require("grapple").name_or_index()`
- `require("grapple").exists()`

<details>
<summary><b>Examples</b></summary>

```lua
require("grapple").statusline()
-- Returns "󰛢 [1] 2 3 4"

require("grapple").name_or_index()
-- Returns "1" or "bob"

-- Modify the statusline options
require("grapple").setup({
statusline = {
icon = "G",
active = "|%s|",
inactive = " %s "
}
})
```

</details>

#### Lualine Component

<table>
<tr>
Expand Down Expand Up @@ -913,7 +951,7 @@ require("lualine").setup({
sections = {
lualine_b = {
{
require("grapple").statusline,
require("grapple").name_or_index,
cond = require("grapple").exists
}
}
Expand Down
55 changes: 41 additions & 14 deletions lua/grapple.lua
Original file line number Diff line number Diff line change
Expand Up @@ -319,20 +319,6 @@ function Grapple.name_or_index(opts)
return name_or_index
end

---Return a formatted string to be displayed on the statusline
---@return string | nil
function Grapple.statusline()
local App = require("grapple.app")
local app = App.get()

local icon = app.settings.icons and "󰛢 " or ""

local key = Grapple.name_or_index()
if key then
return icon .. key
end
end

---Return the tags for a given scope. Used for integrations
---@param opts? { scope?: string }
---@return grapple.tag[] | nil, string? error
Expand All @@ -356,6 +342,47 @@ function Grapple.tags(opts)
return tags, nil
end

---Return a formatted string to be displayed on the statusline
---@param opts grapple.statusline.options
---@return string | nil
function Grapple.statusline(opts)
local App = require("grapple.app")
local app = App.get()

opts = vim.tbl_deep_extend("keep", opts or {}, app.settings.statusline)

local tags, err = Grapple.tags()
if not tags then
return err
end

local current = Grapple.find({ buffer = 0 })

local quick_select = app.settings:quick_select()
local output = {}

for i, tag in ipairs(tags) do
-- stylua: ignore
local tag_str = tag.name and tag.name
or quick_select[i] and quick_select[i]
or i

local tag_fmt = opts.inactive
if current and current.path == tag.path then
tag_fmt = opts.active
end

table.insert(output, string.format(tag_fmt, tag_str))
end

local statusline = table.concat(output)
if opts.include_icon then
statusline = string.format("%s %s", opts.icon, statusline)
end

return statusline
end

---Reset tags for a given (scope) name or loaded scope (id)
---By default, uses the current scope
---@param opts? { scope?: string, id?: string }
Expand Down
13 changes: 13 additions & 0 deletions lua/grapple/settings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,19 @@ local DEFAULT_SETTINGS = {
"",
},
},

---Not user documented
---Default statusline options
---@class grapple.statusline.options
statusline = {
icon = "󰛢",
inactive = " %s ",
active = "[%s]",

-- Mostly for lualine integration. Lualine will automatically prepend
-- the icon to the returned output
include_icon = true,
},
}

Settings.__index = function(tbl, key)
Expand Down
11 changes: 8 additions & 3 deletions lua/grapple/tag.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,27 @@ local Path = require("grapple.path")
---@field path string absolute path
---@field name string | nil (optional) tag name
---@field cursor integer[] | nil (optional) (1, 0)-indexed cursor position
---@field frozen boolean
local Tag = {}
Tag.__index = Tag

---@param path string
---@param name? string
---@param cursor? integer[]
function Tag:new(path, name, cursor)
---@param frozen? boolean
function Tag:new(path, name, cursor, frozen)
return setmetatable({
path = path,
name = name,
cursor = cursor,
frozen = frozen,
}, self)
end

function Tag:update()
self.cursor = vim.api.nvim_win_get_cursor(0)
if not self.frozen then
self.cursor = vim.api.nvim_win_get_cursor(0)
end
end

---@param command? fun(path: string)
Expand All @@ -43,7 +48,7 @@ function Tag:select(command)
}

-- If the cursor has already been set, don't set again
if current_cursor[1] == 1 or current_cursor[2] == 0 then
if self.frozen or (current_cursor[1] == 1 and current_cursor[2] == 0) then
pcall(vim.api.nvim_win_set_cursor, 0, cursor)
end
end
Expand Down
72 changes: 13 additions & 59 deletions lua/lualine/components/grapple.lua
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
---@class grapple.lualine.component
---@field options grapple.lualine.options
---@field options grapple.statusline.options
local Component = require("lualine.component"):extend()

---@class grapple.lualine.options
local defaults = {
icon = "󰛢",
inactive = " %s ",
active = "[%s]",
}

---@class grapple.lualine.options
---@param opts? grapple.statusline.options
function Component:init(opts)
opts = vim.tbl_deep_extend("keep", opts or {}, defaults)
Component.super:init(opts)
end

---@return string | nil
function Component:update_status()
if package.loaded["grapple"] == nil then
return
Expand All @@ -25,59 +18,20 @@ function Component:update_status()
return
end

local tags, err = grapple.tags()
if not tags then
return err
end

local current = grapple.find({ buffer = 0 })
-- Lazyily add statusline options to the component
if not self.options.icon or not self.options.active or not self.options.inactive then
local App = require("grapple.app")
local app = App.get()

local App = require("grapple.app")
local app = App.get()
local quick_select = app.settings:quick_select()
local output = {}
for i, tag in ipairs(tags) do
-- stylua: ignore
local tag_str = tag.name and tag.name
or quick_select[i] and quick_select[i]
or i

local tag_fmt = self.options.inactive
if current and current.path == tag.path then
tag_fmt = self.options.active
end
table.insert(output, string.format(tag_fmt, tag_str))
self.options = vim.tbl_deep_extend("keep",
self.options,
{ include_icon = false },
app.settings.statusline
)
end

return table.concat(output)
return grapple.statusline(self.options)
end

return Component

--[[
local lualine_require = require("lualine_require")
local M = lualine_require.require("lualine.component"):extend()
local hl = require("harpoon-lualine")
local default_options = {
icon = "󰀱 ",
indicators = { "1", "2", "3", "4" },
active_indicators = { "[1]", "[2]", "[3]", "[4]" },
}
function M:init(options)
M.super.init(self, options)
self.options = vim.tbl_deep_extend("keep", self.options or {}, default_options)
end
function M:update_status()
local harpoon_loaded = package.loaded["harpoon"] ~= nil
if not harpoon_loaded then
return "Harpoon not loaded"
end
return hl.status(self.options)
end
return M--]]

0 comments on commit 0795b55

Please sign in to comment.