summaryrefslogtreecommitdiff
path: root/src/bin/jv.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-01-10 06:10:59 +0800
committer魏曹先生 <1992414357@qq.com>2026-01-10 06:10:59 +0800
commit412f9a2caa9248d97ade098b7bb160f84b1ebce9 (patch)
treeb348af45c20c735a8a1ebd24022f1fc938355c90 /src/bin/jv.rs
parentb97a5ac6300e23bd15172e52e7ad0a9f06dc2530 (diff)
Add editor mode for share command with --work flag
Diffstat (limited to 'src/bin/jv.rs')
-rw-r--r--src/bin/jv.rs129
1 files changed, 124 insertions, 5 deletions
diff --git a/src/bin/jv.rs b/src/bin/jv.rs
index 0f42318..7efa70f 100644
--- a/src/bin/jv.rs
+++ b/src/bin/jv.rs
@@ -739,6 +739,10 @@ struct ShareMappingArgs {
/// Show json output pretty
#[arg(long = "pretty")]
pretty: bool,
+
+ /// Share - Editor mode
+ #[arg(short, long)]
+ work: bool,
}
#[derive(Parser, Debug)]
@@ -4750,7 +4754,6 @@ async fn proc_mapping_edit(
}
async fn jv_share(args: ShareMappingArgs) {
- // Import share mode
if let (Some(args1), None, None) = (&args.args1, &args.args2, &args.args3) {
// List mode
if args1.trim() == "list" || args1.trim() == "ls" {
@@ -4762,8 +4765,19 @@ async fn jv_share(args: ShareMappingArgs) {
return;
}
- // Pull mode
if let (Some(args1), Some(args2), None) = (&args.args1, &args.args2, &args.args3) {
+ // 如果是 work 模式,那么就是分享
+ if args.work {
+ share_out(
+ args1.to_string(),
+ args2.to_string(),
+ String::default(),
+ args,
+ )
+ .await;
+ return;
+ }
+
// See mode
if args1.trim() == "see" {
share_see(args2.to_string(), args).await;
@@ -4774,7 +4788,6 @@ async fn jv_share(args: ShareMappingArgs) {
return;
}
- // Share mode
if let (Some(share_pattern), Some(to_sheet), Some(description)) =
(&args.args1, &args.args2, &args.args3)
{
@@ -5080,9 +5093,9 @@ async fn share_out(
share_pattern: String,
to_sheet: String,
description: String,
- _args: ShareMappingArgs,
+ args: ShareMappingArgs,
) {
- let shared_files = {
+ let mut shared_files = {
let local_dir = match current_local_path() {
Some(dir) => dir,
None => {
@@ -5109,6 +5122,11 @@ async fn share_out(
None => return,
};
+ let Some(local_workspace) = LocalWorkspace::init_current_dir(local_config.clone()) else {
+ eprintln!("{}", md(t!("jv.fail.workspace_not_found")).trim());
+ return;
+ };
+
let Ok(latest_info) = LatestInfo::read_from(LatestInfo::latest_info_path(
&local_dir,
&local_config.current_account(),
@@ -5162,6 +5180,15 @@ async fn share_out(
}
};
+ let Some(description) = (if args.work {
+ start_share_editor(&local_workspace, &mut shared_files, &to_sheet_holder).await
+ } else {
+ Some(description.to_string())
+ }) else {
+ eprintln!("{}", md(t!("jv.fail.share.no_description")));
+ return;
+ };
+
match proc_share_mapping_action(
&pool,
ctx,
@@ -5222,6 +5249,98 @@ async fn share_out(
}
}
+async fn start_share_editor(
+ workspace: &LocalWorkspace,
+ shared_files: &mut Vec<PathBuf>,
+ holder: &MemberId,
+) -> Option<String> {
+ let config = workspace.config().lock().await.clone();
+
+ let sheet_name = config.sheet_in_use().clone();
+ let Some(sheet_name) = sheet_name else {
+ eprintln!("{}", md(t!("jv.fail.status.no_sheet_in_use")).trim());
+ return None;
+ };
+
+ let account = config.current_account();
+ let Ok(local_sheet) = workspace.local_sheet(&account, &sheet_name).await else {
+ eprintln!(
+ "{}",
+ md(t!(
+ "jv.fail.cfg_not_found.local_sheet",
+ account = &account,
+ sheet = &sheet_name
+ ))
+ );
+ return None;
+ };
+
+ // Generate shared files and automatically comment out lost mappings
+ let shared_files_str: String = shared_files
+ .iter()
+ .map(|p| {
+ if local_sheet.mapping_data(p).is_err() {
+ format!("# {}", p.display().to_string())
+ } else {
+ p.display().to_string()
+ }
+ })
+ .collect::<Vec<String>>()
+ .join("\n");
+ let shared_files_str = shared_files_str.trim();
+
+ let editor_content = t!(
+ "editor.share_editor",
+ sheet = sheet_name,
+ holder = holder,
+ shared_files = shared_files_str
+ );
+
+ let path = workspace
+ .local_path()
+ .join(CLIENT_PATH_WORKSPACE_ROOT)
+ .join(".SHARE.md");
+
+ let result = input_with_editor(format!("{}\n", editor_content), path, "#")
+ .await
+ .unwrap_or_default();
+
+ // Find the last separator line (a line that, when trimmed, consists of at least 3 '-' characters)
+ let lines: Vec<&str> = result.lines().collect();
+ let mut last_separator_index = None;
+
+ for (i, line) in lines.iter().enumerate() {
+ let trimmed = line.trim();
+ if trimmed.chars().all(|c| c == '-') && trimmed.len() >= 3 {
+ last_separator_index = Some(i);
+ }
+ }
+
+ // Extract content after the last separator
+ let description = if let Some(sep_idx) = last_separator_index {
+ lines[sep_idx + 1..].join("\n").trim().to_string()
+ } else {
+ result.trim().to_string()
+ };
+
+ // Update shared_files with the first segment (before the first separator)
+ if let Some(sep_idx) = last_separator_index {
+ let first_segment: Vec<PathBuf> = lines[..sep_idx]
+ .iter()
+ .map(|line| line.trim())
+ .filter(|line| !line.is_empty())
+ .map(PathBuf::from)
+ .collect();
+ *shared_files = first_segment;
+ }
+
+ if description.trim().is_empty() {
+ None
+ } else {
+ Some(description)
+ }
+}
+
async fn jv_account_add(user_dir: UserDirectory, args: AccountAddArgs) {
let member = Member::new(args.account_name.clone());