diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,28 @@
 Brick changelog
 ---------------
 
+0.64
+----
+
+API changes:
+ * Added `Brick.Main.continueWithoutRedraw`, an alternative to
+   `Brick.Main.continue` that does not trigger a screen redraw. See the
+   Haddock and User Guide for details.
+ * Added `Brick.Widgets.Core.putCursor` to support Vty's new (as of
+   5.33) API for placing cursors without visually representing
+   them. This change also updated `Brick.Forms.renderCheckbox` and
+   `Brick.Forms.renderRadio` to use `putCursor`.
+
+Other improvements:
+ * `Brick.Widgets.Edit` now supports a few more Emacs-style keybindings
+   (thanks Mario Lang):
+    * `M-b` and `M-f` to navigate by word
+    * `C-b` and `C-f` for consistency
+    * `M-d` to delete word under cursor
+    * `C-t` to transpose previous character with current character
+    * `M-<` and `M->` to goto-beginning-of-file and end of file,
+      respectively
+
 0.63
 ----
 
@@ -501,14 +523,14 @@
  * The Forms API got two new functions, `setFormConcat` and
    `setFieldConcat`, used for controlling the previously hard-coded
    concatenation behavior of form fields. These are optional and both
-   concatentation settings default to their former hard-coded values,
+   concatenation settings default to their former hard-coded values,
    `vBox` (#172).
 
 0.36.1
 ------
 
 Package changes:
- * Raiseed upper bound to support GHC 8.4.2 (#171)
+ * Raised upper bound to support GHC 8.4.2 (#171)
 
 Other changes:
  * Improved List accessor documentation (thanks liam <liam@magicseaweed.com>)
@@ -522,7 +544,7 @@
  * Dynamic border support: adjacent widgets that use borders can make
    those borders seamlessly connect to each other! Thanks
    so much to Daniel Wagner for this feature! Please see
-   `programs/DynamicBorderDemo.hs` for a demonstraton. Also see the
+   `programs/DynamicBorderDemo.hs` for a demonstration. Also see the
    "Joinable Borders" section of the User Guide.
 
 0.35.1
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -76,6 +76,8 @@
 | [`pboy`](https://github.com/2mol/pboy) | A tiny PDF organizer |
 | [`hyahtzee2`](https://github.com/DamienCassou/hyahtzee2#readme) | Famous Yahtzee dice game |
 | [`brewsage`](https://github.com/gerdreiss/brewsage#readme) | A TUI for Homebrew |
+| [`sandwich`](https://codedownio.github.io/sandwich/) | A test framework with a TUI interface |
+| [`youbrick`](https://github.com/florentc/youbrick) | A feed aggregator and launcher for Youtube channels |
 
 These third-party packages also extend `brick`:
 
diff --git a/brick.cabal b/brick.cabal
--- a/brick.cabal
+++ b/brick.cabal
@@ -1,5 +1,5 @@
 name:                brick
-version:             0.63
+version:             0.64
 synopsis:            A declarative terminal user interface library
 description:
   Write terminal user interfaces (TUIs) painlessly with 'brick'! You
@@ -115,7 +115,7 @@
     Brick.Widgets.Internal
 
   build-depends:       base < 4.16.0.0,
-                       vty >= 5.31,
+                       vty >= 5.33,
                        transformers,
                        data-clist >= 0.1,
                        directory >= 1.2.5.0,
@@ -131,7 +131,7 @@
                        contravariant,
                        stm >= 2.4.3,
                        text,
-                       text-zipper >= 0.7.1,
+                       text-zipper >= 0.11,
                        template-haskell,
                        deepseq >= 1.3 && < 1.5,
                        unix,
diff --git a/docs/guide.rst b/docs/guide.rst
--- a/docs/guide.rst
+++ b/docs/guide.rst
@@ -221,11 +221,18 @@
 the corresponding types in ``App`` and ``EventM``.
 
 The return value type ``Next s`` value describes what should happen
-after the event handler is finished. We have three choices:
+after the event handler is finished. We have four choices:
 
 * ``Brick.Main.continue s``: continue executing the event loop with the
   specified application state ``s`` as the next value. Commonly this is
   where you'd modify the state based on the event and return it.
+* ``Brick.Main.continueWithoutRedraw s``: continue executing the event
+  loop with the specified application state ``s`` as the next value, but
+  unlike ``continue``, do not redraw the screen using the new state.
+  This is a faster version of ``continue`` since it doesn't redraw the
+  screen; it just leaves up the previous screen contents. This function
+  is only useful when you know that your state change won't cause
+  anything on the screen to change. When in doubt, use ``continue``.
 * ``Brick.Main.halt s``: halt the event loop and return the final
   application state value ``s``. This state value is returned to the
   caller of ``defaultMain`` or ``customMain`` where it can be used prior
@@ -533,7 +540,7 @@
 appAttrMap: Managing Attributes
 -------------------------------
 
-In ``brick`` we use an *attribute map* to assign attibutes to elements
+In ``brick`` we use an *attribute map* to assign attributes to elements
 of the interface. Rather than specifying specific attributes when
 drawing a widget (e.g. red-on-black text) we specify an *attribute name*
 that is an abstract name for the kind of thing we are drawing, e.g.
@@ -784,7 +791,7 @@
 follows:
 
 * The application provides a default theme built in to the program.
-* The application customizes the them by loading theme customizations
+* The application customizes the theme by loading theme customizations
   from a user-specified customization file.
 * The application can save new customizations to files for later
   re-loading.
@@ -934,12 +941,12 @@
      mExtent <- Brick.Main.lookupExtent FooBox
      case mExtent of
        Nothing -> ...
-       Just (Extent _ upperLeft (width, height) offset) -> ...
+       Just (Extent _ upperLeft (width, height)) -> ...
 
 Paste Support
 =============
 
-Some terminal emulators support "bracketed paste" support. This feature
+Some terminal emulators support "bracketed paste" mode. This feature
 enables OS-level paste operations to send the pasted content as a
 single chunk of data and bypass the usual input processing that the
 application does. This enables more secure handling of pasted data since
@@ -1352,7 +1359,7 @@
 to initialize all of the form fields. Each form field will use the lens
 provided to extract the initial value from the ``UserInfo`` record,
 convert it into an appropriate state type for the field in question, and
-later validate that state and convert it back into the approprate type
+later validate that state and convert it back into the appropriate type
 for storage in ``UserInfo``.
 
 The form value itself -- of type ``Form`` -- must be stored in your
diff --git a/programs/ReadmeDemo.hs b/programs/ReadmeDemo.hs
--- a/programs/ReadmeDemo.hs
+++ b/programs/ReadmeDemo.hs
@@ -1,9 +1,9 @@
 module Main where
 
-import Brick
-import Brick.Widgets.Center
-import Brick.Widgets.Border
-import Brick.Widgets.Border.Style
+import Brick (Widget, simpleMain, (<+>), str, withBorderStyle)
+import Brick.Widgets.Center (center)
+import Brick.Widgets.Border (borderWithLabel, vBorder)
+import Brick.Widgets.Border.Style (unicode)
 
 ui :: Widget ()
 ui =
diff --git a/src/Brick/AttrMap.hs b/src/Brick/AttrMap.hs
--- a/src/Brick/AttrMap.hs
+++ b/src/Brick/AttrMap.hs
@@ -17,7 +17,7 @@
 -- Attribute names are mapped to attributes, but some attributes may
 -- be partial (specify only a foreground or background color). When
 -- attribute name lookups occur, the attribute corresponding to a more
--- specific name ('parent <> child' as above) is sucessively merged with
+-- specific name ('parent <> child' as above) is successively merged with
 -- the parent attribute ('parent' as above) all the way to the "root"
 -- of the attribute map, the map's default attribute. In this way, more
 -- specific attributes inherit what they don't specify from more general
diff --git a/src/Brick/Focus.hs b/src/Brick/Focus.hs
--- a/src/Brick/Focus.hs
+++ b/src/Brick/Focus.hs
@@ -60,7 +60,7 @@
               -> (Bool -> a -> b)
               -- ^ A function that takes a value and its focus state.
               -> a
-              -- ^ The wiget state value that we need to check for focus.
+              -- ^ The widget state value that we need to check for focus.
               -> b
               -- ^ The rest of the computation.
 withFocusRing ring f a = f (focusGetCurrent ring == Just (getName a)) a
diff --git a/src/Brick/Forms.hs b/src/Brick/Forms.hs
--- a/src/Brick/Forms.hs
+++ b/src/Brick/Forms.hs
@@ -124,12 +124,12 @@
               -- ^ A validation function converting this field's state
               -- into a value of your choosing. @Nothing@ indicates a
               -- validation failure. For example, this might validate
-              -- an 'Editor' state value by parsing its text contents s
-              -- aan integer and return 'Maybe' 'Int'. This is for pure
-              -- avalue validation; if additional validation is required
-              -- a(e.g. via 'IO'), use this field's state value in an
-              -- aexternal validation routine and use 'setFieldValid' to
-              -- afeed the result back into the form.
+              -- an 'Editor' state value by parsing its text contents as
+              -- an integer and return 'Maybe' 'Int'. This is for pure
+              -- value validation; if additional validation is required
+              -- (e.g. via 'IO'), use this field's state value in an
+              -- external validation routine and use 'setFieldValid' to
+              -- feed the result back into the form.
               , formFieldExternallyValid :: Bool
               -- ^ Whether the field is valid according to an external
               -- validation source. Defaults to always being 'True' and
@@ -349,7 +349,7 @@
 renderCheckbox :: Char -> Char -> Char -> T.Text -> n -> Bool -> Bool -> Widget n
 renderCheckbox lb check rb label n foc val =
     let addAttr = if foc then withDefAttr focusedFormInputAttr else id
-        csr = if foc then showCursor n (Location (1,0)) else id
+        csr = if foc then putCursor n (Location (1,0)) else id
     in clickable n $
        addAttr $ csr $
        (txt $ T.singleton lb <> (if val then T.singleton check else " ") <>
@@ -478,7 +478,7 @@
                   then withDefAttr focusedFormInputAttr
                   else id
         isSet = val == cur
-        csr = if foc then showCursor name (Location (1,0)) else id
+        csr = if foc then putCursor name (Location (1,0)) else id
     in clickable name $
        addAttr $ csr $
        hBox [ txt $ T.singleton lb
diff --git a/src/Brick/Main.hs b/src/Brick/Main.hs
--- a/src/Brick/Main.hs
+++ b/src/Brick/Main.hs
@@ -10,6 +10,7 @@
 
   -- * Event handler functions
   , continue
+  , continueWithoutRedraw
   , halt
   , suspendAndResume
   , lookupViewport
@@ -114,7 +115,8 @@
         -- ^ This function takes the current application state and an
         -- event and returns an action to be taken and a corresponding
         -- transformed application state. Possible options are
-        -- 'continue', 'suspendAndResume', and 'halt'.
+        -- 'continue', 'continueWithoutRedraw', 'suspendAndResume', and
+        -- 'halt'.
         , appStartEvent :: s -> EventM n s
         -- ^ This function gets called once just prior to the first
         -- drawing of your application. Here is where you can make
@@ -191,8 +193,8 @@
     let readEvent = case mUserChan of
           Nothing -> readBChan brickChan
           Just uc -> readBrickEvent brickChan uc
-        runInner rs st = do
-          (result, newRS) <- runVty vty readEvent app st (resetRenderState rs)
+        runInner rs es draw st = do
+          (result, newRS, newExtents) <- runVty vty readEvent app st (resetRenderState rs) es draw
           case result of
               SuspendAndResume act -> do
                   killThread pid
@@ -200,8 +202,10 @@
               Halt s -> do
                   killThread pid
                   return $ InternalHalt s
-              Continue s -> runInner newRS s
-    runInner initialRS initialSt
+              Continue s -> runInner newRS newExtents True s
+              ContinueWithoutRedraw s ->
+                  runInner newRS newExtents False s
+    runInner initialRS mempty True initialSt
 
 -- | The custom event loop entry point to use when the simpler ones
 -- don't permit enough control. Returns the final application state
@@ -293,9 +297,14 @@
        -> App s e n
        -> s
        -> RenderState n
-       -> IO (Next s, RenderState n)
-runVty vty readEvent app appState rs = do
-    (firstRS, exts) <- renderApp vty app appState rs
+       -> [Extent n]
+       -> Bool
+       -> IO (Next s, RenderState n, [Extent n])
+runVty vty readEvent app appState rs prevExtents draw = do
+    (firstRS, exts) <- case draw of
+        True -> renderApp vty app appState rs
+        False -> return (rs, prevExtents)
+
     e <- readEvent
 
     (e', nextRS, nextExts) <- case e of
@@ -361,10 +370,13 @@
 
     (next, eState) <- runStateT (runReaderT (runEventM (appHandleEvent app appState e'))
                                 eventRO) emptyES
-    return (next, nextRS { rsScrollRequests = esScrollRequests eState
-                         , renderCache = applyInvalidations (cacheInvalidateRequests eState) $
-                                         renderCache nextRS
-                         })
+    return ( next
+           , nextRS { rsScrollRequests = esScrollRequests eState
+                    , renderCache = applyInvalidations (cacheInvalidateRequests eState) $
+                                    renderCache nextRS
+                    }
+           , nextExts
+           )
 
 applyInvalidations :: (Ord n) => S.Set (CacheInvalidateRequest n) -> M.Map n v -> M.Map n v
 applyInvalidations ns cache =
@@ -441,8 +453,11 @@
                                         rs
         picWithCursor = case theCursor of
             Nothing -> pic { picCursor = NoCursor }
-            Just cloc -> pic { picCursor = AbsoluteCursor (cloc^.locationColumnL)
-                                                          (cloc^.locationRowL)
+            Just cloc -> pic { picCursor = (if cursorLocationVisible cloc
+                                            then AbsoluteCursor
+                                            else PositionOnly True)
+                                           (cloc^.locationColumnL)
+                                           (cloc^.locationRowL)
                              }
 
     update vty picWithCursor
@@ -529,6 +544,17 @@
 -- state.
 continue :: s -> EventM n (Next s)
 continue = return . Continue
+
+-- | Continue running the event loop with the specified application
+-- state without redrawing the screen. This is faster than 'continue'
+-- because it skips the redraw, but the drawback is that you need to
+-- be really sure that you don't want a screen redraw. If your state
+-- changed in a way that needs to be reflected on the screen, use
+-- 'continue'. This function is for cases where you know that you did
+-- something that won't have an impact on the screen state and you want
+-- to save on redraw cost.
+continueWithoutRedraw :: s -> EventM n (Next s)
+continueWithoutRedraw = return . ContinueWithoutRedraw
 
 -- | Halt the event loop and return the specified application state as
 -- the final state value.
diff --git a/src/Brick/Types/Internal.hs b/src/Brick/Types/Internal.hs
--- a/src/Brick/Types/Internal.hs
+++ b/src/Brick/Types/Internal.hs
@@ -19,6 +19,7 @@
   , CursorLocation(..)
   , cursorLocationL
   , cursorLocationNameL
+  , cursorLocationVisibleL
   , Context(..)
   , EventState(..)
   , EventRO(..)
@@ -131,6 +132,7 @@
 
 -- | The type of actions to take upon completion of an event handler.
 data Next a = Continue a
+            | ContinueWithoutRedraw a
             | SuspendAndResume (IO a)
             | Halt a
             deriving Functor
@@ -164,6 +166,8 @@
                    -- ^ The location
                    , cursorLocationName :: !(Maybe n)
                    -- ^ The name of the widget associated with the location
+                   , cursorLocationVisible :: !Bool
+                   -- ^ Whether the cursor should actually be visible
                    }
                    deriving (Read, Show, Generic, NFData)
 
diff --git a/src/Brick/Widgets/Core.hs b/src/Brick/Widgets/Core.hs
--- a/src/Brick/Widgets/Core.hs
+++ b/src/Brick/Widgets/Core.hs
@@ -59,6 +59,7 @@
 
   -- * Cursor placement
   , showCursor
+  , putCursor
 
   -- * Naming
   , Named(..)
@@ -152,12 +153,14 @@
 -- | When rendering the specified widget, use the specified border style
 -- for any border rendering.
 withBorderStyle :: BorderStyle -> Widget n -> Widget n
-withBorderStyle bs p = Widget (hSize p) (vSize p) $ withReaderT (& ctxBorderStyleL .~ bs) (render p)
+withBorderStyle bs p = Widget (hSize p) (vSize p) $
+    withReaderT (ctxBorderStyleL .~ bs) (render p)
 
 -- | When rendering the specified widget, create borders that respond
 -- dynamically to their neighbors to form seamless connections.
 joinBorders :: Widget n -> Widget n
-joinBorders p = Widget (hSize p) (vSize p) $ withReaderT (& ctxDynBordersL .~ True) (render p)
+joinBorders p = Widget (hSize p) (vSize p) $
+    withReaderT (ctxDynBordersL .~ True) (render p)
 
 -- | When rendering the specified widget, use static borders. This
 -- may be marginally faster, but will introduce a small gap between
@@ -165,7 +168,8 @@
 --
 -- This is the default for backwards compatibility.
 separateBorders :: Widget n -> Widget n
-separateBorders p = Widget (hSize p) (vSize p) $ withReaderT (&ctxDynBordersL .~ False) (render p)
+separateBorders p = Widget (hSize p) (vSize p) $
+    withReaderT (ctxDynBordersL .~ False) (render p)
 
 -- | After the specified widget has been rendered, freeze its borders. A
 -- frozen border will not be affected by neighbors, nor will it affect
@@ -339,7 +343,7 @@
     Widget (hSize p) (vSize p) $ do
         c <- getContext
         let attr = attrMapLookup (c^.ctxAttrNameL) (c^.ctxAttrMapL) `V.withURL` url
-        withReaderT (& ctxAttrMapL %~ setDefaultAttr attr) (render p)
+        withReaderT (ctxAttrMapL %~ setDefaultAttr attr) (render p)
 
 -- | Pad the specified widget on the left. If max padding is used, this
 -- grows greedily horizontally; otherwise it defers to the padded
@@ -690,7 +694,7 @@
 -- | Given borders that should be placed next to each other (the first argument
 -- on the right or bottom, and the second argument on the left or top), compute
 -- new borders and the rewrites that should be done along the edges of the two
--- images to keep the image in synch with the border information.
+-- images to keep the image in sync with the border information.
 --
 -- The input borders are assumed to be disjoint. This property is not checked.
 catBorders
@@ -836,17 +840,16 @@
 withAttr :: AttrName -> Widget n -> Widget n
 withAttr an p =
     Widget (hSize p) (vSize p) $
-      withReaderT (& ctxAttrNameL .~ an) (render p)
+      withReaderT (ctxAttrNameL .~ an) (render p)
 
 -- | Update the attribute map while rendering the specified widget: set
--- its new default attribute to the one that we get by looking up the
--- specified attribute name in the map and then modifying it with the
--- specified function.
+-- its new default attribute to the one that we get by applying specified
+-- function to the current default attribute.
 modifyDefAttr :: (V.Attr -> V.Attr) -> Widget n -> Widget n
 modifyDefAttr f p =
     Widget (hSize p) (vSize p) $ do
         c <- getContext
-        withReaderT (& ctxAttrMapL %~ (setDefaultAttr (f $ getDefaultAttr (c^.ctxAttrMapL)))) (render p)
+        withReaderT (ctxAttrMapL %~ (setDefaultAttr (f $ getDefaultAttr (c^.ctxAttrMapL)))) (render p)
 
 -- | Update the attribute map while rendering the specified widget: set
 -- its new default attribute to the one that we get by looking up the
@@ -855,14 +858,14 @@
 withDefAttr an p =
     Widget (hSize p) (vSize p) $ do
         c <- getContext
-        withReaderT (& ctxAttrMapL %~ (setDefaultAttr (attrMapLookup an (c^.ctxAttrMapL)))) (render p)
+        withReaderT (ctxAttrMapL %~ (setDefaultAttr (attrMapLookup an (c^.ctxAttrMapL)))) (render p)
 
 -- | When rendering the specified widget, update the attribute map with
 -- the specified transformation.
 updateAttrMap :: (AttrMap -> AttrMap) -> Widget n -> Widget n
 updateAttrMap f p =
     Widget (hSize p) (vSize p) $
-        withReaderT (& ctxAttrMapL %~ f) (render p)
+        withReaderT (ctxAttrMapL %~ f) (render p)
 
 -- | When rendering the specified widget, force all attribute lookups
 -- in the attribute map to use the value currently assigned to the
@@ -876,7 +879,7 @@
 forceAttr an p =
     Widget (hSize p) (vSize p) $ do
         c <- getContext
-        withReaderT (& ctxAttrMapL .~ (forceAttrMap (attrMapLookup an (c^.ctxAttrMapL)))) (render p)
+        withReaderT (ctxAttrMapL .~ (forceAttrMap (attrMapLookup an (c^.ctxAttrMapL)))) (render p)
 
 -- | Override the lookup of 'targetName' to return the attribute value
 -- associated with 'fromName' when rendering the specified widget.
@@ -991,32 +994,37 @@
 -- | When rendering the specified widget, also register a cursor
 -- positioning request using the specified name and location.
 showCursor :: n -> Location -> Widget n -> Widget n
-showCursor n cloc p =
-    Widget (hSize p) (vSize p) $ do
-      result <- render p
-      return $ result & cursorsL %~ (CursorLocation cloc (Just n):)
+showCursor n cloc p = Widget (hSize p) (vSize p) $
+    (cursorsL %~ (CursorLocation cloc (Just n) True:)) <$> (render p)
 
+-- | When rendering the specified widget, also register a cursor
+-- positioning request using the specified name and location.
+-- The cursor will only be positioned but not made visible.
+putCursor :: n -> Location -> Widget n -> Widget n
+putCursor n cloc p = Widget (hSize p) (vSize p) $
+    (cursorsL %~ (CursorLocation cloc (Just n) False:)) <$> (render p)
+
 hRelease :: Widget n -> Maybe (Widget n)
 hRelease p =
     case hSize p of
         Fixed -> Just $ Widget Greedy (vSize p) $
-                        withReaderT (& availWidthL .~ unrestricted) (render p)
+                        withReaderT (availWidthL .~ unrestricted) (render p)
         Greedy -> Nothing
 
 vRelease :: Widget n -> Maybe (Widget n)
 vRelease p =
     case vSize p of
         Fixed -> Just $ Widget (hSize p) Greedy $
-                        withReaderT (& availHeightL .~ unrestricted) (render p)
+                        withReaderT (availHeightL .~ unrestricted) (render p)
         Greedy -> Nothing
 
 -- | If the specified resource name has an entry in the rendering cache,
 -- use the rendered version from the cache. If not, render the specified
 -- widget and update the cache with the result.
 --
--- To ensure that mouse events are emitted correctly for cached widgets, 
--- in addition to the rendered widget, we also cache (the names of) 
--- any clickable extents that were rendered and restore that when utilizing
+-- To ensure that mouse events are emitted correctly for cached widgets,
+-- in addition to the rendered widget, we also cache (the names of) any
+-- clickable extents that were rendered and restore that when utilizing
 -- the cache.
 --
 -- See also 'invalidateCacheEntry'.
@@ -1047,8 +1055,8 @@
     cache <- lift $ gets (^.renderCacheL)
     return $ M.lookup n cache
 
-cacheUpdate :: (Ord n) => n -> ([n], Result n) -> RenderM n ()
-cacheUpdate n r = lift $ modify (& renderCacheL %~ M.insert n r)
+cacheUpdate :: Ord n => n -> ([n], Result n) -> RenderM n ()
+cacheUpdate n r = lift $ modify (renderCacheL %~ M.insert n r)
 
 -- | Render the specified widget in a named viewport with the
 -- specified type. This permits widgets to be scrolled without being
@@ -1107,7 +1115,7 @@
           doInsert (Just vp) = Just $ vp & vpSize .~ newSize
           doInsert Nothing = Just newVp
 
-      lift $ modify (& viewportMapL %~ (M.alter doInsert vpname))
+      lift $ modify (viewportMapL %~ (M.alter doInsert vpname))
 
       -- Then render the viewport content widget with the rendering
       -- layout constraint released (but raise an exception if we are
@@ -1148,7 +1156,7 @@
                               Both -> scrollTo Horizontal rq (initialResult^.imageL) $
                                       scrollTo Vertical rq (initialResult^.imageL) $
                                       applyRequests rqs v
-                  lift $ modify (& viewportMapL %~ (M.insert vpname updatedVp))
+                  lift $ modify (viewportMapL %~ (M.insert vpname updatedVp))
 
       -- If the sub-rendering requested visibility, update the scroll
       -- state accordingly
@@ -1162,7 +1170,7 @@
                           Both -> scrollToView Horizontal rq $ scrollToView Vertical rq vp'
                           Horizontal -> scrollToView typ rq vp'
                           Vertical -> scrollToView typ rq vp'
-                  lift $ modify (& viewportMapL %~ (M.insert vpname $ foldl updateVp vp rqs))
+                  lift $ modify (viewportMapL %~ (M.insert vpname $ foldl updateVp vp rqs))
 
       -- If the size of the rendering changes enough to make the
       -- viewport offsets invalid, reset them
@@ -1183,7 +1191,7 @@
               Both -> fixLeft . fixTop
               Horizontal -> fixLeft
               Vertical -> fixTop
-      lift $ modify (& viewportMapL %~ (M.insert vpname (updateVp vp)))
+      lift $ modify (viewportMapL %~ (M.insert vpname (updateVp vp)))
 
       -- Get the viewport state now that it has been updated.
       mVpFinal <- lift $ gets (M.lookup vpname . (^.viewportMapL))
diff --git a/src/Brick/Widgets/Edit.hs b/src/Brick/Widgets/Edit.hs
--- a/src/Brick/Widgets/Edit.hs
+++ b/src/Brick/Widgets/Edit.hs
@@ -52,6 +52,7 @@
 import qualified Data.Text.Encoding as T
 import qualified Data.Text.Zipper as Z hiding ( textZipper )
 import qualified Data.Text.Zipper.Generic as Z
+import qualified Data.Text.Zipper.Generic.Words as Z
 
 import Brick.Types
 import Brick.Widgets.Core
@@ -59,12 +60,20 @@
 
 -- | Editor state.  Editors support the following events by default:
 --
--- * Ctrl-a: go to beginning of line
--- * Ctrl-e: go to end of line
+-- * Meta-<: go to beginning of file
+-- * Meta->: go to end of file
+-- * Ctrl-a, Home: go to beginning of line
+-- * Ctrl-e, End: go to end of line
 -- * Ctrl-d, Del: delete character at cursor position
+-- * Meta-d: delete word at cursor position
 -- * Backspace: delete character prior to cursor position
 -- * Ctrl-k: delete all from cursor to end of line
 -- * Ctrl-u: delete all from cursor to beginning of line
+-- * Ctrl-t: transpose character before cursor with the one at cursor position
+-- * Meta-b: move one word to the left
+-- * Ctrl-b: move one character to the left
+-- * Meta-f: move one word to the right
+-- * Ctrl-f: move one character to the right
 -- * Arrow keys: move cursor
 -- * Enter: break the current line at the cursor position
 -- * Paste: Bracketed Pastes from the terminal will be pasted, provided
@@ -105,7 +114,8 @@
 instance DecodeUtf8 String where
     decodeUtf8 bs = T.unpack <$> decodeUtf8 bs
 
-handleEditorEvent :: (DecodeUtf8 t, Eq t, Monoid t) => Event -> Editor t n -> EventM n (Editor t n)
+handleEditorEvent :: (DecodeUtf8 t, Eq t, Z.GenericTextZipper t)
+                  => Event -> Editor t n -> EventM n (Editor t n)
 handleEditorEvent e ed =
         let f = case e of
                   EvPaste bs -> case decodeUtf8 bs of
@@ -114,6 +124,7 @@
                   EvKey (KChar 'a') [MCtrl] -> Z.gotoBOL
                   EvKey (KChar 'e') [MCtrl] -> Z.gotoEOL
                   EvKey (KChar 'd') [MCtrl] -> Z.deleteChar
+                  EvKey (KChar 'd') [MMeta] -> Z.deleteWord
                   EvKey (KChar 'k') [MCtrl] -> Z.killToEOL
                   EvKey (KChar 'u') [MCtrl] -> Z.killToBOL
                   EvKey KEnter [] -> Z.breakLine
@@ -123,9 +134,16 @@
                   EvKey KDown [] -> Z.moveDown
                   EvKey KLeft [] -> Z.moveLeft
                   EvKey KRight [] -> Z.moveRight
+                  EvKey (KChar 'b') [MCtrl] -> Z.moveLeft
+                  EvKey (KChar 'f') [MCtrl] -> Z.moveRight
+                  EvKey (KChar 'b') [MMeta] -> Z.moveWordLeft
+                  EvKey (KChar 'f') [MMeta] -> Z.moveWordRight
                   EvKey KBS [] -> Z.deletePrevChar
+                  EvKey (KChar 't') [MCtrl] -> Z.transposeChars
                   EvKey KHome [] -> Z.gotoBOL
                   EvKey KEnd [] -> Z.gotoEOL
+                  EvKey (KChar '<') [MMeta] -> Z.gotoBOF
+                  EvKey (KChar '>') [MMeta] -> Z.gotoEOF
                   _ -> id
         in return $ applyEdit f ed
 
diff --git a/src/Brick/Widgets/FileBrowser.hs b/src/Brick/Widgets/FileBrowser.hs
--- a/src/Brick/Widgets/FileBrowser.hs
+++ b/src/Brick/Widgets/FileBrowser.hs
@@ -3,7 +3,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TupleSections #-}
--- | This module provids a file browser widget that allows users to
+-- | This module provides a file browser widget that allows users to
 -- navigate directory trees, search for files and directories, and
 -- select entries of interest. For a complete working demonstration of
 -- this module, see @programs/FileBrowserDemo.hs@.
@@ -798,7 +798,7 @@
         addAttr = maybe id (withDefAttr . attrForFileType) (fileInfoFileType info)
         body = addAttr (hLimit (maxLen + 1) $
                padRight Max $
-               (if foc && listSel then showCursor n (Location (0,0)) else id) $
+               (if foc && listSel then putCursor n (Location (0,0)) else id) $
                str $ fileInfoSanitizedFilename info <> suffix)
         suffix = (if fileInfoFileType info == Just Directory then "/" else "") <>
                  (if sel then "*" else "")
diff --git a/src/Brick/Widgets/List.hs b/src/Brick/Widgets/List.hs
--- a/src/Brick/Widgets/List.hs
+++ b/src/Brick/Widgets/List.hs
@@ -545,7 +545,7 @@
 -- If @pos >= 0@, indexes from the start of the list (which gets
 -- evaluated up to the target index)
 --
--- If @pos < 0@, indexes from the end of the list (which evalutes
+-- If @pos < 0@, indexes from the end of the list (which evaluates
 -- 'length' of the list).
 --
 -- Complexity: same as 'splitAt' for the container type.
diff --git a/src/Brick/Widgets/ProgressBar.hs b/src/Brick/Widgets/ProgressBar.hs
--- a/src/Brick/Widgets/ProgressBar.hs
+++ b/src/Brick/Widgets/ProgressBar.hs
@@ -10,7 +10,6 @@
 where
 
 import Lens.Micro ((^.))
-import Data.List (splitAt)
 import Data.Maybe (fromMaybe)
 #if !(MIN_VERSION_base(4,11,0))
 import Data.Monoid
diff --git a/tests/List.hs b/tests/List.hs
--- a/tests/List.hs
+++ b/tests/List.hs
@@ -353,7 +353,7 @@
 
 -- Laziness tests.  Here we create a custom container type
 -- that we use to ensure certain operations do not cause the
--- whole container to be evaulated.
+-- whole container to be evaluated.
 --
 newtype L a = L [a]
   deriving (Functor, Foldable, Traversable)
