1use crate::config::YamlConfig;
2use crate::constants::{section, shell};
3use crate::{error, info};
4use std::fs;
5
6fn wait_for_key_template() -> String {
8 if std::env::consts::OS == shell::WINDOWS_OS {
9 "echo.\necho 脚本执行完毕,按任意键退出...\npause >nul".to_string()
10 } else {
11 "echo ''\necho '\\033[32m✅ 脚本执行完毕,按回车键退出...\\033[0m'\nread _".to_string()
12 }
13}
14
15pub fn handle_concat(name: &str, content: &[String], config: &mut YamlConfig) {
19 if config.contains(section::PATH, name) {
21 let existing_path = match config.get_property(section::SCRIPT, name)
23 .or_else(|| config.get_property(section::PATH, name))
24 {
25 Some(p) => p.clone(),
26 None => {
27 error!("❌ 别名 {{{}}} 已存在,但未找到对应的脚本路径", name);
28 return;
29 }
30 };
31
32 let existing_content = match fs::read_to_string(&existing_path) {
34 Ok(c) => c,
35 Err(e) => {
36 error!("❌ 读取已有脚本文件失败: {} (路径: {})", e, existing_path);
37 return;
38 }
39 };
40
41 let initial_lines: Vec<String> = existing_content.lines().map(|l| l.to_string()).collect();
43 match crate::tui::editor::open_multiline_editor_with_content(
44 &format!("📝 编辑脚本: {}", name),
45 &initial_lines,
46 ) {
47 Ok(Some(new_content)) => {
48 if new_content.trim().is_empty() {
49 error!("⚠️ 脚本内容为空,未保存修改");
50 return;
51 }
52 match fs::write(&existing_path, &new_content) {
54 Ok(_) => info!("✅ 脚本 {{{}}} 已更新,路径: {}", name, existing_path),
55 Err(e) => error!("💥 写入脚本文件失败: {}", e),
56 }
57 }
58 Ok(None) => {
59 info!("已取消编辑脚本");
60 }
61 Err(e) => {
62 error!("❌ 编辑器启动失败: {}", e);
63 }
64 }
65 return;
66 }
67
68 let script_content = if content.is_empty() {
70 let initial_lines = vec![
72 "#!/bin/bash".to_string(),
73 "".to_string(),
74 "# 在此编写脚本内容...".to_string(),
75 "".to_string(),
76 "# --- 以下为等待按键模板(可删除) ---".to_string(),
77 wait_for_key_template(),
78 ];
79
80 match crate::tui::editor::open_multiline_editor_with_content(
81 &format!("📝 编写脚本: {}", name),
82 &initial_lines,
83 ) {
84 Ok(Some(text)) => text,
85 Ok(None) => {
86 info!("已取消创建脚本");
87 return;
88 }
89 Err(e) => {
90 error!("❌ 编辑器启动失败: {}", e);
91 return;
92 }
93 }
94 } else {
95 let text = content.join(" ");
97 text.trim()
98 .trim_start_matches('"')
99 .trim_end_matches('"')
100 .to_string()
101 };
102
103 if script_content.trim().is_empty() {
104 error!("⚠️ 脚本内容为空,无法创建");
105 return;
106 }
107
108 let scripts_dir = YamlConfig::scripts_dir();
110
111 let ext = if std::env::consts::OS == shell::WINDOWS_OS {
113 ".cmd"
114 } else {
115 ".sh"
116 };
117 let script_path = scripts_dir.join(format!("{}{}", name, ext));
118 let script_path_str = script_path.to_string_lossy().to_string();
119
120 if let Some(parent) = script_path.parent() {
122 if let Err(e) = fs::create_dir_all(parent) {
123 error!("❌ 创建目录失败: {}", e);
124 return;
125 }
126 }
127
128 match fs::write(&script_path, &script_content) {
130 Ok(_) => {
131 info!("🎉 文件创建成功: {}", script_path_str);
132 }
133 Err(e) => {
134 error!("💥 写入脚本文件失败: {}", e);
135 return;
136 }
137 }
138
139 #[cfg(unix)]
141 {
142 use std::os::unix::fs::PermissionsExt;
143 if let Ok(metadata) = fs::metadata(&script_path) {
144 let mut perms = metadata.permissions();
145 perms.set_mode(perms.mode() | 0o111); if let Err(e) = fs::set_permissions(&script_path, perms) {
147 error!("❌ 设置执行权限失败: {}", e);
148 } else {
149 info!("🔧 已为脚本 {{{}}} 设置执行权限", name);
150 }
151 }
152 }
153
154 config.set_property(section::PATH, name, &script_path_str);
156 config.set_property(section::SCRIPT, name, &script_path_str);
157
158 info!(
159 "✅ 成功创建脚本 {{{}}},路径: {}",
160 name, script_path_str
161 );
162}