aboutsummaryrefslogtreecommitdiff
path: root/helix-core
diff options
context:
space:
mode:
authorArmin Ronacher2022-11-01 11:48:37 +0000
committerGitHub2022-11-01 11:48:37 +0000
commit8584b38cfbe6ffe3e5d539ad953c413e44e90bfa (patch)
treed2013dc542e6d1c15468b0357ffba509cb1285a0 /helix-core
parent3881fef39d01c94a09b8f5da67decc2c3ccb3660 (diff)
Correctly handle escaping in completion (#4316)
* Correctly handle escaping in completion * Added escaping tests
Diffstat (limited to 'helix-core')
-rw-r--r--helix-core/src/shellwords.rs31
1 files changed, 31 insertions, 0 deletions
diff --git a/helix-core/src/shellwords.rs b/helix-core/src/shellwords.rs
index afc83496..6edf3cc7 100644
--- a/helix-core/src/shellwords.rs
+++ b/helix-core/src/shellwords.rs
@@ -1,5 +1,22 @@
use std::borrow::Cow;
+/// Auto escape for shellwords usage.
+pub fn escape(input: &str) -> Cow<'_, str> {
+ if !input.chars().any(|x| x.is_ascii_whitespace()) {
+ Cow::Borrowed(input)
+ } else if cfg!(unix) {
+ Cow::Owned(input.chars().fold(String::new(), |mut buf, c| {
+ if c.is_ascii_whitespace() {
+ buf.push('\\');
+ }
+ buf.push(c);
+ buf
+ }))
+ } else {
+ Cow::Owned(format!("\"{}\"", input))
+ }
+}
+
/// Get the vec of escaped / quoted / doublequoted filenames from the input str
pub fn shellwords(input: &str) -> Vec<Cow<'_, str>> {
enum State {
@@ -226,4 +243,18 @@ mod test {
];
assert_eq!(expected, result);
}
+
+ #[cfg(unix)]
+ fn test_escaping_unix() {
+ assert_eq!(escape("foobar"), Cow::Borrowed("foobar"));
+ assert_eq!(escape("foo bar"), Cow::Borrowed("foo\\ bar"));
+ assert_eq!(escape("foo\tbar"), Cow::Borrowed("foo\\\tbar"));
+ }
+
+ #[test]
+ #[cfg(windows)]
+ fn test_escaping_windows() {
+ assert_eq!(escape("foobar"), Cow::Borrowed("foobar"));
+ assert_eq!(escape("foo bar"), Cow::Borrowed("\"foo bar\""));
+ }
}