feat: Properly support nvim-0.7, and fix highlights

This commit is contained in:
hedy
2023-11-21 08:39:05 +08:00
parent b03c3a4e3d
commit 699bc85cc5
7 changed files with 174 additions and 106 deletions

View File

@@ -62,6 +62,17 @@
option is `symbol_folding.auto_unfold` with keys `hovered` and `only`.
Key `hovered` is the successor of the legacy `symbol_folding.auto_unfold_hover`
option. **The old option would still work as expected.**
- Updated the default symbols icon highlights to not use highlight groups that
start with `@`. Everything should still work as expected, most highlights
should still be the same. This is to support `nvim-0.7`. The symbols icon
highlights is still configurable as before.
- Highlights used by outline.nvim are now set to default using links if they
aren't already defined. Default winhl for outline window is now an empty
string, and for preview window, `NormalFloat:` to ensure the preview window
looks similar to a normal window (since it displays a preview of the actual
code)
- Highlights will also take into account `ctermfg/bg` when setting default values.
This ensures outline.nvim highlights work if `termguicolors` is not enabled
### Fixes

View File

@@ -205,10 +205,8 @@ Pass a table to the setup call with your configuration options.
focus_on_open = true,
-- Winhighlight option for outline window.
-- See :help 'winhl'
-- To change background color to "CustomHl" for example, append "Normal:CustomHl".
-- Note that if you're adding highlight changes, you should append to this
-- default value, otherwise details/lineno will not have highlights.
winhl = "OutlineDetails:Comment,OutlineLineno:LineNr",
-- To change background color to "CustomHl" for example, use "Normal:CustomHl".
winhl = '',
},
outline_items = {
@@ -287,7 +285,7 @@ Pass a table to the setup call with your configuration options.
-- See :help nvim_open_win() and search for "border" option.
border = 'single',
-- winhl options for the preview window, see ':h winhl'
winhl = '',
winhl = 'NormalFloat:',
-- Pseudo-transparency of the preview window, see ':h winblend'
winblend = 0
},
@@ -366,38 +364,38 @@ Pass a table to the setup call with your configuration options.
-- the custom mapping of icons specified below. The icons table is also
-- needed for specifying hl group.
icons = {
File = { icon = '󰈔', hl = '@text.uri' },
Module = { icon = '󰆧', hl = '@namespace' },
Namespace = { icon = '󰅪', hl = '@namespace' },
Package = { icon = '󰏗', hl = '@namespace' },
Class = { icon = '𝓒', hl = '@type' },
Method = { icon = 'ƒ', hl = '@method' },
Property = { icon = '', hl = '@method' },
Field = { icon = '󰆨', hl = '@field' },
Constructor = { icon = '', hl = '@constructor' },
Enum = { icon = '', hl = '@type' },
Interface = { icon = '󰜰', hl = '@type' },
Function = { icon = '', hl = '@function' },
Variable = { icon = '', hl = '@constant' },
Constant = { icon = '', hl = '@constant' },
String = { icon = '𝓐', hl = '@string' },
Number = { icon = '#', hl = '@number' },
Boolean = { icon = '⊨', hl = '@boolean' },
Array = { icon = '󰅪', hl = '@constant' },
Object = { icon = '⦿', hl = '@type' },
Key = { icon = '🔐', hl = '@type' },
Null = { icon = 'NULL', hl = '@type' },
EnumMember = { icon = '', hl = '@field' },
Struct = { icon = '𝓢', hl = '@type' },
Event = { icon = '🗲', hl = '@type' },
Operator = { icon = '+', hl = '@operator' },
TypeParameter = { icon = '𝙏', hl = '@parameter' },
Component = { icon = '󰅴', hl = '@function' },
Fragment = { icon = '󰅴', hl = '@constant' },
TypeAlias = { icon = ' ', hl = '@type' },
Parameter = { icon = ' ', hl = '@parameter' },
StaticMethod = { icon = ' ', hl = '@function' },
Macro = { icon = ' ', hl = '@macro' },
File = { icon = '󰈔', hl = 'Identifier' },
Module = { icon = '󰆧', hl = 'Include' },
Namespace = { icon = '󰅪', hl = 'Include' },
Package = { icon = '󰏗', hl = 'Include' },
Class = { icon = '𝓒', hl = 'Type' },
Method = { icon = 'ƒ', hl = 'Function' },
Property = { icon = '', hl = 'Identifier' },
Field = { icon = '󰆨', hl = 'Identifier' },
Constructor = { icon = '', hl = 'Special' },
Enum = { icon = '', hl = 'Type' },
Interface = { icon = '󰜰', hl = 'Type' },
Function = { icon = '', hl = 'Function' },
Variable = { icon = '', hl = 'Constant' },
Constant = { icon = '', hl = 'Constant' },
String = { icon = '𝓐', hl = 'String' },
Number = { icon = '#', hl = 'Number' },
Boolean = { icon = '⊨', hl = 'Boolean' },
Array = { icon = '󰅪', hl = 'Constant' },
Object = { icon = '⦿', hl = 'Type' },
Key = { icon = '🔐', hl = 'Type' },
Null = { icon = 'NULL', hl = 'Type' },
EnumMember = { icon = '', hl = 'Identifier' },
Struct = { icon = '𝓢', hl = 'Structure' },
Event = { icon = '🗲', hl = 'Type' },
Operator = { icon = '+', hl = 'Identifier' },
TypeParameter = { icon = '𝙏', hl = 'Identifier' },
Component = { icon = '󰅴', hl = 'Function' },
Fragment = { icon = '󰅴', hl = 'Constant' },
TypeAlias = { icon = ' ', hl = 'Type' },
Parameter = { icon = ' ', hl = 'Identifier' },
StaticMethod = { icon = ' ', hl = 'Function' },
Macro = { icon = ' ', hl = 'Function' },
},
},
}
@@ -560,7 +558,7 @@ Default:
```lua
outline_window = {
winhl = "OutlineDetails:Comment,OutlineLineno:LineNr",
winhl = '',
},
```
@@ -574,9 +572,21 @@ Possible highlight groups for the outline window:
| OutlineDetails | Symbol details in virtual text |
| OutlineLineno | The Lineno column virtual text |
You can customize any other highlight groups using `winhl` too, this option is
You can customize any other highlight groups using `winhl`, this option is
passed directly to the `winhl` vim option unprocessed.
If any of the above highlights have not already been set before outline.setup
is called (say by a theme), the following links are used:
| Highlight | Link |
| -------------------- | -------- |
| OutlineGuides | Comment |
| OutlineFoldMarker | Normal |
| OutlineDetails | Comment |
| OutlineLineno | LineNr |
For `OutlineCurrent`, foreground is set to String and background CursorLine.
To customize colors of the symbol icons, use the `symbols.icons` table. See
[config](#configuration).
@@ -584,15 +594,15 @@ To customize colors of the symbol icons, use the `symbols.icons` table. See
```lua
preview_window = {
winhl = "",
winhl = 'NormalFloat:',
},
```
### Other highlight groups
| Highlight | Description |
| -------------------- | ---------------------------------------------------------- |
| OutlineJumpHighlight | Used for indicating cursor position when jumping/focusing |
| -------------------- | --------------------------------------------------------------------- |
| OutlineJumpHighlight | Indicating cursor position when jumping/focusing, defaults to Visual |
You can also use `outline_window.jump_highlight_duration` to customize in milliseconds,
how long the highlight is applied for.

View File

@@ -43,7 +43,7 @@ M.defaults = {
---@type boolean|string?
show_cursorline = true,
hide_cursor = false,
winhl = 'OutlineDetails:Comment,OutlineLineno:LineNr',
winhl = '',
jump_highlight_duration = 400,
center_on_jump = true,
},
@@ -55,7 +55,7 @@ M.defaults = {
min_height = 10,
border = 'single',
open_hover_on_preview = false,
winhl = '',
winhl = 'NormalFloat:',
winblend = 0,
},
symbol_folding = {
@@ -100,39 +100,39 @@ M.defaults = {
icon_source = nil,
icon_fetcher = nil,
icons = {
File = { icon = '󰈔', hl = '@text.uri' },
Module = { icon = '󰆧', hl = '@namespace' },
Namespace = { icon = '󰅪', hl = '@namespace' },
Package = { icon = '󰏗', hl = '@namespace' },
Class = { icon = '𝓒', hl = '@type' },
Method = { icon = 'ƒ', hl = '@method' },
Property = { icon = '', hl = '@method' },
Field = { icon = '󰆨', hl = '@field' },
Constructor = { icon = '', hl = '@constructor' },
Enum = { icon = '', hl = '@type' },
Interface = { icon = '󰜰', hl = '@type' },
Function = { icon = '', hl = '@function' },
Variable = { icon = '', hl = '@constant' },
Constant = { icon = '', hl = '@constant' },
String = { icon = '𝓐', hl = '@string' },
Number = { icon = '#', hl = '@number' },
Boolean = { icon = '', hl = '@boolean' },
Array = { icon = '󰅪', hl = '@constant' },
Object = { icon = '⦿', hl = '@type' },
Key = { icon = '🔐', hl = '@type' },
Null = { icon = 'NULL', hl = '@type' },
EnumMember = { icon = '', hl = '@field' },
Struct = { icon = '𝓢', hl = '@type' },
Event = { icon = '🗲', hl = '@type' },
Operator = { icon = '+', hl = '@operator' },
TypeParameter = { icon = '𝙏', hl = '@parameter' },
Component = { icon = '󰅴', hl = '@function' },
Fragment = { icon = '󰅴', hl = '@constant' },
File = { icon = '󰈔', hl = 'Identifier' },
Module = { icon = '󰆧', hl = 'Include' },
Namespace = { icon = '󰅪', hl = 'Include' },
Package = { icon = '󰏗', hl = 'Include' },
Class = { icon = '𝓒', hl = 'Type' },
Method = { icon = 'ƒ', hl = 'Function' },
Property = { icon = '', hl = 'Identifier' },
Field = { icon = '󰆨', hl = 'Identifier' },
Constructor = { icon = '', hl = 'Special' },
Enum = { icon = '', hl = 'Type' },
Interface = { icon = '󰜰', hl = 'Type' },
Function = { icon = '', hl = 'Function' },
Variable = { icon = '', hl = 'Constant' },
Constant = { icon = '', hl = 'Constant' },
String = { icon = '𝓐', hl = 'String' },
Number = { icon = '#', hl = 'Number' },
Boolean = { icon = '', hl = 'Boolean' },
Array = { icon = '󰅪', hl = 'Constant' },
Object = { icon = '⦿', hl = 'Type' },
Key = { icon = '🔐', hl = 'Type' },
Null = { icon = 'NULL', hl = 'Type' },
EnumMember = { icon = '', hl = 'Identifier' },
Struct = { icon = '𝓢', hl = 'Structure' },
Event = { icon = '🗲', hl = 'Type' },
Operator = { icon = '+', hl = 'Identifier' },
TypeParameter = { icon = '𝙏', hl = 'Identifier' },
Component = { icon = '󰅴', hl = 'Function' },
Fragment = { icon = '󰅴', hl = 'Constant' },
-- ccls
TypeAlias = { icon = '', hl = '@type' },
Parameter = { icon = '', hl = '@parameter' },
StaticMethod = { icon = '', hl = '@function' },
Macro = { icon = '', hl = '@macro' },
TypeAlias = { icon = '', hl = 'Type' },
Parameter = { icon = '', hl = 'Identifier' },
StaticMethod = { icon = '', hl = 'Function' },
Macro = { icon = '', hl = 'Function' },
},
},
}

View File

@@ -1,5 +1,3 @@
-- local cfg = require('outline.config')
local Float = {}
---@class outline.Float
@@ -37,7 +35,7 @@ function Float:open(lines, hl, title, indent)
local row = math.floor((nvim_height - height) / 2)
local col = math.floor((nvim_width - width) / 2)
self.winnr = vim.api.nvim_open_win(self.bufnr, true, {
local opts = {
relative = 'editor',
width = width,
height = height,
@@ -45,9 +43,13 @@ function Float:open(lines, hl, title, indent)
col = col,
border = 'rounded',
style = 'minimal',
title = title,
title_pos = 'center',
})
}
if _G._outline_nvim_has[9] then
opts.title = title
opts.title_pos = 'center'
end
self.winnr = vim.api.nvim_open_win(self.bufnr, true, opts)
if indent > 0 then
local pad = string.rep(' ', indent)
@@ -73,13 +75,14 @@ function Float:open(lines, hl, title, indent)
(h.to ~= -1 and h.to + indent) or -1
)
end
vim.api.nvim_win_set_hl_ns(self.winnr, self.ns)
end
end
function Float:close()
if self.winnr then
if self.ns then
vim.api.nvim_buf_clear_namespace(self.bufnr, self.ns, 0, -1)
end
vim.api.nvim_win_close(self.winnr, true)
self.winnr = nil
self.bufnr = nil

