Skip to content

Commit d5c51f4

Browse files
committed
feat: enhance icon configuration and highlight system
- add support for configurable icons and highlights in symbols configuration - implement dynamic width calculation with percentage support - improve highlight handling with namespace-based extmarks - add devicons integration for file-like nodes - update lsp command calls to use client:request syntax - refactor preview and hover windows with markdown support - normalize configuration options in setup function - add tree guide line highlights with configurable highlight group - fix buffer and window option handling with nvim_set_option_value
1 parent 5c37c95 commit d5c51f4

File tree

9 files changed

+268
-66
lines changed

9 files changed

+268
-66
lines changed

README.md

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,50 @@
1313
ft = "java",
1414
dependencies = "mfussenegger/nvim-jdtls",
1515
config = function()
16-
require("java-deps").setup({})
16+
require("java-deps").setup({
17+
symbols = {
18+
icons = {
19+
NodeKind = {
20+
-- project 节点改成文件夹图标
21+
Project = "󰉋",
22+
-- 也支持同时覆盖 icon 和高亮
23+
Workspace = { icon = "󱁐", hl = "Directory" },
24+
},
25+
TypeKind = {
26+
Class = "󰌗",
27+
Interface = { icon = "", hl = "Function" },
28+
},
29+
},
30+
highlights = {
31+
default_icon = "Identifier",
32+
NodeKind = {
33+
File = "Directory",
34+
Package = "Directory",
35+
},
36+
},
37+
},
38+
highlights = {
39+
LineGuide = { link = "Comment" },
40+
},
41+
})
1742
end,
1843
}
1944

2045
```
2146

47+
可配置项说明:
48+
49+
- `symbols.icons.<分类>.<枚举名>`: 覆盖图标,值可以是字符串,或者 `{ icon = "...", hl = "..." }`
50+
- `symbols.highlights.default_icon`: 没有单独指定时,图标默认使用的高亮组
51+
- `symbols.highlights.<分类>.<枚举名>`: 仅覆盖某个图标的高亮组
52+
- `highlights.LineGuide`: 定义 `JavaDepsLineGuide` 高亮组
53+
54+
目前支持的分类:
55+
56+
- `symbols.icons.NodeKind`: `Workspace` `Project` `PackageRoot` `Package` `PrimaryType` `CompilationUnit` `ClassFile` `Container` `Folder` `File`
57+
- `symbols.icons.TypeKind`: `Class` `Interface` `Enum`
58+
- `symbols.icons.EntryKind`: `K_SOURCE` `K_BINARY`
59+
2260
- 手动编译 `vscode-java-dependency` (可选)
2361

2462
```sh

lua/java-deps/config.lua

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ local M = {
33
options = {
44
show_guides = true,
55
auto_close = false,
6-
width = 40,
6+
width = "30%",
77
show_numbers = false,
88
show_relative_numbers = false,
99
preview_bg_highlight = "Pmenu",
@@ -17,13 +17,41 @@ local M = {
1717
toggle_fold = "o",
1818
},
1919
symbols = {
20-
icons = {},
20+
icons = {
21+
NodeKind = {},
22+
TypeKind = {},
23+
EntryKind = {},
24+
},
25+
highlights = {
26+
default_icon = "Type",
27+
NodeKind = {},
28+
TypeKind = {},
29+
EntryKind = {},
30+
},
31+
},
32+
highlights = {
33+
LineGuide = { link = "Comment" },
2134
},
2235
},
2336
}
2437
M.setup = function(config)
2538
if config then
26-
local new_config = vim.tbl_deep_extend("force", M, config)
39+
local normalized = vim.deepcopy(config)
40+
local option_keys = vim.tbl_keys(M.options)
41+
42+
for _, key in ipairs(option_keys) do
43+
if normalized[key] ~= nil then
44+
normalized.options = normalized.options or {}
45+
if type(normalized[key]) == "table" then
46+
normalized.options[key] = vim.tbl_deep_extend("force", normalized.options[key] or {}, normalized[key])
47+
else
48+
normalized.options[key] = normalized[key]
49+
end
50+
normalized[key] = nil
51+
end
52+
end
53+
54+
local new_config = vim.tbl_deep_extend("force", M, normalized)
2755
for key, value in pairs(new_config) do
2856
M[key] = value
2957
end
@@ -47,6 +75,16 @@ function M.get_split_command()
4775
end
4876
end
4977
function M.get_window_width()
50-
return M.options.width
78+
local width = M.options.width
79+
if type(width) == "string" then
80+
local percent = tonumber(width:match("^%s*(%d+)%%%s*$"))
81+
if percent ~= nil then
82+
return math.max(1, math.floor(vim.o.columns * percent / 100))
83+
end
84+
end
85+
if type(width) == "number" then
86+
return math.max(1, math.floor(width))
87+
end
88+
return math.max(1, math.floor(vim.o.columns * 0.3))
5189
end
5290
return M

