File: config.lua

package info (click to toggle)
neovim-toggleterm 2.13.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 316 kB
  • sloc: makefile: 2
file content (157 lines) | stat: -rw-r--r-- 5,154 bytes parent folder | download
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,
})