Skip to content

Commit b619649

Browse files
authored
Merge pull request #22 from mhiro2/fix/path-types-health-docs-consistency
feat(health): Add config-aware diagnostics and align path display behavior
2 parents c73aac6 + b9fda3b commit b619649

6 files changed

Lines changed: 206 additions & 8 deletions

File tree

doc/peekstack.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ Built-in provider names:
399399
`require("peekstack").register_provider(name, fn)`
400400
Register a custom location provider.
401401
>lua
402-
require("peekstack").register_provider("my.provider", function(cb)
402+
require("peekstack").register_provider("my.provider", function(ctx, cb)
403403
cb({ { uri = "file:///path", range = { ... } } })
404404
end)
405405
<
@@ -570,6 +570,9 @@ HEALTH *peekstack-health*
570570
Run `:checkhealth peekstack` to verify requirements:
571571
- Neovim >= 0.10
572572
- `rg` executable (optional, for grep.search)
573+
- Configured picker backend availability (telescope / fzf-lua / snacks)
574+
- Persist setup and git repository detection
575+
- Tree-sitter context parser availability (when `ui.title.context` is enabled)
573576

574577
==============================================================================
575578
vim:tw=78:ts=8:ft=help:norl:

lua/peekstack/commands.lua

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,22 @@ function M.setup()
147147
vim.api.nvim_create_user_command("PeekstackHistory", function()
148148
local stack = require("peekstack.core.stack")
149149
local loc = require("peekstack.core.location")
150+
local cfg = require("peekstack.config").get()
150151
local history = stack.history_list()
151152
if #history == 0 then
152153
notify.info("No history entries")
153154
return
154155
end
156+
local ui_path = cfg.ui.path or {}
157+
---@type PeekstackDisplayTextOpts
158+
local dt_opts = {
159+
path_base = ui_path.base,
160+
max_width = ui_path.max_width,
161+
}
155162
local items = {}
156163
for i = #history, 1, -1 do
157164
local entry = history[i]
158-
local label = entry.title or loc.display_text(entry.location, 0)
165+
local label = entry.title or loc.display_text(entry.location, 0, dt_opts)
159166
table.insert(items, { idx = i, label = label, entry = entry })
160167
end
161168
vim.ui.select(items, {

lua/peekstack/health.lua

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
local M = {}
22

3+
---@type table<string, string>
4+
local PICKER_MODULES = {
5+
telescope = "telescope",
6+
["fzf-lua"] = "fzf-lua",
7+
snacks = "snacks",
8+
}
9+
310
function M.check()
411
vim.health.start("peekstack")
512

@@ -14,6 +21,54 @@ function M.check()
1421
else
1522
vim.health.warn("rg not found (grep.search will be unavailable)")
1623
end
24+
25+
local ok, cfg_mod = pcall(require, "peekstack.config")
26+
if not ok then
27+
return
28+
end
29+
local cfg = cfg_mod.get()
30+
31+
-- Picker backend
32+
local backend = cfg.picker and cfg.picker.backend
33+
if backend and backend ~= "builtin" then
34+
local plugin_name = PICKER_MODULES[backend]
35+
if plugin_name then
36+
local has = pcall(require, plugin_name)
37+
if has then
38+
vim.health.ok("picker backend '" .. backend .. "' available")
39+
else
40+
vim.health.warn("picker backend '" .. backend .. "' is configured but the plugin is not installed")
41+
end
42+
else
43+
vim.health.warn("unknown picker backend '" .. backend .. "'")
44+
end
45+
end
46+
47+
-- Persist
48+
local persist = cfg.persist
49+
if persist and persist.enabled then
50+
local fs = require("peekstack.util.fs")
51+
local repo = fs.repo_root()
52+
if repo then
53+
vim.health.ok("persist enabled (repo: " .. repo .. ")")
54+
else
55+
vim.health.warn("persist enabled but not inside a git repository; sessions will use cwd-based storage")
56+
end
57+
if persist.auto and persist.auto.enabled then
58+
vim.health.ok("auto persist enabled (session: " .. (persist.auto.session_name or "auto") .. ")")
59+
end
60+
end
61+
62+
-- Tree-sitter context
63+
local title = cfg.ui and cfg.ui.title
64+
if title and title.context and title.context.enabled then
65+
local ts_ok = pcall(vim.treesitter.get_parser, 0)
66+
if ts_ok then
67+
vim.health.ok("tree-sitter context enabled (parser available for current buffer)")
68+
else
69+
vim.health.info("tree-sitter context enabled but no parser for the current buffer filetype")
70+
end
71+
end
1772
end
1873

1974
return M

lua/peekstack/types.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,22 @@
3939
---@field id integer
4040
---@field bufnr integer
4141
---@field source_bufnr integer
42-
---@field winid integer
42+
---@field winid integer?
4343
---@field location PeekstackLocation
4444
---@field diagnostics? PeekstackDiagnosticExtmarks
4545
---@field origin { winid: integer, bufnr: integer, row: integer, col: integer }
4646
---@field origin_bufnr integer
4747
---@field origin_is_popup boolean
4848
---@field parent_popup_id? integer
49-
---@field title string
49+
---@field title string?
5050
---@field title_chunks? PeekstackTitleChunk[]
5151
---@field pinned boolean
5252
---@field buffer_mode "copy"|"source"
5353
---@field line_offset integer
5454
---@field created_at integer
5555
---@field last_active_at integer
5656
---@field ephemeral boolean
57-
---@field win_opts PeekstackRenderWinOpts
57+
---@field win_opts PeekstackRenderWinOpts?
5858

5959
---@class PeekstackStackModel
6060
---@field root_winid integer

lua/peekstack/ui/render.lua

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,16 @@ local function build_title(location)
117117
icon = icons_cfg.map[provider_name] or icons_cfg.map[category] or ""
118118
end
119119

120-
local path = str.shorten_path(fs.uri_to_fname(location.uri))
121-
local path_max_width = ui.path and ui.path.max_width
122-
if is_diagnostic and type(path_max_width) == "number" and path_max_width > 0 then
120+
local ui_path = ui.path or {}
121+
local raw_path = fs.uri_to_fname(location.uri)
122+
local path
123+
if ui_path.base then
124+
path = str.relative_path(raw_path, ui_path.base)
125+
else
126+
path = str.shorten_path(raw_path)
127+
end
128+
local path_max_width = ui_path.max_width
129+
if type(path_max_width) == "number" and path_max_width > 0 then
123130
path = str.truncate_middle(path, path_max_width)
124131
end
125132
local line = (location.range.start.line or 0) + 1

tests/health_spec.lua

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
describe("peekstack.health", function()
2+
local health = require("peekstack.health")
3+
local config = require("peekstack.config")
4+
5+
local original_health_start
6+
local original_health_ok
7+
local original_health_warn
8+
local original_health_error
9+
local original_health_info
10+
local original_executable
11+
local original_has
12+
13+
---@type string[]
14+
local messages
15+
16+
before_each(function()
17+
messages = {}
18+
original_health_start = vim.health.start
19+
original_health_ok = vim.health.ok
20+
original_health_warn = vim.health.warn
21+
original_health_error = vim.health.error
22+
original_health_info = vim.health.info
23+
original_executable = vim.fn.executable
24+
original_has = vim.fn.has
25+
26+
vim.health.start = function() end
27+
vim.health.ok = function(msg)
28+
table.insert(messages, "ok:" .. msg)
29+
end
30+
vim.health.warn = function(msg)
31+
table.insert(messages, "warn:" .. msg)
32+
end
33+
vim.health.error = function(msg)
34+
table.insert(messages, "error:" .. msg)
35+
end
36+
vim.health.info = function(msg)
37+
table.insert(messages, "info:" .. msg)
38+
end
39+
end)
40+
41+
after_each(function()
42+
vim.health.start = original_health_start
43+
vim.health.ok = original_health_ok
44+
vim.health.warn = original_health_warn
45+
vim.health.error = original_health_error
46+
vim.health.info = original_health_info
47+
vim.fn.executable = original_executable
48+
vim.fn.has = original_has
49+
config.setup({})
50+
end)
51+
52+
it("reports ok for nvim version and rg when available", function()
53+
vim.fn.has = function()
54+
return 1
55+
end
56+
vim.fn.executable = function()
57+
return 1
58+
end
59+
config.setup({})
60+
61+
health.check()
62+
63+
assert.is_true(vim.list_contains(messages, "ok:nvim >= 0.10"))
64+
assert.is_true(vim.list_contains(messages, "ok:rg available"))
65+
end)
66+
67+
it("warns when rg is not available", function()
68+
vim.fn.has = function()
69+
return 1
70+
end
71+
vim.fn.executable = function()
72+
return 0
73+
end
74+
config.setup({})
75+
76+
health.check()
77+
78+
local found = false
79+
for _, msg in ipairs(messages) do
80+
if msg:find("warn:rg not found") then
81+
found = true
82+
end
83+
end
84+
assert.is_true(found)
85+
end)
86+
87+
it("warns when configured picker backend is not installed", function()
88+
vim.fn.has = function()
89+
return 1
90+
end
91+
vim.fn.executable = function()
92+
return 1
93+
end
94+
config.setup({ picker = { backend = "telescope" } })
95+
96+
health.check()
97+
98+
local found = false
99+
for _, msg in ipairs(messages) do
100+
if msg:find("warn:") and msg:find("telescope") and msg:find("not installed") then
101+
found = true
102+
end
103+
end
104+
assert.is_true(found)
105+
end)
106+
107+
it("reports persist status when enabled inside a git repo", function()
108+
vim.fn.has = function()
109+
return 1
110+
end
111+
vim.fn.executable = function()
112+
return 1
113+
end
114+
config.setup({ persist = { enabled = true } })
115+
116+
health.check()
117+
118+
local found_persist = false
119+
for _, msg in ipairs(messages) do
120+
if msg:find("persist") then
121+
found_persist = true
122+
end
123+
end
124+
assert.is_true(found_persist)
125+
end)
126+
end)

0 commit comments

Comments
 (0)