├── Cargo.toml ├── lua-syntect-dev-1.rockspec └── src └── lib.rs /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lua-syntect" 3 | version = "0.1.0" 4 | authors = ["Hisham Muhammad "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | syntect = "3.2" 11 | libc = "*" 12 | 13 | [lib] 14 | name = "syntect" 15 | crate-type = ["dylib"] 16 | -------------------------------------------------------------------------------- /lua-syntect-dev-1.rockspec: -------------------------------------------------------------------------------- 1 | rockspec_format = "3.0" 2 | package = "lua-syntect" 3 | version = "dev-1" 4 | source = { 5 | url = "git://github.com/hishamhm/lua-syntect" 6 | } 7 | description = { 8 | summary = "Minimal Lua binding for syntect, a syntax highlighting library", 9 | detailed = [[ 10 | This is a minimal Lua binding for syntect, a syntax highlighting library 11 | written in Rust. 12 | ]], 13 | homepage = "https://github.com/hishamhm/lua-syntect", 14 | license = "MIT" 15 | } 16 | build_dependencies = { 17 | "luarocks-build-rust", 18 | } 19 | build = { 20 | type = "rust", 21 | modules = { 22 | "syntect" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate libc; 2 | 3 | use libc::c_int; 4 | use libc::size_t; 5 | use std::ffi::CStr; 6 | use std::ffi::CString; 7 | use std::os::raw::c_char; 8 | 9 | use syntect::parsing::SyntaxSet; 10 | use syntect::highlighting::{ThemeSet, Style}; 11 | use syntect::easy::HighlightFile; 12 | use std::io::BufRead; 13 | 14 | #[repr(C)] pub struct lua_State { _private: [u8; 0] } 15 | 16 | extern "C" { 17 | pub fn lua_createtable(L: *mut lua_State, narr: c_int, nrec: c_int); 18 | pub fn lua_pushnil(L: *mut lua_State); 19 | pub fn lua_pushstring(L: *mut lua_State, str: *const c_char); 20 | pub fn lua_pushcclosure(L: *mut lua_State, f: extern "C" fn(*mut lua_State) -> c_int, nup: c_int); 21 | pub fn lua_settable(L: *mut lua_State, idx: c_int); 22 | pub fn lua_pushinteger(L: *mut lua_State, idx: c_int); 23 | pub fn lua_rawseti(L: *mut lua_State, tbl: c_int, i: c_int); 24 | pub fn luaL_checklstring(L: *mut lua_State, idx: c_int, len: *const size_t) -> *const c_char; 25 | } 26 | 27 | fn checkstring(l: *mut lua_State, idx: i32) -> String { 28 | unsafe { 29 | CStr::from_ptr(luaL_checklstring(l, idx, std::ptr::null())).to_string_lossy().into_owned() 30 | } 31 | } 32 | 33 | pub extern "C" fn l_highlight_file(l: *mut lua_State) -> c_int { 34 | let ss = SyntaxSet::load_defaults_newlines(); 35 | let ts = ThemeSet::load_defaults(); 36 | 37 | let theme = &ts.themes["base16-ocean.dark"]; 38 | 39 | let filename = checkstring(l, 1); 40 | 41 | let mut i = 1; 42 | unsafe { 43 | lua_createtable(l, 0, 0); 44 | } 45 | 46 | match HighlightFile::new(filename, &ss, theme) { 47 | Ok(mut highlighter) => { 48 | let mut line = String::new(); 49 | while highlighter.reader.read_line(&mut line).unwrap() > 0 { 50 | unsafe { 51 | lua_createtable(l, 0, 0); 52 | } 53 | { 54 | let regions: Vec<(Style, &str)> = highlighter.highlight_lines.highlight(&line, &ss); 55 | let mut j = 1; 56 | for (style, text) in regions { 57 | unsafe { 58 | let fg = style.foreground; 59 | lua_pushinteger(l, (fg.r as i32) << 16 | (fg.g as i32) << 8 | fg.b as i32); 60 | lua_rawseti(l, -2, j); 61 | j += 1; 62 | lua_pushstring(l, CString::new(text).unwrap().as_ptr()); 63 | lua_rawseti(l, -2, j); 64 | j += 1; 65 | } 66 | } 67 | } // until NLL this scope is needed so we can clear the buffer after 68 | line.clear(); // read_line appends so we need to clear between lines 69 | unsafe { 70 | lua_rawseti(l, -2, i); 71 | } 72 | i += 1; 73 | } 74 | return 1; 75 | } 76 | Err(e) => { 77 | unsafe { 78 | lua_pushnil(l); 79 | lua_pushstring(l, CString::new(e.to_string()).unwrap().as_ptr()); 80 | } 81 | return 2; 82 | } 83 | } 84 | } 85 | 86 | #[no_mangle] 87 | pub extern "C" fn luaopen_syntect(l: *mut lua_State) -> c_int { 88 | unsafe { 89 | lua_createtable(l, 0, 0); 90 | lua_pushstring(l, CString::new("highlight_file").unwrap().as_ptr()); 91 | lua_pushcclosure(l, l_highlight_file, 0); 92 | lua_settable(l, -3); 93 | } 94 | return 1; 95 | } 96 | --------------------------------------------------------------------------------