aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorath32022-06-21 16:48:01 +0000
committerGitHub2022-06-21 16:48:01 +0000
commitce85b9716df5e1ea804994202687f19cd711ae1b (patch)
tree937b70f08d090e4826ecbe4328b53839fd7dc5a8
parent8b67acf130e12cf8aaa439fe19ea7b8917db300b (diff)
Enable shellwords for Windows (with escaping disabled) (#2767)
-rw-r--r--helix-core/src/shellwords.rs52
-rw-r--r--helix-term/src/commands/typed.rs10
2 files changed, 44 insertions, 18 deletions
diff --git a/helix-core/src/shellwords.rs b/helix-core/src/shellwords.rs
index 13f6f3e9..4323039a 100644
--- a/helix-core/src/shellwords.rs
+++ b/helix-core/src/shellwords.rs
@@ -24,9 +24,13 @@ pub fn shellwords(input: &str) -> Vec<Cow<'_, str>> {
state = match state {
Normal => match c {
'\\' => {
- escaped.push_str(&input[start..i]);
- start = i + 1;
- NormalEscaped
+ if cfg!(unix) {
+ escaped.push_str(&input[start..i]);
+ start = i + 1;
+ NormalEscaped
+ } else {
+ Normal
+ }
}
'"' => {
end = i;
@@ -45,9 +49,13 @@ pub fn shellwords(input: &str) -> Vec<Cow<'_, str>> {
NormalEscaped => Normal,
Quoted => match c {
'\\' => {
- escaped.push_str(&input[start..i]);
- start = i + 1;
- QuoteEscaped
+ if cfg!(unix) {
+ escaped.push_str(&input[start..i]);
+ start = i + 1;
+ QuoteEscaped
+ } else {
+ Quoted
+ }
}
'\'' => {
end = i;
@@ -58,9 +66,13 @@ pub fn shellwords(input: &str) -> Vec<Cow<'_, str>> {
QuoteEscaped => Quoted,
Dquoted => match c {
'\\' => {
- escaped.push_str(&input[start..i]);
- start = i + 1;
- DquoteEscaped
+ if cfg!(unix) {
+ escaped.push_str(&input[start..i]);
+ start = i + 1;
+ DquoteEscaped
+ } else {
+ Dquoted
+ }
}
'"' => {
end = i;
@@ -99,6 +111,25 @@ mod test {
use super::*;
#[test]
+ #[cfg(windows)]
+ fn test_normal() {
+ let input = r#":o single_word twó wörds \three\ \"with\ escaping\\"#;
+ let result = shellwords(input);
+ let expected = vec![
+ Cow::from(":o"),
+ Cow::from("single_word"),
+ Cow::from("twó"),
+ Cow::from("wörds"),
+ Cow::from("\\three\\"),
+ Cow::from("\\"),
+ Cow::from("with\\ escaping\\\\"),
+ ];
+ // TODO test is_owned and is_borrowed, once they get stabilized.
+ assert_eq!(expected, result);
+ }
+
+ #[test]
+ #[cfg(unix)]
fn test_normal() {
let input = r#":o single_word twó wörds \three\ \"with\ escaping\\"#;
let result = shellwords(input);
@@ -114,6 +145,7 @@ mod test {
}
#[test]
+ #[cfg(unix)]
fn test_quoted() {
let quoted =
r#":o 'single_word' 'twó wörds' '' ' ''\three\' \"with\ escaping\\' 'quote incomplete"#;
@@ -129,6 +161,7 @@ mod test {
}
#[test]
+ #[cfg(unix)]
fn test_dquoted() {
let dquoted = r#":o "single_word" "twó wörds" "" " ""\three\' \"with\ escaping\\" "dquote incomplete"#;
let result = shellwords(dquoted);
@@ -143,6 +176,7 @@ mod test {
}
#[test]
+ #[cfg(unix)]
fn test_mixed() {
let dquoted = r#":o single_word 'twó wörds' "\three\' \"with\ escaping\\""no space before"'and after' $#%^@ "%^&(%^" ')(*&^%''a\\\\\b' '"#;
let result = shellwords(dquoted);
diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs
index ae3e63af..58256c7d 100644
--- a/helix-term/src/commands/typed.rs
+++ b/helix-term/src/commands/typed.rs
@@ -1802,15 +1802,7 @@ pub fn command_mode(cx: &mut Context) {
// Handle typable commands
if let Some(cmd) = typed::TYPABLE_COMMAND_MAP.get(parts[0]) {
- let args = if cfg!(unix) {
- shellwords::shellwords(input)
- } else {
- // Windows doesn't support POSIX, so fallback for now
- parts
- .into_iter()
- .map(|part| part.into())
- .collect::<Vec<_>>()
- };
+ let args = shellwords::shellwords(input);
if let Err(e) = (cmd.fun)(cx, &args[1..], event) {
cx.editor.set_error(format!("{}", e));