mirror of
https://github.com/sharkdp/bat.git
synced 2025-02-07 13:41:14 +00:00
Initial prototype for Lua plugins
This commit is contained in:
parent
3339eee2dc
commit
3811615606
25
Cargo.lock
generated
25
Cargo.lock
generated
@ -98,6 +98,7 @@ dependencies = [
|
|||||||
"path_abs",
|
"path_abs",
|
||||||
"predicates",
|
"predicates",
|
||||||
"regex",
|
"regex",
|
||||||
|
"rlua",
|
||||||
"semver",
|
"semver",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
@ -916,6 +917,30 @@ dependencies = [
|
|||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rlua"
|
||||||
|
version = "0.19.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "627ae78424400009e889c43b0c188d0b7af3fe7301b68c03d9cfacb29115408a"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"bstr",
|
||||||
|
"libc",
|
||||||
|
"num-traits",
|
||||||
|
"rlua-lua54-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rlua-lua54-sys"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b4e1fdfc6a5f7acfa1b1fe26c5076b54f5ebd6818b5982460c39844c8b859370"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.6"
|
version = "1.0.6"
|
||||||
|
@ -30,6 +30,7 @@ minimal-application = [
|
|||||||
"paging",
|
"paging",
|
||||||
"regex-onig",
|
"regex-onig",
|
||||||
"wild",
|
"wild",
|
||||||
|
"rlua"
|
||||||
]
|
]
|
||||||
git = ["git2"] # Support indicating git modifications
|
git = ["git2"] # Support indicating git modifications
|
||||||
paging = ["shell-words", "grep-cli"] # Support applying a pager on the output
|
paging = ["shell-words", "grep-cli"] # Support applying a pager on the output
|
||||||
@ -65,6 +66,7 @@ grep-cli = { version = "0.1.6", optional = true }
|
|||||||
regex = { version = "1.5.5", optional = true }
|
regex = { version = "1.5.5", optional = true }
|
||||||
walkdir = { version = "2.0", optional = true }
|
walkdir = { version = "2.0", optional = true }
|
||||||
bytesize = { version = "1.1.0" }
|
bytesize = { version = "1.1.0" }
|
||||||
|
rlua = { version = "0.19", optional = true }
|
||||||
|
|
||||||
[dependencies.git2]
|
[dependencies.git2]
|
||||||
version = "0.14"
|
version = "0.14"
|
||||||
|
21
plugins/uncompress.lua
Normal file
21
plugins/uncompress.lua
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
function tempdir()
|
||||||
|
local stream = assert(io.popen('mktemp --directory'))
|
||||||
|
local output = stream:read('*all')
|
||||||
|
stream:close()
|
||||||
|
return string.gsub(output, "\n", "")
|
||||||
|
end
|
||||||
|
|
||||||
|
function preprocess(path)
|
||||||
|
prefix = string.match(path, '^(.*)%.gz$')
|
||||||
|
if prefix then
|
||||||
|
local temp_directory = tempdir()
|
||||||
|
local new_path = temp_directory .. "/" .. prefix
|
||||||
|
|
||||||
|
-- TODO: how to prevent shell injection bugs?
|
||||||
|
os.execute("gunzip < '" .. path .. "' > '" .. new_path .. "'")
|
||||||
|
|
||||||
|
return new_path
|
||||||
|
else
|
||||||
|
return path
|
||||||
|
end
|
||||||
|
end
|
@ -241,6 +241,11 @@ impl App {
|
|||||||
.map(HighlightedLineRanges)
|
.map(HighlightedLineRanges)
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
use_custom_assets: !self.matches.is_present("no-custom-assets"),
|
use_custom_assets: !self.matches.is_present("no-custom-assets"),
|
||||||
|
plugins: self
|
||||||
|
.matches
|
||||||
|
.values_of_os("load-plugin")
|
||||||
|
.unwrap_or_default()
|
||||||
|
.collect(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,6 +474,14 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
|
|||||||
.help("Display all supported languages.")
|
.help("Display all supported languages.")
|
||||||
.long_help("Display a list of supported languages for syntax highlighting."),
|
.long_help("Display a list of supported languages for syntax highlighting."),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("load-plugin")
|
||||||
|
.long("load-plugin")
|
||||||
|
.takes_value(true)
|
||||||
|
.value_name("name")
|
||||||
|
.help("Load plugin with specified name.")
|
||||||
|
.hidden_short_help(true)
|
||||||
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("unbuffered")
|
Arg::with_name("unbuffered")
|
||||||
.short("u")
|
.short("u")
|
||||||
|
@ -8,6 +8,7 @@ mod directories;
|
|||||||
mod input;
|
mod input;
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
use std::ffi::OsStr;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::{BufReader, Write};
|
use std::io::{BufReader, Write};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
@ -218,7 +219,51 @@ pub fn list_themes(cfg: &Config) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_controller(inputs: Vec<Input>, config: &Config) -> Result<bool> {
|
fn load_and_run_preprocess_plugins(plugins: &[&OsStr], inputs: &mut Vec<Input>) -> Result<()> {
|
||||||
|
use bat::input::InputKind;
|
||||||
|
use rlua::{Function, Lua, Result as LuaResult};
|
||||||
|
use std::fs;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
let lua = Lua::new();
|
||||||
|
|
||||||
|
for plugin_name in plugins {
|
||||||
|
// TODO: how to handle plugin priority?
|
||||||
|
let mut plugin_path = PathBuf::from("plugins");
|
||||||
|
plugin_path.push(plugin_name);
|
||||||
|
|
||||||
|
let plugin_source_code = fs::read_to_string(&plugin_path).unwrap(); // TODO: proper error handling
|
||||||
|
|
||||||
|
lua.context::<_, LuaResult<()>>(|lua_ctx| {
|
||||||
|
let globals = lua_ctx.globals();
|
||||||
|
|
||||||
|
lua_ctx.load(&plugin_source_code).exec()?;
|
||||||
|
|
||||||
|
let preprocess: Function = globals.get("preprocess")?;
|
||||||
|
|
||||||
|
for input in inputs.iter_mut() {
|
||||||
|
if let InputKind::OrdinaryFile(ref mut path) = &mut input.kind {
|
||||||
|
let path_str: String = path.to_string_lossy().into();
|
||||||
|
let new_path = preprocess.call::<_, String>(path_str)?;
|
||||||
|
|
||||||
|
*path = PathBuf::from(new_path);
|
||||||
|
|
||||||
|
input.metadata.user_provided_name =
|
||||||
|
Some(PathBuf::from(path.file_name().unwrap())); // TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.map_err(|e| format!("Error while executing Lua code: {}", e))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_controller(mut inputs: Vec<Input>, config: &Config) -> Result<bool> {
|
||||||
|
load_and_run_preprocess_plugins(&config.plugins, &mut inputs)?;
|
||||||
|
|
||||||
let assets = assets_from_cache_or_binary(config.use_custom_assets)?;
|
let assets = assets_from_cache_or_binary(config.use_custom_assets)?;
|
||||||
let controller = Controller::new(config, &assets);
|
let controller = Controller::new(config, &assets);
|
||||||
controller.run(inputs)
|
controller.run(inputs)
|
||||||
|
@ -5,6 +5,8 @@ use crate::style::StyleComponents;
|
|||||||
use crate::syntax_mapping::SyntaxMapping;
|
use crate::syntax_mapping::SyntaxMapping;
|
||||||
use crate::wrapping::WrappingMode;
|
use crate::wrapping::WrappingMode;
|
||||||
|
|
||||||
|
use std::ffi::OsStr;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum VisibleLines {
|
pub enum VisibleLines {
|
||||||
/// Show all lines which are included in the line ranges
|
/// Show all lines which are included in the line ranges
|
||||||
@ -86,6 +88,9 @@ pub struct Config<'a> {
|
|||||||
/// Whether or not to allow custom assets. If this is false or if custom assets (a.k.a.
|
/// Whether or not to allow custom assets. If this is false or if custom assets (a.k.a.
|
||||||
/// cached assets) are not available, assets from the binary will be used instead.
|
/// cached assets) are not available, assets from the binary will be used instead.
|
||||||
pub use_custom_assets: bool,
|
pub use_custom_assets: bool,
|
||||||
|
|
||||||
|
/// List of bat plugins to be loaded
|
||||||
|
pub plugins: Vec<&'a OsStr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "minimal-application", feature = "paging"))]
|
#[cfg(all(feature = "minimal-application", feature = "paging"))]
|
||||||
|
12
src/input.rs
12
src/input.rs
@ -69,7 +69,8 @@ impl InputDescription {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) enum InputKind<'a> {
|
pub enum InputKind<'a> {
|
||||||
|
// TODO
|
||||||
OrdinaryFile(PathBuf),
|
OrdinaryFile(PathBuf),
|
||||||
StdIn,
|
StdIn,
|
||||||
CustomReader(Box<dyn Read + 'a>),
|
CustomReader(Box<dyn Read + 'a>),
|
||||||
@ -86,14 +87,15 @@ impl<'a> InputKind<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub(crate) struct InputMetadata {
|
pub struct InputMetadata {
|
||||||
pub(crate) user_provided_name: Option<PathBuf>,
|
// TODO
|
||||||
|
pub user_provided_name: Option<PathBuf>,
|
||||||
pub(crate) size: Option<u64>,
|
pub(crate) size: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Input<'a> {
|
pub struct Input<'a> {
|
||||||
pub(crate) kind: InputKind<'a>,
|
pub kind: InputKind<'a>, // TODO
|
||||||
pub(crate) metadata: InputMetadata,
|
pub metadata: InputMetadata, // TODO
|
||||||
pub(crate) description: InputDescription,
|
pub(crate) description: InputDescription,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user