|
| 1 | +use std::collections::{HashMap, HashSet}; |
| 2 | + |
1 | 3 | use globset::GlobBuilder;
|
2 | 4 | use mlua::{ExternalError, ExternalResult, IntoLuaMulti, Lua, Table, Value};
|
3 | 5 | use tokio::fs;
|
4 |
| -use yazi_shared::fs::remove_dir_clean; |
| 6 | +use yazi_shared::fs::{maybe_exists, ok_or_not_found, realname, remove_dir_clean, FilesOp, UrnBuf}; |
5 | 7 |
|
6 |
| -use crate::{bindings::Cast, cha::Cha, file::File, url::{Url, UrlRef}}; |
| 8 | +use crate::{ |
| 9 | + bindings::Cast, |
| 10 | + cha::Cha, |
| 11 | + file::File, |
| 12 | + url::{Url, UrlRef}, |
| 13 | +}; |
7 | 14 |
|
8 | 15 | pub fn install(lua: &Lua) -> mlua::Result<()> {
|
9 | 16 | lua.globals().raw_set(
|
@@ -33,6 +40,50 @@ pub fn install(lua: &Lua) -> mlua::Result<()> {
|
33 | 40 | }
|
34 | 41 | })?,
|
35 | 42 | ),
|
| 43 | + ( |
| 44 | + "create", |
| 45 | + lua.create_async_function( |
| 46 | + |lua, (url, is_dir, overwrite): (UrlRef, Option<bool>, Option<bool>)| async move { |
| 47 | + let Some(parent_dir) = url.parent_url() else { |
| 48 | + let error_msg = format!("{} has no parent directory", url.to_string()); |
| 49 | + return (false, error_msg.into_lua_err()).into_lua_multi(lua); |
| 50 | + }; |
| 51 | + |
| 52 | + if !overwrite.unwrap_or(false) && maybe_exists(&*url).await { |
| 53 | + let error_msg = format!("{} already exists", url.to_string()); |
| 54 | + return (false, error_msg.into_lua_err()).into_lua_multi(lua); |
| 55 | + } |
| 56 | + |
| 57 | + let outcome = if is_dir.unwrap_or(false) { |
| 58 | + fs::create_dir_all(&*url).await |
| 59 | + } else if let Some(real) = realname(&url).await { |
| 60 | + ok_or_not_found(fs::remove_file(&*url).await)?; |
| 61 | + FilesOp::Deleting(parent_dir.clone(), HashSet::from_iter([UrnBuf::from(real)])) |
| 62 | + .emit(); |
| 63 | + match fs::File::create(&*url).await { |
| 64 | + Ok(_) => Ok(()), |
| 65 | + Err(e) => Err(e), |
| 66 | + } |
| 67 | + } else { |
| 68 | + fs::create_dir_all(&parent_dir).await.ok(); |
| 69 | + ok_or_not_found(fs::remove_file(&*url).await)?; |
| 70 | + match fs::File::create(&*url).await { |
| 71 | + Ok(_) => Ok(()), |
| 72 | + Err(e) => Err(e), |
| 73 | + } |
| 74 | + }; |
| 75 | + |
| 76 | + if let Ok(f) = yazi_shared::fs::File::from(url.clone()).await { |
| 77 | + FilesOp::Upserting(parent_dir, HashMap::from_iter([(f.urn_owned(), f)])).emit(); |
| 78 | + }; |
| 79 | + |
| 80 | + match outcome { |
| 81 | + Ok(_) => (true, Value::Nil).into_lua_multi(lua), |
| 82 | + Err(e) => (false, e.raw_os_error()).into_lua_multi(lua), |
| 83 | + } |
| 84 | + }, |
| 85 | + )?, |
| 86 | + ), |
36 | 87 | (
|
37 | 88 | "remove",
|
38 | 89 | lua.create_async_function(|lua, (type_, url): (mlua::String, UrlRef)| async move {
|
|
0 commit comments