Font selector to dynamically switch fonts #5369
Replies: 2 comments 2 replies
-
Thanks a ton for sharing this. Incorporated into my config for the long haul now. |
Beta Was this translation helpful? Give feedback.
-
@akthe-at since I first posted this, I've made some enhancements that I'd share in case others are interested. Specifically, you no longer need to explicitly register your fonts as before. This new version will automatically register any fonts listed in your config directory. Further, I also abstracted it to allow selection of any pre-defined configuration items via a selector (defined in For example, in my configuration, I have three selectors defined: one for fonts, one for leading (typographic term for vertical spacing), and one for my color scheme: local wezterm = require("wezterm")
local act = wezterm.action
local config = wezterm.config_builder()
local fonts = require("config-selector").new({
title = "Font Selector",
subdir = "fonts",
})
fonts:select(config, "Berkeley Mono")
local leading = require("config-selector").new({
title = "Leading Selector",
subdir = "leading",
})
leading:select(config, "Loose")
local colorschemes = require("config-selector").new({
title = "Color Scheme Selector",
subdir = "colorschemes",
})
colorschemes:select(config, "MiniHues - Nord")
config.leader = { key = "o", mods = "SUPER", timeout_milliseconds = 1000 }
config.keys = {
{ key = "c", mods = "LEADER", action = colorschemes:selector_action() },
{ key = "f", mods = "LEADER", action = fonts:selector_action() },
{ key = "l", mods = "LEADER", action = leading:selector_action() },
} In my .
├── colorschemes
│ ├── ayu.lua
│ ├── minihues-cyan.lua
│ ├── minihues-green.lua
│ ├── minihues-nightowl.lua
│ ├── minihues-nord.lua
│ ├── minihues-purple.lua
│ ├── minihues-slate.lua
│ └── tokyonight-moon.lua
├── fonts
│ ├── berkeley.lua
│ ├── jetbrains.lua
│ ├── menlo.lua
│ ├── monaspace-argon.lua
│ ├── monaspace-krypton.lua
│ ├── monaspace-neon.lua
│ ├── monaspace-radon.lua
│ ├── monaspace-xenon.lua
│ ├── operator.lua
│ ├── pragmata.lua
│ ├── roboto.lua
│ ├── scp.lua
│ ├── sf.lua
│ ├── sudo.lua
│ ├── ubuntu.lua
│ └── victor.lua
├── leading
│ ├── loose.lua
│ ├── medium.lua
│ └── tight.lua
├── config-selector.lua
├── stylua.toml
└── wezterm.lua Each module should contain two exported functions called local M = {}
M.init = function()
return "Item name"
end
M.activate = function(config)
-- Just set some configuration options, e.g.
-- config.line_height = 1.0
end
return M For example, here is one of my font definitions: local wezterm = require("wezterm")
local M = {}
local name = "Berkeley Mono"
M.init = function()
return name
end
M.activate = function(config)
config.font = wezterm.font(name)
-- config.freetype_load_target = "Light"
-- config.freetype_render_target = "HorizontalLcd"
config.font_size = 14.0
config.harfbuzz_features = { "ss02=1" }
config.font_rules = {}
end
return M And, here is one of my leading definitions: local M = {}
M.init = function()
return "Loose"
end
M.activate = function(config)
config.line_height = 1.3
end
return M And, here is a color scheme definition for a built-in theme: local M = {}
local name = "Tokyo Night Moon"
M.init = function()
return name
end
M.activate = function(config)
config.color_scheme = name
end
return M And, here is one of my custom color scheme definitions: local M = {}
local name = "MiniHues - NightOwl"
M.init = function()
return name
end
M.activate = function(config)
config.color_schemes = config.color_schemes or {}
config.color_schemes[name] = {
ansi = { "#021d33", "#f5b1bb", "#a7d5a6", "#d3c88b", "#92d0f3", "#e1b5e4", "#87d8d1", "#c0c8cb" },
background = "#021d33",
brights = { "#1d3850", "#f5b1bb", "#a7d5a6", "#d3c88b", "#92d0f3", "#e1b5e4", "#87d8d1", "#a2a9ac" },
compose_cursor = "#f0b995",
copy_mode_active_highlight_bg = {
Color = "#021d33",
},
copy_mode_active_highlight_fg = {
Color = "#a2a9ac",
},
copy_mode_inactive_highlight_bg = {
Color = "#a7d5a6",
},
copy_mode_inactive_highlight_fg = {
Color = "#021d33",
},
cursor_bg = "#92d0f3",
cursor_border = "#92d0f3",
cursor_fg = "#00364d",
foreground = "#c0c8cb",
indexed = {
[136] = "#f0b995",
},
quick_select_label_bg = {
Color = "#f0b995",
},
quick_select_label_fg = {
Color = "#021d33",
},
quick_select_match_bg = {
Color = "#1d3850",
},
quick_select_match_fg = {
Color = "#92d0f3",
},
scrollbar_thumb = "#1d3850",
selection_bg = "#38546e",
split = "#38546e",
}
config.color_scheme = name
end
return M Hopefully this gives you an idea of how you can use this new module I wrote for myself. In order to use, you just need to save this to your wezterm config directory in a file called local wezterm = require("wezterm")
local H = {}
local M = {}
local sep = package.config:sub(1, 1)
M.new = function(opts)
local self = setmetatable({}, { __index = M })
self.title = opts.title or "Config Selector"
self.config_items = {}
local dir = wezterm.config_dir .. sep .. opts.subdir
for _, path in ipairs(wezterm.read_dir(dir)) do
self:register(H.path_to_module_name(path))
end
return self
end
M.register = function(self, module_name)
local module = require(module_name)
local item_name = module.init()
self.config_items[item_name] = module
end
M.select = function(self, config, item_name)
local module = self.config_items[item_name]
module.activate(config)
end
M.selector_action = function(self)
return wezterm.action_callback(function(window, pane)
local choices = {}
for k, _ in pairs(self.config_items) do
table.insert(choices, { label = k })
end
table.sort(choices, function(a, b)
return a.label < b.label
end)
window:perform_action(
wezterm.action.InputSelector({
action = wezterm.action_callback(function(win, _, _, label)
local overrides = win:get_config_overrides() or {}
self:select(overrides, label)
win:set_config_overrides(overrides)
end),
title = self.title,
choices = choices,
fuzzy = true,
}),
pane
)
end)
end
H.path_to_module_name = function(path)
path = string.sub(path, #wezterm.config_dir + 2)
path = string.gsub(path, ".lua$", "")
path = string.gsub(path, sep, ".")
return path
end
return M |
Beta Was this translation helpful? Give feedback.
-
I switch fonts frequently based on which monitors I'm using (work vs home), time of day (when I first wake I wear my glasses instead of contacts), and size of font at which I'm working (some fonts look better at different sizes). So, I wrote myself a little font selector that I bind to
<leader>f
and thought I'd share. Here is a screencast showing it in action:Screen.Recording.2024-05-04.at.9.30.46.AM.mov
In my config, I "register" a list of fonts that I want in the menu:
For each font, I have a corresponding module with its font settings. For example, here is
font-monaspace-neon
, where I apply my custom rules (I prefer to use Monaspace Radon as my italic):Then I bind it to
<leader>f
:Finally, here is the
font
module that makes the popup:Beta Was this translation helpful? Give feedback.
All reactions