diff --git a/Cargo.lock b/Cargo.lock index 3b3df0d32..f927de8c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1167,7 +1167,7 @@ checksum = "e11dcc7e4d79a8c89b9ab4c6f5c30b1fc4a83c420792da3542fd31179ed5f517" dependencies = [ "cfg-if 1.0.0", "rustix", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -1188,7 +1188,7 @@ dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -2324,7 +2324,7 @@ dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -2651,6 +2651,7 @@ dependencies = [ "num-format", "num-traits", "once_cell", + "open", "pathdiff", "polars", "powierza-coefficient", @@ -3110,6 +3111,16 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +[[package]] +name = "open" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2078c0039e6a54a0c42c28faa984e115fb4c2d5bf2208f77d1961002df8576f8" +dependencies = [ + "pathdiff", + "windows-sys 0.42.0", +] + [[package]] name = "openssl" version = "0.10.42" @@ -3219,7 +3230,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -4273,7 +4284,7 @@ dependencies = [ "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -4316,7 +4327,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" dependencies = [ "lazy_static", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -4955,7 +4966,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8440c860cf79def6164e4a0a983bcc2305d82419177a0e0c71930d049e3ac5a1" dependencies = [ "rustix", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -5664,6 +5675,21 @@ dependencies = [ "windows_x86_64_msvc 0.36.1", ] +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.0" diff --git a/crates/nu-command/Cargo.toml b/crates/nu-command/Cargo.toml index 4d3b13b54..d9cc14ad9 100644 --- a/crates/nu-command/Cargo.toml +++ b/crates/nu-command/Cargo.toml @@ -64,6 +64,7 @@ notify = "4.0.17" num = { version = "0.4.0", optional = true } num-traits = "0.2.14" once_cell = "1.0" +open = "3.2.0" pathdiff = "0.2.1" powierza-coefficient = "1.0.2" quick-xml = "0.25" diff --git a/crates/nu-command/src/dataframe/eager/mod.rs b/crates/nu-command/src/dataframe/eager/mod.rs index 5844794e3..65c90038b 100644 --- a/crates/nu-command/src/dataframe/eager/mod.rs +++ b/crates/nu-command/src/dataframe/eager/mod.rs @@ -30,6 +30,7 @@ mod with_column; use nu_protocol::engine::StateWorkingSet; +pub use self::open::OpenDataFrame; pub use append::AppendDF; pub use columns::ColumnsDF; pub use drop::DropDF; @@ -43,7 +44,6 @@ pub use get::GetDF; pub use last::LastDF; pub use list::ListDF; pub use melt::MeltDF; -pub use open::OpenDataFrame; pub use query_df::QueryDf; pub use rename::RenameDF; pub use sample::SampleDF; diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index f722e20f9..9d257236c 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -275,6 +275,7 @@ pub fn create_default_context() -> EngineState { Mkdir, Mv, Open, + Start, Rm, Save, Touch, diff --git a/crates/nu-command/src/filesystem/mod.rs b/crates/nu-command/src/filesystem/mod.rs index 17ef8f54e..1bdcc206f 100644 --- a/crates/nu-command/src/filesystem/mod.rs +++ b/crates/nu-command/src/filesystem/mod.rs @@ -8,10 +8,12 @@ mod mv; mod open; mod rm; mod save; +mod start; mod touch; mod util; mod watch; +pub use self::open::Open; pub use cd::Cd; pub use cd_query::query; pub use cp::Cp; @@ -19,9 +21,9 @@ pub use glob::Glob; pub use ls::Ls; pub use mkdir::Mkdir; pub use mv::Mv; -pub use open::Open; pub use rm::Rm; pub use save::Save; +pub use start::Start; pub use touch::Touch; pub use util::BufferedReader; pub use watch::Watch; diff --git a/crates/nu-command/src/filesystem/start.rs b/crates/nu-command/src/filesystem/start.rs new file mode 100644 index 000000000..057b31ba3 --- /dev/null +++ b/crates/nu-command/src/filesystem/start.rs @@ -0,0 +1,103 @@ +use nu_engine::CallExt; +use nu_protocol::ast::Call; +use nu_protocol::engine::{Command, EngineState, Stack}; +use nu_protocol::{ + Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape, Type, Value, +}; +use std::path::Path; + +#[derive(Clone)] +pub struct Start; + +impl Command for Start { + fn name(&self) -> &str { + "start" + } + + fn usage(&self) -> &str { + "Open a folder or file in the default application or viewer." + } + + fn search_terms(&self) -> Vec<&str> { + vec!["load", "folder", "directory", "run", "open"] + } + + fn signature(&self) -> nu_protocol::Signature { + Signature::build("start") + .input_output_types(vec![(Type::Nothing, Type::Any), (Type::String, Type::Any)]) + .optional("filepath", SyntaxShape::Filepath, "the filepath to open") + .category(Category::FileSystem) + } + + fn run( + &self, + engine_state: &EngineState, + stack: &mut Stack, + call: &Call, + input: PipelineData, + ) -> Result { + let path = call.opt::>(engine_state, stack, 0)?; + + let path = { + if let Some(path_val) = path { + Some(Spanned { + item: nu_utils::strip_ansi_string_unlikely(path_val.item), + span: path_val.span, + }) + } else { + path + } + }; + + let path = if let Some(path) = path { + path + } else { + // Collect a filename from the input + match input { + PipelineData::Value(Value::Nothing { .. }, ..) => { + return Err(ShellError::MissingParameter( + "needs filename".to_string(), + call.head, + )) + } + PipelineData::Value(val, ..) => val.as_spanned_string()?, + _ => { + return Err(ShellError::MissingParameter( + "needs filename".to_string(), + call.head, + )); + } + } + }; + let path_no_whitespace = &path.item.trim_end_matches(|x| matches!(x, '\x09'..='\x0d')); + let path = Path::new(path_no_whitespace); + + open::that(path)?; + Ok(PipelineData::Empty) + } + + fn examples(&self) -> Vec { + vec![ + Example { + description: "Open a text file with the default text editor", + example: "start file.txt", + result: None, + }, + Example { + description: "Open an image with the default image viewer", + example: "start file.jpg", + result: None, + }, + Example { + description: "Open the current directory with the default file manager", + example: "start .", + result: None, + }, + Example { + description: "Open a pdf with the default pdf viewer", + example: "start file.pdf", + result: None, + }, + ] + } +}