Add option to pipe from stdin on cli (#16084)
Closes #5044 Release Notes: - Linux: Added CLI pipe support.
This commit is contained in:
parent
e1b05bf7a3
commit
f45af17fd4
3 changed files with 34 additions and 1 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2266,6 +2266,7 @@ dependencies = [
|
||||||
"plist",
|
"plist",
|
||||||
"release_channel",
|
"release_channel",
|
||||||
"serde",
|
"serde",
|
||||||
|
"tempfile",
|
||||||
"util",
|
"util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ paths.workspace = true
|
||||||
release_channel.workspace = true
|
release_channel.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
util.workspace = true
|
util.workspace = true
|
||||||
|
tempfile.workspace = true
|
||||||
|
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
exec.workspace = true
|
exec.workspace = true
|
||||||
|
|
|
@ -11,6 +11,7 @@ use std::{
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
thread::{self, JoinHandle},
|
thread::{self, JoinHandle},
|
||||||
};
|
};
|
||||||
|
use tempfile::NamedTempFile;
|
||||||
use util::paths::PathWithPosition;
|
use util::paths::PathWithPosition;
|
||||||
|
|
||||||
struct Detect;
|
struct Detect;
|
||||||
|
@ -22,7 +23,11 @@ trait InstalledApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[command(name = "zed", disable_version_flag = true)]
|
#[command(
|
||||||
|
name = "zed",
|
||||||
|
disable_version_flag = true,
|
||||||
|
after_help = "To read from stdin, append '-' (e.g. 'ps axf | zed -')"
|
||||||
|
)]
|
||||||
struct Args {
|
struct Args {
|
||||||
/// Wait for all of the given paths to be opened/closed before exiting.
|
/// Wait for all of the given paths to be opened/closed before exiting.
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
|
@ -120,6 +125,7 @@ fn main() -> Result<()> {
|
||||||
let exit_status = Arc::new(Mutex::new(None));
|
let exit_status = Arc::new(Mutex::new(None));
|
||||||
let mut paths = vec![];
|
let mut paths = vec![];
|
||||||
let mut urls = vec![];
|
let mut urls = vec![];
|
||||||
|
let mut stdin_tmp_file: Option<fs::File> = None;
|
||||||
for path in args.paths_with_position.iter() {
|
for path in args.paths_with_position.iter() {
|
||||||
if path.starts_with("zed://")
|
if path.starts_with("zed://")
|
||||||
|| path.starts_with("http://")
|
|| path.starts_with("http://")
|
||||||
|
@ -128,6 +134,11 @@ fn main() -> Result<()> {
|
||||||
|| path.starts_with("ssh://")
|
|| path.starts_with("ssh://")
|
||||||
{
|
{
|
||||||
urls.push(path.to_string());
|
urls.push(path.to_string());
|
||||||
|
} else if path == "-" && args.paths_with_position.len() == 1 {
|
||||||
|
let file = NamedTempFile::new()?;
|
||||||
|
paths.push(file.path().to_string_lossy().to_string());
|
||||||
|
let (file, _) = file.keep()?;
|
||||||
|
stdin_tmp_file = Some(file);
|
||||||
} else {
|
} else {
|
||||||
paths.push(parse_path_with_position(path)?)
|
paths.push(parse_path_with_position(path)?)
|
||||||
}
|
}
|
||||||
|
@ -162,11 +173,31 @@ fn main() -> Result<()> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let pipe_handle: JoinHandle<anyhow::Result<()>> = thread::spawn(move || {
|
||||||
|
if let Some(mut tmp_file) = stdin_tmp_file {
|
||||||
|
let mut stdin = std::io::stdin().lock();
|
||||||
|
if io::IsTerminal::is_terminal(&stdin) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let mut buffer = [0; 8 * 1024];
|
||||||
|
loop {
|
||||||
|
let bytes_read = io::Read::read(&mut stdin, &mut buffer)?;
|
||||||
|
if bytes_read == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
io::Write::write(&mut tmp_file, &buffer[..bytes_read])?;
|
||||||
|
}
|
||||||
|
io::Write::flush(&mut tmp_file)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
|
||||||
if args.foreground {
|
if args.foreground {
|
||||||
app.run_foreground(url)?;
|
app.run_foreground(url)?;
|
||||||
} else {
|
} else {
|
||||||
app.launch(url)?;
|
app.launch(url)?;
|
||||||
sender.join().unwrap()?;
|
sender.join().unwrap()?;
|
||||||
|
pipe_handle.join().unwrap()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(exit_status) = exit_status.lock().take() {
|
if let Some(exit_status) = exit_status.lock().take() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue