3 patches for repository http://code.haskell.org/yi:
Thu Sep 16 00:17:42 CDT 2010 jw...@google.com * fix scrolling so it no longer snaps to the middle. scrolling off the top or bottom of the screen now just moves the viewport the minimum # of lines necessary to keep the point in sight. This is a much less disruptive scrolling experience. Fri Sep 17 23:20:58 CDT 2010 jw...@google.com * Scrolling - Store actual buffer lines displayed in a window. In order for scrolling to work we have to differentiate between the height of the window in display lines and the number of actual buffer lines displayed in a window. This patch stores that information in a window. Wed Oct 6 15:51:36 CDT 2010 jw...@google.com * add documentation and clean up Document the rational for this change as well as clean up some of the comments and todos.
-- Yi development mailing list yi-devel@googlegroups.com http://groups.google.com/group/yi-devel
New patches: [fix scrolling so it no longer snaps to the middle. jw...@google.com**20100916051742 Ignore-this: e80f848c675274b889129e20d4e9a5b6 scrolling off the top or bottom of the screen now just moves the viewport the minimum # of lines necessary to keep the point in sight. This is a much less disruptive scrolling experience. ] hunk ./src/Yi/Buffer/HighLevel.hs 376 p <- pointB moveTo $ max (regionStart r) $ min (regionEnd r) $ p - - - -- | return index of Sol on line @n@ above current line indexOfSolAbove :: Int -> BufferM Point indexOfSolAbove n = pointAt $ gotoLnFrom (negate n) hunk ./src/Yi/Buffer/HighLevel.hs 380 +data RelPosition = Above | Below | Within + deriving (Show) + +-- | return relative position of the point @p@ +-- relative to the region defined by the points @rs@ and @re@ +pointScreenRelPosition :: Point -> Point -> Point -> RelPosition +pointScreenRelPosition p rs re + | rs > p && p > re = Within + | p < rs = Above + | p > re = Below +pointScreenRelPosition _ _ _ = Within -- just to disable the non-exhaustive pattern match warning + -- | Move the visible region to include the point snapScreenB :: BufferM Bool snapScreenB = do hunk ./src/Yi/Buffer/HighLevel.hs 401 inWin <- pointInWindowB =<< pointB if inWin then return False else do h <- askWindow height - let gap = h `div` 2 + r <- winRegionB + p <- pointB + let gap = case pointScreenRelPosition p (regionStart r) (regionEnd r) of + Above -> 0 + Below -> h - 2 + Within -> 0 -- Impossible but handle it anyway i <- indexOfSolAbove gap f <- fromMark <$> askMarks setMarkPointB f i [Scrolling - Store actual buffer lines displayed in a window. jw...@google.com**20100918042058 Ignore-this: 832bc90350c820a84a56aab985a46f35 In order for scrolling to work we have to differentiate between the height of the window in display lines and the number of actual buffer lines displayed in a window. This patch stores that information in a window. ] hunk ./src/Yi/Buffer/HighLevel.hs 391 | p < rs = Above | p > re = Below pointScreenRelPosition _ _ _ = Within -- just to disable the non-exhaustive pattern match warning - + -- | Move the visible region to include the point snapScreenB :: BufferM Bool snapScreenB = do hunk ./src/Yi/Buffer/HighLevel.hs 400 if movePoint w then return False else do inWin <- pointInWindowB =<< pointB if inWin then return False else do - h <- askWindow height + h <- askWindow actualLines + --h <- askWindow height r <- winRegionB p <- pointB let gap = case pointScreenRelPosition p (regionStart r) (regionEnd r) of hunk ./src/Yi/Buffer/HighLevel.hs 406 Above -> 0 - Below -> h - 2 + Below -> h - 1 Within -> 0 -- Impossible but handle it anyway i <- indexOfSolAbove gap f <- fromMark <$> askMarks hunk ./src/Yi/Buffer/HighLevel.hs 439 pointInWindowB :: Point -> BufferM Bool pointInWindowB p = nearRegion p <$> winRegionB -- do w <- winRegionB; trace ("pointInWindowB " ++ show w ++ " p = " ++ show p) - + ----------------------------- -- Region-related operations hunk ./src/Yi/Editor.hs 447 then fail "no alternate buffer" else switchToBufferE $ lst!!n +-- | Create a new zero size window on a given buffer +newZeroSizeWindow ::Bool -> BufferRef -> WindowRef -> Window +newZeroSizeWindow mini bk ref = Window mini bk [] 0 emptyRegion ref 0 + -- | Create a new window onto the given buffer. newWindowE :: Bool -> BufferRef -> EditorM Window hunk ./src/Yi/Editor.hs 453 -newWindowE mini bk = Window mini bk [] 0 emptyRegion <$> newRef +newWindowE mini bk = newZeroSizeWindow mini bk <$> newRef -- | Attach the specified buffer to the current window switchToBufferE :: BufferRef -> EditorM () hunk ./src/Yi/UI/Vty.hs 181 -- Discard this field, otherwise we keep retaining reference to -- old Window objects (leak) apply win = win { - winRegion = getRegionImpl win (configUI $ config ui) e cols (height win) + winRegion = getRegionImpl win (configUI $ config ui) e cols (height win) + ,actualLines = windowLinesDisp win (configUI $ config ui) e cols (height win) } return $ windowsA ^= ws'' $ e hunk ./src/Yi/UI/Vty.hs 256 put s' return s +windowLinesDisp :: Window -> UIConfig -> Editor -> Int -> Int -> Int +windowLinesDisp win cfg e w h = dispCount + where (_,_,dispCount) = drawWindow cfg e (error "focus must not be used") win w h + getRegionImpl :: Window -> UIConfig -> Editor -> Int -> Int -> Region hunk ./src/Yi/UI/Vty.hs 261 -getRegionImpl win cfg e w h = snd $ - drawWindow cfg e (error "focus must not be used") win w h +getRegionImpl win cfg e w h = region + where (_,region,_) = drawWindow cfg e (error "focus must not be used") win w h -- | Return a rendered wiew of the window. renderWindow :: UIConfig -> Editor -> Int -> (Window, Bool) -> Rendered hunk ./src/Yi/UI/Vty.hs 267 renderWindow cfg e width (win,hasFocus) = - let (rendered,_) = drawWindow cfg e hasFocus win width (height win) + let (rendered,_,_) = drawWindow cfg e hasFocus win width (height win) in rendered -- | Draw a window hunk ./src/Yi/UI/Vty.hs 272 -- TODO: horizontal scrolling. -drawWindow :: UIConfig -> Editor -> Bool -> Window -> Int -> Int -> (Rendered, Region) -drawWindow cfg e focused win w h = (Rendered { picture = pict,cursor = cur}, mkRegion fromMarkPoint toMarkPoint') +-- TODO(jwall): Store display line counts so scrolling has all the necesary info +drawWindow :: UIConfig -> Editor -> Bool -> Window -> Int -> Int -> (Rendered, Region, Int) +drawWindow cfg e focused win w h = (Rendered { picture = pict,cursor = cur}, mkRegion fromMarkPoint toMarkPoint', dispLnCount) where b = findBufferWith (bufkey win) e sty = configStyle cfg hunk ./src/Yi/UI/Vty.hs 307 tabWidth = tabSize . fst $ runBuffer win b indentSettingsB prompt = if isMini win then miniIdentString b else "" - (rendered,toMarkPoint',cur) = drawText h' w + (rendered,toMarkPoint',cur,dispLnCount) = drawText h' w fromMarkPoint point tabWidth hunk ./src/Yi/UI/Vty.hs 324 -- | Renders text in a rectangle. -- This also returns -- * the index of the last character fitting in the rectangle --- * the position of the Point in (x,y) coordinates, if in the window. +-- * the position of the Point in (x,y) coordinates, if in the window, +-- * the number of display lines for this drawing. drawText :: Int -- ^ The height of the part of the window we are in -> Int -- ^ The width of the part of the window we are in -> Point -- ^ The position of the first character to draw hunk ./src/Yi/UI/Vty.hs 332 -> Point -- ^ The position of the cursor -> Int -- ^ The number of spaces to represent a tab character with. -> [(Char,(Vty.Attr,Point))] -- ^ The data to draw. - -> ([Image], Point, Maybe (Int,Int)) + -> ([Image], Point, Maybe (Int,Int), Int) drawText h w topPoint point tabWidth bufData hunk ./src/Yi/UI/Vty.hs 334 - | h == 0 || w == 0 = ([], topPoint, Nothing) - | otherwise = (rendered_lines, bottomPoint, pntpos) + | h == 0 || w == 0 = ([], topPoint, Nothing, 0) + | otherwise = (rendered_lines, bottomPoint, pntpos, h - (length wrapped - h)) where hunk ./src/Yi/UI/Vty.hs 338 - lns0 = take h $ concatMap (wrapLine w) $ map (concatMap expandGraphic) $ take h $ lines' $ bufData + -- the actual lines to display, can get line count from here. + wrapped = concatMap (wrapLine w) $ map (concatMap expandGraphic) $ take h $ lines' $ bufData + lns0 = take h wrapped bottomPoint = case lns0 of [] -> topPoint hunk ./src/Yi/Window.hs 24 isMini :: !Bool -- ^ regular or mini window? ,bufkey :: !BufferRef -- ^ the buffer this window opens to ,bufAccessList :: ![BufferRef] -- ^ list of last accessed buffers (former bufKeys). Last accessed one is first element - ,height :: Int -- ^ height of the window (in number of lines displayed) + ,height :: Int -- ^ height of the window (in number of screen lines displayed) ,winRegion :: Region -- ^ view area. -- note that the top point is also available as a buffer mark. ,wkey :: !WindowRef -- ^ identifier for the window (for UI sync) hunk ./src/Yi/Window.hs 28 + ,actualLines :: Int-- ^ The actual number of lines displayed. Taking into account line wrapping } deriving (Typeable) hunk ./src/Yi/Window.hs 33 instance Binary Window where - put (Window mini bk bl _h _rgn key) = put mini >> put bk >> put bl >> put key + put (Window mini bk bl _h _rgn key lns) = put mini >> put bk >> put bl >> put key >> put lns get = Window <$> get <*> get <*> get <*> return 0 <*> return emptyRegion hunk ./src/Yi/Window.hs 36 - <*> get + <*> get <*> get -- | Get the identification of a window. hunk ./src/Yi/Window.hs 62 -- | Return a "fake" window onto a buffer. dummyWindow :: BufferRef -> Window -dummyWindow b = Window False b [] 0 emptyRegion dummyWindowKey +dummyWindow b = Window False b [] 0 emptyRegion dummyWindowKey 0 [add documentation and clean up jw...@google.com**20101006205136 Ignore-this: 62d3c4a4707e0ed5fbbfd0967be5f40f Document the rational for this change as well as clean up some of the comments and todos. ] hunk ./src/Yi/Buffer/HighLevel.hs 401 inWin <- pointInWindowB =<< pointB if inWin then return False else do h <- askWindow actualLines - --h <- askWindow height r <- winRegionB p <- pointB let gap = case pointScreenRelPosition p (regionStart r) (regionEnd r) of hunk ./src/Yi/UI/Vty.hs 182 -- old Window objects (leak) apply win = win { winRegion = getRegionImpl win (configUI $ config ui) e cols (height win) + -- ,actualLines = windowLinesDisp win (configUI $ config ui) e cols (height win) } hunk ./src/Yi/UI/Vty.hs 257 put s' return s +-- | Calculate the lines a window can display from a buffer. windowLinesDisp :: Window -> UIConfig -> Editor -> Int -> Int -> Int windowLinesDisp win cfg e w h = dispCount where (_,_,dispCount) = drawWindow cfg e (error "focus must not be used") win w h hunk ./src/Yi/UI/Vty.hs 273 in rendered -- | Draw a window +-- -- TODO: horizontal scrolling. hunk ./src/Yi/UI/Vty.hs 275 --- TODO(jwall): Store display line counts so scrolling has all the necesary info drawWindow :: UIConfig -> Editor -> Bool -> Window -> Int -> Int -> (Rendered, Region, Int) drawWindow cfg e focused win w h = (Rendered { picture = pict,cursor = cur}, mkRegion fromMarkPoint toMarkPoint', dispLnCount) where hunk ./src/Yi/UI/Vty.hs 328 -- * the index of the last character fitting in the rectangle -- * the position of the Point in (x,y) coordinates, if in the window, -- * the number of display lines for this drawing. +-- +-- We calculate the number of lines displayed for this window so that line +-- wrapping doesn't break scrolling. drawText :: Int -- ^ The height of the part of the window we are in -> Int -- ^ The width of the part of the window we are in -> Point -- ^ The position of the first character to draw hunk ./src/Yi/UI/Vty.hs 343 | otherwise = (rendered_lines, bottomPoint, pntpos, h - (length wrapped - h)) where - -- the actual lines to display, can get line count from here. + -- the number of lines that taking wrapping into account, + -- we use this to calculate the number of lines displayed. wrapped = concatMap (wrapLine w) $ map (concatMap expandGraphic) $ take h $ lines' $ bufData lns0 = take h wrapped hunk ./src/Yi/Window.hs 28 ,winRegion :: Region -- ^ view area. -- note that the top point is also available as a buffer mark. ,wkey :: !WindowRef -- ^ identifier for the window (for UI sync) - ,actualLines :: Int-- ^ The actual number of lines displayed. Taking into account line wrapping + -- This is required for accurate scrolling. + -- Scrolling depends on the actual number of buffer + -- lines displayed. Line wrapping changes that number + -- relative to the height so we can't use height for that + -- purpose. + ,actualLines :: Int-- ^ The actual number of buffer lines displayed. Taking into account line wrapping } deriving (Typeable) Context: [compilation fix jeanphilippe.berna...@gmail.com**20100829162455 Ignore-this: d3533951084623ae2697a012d314f165 ] [Add Yi/File.hs-boot that I forgot jeffwhee...@gmail.com**20100812064755 Ignore-this: 5348938d1f93a7615aad115fe7200dd7 ] [Restrict monads-fd version Malte Sommerkorn <malte.sommerk...@gmail.com>**20100807175958 Ignore-this: 1461085ee6150364333a173040269203 Fixed compilation for me ] [Remove some trailing whitespace jeffwhee...@gmail.com**20100716053746 Ignore-this: fd303d5446fc978aa3f233c42accd97d ] [Move Yi.Dired.fnewE to Yi.File.editFile jeffwhee...@gmail.com**20100716053557 Ignore-this: 578136341ce60c89d8a7e97f9712d6bd It can actually open dirs too. Thought about the name a lot, and this is the most intuitive I can think of. Open to suggestions, though. ] [-Wall in dired jeffwhee...@gmail.com**20100715071636 Ignore-this: 218351628f93cbb2278ad1a89211e149 ] [Begin to clean up fnewE, which opens buffers new buffers based on a filename jeffwhee...@gmail.com**20100715071435 Ignore-this: a9430b3d156311402fa32a49e26f2178 The behavior right now hasn't changed. I think some behavior should change, but I have left that for the future (tomorrow?). Creating the parent directories here seems especially broken. ] [TAG 0.6.2.4 jeffwhee...@gmail.com**20100715044543 Ignore-this: a03d48b597790a46cb899c354b5a97d1 ] Patch bundle hash: 794c023c0395999a722bb05e9b1680c577e52037