Add support for native lua bindings

Ref: https://github.com/sayanarijit/xplr/discussions/146#discussioncomment-741580
pull/162/head v0.10.0-beta.0
Arijit Basu 3 years ago committed by Arijit Basu
parent 98687515d7
commit f744553a0a

59
Cargo.lock generated

@ -126,6 +126,12 @@ dependencies = [
"rustc_version",
]
[[package]]
name = "cc"
version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -332,6 +338,15 @@ version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "erased-serde"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0465971a8cc1fa2455c8465aaa377131e1f1cf4983280f474a13e68793aa770c"
dependencies = [
"serde",
]
[[package]]
name = "fake-simd"
version = "0.1.2"
@ -488,6 +503,24 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "lua-src"
version = "543.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "029180f994b9b36f47d905f92569b516acf7d073778e2e781c15ee375b1ca27d"
dependencies = [
"cc",
]
[[package]]
name = "luajit-src"
version = "210.1.3+restyfe08842"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36d3de8377d8e0492b646527befb7eb826a9ecd2dc8c1f81ab0e654bc03a029b"
dependencies = [
"cc",
]
[[package]]
name = "maplit"
version = "1.0.2"
@ -547,6 +580,23 @@ dependencies = [
"winapi",
]
[[package]]
name = "mlua"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd448d3e7018f2ff38dd732a374045f5b037eb4ee477d9241d9bb8c209528c1c"
dependencies = [
"bstr",
"cc",
"erased-serde",
"lazy_static",
"lua-src",
"luajit-src",
"num-traits",
"pkg-config",
"serde",
]
[[package]]
name = "natord"
version = "1.0.9"
@ -677,6 +727,12 @@ dependencies = [
"sha-1",
]
[[package]]
name = "pkg-config"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
[[package]]
name = "plotters"
version = "0.3.0"
@ -1193,7 +1249,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "xplr"
version = "0.9.1"
version = "0.10.0-beta.0"
dependencies = [
"anyhow",
"chrono",
@ -1205,6 +1261,7 @@ dependencies = [
"indexmap",
"lazy_static",
"mime_guess",
"mlua",
"natord",
"serde",
"serde_yaml",

@ -1,6 +1,6 @@
[package]
name = "xplr"
version = "0.9.1" # Update config.yml, config.rs
version = "0.10.0-beta.0" # Update config.yml, config.rs
authors = ["Arijit Basu <sayanarijit@gmail.com>"]
edition = "2018"
description = "A hackable, minimal, fast TUI file explorer"
@ -29,6 +29,7 @@ lazy_static = "1.4.0"
indexmap = { version = "1.6.2", features = ["serde"] }
natord = "1.0.9"
humansize = "1.1.0"
mlua = { version = "0.5.4", features = ["luajit", "vendored", "serialize"] }
[dev-dependencies]
criterion = "0.3"

@ -5,6 +5,7 @@ use crate::ui::Layout;
use anyhow::{bail, Result};
use chrono::{DateTime, Local};
use indexmap::set::IndexSet;
use mlua::LuaSerdeExt;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::collections::HashMap;
@ -1416,6 +1417,18 @@ impl History {
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct LuaData {
config: Config,
}
impl LuaData {
pub fn new(config: Config) -> Self {
Self { config }
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct App {
version: String,
@ -1442,14 +1455,16 @@ impl App {
let config_dir = dirs::config_dir()
.unwrap_or_else(|| PathBuf::from("."))
.join("xplr");
let yaml_config_file = config_dir.join("config.yml");
let lua_script_file = config_dir.join("init.lua");
let config_file = config_dir.join("config.yml");
let default_config = Config::default();
let default_config_version = default_config.version().clone();
let config: Config = if config_file.exists() {
// TODO deprecate this ---------------------------------
let config: Config = if yaml_config_file.exists() {
let c: Config =
serde_yaml::from_reader(io::BufReader::new(&fs::File::open(&config_file)?))?;
serde_yaml::from_reader(io::BufReader::new(&fs::File::open(&yaml_config_file)?))?;
c.extended()
} else {
default_config
@ -1461,7 +1476,59 @@ impl App {
You config version is : {}
Required version is : {}
Visit {}",
config_file.to_string_lossy().to_string(),
yaml_config_file.to_string_lossy().to_string(),
config.version(),
default_config_version,
UPGRADE_GUIDE_LINK,
)
};
// -------------------------------------------------------
let config: Config = if lua_script_file.exists() {
let lua = mlua::Lua::new();
let globals = lua.globals();
let lua_script = fs::read_to_string(&lua_script_file)?;
let luadata = LuaData::new(config);
// TODO: https://github.com/khvzak/mlua/issues/48
if let Err(e) = lua.to_value(&luadata).and_then(|v| globals.set("xplr", v)) {
bail!(e.to_string())
};
if let Err(e) = lua
.load(&lua_script)
.set_name("init")
.and_then(|l| l.exec())
{
bail!(e.to_string())
}
let version: String = match globals.get("version").and_then(|v| lua.from_value(v)) {
Ok(v) => v,
Err(_) => bail!(format!(
"'version' must globally be defined in {}",
&lua_script_file.to_string_lossy().to_string()
)),
};
let luadata: LuaData = match globals.get("xplr").and_then(|v| lua.from_value(v)) {
Ok(d) => d,
Err(e) => bail!(e.to_string()),
};
luadata.config.with_version(version)
} else {
config
};
if !config.is_compatible()? {
bail!(
"incompatible configuration version in {}
You config version is : {}
Required version is : {}
Visit {}",
lua_script_file.to_string_lossy().to_string(),
config.version(),
default_config_version,
UPGRADE_GUIDE_LINK,
@ -1542,7 +1609,7 @@ impl App {
if let Some(notif) = config.upgrade_notification()? {
let notif = format!(
"{}. To stop seeing this log, update your config version from {} to {}.",
"{}. To stop seeing this log, update your config version from {} to {}",
&notif,
config.version(),
app.version()
@ -1553,6 +1620,18 @@ impl App {
));
}
// if yaml_config_file.exists() && !lua_script_file.exists() {
// let notif = format!(
// "`config.yml` will be deprecated in favor of `init.lua`. To stop this warning, create empty file {}",
// lua_script_file.to_string_lossy().to_string()
// );
// app = app.enqueue(Task::new(
// MsgIn::External(ExternalMsg::LogWarning(notif)),
// None,
// ));
// }
app.write_pipes()?;
Ok(app)
}

@ -1259,7 +1259,7 @@ impl Config {
self
}
fn parsed_version(&self) -> Result<(u16, u16, u16)> {
fn parsed_version(&self) -> Result<(u16, u16, u16, Option<u16>)> {
let mut configv = self
.version
.strip_prefix('v')
@ -1268,27 +1268,31 @@ impl Config {
let major = configv.next().unwrap_or_default().parse::<u16>()?;
let minor = configv.next().unwrap_or_default().parse::<u16>()?;
let bugfix = configv.next().unwrap_or_default().parse::<u16>()?;
let bugfix = configv
.next()
.and_then(|s| s.split('-').next())
.unwrap_or_default()
.parse::<u16>()?;
let beta = configv.next().unwrap_or_default().parse::<u16>().ok();
Ok((major, minor, bugfix))
Ok((major, minor, bugfix, beta))
}
pub fn is_compatible(&self) -> Result<bool> {
let result = match self.parsed_version()? {
(0, 9, 1) => true,
(0, 9, 0) => true,
(_, _, _) => false,
(0, 10, 0, Some(0)) => true,
(_, _, _, _) => false,
};
Ok(result)
}
pub fn upgrade_notification(&self) -> Result<Option<&str>> {
let result = match self.parsed_version()? {
(0, 9, 1) => None,
(0, 9, 0) => Some("App version updated. Improved remap feature"),
(_, _, _) => None,
};
let result = None;
// let result = match self.parsed_version()? {
// (_, _, _, _) => None,
// };
Ok(result)
}
@ -1317,6 +1321,12 @@ impl Config {
pub fn modes(&self) -> &ModesConfig {
&self.modes
}
/// Set the config's version.
pub fn with_version(mut self, version: String) -> Self {
self.version = version;
self
}
}
#[cfg(test)]

@ -1,4 +1,4 @@
version: v0.9.1
version: v0.10.0-beta.0
layouts:
custom: {}
builtin:

Loading…
Cancel
Save