Haskell development library and tool with support of autocompletion, symbol info, go to declaration, find references, hayoo search etc.
And several utils hsinspect, hsclearimports, hscabal, hshayoo, hsautofix
Use hsdev start to start remote server. Specify --cache, where hsdev will store information.
Then you can connect to server and send requests (see requests/responses) or you can use hsdev itself. It will send command to server and outputs the response.
start,runandstop— server commandsconnect— interactive connect to serverping— ping serveradd— add inspected modulesscan,rescan— scan installed modules, cabal projects and filesremove— unload datamodules,packages,projects— list information about specified modules, packages or projectsresolve— resolve scope symbols and exports for sources modulesymbol,module,project— find symbol, module or projectlookup,whois— find visible or imported symbolscope— get modules or declarations, accessible from filecomplete— get completions for file and inputhayoo— search in hayoocabal list— search packages infoghc-mod type,ghc-mod check,ghc-mod lint,ghc-mod lang,ghc-mod flags— runghc-modcommand in corresponding ghc-mod worker (separate workers per project and per sandbox)autofix show,autofix fix— commands to fix some warnings and applyhlintsuggestionsdump— dump modules or projects infoload— load data
PS> hsdev start --cache cache
Server started at port 4567
PS> hsdev scan --cabal
{}
PS> hsdev scan --project hsdev
{}
PS> hsdev modules --project hsdev | json | % { $_.result.name } | select -first 3
Data.Async
Data.Group
HsDev
PS> hsdev symbol enumProject | json | % { $_.result.declaration } | % { $_.name + ' :: ' + $_.decl.type }
enumProject :: Project -> ErrorT String IO ProjectToScan
PS> hsdev complete C -f .\hsdev\tools\hsdev.hs | json | % { $_.result.declaration.name }
ClientOpts
CommandAction
CommandOptions
CommandResult
PS> hsdev symbol foldr | json | % result | % { $_.declaration.name + ' :: ' + $_.declaration.decl.type + ' -- ' + $_.'module-id'.name } | select -first 3
foldr :: (Word8 -> a -> a) -> a -> ByteString -> a -- Data.ByteString
foldr :: (Char -> a -> a) -> a -> ByteString -> a -- Data.ByteString.Char8
foldr :: (Word8 -> a -> a) -> a -> ByteString -> a -- Data.ByteString.Lazy
PS> hsdev stop
{}
Tool to inspect source files, .cabal files and installed modules. For source files it also scan docs and try infer types.
PS> hsinspect .\hsdev.cabal | json | % { $_.description.library.modules[3] }
HsDev.Cache
PS> hsinspect .\tools\hsdev.hs | json | % { $_.module.declarations } | % { $_.name + ' :: ' + $_.decl.type }
main :: IO ()
printMainUsage :: IO ()
printUsage :: IO ()
PS> hsinspect Data.Either | json | % { $_.module.declarations } | % { $_.name + ' :: ' + $_.decl.type }
Either :: data Either a b
Left :: a -> Either a b
Right :: b -> Either a b
either :: (a -> c) -> (b -> c) -> Either a b -> c
isLeft :: Either a b -> Bool
isRight :: Either a b -> Bool
lefts :: [Either a b] -> [a]
partitionEithers :: [Either a b] -> ([a], [b])
rights :: [Either a b] -> [b]
Cabal helper with JSON output. For now only list command supported
PS> hscabal list aeson | json | ? { $_.'installed-versions' } | % { $_.name + ' - ' + $_.'installed-versions' }
aeson - 0.7.0.3
aeson-pretty - 0.7.1
Search in hayoo
PS> hshayoo "(a -> b) -> c" | json | % { $_.declaration } | % { $_.name + ' :: ' + $_.decl.type } | select -first 5
unC :: (tau -> a) -> b
map3 :: (a -> b) -> f (g (h a)) -> f (g (h b))
map2 :: (a -> b) -> f (g a) -> f (g b)
map' :: (a -> b) -> map a -> map b
map :: (a -> b) -> map a -> map b
Tool to fix some build warnings and to apply hlint suggestions
hsautofix show— read output messages and return suggestionshsautofix fix -n <i> -n ...— fix selected suggestions (by index) and return updated rest suggestions, so this command can be chained. There are also flag--pure. If set, files will not be modified. Use it, if you don't wanthsautofixto apply fixes itself.
Here's how you can apply first three suggestions sequentically. On each step suggestion is removed, so we just apply first suggestion three times. We can do the same in reverse order, and in that case indices will be 3, 2, 1. And we can apply all three in one call. Three commands below have same effect
PS> ghc-mod Test.hs | hsautofix show | hsautofix fix -n 1 | hsautofix fix -n 1 | hsautofix fix -n 1 ... PS> ghc-mod Test.hs | hsautofix show | hsautofix fix -n 3 | hsautofix fix -n 2 | hsautofix fix -n 1 ... PS> ghc-mod Test.hs | hsautofix show | hsautofix fix -n 1 -n 2 -n 3 ...
You can use this ghci.conf to allow search from ghci:
:set prompt "λ> "
import Control.Monad.Error
import HsDev.Tools.Hayoo
import Data.List (intercalate)
:{
let
showHayooFunction f =
(hayooName f ++ " :: " ++ hayooSignature f) :
(map ('\t':) $
lines (untagDescription (hayooDescription f)) ++
["-- Defined in '" ++ intercalate ", " (hayooModules f) ++ "', " ++ hayooPackage f])
showHayoo = concatMap showHayooFunction . resultResult
:}
:def hayoo \s -> return $ "runErrorT (hayoo \"" ++ s ++ "\" Nothing) >>= (mapM_ putStrLn) . either (return . (\"Error: \" ++)) showHayoo"
Usage:
λ> :hayoo (a -> c) -> (b -> c)
query :: (a -> c) -> b -> c
query f x walks the structure x (bottom up) and applies f
to every a, appending the results.
-- Defined in 'Text.Pandoc.Walk', pandoc-types
...
I'm using PowerShell and json function from PSUtils to parse JSON output, which returns PSObject, that can be inspected in common way:
PS> hsinspect module GHC -g "-package ghc" | json | % { $_.module.declarations } | % { $_.name + ' :: ' + $_.decl.type } | select -first 5
ABE :: id -> id -> HsWrapper -> TcSpecPrags -> ABExport id
ABExport :: data ABExport id
ACoAxiom :: CoAxiom Branched -> TyThing
AConLike :: ConLike -> TyThing
ATyCon :: TyCon -> TyThing
Another way is to use jq tool, which is pretty simple:
PS> hsinspect module GHC -g "-package ghc" | jq -r '.module.declarations[range(0;5)] | .name + \" :: \" + .decl.type' ABE :: id -> id -> HsWrapper -> TcSpecPrags -> ABExport id ABExport :: data ABExport id ACoAxiom :: CoAxiom Branched -> TyThing AConLike :: ConLike -> TyThing ATyCon :: TyCon -> TyThing
