diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -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.
diff --git a/WEditorBrick.cabal b/WEditorBrick.cabal
--- a/WEditorBrick.cabal
+++ b/WEditorBrick.cabal
@@ -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
diff --git a/WEditorBrick/WrappingEditor.hs b/WEditorBrick/WrappingEditor.hs
--- a/WEditorBrick/WrappingEditor.hs
+++ b/WEditorBrick/WrappingEditor.hs
@@ -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 =
diff --git a/example/brick-example.hs b/example/brick-example.hs
new file mode 100644
--- /dev/null
+++ b/example/brick-example.hs
@@ -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
