-- | Module : Hum.Views.Help -- Copyright : (c) Itai Y. Efrat 2020-2021 -- License : GPLv2-or-later (see LICENSE) -- Maintainer : Itai Y. Efrat -- -- Shared functions for views. module Hum.Views.Help where import Prelude hiding ( Down ) import Hum.Types import Brick.Types import Graphics.Vty.Input.Events import Brick.Main import Brick.Widgets.Core import Brick.Widgets.Search import Control.Lens import Text.Regex.TDFA.Text import Text.Regex.TDFA -- | Draws help. drawViewHelp :: HumState -> Widget Name drawViewHelp st = viewport Help Vertical (helpW st) -- | Help widget. Parses the last search as a case insensitive POSIX regex. helpW :: HumState -> Widget Name helpW st = let htx = st ^. helpL . helpTextL hi = st ^. helpL . helpSearchIntL mterm = viaNonEmpty head (st ^. exL . searchHistoryL) mterm' = if mterm == Just "" then Nothing else mterm eterm = maybe (Left "empty") (compile defaultCompOpt{caseSensitive = False} defaultExecOpt) mterm' in either (\_ -> txt htx) (\term -> regexW hi term htx) eterm -- | Help widget. Parses the last search as an exact match. helpW' :: HumState -> Widget Name helpW' st = let htx = st ^. helpL . helpTextL hi = st ^. helpL . helpSearchIntL mterm = viaNonEmpty head (st ^. exL . searchHistoryL) mterm' = if mterm == Just "" then Nothing else mterm in maybe (txt htx) (\term -> searchW hi term htx) mterm' -- | Helper function that keeps "Hum.UI" tidy. helpText' :: Text helpText' = unlines [ "Change views:" , " 1 - queue" , " 2 - library" , " 3 - playlists" , "" , "General bindings:" , " t - play/pause toggle" , " , - previous song" , " . - next song" , " [ and ] - skip 5 second in either direction" , " { and } - skip 30 second in either direction" , " hjkl - vim movements" , " / and ? - forwards and backwards search" , " n and N - move to next and previous match of search" , " : - execute commands" , " q - quit" , " s - toggle single mode in mpd" , " c - toggle consume mode in mpd" , " x - toggle crossfade mode in mpd" , " r - toggle repeat mode in mpd" , " z - toggle random mode in mpd" , "" , "Queue keybindings:" , " SPC - select song" , " y and d - yank and delete the selected songs" , " p - paste selected song" , " a - add selected songs to playlist" , "" , "Library and Playlists keybindigns:" , " SPC - add song/song collection to queue" , " RET - add song/song collection to queue, and start playing the first one" , " ` - toggle sort of the album column between release order and alphabetical order" , "" , "Playlists keybindigns:" , " On playlist contents:" , " e - make playlist editable, press again to get save prompt." , " editing a playlist is the same as editing the queue" , "" , " On list of playlists:" , " e - rename playlist" , " y and p - copy and paste playlists (with -copy added to the name)" , " d - delete playlist (with prompt)" , "" , "commands:" , ":help - gets you this" , ":q - quits" , ":save $name - saves the queue to a playlist called $name" ] -- | Updates which mathc is focused in the help buffer. helpSearch :: Bool -- ^ Search direction, True for forward. -> HumState -> EventM Name HumState helpSearch dir st = pure $ if dir then st & helpL . helpSearchIntL %~ (\x->x+1) else st & helpL . helpSearchIntL %~ (\x->x-1) -- | handle key events in help view. handleEventHelp :: HumState -> BrickEvent Name HumEvent -> EventM Name (Next HumState) handleEventHelp s e = case e of VtyEvent vtye -> case vtye of EvKey (KChar 'j') [] -> vScrollBy (viewportScroll Help) 1 >> continue s EvKey (KChar 'k') [] -> vScrollBy (viewportScroll Help) (-1) >> continue s EvKey (KChar 'n') [] -> continue =<< helpSearch (s ^. exL . searchDirectionL) s EvKey (KChar 'N') [] -> continue =<< helpSearch (s ^. exL . searchDirectionL & not) s EvKey (KChar 'G') [] -> continue s EvKey (KChar 'g') [] -> continue s _ -> continue s _ -> continue s