@@ -30,6 +30,7 @@ import Output.Names
30
30
import Output.Tags
31
31
import Output.Types
32
32
import Query
33
+ import System.Console.ANSI
33
34
34
35
-- -- generate all
35
36
-- @tagsoup -- generate tagsoup
@@ -40,19 +41,21 @@ actionSearch :: CmdLine -> IO ()
40
41
actionSearch Search {.. } = replicateM_ repeat_ $ -- deliberately reopen the database each time
41
42
withSearch database $ \ store ->
42
43
if null compare_ then do
43
- count' <- pure $ fromMaybe 10 count
44
- (q, res) <- pure $ search store $ parseQuery $ unwords query
45
- whenLoud $ putStrLn $ " Query: " ++ unescapeHTML (LBS. unpack $ renderMarkup $ renderQuery q)
46
- let (shown, hidden) = splitAt count' $ nubOrd $ map (targetResultDisplay link) res
44
+ -- should we check for color support?
45
+ -- --color implies ANSI support, i.e. --color=always
46
+ let color' = fromMaybe False color
47
+ let count' = fromMaybe 10 count
48
+ let (qs, res) = search store $ parseQuery $ unwords query
49
+ let (shown, hidden) = splitAt count' $ nubOrd $ map (targetResultDisplay link color' qs) res
50
+ whenLoud $ putStrLn $ " Query: " ++ unescapeHTML (LBS. unpack $ renderMarkup $ renderQuery qs)
47
51
if null res then
48
52
putStrLn " No results found"
49
53
else if info then do
50
- putStr $ targetInfo $ head res
54
+ putStr $ targetInfo color' qs $ head res
51
55
else do
52
- let toShow = if numbers && not info then addCounter shown else shown
53
56
if | json -> LBS. putStrLn $ JSON. encode $ maybe id take count $ map unHTMLtargetItem res
54
57
| jsonl -> mapM_ (LBS. putStrLn . JSON. encode) $ maybe id take count $ map unHTMLtargetItem res
55
- | otherwise -> putStr $ unlines toShow
58
+ | otherwise -> putStr $ unlines $ if numbers then addCounter shown else shown
56
59
when (hidden /= [] && not json) $ do
57
60
whenNormal $ putStrLn $ " -- plus more results not shown, pass --count=" ++ show (count'+ 10 ) ++ " to see more"
58
61
else do
@@ -62,21 +65,39 @@ actionSearch Search{..} = replicateM_ repeat_ $ -- deliberately reopen the datab
62
65
putStr $ unlines $ searchFingerprintsDebug store (parseType $ unwords query) (map parseType compare_)
63
66
64
67
-- | Returns the details printed out when hoogle --info is called
65
- targetInfo :: Target -> String
66
- targetInfo Target {.. } =
67
- unlines $ [ unHTML targetItem ] ++
68
+ targetInfo :: Bool -> [ Query ] -> Target -> String
69
+ targetInfo color qs Target {.. } =
70
+ unlines $ [ unHTML . ( if color then highlightItem qs else id ) $ targetItem ] ++
68
71
[ unwords packageModule | not $ null packageModule] ++
69
72
[ unHTML targetDocs ]
70
73
where packageModule = map fst $ catMaybes [targetPackage, targetModule]
71
74
72
75
-- | Returns the Target formatted as an item to display in the results
73
76
-- | Bool argument decides whether links are shown
74
- targetResultDisplay :: Bool -> Target -> String
75
- targetResultDisplay link Target {.. } = unHTML $ unwords $
77
+ targetResultDisplay :: Bool -> Bool -> [ Query ] -> Target -> String
78
+ targetResultDisplay link color qs Target {.. } = unHTML $ unwords $
76
79
map fst (maybeToList targetModule) ++
77
- [targetItem] ++
80
+ [if color then highlightItem qs targetItem else targetItem] ++
78
81
[" -- " ++ targetURL | link]
79
82
83
+ highlightItem :: [Query ] -> String -> String
84
+ highlightItem qs x
85
+ | Just (pre,x) <- stripInfix " <s0>" x, Just (name,post) <- stripInfix " </s0>" x
86
+ = pre ++ dull ++ highlight (unescapeHTML name) ++ rst ++ post
87
+ | otherwise = x
88
+ where
89
+ dull = setSGRCode [SetColor Foreground Dull Yellow ]
90
+ bold = setSGRCode [SetColor Foreground Vivid Yellow ]
91
+ rst = setSGRCode []
92
+ highlight = mconcatMap (\ xs@ ((b,_): _) -> let s = map snd xs in if b then bold ++ s ++ dull else s) .
93
+ groupOn fst . (\ x -> zip (mapIsInQueries x) x)
94
+ where
95
+ mapIsInQueries :: String -> [Bool ]
96
+ mapIsInQueries (x: xs) | m > 0 = replicate m True ++ (mapIsInQueries $ drop (m - 1 ) xs)
97
+ where m = maximum $ 0 : [length y | QueryName y <- qs, lower y `isPrefixOf` lower (x: xs)]
98
+ mapIsInQueries (x: xs) = False : mapIsInQueries xs
99
+ mapIsInQueries [] = []
100
+
80
101
unHTMLtargetItem :: Target -> Target
81
102
unHTMLtargetItem target = target {targetItem = unHTML $ targetItem target}
82
103
0 commit comments