diff --git a/fcore/cursor.sml b/fcore/cursor.sml index ee64ef8..bfd17a0 100644 --- a/fcore/cursor.sml +++ b/fcore/cursor.sml @@ -1,51 +1,58 @@ structure Cursor = struct - (* Prerequisite: lineGap is moved to requested idx first *) - fun viL (lineGap: LineGap.t, cursorIdx) = - let - val {rightStrings, idx = bufferIdx, ...} = lineGap - in - case rightStrings of - hd :: tl => - let - (* idx relative to this string *) - val strIdx = cursorIdx - bufferIdx - in - if strIdx < String.size hd - 2 then - (* increment if there is a character after where cursor is - * but first, check if we are in a \r\n pair; - * if we are, then increment cursor by 2 *) - if - String.size hd > strIdx + 2 - andalso String.sub (hd, strIdx + 1) = #"\r" - andalso String.sub (hd, strIdx + 2) = #"\n" - then - (* increment cursor by 2 if we are inside \r\n pair *) - cursorIdx + 2 + (* todo: viL does not handle \r\n pair right now + * but this is not a priority so it's okay *) + local + fun helpVilLf (hd, strIdx, bufferIdx, cursorIdx, tl) = + (* if we are in \n, + * move cursor to character after newline + * if possible *) + if strIdx < String.size hd - 3 then + (* we know it is safe to move cursorIdx by 2 + * if strIdx + 2 is before or at the end of the string. *) + cursorIdx + 2 + else + (* we have to check the tl to see if it is not empty + * so we know it is safe to move. *) + case tl of + _ :: _ => + (* not empty, so we can increment by 2 *) + cursorIdx + 2 + | [] => + (* empty, so return end of string which is \n *) + bufferIdx + String.size hd - 1 + in + (* Prerequisite: lineGap is moved to requested idx first + * todo: check if we are in a \r\n pair, but this is not a priority *) + fun viL (lineGap: LineGap.t, cursorIdx) = + let + val {rightStrings, idx = bufferIdx, ...} = lineGap + in + case rightStrings of + hd :: tl => + let + (* convert absolute cursorIdx to idx relative to hd string *) + val strIdx = cursorIdx - bufferIdx + in + if strIdx < String.size hd - 2 then + (case String.sub (hd, strIdx + 1) of + #"\n" => helpVilLf (hd, strIdx, bufferIdx, cursorIdx, tl) + | _ => cursorIdx + 1) else - (* inccrement cursor by 1 if we are not inside \r\n pair *) - cursorIdx + 1 - else - (case tl of - _ :: _ => - (* if there is another string after current head, we can increment cursorIdx - * however, first we need to check if next string is \r\n pair. *) - if - String.size hd > strIdx + 2 - andalso String.sub (hd, strIdx + 1) = #"\r" - andalso String.sub (hd, strIdx + 2) = #"\n" - then - (* increment cursor by 2 if we are inside \r\n pair *) - cursorIdx + 2 - else - (* inccrement cursor by 1 if we are not inside \r\n pair *) - cursorIdx + 1 - | _ => - (* if there is no string after current head, return original cursorIdx *) - cursorIdx) - end - | [] => - (* return original cursorIdx if there is nothing to the right *) - cursorIdx - end + (case tl of + tlhd :: tltl => + (* if there is another string after current head, we can increment cursorIdx + * however, first we need to check if next char is \n. *) + (case String.sub (tlhd, 0) of + #"\n" => helpVilLf (tlhd, 0, bufferIdx, cursorIdx, tltl) + | _ => cursorIdx + 1) + | _ => + (* if there is no string after current head, return original cursorIdx *) + cursorIdx) + end + | [] => + (* return original cursorIdx if there is nothing to the right *) + cursorIdx + end + end end diff --git a/fcore/text-builder.sml b/fcore/text-builder.sml index 88455d1..0b0389e 100644 --- a/fcore/text-builder.sml +++ b/fcore/text-builder.sml @@ -316,11 +316,25 @@ struct ) | #"\n" => if posY + ySpace < windowHeight then - buildTextStringWithinCursor - ( pos + 1, str, acc, startX, posY + ySpace, startX - , windowWidth, windowHeight, fWindowWidth, fWindowHeight - , r, g, b, tl, absIdx + 1, cursorPos, cursorAcc, hr, hg, hb - ) + if absIdx <> cursorPos then + (* not in cursor position, so iterate like normal *) + buildTextStringWithinCursor + ( pos + 1, str, acc, startX, posY + ySpace, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, absIdx + 1, cursorPos, cursorAcc, hr, hg, hb + ) + else + (* in cursor position, so build cursorAcc + * and call AfterCursor function *) + let + val cursorAcc = buildCursor (posX, posY, fWindowWidth, fWindowHeight, r, g ,b) + in + buildTextStringAfterCursor + ( pos + 1, str, acc, startX, posY + ySpace, startX + , windowWidth, windowHeight, fWindowWidth, fWindowHeight + , r, g, b, tl, cursorAcc + ) + end else accToDrawMsg (acc, cursorAcc) | #"\r" => diff --git a/shf b/shf index 635e6f5..b31941f 100755 Binary files a/shf and b/shf differ diff --git a/temp.txt b/temp.txt index 31fbbaa..49dd153 100644 --- a/temp.txt +++ b/temp.txt @@ -1,6 +1,8 @@ signature TEXT_BUILDER = + sig (* Prerequisite: LineGap is moved to requested line first. *) val build: int * int * LineGap.t * int * int -> MailboxType.t list enda +