mirror of
https://github.com/jtdaugherty/brick.git
synced 2024-12-01 17:32:52 +03:00
Merge pull request #382 from frasertweedale/feature/selected-element-traversal
add listSelectedElementL Traversal
This commit is contained in:
commit
1d8e0832d1
@ -37,6 +37,7 @@ module Brick.Widgets.List
|
||||
, listSelectedL
|
||||
, listNameL
|
||||
, listItemHeightL
|
||||
, listSelectedElementL
|
||||
|
||||
-- * Accessors
|
||||
, listElements
|
||||
@ -81,7 +82,7 @@ import Control.Applicative ((<|>))
|
||||
import Data.Foldable (find, toList)
|
||||
import Control.Monad.Trans.State (evalState, get, put)
|
||||
|
||||
import Lens.Micro ((^.), (^?), (&), (.~), (%~), _2, _head, set)
|
||||
import Lens.Micro (Traversal', (^.), (^?), (&), (.~), (%~), _2, _head, set)
|
||||
import Data.Functor (($>))
|
||||
import Data.List.NonEmpty (NonEmpty((:|)))
|
||||
import Data.Maybe (fromMaybe)
|
||||
@ -602,6 +603,31 @@ listFindBy test l =
|
||||
result = tailResult <|> headResult
|
||||
in maybe id (set listSelectedL . Just . fst) result l
|
||||
|
||||
-- | Traversal that targets the selected element, if any.
|
||||
--
|
||||
-- Complexity: depends on usage as well as container type
|
||||
--
|
||||
-- @
|
||||
-- listSelectedElementL for 'List': O(1) -- preview, fold
|
||||
-- O(n) -- set, modify, traverse
|
||||
-- listSelectedElementL for 'Seq.Seq': O(log(min(i, n - i))) -- all operations
|
||||
-- @
|
||||
--
|
||||
listSelectedElementL
|
||||
:: (Splittable t, Traversable t, Semigroup (t e))
|
||||
=> Traversal' (GenericList n t e) e
|
||||
listSelectedElementL f l =
|
||||
case l ^. listSelectedL of
|
||||
Nothing -> pure l
|
||||
Just i -> listElementsL go l
|
||||
where
|
||||
go l' =
|
||||
let
|
||||
(left, rest) = splitAt i l'
|
||||
-- middle contains the target element (if any)
|
||||
(middle, right) = splitAt 1 rest
|
||||
in fmap (\m -> left <> m <> right) (traverse f middle)
|
||||
|
||||
-- | Return a list's selected element, if any.
|
||||
--
|
||||
-- Only evaluates as much of the container as needed.
|
||||
|
@ -356,7 +356,7 @@ prop_reverseAppend_Seq l1 l2 =
|
||||
-- whole container to be evaluated.
|
||||
--
|
||||
newtype L a = L [a]
|
||||
deriving (Functor, Foldable, Traversable)
|
||||
deriving (Functor, Foldable, Traversable, Semigroup)
|
||||
|
||||
instance Splittable L where
|
||||
splitAt i (L xs) = over both L (Data.List.splitAt i xs)
|
||||
@ -383,6 +383,22 @@ prop_findByLazy =
|
||||
l' ^. listSelectedL == Just 1
|
||||
&& l'' ^. listSelectedL == Just 3
|
||||
|
||||
prop_listSelectedElement_lazy :: Bool
|
||||
prop_listSelectedElement_lazy =
|
||||
let
|
||||
v = L (1:2:3:4:undefined) :: L Int
|
||||
l = list () v 1 & listSelectedL .~ Just 3
|
||||
in
|
||||
listSelectedElement l == Just (3, 4)
|
||||
|
||||
prop_listSelectedElementL_lazy :: Bool
|
||||
prop_listSelectedElementL_lazy =
|
||||
let
|
||||
v = L (1:2:3:4:undefined) :: L Int
|
||||
l = list () v 1 & listSelectedL .~ Just 3
|
||||
in
|
||||
over listSelectedElementL (*2) l ^? listSelectedElementL == Just 8
|
||||
|
||||
|
||||
return []
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user