diff --git a/.travis.yml b/.travis.yml
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,156 +1,173 @@
 # This Travis job script has been generated by a script via
 #
-#   runghc make_travis_yml_2.hs '-o' '.travis.yml' '--ghc-head' '--irc-channel=irc.freenode.org#haskell-lens' '--no-no-tests-no-bench' '--no-unconstrained' 'cabal.project'
+#   haskell-ci '--output=.travis.yml' '--config=cabal.haskell-ci' 'cabal.project'
 #
-# For more information, see https://github.com/hvr/multi-ghc-travis
+# For more information, see https://github.com/haskell-CI/haskell-ci
 #
+# version: 0.5.20180830
+#
 language: c
-sudo: false
-
+dist: xenial
 git:
-  submodules: false  # whether to recursively clone submodules
-
+  # whether to recursively clone submodules
+  submodules: false
 notifications:
   irc:
     channels:
-      - "irc.freenode.org#haskell-lens"
+      - irc.freenode.org#haskell-lens
     skip_join: true
     template:
-      - "\x0313trifecta\x03/\x0306%{branch}\x03 \x0314%{commit}\x03 %{build_url} %{message}"
-
+      - "\"\\x0313trifecta\\x03/\\x0306%{branch}\\x03 \\x0314%{commit}\\x03 %{build_url} %{message}\""
 cache:
   directories:
     - $HOME/.cabal/packages
     - $HOME/.cabal/store
-
 before_cache:
-  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
+  - rm -fv $CABALHOME/packages/hackage.haskell.org/build-reports.log
   # remove files that are regenerated by 'cabal update'
-  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.*
-  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/*.json
-  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.cache
-  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.tar
-  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/01-index.tar.idx
-
-  - rm -rfv $HOME/.cabal/packages/head.hackage
-
+  - rm -fv $CABALHOME/packages/hackage.haskell.org/00-index.*
+  - rm -fv $CABALHOME/packages/hackage.haskell.org/*.json
+  - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.cache
+  - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar
+  - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar.idx
+  - rm -rfv $CABALHOME/packages/head.hackage
 matrix:
   include:
-    - compiler: "ghc-8.6.1"
-      env: GHCHEAD=true
-      addons: {apt: {packages: [ghc-ppa-tools,cabal-install-head,ghc-8.6.1], sources: [hvr-ghc]}}
-    - compiler: "ghc-8.4.3"
-    # env: TEST=--disable-tests BENCH=--disable-benchmarks
-      addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-8.4.3], sources: [hvr-ghc]}}
-    - compiler: "ghc-8.2.2"
-    # env: TEST=--disable-tests BENCH=--disable-benchmarks
-      addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-8.2.2], sources: [hvr-ghc]}}
-    - compiler: "ghc-8.0.2"
-    # env: TEST=--disable-tests BENCH=--disable-benchmarks
-      addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-8.0.2], sources: [hvr-ghc]}}
-    - compiler: "ghc-7.10.3"
-    # env: TEST=--disable-tests BENCH=--disable-benchmarks
-      addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-7.10.3], sources: [hvr-ghc]}}
-    - compiler: "ghc-7.8.4"
-    # env: TEST=--disable-tests BENCH=--disable-benchmarks
-      addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-7.8.4], sources: [hvr-ghc]}}
-    - compiler: "ghc-7.6.3"
-    # env: TEST=--disable-tests BENCH=--disable-benchmarks
-      addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-7.6.3], sources: [hvr-ghc]}}
-    - compiler: "ghc-7.4.2"
-    # env: TEST=--disable-tests BENCH=--disable-benchmarks
-      addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.2,ghc-7.4.2], sources: [hvr-ghc]}}
-    - compiler: "ghc-head"
-      env: GHCHEAD=true
-      addons: {apt: {packages: [ghc-ppa-tools,cabal-install-head,ghc-head], sources: [hvr-ghc]}}
-
+    - compiler: ghc-8.8.1
+      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.8.1","cabal-install-3.0"]}}
+    - compiler: ghc-8.6.5
+      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.5","cabal-install-3.0"]}}
+    - compiler: ghc-8.4.4
+      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.4","cabal-install-3.0"]}}
+    - compiler: ghc-8.2.2
+      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.2.2","cabal-install-3.0"]}}
+    - compiler: ghc-8.0.2
+      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.0.2","cabal-install-3.0"]}}
+    - compiler: ghc-7.10.3
+      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.3","cabal-install-3.0"]}}
+    - compiler: ghc-7.8.4
+      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.4","cabal-install-3.0"]}}
+    - compiler: ghc-head
+      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-head","cabal-install-head"]}}
   allow_failures:
-    - compiler: "ghc-head"
-    - compiler: "ghc-8.6.1"
-
+    - compiler: ghc-head
 before_install:
-  - HC=${CC}
-  - HCPKG=${HC/ghc/ghc-pkg}
+  - HC=$(echo "/opt/$CC/bin/ghc" | sed 's/-/\//')
+  - WITHCOMPILER="-w $HC"
+  - HADDOCK=$(echo "/opt/$CC/bin/haddock" | sed 's/-/\//')
+  - HCPKG="$HC-pkg"
   - unset CC
-  - ROOTDIR=$(pwd)
-  - mkdir -p $HOME/.local/bin
-  - "PATH=/opt/ghc/bin:/opt/ghc-ppa-tools/bin:$HOME/local/bin:$PATH"
-  - HCNUMVER=$(( $(${HC} --numeric-version|sed -E 's/([0-9]+)\.([0-9]+)\.([0-9]+).*/\1 * 10000 + \2 * 100 + \3/') ))
+  - CABAL=/opt/ghc/bin/cabal
+  - CABALHOME=$HOME/.cabal
+  - export PATH="$CABALHOME/bin:$PATH"
+  - TOP=$(pwd)
+  - "HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\\d+)\\.(\\d+)\\.(\\d+)(\\.(\\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')"
   - echo $HCNUMVER
-
+  - CABAL="$CABAL -vnormal+nowrap+markoutput"
+  - set -o pipefail
+  - |
+    echo 'function blue(s) { printf "\033[0;34m" s "\033[0m " }'           >> .colorful.awk
+    echo 'BEGIN { state = "output"; }'                                     >> .colorful.awk
+    echo '/^-----BEGIN CABAL OUTPUT-----$/ { state = "cabal" }'            >> .colorful.awk
+    echo '/^-----END CABAL OUTPUT-----$/ { state = "output" }'             >> .colorful.awk
+    echo '!/^(-----BEGIN CABAL OUTPUT-----|-----END CABAL OUTPUT-----)/ {' >> .colorful.awk
+    echo '  if (state == "cabal") {'                                       >> .colorful.awk
+    echo '    print blue($0)'                                              >> .colorful.awk
+    echo '  } else {'                                                      >> .colorful.awk
+    echo '    print $0'                                                    >> .colorful.awk
+    echo '  }'                                                             >> .colorful.awk
+    echo '}'                                                               >> .colorful.awk
+  - cat .colorful.awk
+  - |
+    color_cabal_output () {
+      awk -f $TOP/.colorful.awk
+    }
+  - echo text | color_cabal_output
 install:
-  - cabal --version
+  - ${CABAL} --version
   - echo "$(${HC} --version) [$(${HC} --print-project-git-commit-id 2> /dev/null || echo '?')]"
-  - BENCH=${BENCH---enable-benchmarks}
-  - TEST=${TEST---enable-tests}
-  - HADDOCK=${HADDOCK-true}
-  - UNCONSTRAINED=${UNCONSTRAINED-true}
-  - NOINSTALLEDCONSTRAINTS=${NOINSTALLEDCONSTRAINTS-false}
-  - GHCHEAD=${GHCHEAD-false}
-  - travis_retry cabal update -v
-  - "sed -i.bak 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config"
-  - rm -fv cabal.project cabal.project.local
-  # Overlay Hackage Package Index for GHC HEAD: https://github.com/hvr/head.hackage
+  - TEST=--enable-tests
+  - BENCH=--enable-benchmarks
+  - HEADHACKAGE=false
+  - if [ $HCNUMVER -gt 80801 ] ; then HEADHACKAGE=true ; fi
+  - rm -f $CABALHOME/config
   - |
-    if $GHCHEAD; then
-      sed -i 's/-- allow-newer: .*/allow-newer: *:base/' ${HOME}/.cabal/config
-      for pkg in $($HCPKG list --simple-output); do pkg=$(echo $pkg | sed 's/-[^-]*$//'); sed -i "s/allow-newer: /allow-newer: *:$pkg, /" ${HOME}/.cabal/config; done
-
-      echo 'repository head.hackage'                                                        >> ${HOME}/.cabal/config
-      echo '   url: http://head.hackage.haskell.org/'                                       >> ${HOME}/.cabal/config
-      echo '   secure: True'                                                                >> ${HOME}/.cabal/config
-      echo '   root-keys: 07c59cb65787dedfaef5bd5f987ceb5f7e5ebf88b904bbd4c5cbdeb2ff71b740' >> ${HOME}/.cabal/config
-      echo '              2e8555dde16ebd8df076f1a8ef13b8f14c66bad8eafefd7d9e37d0ed711821fb' >> ${HOME}/.cabal/config
-      echo '              8f79fd2389ab2967354407ec852cbe73f2e8635793ac446d09461ffb99527f6e' >> ${HOME}/.cabal/config
-      echo '   key-threshold: 3'                                                            >> ${HOME}/.cabal.config
-
-      grep -Ev -- '^\s*--' ${HOME}/.cabal/config | grep -Ev '^\s*$'
-
-      cabal new-update head.hackage -v
+    echo "verbose: normal +nowrap +markoutput"          >> $CABALHOME/config
+    echo "remote-build-reporting: anonymous"            >> $CABALHOME/config
+    echo "write-ghc-environment-files: always"          >> $CABALHOME/config
+    echo "remote-repo-cache: $CABALHOME/packages"       >> $CABALHOME/config
+    echo "logs-dir:          $CABALHOME/logs"           >> $CABALHOME/config
+    echo "world-file:        $CABALHOME/world"          >> $CABALHOME/config
+    echo "extra-prog-path:   $CABALHOME/bin"            >> $CABALHOME/config
+    echo "symlink-bindir:    $CABALHOME/bin"            >> $CABALHOME/config
+    echo "installdir:        $CABALHOME/bin"            >> $CABALHOME/config
+    echo "build-summary:     $CABALHOME/logs/build.log" >> $CABALHOME/config
+    echo "store-dir:         $CABALHOME/store"          >> $CABALHOME/config
+    echo "install-dirs user"                            >> $CABALHOME/config
+    echo "  prefix: $CABALHOME"                         >> $CABALHOME/config
+    echo "repository hackage.haskell.org"               >> $CABALHOME/config
+    echo "  url: http://hackage.haskell.org/"           >> $CABALHOME/config
+  - |
+    if $HEADHACKAGE; then
+    echo "allow-newer: $($HCPKG list --simple-output | sed -E 's/([a-zA-Z-]+)-[0-9.]+/*:\1/g')" >> $CABALHOME/config
+    echo "repository head.hackage.ghc.haskell.org"                                        >> $CABALHOME/config
+    echo "   url: https://ghc.gitlab.haskell.org/head.hackage/"                           >> $CABALHOME/config
+    echo "   secure: True"                                                                >> $CABALHOME/config
+    echo "   root-keys: 7541f32a4ccca4f97aea3b22f5e593ba2c0267546016b992dfadcd2fe944e55d" >> $CABALHOME/config
+    echo "              26021a13b401500c8eb2761ca95c61f2d625bfef951b939a8124ed12ecf07329" >> $CABALHOME/config
+    echo "              f76d08be13e9a61a377a85e2fb63f4c5435d40f8feb3e12eb05905edb8cdea89" >> $CABALHOME/config
+    echo "   key-threshold: 3"                                                            >> $CABALHOME/config
     fi
-  - grep -Ev -- '^\s*--' ${HOME}/.cabal/config | grep -Ev '^\s*$'
-  - "printf 'packages: \".\" \"./examples\"\\n' > cabal.project"
-  - touch cabal.project.local
-  - "if ! $NOINSTALLEDCONSTRAINTS; then for pkg in $($HCPKG list --simple-output); do echo $pkg | sed 's/^/constraints: /' | sed 's/-[^-]*$/ installed/' >> cabal.project.local; done; fi"
+  - cat $CABALHOME/config
+  - rm -fv cabal.project cabal.project.local cabal.project.freeze
+  - travis_retry ${CABAL} v2-update -v
+  # Generate cabal.project
+  - rm -rf cabal.project cabal.project.local cabal.project.freeze
+  - touch cabal.project
+  - |
+    echo "packages: ." >> cabal.project
+    echo "packages: ./examples" >> cabal.project
+  - |
+  - "for pkg in $($HCPKG list --simple-output); do echo $pkg | sed 's/-[^-]*$//' | (grep -vE -- '^(trifecta|trifecta-examples)$' || true) | sed 's/^/constraints: /' | sed 's/$/ installed/' >> cabal.project.local; done"
   - cat cabal.project || true
   - cat cabal.project.local || true
