progress functorising

This commit is contained in:
2025-08-04 04:24:24 +01:00
parent 895c286b4b
commit fe9dd0f034

View File

@@ -863,146 +863,114 @@ struct
val toPrevChr = ToPrevChr.foldPrev val toPrevChr = ToPrevChr.foldPrev
fun helpTillPrevChr structure TillPrevChr =
( strPos MakeIfCharFolderPrev
, str (struct
, absIdx type env = char
, stl
, ltl
, origIdx
, findChr
, lastNonLine
, lastLine
, lastValid
) =
if strPos < 0 then
case (stl, ltl) of
(shd :: stl, lhd :: ltl) =>
helpTillPrevChr
( String.size shd - 1
, shd
, absIdx
, stl
, ltl
, origIdx
, findChr
, lastNonLine
, lastLine
, lastValid
)
| (_, _) => origIdx
else
let
val chr = String.sub (str, strPos)
in
if chr = findChr then
if lastLine = lastNonLine then lastNonLine
else if absIdx + 1 = lastLine then lastValid + 1
else Int.min (lastLine, lastNonLine)
else
let
val lastLine = if chr = #"\n" then absIdx else lastLine
val lastNonLine = if chr = #"\n" then lastNonLine else absIdx
(* There is a slightly tricky edge case fun helpTillPrevChr
* which is the reason the lastValid variable. ( strPos
* Say we have a string "a\n\n\nbcd" , str
* and we type "Ta" with the cursor at the end. , absIdx
* We want the cursor to go to the second line break , stl
* because (graphical-chr -> \n) should not be selectable. , origIdx
* However, with only lastLine and lastNonLine variables, , findChr
* we only have information about the most recent \n , lastNonLine
* and the most recent graphical-chr. , lastLine
* This means we don't have information about the case , lastValid
* where a graphical-chr is followed by multiple '\n's. ) =
* The lastValid variable keeps track of this information if strPos < 0 then
* so we can use it to provide the expected behaviour. case stl of
* *) shd :: stl =>
val lastValid = helpTillPrevChr
if lastLine = lastNonLine + 1 then lastLine + 1 ( String.size shd - 1
else Int.min (lastLine, lastNonLine) , shd
in , absIdx
helpTillPrevChr , stl
( strPos - 1 , origIdx
, str , findChr
, absIdx - 1 , lastNonLine
, stl , lastLine
, ltl , lastValid
, origIdx )
, findChr | [] => origIdx
, lastNonLine else
, lastLine let
, lastValid val chr = String.sub (str, strPos)
) in
end if chr = findChr then
end if lastLine = lastNonLine then lastNonLine
else if absIdx + 1 = lastLine then lastValid + 1
else Int.min (lastLine, lastNonLine)
else
let
val lastLine = if chr = #"\n" then absIdx else lastLine
val lastNonLine = if chr = #"\n" then lastNonLine else absIdx
fun startTillPrevChr (shd, strIdx, absIdx, stl, ltl, findChr) = (* There is a slightly tricky edge case
(* we want to start iterating from Prev char after strIdx *) * which is the reason the lastValid variable.
if strIdx > 0 then * Say we have a string "a\n\n\nbcd"
helpTillPrevChr * and we type "Ta" with the cursor at the end.
( strIdx - 1 * We want the cursor to go to the second line break
, shd * because (graphical-chr -> \n) should not be selectable.
, absIdx - 1 * However, with only lastLine and lastNonLine variables,
, stl * we only have information about the most recent \n
, ltl * and the most recent graphical-chr.
, absIdx * This means we don't have information about the case
, findChr * where a graphical-chr is followed by multiple '\n's.
, absIdx * The lastValid variable keeps track of this information
, absIdx * so we can use it to provide the expected behaviour.
, absIdx * *)
) val lastValid =
else if lastLine = lastNonLine + 1 then lastLine + 1
case (stl, ltl) of else Int.min (lastLine, lastNonLine)
(stlhd :: stltl, ltlhd :: ltltl) => in
helpTillPrevChr helpTillPrevChr
( String.size stlhd - 1 ( strPos - 1
, stlhd , str
, absIdx - 1 , absIdx - 1
, stltl , stl
, ltltl , origIdx
, absIdx , findChr
, findChr , lastNonLine
, absIdx , lastLine
, absIdx , lastValid
, absIdx )
) end
| (_, _) => (* tl is empty; return 0 for lineGap start *) 0 end
fun prevChr (lineGap: LineGap.t, cursorIdx, chr, fStart) = fun fStart (strIdx, shd, _, absIdx, stl, ltl, findChr) =
let (* we want to start iterating from Prev char after strIdx *)
val if strIdx > 0 then
{rightStrings, rightLines, idx = bufferIdx, leftStrings, leftLines, ...} = helpTillPrevChr
lineGap ( strIdx - 1
in , shd
case (rightStrings, rightLines) of , absIdx - 1
(shd :: stl, lhd :: ltl) => , stl
let , absIdx
(* convert absolute cursorIdx to idx relative to hd string *) , findChr
val strIdx = cursorIdx - bufferIdx , absIdx
in , absIdx
if strIdx < String.size shd then , absIdx
(* strIdx is in this string *) )
fStart (shd, strIdx, cursorIdx, leftStrings, leftLines, chr) else
else case stl of
(* strIdx is in tl *) stlhd :: stltl =>
(case (stl, ltl) of helpTillPrevChr
(stlhd :: stltl, ltlhd :: ltltl) => ( String.size stlhd - 1
let , stlhd
val strIdx = strIdx - String.size shd , absIdx - 1
val leftStrings = shd :: leftStrings , stltl
val leftLines = lhd :: leftLines , absIdx
in , findChr
fStart , absIdx
(shd, strIdx, cursorIdx, leftStrings, leftLines, chr) , absIdx
end , absIdx
| (_, _) => cursorIdx) )
end | [] => (* tl is empty; return 0 for lineGap start *) 0
| (_, _) => cursorIdx end)
end
fun tillPrevChr (lineGap, cursorIdx, chr) = val tillPrevChr = TillPrevChr.foldPrev
prevChr (lineGap, cursorIdx, chr, startTillPrevChr)
fun helpMatchPairNext fun helpMatchPairNext
(strPos, str, absIdx, stl, origIdx, openChr, openNum, closeChr, closeNum) = (strPos, str, absIdx, stl, origIdx, openChr, openNum, closeChr, closeNum) =