Skip to content

Instantly share code, notes, and snippets.

@BlinkyStitt
Last active January 29, 2018 20:17
Show Gist options
  • Save BlinkyStitt/f5659eb14d32d9fa6d68b87b5c8b1d6c to your computer and use it in GitHub Desktop.
Save BlinkyStitt/f5659eb14d32d9fa6d68b87b5c8b1d6c to your computer and use it in GitHub Desktop.
unison whitespace backport to 2.40.102. Credit to https://github.com/bcpierce00/unison/pull/121
diff --git a/ubase/util.ml b/src/ubase/util.ml
index 7376799..1231eb6 100644
--- a/ubase/util.ml
+++ b/src/ubase/util.ml
@@ -399,15 +399,25 @@ let rec trimWhitespace s =
else
s
-let splitIntoWords (s:string) (c:char) =
- let rec inword acc start pos =
- if pos >= String.length(s) || s.[pos] = c then
- betweenwords ((String.sub s start (pos-start)) :: acc) pos
- else inword acc start (pos+1)
+let splitIntoWords ?esc:(e='\\') (s:string) (c:char) =
+ let rec inword acc eacc start pos =
+ if pos >= String.length s || s.[pos] = c then
+ let word =
+ String.concat "" (Safelist.rev (String.sub s start (pos-start)::eacc)) in
+ betweenwords (word::acc) pos
+ else if s.[pos] = e then inescape acc eacc start pos
+ else inword acc eacc start (pos+1)
+ and inescape acc eacc start pos =
+ let eword = String.sub s start (pos-start) in
+ if pos+1 >= String.length s
+ then inword acc (eword::eacc) (pos+1) (pos+1) (* ignore final esc *)
+ else (* take any following char *)
+ let echar = String.make 1 (String.get s (pos+1)) in
+ inword acc (echar::eword::eacc) (pos+2) (pos+2)
and betweenwords acc pos =
- if pos >= (String.length s) then (Safelist.rev acc)
+ if pos >= String.length s then (Safelist.rev acc)
else if s.[pos]=c then betweenwords acc (pos+1)
- else inword acc pos pos
+ else inword acc [] pos pos
in betweenwords [] 0
let rec splitIntoWordsByString s sep =
diff --git a/ubase/util.mli b/src/ubase/util.mli
index d4bd8f7..d7409c8 100644
--- a/ubase/util.mli
+++ b/src/ubase/util.mli
@@ -55,7 +55,7 @@ val replacesubstrings : string -> (string * string) list -> string
val concatmap : string -> ('a -> string) -> 'a list -> string
val removeTrailingCR : string -> string
val trimWhitespace : string -> string
-val splitIntoWords : string -> char -> string list
+val splitIntoWords : ?esc:char -> string -> char -> string list
val splitIntoWordsByString : string -> string -> string list
val padto : int -> string -> string
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment