bhoogle 0.1.3.5 → 0.1.4.1
raw patch · 3 files changed
+73/−66 lines, 3 filesdep ~brickdep ~bytestringdep ~containers
Dependency ranges changed: brick, bytestring, containers, directory, filepath, hoogle, lens, process, protolude, text, time, typed-process, vector, vty
Files
- README.md +1/−1
- app/Main.hs +56/−49
- bhoogle.cabal +16/−16
README.md view
@@ -13,7 +13,7 @@ 1. Generate the default database (```hoogle generate```) ## Usage- 1. Enter a search in the "type" edit box+ 1. Enter a string in the "Type" edit box. You can filter the results to specific packages appending the `+packagename` syntax just like with Hoogle. 1. Press enter to search: focus goes directly to the results list 1. Or press tab to search and focus will go to the "text" edit box 1. You can then filter the results by typing in the "text" edit box, any result containing the sub-string typed will be shown
app/Main.hs view
@@ -69,10 +69,11 @@ -- | Defines how the brick application will work / handle events app :: B.App BrickState Event Name-app = B.App { B.appDraw = drawUI+app =+ B.App { B.appDraw = drawUI , B.appChooseCursor = B.showFirstCursor , B.appHandleEvent = handleEvent- , B.appStartEvent = pure+ , B.appStartEvent = pass , B.appAttrMap = const theMap } @@ -126,8 +127,11 @@ } -- And run brick- void $ B.customMain (V.mkVty V.defaultConfig) (Just chan) app st+ let vtyBuilder = V.mkVty V.defaultConfig+ initialVty <- vtyBuilder + void $ B.customMain initialVty vtyBuilder (Just chan) app st+ where -- | Get the local time getTime = do@@ -137,8 +141,8 @@ -- | Main even handler for brick events-handleEvent :: BrickState -> B.BrickEvent Name Event -> B.EventM Name (B.Next BrickState)-handleEvent st ev =+handleEvent :: B.BrickEvent Name Event -> B.EventM Name BrickState ()+handleEvent ev = case ev of -- Handle keyboard events -- k is the key@@ -146,86 +150,89 @@ (B.VtyEvent ve@(V.EvKey k ms)) -> case (k, ms) of -- Escape quits the app, no matter what control has focus- (K.KEsc, []) -> B.halt st+ (K.KEsc, []) -> B.halt - _ ->+ _ -> do+ st' <- get -- How to interpret the key press depends on which control is focused- case BF.focusGetCurrent $ st ^. stFocus of+ case BF.focusGetCurrent $ st' ^. stFocus of Just TypeSearch -> case k of K.KChar '\t' -> do -- Search, clear sort order, focus next- found <- doSearch st- B.continue . filterResults $ st & stFocus %~ BF.focusNext+ found <- liftIO $ doSearch st'+ modify $ \st -> filterResults $ st & stFocus %~ BF.focusNext & stResults .~ found & stSortResults .~ SortNone K.KBackTab ->do -- Search, clear sort order, focus prev- found <- doSearch st- B.continue . filterResults $ st & stFocus %~ BF.focusPrev+ found <- liftIO $ doSearch st'+ modify $ \st -> filterResults $ st & stFocus %~ BF.focusPrev & stResults .~ found & stSortResults .~ SortNone K.KEnter -> do -- Search, clear sort order, focus on results -- This makes it faster if you want to search and navigate results without tabing through the text search box- found <- doSearch st- B.continue . filterResults $ st & stResults .~ found+ found <- liftIO $ doSearch st'+ modify $ \st -> filterResults $ st & stResults .~ found & stSortResults .~ SortNone & stFocus %~ BF.focusNext & stFocus %~ BF.focusNext -- TODO with brick >= 0.33, rather than 2x focus next: & stFocus %~ BF.focusSetCurrent ListResults _ -> do -- Let the editor handle all other events- r <- BE.handleEditorEvent ve $ st ^. stEditType- next <- liftIO . searchAhead doSearch $ st & stEditType .~ r - B.continue next+ B.zoom stEditType $ BE.handleEditorEvent ev+ st <- get+ st2 <- liftIO $ searchAhead doSearch st+ put st2 Just TextSearch -> case k of- K.KChar '\t' -> B.continue $ st & stFocus %~ BF.focusNext -- Focus next- K.KBackTab -> B.continue $ st & stFocus %~ BF.focusPrev -- Focus previous+ K.KChar '\t' -> modify $ \st -> st & stFocus %~ BF.focusNext -- Focus next+ K.KBackTab -> modify $ \st -> st & stFocus %~ BF.focusPrev -- Focus previous _ -> do -- Let the editor handle all other events- r <- BE.handleEditorEvent ve $ st ^. stEditText- B.continue . filterResults $ st & stEditText .~ r+ B.zoom stEditText $ BE.handleEditorEvent ev+ modify filterResults + Just ListResults -> case k of- K.KChar '\t' -> B.continue $ st & stFocus %~ BF.focusNext -- Focus next- K.KBackTab -> B.continue $ st & stFocus %~ BF.focusPrev -- Focus previous+ K.KChar '\t' -> modify $ \st -> st & stFocus %~ BF.focusNext -- Focus next+ K.KBackTab -> modify $ \st -> st & stFocus %~ BF.focusPrev -- Focus previous K.KChar 's' -> -- Toggle the search order between ascending and descending, use asc if sort order was 'none'- let sortDir = if (st ^. stSortResults) == SortAsc then SortDec else SortAsc in- let sorter = if sortDir == SortDec then (Lst.sortBy $ flip compareType) else (Lst.sortBy compareType) in- B.continue . filterResults $ st & stResults %~ sorter- & stSortResults .~ sortDir+ let sortDir = if (st' ^. stSortResults) == SortAsc then SortDec else SortAsc in+ let sorter = if sortDir == SortDec then Lst.sortBy (flip compareType) else Lst.sortBy compareType in+ modify $ \st -> filterResults $ st & stResults %~ sorter+ & stSortResults .~ sortDir K.KChar 'p' -> do- let selected = BL.listSelectedElement $ st ^. stResultsList- B.suspendAndResume (yankPackage st selected)+ let selected = BL.listSelectedElement $ st' ^. stResultsList+ B.suspendAndResume (yankPackage st' selected) K.KChar 'm' -> do- let selected = BL.listSelectedElement $ st ^. stResultsList- B.suspendAndResume (yankModule st selected)+ let selected = BL.listSelectedElement $ st' ^. stResultsList+ B.suspendAndResume (yankModule st' selected) _ -> do -- Let the list handle all other events -- Using handleListEventVi which adds vi-style keybindings for navigation -- and the standard handleListEvent as a fallback for all other events- r <- BL.handleListEventVi BL.handleListEvent ve $ st ^. stResultsList- B.continue $ st & stResultsList .~ r+ B.zoom stResultsList $ BL.handleListEventVi BL.handleListEvent ve - _ -> B.continue st+ _ -> pass (B.AppEvent (EventUpdateTime time)) -> -- Update the time in the state- B.continue $ st & stTime .~ time+ modify $ \st -> st & stTime .~ time - _ -> B.continue st+ _ -> pass where+ doSearch :: BrickState -> IO [H.Target] doSearch st' = - liftIO $ searchHoogle (st' ^. stDbPath) (Txt.strip . Txt.concat $ BE.getEditContents (st' ^. stEditType))+ searchHoogle (st' ^. stDbPath) (Txt.strip . Txt.concat $ BE.getEditContents (st' ^. stEditType)) yank :: (H.Target -> Maybe Text) -> BrickState -> Maybe (Int, H.Target) -> IO BrickState@@ -276,7 +283,7 @@ let results = if Txt.null filterText then allResults- else filter (\t -> Txt.isInfixOf filterText . Txt.toLower $ formatResult t) allResults+ else filter (Txt.isInfixOf filterText . Txt.toLower . formatResult) allResults in st & stResultsList .~ BL.list ListResults (Vec.fromList results) 1 @@ -295,7 +302,7 @@ resultsBlock = let total = show . length $ st ^. stResults in let showing = show . length $ st ^. stResultsList ^. BL.listElementsL in- (B.withAttr "infoTitle" $ B.txt "Results: ") <+> B.txt (showing <> "/" <> total)+ (B.withAttr (B.attrName "infoTitle") $ B.txt "Results: ") <+> B.txt (showing <> "/" <> total) <=> (B.padTop (B.Pad 1) $ resultsContent <+> resultsDetail@@ -328,11 +335,11 @@ htitle t = B.hLimit 20 $- B.withAttr "infoTitle" $+ B.withAttr (B.attrName "infoTitle") $ B.txt t vtitle t =- B.withAttr "infoTitle" $+ B.withAttr (B.attrName "infoTitle") $ B.txt t editor n e =@@ -342,7 +349,7 @@ time t = B.padLeft (B.Pad 1) $ B.hLimit 20 $- B.withAttr "time" $+ B.withAttr (B.attrName "time") $ B.str (Tm.formatTime Tm.defaultTimeLocale "%H-%M-%S" t) getSelectedDetail fn =@@ -357,18 +364,18 @@ theMap :: BA.AttrMap-theMap = BA.attrMap V.defAttr [ (BE.editAttr , V.black `B.on` V.cyan)- , (BE.editFocusedAttr , V.black `B.on` V.yellow)- , (BL.listAttr , V.white `B.on` V.blue)- , (BL.listSelectedAttr, V.blue `B.on` V.white)- , ("infoTitle" , B.fg V.cyan)- , ("time" , B.fg V.yellow)+theMap = BA.attrMap V.defAttr [ (BE.editAttr , V.black `B.on` V.cyan)+ , (BE.editFocusedAttr , V.black `B.on` V.yellow)+ , (BL.listAttr , V.white `B.on` V.blue)+ , (BL.listSelectedAttr , V.blue `B.on` V.white)+ , (B.attrName "infoTitle", B.fg V.cyan)+ , (B.attrName "time" , B.fg V.yellow) ] getFiles :: FilePath -> IO [FilePath] getFiles p = do- entries <- (p </>) <<$>> (Dir.listDirectory p)+ entries <- (p </>) <<$>> Dir.listDirectory p filterM Dir.doesFileExist entries ----------------------------------------------------------------------------------------------
bhoogle.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: bhoogle-version: 0.1.3.5+version: 0.1.4.1 synopsis: Simple terminal GUI for local hoogle. description: bhoogle is a terminal GUI layer over local hoogle. It provides search ahead and sub-string filtering in addition to the usual type-search. homepage: https://github.com/andrevdm/bhoogle#readme@@ -8,7 +8,7 @@ license-file: LICENSE author: Andre Van Der Merwe maintainer: andre@andrevdm.com-copyright: 2018 Andre Van Der Merwe+copyright: 2018-2022 Andre Van Der Merwe category: Development, Terminal build-type: Simple extra-source-files: README.md@@ -18,20 +18,20 @@ main-is: Main.hs ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -Wimplicit-prelude build-depends: base >= 4.9.1.0 && <5- , protolude >= 0.2.2 && < 0.2.3- , text >= 1.2.3.0 && < 1.2.4.0- , bytestring >= 0.10.8.2 && < 0.10.9.0- , directory >= 1.3.0.2 && < 1.3.2.0- , filepath >= 1.4.1.2 && < 1.4.2.0- , containers >= 0.5.11.0- , brick >= 0.37.1 && < 0.41.0- , vty >= 5.21 && < 5.24- , vector >= 0.12.0.1 && < 0.12.2.0- , process >= 1.6.3.0 && < 1.6.4.0- , lens >= 4.16.1 && < 4.17.0- , time >= 1.8.0.2 && < 1.8.1.0- , hoogle >= 5.0.17.3 && < 5.0.19.0- , typed-process >= 0.2.2.0 && < 0.2.4.0+ , protolude+ , text+ , bytestring+ , directory+ , filepath+ , containers+ , brick >= 1.1+ , vty >= 5.3.6+ , vector+ , process+ , lens+ , time+ , hoogle+ , typed-process default-language: Haskell2010 source-repository head