Support passing argument to `LuaEval` and `LuaEvalSilently`

If the argument of `LuaEval` evaluates to a function, xplr will try to
pass Lua Context to it.

Example:

```lua
{ LuaEval = [[function(app) return { { LogInfo = app.pwd } } end]] }
```

Closes: https://github.com/sayanarijit/xplr/issues/394
pull/425/head
Arijit Basu 3 years ago committed by Arijit Basu
parent ea235b6969
commit 7b9e4deff5

@ -469,12 +469,16 @@ stderr will be piped to null. So it's non-interactive.
**YAML:** `LuaEval: string`
Execute Lua code without needing to define a function. However,
[Lua Context][14] won't be available.
Execute Lua code without needing to define a function.
If the `string` is a callable, xplr will try to call it with with the
[Lua Context][14] argument.
**YAML Example:** `LuaEval: "return { { LogInfo = io.read() } }"`
**YAML Example:** `LuaEval: "function(app) return { { LogInfo = app.pwd } } end"`
**Lua Example:** `{ LuaEval = [[return { { LogInfo = io.read() } }]] }`
**Lua Example:** `{ LuaEval = [[function(app) return { { LogInfo = app.pwd } } end]] }`
### { LuaEvalSilently = "string" }

@ -14,6 +14,7 @@ use crossterm::event;
use crossterm::execute;
use crossterm::terminal as term;
use mlua::LuaSerdeExt;
use mlua::Value;
use std::fs;
use std::io::Write;
use std::path::PathBuf;
@ -555,18 +556,55 @@ impl Runner {
term::disable_raw_mode()?;
terminal.show_cursor()?;
let res: Result<Option<Vec<ExternalMsg>>> = lua
.load(&code)
.eval()
.and_then(|v| lua.from_value(v))
.map_err(Error::from);
let res: Result<Value> =
lua.load(&code).eval().map_err(Error::from);
match res {
Ok(Some(msgs)) => {
app = app
.handle_batch_external_msgs(msgs)?;
Ok(Value::Function(f)) => {
let arg = app.to_lua_ctx_heavy();
let res: Result<
Option<Vec<ExternalMsg>>,
> = lua
.to_value(&arg)
.and_then(|a| f.call(a))
.and_then(|v| lua.from_value(v))
.map_err(Error::from);
match res {
Ok(Some(msgs)) => {
app = app
.handle_batch_external_msgs(
msgs,
)?;
}
Ok(None) => {}
Err(err) => {
app = app.log_error(
err.to_string(),
)?;
}
}
}
Ok(v) => {
let res: Result<
Option<Vec<ExternalMsg>>,
> = lua
.from_value(v)
.map_err(Error::from);
match res {
Ok(Some(msgs)) => {
app = app
.handle_batch_external_msgs(
msgs,
)?;
}
Ok(None) => {}
Err(err) => {
app = app.log_error(
err.to_string(),
)?;
}
}
}
Ok(None) => {}
Err(err) => {
app = app.log_error(err.to_string())?;
}
@ -594,18 +632,55 @@ impl Runner {
}
LuaEvalSilently(code) => {
let res: Result<Option<Vec<ExternalMsg>>> = lua
.load(&code)
.eval()
.and_then(|v| lua.from_value(v))
.map_err(Error::from);
let res: Result<Value> =
lua.load(&code).eval().map_err(Error::from);
match res {
Ok(Some(msgs)) => {
app = app
.handle_batch_external_msgs(msgs)?;
Ok(Value::Function(f)) => {
let arg = app.to_lua_ctx_heavy();
let res: Result<
Option<Vec<ExternalMsg>>,
> = lua
.to_value(&arg)
.and_then(|a| f.call(a))
.and_then(|v| lua.from_value(v))
.map_err(Error::from);
match res {
Ok(Some(msgs)) => {
app = app
.handle_batch_external_msgs(
msgs,
)?;
}
Ok(None) => {}
Err(err) => {
app = app.log_error(
err.to_string(),
)?;
}
}
}
Ok(v) => {
let res: Result<
Option<Vec<ExternalMsg>>,
> = lua
.from_value(v)
.map_err(Error::from);
match res {
Ok(Some(msgs)) => {
app = app
.handle_batch_external_msgs(
msgs,
)?;
}
Ok(None) => {}
Err(err) => {
app = app.log_error(
err.to_string(),
)?;
}
}
}
Ok(None) => {}
Err(err) => {
app = app.log_error(err.to_string())?;
}

Loading…
Cancel
Save