lua/java-deps/highlight.lua

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,31 @@
1+
local config = require("java-deps.config")
2+
13
local M = {
24
items = {
35
nsid = vim.api.nvim_create_namespace("java-deps-items"),
4-
highlights = {
5-
LineGuide = { link = "Comment" },
6-
},
76
},
87
}
98

109
M.init_hl = function()
11-
local ihlf = function(hls)
12-
for name, hl in pairs(hls.highlights) do
13-
if vim.fn.hlexists("JavaDeps" .. name) == 0 then
14-
vim.api.nvim_set_hl(0, "JavaDeps" .. name, { link = hl.link })
15-
end
16-
end
10+
local highlights = config.options.highlights or {}
11+
for name, hl in pairs(highlights) do
12+
vim.api.nvim_set_hl(0, "JavaDeps" .. name, hl)
1713
end
18-
ihlf(M.items)
1914
end
2015
M.clear_all_ns = function(bufnr)
21-
vim.api.nvim_buf_clear_namespace(bufnr, -1, 0, -1)
16+
vim.api.nvim_buf_clear_namespace(bufnr, M.items.nsid, 0, -1)
2217
end
2318

2419
---@param bufnr number
2520
---@param hl_info table
26-
---@param nodes TreeItem[]
27-
function M.add_item_highlights(bufnr, hl_info, nodes)
21+
---@param _ TreeItem[]
22+
function M.add_item_highlights(bufnr, hl_info, _)
2823
for _, line_hl in ipairs(hl_info) do
2924
local line, hl_start, hl_end, hl_type = unpack(line_hl)
30-
vim.api.nvim_buf_add_highlight(bufnr, M.items.nsid, hl_type, line - 1, hl_start, hl_end)
25+
vim.api.nvim_buf_set_extmark(bufnr, M.items.nsid, line - 1, hl_start, {
26+
end_col = hl_end,
27+
hl_group = hl_type,
28+
})
3129
end
3230
end
3331

lua/java-deps/java/lsp-command.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ M.execute_command_async = function(command, callback, bufnr)
3333
end
3434
end
3535
end
36-
client.request("workspace/executeCommand", command, callback, bufnr)
36+
client:request("workspace/executeCommand", command, callback, bufnr)
3737
if co then
3838
return coroutine.yield()
3939
end
@@ -43,7 +43,7 @@ M.execute_command = function(command, bufnr)
4343
if not client then
4444
return
4545
end
46-
local resp = client.request_sync("workspace/executeCommand", command, 20000, bufnr)
46+
local resp = client:request_sync("workspace/executeCommand", command, 20000, bufnr)
4747
if not resp then
4848
return "No response"
4949
end

lua/java-deps/parser.lua

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,20 @@ local function table_to_str(t)
1818
return ret
1919
end
2020

