on master help sign in
Enable shellwords for Windows (with escaping disabled) (#2767)
commitce85b9716df5e1ea804994202687f19cd711ae1b authorath3 <45574139+ath3@users.noreply.github.com> dateTue 21 Jun 2022, 18:48 (4 years ago) parent8b67acf
2 files changed+44−18
helix-core/src/shellwords.rs+43−9 helix-term/src/commands/typed.rs+1−9
helix-core/src/shellwords.rs+43−9
@@ -24,9 +24,13 @@ pub fn shellwords(input: &str) -> Vec<Cow<'_, str>> {
2424 state = match state {
2525 Normal => match c {
2626 '\\' => {
27− escaped.push_str(&input[start..i]);
28− start = i + 1;
29− NormalEscaped
27+ if cfg!(unix) {
28+ escaped.push_str(&input[start..i]);
29+ start = i + 1;
30+ NormalEscaped
31+ } else {
32+ Normal
33+ }
3034 }
3135 '"' => {
3236 end = i;
@@ -45,9 +49,13 @@ pub fn shellwords(input: &str) -> Vec<Cow<'_, str>> {
4549 NormalEscaped => Normal,
4650 Quoted => match c {
4751 '\\' => {
48− escaped.push_str(&input[start..i]);
49− start = i + 1;
50− QuoteEscaped
52+ if cfg!(unix) {
53+ escaped.push_str(&input[start..i]);
54+ start = i + 1;
55+ QuoteEscaped
56+ } else {
57+ Quoted
58+ }
5159 }
5260 '\'' => {
5361 end = i;
@@ -58,9 +66,13 @@ pub fn shellwords(input: &str) -> Vec<Cow<'_, str>> {
5866 QuoteEscaped => Quoted,
5967 Dquoted => match c {
6068 '\\' => {
61− escaped.push_str(&input[start..i]);
62− start = i + 1;
63− DquoteEscaped
69+ if cfg!(unix) {
70+ escaped.push_str(&input[start..i]);
71+ start = i + 1;
72+ DquoteEscaped
73+ } else {
74+ Dquoted
75+ }
6476 }
6577 '"' => {
6678 end = i;
@@ -99,6 +111,25 @@ mod test {
99111 use super::*;
100112
101113 #[test]
114+ #[cfg(windows)]
115+ fn test_normal() {
116+ let input = r#":o single_word twó wörds \three\ \"with\ escaping\\"#;
117+ let result = shellwords(input);
118+ let expected = vec![
119+ Cow::from(":o"),
120+ Cow::from("single_word"),
121+ Cow::from("twó"),
122+ Cow::from("wörds"),
123+ Cow::from("\\three\\"),
124+ Cow::from("\\"),
125+ Cow::from("with\\ escaping\\\\"),
126+ ];
127+ // TODO test is_owned and is_borrowed, once they get stabilized.
128+ assert_eq!(expected, result);
129+ }
130+
131+ #[test]
132+ #[cfg(unix)]
102133 fn test_normal() {
103134 let input = r#":o single_word twó wörds \three\ \"with\ escaping\\"#;
104135 let result = shellwords(input);
@@ -114,6 +145,7 @@ mod test {
114145 }
115146
116147 #[test]
148+ #[cfg(unix)]
117149 fn test_quoted() {
118150 let quoted =
119151 r#":o 'single_word' 'twó wörds' '' ' ''\three\' \"with\ escaping\\' 'quote incomplete"#;
@@ -129,6 +161,7 @@ mod test {
129161 }
130162
131163 #[test]
164+ #[cfg(unix)]
132165 fn test_dquoted() {
133166 let dquoted = r#":o "single_word" "twó wörds" "" " ""\three\' \"with\ escaping\\" "dquote incomplete"#;
134167 let result = shellwords(dquoted);
@@ -143,6 +176,7 @@ mod test {
143176 }
144177
145178 #[test]
179+ #[cfg(unix)]
146180 fn test_mixed() {
147181 let dquoted = r#":o single_word 'twó wörds' "\three\' \"with\ escaping\\""no space before"'and after' $#%^@ "%^&(%^" ')(*&^%''a\\\\\b' '"#;
148182 let result = shellwords(dquoted);
helix-term/src/commands/typed.rs+1−9
@@ -1802,15 +1802,7 @@ pub fn command_mode(cx: &mut Context) {
18021802
18031803 // Handle typable commands
18041804 if let Some(cmd) = typed::TYPABLE_COMMAND_MAP.get(parts[0]) {
1805− let args = if cfg!(unix) {
1806− shellwords::shellwords(input)
1807− } else {
1808− // Windows doesn't support POSIX, so fallback for now
1809− parts
1810− .into_iter()
1811− .map(|part| part.into())
1812− .collect::<Vec<_>>()
1813− };
1805+ let args = shellwords::shellwords(input);
18141806
18151807 if let Err(e) = (cmd.fun)(cx, &args[1..], event) {
18161808 cx.editor.set_error(format!("{}", e));