1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
local colors = require("toggleterm.colors")
local constants = require("toggleterm.constants")
local utils = require("toggleterm.utils")
local M = {}
local fmt = string.format
local function shade(color, factor) return colors.shade_color(color, factor) end
--- @alias ToggleTermHighlights table<string, table<string, string>>
---@class WinbarOpts
---@field name_formatter fun(term: Terminal):string
---@field enabled boolean
--- @class Responsiveness
--- @field horizontal_breakpoint number
--- @class ToggleTermConfig
--- @field size number
--- @field shade_filetypes string[]
--- @field hide_numbers boolean
--- @field open_mapping string | string[]
--- @field shade_terminals boolean
--- @field insert_mappings boolean
--- @field terminal_mappings boolean
--- @field start_in_insert boolean
--- @field persist_size boolean
--- @field persist_mode boolean
--- @field close_on_exit boolean
--- @field clear_env boolean
--- @field direction '"horizontal"' | '"vertical"' | '"float"'
--- @field shading_factor number
--- @field shading_ratio number
--- @field shell string|fun():string
--- @field auto_scroll boolean
--- @field float_opts table<string, any>
--- @field highlights ToggleTermHighlights
--- @field winbar WinbarOpts
--- @field autochdir boolean
--- @field title_pos '"left"' | '"center"' | '"right"'
--- @field responsiveness Responsiveness
---@type ToggleTermConfig
local config = {
size = 12,
shade_filetypes = {},
hide_numbers = true,
shade_terminals = true,
insert_mappings = true,
terminal_mappings = true,
start_in_insert = true,
persist_size = true,
persist_mode = true,
close_on_exit = true,
clear_env = false,
direction = "horizontal",
shading_factor = constants.shading_amount,
shading_ratio = constants.shading_ratio,
shell = vim.o.shell,
autochdir = false,
auto_scroll = true,
winbar = {
enabled = false,
name_formatter = function(term) return fmt("%d:%s", term.id, term:_display_name()) end,
},
float_opts = {
winblend = 0,
title_pos = "left",
},
responsiveness = {
horizontal_breakpoint = 0,
},
}
---Derive the highlights for a toggleterm and merge these with the user's preferences
---A few caveats must be noted. Since I link the normal and float border to the Normal
---highlight this has to be done carefully as if the user has specified any Float highlights
---themselves merging will result in a mix of user highlights and the link key which is invalid
---so I check that they have not attempted to highlight these themselves. Also
---if they have chosen to shade the terminal then this takes priority over their own highlights
---since they can't have it both ways i.e. custom highlighting and shading
---@param conf ToggleTermConfig
---@return ToggleTermHighlights
local function get_highlights(conf)
local user = conf.highlights
local defaults = {
NormalFloat = vim.F.if_nil(user.NormalFloat, { link = "Normal" }),
FloatBorder = vim.F.if_nil(user.FloatBorder, { link = "Normal" }),
StatusLine = { gui = "NONE" },
StatusLineNC = { cterm = "italic", gui = "NONE" },
}
local overrides = {}
local nightly = utils.is_nightly()
local comment_fg = colors.get_hex("Comment", "fg")
local dir_fg = colors.get_hex("Directory", "fg")
local winbar_inactive_opts = { guifg = comment_fg }
local winbar_active_opts = { guifg = dir_fg, gui = "underline" }
if conf.shade_terminals then
local is_bright = colors.is_bright_background()
local degree = is_bright and conf.shading_ratio or 1
local amount = conf.shading_factor * degree
local normal_bg = colors.get_hex("Normal", "bg")
local terminal_bg = conf.shade_terminals and shade(normal_bg, amount) or normal_bg
overrides = {
Normal = { guibg = terminal_bg },
SignColumn = { guibg = terminal_bg },
EndOfBuffer = { guibg = terminal_bg },
StatusLine = { guibg = terminal_bg },
StatusLineNC = { guibg = terminal_bg },
}
-- TODO: Move this to the main overrides block once nvim 0.8 is stable
if nightly then
winbar_inactive_opts.guibg = terminal_bg
winbar_active_opts.guibg = terminal_bg
overrides.WinBarNC = { guibg = terminal_bg }
overrides.WinBar = { guibg = terminal_bg }
end
end
if nightly and conf.winbar.enabled then
colors.set_hl("WinBarActive", winbar_active_opts)
colors.set_hl("WinBarInactive", winbar_inactive_opts)
end
return vim.tbl_deep_extend("force", defaults, conf.highlights, overrides)
end
--- get the full user config or just a specified value
---@param key string?
---@return any
function M.get(key)
if key then return config[key] end
return config
end
function M.reset_highlights() config.highlights = get_highlights(config) end
---@param user_conf ToggleTermConfig
---@return ToggleTermConfig
function M.set(user_conf)
user_conf = user_conf or {}
user_conf.highlights = user_conf.highlights or {}
config = vim.tbl_deep_extend("force", config, user_conf)
config.highlights = get_highlights(config)
return config
end
---@return ToggleTermConfig
return setmetatable(M, {
__index = function(_, k) return config[k] end,
})
|