diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -14,16 +14,15 @@
 
 by cabal:
 ```shell
-cabal update  
+cabal update
 cabal install pgdl
 ```
+In case of the versions of dependencies cannot be resolved, you may need to `rm -rf ~/.ghc`.
 
 via nix:
 ```shell
-nix-env -iA nixos.haskellPackages.pgdl
-```
-Or,
-```shell
+git clone https://github.com/sifmelcara/pgdl.git
+cd pgdl
 nix-env -i -f pgdl.nix
 ```
 
@@ -32,7 +31,7 @@
 ```shell
 pgdl https://www.kernel.org/pub/linux/
 ```
-or simply type pgdl if you have set servpath attribute in the config file.
+or simply type `pgdl` if you have set servpath attribute in the config file (config file will be explained later).
 
 ## Shortcut keys
 
@@ -49,15 +48,15 @@
 
 ## Config file
 
-If you want to access webpage that uses basic authentication, you should at least set
-*username* attribute in config file.
-(if password is not set, you need to enter password manually when program launch)
+If you want to access webpage that uses basic authentication, you should at least set *username* attribute in config file.
+(if password is not set, you will need to enter password manually when you launch the program)
 
 (~/.pgdl)
 ```bash
-# example: 
+# example:
 username = "jack"      # should be set if the webpage have basic authentication
 password = "mypassw"   # optional
 servpath = "example.org/videodir/" # default server location, optional
 localdir = "/home/jack/Downloads/" # where to store downloaded files, optional
 ```
+
diff --git a/pgdl.cabal b/pgdl.cabal
--- a/pgdl.cabal
+++ b/pgdl.cabal
@@ -1,6 +1,6 @@
 
 name:                pgdl
-version:             10.8
+version:             10.9
 license:             PublicDomain
 license-file:        LICENSE
 author:              mingchuan
@@ -38,7 +38,7 @@
                        filepath, directory,
                        tagsoup,
                        directory-listing-webpage-parser >= 0.1.1.0,
-                       brick >= 0.13 && < 0.19, vty, microlens,
+                       brick >= 0.17 && < 0.21, vty, microlens,
                        conduit, conduit-extra,
                        http-conduit, http-types, resourcet,
                        configurator >= 0.3,
diff --git a/src/Cache.hs b/src/Cache.hs
--- a/src/Cache.hs
+++ b/src/Cache.hs
@@ -15,7 +15,7 @@
 import Text.HTML.DirectoryListing.Type
 
 import Configure
-import Types 
+import Types
 
 -- | this conversion may lose accuracy?
 instance Binary LocalTime where
@@ -38,7 +38,7 @@
                      , lastModified = l
                      , fileSize = f
                      }
-        
+
 writeCache :: [Entry] -> IO ()
 writeCache es = do
     p <- getCacheFileLocation
@@ -63,4 +63,4 @@
             downloaded <- doesFileExist $ lcd </> T.unpack (decodedName e)
             return $ File e "offline mode" downloaded
     noData = error "offline mode"
-    
+
diff --git a/src/Configure.hs b/src/Configure.hs
--- a/src/Configure.hs
+++ b/src/Configure.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE LambdaCase #-}
 
-module Configure 
+module Configure
 where
 
 import qualified Data.Text as T
@@ -21,25 +21,25 @@
     doesFileExist cfgFile >>= \case
         False -> return Nothing
         True -> Just <$> C.load [C.Required cfgFile]
-    
+
 getUsername :: IO (Maybe Text)
 getUsername =
     getConfig >>= \case
         Nothing -> return Nothing
-        Just cfg -> C.lookup cfg "username" 
+        Just cfg -> C.lookup cfg "username"
 
 
 getPassword :: IO (Maybe Text)
-getPassword = 
+getPassword =
     getConfig >>= \case
         Nothing -> return Nothing
-        Just cfg -> C.lookup cfg "password" 
+        Just cfg -> C.lookup cfg "password"
 
 getLocaldir :: IO (Maybe Text)
 getLocaldir =
     getConfig >>= \case
         Nothing -> return Nothing
-        Just cfg -> C.lookup cfg "localdir" 
+        Just cfg -> C.lookup cfg "localdir"
 
 -- | return Nothing if there are no servpath or config file do not exist
 getServpath :: IO (Maybe Text)
