mirror of
https://github.com/jtdaugherty/brick.git
synced 2025-01-08 15:08:46 +03:00
Implements listReplace
- replaces list content while preserving selected index
This commit is contained in:
parent
76a3379d2f
commit
d8538b10db
@ -28,11 +28,13 @@ library
|
|||||||
Brick.Util
|
Brick.Util
|
||||||
other-modules:
|
other-modules:
|
||||||
Brick.Prim.Internal
|
Brick.Prim.Internal
|
||||||
|
Brick.Merge
|
||||||
|
|
||||||
build-depends: base >=4.7 && <4.8,
|
build-depends: base >=4.7 && <4.8,
|
||||||
vty >= 5.2.9,
|
vty >= 5.2.9,
|
||||||
transformers,
|
transformers,
|
||||||
data-default,
|
data-default,
|
||||||
|
Diff,
|
||||||
containers,
|
containers,
|
||||||
lens
|
lens
|
||||||
|
|
||||||
|
@ -5,17 +5,19 @@ module Brick.List
|
|||||||
, drawList
|
, drawList
|
||||||
, listInsert
|
, listInsert
|
||||||
, listRemove
|
, listRemove
|
||||||
|
, listReplace
|
||||||
, listSelectedElement
|
, listSelectedElement
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
import Control.Applicative ((<$>), (<|>))
|
import Control.Applicative ((<$>), (<|>))
|
||||||
import Data.Default
|
import Data.Default
|
||||||
import Data.Maybe (catMaybes)
|
import Data.Maybe (fromMaybe, catMaybes)
|
||||||
import Graphics.Vty (Event(..), Key(..), DisplayRegion)
|
import Graphics.Vty (Event(..), Key(..), DisplayRegion)
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
|
|
||||||
import Brick.Core (HandleEvent(..), SetSize(..))
|
import Brick.Core (HandleEvent(..), SetSize(..))
|
||||||
|
import Brick.Merge (maintainSel)
|
||||||
import Brick.Prim
|
import Brick.Prim
|
||||||
import Brick.Scroll (VScroll, vScroll, scrollToView)
|
import Brick.Scroll (VScroll, vScroll, scrollToView)
|
||||||
import Brick.Util (clamp, for)
|
import Brick.Util (clamp, for)
|
||||||
@ -101,6 +103,22 @@ listRemove pos l | null es = l
|
|||||||
where
|
where
|
||||||
es = listElements l
|
es = listElements l
|
||||||
|
|
||||||
|
-- Replaces entire list with a new set of elements, but preserves selected index
|
||||||
|
-- using a two-way merge algorithm.
|
||||||
|
listReplace :: Eq e => [e] -> List e -> List e
|
||||||
|
listReplace es' l | es' == es = l
|
||||||
|
| otherwise =
|
||||||
|
let sel = fromMaybe 0 (listSelected l)
|
||||||
|
newSel = case (null es, null es') of
|
||||||
|
(_, True) -> Nothing
|
||||||
|
(True, False) -> Just 0
|
||||||
|
(False, False) -> Just (maintainSel es es' sel)
|
||||||
|
in ensureSelectedVisible $ l { listSelected = newSel
|
||||||
|
, listElements = es'
|
||||||
|
}
|
||||||
|
where
|
||||||
|
es = listElements l
|
||||||
|
|
||||||
moveUp :: List e -> List e
|
moveUp :: List e -> List e
|
||||||
moveUp = moveBy (-1)
|
moveUp = moveBy (-1)
|
||||||
|
|
||||||
|
31
src/Brick/Merge.hs
Normal file
31
src/Brick/Merge.hs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
module Brick.Merge
|
||||||
|
( maintainSel
|
||||||
|
)
|
||||||
|
where
|
||||||
|
|
||||||
|
import Data.Algorithm.Diff
|
||||||
|
|
||||||
|
-- Assuming `xs` is an existing list that we want to update to match the state
|
||||||
|
-- of `ys`. Given a selected index in `xs`, the goal is to compute the
|
||||||
|
-- corresponding index in `ys`.
|
||||||
|
maintainSel :: Eq e => [e] -> [e] -> Int -> Int
|
||||||
|
maintainSel xs ys sel = let hunks = getDiff xs ys
|
||||||
|
in merge 0 sel hunks
|
||||||
|
|
||||||
|
merge :: Eq e => Int -> Int -> [Diff e] -> Int
|
||||||
|
merge _ sel [] = sel
|
||||||
|
merge idx sel (h:hs) | idx > sel = sel
|
||||||
|
| otherwise = case h of
|
||||||
|
Both _ _ -> merge sel (idx+1) hs
|
||||||
|
|
||||||
|
-- element removed in new list
|
||||||
|
First _ -> let newSel = if idx < sel
|
||||||
|
then sel - 1
|
||||||
|
else sel
|
||||||
|
in merge newSel idx hs
|
||||||
|
|
||||||
|
-- element added in new list
|
||||||
|
Second _ -> let newSel = if idx <= sel
|
||||||
|
then sel + 1
|
||||||
|
else sel
|
||||||
|
in merge newSel (idx+1) hs
|
Loading…
Reference in New Issue
Block a user