Enable shellwords for Windows (with escaping disabled) (#2767)

pull/2851/head
ath3 2 years ago committed by GitHub
parent 8b67acf130
commit ce85b9716d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -24,9 +24,13 @@ pub fn shellwords(input: &str) -> Vec<Cow<'_, str>> {
state = match state { state = match state {
Normal => match c { Normal => match c {
'\\' => { '\\' => {
escaped.push_str(&input[start..i]); if cfg!(unix) {
start = i + 1; escaped.push_str(&input[start..i]);
NormalEscaped start = i + 1;
NormalEscaped
} else {
Normal
}
} }
'"' => { '"' => {
end = i; end = i;
@ -45,9 +49,13 @@ pub fn shellwords(input: &str) -> Vec<Cow<'_, str>> {
NormalEscaped => Normal, NormalEscaped => Normal,
Quoted => match c { Quoted => match c {
'\\' => { '\\' => {
escaped.push_str(&input[start..i]); if cfg!(unix) {
start = i + 1; escaped.push_str(&input[start..i]);
QuoteEscaped start = i + 1;
QuoteEscaped
} else {
Quoted
}
} }
'\'' => { '\'' => {
end = i; end = i;
@ -58,9 +66,13 @@ pub fn shellwords(input: &str) -> Vec<Cow<'_, str>> {
QuoteEscaped => Quoted, QuoteEscaped => Quoted,
Dquoted => match c { Dquoted => match c {
'\\' => { '\\' => {
escaped.push_str(&input[start..i]); if cfg!(unix) {
start = i + 1; escaped.push_str(&input[start..i]);
DquoteEscaped start = i + 1;
DquoteEscaped
} else {
Dquoted
}
} }
'"' => { '"' => {
end = i; end = i;
@ -99,6 +111,25 @@ mod test {
use super::*; use super::*;
#[test] #[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() { fn test_normal() {
let input = r#":o single_word twó wörds \three\ \"with\ escaping\\"#; let input = r#":o single_word twó wörds \three\ \"with\ escaping\\"#;
let result = shellwords(input); let result = shellwords(input);
@ -114,6 +145,7 @@ mod test {
} }
#[test] #[test]
#[cfg(unix)]
fn test_quoted() { fn test_quoted() {
let quoted = let quoted =
r#":o 'single_word' 'twó wörds' '' ' ''\three\' \"with\ escaping\\' 'quote incomplete"#; r#":o 'single_word' 'twó wörds' '' ' ''\three\' \"with\ escaping\\' 'quote incomplete"#;
@ -129,6 +161,7 @@ mod test {
} }
#[test] #[test]
#[cfg(unix)]
fn test_dquoted() { fn test_dquoted() {
let dquoted = r#":o "single_word" "twó wörds" "" " ""\three\' \"with\ escaping\\" "dquote incomplete"#; let dquoted = r#":o "single_word" "twó wörds" "" " ""\three\' \"with\ escaping\\" "dquote incomplete"#;
let result = shellwords(dquoted); let result = shellwords(dquoted);
@ -143,6 +176,7 @@ mod test {
} }
#[test] #[test]
#[cfg(unix)]
fn test_mixed() { fn test_mixed() {
let dquoted = r#":o single_word 'twó wörds' "\three\' \"with\ escaping\\""no space before"'and after' $#%^@ "%^&(%^" ')(*&^%''a\\\\\b' '"#; let dquoted = r#":o single_word 'twó wörds' "\three\' \"with\ escaping\\""no space before"'and after' $#%^@ "%^&(%^" ')(*&^%''a\\\\\b' '"#;
let result = shellwords(dquoted); let result = shellwords(dquoted);

@ -1802,15 +1802,7 @@ pub fn command_mode(cx: &mut Context) {
// Handle typable commands // Handle typable commands
if let Some(cmd) = typed::TYPABLE_COMMAND_MAP.get(parts[0]) { if let Some(cmd) = typed::TYPABLE_COMMAND_MAP.get(parts[0]) {
let args = if cfg!(unix) { let args = shellwords::shellwords(input);
shellwords::shellwords(input)
} else {
// Windows doesn't support POSIX, so fallback for now
parts
.into_iter()
.map(|part| part.into())
.collect::<Vec<_>>()
};
if let Err(e) = (cmd.fun)(cx, &args[1..], event) { if let Err(e) = (cmd.fun)(cx, &args[1..], event) {
cx.editor.set_error(format!("{}", e)); cx.editor.set_error(format!("{}", e));

Loading…
Cancel
Save