1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-22 12:51:31 +03:00

add window:set_config_overrides lua method

This commit expands on the prior commits to introduce the concept
of per-window configuration overrides.

Each TermWindow maintains json compatible object value holding
a map of config key -> config value overrides.

When the window notices that the config has changed, the config
file is loaded, the CLI overrides (if any) are applied, and then
finally the per-window overrides, before attempting to coerce
the resultant lua value into a Config object.

This mechanism has some important constraints:

* Only data can be assigned to the overrides.  Closures or special
  lua userdata object handles are not permitted.  This is because
  the lifetime of those objects is tied to the lua context in which
  they were parsed, which doesn't really exist in the context of
  the window.
* Only simple keys are supported for the per-window overrides.
  That means that trying to override a very specific field of
  a deeply structured value (eg: something like `font_rules[1].italic = false`
  isn't able to be expressed in this scheme.  Instead, you would
  need to assign the entire `font_rules` key.  I don't anticipate
  this being a common desire at this time; if more advance manipulations
  are required, then I have some thoughts on an event where arbitrary
  lua modifications can be applied.

The implementation details are fairly straight-forward, but in testing
the two examplary use cases I noticed that some hangovers from
supporting overrides for a couple of font related options meant that the
window-specific config wasn't being honored.  I've removed the code that
handled those overrides in favor of the newer more general CLI option
override support, and threaded the config through to the font code.

closes: #469
closes: #329
This commit is contained in:
Wez Furlong 2021-02-27 14:53:19 -08:00
parent 60be1a98a0
commit db08b8c1dc
19 changed files with 235 additions and 120 deletions

2
Cargo.lock generated
View File

@ -687,6 +687,7 @@ dependencies = [
"pretty_env_logger",
"promise",
"serde",
"serde_json",
"smol",
"termwiz",
"toml",
@ -1929,6 +1930,7 @@ dependencies = [
"log",
"mlua",
"serde",
"serde_json",
"strsim 0.10.0",
"thiserror",
]

View File

@ -30,6 +30,7 @@ notify = "4.0"
portable-pty = { path = "../pty", features = ["serde_support"]}
promise = { path = "../promise" }
serde = {version="1.0", features = ["rc", "derive"]}
serde_json = "1.0"
smol = "1.2"
termwiz = { path = "../termwiz" }
toml = "0.5"

View File

@ -369,10 +369,6 @@ pub enum FontLocatorSelection {
ConfigDirsOnly,
}
lazy_static::lazy_static! {
static ref DEFAULT_LOCATOR: Mutex<FontLocatorSelection> = Mutex::new(Default::default());
}
impl Default for FontLocatorSelection {
fn default() -> Self {
if cfg!(windows) {
@ -386,16 +382,6 @@ impl Default for FontLocatorSelection {
}
impl FontLocatorSelection {
pub fn set_default(self) {
let mut def = DEFAULT_LOCATOR.lock().unwrap();
*def = self;
}
pub fn get_default() -> Self {
let def = DEFAULT_LOCATOR.lock().unwrap();
*def
}
pub fn variants() -> Vec<&'static str> {
vec!["FontConfig", "CoreText", "ConfigDirsOnly", "Gdi"]
}
@ -423,10 +409,6 @@ pub enum FontRasterizerSelection {
FreeType,
}
lazy_static::lazy_static! {
static ref DEFAULT_RASTER: Mutex<FontRasterizerSelection> = Mutex::new(Default::default());
}
impl Default for FontRasterizerSelection {
fn default() -> Self {
FontRasterizerSelection::FreeType
@ -434,16 +416,6 @@ impl Default for FontRasterizerSelection {
}
impl FontRasterizerSelection {
pub fn set_default(self) {
let mut def = DEFAULT_RASTER.lock().unwrap();
*def = self;
}
pub fn get_default() -> Self {
let def = DEFAULT_RASTER.lock().unwrap();
*def
}
pub fn variants() -> Vec<&'static str> {
vec!["FreeType"]
}
@ -469,10 +441,6 @@ pub enum FontShaperSelection {
Harfbuzz,
}
lazy_static::lazy_static! {
static ref DEFAULT_SHAPER: Mutex<FontShaperSelection> = Mutex::new(Default::default());
}
impl Default for FontShaperSelection {
fn default() -> Self {
FontShaperSelection::Harfbuzz
@ -480,16 +448,6 @@ impl Default for FontShaperSelection {
}
impl FontShaperSelection {
pub fn set_default(self) {
let mut def = DEFAULT_SHAPER.lock().unwrap();
*def = self;
}
pub fn get_default() -> Self {
let def = DEFAULT_SHAPER.lock().unwrap();
*def
}
pub fn variants() -> Vec<&'static str> {
vec!["Harfbuzz", "AllSorts"]
}

View File

@ -310,6 +310,12 @@ pub fn configuration() -> ConfigHandle {
CONFIG.get()
}
/// Returns a version of the config (loaded from the config file)
/// with some field overridden based on the supplied overrides object.
pub fn overridden_config(overrides: &serde_json::Value) -> Result<ConfigHandle, Error> {
CONFIG.overridden(overrides)
}
pub fn reload() {
CONFIG.reload();
}
@ -447,9 +453,17 @@ impl ConfigInner {
self.generation += 1;
}
fn overridden(&mut self, overrides: &serde_json::Value) -> Result<ConfigHandle, Error> {
let config = Config::load_with_overrides(overrides)?;
Ok(ConfigHandle {
config: Arc::new(config.config),
generation: self.generation,
})
}
fn use_test(&mut self) {
FontLocatorSelection::ConfigDirsOnly.set_default();
let mut config = Config::default_config();
config.font_locator = FontLocatorSelection::ConfigDirsOnly;
// Specify the same DPI used on non-mac systems so
// that we have consistent values regardless of the
// operating system that we're running tests on
@ -491,6 +505,11 @@ impl Configuration {
inner.use_this_config(cfg);
}
fn overridden(&self, overrides: &serde_json::Value) -> Result<ConfigHandle, Error> {
let mut inner = self.inner.lock().unwrap();
inner.overridden(overrides)
}
/// Use a config that doesn't depend on the user's
/// environment and is suitable for unit testing
pub fn use_test(&self) {
@ -1136,6 +1155,10 @@ impl PathPossibility {
impl Config {
pub fn load() -> Result<LoadedConfig, Error> {
Self::load_with_overrides(&serde_json::Value::default())
}
pub fn load_with_overrides(overrides: &serde_json::Value) -> Result<LoadedConfig, Error> {
// Note that the directories crate has methods for locating project
// specific config directories, but only returns one of them, not
// multiple. In addition, it spawns a lot of subprocesses,
@ -1193,6 +1216,7 @@ impl Config {
.eval_async(),
)?;
let config = Self::apply_overrides_to(&lua, config)?;
let config = Self::apply_overrides_obj_to(config, overrides)?;
cfg = luahelper::from_lua_value(config).with_context(|| {
format!(
"Error converting lua value returned by script {} to Config struct",
@ -1222,6 +1246,24 @@ impl Config {
})
}
fn apply_overrides_obj_to<'l>(
mut config: mlua::Value<'l>,
overrides: &serde_json::Value,
) -> anyhow::Result<mlua::Value<'l>> {
match overrides {
serde_json::Value::Object(obj) => {
if let mlua::Value::Table(tbl) = &mut config {
for (key, value) in obj {
let value = luahelper::JsonLua(value.clone());
tbl.set(key.as_str(), value)?;
}
}
Ok(config)
}
_ => Ok(config),
}
}
fn apply_overrides_to<'l>(
lua: &'l mlua::Lua,
mut config: mlua::Value<'l>,

View File

@ -33,7 +33,8 @@ brief notes about them may accumulate here.
* Windows: Fixed [ToggleFullScreen](config/lua/keyassignment/ToggleFullScreen.md) so that it once again toggles between full screen and normal placement. [#177](https://github.com/wez/wezterm/issues/177)
* New: [exit_behavior](config/lua/config/exit_behavior.md) config option to keep panes open after the program has completed. [#499](https://github.com/wez/wezterm/issues/499)
* Closing the configuration error window no longer requires confirmation
* New: added `--config name=value` options to `wezterm`, `wezterm-gui` and `wezterm-mux-server`
* New: added `--config name=value` options to `wezterm`, `wezterm-gui` and `wezterm-mux-server`. The `--font-locator`, `--font-rasterizer` and `--font-shaper` CLI options have been removed in favor of this new mechanism.
* New: [window:set_config_overrides](config/lua/window/set_config_overrides.md) method that can be used to override GUI related configuration options on a per-window basis. Click through to see examples of dynamically toggling ligatures and window opacity. [#469](https://github.com/wez/wezterm/issues/469) [#329](https://github.com/wez/wezterm/issues/329)
### 20210203-095643-70a364eb

View File

@ -10,6 +10,8 @@ configuration, including any CLI or per-window configuration overrides.
Note: changing the config table will NOT change the effective window config;
it is just a copy of that information.
If you want to change the configuration in a window, look at [set_config_overrides](set_config_overrides.md).
This example will log the configured font size when `CTRL-SHIFT-E` is pressed:
```lua

View File

@ -0,0 +1,9 @@
# `window:get_config_overrides()`
*Since: nightly*
Returns a copy of the current set of configuration overrides that is in effect
for the window.
See [set_config_overrides](set_config_overrides.md) for examples!

View File

@ -0,0 +1,61 @@
# `window:set_config_overrides(overrides)`
*Since: nightly*
Changes the set of configuration overrides for the window.
The config file is re-evaluated and any CLI overrides are
applied, followed by the keys and values from the `overrides`
parameter.
This can be used to override configuration on a per-window basis;
this is only useful for options that apply to the GUI window, such
as rendering the GUI.
In this example, a key assignment (`CTRL-SHIFT-E`) is used to toggle the use of
ligatures in the current window:
```lua
local wezterm = require 'wezterm'
wezterm.on("toggle-ligature", function(window, pane)
local overrides = window:get_config_overrides() or {}
if not overrides.harfbuzz_features then
-- If we haven't overriden it yet, then override with ligatures disabled
overrides.harfbuzz_features = {"calt=0", "clig=0", "liga=0"}
else
-- else we did already, and we should disable out override now
overrides.harfbuzz_features = nil
end
window:set_config_overrides(overrides)
end)
return {
keys = {
{key="E", mods="CTRL", action=wezterm.action{EmitEvent="toggle-ligature"}},
},
}
```
In this example, a key assignment (`CTRL-SHIFT-B`) is used to toggle opacity
for the window:
```lua
local wezterm = require 'wezterm'
wezterm.on("toggle-opacity", function(window, pane)
local overrides = window:get_config_overrides() or {}
if not overrides.window_background_opacity then
overrides.window_background_opacity = 0.5;
else
overrides.window_background_opacity = nil
end
window:set_config_overrides(overrides)
end)
return {
keys = {
{key="B", mods="CTRL", action=wezterm.action{EmitEvent="toggle-opacity"}},
},
}
```

View File

@ -11,5 +11,6 @@ bstr = "0.2"
log = "0.4"
mlua = "0.5"
serde = {version="1.0", features = ["rc", "derive"]}
serde_json = "1.0"
strsim = "0.10"
thiserror = "1.0"

View File

@ -1,5 +1,7 @@
#![macro_use]
use serde::{Deserialize, Serialize};
mod serde_lua;
pub use mlua;
pub use serde_lua::from_lua_value;
@ -19,7 +21,7 @@ macro_rules! impl_lua_conversion {
self,
lua: &'lua $crate::mlua::Lua,
) -> Result<$crate::mlua::Value<'lua>, $crate::mlua::Error> {
Ok(luahelper::to_lua_value(lua, self)?)
Ok($crate::to_lua_value(lua, self)?)
}
}
@ -28,8 +30,13 @@ macro_rules! impl_lua_conversion {
value: $crate::mlua::Value<'lua>,
_lua: &'lua $crate::mlua::Lua,
) -> Result<Self, $crate::mlua::Error> {
Ok(luahelper::from_lua_value(value)?)
Ok($crate::from_lua_value(value)?)
}
}
};
}
#[derive(Serialize, Deserialize)]
#[serde(transparent)]
pub struct JsonLua(pub serde_json::Value);
impl_lua_conversion!(JsonLua);

View File

@ -1,7 +1,7 @@
use crate::db::FontDatabase;
use crate::locator::{new_locator, FontDataHandle, FontLocator, FontLocatorSelection};
use crate::locator::{new_locator, FontDataHandle, FontLocator};
use crate::rasterizer::{new_rasterizer, FontRasterizer};
use crate::shaper::{new_shaper, FontShaper, FontShaperSelection};
use crate::shaper::{new_shaper, FontShaper};
use anyhow::{Context, Error};
use config::{configuration, ConfigHandle, FontRasterizerSelection, TextStyle};
use std::cell::RefCell;
@ -60,8 +60,10 @@ impl LoadedFont {
}
}
if loaded {
if let Some(font_config) = self.font_config.upgrade() {
*self.shaper.borrow_mut() =
new_shaper(FontShaperSelection::get_default(), &self.handles.borrow())?;
new_shaper(&*font_config.config.borrow(), &self.handles.borrow())?;
}
}
Ok(loaded)
}
@ -152,10 +154,13 @@ impl LoadedFont {
if let Some(raster) = rasterizers.get(&fallback) {
raster.rasterize_glyph(glyph_pos, self.font_size, self.dpi)
} else {
let raster = new_rasterizer(
FontRasterizerSelection::get_default(),
&(self.handles.borrow())[fallback],
)?;
let raster_selection = self
.font_config
.upgrade()
.map_or(FontRasterizerSelection::default(), |c| {
c.config.borrow().font_rasterizer
});
let raster = new_rasterizer(raster_selection, &(self.handles.borrow())[fallback])?;
let result = raster.rasterize_glyph(glyph_pos, self.font_size, self.dpi);
rasterizers.insert(fallback, raster);
result
@ -168,7 +173,7 @@ struct FontConfigInner {
metrics: RefCell<Option<FontMetrics>>,
dpi_scale: RefCell<f64>,
font_scale: RefCell<f64>,
config_generation: RefCell<usize>,
config: RefCell<ConfigHandle>,
locator: Box<dyn FontLocator>,
font_dirs: RefCell<FontDatabase>,
built_in: RefCell<FontDatabase>,
@ -181,36 +186,43 @@ pub struct FontConfiguration {
impl FontConfigInner {
/// Create a new empty configuration
pub fn new() -> anyhow::Result<Self> {
let locator = new_locator(FontLocatorSelection::get_default());
let config = configuration();
pub fn new(config: Option<ConfigHandle>) -> anyhow::Result<Self> {
let config = config.unwrap_or_else(|| configuration());
let locator = new_locator(config.font_locator);
Ok(Self {
fonts: RefCell::new(HashMap::new()),
locator,
metrics: RefCell::new(None),
font_scale: RefCell::new(1.0),
dpi_scale: RefCell::new(1.0),
config_generation: RefCell::new(config.generation()),
config: RefCell::new(config.clone()),
font_dirs: RefCell::new(FontDatabase::with_font_dirs(&config)?),
built_in: RefCell::new(FontDatabase::with_built_in()?),
})
}
/// Given a text style, load (with caching) the font that best
/// matches according to the fontconfig pattern.
fn resolve_font(&self, myself: &Rc<Self>, style: &TextStyle) -> anyhow::Result<Rc<LoadedFont>> {
fn config_changed(&self, config: &ConfigHandle) -> anyhow::Result<()> {
let mut fonts = self.fonts.borrow_mut();
let config = configuration();
let current_generation = config.generation();
if current_generation != *self.config_generation.borrow() {
*self.config.borrow_mut() = config.clone();
// Config was reloaded, invalidate our caches
fonts.clear();
self.metrics.borrow_mut().take();
*self.font_dirs.borrow_mut() = FontDatabase::with_font_dirs(&config)?;
*self.config_generation.borrow_mut() = current_generation;
*self.font_dirs.borrow_mut() = FontDatabase::with_font_dirs(config)?;
Ok(())
}
/// Given a text style, load (with caching) the font that best
/// matches according to the fontconfig pattern.
fn resolve_font(&self, myself: &Rc<Self>, style: &TextStyle) -> anyhow::Result<Rc<LoadedFont>> {
let global_config = configuration();
let current_generation = global_config.generation();
if current_generation != self.config.borrow().generation() {
self.config_changed(&global_config)?;
}
let config = self.config.borrow();
let mut fonts = self.fonts.borrow_mut();
if let Some(entry) = fonts.get(style) {
return Ok(Rc::clone(entry));
}
@ -284,9 +296,8 @@ impl FontConfigInner {
}
}
let shaper = new_shaper(FontShaperSelection::get_default(), &handles)?;
let shaper = new_shaper(&*config, &handles)?;
let config = configuration();
let font_size = config.font_size * *self.font_scale.borrow();
let dpi =
*self.dpi_scale.borrow() as u32 * config.dpi.unwrap_or(::window::DEFAULT_DPI) as u32;
@ -326,7 +337,7 @@ impl FontConfigInner {
/// Returns the baseline font specified in the configuration
pub fn default_font(&self, myself: &Rc<Self>) -> anyhow::Result<Rc<LoadedFont>> {
self.resolve_font(myself, &configuration().font)
self.resolve_font(myself, &self.config.borrow().font)
}
pub fn get_font_scale(&self) -> f64 {
@ -392,11 +403,15 @@ impl FontConfigInner {
impl FontConfiguration {
/// Create a new empty configuration
pub fn new() -> anyhow::Result<Self> {
let inner = Rc::new(FontConfigInner::new()?);
pub fn new(config: Option<ConfigHandle>) -> anyhow::Result<Self> {
let inner = Rc::new(FontConfigInner::new(config)?);
Ok(Self { inner })
}
pub fn config_changed(&self, config: &ConfigHandle) -> anyhow::Result<()> {
self.inner.config_changed(config)
}
/// Given a text style, load (with caching) the font that best
/// matches according to the fontconfig pattern.
pub fn resolve_font(&self, style: &TextStyle) -> anyhow::Result<Rc<LoadedFont>> {

View File

@ -452,7 +452,7 @@ pub struct AllsortsShaper {
}
impl AllsortsShaper {
pub fn new(handles: &[FontDataHandle]) -> anyhow::Result<Self> {
pub fn new(_: &config::ConfigHandle, handles: &[FontDataHandle]) -> anyhow::Result<Self> {
let mut fonts = vec![];
let mut success = false;
for handle in handles {

View File

@ -4,7 +4,7 @@ use crate::locator::FontDataHandle;
use crate::shaper::{FallbackIdx, FontMetrics, FontShaper, GlyphInfo};
use crate::units::*;
use anyhow::anyhow;
use config::configuration;
use config::ConfigHandle;
use log::error;
use ordered_float::NotNan;
use std::cell::{RefCell, RefMut};
@ -66,6 +66,7 @@ pub struct HarfbuzzShaper {
fonts: Vec<RefCell<Option<FontPair>>>,
lib: ftwrap::Library,
metrics: RefCell<HashMap<MetricsKey, FontMetrics>>,
config: ConfigHandle,
}
#[derive(Error, Debug)]
@ -102,7 +103,7 @@ fn is_question_string(s: &str) -> bool {
}
impl HarfbuzzShaper {
pub fn new(handles: &[FontDataHandle]) -> anyhow::Result<Self> {
pub fn new(config: &ConfigHandle, handles: &[FontDataHandle]) -> anyhow::Result<Self> {
let lib = ftwrap::Library::new()?;
let handles = handles.to_vec();
let mut fonts = vec![];
@ -114,6 +115,7 @@ impl HarfbuzzShaper {
handles,
lib,
metrics: RefCell::new(HashMap::new()),
config: config.clone(),
})
}
@ -149,7 +151,7 @@ impl HarfbuzzShaper {
dpi: u32,
no_glyphs: &mut Vec<char>,
) -> anyhow::Result<Vec<GlyphInfo>> {
let config = configuration();
let config = &self.config;
let features: Vec<harfbuzz::hb_feature_t> = config
.harfbuzz_features
.iter()
@ -451,7 +453,9 @@ mod test {
.unwrap()
.clone();
let shaper = HarfbuzzShaper::new(&[handle]).unwrap();
let config = config::configuration();
let shaper = HarfbuzzShaper::new(&config, &[handle]).unwrap();
{
let mut no_glyphs = vec![];
let info = shaper.shape("abc", 10., 72, &mut no_glyphs).unwrap();

View File

@ -74,11 +74,15 @@ pub trait FontShaper {
pub use config::FontShaperSelection;
pub fn new_shaper(
shaper: FontShaperSelection,
config: &config::ConfigHandle,
handles: &[FontDataHandle],
) -> anyhow::Result<Box<dyn FontShaper>> {
match shaper {
FontShaperSelection::Harfbuzz => Ok(Box::new(harfbuzz::HarfbuzzShaper::new(handles)?)),
FontShaperSelection::Allsorts => Ok(Box::new(allsorts::AllsortsShaper::new(handles)?)),
match config.font_shaper {
FontShaperSelection::Harfbuzz => {
Ok(Box::new(harfbuzz::HarfbuzzShaper::new(config, handles)?))
}
FontShaperSelection::Allsorts => {
Ok(Box::new(allsorts::AllsortsShaper::new(config, handles)?))
}
}
}

View File

@ -1,6 +1,3 @@
use config::FontLocatorSelection;
use config::FontRasterizerSelection;
use config::FontShaperSelection;
use config::{FrontEndSelection, SshParameters};
use std::ffi::OsString;
use structopt::StructOpt;
@ -32,27 +29,6 @@ pub struct StartCommand {
)]
pub front_end: Option<FrontEndSelection>,
#[structopt(
long = "font-locator",
possible_values = &FontLocatorSelection::variants(),
case_insensitive = true
)]
pub font_locator: Option<FontLocatorSelection>,
#[structopt(
long = "font-rasterizer",
possible_values = &FontRasterizerSelection::variants(),
case_insensitive = true
)]
pub font_rasterizer: Option<FontRasterizerSelection>,
#[structopt(
long = "font-shaper",
possible_values = &FontShaperSelection::variants(),
case_insensitive = true
)]
pub font_shaper: Option<FontShaperSelection>,
/// If true, do not connect to domains marked as connect_automatically
/// in your wezterm.toml configuration file.
#[structopt(long = "no-auto-connect")]

View File

@ -270,7 +270,7 @@ mod test {
.filter_level(log::LevelFilter::Trace)
.try_init();
let fonts = Rc::new(FontConfiguration::new().unwrap());
let fonts = Rc::new(FontConfiguration::new(None).unwrap());
let render_metrics = RenderMetrics::new(&fonts).unwrap();
let mut glyph_cache = GlyphCache::new_in_memory(&fonts, 128, &render_metrics).unwrap();

View File

@ -222,6 +222,7 @@ pub struct TabState {
pub struct TermWindow {
pub window: Option<Window>,
pub config: ConfigHandle,
pub config_overrides: serde_json::Value,
/// When we most recently received keyboard focus
focused: Option<Instant>,
fonts: Rc<FontConfiguration>,
@ -720,6 +721,7 @@ impl WindowCallbacks for TermWindow {
let guts = Box::new(Self {
window: None,
config: self.config.clone(),
config_overrides: self.config_overrides.clone(),
window_background: self.window_background.clone(),
palette: None,
focused: None,
@ -935,7 +937,7 @@ impl TermWindow {
let window_background = load_background_image(&config);
let fontconfig = Rc::new(FontConfiguration::new()?);
let fontconfig = Rc::new(FontConfiguration::new(Some(config.clone()))?);
let mux = Mux::get().expect("to be main thread with mux running");
let size = match mux.get_active_tab_for_window(mux_window_id) {
Some(tab) => tab.get_size(),
@ -994,6 +996,7 @@ impl TermWindow {
window: None,
window_background,
config: config.clone(),
config_overrides: serde_json::Value::default(),
palette: None,
focused: None,
mux_window_id,
@ -1304,8 +1307,22 @@ impl TermWindow {
self.palette.as_ref().unwrap()
}
fn config_was_reloaded(&mut self) {
let config = configuration();
pub fn config_was_reloaded(&mut self) {
log::debug!(
"config was reloaded, overrides: {:?}",
self.config_overrides
);
let config = match config::overridden_config(&self.config_overrides) {
Ok(config) => config,
Err(err) => {
log::error!(
"Failed to apply config overrides to window: {:#}: {:?}",
err,
self.config_overrides
);
configuration()
}
};
self.config = config.clone();
self.palette.take();
@ -1328,6 +1345,10 @@ impl TermWindow {
self.leader_is_down = None;
let dimensions = self.dimensions;
let cell_dims = self.current_cell_dimensions();
if let Err(err) = self.fonts.config_changed(&config) {
log::error!("Failed to load font configuration: {:#}", err);
}
self.apply_scale_change(&dimensions, self.fonts.get_font_scale());
self.apply_dimensions(&dimensions, Some(cell_dims));
if let Some(window) = self.window.as_ref() {
@ -2412,7 +2433,7 @@ impl TermWindow {
fn reset_font_and_window_size(&mut self) -> anyhow::Result<()> {
let config = &self.config;
let size = config.initial_size();
let fontconfig = Rc::new(FontConfiguration::new()?);
let fontconfig = Rc::new(FontConfiguration::new(Some(config.clone()))?);
let render_metrics = RenderMetrics::new(&fontconfig)?;
let terminal_size = PtySize {

View File

@ -289,14 +289,6 @@ fn run_terminal_gui(config: config::ConfigHandle, opts: StartCommand) -> anyhow:
}
let run = move || -> anyhow::Result<()> {
opts.font_locator
.unwrap_or(config.font_locator)
.set_default();
opts.font_shaper.unwrap_or(config.font_shaper).set_default();
opts.font_rasterizer
.unwrap_or(config.font_rasterizer)
.set_default();
let need_builder = !opts.prog.is_empty() || opts.cwd.is_some();
let cmd = if need_builder {

View File

@ -4,6 +4,7 @@ use super::pane::PaneObject;
use crate::gui::TermWindow;
use anyhow::anyhow;
use config::keyassignment::KeyAssignment;
use luahelper::JsonLua;
use mlua::{UserData, UserDataMethods};
use mux::window::WindowId as MuxWindowId;
use window::WindowOps;
@ -59,5 +60,23 @@ impl UserData for GuiWin {
this.with_term_window(move |term_window, _ops| Ok((*term_window.config).clone()))
.await
});
methods.add_async_method("get_config_overrides", |_, this, _: ()| async move {
this.with_term_window(move |term_window, _ops| {
let wrap = JsonLua(term_window.config_overrides.clone());
Ok(wrap)
})
.await
});
methods.add_async_method(
"set_config_overrides",
|_, this, value: JsonLua| async move {
this.with_term_window(move |term_window, _ops| {
term_window.config_overrides = value.0.clone();
term_window.config_was_reloaded();
Ok(())
})
.await
},
);
}
}