21+
---@param line_number integer
22+
---@param parts string[]
23+
---@param hl_info table
24+
local function add_prefix_highlights(line_number, parts, hl_info)
25+
local col = 0
26+
for _, part in ipairs(parts) do
27+
local start_col, end_col = part:find("%S+")
28+
if start_col ~= nil and end_col ~= nil then
29+
table.insert(hl_info, { line_number, col + start_col - 1, col + end_col, "JavaDepsLineGuide" })
30+
end
31+
col = col + #part
32+
end
33+
end
34+
2135
local guides = {
2236
markers = {
2337
bottom = "",
@@ -66,19 +80,16 @@ function M.get_lines(flattened_outline_items)
6680
line[index] = line[index] .. " "
6781
end
6882

69-
local string_prefix = ""
70-
71-
for _, value in ipairs(line) do
72-
string_prefix = string_prefix .. tostring(value)
73-
end
83+
local string_prefix = table_to_str(line)
84+
add_prefix_highlights(node_line, line, hl_info)
7485

7586
local hl_icon = icons.get_icon(node.data)
7687
local icon = hl_icon.icon
7788
table.insert(lines, string_prefix .. icon .. " " .. node.label)
7889

7990
local hl_start = #string_prefix
8091
local hl_end = #string_prefix + #icon
81-
local hl_type = hl_icon.hl or "Type"
92+
local hl_type = hl_icon.hl or config.options.symbols.highlights.default_icon or "Type"
8293
table.insert(hl_info, { node_line, hl_start, hl_end, hl_type })
8394
node.prefix_length = #string_prefix + #icon + 1
8495
end

lua/java-deps/preview.lua

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ end
7373

7474
local function setup_preview_buf()
7575
local code_buf = vim.api.nvim_win_get_buf(jd.state.code_win)
76-
local ft = vim.api.nvim_buf_get_option(code_buf, "filetype")
76+
local ft = vim.api.nvim_get_option_value("filetype", { buf = code_buf })
7777

7878
local function treesitter_attach()
7979
local ts_highlight = require("nvim-treesitter.highlight")
@@ -84,9 +84,9 @@ local function setup_preview_buf()
8484
-- user might not have tree sitter installed
8585
pcall(treesitter_attach)
8686

87-
vim.api.nvim_buf_set_option(state.preview_buf, "syntax", ft)
88-
vim.api.nvim_buf_set_option(state.preview_buf, "bufhidden", "delete")
89-
vim.api.nvim_win_set_option(state.preview_win, "cursorline", true)
87+
vim.api.nvim_set_option_value("syntax", ft, { buf = state.preview_buf })
88+
vim.api.nvim_set_option_value("bufhidden", "delete", { buf = state.preview_buf })
89+
vim.api.nvim_set_option_value("cursorline", true, { win = state.preview_win })
9090
update_preview(code_buf)
9191
end
9292

@@ -138,13 +138,11 @@ local function update_hover()
138138
{ kind = "markdown", value = "[" .. node.name .. "](" .. node.path .. ")" },
139139
}
140140
local markdown_lines = vim.lsp.util.convert_input_to_markdown_lines(mdstring)
141-
markdown_lines = vim.lsp.util.trim_empty_lines(markdown_lines)
141+
markdown_lines = vim.split(table.concat(markdown_lines, "\n"), "\n", { plain = true, trimempty = true })
142142
if vim.tbl_isempty(markdown_lines) then
143143
markdown_lines = { "###No info available!" }
144144
end
145145

146-
markdown_lines = vim.lsp.util.stylize_markdown(state.hover_buf, markdown_lines, {})
147-
148146
if state.hover_buf ~= nil then
149147
vim.api.nvim_buf_set_lines(state.hover_buf, 0, -1, 0, markdown_lines)
150148
end
@@ -155,21 +153,24 @@ local function setup_hover_buf()
155153
return
156154
end
157155
-- local code_buf = vim.api.nvim_win_get_buf(jd.state.code_win)
158-
-- local ft = vim.api.nvim_buf_get_option(code_buf, "filetype")
159-
-- vim.api.nvim_buf_set_option(state.hover_buf, "syntax", "xml")
160-
vim.api.nvim_buf_set_option(state.hover_buf, "bufhidden", "delete")
161-
vim.api.nvim_win_set_option(state.hover_win, "wrap", true)
162-
vim.api.nvim_win_set_option(state.hover_win, "cursorline", false)
156+
-- local ft = vim.api.nvim_get_option_value("filetype", { buf = code_buf })
157+
-- vim.api.nvim_set_option_value("syntax", "xml", { buf = state.hover_buf })
158+
vim.api.nvim_set_option_value("filetype", "markdown", { buf = state.hover_buf })
159+
vim.api.nvim_set_option_value("bufhidden", "delete", { buf = state.hover_buf })
160+
vim.api.nvim_set_option_value("wrap", true, { win = state.hover_win })
161+
vim.api.nvim_set_option_value("conceallevel", 2, { win = state.hover_win })
162+
vim.api.nvim_set_option_value("cursorline", false, { win = state.hover_win })
163+
pcall(vim.treesitter.start, state.hover_buf, "markdown")
163164
update_hover()
164165
end
165166

166167
local function set_bg_hl()
167168
local winhi = "Normal:" .. config.options.preview_bg_highlight
168-
-- vim.api.nvim_win_set_option(state.preview_win, "winhighlight", winhi)
169-
vim.api.nvim_win_set_option(state.hover_win, "winhighlight", winhi)
169+
-- vim.api.nvim_set_option_value("winhighlight", winhi, { win = state.preview_win })
170+
vim.api.nvim_set_option_value("winhighlight", winhi, { win = state.hover_win })
170171
local winblend = config.options.winblend
171-
-- vim.api.nvim_win_set_option(state.preview_win, "winblend", winblend)
172-
vim.api.nvim_win_set_option(state.hover_win, "winblend", winblend)
172+
-- vim.api.nvim_set_option_value("winblend", winblend, { win = state.preview_win })
173+
vim.api.nvim_set_option_value("winblend", winblend, { win = state.hover_win })
173174
end
174175

175176

lua/java-deps/view.lua

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function View:setup_view()
2525
self.bufnr = vim.api.nvim_create_buf(false, true)
2626

2727
-- delete buffer when window is closed / buffer is hidden
28-
vim.api.nvim_buf_set_option(self.bufnr, "bufhidden", "delete")
28+
vim.api.nvim_set_option_value("bufhidden", "delete", { buf = self.bufnr })
2929
-- create a split
3030
vim.cmd(config.get_split_command())
3131
-- resize to a % of the current window size
@@ -36,32 +36,32 @@ function View:setup_view()
3636
vim.api.nvim_win_set_buf(self.winnr, self.bufnr)
3737

3838
-- window stuff
39-
vim.api.nvim_win_set_option(self.winnr, "spell", false)
40-
vim.api.nvim_win_set_option(self.winnr, "signcolumn", "no")
41-
vim.api.nvim_win_set_option(self.winnr, "foldcolumn", "0")
42-
vim.api.nvim_win_set_option(self.winnr, "number", false)
43-
vim.api.nvim_win_set_option(self.winnr, "relativenumber", false)
44-
vim.api.nvim_win_set_option(self.winnr, "winfixwidth", true)
45-
vim.api.nvim_win_set_option(self.winnr, "list", false)
46-
vim.api.nvim_win_set_option(self.winnr, "wrap", config.options.wrap)
47-
vim.api.nvim_win_set_option(self.winnr, "linebreak", true) -- only has effect when wrap=true
48-
vim.api.nvim_win_set_option(self.winnr, "breakindent", true) -- only has effect when wrap=true
39+
vim.api.nvim_set_option_value("spell", false, { win = self.winnr })
40+
vim.api.nvim_set_option_value("signcolumn", "no", { win = self.winnr })
41+
vim.api.nvim_set_option_value("foldcolumn", "0", { win = self.winnr })
42+
vim.api.nvim_set_option_value("number", false, { win = self.winnr })
43+
vim.api.nvim_set_option_value("relativenumber", false, { win = self.winnr })
44+
vim.api.nvim_set_option_value("winfixwidth", true, { win = self.winnr })
45+
vim.api.nvim_set_option_value("list", false, { win = self.winnr })
46+
vim.api.nvim_set_option_value("wrap", config.options.wrap, { win = self.winnr })
47+
vim.api.nvim_set_option_value("linebreak", true, { win = self.winnr }) -- only has effect when wrap=true
48+
vim.api.nvim_set_option_value("breakindent", true, { win = self.winnr }) -- only has effect when wrap=true
4949
-- Would be nice to use ui.markers.vertical as part of showbreak to keep
5050
-- continuity of the tree UI, but there's currently no way to style the
5151
-- color, apart from globally overriding hl-NonText, which will potentially
5252
-- mess with other theme/user settings. So just use empty spaces for now.
53-
vim.api.nvim_win_set_option(self.winnr, "showbreak", " ") -- only has effect when wrap=true.
53+
vim.api.nvim_set_option_value("showbreak", " ", { win = self.winnr }) -- only has effect when wrap=true.
5454
-- buffer stuff
5555
vim.api.nvim_buf_set_name(self.bufnr, "JavaProjects")
56-
vim.api.nvim_buf_set_option(self.bufnr, "filetype", "JavaProjects")
57-
vim.api.nvim_buf_set_option(self.bufnr, "modifiable", false)
56+
vim.api.nvim_set_option_value("filetype", "JavaProjects", { buf = self.bufnr })
57+
vim.api.nvim_set_option_value("modifiable", false, { buf = self.bufnr })
5858

5959
if config.options.show_numbers or config.options.show_relative_numbers then
60-
vim.api.nvim_win_set_option(self.winnr, "nu", true)
60+
vim.api.nvim_set_option_value("nu", true, { win = self.winnr })
6161
end
6262

6363
if config.options.show_relative_numbers then
64-
vim.api.nvim_win_set_option(self.winnr, "rnu", true)
64+
vim.api.nvim_set_option_value("rnu", true, { win = self.winnr })
6565
end
6666
end
6767

0 commit comments

Comments
 (0)