diff --git a/src/DList.hs b/src/DList.hs
--- a/src/DList.hs
+++ b/src/DList.hs
@@ -23,8 +23,8 @@
 --                 ^ DNode pool
 
 
-newDList :: [DNode] -> DList 
-newDList = pushDList (DList S.empty []) 
+newDList :: [DNode] -> DList
+newDList = pushDList (DList S.empty [])
 
 -- | filter the elements in a DList, this action directly modify
 -- the state of the top element of directory stack. The purpose of this function is
@@ -42,10 +42,10 @@
         0 -> Nothing
         _ -> Just . fromMaybe 0 $ do
             oldSelVal <- oldSelectionVal
-            V.elemIndex oldSelVal newElements 
+            V.elemIndex oldSelVal newElements
 
 -- | pop the directory stack (used when leaving a directory or exiting a filtered list)
-popDList :: DList -> DList 
+popDList :: DList -> DList
 popDList dl@(DList _ [_]) = dl
 popDList (DList sDn (x:y:xs)) = DList sDn (x':xs)
     where
@@ -84,7 +84,7 @@
         return $ DList (S.update i e' sDn) (x:xs)
 
 replaceSelectedDNode :: DList -> DNode -> Maybe DList
-replaceSelectedDNode dlst d = join $ mapSelectedDNodeM dlst (const $ Just d) 
+replaceSelectedDNode dlst d = join $ mapSelectedDNodeM dlst (const $ Just d)
 
 adjustCurrentBrickList :: Monad m => DList -> (L.List String Int -> m (L.List String Int)) -> m DList
 adjustCurrentBrickList (DList sDn (x:xs)) f = do
@@ -95,4 +95,4 @@
 renderDList (DList sDn (x:_)) render = L.renderList render True actualList
     where
     actualList = x & listElementsL %~ V.map (S.index sDn)
-    
+
diff --git a/src/DownloadInterface.hs b/src/DownloadInterface.hs
--- a/src/DownloadInterface.hs
+++ b/src/DownloadInterface.hs
@@ -14,7 +14,7 @@
 import Data.List
 import Data.Monoid
 import Control.Monad
-import Control.Monad.Trans.Resource 
+import Control.Monad.Trans.Resource
 import Control.Monad.IO.Class
 import Control.Concurrent
 import Control.Applicative
@@ -25,9 +25,7 @@
 import qualified System.IO as IO
 import Distribution.System
 import qualified Control.Concurrent.Chan as C
-#if MIN_VERSION_brick(0, 16, 0)
 import qualified Brick.BChan as BC
-#endif
 
 import qualified Graphics.Vty as V
 import qualified Brick.Main as M
@@ -63,17 +61,11 @@
 data DownloadEvent = UpdateFinishedSize Integer
                    | DownloadFinish
 
-downloadInterface :: DownloadSettings -> IO () 
+downloadInterface :: DownloadSettings -> IO ()
 downloadInterface dSettings = do
-#if MIN_VERSION_brick(0, 16, 0)
     eventChan <- BC.newBChan 100000000 -- select a big enough number
     unless (justOpen dSettings) . void . forkIO $
         download dSettings (BC.writeBChan eventChan)
-#else
-    eventChan <- C.newChan 
-    unless (justOpen dSettings) . void . forkIO $
-        download dSettings (C.writeChan eventChan)
-#endif
     progressBarTotSize <- if justOpen dSettings
                           then getLocalFileSize (T.unpack $ localStoragePath dSettings) >>= \case
                                 Nothing -> error "file do not exist."
@@ -88,14 +80,18 @@
                   , M.appChooseCursor = M.neverShowCursor
                   , M.appHandleEvent = appEvent
                   , M.appStartEvent = return
-                  , M.appAttrMap = const theMap 
+                  , M.appAttrMap = const theMap
                   }
         appEvent :: DownloadState -> T.BrickEvent String DownloadEvent -> T.EventM String (T.Next DownloadState)
         appEvent ds@(DownloadState _) be = case be of
             T.VtyEvent e -> case e of
                 V.EvKey V.KEsc [] -> M.halt ds
                 V.EvKey (V.KChar 'q') _ -> M.halt ds
-                V.EvKey (V.KChar 'o') [] -> M.continue $ UserInput ds (E.editor "command" (str.unlines) (Just 1) "")
+#if MIN_VERSION_brick(0, 19, 0)
+                V.EvKey (V.KChar 'o') [] -> M.continue $ UserInput ds (E.editor "command" (Just 1) "")
+#else
+                V.EvKey (V.KChar 'o') [] -> M.continue $ UserInput ds (E.editor "command" (str . unlines) (Just 1) "")
+#endif
                 V.EvKey V.KEnter [] -> do
                     liftIO $ localStoragePath dSettings `openBy` ""
                     M.continue ds
@@ -106,7 +102,11 @@
         appEvent FinishedState be = case be of
             T.VtyEvent e -> case e of
                 V.EvKey (V.KChar 'q') _ -> M.halt FinishedState
-                V.EvKey (V.KChar 'o') [] -> M.continue $ UserInput FinishedState (E.editor "command" (str.unlines) (Just 1) "")
+#if MIN_VERSION_brick(0, 19, 0)
+                V.EvKey (V.KChar 'o') [] -> M.continue $ UserInput FinishedState (E.editor "command" (Just 1) "")
+#else
+                V.EvKey (V.KChar 'o') [] -> M.continue $ UserInput FinishedState (E.editor "command" (str . unlines) (Just 1) "")
+#endif
                 V.EvKey V.KEnter [] -> do
                     liftIO $ localStoragePath dSettings `openBy` ""
                     M.halt FinishedState
@@ -149,12 +149,16 @@
         drawUI (UserInput (UserInput _ _) _) = error "unexpected state in UserInput state."
         drawUI (UserInput s ed) = (padTop (T.Pad 1) . vLimit 5 $ ask) : drawUI s
             where
-            ask = C.vCenter . C.hCenter . 
-                  hLimit 50 . vLimit 5 . 
+            ask = C.vCenter . C.hCenter .
+                  hLimit 50 . vLimit 5 .
                   B.borderWithLabel (str "please input a program name") .
-                  forceAttr "input box" . 
+                  forceAttr "input box" .
                   hLimit 40 $
+#if MIN_VERSION_brick(0, 19, 0)
+                  E.renderEditor (str . unlines) True ed
+#else
                   E.renderEditor True ed
+#endif
     M.customMain (V.mkVty mempty) (Just eventChan) theApp initialState
     return ()
 
@@ -172,7 +176,7 @@
     filepath = T.unpack file
     addq :: String -> String
     addq s = "\"" ++ s ++ "\""
-    
+
 getContentLength :: DownloadSettings -> IO Integer
 getContentLength dSettings = do
     let (req, manager) = networkResource dSettings $ relativeUrl dSettings
@@ -190,8 +194,8 @@
     fileExist path >>= \case
         False -> return Nothing
         True -> Just . fromIntegral . fileSize <$> getFileStatus path
-    
-download :: DownloadSettings -> 
+
+download :: DownloadSettings ->
             (DownloadEvent -> IO ()) ->
             IO ()
 download dSettings tell = do
diff --git a/src/EntryAttrViewer.hs b/src/EntryAttrViewer.hs
--- a/src/EntryAttrViewer.hs
+++ b/src/EntryAttrViewer.hs
@@ -21,14 +21,14 @@
     (C.txt info :: Widget String)
     where
     info = T.unlines $
-           zipWith (\describ s -> T.intercalate "\n" . 
+           zipWith (\describ s -> T.intercalate "\n" .
                                   U.cutTextByDisplayLength U.terminalWidth $
                                   describ `T.append` ": " `T.append` s
                    )
-           [ "visible name" 
-           , "decoded name" 
-           , "url" 
-           , "file size" 
+           [ "visible name"
+           , "decoded name"
+           , "url"
+           , "file size"
            , "downloaded"
            ]
            [ visibleName entry
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -61,7 +61,7 @@
                   , M.appChooseCursor = M.neverShowCursor
                   , M.appHandleEvent = appEvent
                   , M.appStartEvent = return
-                  , M.appAttrMap = const theMap 
+                  , M.appAttrMap = const theMap
                   }
         appEvent :: MainState -> T.BrickEvent String e -> T.EventM String (T.Next MainState)
         appEvent ls@(LState dlst) (T.VtyEvent e) = case e of
@@ -76,7 +76,7 @@
                     File entry url False -> do
                         let fn = decodedName entry
                         path <- liftIO $ Conf.getLocaldir >>= \case
-                            Nothing -> return fn 
+                            Nothing -> return fn
                             Just pre -> return $ T.pack (T.unpack pre </> T.unpack fn)
                         let dui = downloadInterface DownloadSettings { networkResource = nr
                                                                      , relativeUrl = url
@@ -87,26 +87,30 @@
                         M.suspendAndResume $ do
                             dui
                             ex <- doesFileExist (T.unpack path)
-                            return $ LState (fromJust $ replaceSelectedDNode dlst (File entry url ex)) 
+                            return $ LState (fromJust $ replaceSelectedDNode dlst (File entry url ex))
                         --                   ^ this fromJust is ok since we can be sure that
                         -- there has something been selected. However this need to perform refactor in the future
                     File entry url True -> do -- already downloaded file
                         let fn = decodedName entry
                         path <- liftIO $ Conf.getLocaldir >>= \case
-                            Nothing -> return fn 
+                            Nothing -> return fn
                             Just pre -> return $ T.pack (T.unpack pre </> T.unpack fn)
                         let dui = downloadInterface DownloadSettings { networkResource = nr
                                                                      , relativeUrl = url
                                                                      , localStoragePath = path
                                                                      , justOpen = mdf /= [V.MMeta]
-                                                                     , continueDownload = mdf == [V.MMeta] 
+                                                                     , continueDownload = mdf == [V.MMeta]
                                                                      }
                         M.suspendAndResume $ dui >> return ls
             V.EvKey V.KLeft [] -> M.continue . LState $ popDList dlst
             V.EvKey V.KRight [] -> case extractSelectedDNode dlst of
                 Nothing -> M.continue ls
                 Just d -> M.suspendAndResume $ entryAttrViewer d >> return ls
-            V.EvKey (V.KChar '/') [] -> M.continue $ SearchState (dupDList dlst) (E.editor "searchBar" (str.unlines) (Just 1) "")
+#if MIN_VERSION_brick(0, 19, 0)
+            V.EvKey (V.KChar '/') [] -> M.continue $ SearchState (dupDList dlst) (E.editor "searchBar" (Just 1) "")
+#else
+            V.EvKey (V.KChar '/') [] -> M.continue $ SearchState (dupDList dlst) (E.editor "searchBar" (str . unlines) (Just 1) "")
+#endif
             V.EvKey (V.KChar 'd') [] -> case extractSelectedDNode dlst of
                 Nothing -> M.continue ls
                 Just dnode -> case dnode of
@@ -115,7 +119,7 @@
                     File entry url True -> do -- already downloaded file
                         let fn = decodedName entry
                         path <- liftIO $ Conf.getLocaldir >>= \case
-                                            Nothing -> return $ T.unpack fn 
+                                            Nothing -> return $ T.unpack fn
                                             Just pre -> return $ T.unpack pre </> T.unpack fn
                         liftIO $ removeFile path
                         ex <- liftIO $ doesFileExist path
@@ -132,7 +136,7 @@
                 _ -> M.continue $ LState dlst
             ev -> do
                 newEd <- E.handleEditorEvent ev ed
-                let 
+                let
                     linesToALine [l] = l
                     linesToALine _ = error "not one line of words in the search bar, why?"
                     keyword = T.pack . linesToALine $ E.getEditContents newEd
@@ -155,7 +159,7 @@
 -- | use cropping to draw UI in the future?
 drawUI :: MainState -> [Widget String]
 drawUI mainState = case mainState of
-        (LState dlst) -> [ C.hCenter . hLimit U.terminalWidth $ 
+        (LState dlst) -> [ C.hCenter . hLimit U.terminalWidth $
                            vBox [entryList dlst, statusBar (extractSelectedDNode dlst)]
                          ]
         (SearchState dlst e) -> [ C.hCenter . hLimit U.terminalWidth $
@@ -166,9 +170,7 @@
     listDrawElement :: Bool -> DNode -> [Widget String]
     listDrawElement sel dn = [ color (not sel) attrName . vLimit 3 . hLimit 1 $ fill ' '
                              , color sel attrName text
-#if MIN_VERSION_brick(0, 14, 0)
                              , color (not sel) attrName . vLimit 3 . hLimit 1 $ fill ' '
-#endif
                              ]
         where
         attrName = case dn of
@@ -178,11 +180,7 @@
         name = case dn of
             Directory a _ -> a
             File a _ _ -> a
-#if MIN_VERSION_brick(0, 14, 0)
         text = txt . placeTextIntoRectangle 3 (U.terminalWidth-2) . stripWidth $ decodedName name
-#else
-        text = txt . placeTextIntoRectangle 3 (U.terminalWidth-1) . stripWidth $ decodedName name
-#endif
         color True attr = withAttr attr
         color False _ = id
         stripWidth :: Text -> Text
@@ -190,7 +188,11 @@
                         [] -> ""
                         [singleLine] -> singleLine
                         (x:_) -> x `T.append` "..."
+#if MIN_VERSION_brick(0, 19, 0)
+    searchBar ed = forceAttr "searchBar" $ hBox [txt " search: ", E.renderEditor (str . unlines) True ed]
+#else
     searchBar ed = forceAttr "searchBar" $ hBox [txt " search: ", E.renderEditor True ed]
+#endif
     statusBar = withAttr "statusBar" . str . expand . info
     info Nothing = "  Nothing selected by user"
     info (Just sel) = "  " ++ show (lastModified etr) ++ "    " ++ maybe "Directory" friendlySize (fileSize etr)
@@ -201,7 +203,7 @@
     expand s = s ++ replicate 88 ' '
 
 initializeResource :: IO ([DNode], NetworkResource)
-initializeResource = 
+initializeResource =
     getArgs >>= \case
         ["--offline"] -> readCache >>= \case
             Nothing -> error "no offline data or data corrupted."
@@ -213,7 +215,7 @@
                     Just ru -> Conf.getUsername >>= \case
                                  Nothing -> return (ru, Nothing)
                                  Just user -> Conf.getPassword >>= \case
-                                    Nothing -> do   
+                                    Nothing -> do
                                         pass <- U.askPassword
                                         return (ru, Just (user, pass))
                                     Just pass -> return (ru, Just (user, pass))
@@ -222,6 +224,6 @@
             putStrLn "loading webpage..."
             putStrLn "(you can use 'pgdl --offline' to browse the webpage you load last time)"
             nr <- genNetworkResource rootUrl up
-            dNodes <- fetch nr 
+            dNodes <- fetch nr
             return (dNodes, nr)
 
diff --git a/src/Networking.hs b/src/Networking.hs
--- a/src/Networking.hs
+++ b/src/Networking.hs
@@ -25,7 +25,7 @@
 import qualified Configure as Conf
 import Types
 
-type NetworkResource = Text -> (Request, Manager) 
+type NetworkResource = Text -> (Request, Manager)
 --                    ^ relative path
 
 genNetworkResource :: Text -> -- ^ webpage url (root)
@@ -43,9 +43,9 @@
                     Just (u, p) -> applyBasicAuth (encodeUtf8 u) (encodeUtf8 p)
     manager <- newManager tlsManagerSettings
     return $ \t -> (genReq t, manager)
-    
 
-getWebpage :: NetworkResource -> 
+
+getWebpage :: NetworkResource ->
               Text -> -- relative path
               IO Text
 getWebpage nr rp = do
diff --git a/src/Utils.hs b/src/Utils.hs
--- a/src/Utils.hs
+++ b/src/Utils.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE LambdaCase #-}
 
-module Utils 
+module Utils
 where
 
 import qualified Data.Text as T
@@ -10,7 +10,7 @@
 import System.IO
 import qualified Graphics.Text.Width as TW
 
--- | give a file size in bytes, return pretty file size 
+-- | give a file size in bytes, return pretty file size
 -- represent in KB, MB, GB or TB
 friendlySize :: Integer -> String
 friendlySize b
@@ -56,7 +56,7 @@
         go _ acc []
             | null acc = []
             | otherwise = [reverse acc]
-        go lsum acc str@(x:xs) 
+        go lsum acc str@(x:xs)
             | lsum + snd x <= len = go (lsum + snd x) (fst x : acc) xs
             | otherwise = reverse acc : go 0 "" str
 
@@ -73,7 +73,7 @@
 placeTextIntoRectangle :: Int -> -- ^ height
                           Int -> -- ^ width
                           Text -> Text
-placeTextIntoRectangle h w t 
+placeTextIntoRectangle h w t
     | l > w = error "placeTextIntoRectangle: text too long"
     | otherwise = T.unlines $
         replicate (h `div` 2) (T.replicate w " ") ++
