mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-04 05:50:06 +08:00
272 lines
10 KiB
Lua
272 lines
10 KiB
Lua
local log = require("neo-tree.log")
|
|
local utils = require("neo-tree.utils")
|
|
local vim = vim
|
|
local M = {}
|
|
|
|
---@type integer
|
|
M.ns_id = vim.api.nvim_create_namespace("neo-tree.nvim")
|
|
|
|
M.BUFFER_NUMBER = "NeoTreeBufferNumber"
|
|
M.CURSOR_LINE = "NeoTreeCursorLine"
|
|
M.DIM_TEXT = "NeoTreeDimText"
|
|
M.DIRECTORY_ICON = "NeoTreeDirectoryIcon"
|
|
M.DIRECTORY_NAME = "NeoTreeDirectoryName"
|
|
M.DOTFILE = "NeoTreeDotfile"
|
|
M.FADE_TEXT_1 = "NeoTreeFadeText1"
|
|
M.FADE_TEXT_2 = "NeoTreeFadeText2"
|
|
M.FILE_ICON = "NeoTreeFileIcon"
|
|
M.FILE_NAME = "NeoTreeFileName"
|
|
M.FILE_NAME_OPENED = "NeoTreeFileNameOpened"
|
|
M.FILTER_TERM = "NeoTreeFilterTerm"
|
|
M.FLOAT_BORDER = "NeoTreeFloatBorder"
|
|
M.FLOAT_NORMAL = "NeoTreeFloatNormal"
|
|
M.FLOAT_TITLE = "NeoTreeFloatTitle"
|
|
M.GIT_ADDED = "NeoTreeGitAdded"
|
|
M.GIT_CONFLICT = "NeoTreeGitConflict"
|
|
M.GIT_DELETED = "NeoTreeGitDeleted"
|
|
M.GIT_IGNORED = "NeoTreeGitIgnored"
|
|
M.GIT_MODIFIED = "NeoTreeGitModified"
|
|
M.GIT_RENAMED = "NeoTreeGitRenamed"
|
|
M.GIT_STAGED = "NeoTreeGitStaged"
|
|
M.GIT_UNTRACKED = "NeoTreeGitUntracked"
|
|
M.GIT_UNSTAGED = "NeoTreeGitUnstaged"
|
|
M.HIDDEN_BY_NAME = "NeoTreeHiddenByName"
|
|
M.INDENT_MARKER = "NeoTreeIndentMarker"
|
|
M.MESSAGE = "NeoTreeMessage"
|
|
M.MODIFIED = "NeoTreeModified"
|
|
M.NORMAL = "NeoTreeNormal"
|
|
M.NORMALNC = "NeoTreeNormalNC"
|
|
M.SIGNCOLUMN = "NeoTreeSignColumn"
|
|
M.STATUS_LINE = "NeoTreeStatusLine"
|
|
M.STATUS_LINE_NC = "NeoTreeStatusLineNC"
|
|
M.TAB_ACTIVE = "NeoTreeTabActive"
|
|
M.TAB_INACTIVE = "NeoTreeTabInactive"
|
|
M.TAB_SEPARATOR_ACTIVE = "NeoTreeTabSeparatorActive"
|
|
M.TAB_SEPARATOR_INACTIVE = "NeoTreeTabSeparatorInactive"
|
|
M.VERTSPLIT = "NeoTreeVertSplit"
|
|
M.WINSEPARATOR = "NeoTreeWinSeparator"
|
|
M.END_OF_BUFFER = "NeoTreeEndOfBuffer"
|
|
M.ROOT_NAME = "NeoTreeRootName"
|
|
M.SYMBOLIC_LINK_TARGET = "NeoTreeSymbolicLinkTarget"
|
|
M.TITLE_BAR = "NeoTreeTitleBar"
|
|
M.INDENT_MARKER = "NeoTreeIndentMarker"
|
|
M.EXPANDER = "NeoTreeExpander"
|
|
M.WINDOWS_HIDDEN = "NeoTreeWindowsHidden"
|
|
M.PREVIEW = "NeoTreePreview"
|
|
|
|
local function dec_to_hex(n, chars)
|
|
chars = chars or 6
|
|
local hex = string.format("%0" .. chars .. "x", n)
|
|
while #hex < chars do
|
|
hex = "0" .. hex
|
|
end
|
|
return hex
|
|
end
|
|
|
|
---If the given highlight group is not defined, define it.
|
|
---@param hl_group_name string The name of the highlight group.
|
|
---@param link_to_if_exists table A list of highlight groups to link to, in
|
|
--order of priority. The first one that exists will be used.
|
|
---@param background string|nil The background color to use, in hex, if the highlight group
|
|
--is not defined and it is not linked to another group.
|
|
---@param foreground string|nil The foreground color to use, in hex, if the highlight group
|
|
--is not defined and it is not linked to another group.
|
|
---@gui string|nil The gui to use, if the highlight group is not defined and it is not linked
|
|
--to another group.
|
|
---@return table table The highlight group values.
|
|
M.create_highlight_group = function(hl_group_name, link_to_if_exists, background, foreground, gui)
|
|
local success, hl_group = pcall(vim.api.nvim_get_hl_by_name, hl_group_name, true)
|
|
if not success or not hl_group.foreground or not hl_group.background then
|
|
for _, link_to in ipairs(link_to_if_exists) do
|
|
success, hl_group = pcall(vim.api.nvim_get_hl_by_name, link_to, true)
|
|
if success then
|
|
local new_group_has_settings = background or foreground or gui
|
|
local link_to_has_settings = hl_group.foreground or hl_group.background
|
|
if link_to_has_settings or not new_group_has_settings then
|
|
vim.cmd("highlight default link " .. hl_group_name .. " " .. link_to)
|
|
return hl_group
|
|
end
|
|
end
|
|
end
|
|
|
|
if type(background) == "number" then
|
|
background = dec_to_hex(background)
|
|
end
|
|
if type(foreground) == "number" then
|
|
foreground = dec_to_hex(foreground)
|
|
end
|
|
|
|
local cmd = "highlight default " .. hl_group_name
|
|
if background then
|
|
cmd = cmd .. " guibg=#" .. background
|
|
end
|
|
if foreground then
|
|
cmd = cmd .. " guifg=#" .. foreground
|
|
else
|
|
cmd = cmd .. " guifg=NONE"
|
|
end
|
|
if gui then
|
|
cmd = cmd .. " gui=" .. gui
|
|
end
|
|
vim.cmd(cmd)
|
|
|
|
return {
|
|
background = background and tonumber(background, 16) or nil,
|
|
foreground = foreground and tonumber(foreground, 16) or nil,
|
|
}
|
|
end
|
|
return hl_group
|
|
end
|
|
|
|
local faded_highlight_group_cache = {}
|
|
M.get_faded_highlight_group = function(hl_group_name, fade_percentage)
|
|
if type(hl_group_name) ~= "string" then
|
|
error("hl_group_name must be a string")
|
|
end
|
|
if type(fade_percentage) ~= "number" then
|
|
error("hl_group_name must be a number")
|
|
end
|
|
if fade_percentage < 0 or fade_percentage > 1 then
|
|
error("fade_percentage must be between 0 and 1")
|
|
end
|
|
|
|
local key = hl_group_name .. "_" .. tostring(math.floor(fade_percentage * 100))
|
|
if faded_highlight_group_cache[key] then
|
|
return faded_highlight_group_cache[key]
|
|
end
|
|
|
|
local normal = vim.api.nvim_get_hl_by_name("Normal", true)
|
|
if type(normal.foreground) ~= "number" then
|
|
if vim.api.nvim_get_option("background") == "dark" then
|
|
normal.foreground = 0xffffff
|
|
else
|
|
normal.foreground = 0x000000
|
|
end
|
|
end
|
|
if type(normal.background) ~= "number" then
|
|
if vim.api.nvim_get_option("background") == "dark" then
|
|
normal.background = 0x000000
|
|
else
|
|
normal.background = 0xffffff
|
|
end
|
|
end
|
|
local foreground = dec_to_hex(normal.foreground)
|
|
local background = dec_to_hex(normal.background)
|
|
|
|
local hl_group = vim.api.nvim_get_hl_by_name(hl_group_name, true)
|
|
if type(hl_group.foreground) == "number" then
|
|
foreground = dec_to_hex(hl_group.foreground)
|
|
end
|
|
if type(hl_group.background) == "number" then
|
|
background = dec_to_hex(hl_group.background)
|
|
end
|
|
|
|
local gui = {}
|
|
if hl_group.bold then
|
|
table.insert(gui, "bold")
|
|
end
|
|
if hl_group.italic then
|
|
table.insert(gui, "italic")
|
|
end
|
|
if hl_group.underline then
|
|
table.insert(gui, "underline")
|
|
end
|
|
if hl_group.undercurl then
|
|
table.insert(gui, "undercurl")
|
|
end
|
|
if #gui > 0 then
|
|
gui = table.concat(gui, ",")
|
|
else
|
|
gui = nil
|
|
end
|
|
|
|
local f_red = tonumber(foreground:sub(1, 2), 16)
|
|
local f_green = tonumber(foreground:sub(3, 4), 16)
|
|
local f_blue = tonumber(foreground:sub(5, 6), 16)
|
|
|
|
local b_red = tonumber(background:sub(1, 2), 16)
|
|
local b_green = tonumber(background:sub(3, 4), 16)
|
|
local b_blue = tonumber(background:sub(5, 6), 16)
|
|
|
|
local red = (f_red * fade_percentage) + (b_red * (1 - fade_percentage))
|
|
local green = (f_green * fade_percentage) + (b_green * (1 - fade_percentage))
|
|
local blue = (f_blue * fade_percentage) + (b_blue * (1 - fade_percentage))
|
|
|
|
local new_foreground =
|
|
string.format("%s%s%s", dec_to_hex(red, 2), dec_to_hex(green, 2), dec_to_hex(blue, 2))
|
|
|
|
M.create_highlight_group(key, {}, hl_group.background, new_foreground, gui)
|
|
faded_highlight_group_cache[key] = key
|
|
return key
|
|
end
|
|
|
|
M.setup = function()
|
|
-- Reset this here in case of color scheme change
|
|
faded_highlight_group_cache = {}
|
|
|
|
local normal_hl = M.create_highlight_group(M.NORMAL, { "Normal" })
|
|
local normalnc_hl = M.create_highlight_group(M.NORMALNC, { "NormalNC", M.NORMAL })
|
|
|
|
M.create_highlight_group(M.SIGNCOLUMN, { "SignColumn", M.NORMAL })
|
|
|
|
M.create_highlight_group(M.STATUS_LINE, { "StatusLine" })
|
|
M.create_highlight_group(M.STATUS_LINE_NC, { "StatusLineNC" })
|
|
|
|
M.create_highlight_group(M.VERTSPLIT, { "VertSplit" })
|
|
M.create_highlight_group(M.WINSEPARATOR, { "WinSeparator" })
|
|
|
|
M.create_highlight_group(M.END_OF_BUFFER, { "EndOfBuffer" })
|
|
|
|
local float_border_hl =
|
|
M.create_highlight_group(M.FLOAT_BORDER, { "FloatBorder" }, normalnc_hl.background, "444444")
|
|
|
|
M.create_highlight_group(M.FLOAT_NORMAL, { "NormalFloat", M.NORMAL })
|
|
|
|
M.create_highlight_group(M.FLOAT_TITLE, {}, float_border_hl.background, normal_hl.foreground)
|
|
|
|
local title_fg = normal_hl.background
|
|
if title_fg == float_border_hl.foreground then
|
|
title_fg = normal_hl.foreground
|
|
end
|
|
M.create_highlight_group(M.TITLE_BAR, {}, float_border_hl.foreground, title_fg)
|
|
|
|
M.create_highlight_group(M.BUFFER_NUMBER, { "SpecialChar" })
|
|
M.create_highlight_group(M.DIM_TEXT, {}, nil, "505050")
|
|
M.create_highlight_group(M.MESSAGE, {}, nil, "505050", "italic")
|
|
M.create_highlight_group(M.FADE_TEXT_1, {}, nil, "626262")
|
|
M.create_highlight_group(M.FADE_TEXT_2, {}, nil, "444444")
|
|
M.create_highlight_group(M.DOTFILE, {}, nil, "626262")
|
|
M.create_highlight_group(M.HIDDEN_BY_NAME, { M.DOTFILE }, nil, nil)
|
|
M.create_highlight_group(M.CURSOR_LINE, { "CursorLine" }, nil, nil, "bold")
|
|
M.create_highlight_group(M.DIRECTORY_NAME, { "Directory" }, "NONE", "NONE")
|
|
M.create_highlight_group(M.DIRECTORY_ICON, { "Directory" }, nil, "73cef4")
|
|
M.create_highlight_group(M.FILE_ICON, { M.DIRECTORY_ICON })
|
|
M.create_highlight_group(M.FILE_NAME, {}, "NONE", "NONE")
|
|
M.create_highlight_group(M.FILE_NAME_OPENED, {}, nil, nil, "bold")
|
|
M.create_highlight_group(M.SYMBOLIC_LINK_TARGET, { M.FILE_NAME })
|
|
M.create_highlight_group(M.FILTER_TERM, { "SpecialChar", "Normal" })
|
|
M.create_highlight_group(M.ROOT_NAME, {}, nil, nil, "bold,italic")
|
|
M.create_highlight_group(M.INDENT_MARKER, { M.DIM_TEXT })
|
|
M.create_highlight_group(M.EXPANDER, { M.DIM_TEXT })
|
|
M.create_highlight_group(M.MODIFIED, {}, nil, "d7d787")
|
|
M.create_highlight_group(M.WINDOWS_HIDDEN, { M.DOTFILE }, nil, nil)
|
|
M.create_highlight_group(M.PREVIEW, { "Search" }, nil, nil)
|
|
|
|
M.create_highlight_group(M.GIT_ADDED, { "GitGutterAdd", "GitSignsAdd" }, nil, "5faf5f")
|
|
M.create_highlight_group(M.GIT_DELETED, { "GitGutterDelete", "GitSignsDelete" }, nil, "ff5900")
|
|
M.create_highlight_group(M.GIT_MODIFIED, { "GitGutterChange", "GitSignsChange" }, nil, "d7af5f")
|
|
local conflict = M.create_highlight_group(M.GIT_CONFLICT, {}, nil, "ff8700", "italic,bold")
|
|
M.create_highlight_group(M.GIT_IGNORED, { M.DOTFILE }, nil, nil)
|
|
M.create_highlight_group(M.GIT_RENAMED, { M.GIT_MODIFIED }, nil, nil)
|
|
M.create_highlight_group(M.GIT_STAGED, { M.GIT_ADDED }, nil, nil)
|
|
M.create_highlight_group(M.GIT_UNSTAGED, { M.GIT_CONFLICT }, nil, nil)
|
|
M.create_highlight_group(M.GIT_UNTRACKED, {}, nil, conflict.foreground, "italic")
|
|
|
|
M.create_highlight_group(M.TAB_ACTIVE, {}, nil, nil, "bold")
|
|
M.create_highlight_group(M.TAB_INACTIVE, {}, "141414", "777777")
|
|
M.create_highlight_group(M.TAB_SEPARATOR_ACTIVE, {}, nil, "0a0a0a")
|
|
M.create_highlight_group(M.TAB_SEPARATOR_INACTIVE, {}, "141414", "101010")
|
|
end
|
|
|
|
return M
|