Files
sml-projects/fcore/build-search-list.sml

82 lines
2.5 KiB
Standard ML

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 + 1, buffer, searchString, searchList)
end
| NONE =>
let
val buffer = LineGap.goToIdx (origIdx, buffer)
val searchList = SearchList.goToNum (origIdx, searchList)
in
AppWith.searchList (app, searchList, buffer, searchString)
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