mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 21:32:13 +03:00
add __len and __pairs metamethods to wezterm.GLOBALS
Fixes this: ``` > wezterm.GLOBAL.foo = {"bar", "baz"} > wezterm.GLOBAL.foo [ "bar", "baz", ] > #wezterm.GLOBAL.foo runtime error: [string "repl"]:1: attempt to get length of a userdata value (field 'foo') stack traceback: [string "repl"]:1: in main chunk > ``` and allows this: ``` > for k, v in pairs(wezterm.GLOBAL.foo) do print(k, v) ; end ```
This commit is contained in:
parent
00ada33fe2
commit
8755e731d3
@ -23,6 +23,7 @@ As features stabilize some brief notes about them will accumulate here.
|
|||||||
|
|
||||||
#### Fixed
|
#### Fixed
|
||||||
* ssh ProxyCommand didn't parse command lines containing `=` correctly. #3307
|
* ssh ProxyCommand didn't parse command lines containing `=` correctly. #3307
|
||||||
|
* `wezterm.GLOBALS.foo` now supports `__len` and `__pairs` metamethods
|
||||||
|
|
||||||
### 20230320-124340-559cb7b0
|
### 20230320-124340-559cb7b0
|
||||||
|
|
||||||
|
@ -271,6 +271,75 @@ impl UserData for Value {
|
|||||||
mlua::MetaMethod::Custom("__wezterm_to_dynamic".to_string()),
|
mlua::MetaMethod::Custom("__wezterm_to_dynamic".to_string()),
|
||||||
|lua: &Lua, this, _: ()| -> mlua::Result<mlua::Value> { gvalue_to_lua(lua, this) },
|
|lua: &Lua, this, _: ()| -> mlua::Result<mlua::Value> { gvalue_to_lua(lua, this) },
|
||||||
);
|
);
|
||||||
|
methods.add_meta_method(
|
||||||
|
mlua::MetaMethod::Len,
|
||||||
|
|lua: &Lua, this, _: ()| -> mlua::Result<mlua::Value> {
|
||||||
|
match this {
|
||||||
|
Value::Array(arr) => arr.inner.lock().unwrap().len().to_lua(lua),
|
||||||
|
Value::Object(obj) => obj.inner.lock().unwrap().len().to_lua(lua),
|
||||||
|
Value::String(s) => s.to_string().to_lua(lua),
|
||||||
|
_ => Err(mlua::Error::external(
|
||||||
|
"invalid type for len operator".to_string(),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
methods.add_meta_method(mlua::MetaMethod::Pairs, |lua, this, ()| match this {
|
||||||
|
Value::Array(_) => {
|
||||||
|
let stateless_iter =
|
||||||
|
lua.create_function(|lua, (this, i): (Value, usize)| match this {
|
||||||
|
Value::Array(arr) => {
|
||||||
|
let arr = arr.inner.lock().unwrap();
|
||||||
|
let i = i + 1;
|
||||||
|
|
||||||
|
if i <= arr.len() {
|
||||||
|
return Ok(mlua::Variadic::from_iter(vec![
|
||||||
|
i.to_lua(lua)?,
|
||||||
|
arr[i - 1].clone().to_lua(lua)?,
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
return Ok(mlua::Variadic::new());
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
})?;
|
||||||
|
Ok((stateless_iter, this.clone(), 0.to_lua(lua)?))
|
||||||
|
}
|
||||||
|
Value::Object(_) => {
|
||||||
|
let stateless_iter =
|
||||||
|
lua.create_function(|lua, (this, key): (Value, Option<String>)| match this {
|
||||||
|
Value::Object(obj) => {
|
||||||
|
let obj = obj.inner.lock().unwrap();
|
||||||
|
let mut iter = obj.iter();
|
||||||
|
|
||||||
|
let mut this_is_key = false;
|
||||||
|
|
||||||
|
if key.is_none() {
|
||||||
|
this_is_key = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some((this_key, value)) = iter.next() {
|
||||||
|
if this_is_key {
|
||||||
|
return Ok(mlua::MultiValue::from_vec(vec![
|
||||||
|
this_key.clone().to_lua(lua)?,
|
||||||
|
value.clone().to_lua(lua)?,
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
if Some(this_key.as_str()) == key.as_deref() {
|
||||||
|
this_is_key = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Ok(mlua::MultiValue::new());
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
})?;
|
||||||
|
Ok((stateless_iter, this.clone(), LuaValue::Nil))
|
||||||
|
}
|
||||||
|
_ => Err(mlua::Error::external(
|
||||||
|
"invalid type for __ipairs metamethod".to_string(),
|
||||||
|
)),
|
||||||
|
});
|
||||||
|
|
||||||
methods.add_meta_method(
|
methods.add_meta_method(
|
||||||
mlua::MetaMethod::Index,
|
mlua::MetaMethod::Index,
|
||||||
|lua: &Lua, this, key: LuaValue| -> mlua::Result<mlua::Value> {
|
|lua: &Lua, this, key: LuaValue| -> mlua::Result<mlua::Value> {
|
||||||
|
Loading…
Reference in New Issue
Block a user