From c2ea6e5e04685049265bd009fa9cd3d9600c9fb6 Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Fri, 25 Oct 2024 15:47:39 +0100 Subject: [PATCH] just formatting cursor.sml --- fcore/cursor.sml | 847 ++++++++++++++++++++++------------------------- 1 file changed, 398 insertions(+), 449 deletions(-) diff --git a/fcore/cursor.sml b/fcore/cursor.sml index c274ec6..58b2407 100644 --- a/fcore/cursor.sml +++ b/fcore/cursor.sml @@ -4,16 +4,12 @@ struct if strPos < 0 then case (strTl, lineTl) of (shd :: stl, lhd :: ltl) => - helpVi0 - (String.size shd - 1, shd, absIdx, stl, ltl) - | (_, _) => - 0 + helpVi0 (String.size shd - 1, shd, absIdx, stl, ltl) + | (_, _) => 0 else case String.sub (str, strPos) of - #"\n" => - absIdx + 1 - | _ => - helpVi0 (strPos - 1, str, absIdx - 1, strTl, lineTl) + #"\n" => absIdx + 1 + | _ => helpVi0 (strPos - 1, str, absIdx - 1, strTl, lineTl) fun vi0 (lineGap: LineGap.t, cursorIdx) = let @@ -32,13 +28,10 @@ struct if String.sub (strHd, strIdx) = #"\n" then (* don't need to do anything if we are already at newline; * just return current cursorIdx *) - cursorIdx + cursorIdx else (* not at newline so start iterating *) - helpVi0 - ( strIdx - 1, strHd, cursorIdx - 1 - , strTl, lnTl - ) + helpVi0 (strIdx - 1, strHd, cursorIdx - 1, strTl, lnTl) else (* strIdx must be in the strTl *) (case (strTl, lnTl) of @@ -52,8 +45,11 @@ struct else (* not in linebreak *) helpVi0 - ( strIdx - 1, nestStrHd, cursorIdx - 1 - , strHd :: leftStrings, lnHd :: leftLines + ( strIdx - 1 + , nestStrHd + , cursorIdx - 1 + , strHd :: leftStrings + , lnHd :: leftLines ) end | (_, _) => cursorIdx) @@ -66,17 +62,12 @@ struct fun helpViDlr (strPos, str, absIdx, strTl, lineTl) = if strPos = String.size str then case (strTl, lineTl) of - (shd :: stl, lhd :: ltl) => - helpViDlr - (0, shd, absIdx, stl, ltl) - | (_, _) => - absIdx - 1 + (shd :: stl, lhd :: ltl) => helpViDlr (0, shd, absIdx, stl, ltl) + | (_, _) => absIdx - 1 else case String.sub (str, strPos) of - #"\n" => - absIdx - 1 - | _ => - helpViDlr (strPos + 1, str, absIdx + 1, strTl, lineTl) + #"\n" => absIdx - 1 + | _ => helpViDlr (strPos + 1, str, absIdx + 1, strTl, lineTl) fun viDlr (lineGap: LineGap.t, cursorIdx) = let @@ -93,28 +84,25 @@ struct if strIdx < String.size strHd then if String.sub (strHd, strIdx) <> #"\n" then (* not in double linebreak *) - helpViDlr - (strIdx + 1, strHd, cursorIdx + 1, strTl, lnTl) - else - (* check if we are in double linebreak *) + helpViDlr (strIdx + 1, strHd, cursorIdx + 1, strTl, lnTl) + else + (* check if we are in double linebreak *) if strIdx - 1 >= 0 then if String.sub (strHd, strIdx - 1) = #"\n" then (* we are in double linebreak, so do nothing *) cursorIdx else (* not in double linebreak, so iterate *) - helpViDlr - (strIdx + 1, strHd, cursorIdx + 1 , strTl, lnTl) + helpViDlr (strIdx + 1, strHd, cursorIdx + 1, strTl, lnTl) else (* check if double linebreak in strTl *) (case strTl of - nestStrHd :: _ => - if String.sub (nestStrHd, 0) = #"\n" then - cursorIdx - else - helpViDlr - (strIdx + 1, strHd, cursorIdx + 1, strTl, lnTl) - | [] => cursorIdx) + nestStrHd :: _ => + if String.sub (nestStrHd, 0) = #"\n" then + cursorIdx + else + helpViDlr (strIdx + 1, strHd, cursorIdx + 1, strTl, lnTl) + | [] => cursorIdx) else (* strIdx must be in the strTl *) (case (strTl, lnTl) of @@ -122,8 +110,13 @@ struct let val strIdx = strIdx - String.size strHd in - helpViDlr - (strIdx + 1, nestStrHd, cursorIdx + 1, nestStrTl, nestLnTl) + helpViDlr + ( strIdx + 1 + , nestStrHd + , cursorIdx + 1 + , nestStrTl + , nestLnTl + ) end | (_, _) => cursorIdx) end @@ -246,7 +239,8 @@ struct (* no chars before this idx; have to check leftStrings *) (case leftStrings of lHd :: lTl => - (* if there is another string after current head, we can increment cursorIdx + (* if there is another string after current head, + * we can increment cursorIdx * however, first we need to check if next char is \n. *) let val lastChr = String.sub (lHd, String.size lHd - 1) @@ -429,15 +423,15 @@ struct , lineColumn, preferredColumn, hasPassedLine , strTl, lineTl ) = - if strPos = String.size str then - case (strTl, lineTl) of - (shd :: stl, lhd :: ltl) => - (* todo: possibly check if we have passed line, - * and if so, if there are any line breaks in the lineHd - * which we could use to skip searching part of the string. - * However, this will likely have worse cache locality - * as we switch to searching in string to searcing in line vector - * so perhaps not. *) + if strPos = String.size str then + case (strTl, lineTl) of + (shd :: stl, lhd :: ltl) => + (* todo: possibly check if we have passed line, + * and if so, if there are any line breaks in the lineHd + * which we could use to skip searching part of the string. + * However, this will likely have worse cache locality + * as we switch to searching in string to searcing in line vector + * so perhaps not. *) helpViJ ( 0, shd, absIdx , lineColumn, preferredColumn, hasPassedLine @@ -446,77 +440,77 @@ struct | (_, _) => (* empty, so return end of previous string *) absIdx - 1 - else - case String.sub (str, strPos) of - #"\n" => - if - hasPassedLine - then - (* reached end of line twice, - * but line has fewer chars than preferredColumn - * note: if in double \n\n linebreak, - * then return absIdx of second linebreak. *) - if strPos = String.size str - 1 then - if String.sub (str, strPos + 1) = #"\n" then - (* we are in double linebreak *) - absIdx + 1 - else - (* not in double linebreak *) - absIdx - 1 + else + case String.sub (str, strPos) of + #"\n" => + if + hasPassedLine + then + (* reached end of line twice, + * but line has fewer chars than preferredColumn + * note: if in double \n\n linebreak, + * then return absIdx of second linebreak. *) + if strPos = String.size str - 1 then + if String.sub (str, strPos + 1) = #"\n" then + (* we are in double linebreak *) + absIdx + 1 else - (* this is last chr of string; must check string's tl next *) - (case strTl of - hd :: tl => - if String.sub (hd, 0) = #"\n" then - (* in double linebreak *) - absIdx + 1 - else - (* not in double linebreak *) - absIdx - 1 - | [] => - (* no more strings so return last idx *) - absIdx - 1) - else - (* reached end of line once; - * have to check if this is a double linebreak, - * and return idx of second linebreak if so *) - if strPos < String.size str - 1 then - if String.sub (str, strPos + 1) = #"\n" then - absIdx + 1 - else - helpViJ - ( strPos + 1, str, absIdx + 1 - , 0, preferredColumn, true - , strTl, lineTl - ) - else - (* this is last chr of string; must check string's tl next *) - (case strTl of - hd :: tl => - if String.sub (hd, 0) = #"\n" then - (* in double linebreak *) - absIdx + 1 - else - (* not in double linebreak *) - helpViJ - ( strPos + 1, str, absIdx + 1 - , 0, preferredColumn, true - , strTl, lineTl - ) - | [] => - (* no more strings so return last idx *) - absIdx) - | _ => - if lineColumn = preferredColumn andalso hasPassedLine then - (* we're at the preferredColumn so return absIdx *) - absIdx + (* not in double linebreak *) + absIdx - 1 else - (* we're not in the preferred column, so keep iterating *) - helpViJ - ( strPos + 1, str, absIdx + 1 - , lineColumn + 1, preferredColumn, hasPassedLine - , strTl, lineTl - ) + (* this is last chr of string; must check string's tl next *) + (case strTl of + hd :: tl => + if String.sub (hd, 0) = #"\n" then + (* in double linebreak *) + absIdx + 1 + else + (* not in double linebreak *) + absIdx - 1 + | [] => + (* no more strings so return last idx *) + absIdx - 1) + else + (* reached end of line once; + * have to check if this is a double linebreak, + * and return idx of second linebreak if so *) + if strPos < String.size str - 1 then + if String.sub (str, strPos + 1) = #"\n" then + absIdx + 1 + else + helpViJ + ( strPos + 1, str, absIdx + 1 + , 0, preferredColumn, true + , strTl, lineTl + ) + else + (* this is last chr of string; must check string's tl next *) + (case strTl of + hd :: tl => + if String.sub (hd, 0) = #"\n" then + (* in double linebreak *) + absIdx + 1 + else + (* not in double linebreak *) + helpViJ + ( strPos + 1, str, absIdx + 1 + , 0, preferredColumn, true + , strTl, lineTl + ) + | [] => + (* no more strings so return last idx *) + absIdx) + | _ => + if lineColumn = preferredColumn andalso hasPassedLine then + (* we're at the preferredColumn so return absIdx *) + absIdx + else + (* we're not in the preferred column, so keep iterating *) + helpViJ + ( strPos + 1, str, absIdx + 1 + , lineColumn + 1, preferredColumn, hasPassedLine + , strTl, lineTl + ) fun viJ (lineGap: LineGap.t, cursorIdx) = let @@ -575,7 +569,7 @@ struct helpViJ ( strIdx + 1, nestStrHd, cursorIdx + 1 , lineColumn, lineColumn, false - , nestStrTl, nestStrTl + , nestStrTl, nestLnTl ) end end @@ -591,107 +585,105 @@ struct , lineColumn, preferredColumn, hasPassedLine , strTl, lineHd, lineTl ) = - if strPos < 0 then - case (strTl, lineTl) of - (shd :: stl, lhd :: ltl) => - helpViK - ( String.size shd - 1, shd, absIdx - , lineColumn, preferredColumn, hasPassedLine - , stl, lhd, ltl - ) - | (_, _) => - (* empty, so return start of previous string *) - absIdx + 1 - else - case String.sub (str, strPos) of - #"\n" => - if - hasPassedLine - then - (* reached end of line twice, - * but line has fewer chars than preferredColumn - * note: if in double \n\n linebreak, - * then return absIdx of second linebreak. *) - if strPos > 0 then - (* check for double linebreak in string *) - if String.sub (str, strPos - 1) = #"\n" then - (* in double linebreak *) - absIdx - else - (* not in double linebreak *) - absIdx - 1 + if strPos < 0 then + case (strTl, lineTl) of + (shd :: stl, lhd :: ltl) => + helpViK + ( String.size shd - 1, shd, absIdx + , lineColumn, preferredColumn, hasPassedLine + , stl, lhd, ltl + ) + | (_, _) => + (* empty, so return start of previous string *) + absIdx + 1 + else + case String.sub (str, strPos) of + #"\n" => + if hasPassedLine then + (* reached end of line twice, + * but line has fewer chars than preferredColumn + * note: if in double \n\n linebreak, + * then return absIdx of second linebreak. *) + if strPos > 0 then + (* check for double linebreak in string *) + if String.sub (str, strPos - 1) = #"\n" then + (* in double linebreak *) + absIdx else - (* check for double linebreak in tl *) - (case strTl of - hd :: _ => - if String.sub (hd, String.size hd - 1) = #"\n" then - (* in double linebreak *) - absIdx - else - (* not in double linebreak *) - absIdx - 1 - | [] => - (* tl is empty, so return start *) - 0) - else - (* reached start of line once; - * have to check if this is a double linebreak, - * and return idx of second linebreak if so *) - if strPos > 0 then - if String.sub (str, strPos - 1) = #"\n" then - absIdx - else - let - (* have to calculate column of current line - * so we know which line to stop searching at *) - val lineColumn = - helpGetCursorColumnBranch - (strPos - 1, str, lineHd, strTl, lineTl) - in - helpViK - ( strPos - 1, str, absIdx - 1 - , lineColumn, preferredColumn, true - , strTl, lineHd, lineTl - ) - end - else - (* this is first chr of string; must check string's tl next *) - (case strTl of - hd :: tl => - if String.sub (hd, String.size hd - 1) = #"\n" then - (* in double linebreak *) - absIdx - else - (* not in double linebreak *) - let - val lineColumn = - helpGetCursorColumnBranch - (strPos - 1, str, lineHd, strTl, lineTl) - in - helpViK - ( strPos - 1, str, absIdx - 1 - , lineColumn, preferredColumn, true - , strTl, lineHd, lineTl - ) - end - | [] => - (* no more strings so return last idx *) - absIdx) - | _ => - if lineColumn <= preferredColumn andalso hasPassedLine then - (* We're at or before the preferredColumn so return absIdx - * context: current line may have fewer columns - * than our preferred column value. - * If this is the case, we want to check - * "is lineColumn equal to or before preferredColumn?". *) - absIdx + (* not in double linebreak *) + absIdx - 1 else - (* we're not in the preferred column, so keep iterating *) - helpViK - ( strPos - 1, str, absIdx - 1 - , lineColumn - 1, preferredColumn, hasPassedLine - , strTl, lineHd, lineTl - ) + (* check for double linebreak in tl *) + (case strTl of + hd :: _ => + if String.sub (hd, String.size hd - 1) = #"\n" then + (* in double linebreak *) + absIdx + else + (* not in double linebreak *) + absIdx - 1 + | [] => + (* tl is empty, so return start *) + 0) + else + (* reached start of line once; + * have to check if this is a double linebreak, + * and return idx of second linebreak if so *) + if strPos > 0 then + if String.sub (str, strPos - 1) = #"\n" then + absIdx + else + let + (* have to calculate column of current line + * so we know which line to stop searching at *) + val lineColumn = + helpGetCursorColumnBranch + (strPos - 1, str, lineHd, strTl, lineTl) + in + helpViK + ( strPos - 1, str, absIdx - 1 + , lineColumn, preferredColumn, true + , strTl, lineHd, lineTl + ) + end + else + (* this is first chr of string; must check string's tl next *) + (case strTl of + hd :: tl => + if String.sub (hd, String.size hd - 1) = #"\n" then + (* in double linebreak *) + absIdx + else + (* not in double linebreak *) + let + val lineColumn = + helpGetCursorColumnBranch + (strPos - 1, str, lineHd, strTl, lineTl) + in + helpViK + ( strPos - 1, str, absIdx - 1 + , lineColumn, preferredColumn, true + , strTl, lineHd, lineTl + ) + end + | [] => + (* no more strings so return last idx *) + absIdx) + | _ => + if lineColumn <= preferredColumn andalso hasPassedLine then + (* We're at or before the preferredColumn so return absIdx + * context: current line may have fewer columns + * than our preferred column value. + * If this is the case, we want to check + * "is lineColumn equal to or before preferredColumn?". *) + absIdx + else + (* we're not in the preferred column, so keep iterating *) + helpViK + ( strPos - 1, str, absIdx - 1 + , lineColumn - 1, preferredColumn, hasPassedLine + , strTl, lineHd, lineTl + ) fun viK (lineGap: LineGap.t, cursorIdx) = let @@ -712,11 +704,11 @@ struct if strIdx > 0 then if String.sub (strHd, strIdx - 1) = #"\n" then (* if in double linebreak *) - helpVi0 + helpVi0 (strIdx - 2, strHd, cursorIdx - 2, leftStrings, leftLines) else (* not in double linebreak *) - helpVi0 + helpVi0 (strIdx - 1, strHd, cursorIdx - 1, leftStrings, leftLines) else (* check leftStrings to see if we are in a double linebreak *) @@ -724,16 +716,21 @@ struct (lStrHd :: lStrTl, lLnHd :: lLnTl) => if String.sub (lStrHd, String.size lStrHd - 1) = #"\n" then (* in double linebreak *) - helpVi0 - (String.size lStrHd - 2, lStrHd, cursorIdx - 2, lStrTl, lLnTl) + helpVi0 + ( String.size lStrHd - 2, lStrHd, cursorIdx - 2 + , lStrTl, lLnTl + ) else (* in single linebreak *) - helpVi0 - (strIdx - 1, strHd, cursorIdx - 1, leftStrings, leftLines) + helpVi0 + ( strIdx - 1, strHd, cursorIdx - 1 + , leftStrings, leftLines + ) | (_, _) => helpViK ( strIdx - 1, strHd, cursorIdx - 1 - , 0, 0, true, leftStrings, lnHd, leftLines + , 0, 0, true + , leftStrings, lnHd, leftLines )) else (* not at newline @@ -763,33 +760,31 @@ struct val leftStrings = strHd :: leftStrings val leftLines = lnHd :: leftLines in - helpVi0 + helpVi0 ( strIdx - 2, nestStrHd, cursorIdx - 2 - , leftStrings, leftLines + , leftStrings, leftLines ) end else (* is in single linebreak *) - helpVi0 + helpVi0 ( strIdx - 1, nestStrHd, cursorIdx - 1 - , leftStrings, leftLines + , leftStrings, leftLines ) - else - (* must check strHd for second linebreak *) - if - String.sub (strHd, String.size strHd - 1) = #"\n" - then + else + (* must check strHd for second linebreak *) + if String.sub (strHd, String.size strHd - 1) = #"\n" then (* is in double linebreak *) helpVi0 ( String.size strHd - 2, nestStrHd, cursorIdx - 2 - , leftStrings, leftLines - ) - else - (* is in single linebreak *) - helpVi0 - ( String.size strHd - 1, nestStrHd, cursorIdx - 1 - , leftStrings, leftLines + , leftStrings, leftLines ) + else + (* is in single linebreak *) + helpVi0 + ( String.size strHd - 1, nestStrHd, cursorIdx - 1 + , leftStrings, leftLines + ) else (* not in linebreak *) let @@ -798,7 +793,9 @@ struct helpViK ( strIdx - 1, nestStrHd, cursorIdx - 1 , lineColumn, lineColumn, false - , strHd :: leftStrings, nestLnHd, lnHd :: leftLines + , strHd :: leftStrings + , nestLnHd + , lnHd :: leftLines ) end end @@ -811,36 +808,25 @@ struct fun isNextChrSpace (strPos, str, strTl) = if strPos + 1 < String.size str then - let - val chr = String.sub (str, strPos + 1) - in - Char.isSpace chr + let val chr = String.sub (str, strPos + 1) + in Char.isSpace chr end else case strTl of - hd :: _ => - let - val chr = String.sub (hd, 0) - in - Char.isSpace chr - end + hd :: _ => let val chr = String.sub (hd, 0) in Char.isSpace chr end | [] => false fun notIsNextChrSpace (strPos, str, strTl) = - let - val isSpace = isNextChrSpace (strPos, str, strTl) - in - not isSpace + let val isSpace = isNextChrSpace (strPos, str, strTl) + in not isSpace end fun isNextChrNonBlank (strPos, str, strTl) = if strPos + 1 < String.size str then let val chr = String.sub (str, strPos + 1) - val isNotBlank = - Char.isSpace chr - orelse Char.isAlphaNum chr - orelse chr = #"_" + val isNotBlank = + Char.isSpace chr orelse Char.isAlphaNum chr orelse chr = #"_" in not isNotBlank end @@ -850,9 +836,7 @@ struct let val chr = String.sub (hd, 0) val isNotBlank = - Char.isSpace chr - orelse Char.isAlphaNum chr - orelse chr = #"_" + Char.isSpace chr orelse Char.isAlphaNum chr orelse chr = #"_" in not isNotBlank end @@ -860,59 +844,45 @@ struct fun isNextChrAlphaNum (strPos, str, stl) = if strPos + 1 < String.size str then - let - val chr = String.sub (str, strPos + 1) - in - Char.isAlphaNum chr orelse chr = #"_" + let val chr = String.sub (str, strPos + 1) + in Char.isAlphaNum chr orelse chr = #"_" end else case stl of hd :: _ => - let - val chr = String.sub (str, 0) - in - Char.isAlphaNum chr orelse chr = #"_" + let val chr = String.sub (str, 0) + in Char.isAlphaNum chr orelse chr = #"_" end | [] => false fun isPrevChrSpace (strPos, str, strTl) = if strPos > 0 then - let - val prevChr = String.sub (str, strPos - 1) - in - Char.isSpace prevChr + let val prevChr = String.sub (str, strPos - 1) + in Char.isSpace prevChr end else case strTl of hd :: _ => - let - val prevChr = String.sub (hd, String.size hd - 1) - in - Char.isSpace prevChr + let val prevChr = String.sub (hd, String.size hd - 1) + in Char.isSpace prevChr end | [] => false fun notIsPrevChrSpace (strPos, str, strTl) = - let - val isSpace = isPrevChrSpace (strPos, str, strTl) - in - not isSpace + let val isSpace = isPrevChrSpace (strPos, str, strTl) + in not isSpace end fun isPrevChrAlphaNum (strPos, str, strTl) = if strPos > 0 then - let - val chr = String.sub (str, strPos - 1) - in - Char.isAlphaNum chr orelse chr = #"_" + let val chr = String.sub (str, strPos - 1) + in Char.isAlphaNum chr orelse chr = #"_" end else case strTl of hd :: _ => - let - val chr = String.sub (hd, String.size hd - 1) - in - Char.isAlphaNum chr orelse chr = #"_" + let val chr = String.sub (hd, String.size hd - 1) + in Char.isAlphaNum chr orelse chr = #"_" end | [] => false @@ -920,10 +890,8 @@ struct if strPos > 0 then let val chr = String.sub (str, strPos - 1) - val isNotBlank = - Char.isSpace chr - orelse Char.isAlphaNum chr - orelse chr = #"_" + val isNotBlank = + Char.isSpace chr orelse Char.isAlphaNum chr orelse chr = #"_" in not isNotBlank end @@ -932,19 +900,17 @@ struct hd :: _ => let val chr = String.sub (hd, String.size hd - 1) - val isNotBlank = - Char.isSpace chr - orelse Char.isAlphaNum chr - orelse chr = #"_" + val isNotBlank = + Char.isSpace chr orelse Char.isAlphaNum chr orelse chr = #"_" in not isNotBlank end | [] => false - fun helpNextWord (strPos, str, absIdx , strTl, lineTl) = + fun helpNextWord (strPos, str, absIdx, strTl, lineTl) = if strPos = String.size str then case (strTl, lineTl) of - (shd :: stl, lhd :: ltl) => + (shd :: stl, lhd :: ltl) => helpNextWord (0, shd, absIdx, stl, ltl) | (_, _) => (* reached end of lineGap; @@ -955,117 +921,28 @@ struct val chr = String.sub (str, strPos) in if Char.isAlphaNum chr orelse chr = #"_" then - if isNextChrNonBlank (strPos, str, strTl) then - absIdx + 1 - else - helpNextWord - (strPos + 1, str, absIdx + 1, strTl, lineTl) + if isNextChrNonBlank (strPos, str, strTl) then absIdx + 1 + else helpNextWord (strPos + 1, str, absIdx + 1, strTl, lineTl) else if Char.isSpace chr then if notIsNextChrSpace (strPos, str, strTl) then absIdx + 1 else (* nothing to do on space, except keep iterating *) - helpNextWord - (strPos + 1, str, absIdx + 1, strTl, lineTl) - else - (* chr is NON_BLANK. *) + helpNextWord (strPos + 1, str, absIdx + 1, strTl, lineTl) + else + (* chr is NON_BLANK. *) if isNextChrAlphaNum (strPos, str, strTl) then - absIdx + 1 - else - helpNextWord - (strPos + 1, str, absIdx + 1, strTl, lineTl) + absIdx + 1 + else + helpNextWord (strPos + 1, str, absIdx + 1, strTl, lineTl) end fun startNextWord (shd, strIdx, absIdx, stl, ltl) = - helpNextWord - (strIdx, shd, absIdx, stl, ltl) + helpNextWord (strIdx, shd, absIdx, stl, ltl) fun nextWord (lineGap: LineGap.t, cursorIdx) = let val {rightStrings, rightLines, idx = bufferIdx, ...} = lineGap - in - case (rightStrings, rightLines) of - (shd :: stl, lhd :: ltl) => - let - (* convert absolute cursorIdx to idx relative to hd string *) - val strIdx = cursorIdx - bufferIdx - in - if strIdx < String.size shd then - (* strIdx is in this string *) - startNextWord (shd, strIdx, cursorIdx, stl, ltl) - else - (* strIdx is in tl *) - (case (stl, ltl) of - (stlhd :: stltl, ltlhd :: ltltl) => - let - val strIdx = strIdx - String.size shd - in - startNextWord - (stlhd, strIdx, cursorIdx, stltl, ltltl) - end - | (_, _) => cursorIdx) - end - | (_, _) => cursorIdx - end - - fun helpPrevWord (strPos, str, absIdx, strTl, lineTl) = - if strPos < 0 then - case (strTl, lineTl) of - (shd :: stl, lhd :: ltl) => - helpPrevWord - (String.size shd - 1, shd, absIdx, stl, ltl) - | (_, _) => - (* reached start of lineGap; - * return 0 which is start idx *) - 0 - else - let - val chr = String.sub (str, strPos) - in - if Char.isAlphaNum chr orelse chr = #"_" then - if isPrevChrSpace (strPos, str, strTl) - orelse isPrevChrNonBlank (strPos, str, strTl) then - absIdx - else - helpPrevWord - (strPos - 1, str, absIdx - 1, strTl, lineTl) - else if Char.isSpace chr then - helpPrevWord - (strPos - 1, str, absIdx - 1, strTl, lineTl) - else - (* is NON_BLANK *) - if isPrevChrSpace (strPos, str, strTl) - orelse isPrevChrAlphaNum (strPos, str, strTl) then - absIdx - else - helpPrevWord - (strPos - 1, str, absIdx - 1, strTl, lineTl) - end - - fun startPrevWord (shd, strIdx, absIdx, stl, ltl) = - (* we want to start iterating from previous character - * and ignore the character the cursor is at - * so check previous character *) - if strIdx > 0 then - helpPrevWord - (strIdx - 1, shd, absIdx - 1, stl, ltl) - else - case (stl, ltl) of - (stlhd::stltl, ltlhd::ltltl) => - let - val prevIdx = String.size stlhd - 1 - in - helpPrevWord - (prevIdx, stlhd, absIdx - 1, stltl, ltltl) - end - | (_, _) => - (* tl is empty; just return idx 0 *) - 0 - - (* equivalent of vi's `b` command *) - fun prevWord (lineGap: LineGap.t, cursorIdx) = - let - val {rightStrings, rightLines, leftStrings, leftLines, idx = bufferIdx, ...} = lineGap in case (rightStrings, rightLines) of (shd :: stl, lhd :: ltl) => @@ -1075,21 +952,98 @@ struct in if strIdx < String.size shd then (* strIdx is in this string *) - startPrevWord - (shd, strIdx, cursorIdx, leftStrings, leftLines) + startNextWord (shd, strIdx, cursorIdx, stl, ltl) else (* strIdx is in tl *) (case (stl, ltl) of - (stlhd :: stltl, ltlhd :: ltltl) => - let - val strIdx = strIdx - String.size shd - val leftStrings = shd :: leftStrings - val leftLines = lhd :: leftLines - in - startPrevWord - (stlhd, strIdx, cursorIdx, leftStrings, leftLines) - end - | (_, _) => cursorIdx) + (stlhd :: stltl, ltlhd :: ltltl) => + let val strIdx = strIdx - String.size shd + in startNextWord (stlhd, strIdx, cursorIdx, stltl, ltltl) + end + | (_, _) => cursorIdx) + end + | (_, _) => cursorIdx + end + + fun helpPrevWord (strPos, str, absIdx, strTl, lineTl) = + if strPos < 0 then + case (strTl, lineTl) of + (shd :: stl, lhd :: ltl) => + helpPrevWord (String.size shd - 1, shd, absIdx, stl, ltl) + | (_, _) => + (* reached start of lineGap; + * return 0 which is start idx *) + 0 + else + let + val chr = String.sub (str, strPos) + in + if + Char.isAlphaNum chr orelse chr = #"_" + then + if isPrevChrSpace (strPos, str, strTl) + orelse isPrevChrNonBlank (strPos, str, strTl) + then absIdx + else helpPrevWord (strPos - 1, str, absIdx - 1, strTl, lineTl) + else if + Char.isSpace chr + then + helpPrevWord (strPos - 1, str, absIdx - 1, strTl, lineTl) + else + (* is NON_BLANK *) + if isPrevChrSpace (strPos, str, strTl) + orelse isPrevChrAlphaNum (strPos, str, strTl) + then + absIdx + else + helpPrevWord (strPos - 1, str, absIdx - 1, strTl, lineTl) + end + + fun startPrevWord (shd, strIdx, absIdx, stl, ltl) = + (* we want to start iterating from previous character + * and ignore the character the cursor is at + * so check previous character *) + if strIdx > 0 then + helpPrevWord (strIdx - 1, shd, absIdx - 1, stl, ltl) + else + case (stl, ltl) of + (stlhd :: stltl, ltlhd :: ltltl) => + let val prevIdx = String.size stlhd - 1 + in helpPrevWord (prevIdx, stlhd, absIdx - 1, stltl, ltltl) + end + | (_, _) => + (* tl is empty; just return idx 0 *) + 0 + + (* equivalent of vi's `b` command *) + fun prevWord (lineGap: LineGap.t, cursorIdx) = + let + val + {rightStrings, rightLines, leftStrings, leftLines, idx = bufferIdx, ...} = + lineGap + in + case (rightStrings, rightLines) of + (shd :: stl, lhd :: ltl) => + let + (* convert absolute cursorIdx to idx relative to hd string *) + val strIdx = cursorIdx - bufferIdx + in + if strIdx < String.size shd then + (* strIdx is in this string *) + startPrevWord (shd, strIdx, cursorIdx, leftStrings, leftLines) + else + (* strIdx is in tl *) + (case (stl, ltl) of + (stlhd :: stltl, ltlhd :: ltltl) => + let + val strIdx = strIdx - String.size shd + val leftStrings = shd :: leftStrings + val leftLines = lhd :: leftLines + in + startPrevWord + (stlhd, strIdx, cursorIdx, leftStrings, leftLines) + end + | (_, _) => cursorIdx) end | (_, _) => cursorIdx end @@ -1097,52 +1051,51 @@ struct fun helpEndOfWord (strPos, str, absIdx, stl, ltl) = if strPos = String.size str then case (stl, ltl) of - (shd :: stl, lhd :: ltl) => - helpEndOfWord (0, shd, absIdx, stl, ltl) - | (_, _) => - absIdx - 1 + (shd :: stl, lhd :: ltl) => helpEndOfWord (0, shd, absIdx, stl, ltl) + | (_, _) => absIdx - 1 else let val chr = String.sub (str, strPos) in - if Char.isAlphaNum chr orelse chr = #"_" then - if isNextChrSpace (strPos, str, stl) - orelse isNextChrNonBlank (strPos, str, stl) then + if + Char.isAlphaNum chr orelse chr = #"_" + then + if isNextChrSpace (strPos, str, stl) + orelse isNextChrNonBlank (strPos, str, stl) + then absIdx + else helpEndOfWord (strPos + 1, str, absIdx + 1, stl, ltl) + else if + Char.isSpace chr + then + helpEndOfWord (strPos + 1, str, absIdx + 1, stl, ltl) + else + (* is NON_BLANK *) + if isNextChrSpace (strPos, str, stl) + orelse isNextChrAlphaNum (strPos, str, stl) + then absIdx else - helpEndOfWord - (strPos + 1, str, absIdx + 1, stl, ltl) - else if Char.isSpace chr then - helpEndOfWord - (strPos + 1, str, absIdx + 1, stl, ltl) - else - (* is NON_BLANK *) - if isNextChrSpace (strPos, str, stl) - orelse isNextChrAlphaNum (strPos, str, stl) then - absIdx - else - helpEndOfWord - (strPos + 1, str, absIdx + 1, stl, ltl) + helpEndOfWord (strPos + 1, str, absIdx + 1, stl, ltl) end fun startEndOfWord (shd, strIdx, absIdx, stl, ltl) = (* we want to start iterating from next char after strIdx *) if strIdx - 1 < String.size shd then - helpEndOfWord - (strIdx + 1, shd, absIdx + 1, stl, ltl) + helpEndOfWord (strIdx + 1, shd, absIdx + 1, stl, ltl) else case (stl, ltl) of - (stlhd::stltl, ltlhd::ltltl) => - helpEndOfWord - (0, stlhd, absIdx + 1, stltl, ltltl) - | (_, _) => - (* tl is empty; just return absIdx *) + (stlhd :: stltl, ltlhd :: ltltl) => + helpEndOfWord (0, stlhd, absIdx + 1, stltl, ltltl) + | (_, _) => + (* tl is empty; just return absIdx *) absIdx (* equivalent of vi's `e` command *) fun endOfWord (lineGap: LineGap.t, cursorIdx) = let - val {rightStrings, rightLines, leftStrings, leftLines, idx = bufferIdx, ...} = lineGap + val + {rightStrings, rightLines, leftStrings, leftLines, idx = bufferIdx, ...} = + lineGap in case (rightStrings, rightLines) of (shd :: stl, lhd :: ltl) => @@ -1151,19 +1104,15 @@ struct in if strIdx < String.size shd then (* strIdx is in this string *) - startEndOfWord - (shd, strIdx, cursorIdx, rightStrings, rightLines) + startEndOfWord (shd, strIdx, cursorIdx, rightStrings, rightLines) else (* strIdx is in tl *) (case (stl, ltl) of - (stlhd :: stltl, ltlhd :: ltltl) => - let - val strIdx = strIdx - String.size shd - in - startEndOfWord - (stlhd, strIdx, cursorIdx, stltl, ltltl) - end - | (_, _) => cursorIdx) + (stlhd :: stltl, ltlhd :: ltltl) => + let val strIdx = strIdx - String.size shd + in startEndOfWord (stlhd, strIdx, cursorIdx, stltl, ltltl) + end + | (_, _) => cursorIdx) end | (_, _) => cursorIdx end