From ec4e3a8f0d95091f8f43c046e6e355060e84b274 Mon Sep 17 00:00:00 2001 From: Mateusz Kowalczyk Date: Fri, 24 Oct 2014 17:55:58 +0100 Subject: [PATCH] Fix eolPoint' manouvers Fixes #667 and probably #662 (needs vimtests) and maybe even more. --- CHANGELOG | 1 + yi/src/library/Yi/Buffer/Implementation.hs | 29 +++++++++++++--------- yi/src/library/Yi/Buffer/TextUnit.hs | 6 ++--- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b3289514d..ce14e4012 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ * Try to guess and preserve the file encoding (#638) * Restore cursor position better after deleteTrailingSpacesB (#666) + * Fix eolPoint' when on last, empty line (#667) 0.10.0 ------ diff --git a/yi/src/library/Yi/Buffer/Implementation.hs b/yi/src/library/Yi/Buffer/Implementation.hs index 4704a241d..08199ea50 100644 --- a/yi/src/library/Yi/Buffer/Implementation.hs +++ b/yi/src/library/Yi/Buffer/Implementation.hs @@ -39,7 +39,6 @@ module Yi.Buffer.Implementation , newBI , solPoint , solPoint' - , eolPoint , eolPoint' , charsFromSolBI , regexRegionBI @@ -347,23 +346,29 @@ solPoint line fb = Point $ R.length $ fst $ R.splitAtLine (line - 1) (mem fb) -- | Point that's at EOL. Notably, this puts you right before the -- newline character if one exists, and right at the end of the text -- if one does not. -eolPoint :: Int -- ^ Line for which to grab EOL for - -> BufferImpl syntax -> Point -eolPoint l = Point . checkEol . fst . R.splitAtLine l . mem +eolPoint :: Point + -- ^ Point from which we take the line to find the EOL of + -> BufferImpl syntax + -> Point +eolPoint' p@(Point ofs) fb = Point . checkEol . fst . R.splitAtLine ln $ mem fb where - -- In case we're somewhere without trailing newline, we need to stay where we are - checkEol t = let l' = R.length t in case R.last t of - Just '\n' -> l' - 1 - _ -> l' + ln = lineAt p fb + -- In case we're somewhere without trailing newline, we need to + -- stay where we are + checkEol t = + let l' = R.length t + in case R.last t of + -- We're looking at EOL and we weren't asking for EOL past + -- this point, so back up one for good visual effect + Just '\n' | l' > ofs -> l' - 1 + -- We asked for EOL past the last newline so just go to the + -- very end of content + _ -> l' -- | Get begining of the line relatively to @point@. solPoint' :: Point -> BufferImpl syntax -> Point solPoint' point fb = solPoint (lineAt point fb) fb --- | Get end of the line relative to the point. -eolPoint' :: Point -> BufferImpl s -> Point -eolPoint' p fb = eolPoint (lineAt p fb) fb - charsFromSolBI :: Point -> BufferImpl syntax -> YiString charsFromSolBI pnt fb = nelemsBI (fromIntegral $ pnt - sol) sol fb where sol = solPoint' pnt fb diff --git a/yi/src/library/Yi/Buffer/TextUnit.hs b/yi/src/library/Yi/Buffer/TextUnit.hs index f500e5c4c..9672ab23e 100644 --- a/yi/src/library/Yi/Buffer/TextUnit.hs +++ b/yi/src/library/Yi/Buffer/TextUnit.hs @@ -314,9 +314,9 @@ genMoveB Document _ Forward = moveTo =<< sizeB genMoveB Document _ Backward = moveTo 0 -- impossible to go outside beginning of doc. genMoveB Character _ Forward = rightB genMoveB Character _ Backward = leftB -genMoveB VLine _ Forward = - do ofs <- lineMoveRel 1 - when (ofs < 1) (maybeMoveB Line Forward) +genMoveB VLine _ Forward = do + ofs <- lineMoveRel 1 + when (ofs < 1) (maybeMoveB Line Forward) genMoveB VLine _ Backward = lineUp genMoveB unit (boundDir, boundSide) moveDir = doUntilB_ (genAtBoundaryB unit boundDir boundSide) (moveB Character moveDir)