Something went wrong. Try again.
Making a new TUI editor maybe
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170module Glyph.Update where
----------------------------------------------------------------------------------------------------
import qualified Brick
import Control.Monad ( sequence_ )
import qualified Data.Enum as Enumimport qualified Data.List as Listimport qualified Data.Set as Setimport qualified Data.Text as Textimport qualified Data.Tuple as Tuple
import Glyph.Class.Stringable ( Stringable (..) )import Glyph.Event ( Event )import qualified Glyph.Event as Eventimport Glyph.Extra.Sign ( Sign (..) )import Glyph.Key.Chord ( Chord (..) )import Glyph.Key.Count ( Count )import qualified Glyph.Key.Count as Countimport Glyph.Key.Trigger ( Triggered (..) )import qualified Glyph.Key.Trigger as Triggerimport Glyph.State ( State (..) )import qualified Glyph.State as Stateimport Glyph.State.Input ( InputState (..) )import qualified Glyph.State.Input as InputStateimport qualified Glyph.State.Notice as Noticeimport qualified Glyph.State.Pane as PaneStateimport Glyph.View.Id ( Id )
import Graphics.Vty.Input.Events ( Key (..), Modifier (..) )import qualified Graphics.Vty.Input.Events as VtyEvent
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
update :: Brick.BrickEvent Id Event -> Brick.EventM Id State ()update = \case Brick.VtyEvent event -> handleVtyEvent event Brick.AppEvent event -> handleAppEvent event Brick.MouseDown{} -> return () Brick.MouseUp{} -> return ()
handleVtyEvent :: VtyEvent.Event -> Brick.EventM Id State ()handleVtyEvent = \case VtyEvent.EvResize _width _height -> return () VtyEvent.EvMouseDown{} -> return () VtyEvent.EvMouseUp{} -> return () VtyEvent.EvPaste _bytes -> return () VtyEvent.EvLostFocus -> return () VtyEvent.EvGainedFocus -> return () VtyEvent.EvKey key modifiers -> handleKeys key modifiers
executeAppEvents :: List Event -> Brick.EventM Id State ()executeAppEvents events = fmap handleAppEvent events |> sequence_
handleAppEvent :: Event -> Brick.EventM Id State ()handleAppEvent event = do state <- Brick.get case event of Event.Quit -> Brick.halt Event.EnterModalEntry -> ModalInput [] |> State.updateInputState state |> State.updateBrickState Event.SplitPaneOneOverOther -> PaneState.split state.sequences PaneState.OneOverOther state.focused state.panes |> State.updateSequencesAnd State.updatePanes state |> State.updateBrickState Event.SplitPaneSideBySide -> PaneState.split state.sequences PaneState.SideBySide state.focused state.panes |> State.updateSequencesAnd State.updatePanes state |> State.updateBrickState Event.CloseFocusedPane -> PaneState.close state.sequences state.focused state.panes |> State.updateSequencesAnd State.updatePanes state |> State.updateBrickState Event.ChangeFocusedPane paneId' -> State.updateFocused state paneId' |> State.updateBrickState Event.InsertError text -> Notice.Error text |> State.appendNotice state |> State.updateBrickState Event.InsertWarning text -> Notice.Warn text |> State.appendNotice state |> State.updateBrickState Event.InsertInfo text -> Notice.Info text |> State.appendNotice state |> State.updateBrickState Event.NotificationSelect sign -> let lenNotices = List.length state.notices direction = case sign of Pos -> Enum.succ Neg -> Enum.pred in Enum.fromEnum state.selectedNotice |> direction |> max lenNotices |> min 1 |> Enum.toEnum |> State.updateSelNotice state |> State.updateBrickState Event.NotificationDismiss -> let enumerated = List.zip [1 ..] state.notices byKey (a, _) (b, _) = a == b removed = List.deleteBy byKey (state.selectedNotice, Notice.Info "") enumerated |> fmap Tuple.snd in State.updateNotice state removed |> State.updateBrickState
handleKeys :: Key -> List Modifier -> Brick.EventM Id State ()handleKeys key modifiers = do state <- Brick.get case state.input of ChordInput currentCount currentChords -> handleChord currentCount currentChords state key modifiers ModalInput chars | List.null modifiers -> handleModal chars state key | otherwise -> handleChord Count.NoCount [] state key modifiers
handleChord :: Count -> List Chord -> State -> Key -> List Modifier -> Brick.EventM Id State ()handleChord currentCount currentChords state key modifiers = let newChord = Chord (Set.fromList modifiers) key in handleTrigger (Trigger.feedChord state.chordKeybinds currentCount currentChords newChord) "chord" (fmap toText (currentChords <> [newChord]) |> Text.intercalate " ") state
handleModal :: List Char -> State -> Key -> Brick.EventM Id State ()handleModal currentChars state key = handleTrigger (Trigger.feedModal state.modalKeybinds currentChars key) "command" (Text.pack currentChars <> toText key) state
handleTrigger :: Triggered -> Text -> Text -> State -> Brick.EventM Id State ()handleTrigger trigger noun errorText state = case trigger of Cancelled -> InputState.idle |> State.updateInputState state |> State.updateBrickState DeadEnded -> InputState.idle |> State.updateInputState state |> (\s -> s{status = "Could not resolve " <> noun <> " to an action: " <> errorText}) |> State.updateBrickState Waiting inputState -> State.updateInputState state inputState |> State.updateBrickState Fire action count captured -> do InputState.idle |> State.updateInputState state |> State.updateBrickState Event.planEvents action count captured |> executeAppEvents