Read-only mirror of https://codeberg.org/andyg/leap.nvim
1local opts = require('leap.opts')
2
3local api = vim.api
4
5local M = {
6 group = {
7 label = 'LeapLabel',
8 label_dimmed = 'LeapLabelDimmed',
9 match = 'LeapMatch'
10 },
11 priority = {
12 label = 65535
13 }
14}
15
16local custom_def_maps = {
17 label_light = {
18 fg = 'NvimDarkGrey2',
19 bg = '#ffaf3f',
20 nocombine = true,
21 ctermfg = 'red'
22 },
23 match_light = {
24 fg = 'NvimDarkGrey1',
25 bg = 'NvimLightYellow',
26 ctermfg = 'black',
27 ctermbg = 'red'
28 },
29 label_dark = {
30 fg = 'black',
31 bg = '#ccff88',
32 nocombine = true,
33 ctermfg = 'black',
34 ctermbg = 'red'
35 },
36 match_dark = {
37 fg = '#ccff88',
38 underline = true,
39 nocombine = true,
40 ctermfg = 'red'
41 },
42}
43
44local function get_hl(name)
45 return api.nvim_get_hl(0, { name = name, link = false })
46end
47
48local function to_rgb(n)
49 local r = math.floor((n / 65536))
50 local g = math.floor(((n / 256) % 256))
51 local b = (n % 256)
52 return r, g, b
53end
54
55local function blend(color1, color2, weight)
56 local r1, g1, b1 = to_rgb(color1)
57 local r2, g2, b2 = to_rgb(color2)
58 local r = (r1 * (1 - weight)) + (r2 * weight)
59 local g = (g1 * (1 - weight)) + (g2 * weight)
60 local b = (b1 * (1 - weight)) + (b2 * weight)
61 return string.format('#%02x%02x%02x', r, g, b)
62end
63
64local function dimmed(def_map_)
65 local def_map = vim.deepcopy(def_map_)
66 local normal = get_hl('Normal')
67 -- `bg` can be nil (transparent background), and e.g. the old default
68 -- color scheme (`vim`) does not define Normal at all.
69 -- Also, `nvim_get_hl()` apparently does not guarantee to return
70 -- numeric values in the table (#260).
71 if type(normal.bg) == 'number' then
72 if type(def_map.bg) == 'number' then
73 def_map.bg = blend(def_map.bg, normal.bg, 0.7)
74 end
75 if type(def_map.fg) == 'number' then
76 def_map.fg = blend(def_map.fg, normal.bg, 0.5)
77 end
78 end
79 return def_map
80end
81
82local function set_label_dimmed()
83 local label = get_hl(M.group.label)
84 local label_dimmed = dimmed(label)
85 api.nvim_set_hl(0, M.group.label_dimmed, label_dimmed)
86end
87
88local function set_concealed_label_char()
89 local label = get_hl(M.group.label)
90 local middle_dot = '\194\183'
91 -- Undocumented option, might be exposed in the future.
92 opts.concealed_label = label.bg and ' ' or middle_dot
93end
94
95---@param force? boolean
96function M.init(self, force)
97 local defaults = {}
98 -- vscode-neovim has a problem with linking to built-in groups.
99 local use_custom_defaults = (vim.g.colors_name == 'default') or vim.g.vscode
100
101 if use_custom_defaults then
102 defaults[self.group.label] =
103 custom_def_maps[vim.o.bg == 'light' and 'label_light' or 'label_dark']
104 defaults[self.group.match] =
105 custom_def_maps[vim.o.bg == 'light' and 'match_light' or 'match_dark']
106 else
107 local search_hl = get_hl('Search')
108
109 defaults[self.group.label] =
110 not vim.deep_equal(search_hl, get_hl('IncSearch'))
111 and { link = 'IncSearch' }
112 or not vim.deep_equal(search_hl, get_hl('CurSearch'))
113 and { link = 'CurSearch' }
114 or not vim.deep_equal(search_hl, get_hl('Substitute'))
115 and { link = 'Substitue' }
116 or custom_def_maps[vim.o.bg == 'light' and 'label_light' or 'label_dark']
117
118 defaults[self.group.match] = { link = 'Search' }
119 end
120
121 -- Deepcopy, in case using `custom_def_maps`.
122 for group, def_map in pairs(vim.deepcopy(defaults)) do
123 if not force then
124 def_map.default = true -- :h hi-default
125 end
126 api.nvim_set_hl(0, group, def_map)
127 end
128 -- These should be done last, based on the actual group definitions.
129 set_label_dimmed()
130 set_concealed_label_char()
131
132 -- Handle `LeapBackdrop` (deprecated).
133 if not vim.tbl_isempty(get_hl('LeapBackdrop')) then
134 if force then
135 api.nvim_set_hl(0, 'LeapBackdrop', { link = 'None' })
136 else
137 require('leap.user').set_backdrop_highlight('LeapBackdrop')
138 end
139 end
140end
141
142return M