From b0a37c5c56bf1ddf2ebab7aba6cf15ea6e5bf7a9 Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Tue, 5 Nov 2024 13:14:52 +0000 Subject: [PATCH] new task: rewrite basic cursor.sml functions (h, j, k, l) to look for 'is line break preceded by non-line break?' rather than 'is there a double line break?' because the second question which is already implemented has buggy behaviour on triple line breaks, where cursor does not go to the place user expects. Currently, on Cursor.viL has been rewritten to match the first question. --- fcore/cursor.sml | 86 ++++++++++++++++++++---------------------------- temp.txt | 2 ++ 2 files changed, 38 insertions(+), 50 deletions(-) diff --git a/fcore/cursor.sml b/fcore/cursor.sml index 4b7eaeb..665e2f5 100644 --- a/fcore/cursor.sml +++ b/fcore/cursor.sml @@ -126,6 +126,30 @@ struct cursorIdx end + fun helpViL (strIdx, hd, cursorIdx, tl) = + if String.sub (hd, strIdx) = #"\n" then + (* if line break, go to next idx, no matter what chr is there *) + cursorIdx + 1 + else + if strIdx + 1 < String.size hd then + (* next chr is in hd *) + if String.sub (hd, strIdx + 1) = #"\n" then + (* if non-line break followed by line break, go to chr + 2 *) + cursorIdx + 2 + else + cursorIdx + 1 + else + (case tl of + tlhd :: _ => + if String.sub (tlhd, 0) = #"\n" then + (* non-line break followed by line break *) + cursorIdx + 2 + else + (* non-line break followed by non-line break *) + cursorIdx + | [] => + cursorIdx) + (* 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) = @@ -138,58 +162,20 @@ struct (* convert absolute cursorIdx to idx relative to hd string *) val strIdx = cursorIdx - bufferIdx in - if strIdx + 1 < String.size hd then - (* if there is at least one character after this idx *) - let - val nextChr = String.sub (hd, strIdx + 1) - in - (case nextChr of - #"\n" => - if strIdx + 2 < String.size hd then - (* if there are at least two chars after strIdx *) - cursorIdx + 2 - else - (* only one char after strIdx which is \n - * if there is a string at the tl, can increment by 2 *) - (case tl of - _ :: _ => cursorIdx + 2 - | [] => cursorIdx + 1) - | _ => cursorIdx + 1) - end + if strIdx < String.size hd then + (* strIdx is in hd *) + helpViL (strIdx, hd, cursorIdx, tl) else - (* no chars after this idx; have to check tl *) + (* strIdx is in tl *) (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. *) - let - val nextChr = String.sub (tlhd, 0) - in - (case nextChr of - #"\n" => - if String.size tlhd > 2 then - (* if there is at least one character after \n - * then increment cursorIdx by 2 *) - cursorIdx + 2 - else - (* this string only contains \n - * but there is a small possibility tltl - * contains another string. - * If it does, we can increment cursorIdx by 2, - * moving past newline. - * If not, increment cursorIdx by 1, - * landing on newline. *) - (case tltl of - _ :: _ => cursorIdx + 2 - | [] => cursorIdx + 1) - | _ => - (* next char is not newline, - * so we can just increment by 1 *) - cursorIdx + 1) - end - | [] => - (* if there is no string after current head, return original cursorIdx *) - cursorIdx) + tlhd :: tltl => + let + val strIdx = strIdx - String.size hd + in + helpViL (strIdx, tlhd, cursorIdx, tltl) + end + | [] => + cursorIdx) end | [] => (* return original cursorIdx if there is nothing to the right *) diff --git a/temp.txt b/temp.txt index cc99065..b2794ba 100644 --- a/temp.txt +++ b/temp.txt @@ -5,6 +5,8 @@ sig -> MailboxType.t list end + + structure TextBuilder :> TEXT_BUILDER = struct val xSpace = 13