View File

@@ -146,9 +146,6 @@ function M.__goto_location(change_focus)
vim.fn.win_execute(M.state.code_win, 'normal! zz')
end
if vim.fn.hlexists('OutlineJumpHighlight') == 0 then
vim.api.nvim_set_hl(0, 'OutlineJumpHighlight', { link = 'Visual' })
end
utils.flash_highlight(
M.state.code_win,
node.line + 1,
@@ -522,10 +519,12 @@ end
local function _cmd_open_with_mods(fn)
return function(opts)
local fnopts = { focus_outline = not opts.bang }
if _G._outline_nvim_has[8] then
local sc = opts.smods.split
if sc ~= '' then
fnopts.split_command = sc .. ' vsplit'
end
end
fn(fnopts)
end
@@ -681,6 +680,18 @@ end
---Set up configuration options for outline.
function M.setup(opts)
local minor = vim.version().minor
if minor < 7 then
vim.notify('outline.nvim requires nvim-0.7 or higher!', vim.log.levels.ERROR)
return
end
_G._outline_nvim_has = {
[8] = minor >= 8,
[9] = minor >= 9,
}
cfg.setup(opts)
ui.setup_highlights()

View File

@@ -10,29 +10,62 @@ function M.add_hover_highlight(bufnr, line, col_start)
vim.api.nvim_buf_add_highlight(bufnr, M.hovered_hl_ns, 'OutlineCurrent', line, col_start, -1)
end
local get_hl_by_name
if vim.fn.has('nvim-0.9') == 1 then
get_hl_by_name = function(name)
local hl = vim.api.nvim_get_hl(0, { name = name, link = false })
return { fg = hl.fg, bg = hl.bg, ctermfg = hl.ctermfg, ctermbg = hl.ctermbg }
end
else
get_hl_by_name = function(name)
---@diagnostic disable-next-line undefined-field
local hlrgb = vim.api.nvim_get_hl_by_name(name, true)
---@diagnostic disable-next-line undefined-field
local hl = vim.api.nvim_get_hl_by_name(name, false)
return {
fg = hlrgb.foreground,
bg = hlrgb.background,
ctermfg = hl.foreground,
ctermbg = hl.background,
}
end
end
function M.setup_highlights()
-- Setup the OutlineCurrent highlight group if it hasn't been done already by
-- a theme or manually set
if vim.fn.hlexists('OutlineCurrent') == 0 then
-- TODO: Use nvim_get_hl
local cline_hl = vim.api.nvim_get_hl_by_name('CursorLine', true)
local string_hl = vim.api.nvim_get_hl_by_name('String', true)
local cline_hl = get_hl_by_name('CursorLine')
local string_hl = get_hl_by_name('String')
vim.api.nvim_set_hl(
0,
'OutlineCurrent',
{ bg = cline_hl.background, fg = string_hl.foreground }
{
bg = cline_hl.bg,
fg = string_hl.fg,
ctermbg = cline_hl.ctermbg,
ctermfg = string_hl.ctermfg,
}
)
end
-- Some colorschemes do some funky things with the comment highlight, most
-- notably making them italic, which messes up the outline connector. Fix
-- this by copying the foreground color from the comment hl into a new
-- highlight.
local comment_fg_gui = vim.fn.synIDattr(vim.fn.synIDtrans(vim.fn.hlID('Comment')), 'fg', 'gui')
-- Only inherit fg and bg for OutlineGuides because we do not want the other
-- stylings messing up the alignment.
if vim.fn.hlexists('OutlineGuides') == 0 then
vim.cmd(string.format('hi OutlineGuides guifg=%s', comment_fg_gui))
vim.api.nvim_set_hl(0, 'OutlineGuides', get_hl_by_name('Comment'))
end
for name, link in pairs({
Details = 'Comment',
Lineno = 'LineNr',
JumpHighlight = 'Visual',
FoldMarker = 'Normal',
}) do
if vim.fn.hlexists('Outline' .. name) == 0 then
vim.api.nvim_set_hl(0, 'Outline' .. name, { link = link })
end
end
end

View File

@@ -10,7 +10,7 @@ local strlen = vim.fn.strlen
local M = {}
local hlns = vim.api.nvim_create_namespace('outline-icon-highlight')
local ns = vim.api.nvim_create_namespace('outline-virt-text')
local vtns = vim.api.nvim_create_namespace('outline-virt-text')
---@param bufnr integer
---@return boolean
@@ -36,7 +36,7 @@ end
---@param bufnr integer
local function clear_virt_text(bufnr)
vim.api.nvim_buf_clear_namespace(bufnr, -1, 0, -1)
vim.api.nvim_buf_clear_namespace(bufnr, vtns, 0, -1)
end
---@param bufnr integer
@@ -243,7 +243,7 @@ function M.make_outline(bufnr, items, codewin, find_node)
-- Add details and lineno virtual text.
if cfg.o.outline_items.show_symbol_details then
for index, value in ipairs(details) do
vim.api.nvim_buf_set_extmark(bufnr, ns, index - 1, -1, {
vim.api.nvim_buf_set_extmark(bufnr, vtns, index - 1, -1, {
virt_text = { { value, 'OutlineDetails' } },
virt_text_pos = 'eol',
hl_mode = 'combine',
@@ -256,7 +256,7 @@ function M.make_outline(bufnr, items, codewin, find_node)
-- TODO: Fix lineno not appearing if text in line is truncated on the right
-- due to narrow window, after nvim fixes virt_text_hide.
for index, value in ipairs(linenos) do
vim.api.nvim_buf_set_extmark(bufnr, ns, index - 1, -1, {
vim.api.nvim_buf_set_extmark(bufnr, vtns, index - 1, -1, {
virt_text = { { value, 'OutlineLineno' } },
virt_text_pos = 'overlay',
virt_text_win_col = 0,