mirror of
https://github.com/jj-vcs/jj.git
synced 2026-07-07 09:13:10 +08:00
config: Respect shell quotations in split_name_and_args
This commit is contained in:
@@ -33,6 +33,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
configuration options which are set.
|
||||
[#7774](https://github.com/jj-vcs/jj/issues/7774)
|
||||
|
||||
* Setting the editor via `ui.editor`, `$EDITOR`, or `JJ_EDITOR` now respects shell quoting.
|
||||
|
||||
>>>>>>> Conflict 1 of 1 ends
|
||||
## [0.37.0] - 2026-01-07
|
||||
|
||||
### Release highlights
|
||||
|
||||
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -2391,6 +2391,7 @@ dependencies = [
|
||||
"scm-record",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"shlex",
|
||||
"slab",
|
||||
"strsim",
|
||||
"tempfile",
|
||||
|
||||
@@ -94,6 +94,7 @@ sapling-streampager = "0.11.2"
|
||||
scm-record = "0.9.0"
|
||||
serde = { version = "1.0", features = ["derive", "rc"] }
|
||||
serde_json = "1.0.148"
|
||||
shlex = "1.3.0"
|
||||
slab = "0.4.11"
|
||||
smallvec = { version = "1.15.1", features = [
|
||||
"const_generics",
|
||||
|
||||
@@ -95,6 +95,7 @@ sapling-streampager = { workspace = true }
|
||||
scm-record = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
shlex = { workspace = true }
|
||||
slab = { workspace = true }
|
||||
strsim = { workspace = true }
|
||||
tempfile = { workspace = true }
|
||||
|
||||
@@ -790,9 +790,18 @@ impl CommandNameAndArgs {
|
||||
pub fn split_name_and_args(&self) -> (Cow<'_, str>, Cow<'_, [String]>) {
|
||||
match self {
|
||||
Self::String(s) => {
|
||||
// Handle things like `EDITOR=emacs -nw` (TODO: parse shell escapes)
|
||||
if s.contains('"') || s.contains('\'') {
|
||||
let mut parts = shlex::Shlex::new(s);
|
||||
let res = (
|
||||
parts.next().unwrap_or_default().into(),
|
||||
parts.by_ref().collect(),
|
||||
);
|
||||
if !parts.had_error {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
let mut args = s.split(' ').map(|s| s.to_owned());
|
||||
(args.next().unwrap().into(), args.collect())
|
||||
(args.next().unwrap_or_default().into(), args.collect())
|
||||
}
|
||||
Self::Vec(NonEmptyCommandArgsVec(a)) => (Cow::Borrowed(&a[0]), Cow::Borrowed(&a[1..])),
|
||||
Self::Structured {
|
||||
@@ -1020,6 +1029,7 @@ mod tests {
|
||||
empty_string = ''
|
||||
array = ['emacs', '-nw']
|
||||
string = 'emacs -nw'
|
||||
string_quoted = '\"spaced path/to/emacs\" -nw'
|
||||
structured.env = { KEY1 = 'value1', KEY2 = 'value2' }
|
||||
structured.command = ['emacs', '-nw']
|
||||
"},
|
||||
@@ -1055,6 +1065,15 @@ mod tests {
|
||||
assert_eq!(name, "emacs");
|
||||
assert_eq!(args, ["-nw"].as_ref());
|
||||
|
||||
let command_args: CommandNameAndArgs = config.get("string_quoted").unwrap();
|
||||
assert_eq!(
|
||||
command_args,
|
||||
CommandNameAndArgs::String("\"spaced path/to/emacs\" -nw".to_owned())
|
||||
);
|
||||
let (name, args) = command_args.split_name_and_args();
|
||||
assert_eq!(name, "spaced path/to/emacs");
|
||||
assert_eq!(args, ["-nw"].as_ref());
|
||||
|
||||
let command_args: CommandNameAndArgs = config.get("structured").unwrap();
|
||||
assert_eq!(
|
||||
command_args,
|
||||
|
||||
@@ -24,19 +24,19 @@ pub use self::test_environment::TestWorkDir;
|
||||
pub fn fake_bisector_path() -> String {
|
||||
let path = assert_cmd::cargo::cargo_bin!("fake-bisector");
|
||||
assert!(path.is_file());
|
||||
path.as_os_str().to_str().unwrap().to_owned()
|
||||
path.as_os_str().to_str().unwrap().replace("\\", "\\\\")
|
||||
}
|
||||
|
||||
pub fn fake_editor_path() -> String {
|
||||
let path = assert_cmd::cargo::cargo_bin!("fake-editor");
|
||||
assert!(path.is_file());
|
||||
path.as_os_str().to_str().unwrap().to_owned()
|
||||
path.as_os_str().to_str().unwrap().replace("\\", "\\\\")
|
||||
}
|
||||
|
||||
pub fn fake_diff_editor_path() -> String {
|
||||
let path = assert_cmd::cargo::cargo_bin!("fake-diff-editor");
|
||||
assert!(path.is_file());
|
||||
path.as_os_str().to_str().unwrap().to_owned()
|
||||
path.as_os_str().to_str().unwrap().replace("\\", "\\\\")
|
||||
}
|
||||
|
||||
/// Forcibly enable interactive prompt.
|
||||
|
||||
Reference in New Issue
Block a user