diff --git a/fcore/app-with.sml b/fcore/app-with.sml index 68163da..1a5c1b1 100644 --- a/fcore/app-with.sml +++ b/fcore/app-with.sml @@ -98,4 +98,28 @@ struct , startLine = startLine } end + + fun searchListAndBuffer (app: app_type, newSearchList, newBuffer) = + let + val + { searchList = _ + , buffer = _ + , mode + , searchString + , cursorIdx + , windowWidth + , windowHeight + , startLine + } = app + in + { searchList = newSearchList + , buffer = newBuffer + , mode = mode + , searchString = searchString + , cursorIdx = cursorIdx + , windowWidth = windowWidth + , windowHeight = windowHeight + , startLine = startLine + } + end end diff --git a/fcore/build-search-list.sml b/fcore/build-search-list.sml new file mode 100644 index 0000000..04d6952 --- /dev/null +++ b/fcore/build-search-list.sml @@ -0,0 +1,81 @@ +structure BuildSearchList = +struct + fun helpNextMatch (idx, hd, tl, absIdx, searchString, matchedChrs) = + if idx = String.size hd then + case tl of + tlhd :: tltl => + helpNextMatch (0, tlhd, tltl, absIdx, searchString, matchedChrs) + | [] => + NONE + else + let + val hdChr = String.sub (hd, idx) + val searchChr = String.sub (searchString, matchedChrs) + in + if hdChr = searchChr then + if matchedChrs + 1 = String.size searchString then + let + val matchedIdx = absIdx - String.size searchString - 1 + in + SOME matchedIdx + end + else + helpNextMatch + (idx + 1, hd, tl, absIdx + 1, searchString, matchedChrs + 1) + else + helpNextMatch (idx + 1, hd, tl, absIdx + 1, searchString, 0) + end + + fun nextMatch (bufferIdx, absIdx, rightStrings, searchString) = + case rightStrings of + hd :: tl => + let + val strIdx = absIdx - bufferIdx + in + if strIdx < String.size hd then + helpNextMatch (strIdx, hd, tl, absIdx, searchString, 0) + else + (case tl of + tlhd :: tltl => + let + val strIdx = strIdx - String.size hd + in + helpNextMatch (strIdx, tlhd, tltl, absIdx, searchString, 0) + end + | [] => NONE) + end + | [] => NONE + + fun helpBuild (app, origIdx, absIdx, buffer, searchString, searchList) = + let + val buffer = LineGap.goToIdx (absIdx, buffer) + val {idx = bufferIdx, rightStrings, ...} = buffer + in + case nextMatch (bufferIdx, absIdx, rightStrings, searchString) of + SOME matchedIdx => + let + val searchList = SearchList.append (matchedIdx, searchList) + in + helpBuild + (app, origIdx, matchedIdx, buffer, searchString, searchList) + end + | NONE => + let + val buffer = LineGap.goToIdx (origIdx, buffer) + val searchList = SearchList.goToNum (origIdx, searchList) + in + AppWith.searchListAndBuffer (app, searchList, buffer) + end + end + + fun build (app, cursorIdx, buffer, searchString) = + if String.size searchString > 0 then + let + val buffer = LineGap.goToStart buffer + in + helpBuild + (app, cursorIdx, 0, buffer, searchString, SearchList.empty) + end + else + app +end diff --git a/fcore/search-list.sml b/fcore/search-list.sml index cf38b57..c2f7fac 100644 --- a/fcore/search-list.sml +++ b/fcore/search-list.sml @@ -2,8 +2,12 @@ signature SEARCH_LIST = sig type t = {left: int vector list, right: int vector list} val empty: t + val insert: int * t -> t + val append: int * t -> t val delete: int * int * t -> t + + val goToNum: int * t -> t val mapFromNum: int * int * t -> t end @@ -148,6 +152,13 @@ struct else insLeft (new, left, right) | [] => insLeft (new, left, right) + fun helpAppend (new, left, right) = + case right of + hd :: tl => helpAppend (new, joinEndOfLeft (hd, left), tl) + | [] => {left = joinEndOfLeft (Vector.fromList [new], left), right = right} + + fun append (new, {left, right}: t) = helpAppend (new, left, right) + fun helpGoToNumLeft (num, left, right) = case left of hd :: tl => diff --git a/shf b/shf index 6d62b20..960d02f 100755 Binary files a/shf and b/shf differ diff --git a/shf.mlb b/shf.mlb index 00b6703..7db8eba 100644 --- a/shf.mlb +++ b/shf.mlb @@ -15,6 +15,7 @@ fcore/search-list.sml fcore/app-type.sml fcore/app-with.sml +fcore/build-search-list.sml fcore/text-constants.sml ann "allowVectorExps true"