From 7d6d8f8c43dfdf2e56b0d0454f6e56df78cb4531 Mon Sep 17 00:00:00 2001 From: pdlla Date: Thu, 7 Dec 2023 19:58:40 -0800 Subject: [PATCH 1/3] fix and issue where the cursor tag is set incorrectly on an empty string in displayLinesWithAlignment --- src/Data/Text/Zipper.hs | 21 ++++++++++----------- test/Data/Text/ZipperSpec.hs | 12 ++++++++++++ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/Data/Text/Zipper.hs b/src/Data/Text/Zipper.hs index d97c602..969b542 100644 --- a/src/Data/Text/Zipper.hs +++ b/src/Data/Text/Zipper.hs @@ -404,9 +404,11 @@ wrapWithOffsetAndAlignment alignment maxWidth n txt = assert (n <= maxWidth) r w -- | converts deleted eol spaces into logical lines eolSpacesToLogicalLines :: [[WrappedLine]] -> [[(Text, Int)]] -eolSpacesToLogicalLines = fmap (fmap (\(WrappedLine a _ c) -> (a,c))) . ((L.groupBy (\(WrappedLine _ b _) _ -> not b)) =<<) +eolSpacesToLogicalLines = fmap (fmap (\(WrappedLine a _ c) -> (a,c))) . concatMap (L.groupBy (\(WrappedLine _ b _) _ -> not b)) + +offsetMapWithAlignmentInternal :: [[WrappedLine]] -> OffsetMapWithAlignment +offsetMapWithAlignmentInternal = offsetMapWithAlignment . eolSpacesToLogicalLines --- | Convert logical lines to a map of displayed rows of aligned text offsetMapWithAlignment :: [[(Text, Int)]] -- ^ The outer list represents logical lines, inner list represents wrapped lines -> OffsetMapWithAlignment @@ -423,9 +425,6 @@ offsetMapWithAlignment ts = evalState (offsetMap' ts) (0, 0) -- add additional offset to last line in wrapped lines (for newline char) return $ Map.adjust (\(align,_)->(align,o+1)) dl $ Map.unions maps --- | Convert logical lines to a map of displayed rows of aligned text -offsetMapWithAlignmentInternal :: [[WrappedLine]] -> OffsetMapWithAlignment -offsetMapWithAlignmentInternal = offsetMapWithAlignment . eolSpacesToLogicalLines -- | Given a width and a 'TextZipper', produce a list of display lines -- (i.e., lines of wrapped text) with special attributes applied to @@ -469,7 +468,7 @@ displayLinesWithAlignment alignment width tag cursorTag (TextZipper lb b a la) = -- map to spans and highlight the cursor -- accumulator type (accumulated text length, Either (current y position) (cursor y and x position)) --mapaccumlfn :: (Int, Either Int (Int, Int)) -> WrappedLine -> ((Int, Either Int (Int, Int)), [Span tag]) - mapaccumlfn (acclength, ecpos') (WrappedLine t dwseol xoff) = r where + mapaccumlfn (acclength, ecpos) (WrappedLine t dwseol xoff) = r where tlength = T.length t -- how many words we've gone through nextacclength = acclength + tlength + if dwseol then 1 else 0 @@ -478,7 +477,7 @@ displayLinesWithAlignment alignment width tag cursorTag (TextZipper lb b a la) = charsbeforecursor = blength-acclength ctlength = textWidth $ T.take charsbeforecursor t cursorx = xoff + ctlength - nextecpos = case ecpos' of + nextecpos = case ecpos of Left y -> if cursoroncurspan then if ctlength == width -- cursor wraps to next line case @@ -496,15 +495,15 @@ displayLinesWithAlignment alignment width tag cursorTag (TextZipper lb b a la) = r = if cursoroncurspan then (nextacc, cursorspans) else (nextacc, [Span tag t]) - ((_, ecpos), curlinespans) = if T.null curlinetext + ((_, ecpos_out), curlinespans) = if T.null curlinetext -- manually handle empty case because mapaccumlfn doesn't handle it - then ((0, Right (0, alignmentOffset alignment width "")), [[Span tag ""]]) + then ((0, Right (0, alignmentOffset alignment width "")), [[Span cursorTag ""]]) else L.mapAccumL mapaccumlfn (0, Left 0) curwrappedlines - (cursorY', cursorX) = case ecpos of + (cursorY', cursorX) = case ecpos_out of Right (y,x) -> (y,x) -- if we never hit the cursor position, this means it's at the beginning of the next line - Left y -> (y+1, alignmentOffset alignment width "") + Left y -> (y+1, alignmentOffset alignment width "") cursorY = cursorY' + length spansBefore in DisplayLines diff --git a/test/Data/Text/ZipperSpec.hs b/test/Data/Text/ZipperSpec.hs index 0177c02..3bd3b9d 100644 --- a/test/Data/Text/ZipperSpec.hs +++ b/test/Data/Text/ZipperSpec.hs @@ -83,6 +83,8 @@ spec = dl1 = displayLinesWithAlignment TextAlignment_Right 10 () () (fromText "aoeu\n\n\naoeu") dl2 = displayLinesWithAlignment TextAlignment_Right 10 () () (fromText "\n\n\naoeu") dl3 = displayLinesWithAlignment TextAlignment_Right 10 () () (fromText "aoeu\n\n\n") + dl4 = displayLinesWithAlignment TextAlignment_Right 10 () () (empty) + insertcharnewlinesentence `shouldBe` fromText newlineSentence @@ -91,6 +93,16 @@ spec = _displayLines_spans dl1 `shouldBe` makespans [["aoeu"],[""],[""],["aoeu", ""]] _displayLines_spans dl2 `shouldBe` makespans [[""],[""],[""],["aoeu", ""]] _displayLines_spans dl3 `shouldBe` makespans [["aoeu"],[""],[""],[""]] + _displayLines_spans dl4 `shouldBe` makespans [[""]] + + + it "displayLinesWithAlignment - cursor tag" $ do + let + dl0 = displayLinesWithAlignment TextAlignment_Right 10 0 1 (fromText "abc") + dl1 = displayLinesWithAlignment TextAlignment_Right 10 0 1 empty + _displayLines_spans dl0 `shouldBe` [[Span 0 "abc", Span 1 ""]] + _displayLines_spans dl1 `shouldBe` [[Span 1 ""]] + From 420931c8247df0975b3326994ed887a7175fcffa Mon Sep 17 00:00:00 2001 From: pdlla Date: Thu, 7 Dec 2023 20:00:03 -0800 Subject: [PATCH 2/3] CL --- ChangeLog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index d6c3693..35c4f8c 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,9 @@ # Revision history for reflex-vty +## Unreleased + +* Fix an issue where the cursor tag is not used for an empty string in `displayLineWithAlignment` + ## 0.5.0.0 * *Breaking change*: From f07c3ece9dc41f4f8c31709d3db9079fdda525e1 Mon Sep 17 00:00:00 2001 From: pdlla Date: Thu, 7 Dec 2023 20:09:34 -0800 Subject: [PATCH 3/3] aoeu --- ChangeLog.md | 2 +- reflex-vty.cabal | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 61b9311..3861e15 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,6 +1,6 @@ # Revision history for reflex-vty -## Unreleased +## Unreleased 0.5.1.1 * Fix an issue where the cursor tag is not used for an empty string in `displayLineWithAlignment` diff --git a/reflex-vty.cabal b/reflex-vty.cabal index 841cb9c..8b941d5 100644 --- a/reflex-vty.cabal +++ b/reflex-vty.cabal @@ -1,5 +1,5 @@ name: reflex-vty -version: 0.5.1.0 +version: 0.5.1.1 synopsis: Reflex FRP host and widgets for VTY applications description: Build terminal applications using functional reactive programming (FRP) with Reflex FRP ().