manen

Fancy Lua REPL
Log | Files | Refs | README | LICENSE

main.rs (2911B)


      1 use std::{
      2     fs,
      3     io::{Read, stdin},
      4     path::{Path, PathBuf},
      5     process,
      6 };
      7 
      8 use clap::{Parser, Subcommand};
      9 use editor::Editor;
     10 use emmylua_parser::{LuaParser, ParserConfig};
     11 use mlua::prelude::*;
     12 use reedline::Highlighter;
     13 
     14 use inspect::{comfy_table, inspect};
     15 use parse::LuaHighlighter;
     16 
     17 mod completion;
     18 mod config;
     19 mod editor;
     20 mod hinter;
     21 mod inspect;
     22 mod lua;
     23 mod parse;
     24 mod validator;
     25 
     26 #[derive(Parser)]
     27 #[command(version, about, long_about = None)]
     28 #[command(propagate_version = true)]
     29 struct Cli {
     30     #[command(subcommand)]
     31     command: Option<Command>,
     32 }
     33 
     34 #[derive(Subcommand)]
     35 enum Command {
     36     /// Enter an interactive REPL session
     37     Repl,
     38     /// Run a Lua file
     39     Run {
     40         /// Path to Lua file
     41         path: PathBuf,
     42     },
     43     /// Highlight a Lua file
     44     Highlight {
     45         /// Path to Lua file (default: stdin)
     46         path: Option<PathBuf>,
     47     },
     48     /// DEBUG: Parse a Lua file with emmylua_parser
     49     Parse { path: PathBuf },
     50 }
     51 
     52 fn eval_lua(file: String, path: &Path) -> LuaResult<()> {
     53     let lua = Lua::new();
     54     let globals = lua.globals();
     55 
     56     globals.raw_set(
     57         "inspect",
     58         lua.create_function(|_, (value, colorize): (LuaValue, Option<bool>)| {
     59             println!("{}", inspect(&value, colorize.unwrap_or(true))?);
     60             Ok(())
     61         })?,
     62     )?;
     63 
     64     globals.raw_set(
     65         "comfytable",
     66         lua.create_function(|_, (table, recursive): (LuaTable, Option<bool>)| {
     67             println!("{}", comfy_table(&table, recursive.unwrap_or(true))?);
     68 
     69             Ok(())
     70         })?,
     71     )?;
     72 
     73     let res = lua
     74         .load(file)
     75         .set_name(format!("@{}", path.to_string_lossy()))
     76         .eval::<LuaMultiValue>();
     77 
     78     match res {
     79         Err(e) => {
     80             eprintln!("{e}");
     81             process::exit(1);
     82         }
     83         Ok(values) => {
     84             for value in values {
     85                 println!("{}", inspect(&value, true)?);
     86             }
     87 
     88             Ok(())
     89         }
     90     }
     91 }
     92 
     93 fn main() -> color_eyre::Result<()> {
     94     color_eyre::install()?;
     95 
     96     let cli = Cli::parse();
     97 
     98     match &cli.command {
     99         None | Some(Command::Repl) => Editor::new()?.run(),
    100         Some(Command::Run { path }) => {
    101             eval_lua(fs::read_to_string(path)?, path)?;
    102         }
    103         Some(Command::Highlight { path }) => {
    104             let file = if let Some(path) = path {
    105                 fs::read_to_string(path)?
    106             } else {
    107                 let mut buffer = String::new();
    108                 stdin().read_to_string(&mut buffer)?;
    109 
    110                 buffer
    111             };
    112 
    113             let text = LuaHighlighter.highlight(&file, 0);
    114 
    115             println!("{}", text.render_simple());
    116         }
    117         Some(Command::Parse { path }) => {
    118             let code = fs::read_to_string(path)?;
    119 
    120             let tree = LuaParser::parse(&code, ParserConfig::default());
    121 
    122             parse::debug_tree(&tree);
    123         }
    124     }
    125 
    126     Ok(())
    127 }