mirror of
https://github.com/wez/wezterm.git
synced 2024-12-29 16:42:13 +03:00
lua: make it easier to write type-safe functions
implementing the `ToLua` and `FromLua` traits allows `create_function` to automatically apply the appropriate conversions to the parameters and return values in a callback function. That makes it possible (and nicer!) to write properly typed callbacks.
This commit is contained in:
parent
72097cbfbb
commit
b1b24b48ec
@ -2,7 +2,7 @@ use crate::config::*;
|
||||
use termwiz::cell::CellAttributes;
|
||||
use termwiz::color::{ColorSpec, RgbColor};
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct Palette {
|
||||
/// The text color to use when the attributes are reset to default
|
||||
pub foreground: Option<RgbColor>,
|
||||
@ -26,6 +26,7 @@ pub struct Palette {
|
||||
/// represents the current viewable area
|
||||
pub scrollbar_thumb: Option<RgbColor>,
|
||||
}
|
||||
impl_lua_conversion!(Palette);
|
||||
|
||||
impl From<Palette> for term::color::ColorPalette {
|
||||
fn from(cfg: Palette) -> term::color::ColorPalette {
|
||||
@ -61,7 +62,7 @@ impl From<Palette> for term::color::ColorPalette {
|
||||
}
|
||||
|
||||
/// Specify the text styling for a tab in the tab bar
|
||||
#[derive(Debug, Deserialize, Clone, Default)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, Default)]
|
||||
pub struct TabBarColor {
|
||||
/// Specifies the intensity attribute for the tab title text
|
||||
#[serde(default)]
|
||||
@ -80,6 +81,7 @@ pub struct TabBarColor {
|
||||
/// The forgeground/text color for the tab
|
||||
pub fg_color: RgbColor,
|
||||
}
|
||||
impl_lua_conversion!(TabBarColor);
|
||||
|
||||
impl TabBarColor {
|
||||
pub fn as_cell_attributes(&self) -> CellAttributes {
|
||||
@ -97,7 +99,7 @@ impl TabBarColor {
|
||||
/// Specifies the colors to use for the tab bar portion of the UI.
|
||||
/// These are not part of the terminal model and cannot be updated
|
||||
/// in the same way that the dynamic color schemes are.
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct TabBarColors {
|
||||
/// The background color for the tab bar
|
||||
#[serde(default = "default_background")]
|
||||
@ -115,6 +117,7 @@ pub struct TabBarColors {
|
||||
#[serde(default = "default_inactive_tab_hover")]
|
||||
pub inactive_tab_hover: TabBarColor,
|
||||
}
|
||||
impl_lua_conversion!(TabBarColors);
|
||||
|
||||
fn default_background() -> RgbColor {
|
||||
RgbColor::new(0x0b, 0x00, 0x22)
|
||||
@ -154,8 +157,9 @@ impl Default for TabBarColors {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct ColorSchemeFile {
|
||||
/// The color palette
|
||||
pub colors: Palette,
|
||||
}
|
||||
impl_lua_conversion!(ColorSchemeFile);
|
||||
|
@ -2,12 +2,13 @@ use crate::config::*;
|
||||
use std::fs::{File, OpenOptions};
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Default, Debug, Clone, Deserialize)]
|
||||
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct DaemonOptions {
|
||||
pub pid_file: Option<PathBuf>,
|
||||
pub stdout: Option<PathBuf>,
|
||||
pub stderr: Option<PathBuf>,
|
||||
}
|
||||
impl_lua_conversion!(DaemonOptions);
|
||||
|
||||
fn open_log(path: PathBuf) -> anyhow::Result<File> {
|
||||
create_user_owned_dirs(
|
||||
|
@ -8,7 +8,7 @@ const FONT_FAMILY: &str = "Consolas";
|
||||
#[cfg(all(not(target_os = "macos"), not(windows)))]
|
||||
const FONT_FAMILY: &str = "monospace";
|
||||
|
||||
#[derive(Debug, Copy, Deserialize, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Copy, Deserialize, Serialize, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum FontHinting {
|
||||
/// No hinting is performed
|
||||
None,
|
||||
@ -21,6 +21,7 @@ pub enum FontHinting {
|
||||
/// Vertical and horizontal hinting is performed.
|
||||
Full,
|
||||
}
|
||||
impl_lua_conversion!(FontHinting);
|
||||
|
||||
impl Default for FontHinting {
|
||||
fn default() -> Self {
|
||||
@ -28,12 +29,13 @@ impl Default for FontHinting {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Deserialize, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Copy, Deserialize, Serialize, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum FontAntiAliasing {
|
||||
None,
|
||||
Greyscale,
|
||||
Subpixel,
|
||||
}
|
||||
impl_lua_conversion!(FontAntiAliasing);
|
||||
|
||||
impl Default for FontAntiAliasing {
|
||||
fn default() -> Self {
|
||||
@ -52,6 +54,7 @@ pub struct FontAttributes {
|
||||
#[serde(default)]
|
||||
pub italic: bool,
|
||||
}
|
||||
impl_lua_conversion!(FontAttributes);
|
||||
|
||||
impl FontAttributes {
|
||||
pub fn new(family: &str) -> Self {
|
||||
@ -85,6 +88,7 @@ pub struct TextStyle {
|
||||
/// the text color for eg: bold text.
|
||||
pub foreground: Option<RgbColor>,
|
||||
}
|
||||
impl_lua_conversion!(TextStyle);
|
||||
|
||||
impl Default for TextStyle {
|
||||
fn default() -> Self {
|
||||
@ -178,7 +182,7 @@ impl TextStyle {
|
||||
/// The above is translated as: "if the `CellAttributes` have the italic bit
|
||||
/// set, then use the italic style of font rather than the default", and
|
||||
/// stop processing further font rules.
|
||||
#[derive(Debug, Default, Deserialize, Clone)]
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Clone)]
|
||||
pub struct StyleRule {
|
||||
/// If present, this rule matches when CellAttributes::intensity holds
|
||||
/// a value that matches this rule. Valid values are "Bold", "Normal",
|
||||
@ -207,3 +211,4 @@ pub struct StyleRule {
|
||||
/// When this rule matches, `font` specifies the styling to be used.
|
||||
pub font: TextStyle,
|
||||
}
|
||||
impl_lua_conversion!(StyleRule);
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::keyassignment::{KeyAssignment, SpawnTabDomain};
|
||||
use anyhow::{anyhow, Error};
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use termwiz::input::{KeyCode, Modifiers};
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct Key {
|
||||
#[serde(deserialize_with = "de_keycode")]
|
||||
pub key: KeyCode,
|
||||
@ -13,6 +13,7 @@ pub struct Key {
|
||||
#[serde(default)]
|
||||
pub arg: Option<String>,
|
||||
}
|
||||
impl_lua_conversion!(Key);
|
||||
|
||||
impl std::convert::TryInto<KeyAssignment> for &Key {
|
||||
type Error = Error;
|
||||
@ -89,7 +90,7 @@ impl std::convert::TryInto<KeyAssignment> for &Key {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub enum KeyAction {
|
||||
SpawnTab,
|
||||
SpawnTabInCurrentTabDomain,
|
||||
@ -116,6 +117,7 @@ pub enum KeyAction {
|
||||
ScrollByPage,
|
||||
ShowTabNavigator,
|
||||
}
|
||||
impl_lua_conversion!(KeyAction);
|
||||
|
||||
fn de_keycode<'de, D>(deserializer: D) -> Result<KeyCode, D::Error>
|
||||
where
|
||||
|
@ -492,7 +492,7 @@ pub struct Config {
|
||||
pub use_local_build_for_proxy: bool,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Copy, Debug)]
|
||||
#[derive(Deserialize, Serialize, Clone, Copy, Debug)]
|
||||
pub enum DefaultCursorStyle {
|
||||
BlinkingBlock,
|
||||
SteadyBlock,
|
||||
@ -501,6 +501,7 @@ pub enum DefaultCursorStyle {
|
||||
BlinkingBar,
|
||||
SteadyBar,
|
||||
}
|
||||
impl_lua_conversion!(DefaultCursorStyle);
|
||||
|
||||
impl Default for DefaultCursorStyle {
|
||||
fn default() -> Self {
|
||||
@ -524,7 +525,7 @@ impl DefaultCursorStyle {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Deserialize, Clone, Copy, Debug)]
|
||||
#[derive(Default, Deserialize, Serialize, Clone, Copy, Debug)]
|
||||
pub struct WindowPadding {
|
||||
#[serde(default)]
|
||||
pub left: u16,
|
||||
@ -535,6 +536,7 @@ pub struct WindowPadding {
|
||||
#[serde(default)]
|
||||
pub bottom: u16,
|
||||
}
|
||||
impl_lua_conversion!(WindowPadding);
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
|
@ -1,7 +1,6 @@
|
||||
use crate::config::*;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Default, Debug, Clone, Deserialize)]
|
||||
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct SshDomain {
|
||||
/// The name of this specific domain. Must be unique amongst
|
||||
/// all types of domain in the configuration file.
|
||||
@ -24,3 +23,4 @@ pub struct SshDomain {
|
||||
#[serde(default = "default_read_timeout")]
|
||||
pub timeout: Duration,
|
||||
}
|
||||
impl_lua_conversion!(SshDomain);
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::config::*;
|
||||
use crate::SshParameters;
|
||||
|
||||
#[derive(Default, Debug, Clone, Deserialize)]
|
||||
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct TlsDomainServer {
|
||||
/// The address:port combination on which the server will listen
|
||||
/// for client connections
|
||||
@ -24,8 +24,9 @@ pub struct TlsDomainServer {
|
||||
#[serde(default)]
|
||||
pub pem_root_certs: Vec<PathBuf>,
|
||||
}
|
||||
impl_lua_conversion!(TlsDomainServer);
|
||||
|
||||
#[derive(Default, Debug, Clone, Deserialize)]
|
||||
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct TlsDomainClient {
|
||||
/// The name of this specific domain. Must be unique amongst
|
||||
/// all types of domain in the configuration file.
|
||||
@ -80,6 +81,7 @@ pub struct TlsDomainClient {
|
||||
#[serde(default = "default_write_timeout")]
|
||||
pub write_timeout: Duration,
|
||||
}
|
||||
impl_lua_conversion!(TlsDomainClient);
|
||||
|
||||
impl TlsDomainClient {
|
||||
pub fn ssh_parameters(&self) -> Option<anyhow::Result<SshParameters>> {
|
||||
|
@ -3,7 +3,7 @@ use std::path::PathBuf;
|
||||
|
||||
/// Configures an instance of a multiplexer that can be communicated
|
||||
/// with via a unix domain socket
|
||||
#[derive(Default, Debug, Clone, Deserialize)]
|
||||
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct UnixDomain {
|
||||
/// The name of this specific domain. Must be unique amongst
|
||||
/// all types of domain in the configuration file.
|
||||
@ -44,6 +44,7 @@ pub struct UnixDomain {
|
||||
#[serde(default = "default_write_timeout")]
|
||||
pub write_timeout: Duration,
|
||||
}
|
||||
impl_lua_conversion!(UnixDomain);
|
||||
|
||||
impl UnixDomain {
|
||||
pub fn socket_path(&self) -> PathBuf {
|
||||
|
@ -3,7 +3,7 @@ use crate::mux::tab::Tab;
|
||||
use crate::mux::window::WindowId;
|
||||
use anyhow::{anyhow, Error};
|
||||
use downcast_rs::{impl_downcast, Downcast};
|
||||
use serde::Deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
@ -12,13 +12,14 @@ pub mod activity;
|
||||
pub mod gui;
|
||||
pub mod muxserver;
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum FrontEndSelection {
|
||||
OpenGL,
|
||||
Software,
|
||||
MuxServer,
|
||||
Null,
|
||||
}
|
||||
impl_lua_conversion!(FrontEndSelection);
|
||||
|
||||
impl Default for FrontEndSelection {
|
||||
fn default() -> Self {
|
||||
|
@ -18,6 +18,9 @@ use std::sync::Arc;
|
||||
use structopt::StructOpt;
|
||||
use tabout::{tabulate_output, Alignment, Column};
|
||||
|
||||
// This module defines a macro, so it must be referenced before any other mods
|
||||
mod scripting;
|
||||
|
||||
mod config;
|
||||
mod connui;
|
||||
mod frontend;
|
||||
@ -25,7 +28,6 @@ mod keyassignment;
|
||||
mod localtab;
|
||||
mod mux;
|
||||
mod ratelim;
|
||||
mod scripting;
|
||||
mod server;
|
||||
mod ssh;
|
||||
mod stats;
|
||||
|
@ -1,5 +1,8 @@
|
||||
#![macro_use]
|
||||
|
||||
use crate::config::{FontAttributes, TextStyle};
|
||||
use anyhow::anyhow;
|
||||
use mlua::{Lua, Table, Value};
|
||||
use mlua::{Lua, Table};
|
||||
use std::path::Path;
|
||||
|
||||
mod serde_lua;
|
||||
@ -7,6 +10,31 @@ mod serde_lua;
|
||||
pub use serde_lua::from_lua_value;
|
||||
pub use serde_lua::ser::to_lua_value;
|
||||
|
||||
/// Implement lua conversion traits for a type.
|
||||
/// This implementation requires that the type implement
|
||||
/// serde Serialize and Deserialize.
|
||||
/// Why do we need these traits? They allow `create_function` to
|
||||
/// operate in terms of our internal types rather than forcing
|
||||
/// the implementer to use generic Value parameter or return values.
|
||||
macro_rules! impl_lua_conversion {
|
||||
($struct:ident) => {
|
||||
impl<'lua> mlua::ToLua<'lua> for $struct {
|
||||
fn to_lua(self, lua: &'lua mlua::Lua) -> Result<mlua::Value<'lua>, mlua::Error> {
|
||||
Ok(crate::scripting::to_lua_value(lua, self)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> mlua::FromLua<'lua> for $struct {
|
||||
fn from_lua(
|
||||
value: mlua::Value<'lua>,
|
||||
_lua: &'lua mlua::Lua,
|
||||
) -> Result<Self, mlua::Error> {
|
||||
Ok(crate::scripting::from_lua_value(value)?)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Set up a lua context for executing some code.
|
||||
/// The path to the directory containing the configuration is
|
||||
/// passed in and is used to pre-set some global values in
|
||||
@ -124,24 +152,18 @@ fn hostname<'lua>(_: &'lua Lua, _: ()) -> mlua::Result<String> {
|
||||
/// yields:
|
||||
/// `{ font = {{ family = "foo" }}, foreground="tomato"}`
|
||||
fn font<'lua>(
|
||||
lua: &'lua Lua,
|
||||
(family, map_defaults): (String, Option<Table<'lua>>),
|
||||
) -> mlua::Result<Value<'lua>> {
|
||||
use crate::config::{FontAttributes, TextStyle};
|
||||
|
||||
let mut text_style: TextStyle = match map_defaults {
|
||||
Some(def) => from_lua_value(Value::Table(def))?,
|
||||
None => TextStyle::default(),
|
||||
};
|
||||
_lua: &'lua Lua,
|
||||
(family, map_defaults): (String, Option<TextStyle>),
|
||||
) -> mlua::Result<TextStyle> {
|
||||
let mut text_style = map_defaults.unwrap_or_else(TextStyle::default);
|
||||
|
||||
text_style.font.clear();
|
||||
text_style.font.push(FontAttributes {
|
||||
family,
|
||||
bold: false,
|
||||
italic: false,
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
Ok(to_lua_value(lua, text_style)?)
|
||||
Ok(text_style)
|
||||
}
|
||||
|
||||
/// Given a list of font family names in order of preference, return a
|
||||
@ -152,24 +174,18 @@ fn font<'lua>(
|
||||
/// The second optional argument is a list of other TextStyle fields,
|
||||
/// as described by the `wezterm.font` documentation.
|
||||
fn font_with_fallback<'lua>(
|
||||
lua: &'lua Lua,
|
||||
(fallback, map_defaults): (Vec<String>, Option<Table<'lua>>),
|
||||
) -> mlua::Result<Value<'lua>> {
|
||||
use crate::config::{FontAttributes, TextStyle};
|
||||
|
||||
let mut text_style: TextStyle = match map_defaults {
|
||||
Some(def) => from_lua_value(Value::Table(def))?,
|
||||
None => TextStyle::default(),
|
||||
};
|
||||
_lua: &'lua Lua,
|
||||
(fallback, map_defaults): (Vec<String>, Option<TextStyle>),
|
||||
) -> mlua::Result<TextStyle> {
|
||||
let mut text_style = map_defaults.unwrap_or_else(TextStyle::default);
|
||||
|
||||
text_style.font.clear();
|
||||
for family in fallback {
|
||||
text_style.font.push(FontAttributes {
|
||||
family,
|
||||
bold: false,
|
||||
italic: false,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
||||
Ok(to_lua_value(lua, text_style)?)
|
||||
Ok(text_style)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user