Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: expose file creation API #2069

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 77 additions & 2 deletions yazi-plugin/src/fs/fs.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
use globset::GlobBuilder;
use mlua::{ExternalError, ExternalResult, Function, IntoLua, IntoLuaMulti, Lua, MetaMethod, Table, Value};
use mlua::{
ExternalError, ExternalResult, Function, IntoLua, IntoLuaMulti, Lua, MetaMethod, Table, Value,
};
use tokio::fs;
use yazi_fs::remove_dir_clean;

use crate::{Error, bindings::{Cast, Cha}, file::File, url::{Url, UrlRef}};
use crate::{
Error,
bindings::{Cast, Cha},
file::File,
url::{Url, UrlRef},
};

const READ: u8 = 1;
const WRITE: u8 = 2;
const APPEND: u8 = 4;
const TRUNCATE: u8 = 8;
const CREATE: u8 = 16;
const CREATE_NEW: u8 = 32;

pub fn compose(lua: &Lua) -> mlua::Result<Table> {
let index = lua.create_function(|lua, (ts, key): (Table, mlua::String)| {
let value = match key.as_bytes().as_ref() {
b"cwd" => cwd(lua)?,
b"cha" => cha(lua)?,
b"open" => open(lua)?,
b"write" => write(lua)?,
b"remove" => remove(lua)?,
b"read_dir" => read_dir(lua)?,
Expand All @@ -22,6 +37,17 @@ pub fn compose(lua: &Lua) -> mlua::Result<Table> {
Ok(value)
})?;

let open_options = lua.create_table_from([
("READ", READ),
("WRITE", WRITE),
("APPEND", APPEND),
("TRUNCATE", TRUNCATE),
("CREATE", CREATE),
("CREATE_NEW", CREATE_NEW),
])?;

lua.globals().raw_set("OpenOpts", open_options)?;

let fs = lua.create_table_with_capacity(0, 10)?;
fs.set_metatable(Some(lua.create_table_from([(MetaMethod::Index.name(), index)])?));

Expand Down Expand Up @@ -50,6 +76,55 @@ fn cha(lua: &Lua) -> mlua::Result<Function> {
})
}

fn open(lua: &Lua) -> mlua::Result<Function> {
lua.create_async_function(|lua, (url, opts): (UrlRef, Option<mlua::Integer>)| async move {
let given_options = opts.unwrap_or(READ as i64);
let given_options = given_options as u8;
let mut write_flag = false;
let mut requires_write = false;
let mut open_opts = fs::OpenOptions::new();

if given_options & READ != 0 {
open_opts.read(true);
}
if given_options & WRITE != 0 {
write_flag = true;
open_opts.write(true);
}
if given_options & APPEND != 0 {
open_opts.append(true);
}
if given_options & TRUNCATE != 0 {
requires_write = true;
open_opts.truncate(true);
}
if given_options & CREATE != 0 {
requires_write = true;
open_opts.create(true);
}
if given_options & CREATE_NEW != 0 {
requires_write = true;
open_opts.create_new(true);
}

if requires_write && !write_flag {
open_opts.write(true);
}

let result = open_opts.open(&*url).await;
let yazi_file = yazi_fs::File::from(url.clone()).await;

match (result, yazi_file) {
(Ok(_), Ok(f)) => match File::cast(&lua, f) {
Ok(file) => (file, Value::Nil).into_lua_multi(&lua),
Err(e) => (Value::Nil, e).into_lua_multi(&lua)
}
(Err(e), _) => (Value::Nil, Error::Io(e)).into_lua_multi(&lua),
(_, Err(e)) => (Value::Nil, e).into_lua_multi(&lua)
}
})
}

fn write(lua: &Lua) -> mlua::Result<Function> {
lua.create_async_function(|lua, (url, data): (UrlRef, mlua::String)| async move {
match fs::write(&*url, data.as_bytes()).await {
Expand Down
Loading