-  - if [ -f "./configure.ac" ]; then
-      (cd "." && autoreconf -i);
-    fi
-  - if [ -f "./examples/configure.ac" ]; then
-      (cd "./examples" && autoreconf -i);
-    fi
-  - rm -f cabal.project.freeze
-  - cabal new-build -w ${HC} ${TEST} ${BENCH} --project-file="cabal.project" --dep -j2 all
-  - rm -rf .ghc.environment.* "."/dist "./examples"/dist
-  - DISTDIR=$(mktemp -d /tmp/dist-test.XXXX)
-
-# Here starts the actual work to be performed for the package under test;
-# any command which exits with a non-zero exit code causes the build to fail.
+  - if [ -f "./configure.ac" ]; then (cd "." && autoreconf -i); fi
+  - if [ -f "./examples/configure.ac" ]; then (cd "./examples" && autoreconf -i); fi
+  - ${CABAL} v2-freeze $WITHCOMPILER ${TEST} ${BENCH} | color_cabal_output
+  - "cat cabal.project.freeze | sed -E 's/^(constraints: *| *)//' | sed 's/any.//'"
+  - rm  cabal.project.freeze
+  - ${CABAL} v2-build $WITHCOMPILER ${TEST} ${BENCH} --dep -j2 all | color_cabal_output
 script:
-  # test that source-distributions can be generated
-  - (cd "." && cabal sdist)
-  - (cd "./examples" && cabal sdist)
-  - mv "."/dist/trifecta-*.tar.gz "./examples"/dist/trifecta-examples-*.tar.gz ${DISTDIR}/
+  - DISTDIR=$(mktemp -d /tmp/dist-test.XXXX)
+  # Packaging...
+  - ${CABAL} v2-sdist all | color_cabal_output
+  # Unpacking...
+  - mv dist-newstyle/sdist/*.tar.gz ${DISTDIR}/
   - cd ${DISTDIR} || false
-  - find . -maxdepth 1 -name '*.tar.gz' -exec tar -xvf '{}' \;
-  - "printf 'packages: trifecta-*/*.cabal trifecta-examples-*/*.cabal\\n' > cabal.project"
-  - touch cabal.project.local
-  - "if ! $NOINSTALLEDCONSTRAINTS; then for pkg in $($HCPKG list --simple-output); do echo $pkg | sed 's/^/constraints: /' | sed 's/-[^-]*$/ installed/' >> cabal.project.local; done; fi"
+  - find . -maxdepth 1 -type f -name '*.tar.gz' -exec tar -xvf '{}' \;
+  - find . -maxdepth 1 -type f -name '*.tar.gz' -exec rm       '{}' \;
+  - PKGDIR_trifecta="$(find . -maxdepth 1 -type d -regex '.*/trifecta-[0-9.]*')"
+  - PKGDIR_trifecta_examples="$(find . -maxdepth 1 -type d -regex '.*/trifecta-examples-[0-9.]*')"
+  # Generate cabal.project
+  - rm -rf cabal.project cabal.project.local cabal.project.freeze
+  - touch cabal.project
+  - |
+    echo "packages: ${PKGDIR_trifecta}" >> cabal.project
+    echo "packages: ${PKGDIR_trifecta_examples}" >> cabal.project
+  - |
+  - "for pkg in $($HCPKG list --simple-output); do echo $pkg | sed 's/-[^-]*$//' | (grep -vE -- '^(trifecta|trifecta-examples)$' || true) | sed 's/^/constraints: /' | sed 's/$/ installed/' >> cabal.project.local; done"
   - cat cabal.project || true
   - cat cabal.project.local || true
-
+  # Building with tests and benchmarks...
   # build & run tests, build benchmarks
-  - cabal new-build -w ${HC} ${TEST} ${BENCH} all
-  - if [ "x$TEST" = "x--enable-tests" ]; then cabal new-test -w ${HC} ${TEST} ${BENCH} all; fi
-
-  # cabal check
-  - (cd trifecta-* && cabal check)
-  - (cd trifecta-examples-* && cabal check)
-
-  # haddock
-  - rm -rf ./dist-newstyle
-  - if $HADDOCK; then cabal new-haddock -w ${HC} ${TEST} ${BENCH} all; else echo "Skipping haddock generation";fi
+  - ${CABAL} v2-build $WITHCOMPILER ${TEST} ${BENCH} all | color_cabal_output
+  # Testing...
+  - ${CABAL} v2-test $WITHCOMPILER ${TEST} ${BENCH} all | color_cabal_output
+  # cabal check...
+  - (cd ${PKGDIR_trifecta} && ${CABAL} -vnormal check)
+  - (cd ${PKGDIR_trifecta_examples} && ${CABAL} -vnormal check)
+  # haddock...
+  - ${CABAL} v2-haddock $WITHCOMPILER --with-haddock $HADDOCK ${TEST} ${BENCH} all | color_cabal_output
 
-# REGENDATA ["-o",".travis.yml","--ghc-head","--irc-channel=irc.freenode.org#haskell-lens","--no-no-tests-no-bench","--no-unconstrained","cabal.project"]
+# REGENDATA ["--output=.travis.yml","--config=cabal.haskell-ci","cabal.project"]
 # EOF
diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,13 @@
+2.1 [2019.09.06]
+----------------
+* Support building with `base-4.13` (GHC 8.8).
+* Dropped support for GHC < 7.8.
+* Print line numbers in the gutter.
+* Switched to `prettyprinter` from `ansi-wl-pprint`
+* Switched from `INLINE` to `INLINABLE` to help fight compile time woes
+  while still allowing aggressive inline when you want it.
+* Removed `Text.Trifecta.Util.Array`. `primitive` now exists.
+
 2 [2018.07.03]
 --------------
 * `stepParser` no longer takes a `ByteString`.
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright 2010-2017 Edward Kmett
+Copyright 2010-2019 Edward Kmett
 Copyright 2008 Ross Patterson
 Copyright 2007 Paolo Martini
 Copyright 1999-2000 Daan Leijen
