From 2b05ff3a4651ab7f4fe0a6048b992a6b4abc7f52 Mon Sep 17 00:00:00 2001 From: Koi to Coco Date: Tue, 20 May 2025 23:41:42 +0800 Subject: [PATCH 1/3] feat: Allow bulk opening multiple files #142 --- src/bin/edit/main.rs | 69 +++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/src/bin/edit/main.rs b/src/bin/edit/main.rs index 2c840045ebd..6605f7233ab 100644 --- a/src/bin/edit/main.rs +++ b/src/bin/edit/main.rs @@ -12,9 +12,10 @@ mod localization; mod state; use std::borrow::Cow; +use std::ffi::OsString; #[cfg(feature = "debug-latency")] use std::fmt::Write; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::{env, process}; use draw_editor::*; @@ -234,37 +235,53 @@ fn run() -> apperr::Result<()> { // Returns true if the application should exit early. fn handle_args(state: &mut State) -> apperr::Result { let mut cwd = env::current_dir()?; - let mut path = None; // The best CLI argument parser in the world. - if let Some(arg) = env::args_os().nth(1) { - if arg == "-h" || arg == "--help" || (cfg!(windows) && arg == "/?") { - print_help(); - return Ok(true); - } else if arg == "-v" || arg == "--version" { - print_version(); - return Ok(true); - } else if arg == "-" { - // We'll check for a redirected stdin no matter what, so we can just ignore "-". - } else { - let p = cwd.join(Path::new(&arg)); + let args = env::args_os().collect::>(); + if args.iter().any(|arg| arg == "-h" || arg == "--help" || (cfg!(windows) && arg == "/?")) { + print_help(); + return Ok(true); + } else if args.iter().any(|arg| arg == "-v" || arg == "--version") { + print_version(); + return Ok(true); + } + + let paths = args + .iter() + .skip(1) + .filter_map(|arg| { + if arg == "-" { + // We ignore it + return None; + } + let p = cwd.join(Path::new(arg)); let p = path::normalize(&p); - if let Some(parent) = p.parent() { - cwd = parent.to_path_buf(); + if p.is_dir() { + return None; } - path = Some(p); - } - } + Some(p) + }) + .collect::>(); - if let Some(mut file) = sys::open_stdin_if_redirected() { - let doc = state.documents.add_untitled()?; - let mut tb = doc.buffer.borrow_mut(); - tb.read_file(&mut file, None)?; - tb.mark_as_dirty(); - } else if let Some(path) = path { - state.documents.add_file_path(&path)?; + if paths.len() > 1 { + for p in paths { + state.documents.add_file_path(&p)?; + } + } else if paths.len() == 1 { + let p = paths[0].clone(); + if let Some(parent) = p.parent() { + cwd = parent.to_path_buf(); + } + state.documents.add_file_path(&p)?; } else { - state.documents.add_untitled()?; + if let Some(mut file) = sys::open_stdin_if_redirected() { + let doc = state.documents.add_untitled()?; + let mut tb = doc.buffer.borrow_mut(); + tb.read_file(&mut file, None)?; + tb.mark_as_dirty(); + } else { + state.documents.add_untitled()?; + } } state.file_picker_pending_dir = DisplayablePathBuf::new(cwd); From 78f8cd4128eff566d437aab7a1306bab46e93303 Mon Sep 17 00:00:00 2001 From: Koi to Coco Date: Fri, 23 May 2025 14:27:48 +0800 Subject: [PATCH 2/3] refactor: improve argument handling --- src/bin/edit/main.rs | 80 ++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/src/bin/edit/main.rs b/src/bin/edit/main.rs index 6605f7233ab..6f46026a5a7 100644 --- a/src/bin/edit/main.rs +++ b/src/bin/edit/main.rs @@ -1,7 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -#![feature(let_chains, linked_list_cursors, os_string_truncate, string_from_utf8_lossy_owned)] +#![feature( + allocator_api, + let_chains, + linked_list_cursors, + os_string_truncate, + string_from_utf8_lossy_owned +)] mod documents; mod draw_editor; @@ -12,7 +18,6 @@ mod localization; mod state; use std::borrow::Cow; -use std::ffi::OsString; #[cfg(feature = "debug-latency")] use std::fmt::Write; use std::path::{Path, PathBuf}; @@ -22,7 +27,7 @@ use draw_editor::*; use draw_filepicker::*; use draw_menubar::*; use draw_statusbar::*; -use edit::arena::{self, ArenaString, scratch_arena}; +use edit::arena::{self, Arena, ArenaString, scratch_arena}; use edit::framebuffer::{self, IndexedColor}; use edit::helpers::{KIBI, MEBI, MetricFormatter, Rect, Size}; use edit::input::{self, kbmod, vk}; @@ -234,54 +239,49 @@ fn run() -> apperr::Result<()> { // Returns true if the application should exit early. fn handle_args(state: &mut State) -> apperr::Result { + let scratch = scratch_arena(None); + let mut paths: Vec = Vec::new_in(&*scratch); let mut cwd = env::current_dir()?; // The best CLI argument parser in the world. - let args = env::args_os().collect::>(); - if args.iter().any(|arg| arg == "-h" || arg == "--help" || (cfg!(windows) && arg == "/?")) { - print_help(); - return Ok(true); - } else if args.iter().any(|arg| arg == "-v" || arg == "--version") { - print_version(); - return Ok(true); + for arg in env::args_os().skip(1) { + if arg == "-h" || arg == "--help" || (cfg!(windows) && arg == "/?") { + print_help(); + return Ok(true); + } else if arg == "-v" || arg == "--version" { + print_version(); + return Ok(true); + } else if arg == "-" { + paths.clear(); + break; + } + let p = cwd.join(Path::new(&arg)); + let p = path::normalize(&p); + if !p.is_dir() { + paths.push(p); + } } - let paths = args - .iter() - .skip(1) - .filter_map(|arg| { - if arg == "-" { - // We ignore it - return None; - } - let p = cwd.join(Path::new(arg)); - let p = path::normalize(&p); - if p.is_dir() { - return None; - } - Some(p) - }) - .collect::>(); - if paths.len() > 1 { - for p in paths { - state.documents.add_file_path(&p)?; + for p in &paths { + state.documents.add_file_path(p)?; } } else if paths.len() == 1 { - let p = paths[0].clone(); + let p = &paths[0]; if let Some(parent) = p.parent() { cwd = parent.to_path_buf(); } - state.documents.add_file_path(&p)?; - } else { - if let Some(mut file) = sys::open_stdin_if_redirected() { - let doc = state.documents.add_untitled()?; - let mut tb = doc.buffer.borrow_mut(); - tb.read_file(&mut file, None)?; - tb.mark_as_dirty(); - } else { - state.documents.add_untitled()?; - } + state.documents.add_file_path(p)?; + } + + if let Some(mut file) = sys::open_stdin_if_redirected() { + let doc = state.documents.add_untitled()?; + let mut tb = doc.buffer.borrow_mut(); + tb.read_file(&mut file, None)?; + tb.mark_as_dirty(); + } else if paths.len() == 0 { + // No files were passed, and stdin is not redirected. + state.documents.add_untitled()?; } state.file_picker_pending_dir = DisplayablePathBuf::new(cwd); From fa71f6b7c4a6664ec3344bd28ca1016388d249ad Mon Sep 17 00:00:00 2001 From: Koi to Coco Date: Sat, 24 May 2025 12:01:41 +0800 Subject: [PATCH 3/3] refactor: some minor changes --- src/bin/edit/main.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/bin/edit/main.rs b/src/bin/edit/main.rs index 6f46026a5a7..bac25e04ad9 100644 --- a/src/bin/edit/main.rs +++ b/src/bin/edit/main.rs @@ -262,24 +262,19 @@ fn handle_args(state: &mut State) -> apperr::Result { } } - if paths.len() > 1 { - for p in &paths { - state.documents.add_file_path(p)?; - } - } else if paths.len() == 1 { - let p = &paths[0]; - if let Some(parent) = p.parent() { - cwd = parent.to_path_buf(); - } + for p in &paths { state.documents.add_file_path(p)?; } + if let Some(parent) = paths.first().and_then(|p| p.parent()) { + cwd = parent.to_path_buf(); + } if let Some(mut file) = sys::open_stdin_if_redirected() { let doc = state.documents.add_untitled()?; let mut tb = doc.buffer.borrow_mut(); tb.read_file(&mut file, None)?; tb.mark_as_dirty(); - } else if paths.len() == 0 { + } else if paths.is_empty() { // No files were passed, and stdin is not redirected. state.documents.add_untitled()?; }