Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e0298cf

Browse files
committedFeb 27, 2025··
Deal with term-based editors.
1 parent a6346da commit e0298cf

File tree

1 file changed

+62
-23
lines changed
  • cmd/soroban-cli/src/commands/tx

1 file changed

+62
-23
lines changed
 

‎cmd/soroban-cli/src/commands/tx/edit.rs

+62-23
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
use std::{
2-
env, fs,
2+
env,
3+
fs::{self, File},
34
io::{stdin, Cursor, IsTerminal, Write},
45
path::PathBuf,
5-
process::{self, Stdio},
6+
process::{self},
67
};
78

9+
#[cfg(windows)]
10+
use std::process::Stdio;
11+
812
use base64::{engine::general_purpose::STANDARD as BASE64, Engine as _};
913
use stellar_xdr::curr;
1014

@@ -63,7 +67,9 @@ impl Cmd {
6367
};
6468

6569
let path = tmp_file(&json)?;
66-
open_editor(&print, &path)?;
70+
let editor = get_editor();
71+
72+
open_editor(&print, &editor, &path)?;
6773

6874
let contents = fs::read_to_string(&path)?;
6975
let xdr = json_to_xdr::<curr::TransactionEnvelope>(&contents)?;
@@ -75,8 +81,14 @@ impl Cmd {
7581
}
7682
}
7783

84+
struct Editor {
85+
cmd: String,
86+
source: String,
87+
args: Vec<String>,
88+
}
89+
7890
fn tmp_file(contents: &str) -> Result<PathBuf, Error> {
79-
let temp_dir = env::temp_dir();
91+
let temp_dir = env::current_dir().unwrap_or(env::temp_dir());
8092
let file_name = format!("stellar-json-xdr-{}.json", rand::random::<u64>());
8193
let path = temp_dir.join(file_name);
8294

@@ -86,31 +98,58 @@ fn tmp_file(contents: &str) -> Result<PathBuf, Error> {
8698
Ok(path)
8799
}
88100

89-
fn get_editor() -> String {
90-
env::var("STELLAR_EDITOR")
91-
.or_else(|_| env::var("EDITOR"))
92-
.or_else(|_| env::var("VISUAL"))
93-
.unwrap_or_else(|_| "vi".to_string())
101+
fn get_editor() -> Editor {
102+
let (source, cmd) = env::var("STELLAR_EDITOR")
103+
.map(|val| ("STELLAR_EDITOR", val))
104+
.or_else(|_| env::var("EDITOR").map(|val| ("EDITOR", val)))
105+
.or_else(|_| env::var("VISUAL").map(|val| ("VISUAL", val)))
106+
.unwrap_or_else(|_| ("default", "vim".to_string()));
107+
108+
let parts: Vec<&str> = cmd.split_whitespace().collect();
109+
let cmd = parts[0].to_string();
110+
let args = &parts[1..]
111+
.iter()
112+
.map(|&s| s.to_string())
113+
.collect::<Vec<String>>();
114+
115+
Editor {
116+
source: source.to_string(),
117+
cmd,
118+
args: args.clone(),
119+
}
94120
}
95121

96-
fn open_editor(print: &Print, path: &PathBuf) -> Result<(), Error> {
97-
let editor = get_editor();
98-
print.infoln(format!("Using `{editor}`"));
122+
fn open_editor(print: &Print, editor: &Editor, path: &PathBuf) -> Result<(), Error> {
123+
print.infoln(format!(
124+
"Using `{source}=\"{cmd}\"`",
125+
source = editor.source,
126+
cmd = editor.cmd,
127+
));
99128

100-
let parts: Vec<&str> = editor.split_whitespace().collect();
101-
let cmd = parts[0];
102-
let args = &parts[1..];
129+
print.infoln("Opening editor...".to_string());
103130

104-
print.infoln("Opening editor to edit the transaction envelope...".to_string());
131+
let mut binding = process::Command::new(editor.cmd.clone());
132+
let command = binding.args(editor.args.clone()).arg(path);
133+
134+
#[cfg(windows)]
135+
let tty = Stdio::null();
136+
137+
#[cfg(unix)]
138+
{
139+
let tty = File::open("/dev/tty")?;
140+
let tty_out = fs::OpenOptions::new().write(true).open("/dev/tty")?;
141+
let tty_err = fs::OpenOptions::new().write(true).open("/dev/tty")?;
142+
143+
command
144+
.stdin(tty)
145+
.stdout(tty_out)
146+
.stderr(tty_err)
147+
.env("TERM", "xterm-256color");
148+
}
105149

106-
let result = process::Command::new(cmd)
107-
.stdin(Stdio::null())
108-
.args(args)
109-
.arg(path)
110-
.spawn()?
111-
.wait_with_output()?;
150+
let status = command.spawn()?.wait()?;
112151

113-
if result.status.success() {
152+
if status.success() {
114153
Ok(())
115154
} else {
116155
Err(Error::EditorNonZeroStatus)

0 commit comments

Comments
 (0)
Please sign in to comment.