mirror of https://github.com/sharkdp/fd.git
Fix printing when using multiple command instances.
This commit is contained in:
parent
4b6fca7536
commit
bc564b8f2d
|
@ -58,6 +58,13 @@ pub fn execute_commands<I: Iterator<Item = io::Result<Command>>>(
|
|||
cmd_display_result: Option<String>,
|
||||
) -> ExitCode {
|
||||
let mut output_buffer = OutputBuffer::new(out_perm);
|
||||
|
||||
if let Some(ref d) = cmd_display_result {
|
||||
// Print command.
|
||||
let cmd_bytes: Vec<u8> = d.clone().as_bytes().to_vec();
|
||||
output_buffer.push(cmd_bytes, vec![]);
|
||||
}
|
||||
|
||||
for result in cmds {
|
||||
let mut cmd = match result {
|
||||
Ok(cmd) => cmd,
|
||||
|
@ -73,11 +80,6 @@ pub fn execute_commands<I: Iterator<Item = io::Result<Command>>>(
|
|||
cmd.spawn().and_then(|c| c.wait_with_output())
|
||||
};
|
||||
|
||||
if let Some(ref d) = cmd_display_result {
|
||||
let cmd_bytes: Vec<u8> = d.clone().as_bytes().to_vec();
|
||||
output_buffer.push(cmd_bytes, vec![]);
|
||||
}
|
||||
|
||||
// Then wait for the command to exit, if it was spawned.
|
||||
match output {
|
||||
Ok(output) => {
|
||||
|
|
109
src/exec/mod.rs
109
src/exec/mod.rs
|
@ -68,7 +68,10 @@ impl<'a> CommandSetDisplay<'a> {
|
|||
impl CommandSetDisplay<'_> {
|
||||
fn get_command_string(&self, path_separator: Option<&str>) -> Option<String> {
|
||||
let mut res = String::new();
|
||||
for c in self.command_set.commands.iter() {
|
||||
for (i, c) in self.command_set.commands.iter().enumerate() {
|
||||
if i > 0 {
|
||||
res.push_str(&"; ");
|
||||
}
|
||||
let cmd_hl = c.generate_highlighted_string(self.entry, self.config, path_separator);
|
||||
match cmd_hl {
|
||||
None => return None,
|
||||
|
@ -78,50 +81,6 @@ impl CommandSetDisplay<'_> {
|
|||
res.push('\n');
|
||||
Some(res)
|
||||
}
|
||||
|
||||
fn print_entry_string(
|
||||
entry: &DirEntry,
|
||||
argt: &ArgumentTemplate,
|
||||
config: &Config,
|
||||
path_separator: Option<&str>,
|
||||
) -> Result<(), std::io::Error> {
|
||||
let stdout = io::stdout();
|
||||
let mut stdout = stdout.lock();
|
||||
if let Some(argt_str) = argt
|
||||
.generate_with_highlight(entry, path_separator, config)
|
||||
.to_str()
|
||||
{
|
||||
write!(stdout, "{} ", argt_str)?;
|
||||
}
|
||||
stdout.flush()
|
||||
}
|
||||
|
||||
fn print_pre_args(args: &[OsString]) -> std::io::Result<()> {
|
||||
let stdout = io::stdout();
|
||||
let mut stdout = stdout.lock();
|
||||
|
||||
// Print pre-args; arguments before entry templates.
|
||||
for arg in args {
|
||||
if let Some(arg_str) = arg.to_str() {
|
||||
write!(stdout, "{} ", arg_str)?;
|
||||
}
|
||||
}
|
||||
stdout.flush()
|
||||
}
|
||||
|
||||
fn print_post_args(args: &[OsString]) -> std::io::Result<()> {
|
||||
let stdout = io::stdout();
|
||||
let mut stdout = stdout.lock();
|
||||
|
||||
// Print post-args, arguments after entry templates.
|
||||
for arg in args {
|
||||
if let Some(arg_str) = arg.to_str() {
|
||||
write!(stdout, "{} ", arg_str)?;
|
||||
}
|
||||
}
|
||||
writeln!(stdout)?;
|
||||
stdout.flush()
|
||||
}
|
||||
}
|
||||
|
||||
impl CommandSet {
|
||||
|
@ -223,14 +182,7 @@ impl CommandSet {
|
|||
|
||||
// If provided print config, print command arguments.
|
||||
if let Some(config) = print_with_config {
|
||||
if let Err(e) = CommandSetDisplay::print_entry_string(
|
||||
&entry,
|
||||
&builder.path_arg,
|
||||
config,
|
||||
path_separator,
|
||||
) {
|
||||
return handle_cmd_error(Some(&builder.cmd), e);
|
||||
}
|
||||
builder.push_display_entry(&entry, config, path_separator)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -258,6 +210,7 @@ struct CommandBuilder {
|
|||
count: usize,
|
||||
limit: usize,
|
||||
print: bool,
|
||||
entries_to_print: OsString,
|
||||
}
|
||||
|
||||
impl CommandBuilder {
|
||||
|
@ -286,6 +239,7 @@ impl CommandBuilder {
|
|||
count: 0,
|
||||
limit,
|
||||
print,
|
||||
entries_to_print: OsString::new(),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -298,6 +252,20 @@ impl CommandBuilder {
|
|||
Ok(cmd)
|
||||
}
|
||||
|
||||
fn push_display_entry(
|
||||
&mut self,
|
||||
entry: &DirEntry,
|
||||
config: &Config,
|
||||
path_separator: Option<&str>,
|
||||
) {
|
||||
self.entries_to_print
|
||||
.push(
|
||||
self.path_arg
|
||||
.generate_with_highlight(entry, path_separator, config),
|
||||
);
|
||||
self.entries_to_print.push(" ");
|
||||
}
|
||||
|
||||
fn push(&mut self, path: &Path, separator: Option<&str>) -> io::Result<()> {
|
||||
if self.limit > 0 && self.count >= self.limit {
|
||||
self.finish()?;
|
||||
|
@ -311,21 +279,40 @@ impl CommandBuilder {
|
|||
self.finish()?;
|
||||
}
|
||||
|
||||
// If started a new command, print the arguments before printing entry templates.
|
||||
if self.count == 0 && self.print {
|
||||
CommandSetDisplay::print_pre_args(&self.pre_args)?;
|
||||
}
|
||||
|
||||
self.cmd.try_arg(arg)?;
|
||||
self.count += 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn finish(&mut self) -> io::Result<()> {
|
||||
if self.count > 0 {
|
||||
if self.print {
|
||||
CommandSetDisplay::print_post_args(&self.post_args)?;
|
||||
if self.print {
|
||||
let mut to_print = OsString::new();
|
||||
|
||||
for arg in &self.pre_args {
|
||||
to_print.push(arg);
|
||||
to_print.push(" ");
|
||||
}
|
||||
|
||||
to_print.push(&self.entries_to_print);
|
||||
|
||||
for (i, arg) in self.post_args.iter().enumerate() {
|
||||
if i > 0 {
|
||||
to_print.push(" ");
|
||||
}
|
||||
to_print.push(arg);
|
||||
}
|
||||
|
||||
let stdout = io::stdout();
|
||||
let mut stdout = stdout.lock();
|
||||
|
||||
if let Some(to_print_str) = to_print.to_str() {
|
||||
writeln!(stdout, "{}", to_print_str)?;
|
||||
}
|
||||
|
||||
stdout.flush()?;
|
||||
self.entries_to_print = OsString::new();
|
||||
}
|
||||
if self.count > 0 {
|
||||
self.cmd.try_args(&self.post_args)?;
|
||||
self.cmd.status()?;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
mod testenv;
|
||||
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::io::{stdout, Write};
|
||||
use std::path::Path;
|
||||
use std::time::{Duration, SystemTime};
|
||||
use test_case::test_case;
|
||||
|
@ -1740,6 +1740,69 @@ fn test_print_exec() {
|
|||
"echo beginarg ./a.foo ./one/b.foo ./one/two/C.Foo2 ./one/two/c.foo ./one/two/three/d.foo ./one/two/three/directory_foo endarg
|
||||
beginarg ./a.foo ./one/b.foo ./one/two/C.Foo2 ./one/two/c.foo ./one/two/three/d.foo ./one/two/three/directory_foo endarg",
|
||||
);
|
||||
|
||||
te.assert_output(
|
||||
&[
|
||||
"--absolute-path",
|
||||
"foo",
|
||||
"--print-exec",
|
||||
"--exec",
|
||||
"echo",
|
||||
";",
|
||||
"--exec",
|
||||
"echo",
|
||||
"test",
|
||||
"{/}",
|
||||
],
|
||||
&format!(
|
||||
"echo {abs_path}/a.foo; echo test a.foo
|
||||
echo {abs_path}/one/b.foo; echo test b.foo
|
||||
echo {abs_path}/one/two/C.Foo2; echo test C.Foo2
|
||||
echo {abs_path}/one/two/c.foo; echo test c.foo
|
||||
echo {abs_path}/one/two/three/d.foo; echo test d.foo
|
||||
echo {abs_path}/one/two/three/directory_foo; echo test directory_foo
|
||||
{abs_path}/a.foo
|
||||
{abs_path}/one/b.foo
|
||||
{abs_path}/one/two/C.Foo2
|
||||
{abs_path}/one/two/c.foo
|
||||
{abs_path}/one/two/three/d.foo
|
||||
{abs_path}/one/two/three/directory_foo
|
||||
test a.foo
|
||||
test b.foo
|
||||
test C.Foo2
|
||||
test c.foo
|
||||
test d.foo
|
||||
test directory_foo",
|
||||
abs_path = &abs_path
|
||||
),
|
||||
);
|
||||
|
||||
te.assert_output(
|
||||
&[
|
||||
"foo",
|
||||
"--print-exec",
|
||||
"--exec",
|
||||
"echo",
|
||||
"-n",
|
||||
"{/}: ",
|
||||
";",
|
||||
"--exec",
|
||||
"echo",
|
||||
"{//}",
|
||||
],
|
||||
"echo -n a.foo: ; echo .
|
||||
echo -n b.foo: ; echo ./one
|
||||
echo -n C.Foo2: ; echo ./one/two
|
||||
echo -n c.foo: ; echo ./one/two
|
||||
echo -n d.foo: ; echo ./one/two/three
|
||||
echo -n directory_foo: ; echo ./one/two/three
|
||||
a.foo: .
|
||||
b.foo: ./one
|
||||
C.Foo2: ./one/two
|
||||
c.foo: ./one/two
|
||||
d.foo: ./one/two/three
|
||||
directory_foo: ./one/two/three",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue