packages feed

WEditorBrick 0.1.0.0 → 0.2.0.0

raw patch · 4 files changed

+163/−41 lines, 4 filesdep +WEditorBrickdep ~WEditordep ~basedep ~bricknew-component:exe:brick-examplePVP ok

version bump matches the API change (PVP)

Dependencies added: WEditorBrick

Dependency ranges changed: WEditor, base, brick, vty

API changes (from Hackage documentation)

- WEditorBrick.WrappingEditor: doWrappingEditor :: WrappingEditorDoer c b -> WrappingEditor c n -> b
- WEditorBrick.WrappingEditor: dumpWrappingEditor :: WrappingEditor c n -> [[c]]
- WEditorBrick.WrappingEditor: genericWrappingEditor :: (FixedFontViewer a c, FixedFontEditor a c) => n -> a -> WrappingEditor c n
- WEditorBrick.WrappingEditor: handleWrappingEditor :: Eq n => WrappingEditor Char n -> Event -> EventM n (WrappingEditor Char n)
- WEditorBrick.WrappingEditor: mapWrappingEditor :: WrappingEditorAction c -> WrappingEditor c n -> WrappingEditor c n
- WEditorBrick.WrappingEditor: newWrappingEditor :: FixedFontParser a c => a -> n -> [[c]] -> WrappingEditor c n
- WEditorBrick.WrappingEditor: renderWrappingEditor :: (Ord n, Show n) => Bool -> WrappingEditor Char n -> Widget n
+ WEditorBrick.WrappingEditor: doEditor :: WrappingEditorDoer c b -> WrappingEditor c n -> b
+ WEditorBrick.WrappingEditor: dumpEditor :: WrappingEditor c n -> [[c]]
+ WEditorBrick.WrappingEditor: genericEditor :: (FixedFontViewer a c, FixedFontEditor a c) => n -> a -> WrappingEditor c n
+ WEditorBrick.WrappingEditor: handleEditor :: Eq n => WrappingEditor Char n -> Event -> EventM n (WrappingEditor Char n)
+ WEditorBrick.WrappingEditor: mapEditor :: WrappingEditorAction c -> WrappingEditor c n -> WrappingEditor c n
+ WEditorBrick.WrappingEditor: newEditor :: FixedFontParser a c => a -> n -> [[c]] -> WrappingEditor c n
+ WEditorBrick.WrappingEditor: renderEditor :: (Ord n, Show n) => Bool -> WrappingEditor Char n -> Widget n
+ WEditorBrick.WrappingEditor: updateEditorExtent :: Eq n => WrappingEditor c n -> EventM n (WrappingEditor c n)

Files

ChangeLog.md view
@@ -1,5 +1,13 @@ # Revision history for WEditorBrick +## 0.2.0.0  -- 2020-04-17++* **[breaking]** Shortens function names in the `WrappingEditor` module.++* **[new]** Adds `updateEditorExtent` to better support custom event-handlers.++* **[behavior]** Adds key bindings for vertical scrolling actions.+ ## 0.1.0.0  -- 2020-04-14  * First version. Released on an unsuspecting world.
WEditorBrick.cabal view
@@ -1,5 +1,5 @@ name:                WEditorBrick-version:             0.1.0.0+version:             0.2.0.0 synopsis:            Text-editor widget with dynamic line-wrapping for use with Brick.  description:@@ -13,8 +13,9 @@ license:             Apache-2.0 license-file:        LICENSE author:              Kevin P. Barry-maintainer:          ta0kira@gmail.com-category:            Text+maintainer:          Kevin P. Barry <ta0kira@gmail.com>+copyright:           (c) Kevin P. Barry 2020+category:            Graphics build-type:          Simple  cabal-version:       2.0@@ -36,6 +37,22 @@                        brick >= 0.47 && < 0.53,                        vty >= 5.24,                        microlens >= 0.3,-                       WEditor >= 0.1 && < 0.2+                       WEditor >= 0.2 && < 0.3++  default-language:    Haskell2010+++executable brick-example+  hs-source-dirs:      example++  main-is:             brick-example.hs++  ghc-options:         -threaded++  build-depends:       base,+                       brick,+                       vty,+                       WEditorBrick,+                       WEditor    default-language:    Haskell2010
WEditorBrick/WrappingEditor.hs view
@@ -30,13 +30,14 @@   WrappingEditor,   WrappingEditorAction,   WrappingEditorDoer,-  doWrappingEditor,-  dumpWrappingEditor,-  genericWrappingEditor,-  handleWrappingEditor,-  mapWrappingEditor,-  newWrappingEditor,-  renderWrappingEditor,+  doEditor,+  dumpEditor,+  genericEditor,+  handleEditor,+  mapEditor,+  newEditor,+  renderEditor,+  updateEditorExtent, ) where  import Brick.Main@@ -49,35 +50,35 @@   -- | Create a new 'WrappingEditor' using the default editor component.-newWrappingEditor :: FixedFontParser a c => a -> n -> [[c]] -> WrappingEditor c n-newWrappingEditor b n cs = genericWrappingEditor n $ editDocument b $ map UnparsedPara cs+newEditor :: FixedFontParser a c => a -> n -> [[c]] -> WrappingEditor c n+newEditor b n cs = genericEditor n $ editDocument b $ map UnparsedPara cs  -- | Create a new 'WrappingEditor' using a custom editor component.-genericWrappingEditor :: (FixedFontViewer a c, FixedFontEditor a c) => n -> a -> WrappingEditor c n-genericWrappingEditor = WrappingEditor+genericEditor :: (FixedFontViewer a c, FixedFontEditor a c) => n -> a -> WrappingEditor c n+genericEditor = WrappingEditor  -- | Any action that updates the editor state. type WrappingEditorAction c = forall a. (FixedFontViewer a c, FixedFontEditor a c) => a -> a  -- | Update the editor state.-mapWrappingEditor :: WrappingEditorAction c -> WrappingEditor c n -> WrappingEditor c n-mapWrappingEditor f (WrappingEditor name editor) = WrappingEditor name (f editor)+mapEditor :: WrappingEditorAction c -> WrappingEditor c n -> WrappingEditor c n+mapEditor f (WrappingEditor name editor) = WrappingEditor name (f editor)  -- | Any action that reads the editor state. type WrappingEditorDoer c b = forall a. (FixedFontViewer a c, FixedFontEditor a c) => a -> b  -- | Read from the editor state.-doWrappingEditor :: WrappingEditorDoer c b -> WrappingEditor c n -> b-doWrappingEditor f (WrappingEditor _ editor) = f editor+doEditor :: WrappingEditorDoer c b -> WrappingEditor c n -> b+doEditor f (WrappingEditor _ editor) = f editor  -- | Dump the final contents of the edited document.-dumpWrappingEditor :: WrappingEditor c n -> [[c]]-dumpWrappingEditor = map upText . doWrappingEditor exportData+dumpEditor :: WrappingEditor c n -> [[c]]+dumpEditor = map upText . doEditor exportData  -- | Render the editor as a 'Widget'.-renderWrappingEditor :: (Ord n, Show n) => Bool -> WrappingEditor Char n -> Widget n-renderWrappingEditor focus editor = doWrappingEditor edit editor where-  edit e = Widget Greedy Greedy $ do+renderEditor :: (Ord n, Show n) => Bool -> WrappingEditor Char n -> Widget n+renderEditor focus editor = doEditor view editor where+  view e = Widget Greedy Greedy $ do     ctx <- getContext     let width = ctx^.availWidthL     let height = ctx^.availHeightL@@ -93,29 +94,52 @@       strFill w cs = str $ take w $ cs ++ repeat ' '       lineFill w h ls = take h $ ls ++ repeat (strFill w "") +-- | Updates the viewport size based on the most-recent rendering of the editor.+--+--   Call this before any custom event-handling logic so that the viewport is+--   the correct size. This will ensure that vertical cursor movements match+--   what the user expects.+updateEditorExtent :: Eq n => WrappingEditor c n -> (EventM n (WrappingEditor c n))+updateEditorExtent editor = do+  extent <- lookupExtent (getName editor)+  return $ mapEditor (resize extent) editor where+    resize (Just ext) | snd (extentSize ext) > 0 = viewerResizeAction (extentSize ext)+    resize  _ = id+ -- | Update the editor based on Brick events.-handleWrappingEditor :: (Eq n) => WrappingEditor Char n -> Event -> EventM n (WrappingEditor Char n)-handleWrappingEditor editor event = do+--+--   In addition to the canonical typing events, this editor also supports:+--+--     * `PageUp`, `PageDown`, `Home`, and `End` keys.+--     * `Alt`+`Up` shifts the view upward one line.+--     * `Alt`+`Down` shifts the view downward one line.+--     * `Alt`+`Home` shifts the view to hide empty space at the bottom.+--+--   To disable or override any of these keys, intercept them in the main+--   handler for the `App`.+handleEditor :: Eq n => WrappingEditor Char n -> Event -> EventM n (WrappingEditor Char n)+handleEditor editor event = do   extent <- lookupExtent (getName editor)-  return $ mapWrappingEditor (action . resizeAction extent) editor where-    action :: EditorAction Char+  updateEditorExtent editor >>= return . mapEditor action where+    action :: WrappingEditorAction Char     action =       case event of-           EvKey KBS []       -> editorBackspaceAction-           EvKey KDel []      -> editorDeleteAction-           EvKey KDown []     -> editorDownAction-           EvKey KEnd []      -> editorEndAction-           EvKey KEnter []    -> editorEnterAction-           EvKey KHome []     -> editorHomeAction-           EvKey KLeft []     -> editorLeftAction-           EvKey KPageDown [] -> editorPageDownAction-           EvKey KPageUp []   -> editorPageUpAction-           EvKey KRight []    -> editorRightAction-           EvKey KUp []       -> editorUpAction+           EvKey KBS []        -> editorBackspaceAction+           EvKey KDel []       -> editorDeleteAction+           EvKey KDown []      -> editorDownAction+           EvKey KEnd []       -> editorEndAction+           EvKey KEnter []     -> editorEnterAction+           EvKey KHome []      -> editorHomeAction+           EvKey KLeft []      -> editorLeftAction+           EvKey KPageDown []  -> editorPageDownAction+           EvKey KPageUp []    -> editorPageUpAction+           EvKey KRight []     -> editorRightAction+           EvKey KUp []        -> editorUpAction+           EvKey KDown [MMeta] -> viewerShiftDownAction 1+           EvKey KUp [MMeta]   -> viewerShiftUpAction   1+           EvKey KHome [MMeta] -> viewerFillAction            EvKey (KChar c) [] | not (c `elem` "\t\r\n") -> editorAppendAction [c]            _ -> id-    resizeAction (Just ext) | snd (extentSize ext) > 0 = viewerResizeAction (extentSize ext)-    resizeAction  _ = id  -- | Editor widget for use with Brick. data WrappingEditor c n =
+ example/brick-example.hs view
@@ -0,0 +1,73 @@+{- -----------------------------------------------------------------------------+Copyright 2020 Kevin P. Barry++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++    http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.+----------------------------------------------------------------------------- -}++-- Author: Kevin P. Barry [ta0kira@gmail.com]++{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++import Data.Maybe+import System.Environment+import System.Exit+import System.IO++import Brick.AttrMap+import Brick.Main+import Brick.Types+import Graphics.Vty (defAttr)+import Graphics.Vty.Input+import WEditor.LineWrap             -- For the line-wrapping policy.+import WEditorBrick.WrappingEditor  -- For the wrapping editor Brick widget.+++-- Delegate most events to a single handler.+handleEventsWith _ x (VtyEvent (EvKey KEsc [])) = halt x+handleEventsWith handler x (VtyEvent e) = continue =<< handler x e++-- An app containing nothing but a single editor widget.+app = App {+  -- renderEditor renders the current editor in a viewport with the same name as+  -- the editor. True means that the editor has focus.+  appDraw = \edit -> [renderEditor True edit],+  appChooseCursor = const listToMaybe,+  -- handleEditor handles editor events such as cursor movements and typing.+  appHandleEvent = handleEventsWith handleEditor,+  appStartEvent = return,+  appAttrMap = const (attrMap defAttr [])+}++-- Loads the filename, runs the editor, and returns the final data.+-- NOTE: This *doesn't* modify the contents of the file.+fakeEditFile f = do+  contents <- fmap lines $ readFile f+  -- newEditor creates an editor object. breakWords is semi-aware of words, and+  -- lazyHyphen performs hyphenation.+  let editor = newEditor (breakWords lazyHyphen) "editor" contents+  -- dumpEditor extracts the editor's contents.+  modified <- defaultMain app editor >>= return . dumpEditor+  return $ unlines modified++main = do+  args <- getArgs+  case args of+       [f] -> do+         result <- fakeEditFile f+         hPutStr stdout result+         exitSuccess+       _ -> do+         hPutStrLn stderr "Pass a single filename, or call fakeEditFile from ghci."+         exitFailure