diff --git a/examples/rfc2616/RFC2616.hs b/examples/rfc2616/RFC2616.hs
--- a/examples/rfc2616/RFC2616.hs
+++ b/examples/rfc2616/RFC2616.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE BangPatterns #-}
+{-# language BangPatterns #-}
 
 module RFC2616 where
 
diff --git a/examples/trifecta-examples.cabal b/examples/trifecta-examples.cabal
--- a/examples/trifecta-examples.cabal
+++ b/examples/trifecta-examples.cabal
@@ -8,21 +8,20 @@
 stability:     experimental
 homepage:      http://github.com/ekmett/trifecta/
 bug-reports:   http://github.com/ekmett/trifecta/issues
-copyright:     Copyright (C) 2010-2017 Edward A. Kmett
+copyright:     Copyright (C) 2010-2019 Edward A. Kmett
 synopsis:      A modern parser combinator library with convenient diagnostics
 description:
   A modern parser combinator library with slicing and Clang-style colored diagnostics
 cabal-version: >= 1.10
 build-type:    Simple
-tested-with:   GHC == 7.4.2
-             , GHC == 7.6.3
-             , GHC == 7.8.4
+tested-with:   GHC == 7.8.4
              , GHC == 7.10.3
              , GHC == 8.0.2
              , GHC == 8.2.2
-             , GHC == 8.4.3
-             , GHC == 8.6.1
-extra-source-files: RFC2616.txt
+             , GHC == 8.4.4
+             , GHC == 8.6.5
+             , GHC == 8.8.1
+extra-source-files: RFC2616.txt RFC2616-malformed.txt
 
 source-repository head
   type:     git
@@ -33,7 +32,7 @@
   ghc-options:         -Wall
   exposed-modules:     RFC2616
   hs-source-dirs:      rfc2616
-  build-depends:       base             >= 4.3     && <5,
+  build-depends:       base >= 4.7 && <5,
                        bytestring,
                        charset,
                        parsers,
diff --git a/images/example.png b/images/example.png
new file mode 100644
Binary files /dev/null and b/images/example.png differ
diff --git a/src/Text/Trifecta.hs b/src/Text/Trifecta.hs
--- a/src/Text/Trifecta.hs
+++ b/src/Text/Trifecta.hs
@@ -1,6 +1,6 @@
 -----------------------------------------------------------------------------
 -- |
--- Copyright   :  (C) 2011-2015 Edward Kmett
+-- Copyright   :  (C) 2011-2019 Edward Kmett
 -- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
diff --git a/src/Text/Trifecta/Combinators.hs b/src/Text/Trifecta/Combinators.hs
--- a/src/Text/Trifecta/Combinators.hs
+++ b/src/Text/Trifecta/Combinators.hs
@@ -1,13 +1,13 @@
-{-# LANGUAGE CPP                    #-}
-{-# LANGUAGE FlexibleContexts       #-}
-{-# LANGUAGE FlexibleInstances      #-}
-{-# LANGUAGE FunctionalDependencies #-}
-{-# LANGUAGE MultiParamTypeClasses  #-}
-{-# LANGUAGE UndecidableInstances   #-}
+{-# language CPP                    #-}
+{-# language FlexibleContexts       #-}
+{-# language FlexibleInstances      #-}
+{-# language FunctionalDependencies #-}
+{-# language MultiParamTypeClasses  #-}
+{-# language UndecidableInstances   #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Text.Trifecta.Combinators
--- Copyright   :  (c) Edward Kmett 2011-2015
+-- Copyright   :  (c) Edward Kmett 2011-2019
 -- License     :  BSD3
 --
 -- Maintainer  :  ekmett@gmail.com
@@ -64,141 +64,141 @@
   -- placing a 'Caret' there.
   rend :: m Rendering
   rend = rendered <$> position <*> line
-  {-# INLINE rend #-}
+  {-# inlinable rend #-}
 
   -- | Grab the remainder of the current line
   restOfLine :: m ByteString
   restOfLine = Strict.drop . fromIntegral . columnByte <$> position <*> line
-  {-# INLINE restOfLine #-}
+  {-# inlinable restOfLine #-}
 
 instance (MonadPlus m, DeltaParsing m) => DeltaParsing (Lazy.StateT s m) where
   line = lift line
-  {-# INLINE line #-}
+  {-# inlinable line #-}
   position = lift position
-  {-# INLINE position #-}
+  {-# inlinable position #-}
   slicedWith f (Lazy.StateT m) = Lazy.StateT $ \s -> slicedWith (\(a,s') b -> (f a b, s')) $ m s
-  {-# INLINE slicedWith #-}
+  {-# inlinable slicedWith #-}
   rend = lift rend
-  {-# INLINE rend #-}
+  {-# inlinable rend #-}
   restOfLine = lift restOfLine
-  {-# INLINE restOfLine #-}
+  {-# inlinable restOfLine #-}
 
 instance (MonadPlus m, DeltaParsing m) => DeltaParsing (Strict.StateT s m) where
   line = lift line
-  {-# INLINE line #-}
+  {-# inlinable line #-}
   position = lift position
-  {-# INLINE position #-}
+  {-# inlinable position #-}
   slicedWith f (Strict.StateT m) = Strict.StateT $ \s -> slicedWith (\(a,s') b -> (f a b, s')) $ m s
-  {-# INLINE slicedWith #-}
+  {-# inlinable slicedWith #-}
   rend = lift rend
-  {-# INLINE rend #-}
+  {-# inlinable rend #-}
   restOfLine = lift restOfLine
-  {-# INLINE restOfLine #-}
+  {-# inlinable restOfLine #-}
 
 instance (MonadPlus m, DeltaParsing m) => DeltaParsing (ReaderT e m) where
   line = lift line
-  {-# INLINE line #-}
+  {-# inlinable line #-}
   position = lift position
-  {-# INLINE position #-}
+  {-# inlinable position #-}
   slicedWith f (ReaderT m) = ReaderT $ slicedWith f . m
-  {-# INLINE slicedWith #-}
+  {-# inlinable slicedWith #-}
   rend = lift rend
-  {-# INLINE rend #-}
+  {-# inlinable rend #-}
   restOfLine = lift restOfLine
-  {-# INLINE restOfLine #-}
+  {-# inlinable restOfLine #-}
 
 instance (MonadPlus m, DeltaParsing m, Monoid w) => DeltaParsing (Strict.WriterT w m) where
   line = lift line
-  {-# INLINE line #-}
+  {-# inlinable line #-}
   position = lift position
-  {-# INLINE position #-}
+  {-# inlinable position #-}
   slicedWith f (Strict.WriterT m) = Strict.WriterT $ slicedWith (\(a,s') b -> (f a b, s')) m
-  {-# INLINE slicedWith #-}
+  {-# inlinable slicedWith #-}
   rend = lift rend
-  {-# INLINE rend #-}
+  {-# inlinable rend #-}
   restOfLine = lift restOfLine
-  {-# INLINE restOfLine #-}
+  {-# inlinable restOfLine #-}
 
 instance (MonadPlus m, DeltaParsing m, Monoid w) => DeltaParsing (Lazy.WriterT w m) where
   line = lift line
-  {-# INLINE line #-}
+  {-# inlinable line #-}
   position = lift position
-  {-# INLINE position #-}
+  {-# inlinable position #-}
   slicedWith f (Lazy.WriterT m) = Lazy.WriterT $ slicedWith (\(a,s') b -> (f a b, s')) m
-  {-# INLINE slicedWith #-}
+  {-# inlinable slicedWith #-}
   rend = lift rend
-  {-# INLINE rend #-}
+  {-# inlinable rend #-}
   restOfLine = lift restOfLine
-  {-# INLINE restOfLine #-}
+  {-# inlinable restOfLine #-}
 
 instance (MonadPlus m, DeltaParsing m, Monoid w) => DeltaParsing (Lazy.RWST r w s m) where
   line = lift line
-  {-# INLINE line #-}
+  {-# inlinable line #-}
   position = lift position
-  {-# INLINE position #-}
+  {-# inlinable position #-}
   slicedWith f (Lazy.RWST m) = Lazy.RWST $ \r s -> slicedWith (\(a,s',w) b -> (f a b, s',w)) $ m r s
-  {-# INLINE slicedWith #-}
+  {-# inlinable slicedWith #-}
   rend = lift rend
-  {-# INLINE rend #-}
+  {-# inlinable rend #-}
   restOfLine = lift restOfLine
-  {-# INLINE restOfLine #-}
+  {-# inlinable restOfLine #-}
 
 instance (MonadPlus m, DeltaParsing m, Monoid w) => DeltaParsing (Strict.RWST r w s m) where
   line = lift line
-  {-# INLINE line #-}
+  {-# inlinable line #-}
   position = lift position
-  {-# INLINE position #-}
+  {-# inlinable position #-}
   slicedWith f (Strict.RWST m) = Strict.RWST $ \r s -> slicedWith (\(a,s',w) b -> (f a b, s',w)) $ m r s
-  {-# INLINE slicedWith #-}
+  {-# inlinable slicedWith #-}
   rend = lift rend
-  {-# INLINE rend #-}
+  {-# inlinable rend #-}
   restOfLine = lift restOfLine
-  {-# INLINE restOfLine #-}
+  {-# inlinable restOfLine #-}
 
 instance (MonadPlus m, DeltaParsing m) => DeltaParsing (IdentityT m) where
   line = lift line
-  {-# INLINE line #-}
+  {-# inlinable line #-}
   position = lift position
-  {-# INLINE position #-}
+  {-# inlinable position #-}
   slicedWith f (IdentityT m) = IdentityT $ slicedWith f m
-  {-# INLINE slicedWith #-}
+  {-# inlinable slicedWith #-}
   rend = lift rend
-  {-# INLINE rend #-}
+  {-# inlinable rend #-}
   restOfLine = lift restOfLine
-  {-# INLINE restOfLine #-}
+  {-# inlinable restOfLine #-}
 
 -- | Run a parser, grabbing all of the text between its start and end points and
 -- discarding the original result
 sliced :: DeltaParsing m => m a -> m ByteString
 sliced = slicedWith (\_ bs -> bs)
-{-# INLINE sliced #-}
+{-# inlinable sliced #-}
 
 -- | Grab a 'Caret' pointing to the current location.
 careting :: DeltaParsing m => m Caret
 careting = Caret <$> position <*> line
-{-# INLINE careting #-}
+{-# inlinable careting #-}
 
 -- | Parse a 'Careted' result. Pointing the 'Caret' to where you start.
 careted :: DeltaParsing m => m a -> m (Careted a)
 careted p = (\m l a -> a :^ Caret m l) <$> position <*> line <*> p
-{-# INLINE careted #-}
+{-# inlinable careted #-}
 
 -- | Discard the result of a parse, returning a 'Span' from where we start to
 -- where it ended parsing.
 spanning :: DeltaParsing m => m a -> m Span
 spanning p = (\s l e -> Span s e l) <$> position <*> line <*> (p *> position)
-{-# INLINE spanning #-}
+{-# inlinable spanning #-}
 
 -- | Parse a 'Spanned' result. The 'Span' starts here and runs to the last
 -- position parsed.
 spanned :: DeltaParsing m => m a -> m (Spanned a)
 spanned p = (\s l a e -> a :~ Span s e l) <$> position <*> line <*> p <*> position
-{-# INLINE spanned #-}
+{-# inlinable spanned #-}
 
 -- | Grab a fixit.
 fixiting :: DeltaParsing m => m Strict.ByteString -> m Fixit
 fixiting p = (\(r :~ s) -> Fixit s r) <$> spanned p
-{-# INLINE fixiting #-}
+{-# inlinable fixiting #-}
 
 -- | This class is a refinement of 'DeltaParsing' that adds the ability to mark
 -- your position in the input and return there for further parsing later.
@@ -211,48 +211,48 @@
 
 instance (MonadPlus m, MarkParsing d m) => MarkParsing d (Lazy.StateT s m) where
   mark = lift mark
-  {-# INLINE mark #-}
+  {-# inlinable mark #-}
   release = lift . release
-  {-# INLINE release #-}
+  {-# inlinable release #-}
 
 instance (MonadPlus m, MarkParsing d m) => MarkParsing d (Strict.StateT s m) where
   mark = lift mark
-  {-# INLINE mark #-}
+  {-# inlinable mark #-}
   release = lift . release
-  {-# INLINE release #-}
+  {-# inlinable release #-}
 
 instance (MonadPlus m, MarkParsing d m) => MarkParsing d (ReaderT e m) where
   mark = lift mark
-  {-# INLINE mark #-}
+  {-# inlinable mark #-}
   release = lift . release
-  {-# INLINE release #-}
+  {-# inlinable release #-}
 
 instance (MonadPlus m, MarkParsing d m, Monoid w) => MarkParsing d (Strict.WriterT w m) where
   mark = lift mark
-  {-# INLINE mark #-}
+  {-# inlinable mark #-}
   release = lift . release
-  {-# INLINE release #-}
+  {-# inlinable release #-}
 
 instance (MonadPlus m, MarkParsing d m, Monoid w) => MarkParsing d (Lazy.WriterT w m) where
   mark = lift mark
-  {-# INLINE mark #-}
+  {-# inlinable mark #-}
   release = lift . release
-  {-# INLINE release #-}
+  {-# inlinable release #-}
 
 instance (MonadPlus m, MarkParsing d m, Monoid w) => MarkParsing d (Lazy.RWST r w s m) where
   mark = lift mark
-  {-# INLINE mark #-}
+  {-# inlinable mark #-}
   release = lift . release
-  {-# INLINE release #-}
+  {-# inlinable release #-}
 
 instance (MonadPlus m, MarkParsing d m, Monoid w) => MarkParsing d (Strict.RWST r w s m) where
   mark = lift mark
-  {-# INLINE mark #-}
+  {-# inlinable mark #-}
   release = lift . release
-  {-# INLINE release #-}
+  {-# inlinable release #-}
 
 instance (MonadPlus m, MarkParsing d m) => MarkParsing d (IdentityT m) where
   mark = lift mark
-  {-# INLINE mark #-}
+  {-# inlinable mark #-}
   release = lift . release
-  {-# INLINE release #-}
+  {-# inlinable release #-}
diff --git a/src/Text/Trifecta/Delta.hs b/src/Text/Trifecta/Delta.hs
--- a/src/Text/Trifecta/Delta.hs
+++ b/src/Text/Trifecta/Delta.hs
@@ -1,9 +1,9 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE DeriveGeneric #-}
+{-# language CPP #-}
+{-# language DeriveDataTypeable #-}
+{-# language DeriveGeneric #-}
 -----------------------------------------------------------------------------
 -- |
--- Copyright   :  (C) 2011-2015 Edward Kmett
+-- Copyright   :  (C) 2011-2019 Edward Kmett
 -- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
@@ -17,6 +17,7 @@
   ( Delta(..)
   , HasDelta(..)
   , HasBytes(..)
+  , prettyDelta
   , nextTab
   , rewind
   , near
@@ -38,10 +39,10 @@
 import Data.FingerTree hiding (empty)
 import Data.ByteString as Strict hiding (empty)
 import qualified Data.ByteString.UTF8 as UTF8
+import Data.Text.Prettyprint.Doc hiding (column, line')
 import GHC.Generics
-import Text.PrettyPrint.ANSI.Leijen hiding (column, (<>))
 
-import Text.Trifecta.Instances ()
+import Text.Trifecta.Util.Pretty
 
 class HasBytes t where
   bytes :: t -> Int64
@@ -106,26 +107,23 @@
   delta = either delta delta
 
 -- | Example: @file.txt:12:34@
-instance Pretty Delta where
-    pretty d = case d of
-        Columns c _         -> prettyDelta interactive 0 c
-        Tab x y _           -> prettyDelta interactive 0 (nextTab x + y)
-        Lines l c _ _       -> prettyDelta interactive l c
-        Directed fn l c _ _ -> prettyDelta (UTF8.toString fn) l c
-      where
-        prettyDelta
-            :: String -- Source description
-            -> Int64  -- Line
-            -> Int64  -- Column
-            -> Doc
-        prettyDelta source line' column'
-          = bold (pretty source)
-            <> char ':' <> bold (int64 (line'+1))
-            <> char ':' <> bold (int64 (column'+1))
-        interactive = "(interactive)"
-
-int64 :: Int64 -> Doc
-int64 = pretty . show
+prettyDelta :: Delta -> Doc AnsiStyle
+prettyDelta d = case d of
+    Columns c _         -> go interactive 0 c
+    Tab x y _           -> go interactive 0 (nextTab x + y)
+    Lines l c _ _       -> go interactive l c
+    Directed fn l c _ _ -> go (UTF8.toString fn) l c
+  where
+    go
+        :: String -- Source description
+        -> Int64  -- Line
+        -> Int64  -- Column
+        -> Doc AnsiStyle
+    go source line' column'
+      = annotate bold (pretty source)
+        <> char ':' <> annotate bold (pretty (line'+1))
+        <> char ':' <> annotate bold (pretty (column'+1))
+    interactive = "(interactive)"
 
 -- | Retrieve the character offset within the current line from this 'Delta'.
 column :: HasDelta t => t -> Int64
@@ -134,7 +132,7 @@
   Tab b a _ -> nextTab b + a
   Lines _ c _ _ -> c
   Directed _ _ c _ _ -> c
-{-# INLINE column #-}
+{-# inlinable column #-}
 
 -- | Retrieve the byte offset within the current line from this 'Delta'.
 columnByte :: Delta -> Int64
@@ -142,7 +140,7 @@
 columnByte (Tab _ _ b) = b
 columnByte (Lines _ _ _ b) = b
 columnByte (Directed _ _ _ _ b) = b
-{-# INLINE columnByte #-}
+{-# inlinable columnByte #-}
 
 instance HasBytes Delta where
   bytes (Columns _ b) = b
@@ -177,14 +175,14 @@
 -- | Increment a column number to the next tabstop.
 nextTab :: Int64 -> Int64
 nextTab x = x + (8 - mod x 8)
-{-# INLINE nextTab #-}
+{-# inlinable nextTab #-}
 
 -- | Rewind a 'Delta' to the beginning of the line.
 rewind :: Delta -> Delta
 rewind (Lines n _ b d)      = Lines n 0 (b - d) 0
 rewind (Directed p n _ b d) = Directed p n 0 (b - d) 0
 rewind _                    = Columns 0 0
-{-# INLINE rewind #-}
+{-# inlinable rewind #-}
 
 -- | Should we show two things with a 'Delta' on the same line?
 --
@@ -195,7 +193,7 @@
 -- False
 near :: (HasDelta s, HasDelta t) => s -> t -> Bool
 near s t = rewind (delta s) == rewind (delta t)
-{-# INLINE near #-}
+{-# inlinable near #-}
 
 class HasDelta t where
   delta :: t -> Delta
diff --git a/src/Text/Trifecta/Highlight.hs b/src/Text/Trifecta/Highlight.hs
--- a/src/Text/Trifecta/Highlight.hs
+++ b/src/Text/Trifecta/Highlight.hs
@@ -1,13 +1,13 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE TemplateHaskell #-}
+{-# language CPP #-}
+{-# language OverloadedStrings #-}
+{-# language TemplateHaskell #-}
 
 #ifndef MIN_VERSION_lens
 #define MIN_VERSION_lens(x,y,z) 1
 #endif
 -----------------------------------------------------------------------------
 -- |
--- Copyright   :  (C) 2011-2015 Edward Kmett
+-- Copyright   :  (C) 2011-2019 Edward Kmett
 -- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
@@ -34,6 +34,9 @@
 import Data.List (sort)
 import Data.Semigroup
 import Data.Semigroup.Union
+import Data.Text.Prettyprint.Doc
+import Data.Text.Prettyprint.Doc.Render.Terminal (color)
+import qualified Data.Text.Prettyprint.Doc.Render.Terminal as Pretty
 import Prelude hiding (head)
 import Text.Blaze
 import Text.Blaze.Html5 hiding (a,b,i)
@@ -41,27 +44,26 @@
 import Text.Blaze.Html5.Attributes hiding (title,id)
 import Text.Blaze.Internal (MarkupM(Empty, Leaf))
 import Text.Parser.Token.Highlight
-import Text.PrettyPrint.ANSI.Leijen hiding ((<>))
 import qualified Data.ByteString.Lazy.Char8 as L
-import qualified Data.ByteString.Lazy.UTF8 as LazyUTF8
 
-import Text.Trifecta.Util.IntervalMap as IM
 import Text.Trifecta.Delta
 import Text.Trifecta.Rope
+import Text.Trifecta.Util.IntervalMap as IM
+import Text.Trifecta.Util.Pretty
 
 -- | Convert a 'Highlight' into a coloration on a 'Doc'.
-withHighlight :: Highlight -> Doc -> Doc
-withHighlight Comment                     = blue
-withHighlight ReservedIdentifier          = magenta
-withHighlight ReservedConstructor         = magenta
-withHighlight EscapeCode                  = magenta
-withHighlight Operator                    = yellow
-withHighlight CharLiteral                 = cyan
-withHighlight StringLiteral               = cyan
-withHighlight Constructor                 = bold
-withHighlight ReservedOperator            = yellow
-withHighlight ConstructorOperator         = yellow
-withHighlight ReservedConstructorOperator = yellow
+withHighlight :: Highlight -> Doc AnsiStyle -> Doc AnsiStyle
+withHighlight Comment                     = annotate (color Pretty.Blue)
+withHighlight ReservedIdentifier          = annotate (color Pretty.Magenta)
+withHighlight ReservedConstructor         = annotate (color Pretty.Magenta)
+withHighlight EscapeCode                  = annotate (color Pretty.Magenta)
+withHighlight Operator                    = annotate (color Pretty.Yellow)
+withHighlight CharLiteral                 = annotate (color Pretty.Cyan)
+withHighlight StringLiteral               = annotate (color Pretty.Cyan)
+withHighlight Constructor                 = annotate Pretty.bold
+withHighlight ReservedOperator            = annotate (color Pretty.Yellow)
+withHighlight ConstructorOperator         = annotate (color Pretty.Yellow)
+withHighlight ReservedConstructorOperator = annotate (color Pretty.Yellow)
 withHighlight _                           = id
 
 -- | A 'HighlightedRope' is a 'Rope' with an associated 'IntervalMap' full of highlighted regions.
@@ -114,16 +116,6 @@
     emptyMarkup = Empty
     leafMarkup a b c = Leaf a b c
 #endif
-
-instance Pretty HighlightedRope where
-  pretty (HighlightedRope intervals r) = go mempty lbs boundaries where
-    lbs = L.fromChunks [bs | Strand bs _ <- F.toList (strands r)]
-    ints = intersections mempty (delta r) intervals
-    boundaries = sort [ i | (Interval lo hi, _) <- ints, i <- [ lo, hi ] ]
-    dominated l h = Prelude.foldr (fmap . withHighlight . snd) id (dominators l h intervals)
-    go l cs [] = dominated l (delta r) $ pretty (LazyUTF8.toString cs)
-    go l cs (h:es) = dominated l h (pretty (LazyUTF8.toString om)) <> go h nom es
-      where (om,nom) = L.splitAt (fromIntegral (bytes h - bytes l)) cs
 
 -- | Represents a source file like an HsColour rendered document
 data HighlightDoc = HighlightDoc
diff --git a/src/Text/Trifecta/Instances.hs b/src/Text/Trifecta/Instances.hs
deleted file mode 100644
--- a/src/Text/Trifecta/Instances.hs
+++ /dev/null
@@ -1,22 +0,0 @@
-{-# LANGUAGE CPP #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
------------------------------------------------------------------------------
--- |
--- Copyright   :  (c) Edward Kmett 2013-2015
--- License     :  BSD3
---
--- Maintainer  :  ekmett@gmail.com
--- Stability   :  experimental
--- Portability :  non-portable
---
--- Orphan instances we need to remain sane.
------------------------------------------------------------------------------
-module Text.Trifecta.Instances () where
-
-#if !MIN_VERSION_ansi_wl_pprint(0,6,8)
-import qualified Data.Semigroup               as Data
-import           Text.PrettyPrint.ANSI.Leijen
-
-instance Data.Semigroup Doc where
-  (<>) = (<>)
-#endif
diff --git a/src/Text/Trifecta/Parser.hs b/src/Text/Trifecta/Parser.hs
--- a/src/Text/Trifecta/Parser.hs
+++ b/src/Text/Trifecta/Parser.hs
@@ -1,17 +1,17 @@
-{-# LANGUAGE BangPatterns           #-}
-{-# LANGUAGE CPP                    #-}
-{-# LANGUAGE DeriveFoldable         #-}
-{-# LANGUAGE DeriveFunctor          #-}
-{-# LANGUAGE DeriveTraversable      #-}
-{-# LANGUAGE FlexibleContexts       #-}
-{-# LANGUAGE FlexibleInstances      #-}
-{-# LANGUAGE FunctionalDependencies #-}
-{-# LANGUAGE MultiParamTypeClasses  #-}
-{-# LANGUAGE Rank2Types             #-}
-{-# LANGUAGE TemplateHaskell        #-}
+{-# language BangPatterns           #-}
+{-# language CPP                    #-}
+{-# language DeriveFoldable         #-}
+{-# language DeriveFunctor          #-}
+{-# language DeriveTraversable      #-}
+{-# language FlexibleContexts       #-}
+{-# language FlexibleInstances      #-}
+{-# language FunctionalDependencies #-}
+{-# language MultiParamTypeClasses  #-}
+{-# language Rank2Types             #-}
+{-# language TemplateHaskell        #-}
 -----------------------------------------------------------------------------
 -- |
--- Copyright   :  (c) Edward Kmett 2011-2015
+-- Copyright   :  (c) Edward Kmett 2011-2019
 -- License     :  BSD3
 --
 -- Maintainer  :  ekmett@gmail.com
@@ -51,19 +51,19 @@
 import Data.Semigroup.Reducer
 -- import Data.Sequence as Seq hiding (empty)
 import Data.Set as Set hiding (empty, toList)
+import Data.Text.Prettyprint.Doc as Pretty hiding (line)
 import System.IO
 import Text.Parser.Combinators
 import Text.Parser.Char
 import Text.Parser.LookAhead
 import Text.Parser.Token
-import Text.PrettyPrint.ANSI.Leijen as Pretty hiding (line, (<>), (<$>), empty)
 import Text.Trifecta.Combinators
 import Text.Trifecta.Delta       as Delta
-import Text.Trifecta.Instances   ()
 import Text.Trifecta.Rendering
 import Text.Trifecta.Result
 import Text.Trifecta.Rope
 import Text.Trifecta.Util.It
+import Text.Trifecta.Util.Pretty
 
 -- | The type of a trifecta parser
 --
@@ -111,40 +111,40 @@
 
 instance Functor Parser where
   fmap f (Parser m) = Parser $ \ eo ee co -> m (eo . f) ee (co . f)
-  {-# INLINE fmap #-}
+  {-# inlinable fmap #-}
   a <$ Parser m = Parser $ \ eo ee co -> m (\_ -> eo a) ee (\_ -> co a)
-  {-# INLINE (<$) #-}
+  {-# inlinable (<$) #-}
 
 instance Applicative Parser where
   pure a = Parser $ \ eo _ _ _ _ _ -> eo a mempty
-  {-# INLINE pure #-}
+  {-# inlinable pure #-}
   (<*>) = ap
-  {-# INLINE (<*>) #-}
+  {-# inlinable (<*>) #-}
 
 instance Alternative Parser where
   empty = Parser $ \_ ee _ _ _ _ -> ee mempty
-  {-# INLINE empty #-}
+  {-# inlinable empty #-}
   Parser m <|> Parser n = Parser $ \ eo ee co ce d bs ->
     m eo (\e -> n (\a e' -> eo a (e <> e')) (\e' -> ee (e <> e')) co ce d bs) co ce d bs
-  {-# INLINE (<|>) #-}
+  {-# inlinable (<|>) #-}
   many p = Prelude.reverse <$> manyAccum (:) p
-  {-# INLINE many #-}
+  {-# inlinable many #-}
   some p = (:) <$> p <*> Alternative.many p
 
 instance Semigroup a => Semigroup (Parser a) where
   (<>) = liftA2 (<>)
-  {-# INLINE (<>) #-}
+  {-# inlinable (<>) #-}
 
 instance (Semigroup a, Monoid a) => Monoid (Parser a) where
   mappend = (<>)
-  {-# INLINE mappend #-}
+  {-# inlinable mappend #-}
 
   mempty = pure mempty
-  {-# INLINE mempty #-}
+  {-# inlinable mempty #-}
 
 instance Monad Parser where
   return = pure
-  {-# INLINE return #-}
+  {-# inlinable return #-}
   Parser m >>= k = Parser $ \ eo ee co ce d bs ->
     m -- epsilon result: feed result to monadic continutaion; committed
       -- continuations as they were given to us; epsilon callbacks merge
@@ -174,21 +174,23 @@
          d' bs')
       -- committed error, delta, and bytestring: as given
       ce d bs
-  {-# INLINE (>>=) #-}
+  {-# inlinable (>>=) #-}
   (>>) = (*>)
-  {-# INLINE (>>) #-}
+  {-# inlinable (>>) #-}
+#if !(MIN_VERSION_base(4,13,0))
   fail = Fail.fail
-  {-# INLINE fail #-}
+  {-# inlinable fail #-}
+#endif
 
 instance Fail.MonadFail Parser where
   fail s = Parser $ \ _ ee _ _ _ _ -> ee (failed s)
-  {-# INLINE fail #-}
+  {-# inlinable fail #-}
 
 instance MonadPlus Parser where
   mzero = empty
-  {-# INLINE mzero #-}
+  {-# inlinable mzero #-}
   mplus = (<|>)
-  {-# INLINE mplus #-}
+  {-# inlinable mplus #-}
 
 manyAccum :: (a -> [a] -> [a]) -> Parser a -> Parser [a]
 manyAccum f (Parser p) = Parser $ \eo _ co ce d bs ->
@@ -201,31 +203,31 @@
 liftIt m = Parser $ \ eo _ _ _ _ _ -> do
   a <- m
   eo a mempty
-{-# INLINE liftIt #-}
+{-# inlinable liftIt #-}
 
 instance Parsing Parser where
   try (Parser m) = Parser $ \ eo ee co _ -> m eo ee co (\_ -> ee mempty)
-  {-# INLINE try #-}
+  {-# inlinable try #-}
   Parser m <?> nm = Parser $ \ eo ee -> m
      (\a e -> eo a (if isJust (_reason e) then e { _expected = Set.singleton nm } else e))
      (\e -> ee e { _expected = Set.singleton nm })
-  {-# INLINE (<?>) #-}
+  {-# inlinable (<?>) #-}
   skipMany p = () <$ manyAccum (\_ _ -> []) p
-  {-# INLINE skipMany #-}
+  {-# inlinable skipMany #-}
   unexpected s = Parser $ \ _ ee _ _ _ _ -> ee $ failed $ "unexpected " ++ s
-  {-# INLINE unexpected #-}
+  {-# inlinable unexpected #-}
   eof = notFollowedBy anyChar <?> "end of input"
-  {-# INLINE eof #-}
+  {-# inlinable eof #-}
   notFollowedBy p = try (optional p >>= maybe (pure ()) (unexpected . show))
-  {-# INLINE notFollowedBy #-}
+  {-# inlinable notFollowedBy #-}
 
 instance Errable Parser where
   raiseErr e = Parser $ \ _ ee _ _ _ _ -> ee e
-  {-# INLINE raiseErr #-}
+  {-# inlinable raiseErr #-}
 
 instance LookAheadParsing Parser where
   lookAhead (Parser m) = Parser $ \eo ee _ -> m eo ee (\a _ _ _ -> eo a mempty)
-  {-# INLINE lookAhead #-}
+  {-# inlinable lookAhead #-}
 
 instance CharParsing Parser where
   satisfy f = Parser $ \ _ ee co _ d bs ->
@@ -238,27 +240,27 @@
                                               (co c mempty)
                                               ddc
         | otherwise       -> co c mempty (d <> delta c) bs
-  {-# INLINE satisfy #-}
+  {-# inlinable satisfy #-}
 
 instance TokenParsing Parser
 
 instance DeltaParsing Parser where
   line = Parser $ \eo _ _ _ _ bs -> eo bs mempty
-  {-# INLINE line #-}
+  {-# inlinable line #-}
   position = Parser $ \eo _ _ _ d _ -> eo d mempty
-  {-# INLINE position #-}
+  {-# inlinable position #-}
   rend = Parser $ \eo _ _ _ d bs -> eo (rendered d bs) mempty
-  {-# INLINE rend #-}
+  {-# inlinable rend #-}
   slicedWith f p = do
     m <- position
     a <- p
     r <- position
     f a <$> liftIt (sliceIt m r)
-  {-# INLINE slicedWith #-}
+  {-# inlinable slicedWith #-}
 
 instance MarkParsing Delta Parser where
   mark = position
-  {-# INLINE mark #-}
+  {-# inlinable mark #-}
   release d' = Parser $ \_ ee co _ d bs -> do
     mbs <- rewindIt d'
     case mbs of
@@ -307,7 +309,7 @@
 feed t (StepDone r a)    = StepDone (snoc r t) a
 feed t (StepFail r xs)   = StepFail (snoc r t) xs
 feed t (StepCont r _ k)  = k (snoc r t)
-{-# INLINE feed #-}
+{-# inlinable feed #-}
 
 -- | Assume all possible input has been given to the parser, execute it to yield
 -- a final result.
@@ -315,19 +317,19 @@
 starve (StepDone _ a)    = Success a
 starve (StepFail _ xs)   = Failure xs
 starve (StepCont _ z _)  = z
-{-# INLINE starve #-}
+{-# inlinable starve #-}
 
 stepResult :: Rope -> Result a -> Step a
 stepResult r (Success a)  = StepDone r a
 stepResult r (Failure xs) = StepFail r xs
-{-# INLINE stepResult #-}
+{-# inlinable stepResult #-}
 
 stepIt :: It Rope a -> Step a
 stepIt = go mempty where
   go r m = case simplifyIt m r of
     Pure a -> StepDone r a
     It a k -> StepCont r (pure a) $ \r' -> go r' (k r')
-{-# INLINE stepIt #-}
+{-# inlinable stepIt #-}
 
 data Stepping a
   = EO a Err
@@ -363,7 +365,7 @@
   joinStep (StepDone r (Failure e)) = StepFail r e
   joinStep (StepFail r e)           = StepFail r e
   joinStep (StepCont r a k)         = StepCont r (join a) (joinStep <$> k)
-  {-# INLINE joinStep #-}
+  {-# inlinable joinStep #-}
 
 -- | Run a 'Parser' on input that can be reduced to a 'Rope', e.g. 'String', or
 -- 'ByteString'. See also the monomorphic versions 'parseString' and
@@ -375,7 +377,7 @@
     -> t
     -> Result a
 runParser p d bs = starve $ feed bs $ stepParser p d
-{-# INLINE runParser #-}
+{-# inlinable runParser #-}
 
 -- | @('parseFromFile' p filePath)@ runs a parser @p@ on the input read from
 -- @filePath@ using 'ByteString.readFile'. All diagnostic messages emitted over
@@ -392,7 +394,7 @@
   case result of
    Success a  -> return (Just a)
    Failure xs -> do
-     liftIO $ displayIO stdout $ renderPretty 0.8 80 $ (_errDoc xs) <> linebreak
+     liftIO $ renderIO stdout $ renderPretty 0.8 80 $ (_errDoc xs) <> line'
      return Nothing
 
 -- | @('parseFromFileEx' p filePath)@ runs a parser @p@ on the input read from
@@ -432,5 +434,5 @@
 
 parseTest :: (MonadIO m, Show a) => Parser a -> String -> m ()
 parseTest p s = case parseByteString p mempty (UTF8.fromString s) of
-  Failure xs -> liftIO $ displayIO stdout $ renderPretty 0.8 80 $ (_errDoc xs) <> linebreak -- TODO: retrieve columns
+  Failure xs -> liftIO $ renderIO stdout $ renderPretty 0.8 80 $ (_errDoc xs) <> line' -- TODO: retrieve columns
   Success a  -> liftIO (print a)
diff --git a/src/Text/Trifecta/Rendering.hs b/src/Text/Trifecta/Rendering.hs
--- a/src/Text/Trifecta/Rendering.hs
+++ b/src/Text/Trifecta/Rendering.hs
@@ -1,12 +1,12 @@
-{-# LANGUAGE DeriveDataTypeable    #-}
-{-# LANGUAGE DeriveGeneric         #-}
-{-# LANGUAGE FlexibleInstances     #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE TemplateHaskell       #-}
-{-# LANGUAGE TypeSynonymInstances  #-}
+{-# language DeriveDataTypeable    #-}
+{-# language DeriveGeneric         #-}
+{-# language FlexibleInstances     #-}
+{-# language MultiParamTypeClasses #-}
+{-# language TemplateHaskell       #-}
+{-# language TypeSynonymInstances  #-}
 -----------------------------------------------------------------------------
 -- |
--- Copyright   :  (C) 2011-2015 Edward Kmett
+-- Copyright   :  (C) 2011-2019 Edward Kmett
 -- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
@@ -24,10 +24,12 @@
   , HasRendering(..)
   , nullRendering
   , emptyRendering
+  , prettyRendering
   , Source(..)
   , rendered
   , Renderable(..)
   , Rendered(..)
+  , gutterEffects
   -- * Carets
   , Caret(..)
   , HasCaret(..)
@@ -59,30 +61,32 @@
 import           Control.Comonad
 import           Control.Lens
 import           Data.Array
-import           Data.ByteString              as B hiding (any, empty, groupBy)
-import qualified Data.ByteString.UTF8         as UTF8
+import           Data.ByteString                              as B hiding (any, empty, groupBy)
+import qualified Data.ByteString.UTF8                         as UTF8
 import           Data.Data
 import           Data.Foldable
-import           Data.Function                (on)
+import           Data.Function                                (on)
 import           Data.Hashable
-import           Data.Int                     (Int64)
-import           Data.List                    (groupBy)
+import           Data.Int                                     (Int64)
+import           Data.List                                    (groupBy)
 import           Data.Maybe
+import           Data.Text.Prettyprint.Doc                    hiding (column, line')
+import           Data.Text.Prettyprint.Doc.Render.Terminal    (color, bgColor, colorDull, bgColorDull)
+import qualified Data.Text.Prettyprint.Doc.Render.Terminal    as Pretty
 import           Data.Semigroup
 import           Data.Semigroup.Reducer
 import           GHC.Generics
-import           Prelude                      as P hiding (span)
+import           Prelude                                      as P hiding (span)
 import           System.Console.ANSI
-import           Text.PrettyPrint.ANSI.Leijen hiding (column, (<$>), (<>))
 
 import Text.Trifecta.Delta
-import Text.Trifecta.Instances        ()
 import Text.Trifecta.Util.Combinators
+import Text.Trifecta.Util.Pretty
 
 -- $setup
 --
 -- >>> :set -XOverloadedStrings
--- >>> import Text.PrettyPrint.ANSI.Leijen (pretty, plain)
+-- >>> import Data.Text.Prettyprint.Doc (unAnnotate)
 -- >>> import Data.ByteString (ByteString)
 -- >>> import Data.Monoid (mempty)
 -- >>> import Text.Trifecta.Delta
@@ -91,52 +95,52 @@
 outOfRangeEffects :: [SGR] -> [SGR]
 outOfRangeEffects xs = SetConsoleIntensity BoldIntensity : xs
 
-sgr :: [SGR] -> Doc -> Doc
+sgr :: [SGR] -> Doc AnsiStyle -> Doc AnsiStyle
 sgr xs0 = go (P.reverse xs0) where
   go []                                         = id
-  go (SetConsoleIntensity NormalIntensity : xs) = debold . go xs
-  go (SetConsoleIntensity BoldIntensity   : xs) = bold . go xs
-  go (SetUnderlining NoUnderline          : xs) = deunderline . go xs
-  go (SetUnderlining SingleUnderline      : xs) = underline . go xs
+  go (SetConsoleIntensity NormalIntensity : xs) = annotate debold . go xs
+  go (SetConsoleIntensity BoldIntensity   : xs) = annotate bold . go xs
+  go (SetUnderlining NoUnderline          : xs) = annotate deunderline . go xs
+  go (SetUnderlining SingleUnderline      : xs) = annotate underlined . go xs
   go (SetColor f i c                      : xs) = case f of
     Foreground -> case i of
       Dull -> case c of
-        Black   -> dullblack . go xs
-        Red     -> dullred . go xs
-        Green   -> dullgreen . go xs
-        Yellow  -> dullyellow . go xs
-        Blue    -> dullblue . go xs
-        Magenta -> dullmagenta . go xs
-        Cyan    -> dullcyan . go xs
-        White   -> dullwhite . go xs
+        Black   -> annotate (color Pretty.Black) . go xs
+        Red     -> annotate (color Pretty.Red) . go xs
+        Green   -> annotate (color Pretty.Green) . go xs
+        Yellow  -> annotate (color Pretty.Yellow) . go xs
+        Blue    -> annotate (color Pretty.Blue) . go xs
+        Magenta -> annotate (color Pretty.Magenta) . go xs
+        Cyan    -> annotate (color Pretty.Cyan) . go xs
+        White   -> annotate (color Pretty.White) . go xs
       Vivid -> case c of
-        Black   -> black . go xs
-        Red     -> red . go xs
-        Green   -> green . go xs
-        Yellow  -> yellow . go xs
-        Blue    -> blue . go xs
-        Magenta -> magenta . go xs
-        Cyan    -> cyan . go xs
-        White   -> white . go xs
+        Black   -> annotate (colorDull Pretty.Black) . go xs
+        Red     -> annotate (colorDull Pretty.Red) . go xs
+        Green   -> annotate (colorDull Pretty.Green) . go xs
+        Yellow  -> annotate (colorDull Pretty.Yellow) . go xs
+        Blue    -> annotate (colorDull Pretty.Blue) . go xs
+        Magenta -> annotate (colorDull Pretty.Magenta) . go xs
+        Cyan    -> annotate (colorDull Pretty.Cyan) . go xs
+        White   -> annotate (colorDull Pretty.White) . go xs
     Background -> case i of
       Dull -> case c of
-        Black   -> ondullblack . go xs
-        Red     -> ondullred . go xs
-        Green   -> ondullgreen . go xs
-        Yellow  -> ondullyellow . go xs
-        Blue    -> ondullblue . go xs
-        Magenta -> ondullmagenta . go xs
-        Cyan    -> ondullcyan . go xs
-        White   -> ondullwhite . go xs
+        Black   -> annotate (bgColorDull Pretty.Black) . go xs
+        Red     -> annotate (bgColorDull Pretty.Red) . go xs
+        Green   -> annotate (bgColorDull Pretty.Green) . go xs
+        Yellow  -> annotate (bgColorDull Pretty.Yellow) . go xs
+        Blue    -> annotate (bgColorDull Pretty.Blue) . go xs
+        Magenta -> annotate (bgColorDull Pretty.Magenta) . go xs
+        Cyan    -> annotate (bgColorDull Pretty.Cyan) . go xs
+        White   -> annotate (bgColorDull Pretty.White) . go xs
       Vivid -> case c of
-        Black   -> onblack . go xs
-        Red     -> onred . go xs
-        Green   -> ongreen . go xs
-        Yellow  -> onyellow . go xs
-        Blue    -> onblue . go xs
-        Magenta -> onmagenta . go xs
-        Cyan    -> oncyan . go xs
-        White   -> onwhite . go xs
+        Black   -> annotate (bgColor Pretty.Black) . go xs
+        Red     -> annotate (bgColor Pretty.Red) . go xs
+        Green   -> annotate (bgColor Pretty.Green) . go xs
+        Yellow  -> annotate (bgColor Pretty.Yellow) . go xs
+        Blue    -> annotate (bgColor Pretty.Blue) . go xs
+        Magenta -> annotate (bgColor Pretty.Magenta) . go xs
+        Cyan    -> annotate (bgColor Pretty.Cyan) . go xs
+        White   -> annotate (bgColor Pretty.White) . go xs
   go (_                                   : xs) = go xs
 
 -- | A raw canvas to paint ANSI-styled characters on.
@@ -206,7 +210,7 @@
 
 -- | The empty 'Rendering', which contains nothing at all.
 --
--- >>> show (pretty emptyRendering)
+-- >>> show (prettyRendering emptyRendering)
 -- ""
 emptyRendering :: Rendering
 emptyRendering = Rendering (Columns 0 0) 0 0 id (const id)
@@ -271,16 +275,25 @@
 (.#) :: (Delta -> Lines -> Lines) -> Rendering -> Rendering
 f .# Rendering d ll lb s g = Rendering d ll lb s $ \e l -> f e $ g e l
 
-instance Pretty Rendering where
-  pretty (Rendering d ll _ l f) = nesting $ \k -> columns $ \mn -> go (fromIntegral (fromMaybe 80 mn - k)) where
-    go cols = align (vsep (P.map ln [t..b])) where
-      (lo, hi) = window (column d) ll (min (max (cols - 2) 30) 200)
-      a = f d $ l $ array ((0,lo),(-1,hi)) []
-      ((t,_),(b,_)) = bounds a
-      ln y = hcat
-           $ P.map (\g -> sgr (fst (P.head g)) (pretty (P.map snd g)))
-           $ groupBy ((==) `on` fst)
-           [ a ! (y,i) | i <- [lo..hi] ]
+prettyRendering :: Rendering -> Doc AnsiStyle
+prettyRendering (Rendering d ll _ l f) = nesting $ \k -> columns $ \mn -> go (fromIntegral (fromMaybe 80 mn - k)) where
+  go cols = align (vsep (P.map ln [t..b])) where
+    (lo, hi) = window (column d) ll (min (max (cols - 5 - fromIntegral gutterWidth) 30) 200)
+    a = f d $ l $ array ((0,lo),(-1,hi)) []
+    ((t,_),(b,_)) = bounds a
+    n = show $ case d of
+      Lines      n' _ _ _ -> 1 + n'
+      Directed _ n' _ _ _ -> 1 + n'
+      _                   -> 1
+    separator = char '|'
+    gutterWidth = P.length n
+    gutter = pretty n <+> separator
+    margin = fill gutterWidth space <+> separator
+    ln y = (sgr gutterEffects (if y == 0 then gutter else margin) <+>)
+         $ hcat
+         $ P.map (\g -> sgr (fst (P.head g)) (pretty (P.map snd g)))
+         $ groupBy ((==) `on` fst)
+         [ a ! (y,i) | i <- [lo..hi] ]
 
 window :: Int64 -> Int64 -> Int64 -> (Int64, Int64)
 window c l w
@@ -290,6 +303,10 @@
   | otherwise   = (c-w2, c+w2)
   where w2 = div w 2
 
+-- | ANSI terminal style for rendering the gutter.
+gutterEffects :: [SGR]
+gutterEffects = [SetColor Foreground Vivid Blue]
+
 data Rendered a = a :@ Rendering
   deriving Show
 
@@ -320,9 +337,9 @@
 
 -- | A 'Caret' marks a point in the input with a simple @^@ character.
 --
--- >>> plain (pretty (addCaret (Columns 35 35) exampleRendering))
--- int main(int argc, char ** argv) { int; }<EOF>
---                                    ^
+-- >>> unAnnotate (prettyRendering (addCaret (Columns 35 35) exampleRendering))
+-- 1 | int main(int argc, char ** argv) { int; }<EOF>
+--   |                                    ^
 data Caret = Caret !Delta {-# UNPACK #-} !ByteString deriving (Eq,Ord,Show,Data,Typeable,Generic)
 
 class HasCaret t where
@@ -426,9 +443,9 @@
 -- | A 'Span' marks a range of input characters. If 'Caret' is a point, then
 -- 'Span' is a line.
 --
--- >>> plain (pretty (addSpan (Columns 35 35) (Columns 38 38) exampleRendering))
--- int main(int argc, char ** argv) { int; }<EOF>
---                                    ~~~
+-- >>> unAnnotate (prettyRendering (addSpan (Columns 35 35) (Columns 38 38) exampleRendering))
+-- 1 | int main(int argc, char ** argv) { int; }<EOF>
+--   |                                    ~~~
 data Span = Span !Delta !Delta {-# UNPACK #-} !ByteString deriving (Eq,Ord,Show,Data,Typeable,Generic)
 
 class HasSpan t where
@@ -489,10 +506,10 @@
 
 -- | A 'Fixit' is a 'Span' with a suggestion.
 --
--- >>> plain (pretty (addFixit (Columns 35 35) (Columns 38 38) "Fix this!" exampleRendering))
--- int main(int argc, char ** argv) { int; }<EOF>
---                                    ~~~
---                                    Fix this!
+-- >>> unAnnotate (prettyRendering (addFixit (Columns 35 35) (Columns 38 38) "Fix this!" exampleRendering))
+-- 1 | int main(int argc, char ** argv) { int; }<EOF>
+--   |                                    ~~~
+--   |                                    Fix this!
 data Fixit = Fixit
   { _fixitSpan :: {-# UNPACK #-} !Span
     -- ^ 'Span' where the error occurred
diff --git a/src/Text/Trifecta/Result.hs b/src/Text/Trifecta/Result.hs
--- a/src/Text/Trifecta/Result.hs
+++ b/src/Text/Trifecta/Result.hs
@@ -1,17 +1,17 @@
-{-# LANGUAGE CPP                    #-}
-{-# LANGUAGE DeriveFoldable         #-}
-{-# LANGUAGE DeriveFunctor          #-}
-{-# LANGUAGE DeriveTraversable      #-}
-{-# LANGUAGE FlexibleContexts       #-}
-{-# LANGUAGE FlexibleInstances      #-}
-{-# LANGUAGE FunctionalDependencies #-}
-{-# LANGUAGE MultiParamTypeClasses  #-}
-{-# LANGUAGE Rank2Types             #-}
-{-# LANGUAGE TemplateHaskell        #-}
-{-# LANGUAGE UndecidableInstances   #-}
+{-# language CPP                    #-}
+{-# language DeriveFoldable         #-}
+{-# language DeriveFunctor          #-}
+{-# language DeriveTraversable      #-}
+{-# language FlexibleContexts       #-}
+{-# language FlexibleInstances      #-}
+{-# language FunctionalDependencies #-}
+{-# language MultiParamTypeClasses  #-}
+{-# language Rank2Types             #-}
+{-# language TemplateHaskell        #-}
+{-# language UndecidableInstances   #-}
 -----------------------------------------------------------------------------
 -- |
--- Copyright   :  (c) Edward Kmett 2011-2015
+-- Copyright   :  (c) Edward Kmett 2011-2019
 -- License     :  BSD3
 --
 -- Maintainer  :  ekmett@gmail.com
@@ -35,34 +35,34 @@
   , failed
   ) where
 
-import           Control.Applicative          as Alternative
-import           Control.Lens                 hiding (cons, snoc)
-import           Control.Monad                (guard)
+import           Control.Applicative                          as Alternative
+import           Control.Lens                                 hiding (cons, snoc)
+import           Control.Monad                                (guard)
 import           Data.Foldable
-import qualified Data.List                    as List
-import           Data.Maybe                   (fromMaybe, isJust)
+import qualified Data.List                                    as List
+import           Data.Maybe                                   (fromMaybe, isJust)
 #if !(MIN_VERSION_base(4,11,0))
 import           Data.Semigroup
 #endif
-import           Data.Set                     as Set hiding (empty, toList)
-import           Text.PrettyPrint.ANSI.Leijen as Pretty hiding
-    (empty, line, (<$>), (<>))
+import           Data.Set                                     as Set hiding (empty, toList)
+import           Data.Text.Prettyprint.Doc                    as Pretty
+import           Data.Text.Prettyprint.Doc.Render.Terminal    as Pretty
 
-import Text.Trifecta.Delta     as Delta
-import Text.Trifecta.Instances ()
+import Text.Trifecta.Delta       as Delta
 import Text.Trifecta.Rendering
+import Text.Trifecta.Util.Pretty as Pretty
 
 data ErrInfo = ErrInfo
-  { _errDoc    :: Doc
+  { _errDoc    :: Doc AnsiStyle
   , _errDeltas :: [Delta]
-  } deriving(Show)
+  } deriving (Show)
 
 -- | This is used to report an error. What went wrong, some supplemental docs
 -- and a set of things expected at the current location. This does not, however,
 -- include the actual location.
 data Err = Err
-  { _reason      :: Maybe Doc
-  , _footnotes   :: [Doc]
+  { _reason      :: Maybe (Doc AnsiStyle)
+  , _footnotes   :: [Doc AnsiStyle]
   , _expected    :: Set String
   , _finalDeltas :: [Delta]
   }
@@ -72,22 +72,22 @@
 instance Semigroup Err where
   Err md mds mes delta1 <> Err nd nds nes delta2
     = Err (nd <|> md) (if isJust nd then nds else if isJust md then mds else nds ++ mds) (mes <> nes) (delta1 <> delta2)
-  {-# INLINE (<>) #-}
+  {-# inlinable (<>) #-}
 
 instance Monoid Err where
   mempty = Err Nothing [] mempty mempty
-  {-# INLINE mempty #-}
+  {-# inlinable mempty #-}
   mappend = (<>)
-  {-# INLINE mappend #-}
+  {-# inlinable mappend #-}
 
 -- | Generate a simple 'Err' word-wrapping the supplied message.
 failed :: String -> Err
 failed m = Err (Just (fillSep (pretty <$> words m))) [] mempty mempty
-{-# INLINE failed #-}
+{-# inlinable failed #-}
 
--- | Convert a 'Rendering' of auxiliary information and an 'Err' into a 'Doc',
+-- | Convert a 'Rendering' of auxiliary information and an 'Err' into a 'Doc AnsiStyle',
 -- ready to be prettyprinted to the user.
-explain :: Rendering -> Err -> Doc
+explain :: Rendering -> Err -> Doc AnsiStyle
 explain r (Err mm as es _)
   | Set.null es = report (withEx mempty)
   | isJust mm   = report $ withEx $ Pretty.char ',' <+> expecting
@@ -96,10 +96,10 @@
     now = spaceHack $ toList es
     spaceHack [""] = ["space"]
     spaceHack xs = List.filter (/= "") xs
-    withEx x = fromMaybe (fillSep $ text <$> words "unspecified error") mm <> x
-    expecting = text "expected:" <+> fillSep (punctuate (Pretty.char ',') (text <$> now))
-    report txt = vsep $ [pretty (delta r) <> Pretty.char ':' <+> red (text "error") <> Pretty.char ':' <+> nest 4 txt]
-             <|> pretty r <$ guard (not (nullRendering r))
+    withEx x = fromMaybe (fillSep $ pretty <$> words "unspecified error") mm <> x
+    expecting = pretty "expected:" <+> fillSep (punctuate (Pretty.char ',') (pretty <$> now))
+    report txt = vsep $ [prettyDelta (delta r) <> Pretty.char ':' <+> annotate (Pretty.color Pretty.Red) (pretty "error") <> Pretty.char ':' <+> nest 4 txt]
+             <|> prettyRendering r <$ guard (not (nullRendering r))
              <|> as
 
 class Errable m where
@@ -130,35 +130,31 @@
 
 instance AsResult (Result a) (Result b) a b where
   _Result = id
-  {-# INLINE _Result #-}
+  {-# inlinable _Result #-}
 
 -- | The 'Prism' for the 'Success' constructor of 'Result'
 _Success :: AsResult s t a b => Prism s t a b
 _Success = _Result . dimap seta (either id id) . right' . rmap (fmap Success) where
   seta (Success a) = Right a
   seta (Failure e) = Left (pure (Failure e))
-{-# INLINE _Success #-}
+{-# inlinable _Success #-}
 
 -- | The 'Prism' for the 'Failure' constructor of 'Result'
 _Failure :: AsResult s s a a => Prism' s ErrInfo
 _Failure = _Result . dimap seta (either id id) . right' . rmap (fmap Failure) where
   seta (Failure e) = Right e
   seta (Success a) = Left (pure (Success a))
-{-# INLINE _Failure #-}
-
-instance Show a => Pretty (Result a) where
-  pretty (Success a)    = pretty (show a)
-  pretty (Failure xs) = pretty (_errDoc xs)
+{-# inlinable _Failure #-}
 
 instance Applicative Result where
   pure = Success
-  {-# INLINE pure #-}
+  {-# inlinable pure #-}
   Success f <*> Success a = Success (f a)
   Success _ <*> Failure y = Failure y
   Failure x <*> Success _ = Failure x
   Failure x <*> Failure y =
     Failure $ ErrInfo (vsep [_errDoc x, _errDoc y]) (_errDeltas x <> _errDeltas y)
-  {-# INLINE (<*>) #-}
+  {-# inlinable (<*>) #-}
 
 instance Alternative Result where
   Failure x <|> Failure y =
@@ -166,9 +162,9 @@
   Success a <|> Success _ = Success a
   Success a <|> Failure _ = Success a
   Failure _ <|> Success a = Success a
-  {-# INLINE (<|>) #-}
+  {-# inlinable (<|>) #-}
   empty = Failure mempty
-  {-# INLINE empty #-}
+  {-# inlinable empty #-}
 
 instance Monad Result where
   return = pure
diff --git a/src/Text/Trifecta/Rope.hs b/src/Text/Trifecta/Rope.hs
--- a/src/Text/Trifecta/Rope.hs
+++ b/src/Text/Trifecta/Rope.hs
@@ -1,13 +1,13 @@
-{-# LANGUAGE BangPatterns          #-}
-{-# LANGUAGE CPP                   #-}
-{-# LANGUAGE DeriveDataTypeable    #-}
-{-# LANGUAGE DeriveGeneric         #-}
-{-# LANGUAGE FlexibleInstances     #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE TypeFamilies          #-}
+{-# language BangPatterns          #-}
+{-# language CPP                   #-}
+{-# language DeriveDataTypeable    #-}
+{-# language DeriveGeneric         #-}
+{-# language FlexibleInstances     #-}
+{-# language MultiParamTypeClasses #-}
+{-# language TypeFamilies          #-}
 -----------------------------------------------------------------------------
 -- |
--- Copyright   :  (C) 2011-2015 Edward Kmett
+-- Copyright   :  (C) 2011-2019 Edward Kmett
 -- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
diff --git a/src/Text/Trifecta/Tutorial.hs b/src/Text/Trifecta/Tutorial.hs
--- a/src/Text/Trifecta/Tutorial.hs
+++ b/src/Text/Trifecta/Tutorial.hs
@@ -65,7 +65,7 @@
 -- @
 --
 -- > (interactive):1:8: error: expected: ")"
--- > (1 + 2 + 3))<EOF>
--- >        ^
+-- > 1 | (1 + 2 + 3))<EOF>
+-- >   |        ^
 examples :: docDummy
 examples = error "Haddock dummy for documentation"
diff --git a/src/Text/Trifecta/Util/Array.hs b/src/Text/Trifecta/Util/Array.hs
deleted file mode 100644
--- a/src/Text/Trifecta/Util/Array.hs
+++ /dev/null
@@ -1,397 +0,0 @@
-{-# LANGUAGE BangPatterns, CPP, MagicHash, Rank2Types, UnboxedTuples #-}
------------------------------------------------------------------------------
--- |
--- Copyright   :  Edward Kmett 2011-2015
---                Johan Tibell 2011
--- License     :  BSD3
---
--- Maintainer  :  ekmett@gmail.com
--- Stability   :  experimental
--- Portability :  unknown
---
--- Fast zero based arrays, based on the implementation in the HAMT-branch of
--- unordered-containers
------------------------------------------------------------------------------
-module Text.Trifecta.Util.Array
-  ( Array
-  , MArray
-
-    -- * Creation
-  , new
-  , new_
-  , empty
-  , singleton
-
-    -- * Basic interface
-  , length
-  , lengthM
-  , read
-  , write
-  , index
-  , index_
-  , indexM_
-  , update
-  , insert
-  , delete
-
-  , unsafeFreeze
-  , run
-  , run2
-  , copy
-  , copyM
-
-    -- * Folds
-  , foldl'
-  , foldr
-
-  , thaw
-  , map
-  , map'
-  , traverse
-  , filter
-  ) where
-
-import qualified Data.Traversable as Traversable
-#if __GLASGOW_HASKELL__ < 710
-import Control.Applicative (Applicative)
-#endif
-import Control.DeepSeq
-import Control.Monad.ST
-import GHC.Exts (
-      Array#,
-      copyArray#,
-      copyMutableArray#,
-      indexArray#,
-      Int(I#),
-      MutableArray#,
-      newArray#,
-      readArray#,
-      sizeofArray#,
-      sizeofMutableArray#,
-      thawArray#,
-      unsafeFreezeArray#,
-      writeArray#)
-import GHC.ST (ST(..))
-
-import Prelude hiding (filter, foldr, length, map, read
-#if __GLASGOW_HASKELL__ >= 710
-  , traverse
-#endif
-  )
-
-------------------------------------------------------------------------
-
-#if defined(ASSERTS)
--- This fugly hack is brought by GHC's apparent reluctance to deal
--- with MagicHash and UnboxedTuples when inferring types. Eek!
-# define CHECK_BOUNDS(_func_,_len_,_k_) \
-if (_k_) < 0 || (_k_) >= (_len_) then error ("Data.HashMap.Array." ++ (_func_) ++ ": bounds error, offset " ++ show (_k_) ++ ", length " ++ show (_len_)) else
-# define CHECK_OP(_func_,_op_,_lhs_,_rhs_) \
-if not ((_lhs_) _op_ (_rhs_)) then error ("Data.HashMap.Array." ++ (_func_) ++ ": Check failed: _lhs_ _op_ _rhs_ (" ++ show (_lhs_) ++ " vs. " ++ show (_rhs_) ++ ")") else
-# define CHECK_GT(_func_,_lhs_,_rhs_) CHECK_OP(_func_,>,_lhs_,_rhs_)
-# define CHECK_LE(_func_,_lhs_,_rhs_) CHECK_OP(_func_,<=,_lhs_,_rhs_)
-#else
-# define CHECK_BOUNDS(_func_,_len_,_k_)
-# define CHECK_OP(_func_,_op_,_lhs_,_rhs_)
-# define CHECK_GT(_func_,_lhs_,_rhs_)
-# define CHECK_LE(_func_,_lhs_,_rhs_)
-#endif
-
-data Array a = Array {
-  unArray :: !(Array# a)
-#if __GLASGOW_HASKELL__ < 702
-  , length :: {-# UNPACK #-} !Int
-#endif
-  }
-
-#if __GLASGOW_HASKELL__ >= 702
-length :: Array a -> Int
-length ary = I# (sizeofArray# (unArray ary))
-{-# INLINE length #-}
-#endif
-
--- | Smart constructor
-array :: Array# a -> Int -> Array a
-#if __GLASGOW_HASKELL__ >= 702
-array ary _n = Array ary
-#else
-array = Array
-#endif
-{-# INLINE array #-}
-
-data MArray s a = MArray {
-  unMArray :: !(MutableArray# s a)
-#if __GLASGOW_HASKELL__ < 702
-  , lengthM :: {-# UNPACK #-} !Int
-#endif
-  }
-
-#if __GLASGOW_HASKELL__ >= 702
-lengthM :: MArray s a -> Int
-lengthM mary = I# (sizeofMutableArray# (unMArray mary))
-{-# INLINE lengthM #-}
-#endif
-
--- | Smart constructor
-marray :: MutableArray# s a -> Int -> MArray s a
-#if __GLASGOW_HASKELL__ >= 702
-marray mary _n = MArray mary
-#else
-marray = MArray
-#endif
-{-# INLINE marray #-}
-
-------------------------------------------------------------------------
-
-instance NFData a => NFData (Array a) where
-  rnf = rnfArray
-
-rnfArray :: NFData a => Array a -> ()
-rnfArray ary0 = go ary0 n0 0 where
-  n0 = length ary0
-  go !ary !n !i
-    | i >= n = ()
-    | otherwise = rnf (index ary i) `seq` go ary n (i+1)
-{-# INLINE rnfArray #-}
-
--- | Create a new mutable array of specified size, in the specified
--- state thread, with each element containing the specified initial
--- value.
-new :: Int -> a -> ST s (MArray s a)
-new n@(I# n#) b =
-  CHECK_GT("new",n,(0 :: Int))
-  ST $ \s -> case newArray# n# b s of
-    (# s', ary #) -> (# s', marray ary n #)
-{-# INLINE new #-}
-
-new_ :: Int -> ST s (MArray s a)
-new_ n = new n undefinedElem
-
-empty :: Array a
-empty = run (new_ 0)
-
-singleton :: a -> Array a
-singleton x = run (new 1 x)
-{-# INLINE singleton #-}
-
-read :: MArray s a -> Int -> ST s a
-read ary _i@(I# i#) = ST $ \ s ->
-  CHECK_BOUNDS("read", lengthM ary, _i)
-  readArray# (unMArray ary) i# s
-{-# INLINE read #-}
-
-write :: MArray s a -> Int -> a -> ST s ()
-write ary _i@(I# i#) b = ST $ \ s ->
-  CHECK_BOUNDS("write", lengthM ary, _i)
-  case writeArray# (unMArray ary) i# b s of
-    s' -> (# s' , () #)
-{-# INLINE write #-}
-
-index :: Array a -> Int -> a
-index ary _i@(I# i#) =
-  CHECK_BOUNDS("index", length ary, _i)
-  case indexArray# (unArray ary) i# of (# b #) -> b
-{-# INLINE index #-}
-
-index_ :: Array a -> Int -> ST s a
-index_ ary _i@(I# i#) =
-  CHECK_BOUNDS("index_", length ary, _i)
-  case indexArray# (unArray ary) i# of (# b #) -> return b
-{-# INLINE index_ #-}
-
-indexM_ :: MArray s a -> Int -> ST s a
-indexM_ ary _i@(I# i#) =
-  CHECK_BOUNDS("index_", lengthM ary, _i)
-  ST $ \ s# -> readArray# (unMArray ary) i# s#
-{-# INLINE indexM_ #-}
-
-unsafeFreeze :: MArray s a -> ST s (Array a)
-unsafeFreeze mary =
-  ST $ \s -> case unsafeFreezeArray# (unMArray mary) s of
-    (# s', ary #) -> (# s', array ary (lengthM mary) #)
-{-# INLINE unsafeFreeze #-}
-
-run :: (forall s . ST s (MArray s e)) -> Array e
-run act = runST $ act >>= unsafeFreeze
-{-# INLINE run #-}
-
-run2 :: (forall s. ST s (MArray s e, a)) -> (Array e, a)
-run2 k = runST $ do
-  (marr,b) <- k
-  arr <- unsafeFreeze marr
-  return (arr,b)
-
--- | Unsafely copy the elements of an array. Array bounds are not checked.
-copy :: Array e -> Int -> MArray s e -> Int -> Int -> ST s ()
-#if __GLASGOW_HASKELL__ >= 702
-copy !src !_sidx@(I# sidx#) !dst !_didx@(I# didx#) _n@(I# n#) =
-  CHECK_LE("copy", _sidx + _n, length src)
-  CHECK_LE("copy", _didx + _n, lengthM dst)
-  ST $ \ s# -> case copyArray# (unArray src) sidx# (unMArray dst) didx# n# s# of
-    s2 -> (# s2, () #)
-#else
-copy !src !sidx !dst !didx n =
-  CHECK_LE("copy", sidx + n, length src)
-  CHECK_LE("copy", didx + n, lengthM dst)
-  copy_loop sidx didx 0 where
-  copy_loop !i !j !c
-    | c >= n = return ()
-    | otherwise = do
-      b <- index_ src i
-      write dst j b
-      copy_loop (i+1) (j+1) (c+1)
-#endif
-
--- | Unsafely copy the elements of an array. Array bounds are not checked.
-copyM :: MArray s e -> Int -> MArray s e -> Int -> Int -> ST s ()
-#if __GLASGOW_HASKELL__ >= 702
-copyM !src !_sidx@(I# sidx#) !dst !_didx@(I# didx#) _n@(I# n#) =
-  CHECK_BOUNDS("copyM: src", lengthM src, _sidx + _n - 1)
-  CHECK_BOUNDS("copyM: dst", lengthM dst, _didx + _n - 1)
-  ST $ \ s# -> case copyMutableArray# (unMArray src) sidx# (unMArray dst) didx# n# s# of
-    s2 -> (# s2, () #)
-#else
-copyM !src !sidx !dst !didx n =
-  CHECK_BOUNDS("copyM: src", lengthM src, sidx + n - 1)
-  CHECK_BOUNDS("copyM: dst", lengthM dst, didx + n - 1)
-  copy_loop sidx didx 0 where
-  copy_loop !i !j !c
-    | c >= n = return ()
-    | otherwise = do
-      b <- indexM_ src i
-      write dst j b
-      copy_loop (i+1) (j+1) (c+1)
-#endif
-
--- | /O(n)/ Insert an element at the given position in this array,
--- increasing its size by one.
-insert :: Array e -> Int -> e -> Array e
-insert ary idx b =
-  CHECK_BOUNDS("insert", count + 1, idx)
-  run $ do
-    mary <- new_ (count+1)
-    copy ary 0 mary 0 idx
-    write mary idx b
-    copy ary idx mary (idx+1) (count-idx)
-    return mary
-  where !count = length ary
-{-# INLINE insert #-}
-
--- | /O(n)/ Update the element at the given position in this array.
-update :: Array e -> Int -> e -> Array e
-update ary idx b =
-  CHECK_BOUNDS("update", count, idx)
-  run $ do
-    mary <- thaw ary 0 count
-    write mary idx b
-    return mary
-  where !count = length ary
-{-# INLINE update #-}
-
-foldl' :: (b -> a -> b) -> b -> Array a -> b
-foldl' f = \ z0 ary0 -> go ary0 (length ary0) 0 z0 where
-  go ary n i !z
-    | i >= n    = z
-    | otherwise = go ary n (i+1) (f z (index ary i))
-{-# INLINE foldl' #-}
-
-foldr :: (a -> b -> b) -> b -> Array a -> b
-foldr f = \ z0 ary0 -> go ary0 (length ary0) 0 z0 where
-  go ary n i z
-    | i >= n    = z
-    | otherwise = f (index ary i) (go ary n (i+1) z)
-{-# INLINE foldr #-}
-
-undefinedElem :: a
-undefinedElem = error "Undefined element"
-
-thaw :: Array e -> Int -> Int -> ST s (MArray s e)
-#if __GLASGOW_HASKELL__ >= 702
-thaw !ary !_o@(I# o#) !n@(I# n#) =
-  CHECK_LE("thaw", _o + n, length ary)
-  ST $ \ s -> case thawArray# (unArray ary) o# n# s of
-    (# s2, mary# #) -> (# s2, marray mary# n #)
-#else
-thaw !ary !o !n =
-  CHECK_LE("thaw", o + n, length ary)
-  do mary <- new_ n
-     copy ary o mary 0 n
-     return mary
-#endif
-{-# INLINE thaw #-}
-
--- | /O(n)/ Delete an element at the given position in this array,
--- decreasing its size by one.
-delete :: Array e -> Int -> Array e
-delete ary idx = run $ do
-    mary <- new_ (count-1)
-    copy ary 0 mary 0 idx
-    copy ary (idx+1) mary idx (count-(idx+1))
-    return mary
-  where !count = length ary
-{-# INLINE delete #-}
-
-map :: (a -> b) -> Array a -> Array b
-map f = \ ary ->
-  let !n = length ary
-  in run $ do
-    mary <- new_ n
-    go ary mary 0 n
-  where
-    go ary mary i n
-        | i >= n    = return mary
-        | otherwise = do
-             write mary i $ f (index ary i)
-             go ary mary (i+1) n
-{-# INLINE map #-}
-
--- | Strict version of 'map'.
-map' :: (a -> b) -> Array a -> Array b
-map' f = \ ary ->
-  let !n = length ary
-  in run $ do
-    mary <- new_ n
-    go ary mary 0 n
-  where
-    go ary mary i n
-      | i >= n    = return mary
-      | otherwise = do
-        write mary i $! f (index ary i)
-        go ary mary (i+1) n
-{-# INLINE map' #-}
-
-fromList :: Int -> [a] -> Array a
-fromList n xs0 = run $ do
-  mary <- new_ n
-  go xs0 mary 0
-  where
-    go [] !mary !_   = return mary
-    go (x:xs) mary i = do write mary i x
-                          go xs mary (i+1)
-
-toList :: Array a -> [a]
-toList = foldr (:) []
-
-traverse :: Applicative f => (a -> f b) -> Array a -> f (Array b)
-traverse f = \ ary ->
-  fromList (length ary) `fmap`
-  Traversable.traverse f (toList ary)
-{-# INLINE traverse #-}
-
-filter :: (a -> Bool) -> Array a -> Array a
-filter p = \ ary ->
-  let !n = length ary
-  in run $ do
-    mary <- new_ n
-    go ary mary 0 0 n
-  where
-    go ary mary i j n
-      | i >= n    = if i == j
-                    then return mary
-                    else do mary2 <- new_ j
-                            copyM mary 0 mary2 0 j
-                            return mary2
-      | p el      = write mary j el >> go ary mary (i+1) (j+1) n
-      | otherwise = go ary mary (i+1) j n
-      where el = index ary i
-{-# INLINE filter #-}
diff --git a/src/Text/Trifecta/Util/Combinators.hs b/src/Text/Trifecta/Util/Combinators.hs
--- a/src/Text/Trifecta/Util/Combinators.hs
+++ b/src/Text/Trifecta/Util/Combinators.hs
@@ -1,6 +1,6 @@
 -----------------------------------------------------------------------------
 -- |
--- Copyright   :  (C) 2011-2015 Edward Kmett
+-- Copyright   :  (C) 2011-2019 Edward Kmett
 -- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
diff --git a/src/Text/Trifecta/Util/IntervalMap.hs b/src/Text/Trifecta/Util/IntervalMap.hs
--- a/src/Text/Trifecta/Util/IntervalMap.hs
+++ b/src/Text/Trifecta/Util/IntervalMap.hs
@@ -9,7 +9,7 @@
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Text.Trifecta.Util.IntervalMap
--- Copyright   :  (c) Edward Kmett 2011-2015
+-- Copyright   :  (c) Edward Kmett 2011-2019
 --                (c) Ross Paterson 2008
 -- License     :  BSD-style
 -- Maintainer  :  ekmett@gmail.com
diff --git a/src/Text/Trifecta/Util/It.hs b/src/Text/Trifecta/Util/It.hs
--- a/src/Text/Trifecta/Util/It.hs
+++ b/src/Text/Trifecta/Util/It.hs
@@ -7,7 +7,7 @@
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Text.Trifecta.Util.It
--- Copyright   :  (C) 2011-2015 Edward Kmett
+-- Copyright   :  (C) 2011-2019 Edward Kmett
 -- License     :  BSD-style (see the file LICENSE)
 --
 -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
diff --git a/src/Text/Trifecta/Util/Pretty.hs b/src/Text/Trifecta/Util/Pretty.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Trifecta/Util/Pretty.hs
@@ -0,0 +1,52 @@
+{-# LANGUAGE CPP #-}
+-----------------------------------------------------------------------------
+-- |
+-- Copyright   :  (C) 2011-2019 Edward Kmett
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>
+-- Stability   :  experimental
+-- Portability :  non-portable
+--
+-- Utility functions to augment the prettyprinter library's interface.
+----------------------------------------------------------------------------
+
+module Text.Trifecta.Util.Pretty
+  ( AnsiStyle
+  , renderIO
+  -- * Rendering
+  , char
+  -- * Styles
+  , bold
+  , debold
+  , underlined
+  , deunderline
+  -- * Compatibility shims
+  , renderPretty
+  , columns
+  ) where
+
+
+#if __GLASGOW_HASKELL__ < 710
+import Data.Monoid
+#endif
+
+import Data.Text.Prettyprint.Doc
+import Data.Text.Prettyprint.Doc.Render.Terminal
+import Data.Text.Prettyprint.Doc.Render.Terminal.Internal (ansiBold, ansiUnderlining)
+
+char :: Char -> Doc a
+char = pretty
+
+renderPretty :: Double -> Int -> Doc AnsiStyle -> SimpleDocStream AnsiStyle
+renderPretty ribbonFraction page
+  = layoutSmart LayoutOptions { layoutPageWidth = AvailablePerLine page ribbonFraction }
+
+debold, deunderline :: AnsiStyle
+debold = mempty { ansiBold = Nothing }
+deunderline = mempty { ansiUnderlining = Nothing}
+
+columns :: (Maybe Int -> Doc AnsiStyle) -> Doc AnsiStyle
+columns f = pageWidth (f . toMaybeInt) where
+  toMaybeInt (AvailablePerLine cpl _) = Just cpl
+  toMaybeInt Unbounded = Nothing
diff --git a/trifecta.cabal b/trifecta.cabal
--- a/trifecta.cabal
+++ b/trifecta.cabal
@@ -1,8 +1,8 @@
 name:          trifecta
 category:      Text, Parsing, Diagnostics, Pretty Printer, Logging
-version:       2
+version:       2.1
 license:       BSD3
-cabal-version: >= 1.10
+cabal-version: 1.18
 license-file:  LICENSE
 author:        Edward A. Kmett
 maintainer:    Edward A. Kmett <ekmett@gmail.com>
@@ -13,17 +13,25 @@
 synopsis:      A modern parser combinator library with convenient diagnostics
 description:
   A modern parser combinator library with slicing and Clang-style colored diagnostics
+  .
+  For example:
+  .
+  <<https://i.imgur.com/ZyzUSSn.png>>
+  .
+  <images/example.png (Local Copy)>
 
 build-type:    Custom
-tested-with:   GHC == 7.4.2
-             , GHC == 7.6.3
-             , GHC == 7.8.4
+tested-with:   GHC == 7.8.4
              , GHC == 7.10.3
              , GHC == 8.0.2
              , GHC == 8.2.2
-             , GHC == 8.4.3
-             , GHC == 8.6.1
+             , GHC == 8.4.4
+             , GHC == 8.6.5
+             , GHC == 8.8.1
 
+extra-doc-files:
+  images/*.png
+
 extra-source-files:
   examples/*.hs
   examples/LICENSE
@@ -56,39 +64,39 @@
     Text.Trifecta.Result
     Text.Trifecta.Rope
     Text.Trifecta.Tutorial
-    Text.Trifecta.Util.Array
     Text.Trifecta.Util.IntervalMap
     Text.Trifecta.Util.It
 
   other-modules:
-    Text.Trifecta.Instances
     Text.Trifecta.Util.Combinators
+    Text.Trifecta.Util.Pretty
 
   build-depends:
-    ansi-wl-pprint       >= 0.6.6   && < 0.7,
-    ansi-terminal        >= 0.6     && < 0.9,
-    array                >= 0.3.0.2 && < 0.6,
-    base                 >= 4.4     && < 5,
-    blaze-builder        >= 0.3.0.1 && < 0.5,
-    blaze-html           >= 0.5     && < 0.10,
-    blaze-markup         >= 0.5     && < 0.9,
-    bytestring           >= 0.9.1   && < 0.11,
-    charset              >= 0.3.5.1 && < 1,
-    comonad              >= 4       && < 6,
-    containers           >= 0.3     && < 0.7,
-    deepseq              >= 1.2.0.1 && < 1.5,
-    fingertree           >= 0.1     && < 0.2,
+    ansi-terminal               >= 0.6     && < 0.11,
+    array                       >= 0.3.0.2 && < 0.6,
+    base                        >= 4.7     && < 5,
+    blaze-builder               >= 0.3.0.1 && < 0.5,
+    blaze-html                  >= 0.5     && < 0.10,
+    blaze-markup                >= 0.5     && < 0.9,
+    bytestring                  >= 0.9.1   && < 0.11,
+    charset                     >= 0.3.5.1 && < 1,
+    comonad                     >= 4       && < 6,
+    containers                  >= 0.3     && < 0.7,
+    deepseq                     >= 1.2.0.1 && < 1.5,
+    fingertree                  >= 0.1     && < 0.2,
     ghc-prim,
-    hashable             >= 1.2.1   && < 1.3,
-    lens                 >= 4.0     && < 5,
-    mtl                  >= 2.0.1   && < 2.3,
-    parsers              >= 0.12.1  && < 1,
-    profunctors          >= 4.0     && < 6,
-    reducers             >= 3.10    && < 4,
-    semigroups           >= 0.8.3.1 && < 1,
-    transformers         >= 0.2     && < 0.6,
-    unordered-containers >= 0.2.1   && < 0.3,
-    utf8-string          >= 0.3.6   && < 1.1
+    hashable                    >= 1.2.1   && < 1.4,
+    lens                        >= 4.0     && < 5,
+    mtl                         >= 2.0.1   && < 2.3,
+    parsers                     >= 0.12.1  && < 1,
+    prettyprinter               >= 1.2     && < 2,
+    prettyprinter-ansi-terminal >= 1.1     && < 2,
+    profunctors                 >= 4.0     && < 6,
+    reducers                    >= 3.10    && < 4,
+    semigroups                  >= 0.8.3.1 && < 1,
+    transformers                >= 0.2     && < 0.6,
+    unordered-containers        >= 0.2.1   && < 0.3,
+    utf8-string                 >= 0.3.6   && < 1.1
 
   default-language: Haskell2010
   hs-source-dirs:   src
@@ -96,7 +104,9 @@
 
   -- See https://ghc.haskell.org/trac/ghc/wiki/Migration/8.0#base-4.9.0.0
   if impl(ghc >= 8.0)
-    ghc-options: -Wcompat -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances
+    ghc-options: -Wcompat -Wnoncanonical-monad-instances
+    if !impl(ghc >= 8.8)
+      ghc-options: -Wnoncanonical-monadfail-instances
   else
     build-depends: fail == 4.9.*
 
