{"id":28565658,"url":"https://github.com/mvoidex/hsdev","last_synced_at":"2025-06-10T14:33:18.262Z","repository":{"id":7802889,"uuid":"9173247","full_name":"mvoidex/hsdev","owner":"mvoidex","description":"Haskell development tool","archived":false,"fork":false,"pushed_at":"2020-11-04T20:12:19.000Z","size":2090,"stargazers_count":129,"open_issues_count":24,"forks_count":23,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-05-04T08:38:30.645Z","etag":null,"topics":["backend","developer-tools","haskell"],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mvoidex.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-04-02T15:21:31.000Z","updated_at":"2025-02-07T23:55:00.000Z","dependencies_parsed_at":"2022-09-04T00:10:48.506Z","dependency_job_id":null,"html_url":"https://github.com/mvoidex/hsdev","commit_stats":null,"previous_names":[],"tags_count":50,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mvoidex%2Fhsdev","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mvoidex%2Fhsdev/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mvoidex%2Fhsdev/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mvoidex%2Fhsdev/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mvoidex","download_url":"https://codeload.github.com/mvoidex/hsdev/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mvoidex%2Fhsdev/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":258973040,"owners_count":22786372,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","developer-tools","haskell"],"created_at":"2025-06-10T14:30:53.067Z","updated_at":"2025-06-10T14:33:18.243Z","avatar_url":"https://github.com/mvoidex.png","language":"Haskell","funding_links":["https://www.paypal.com/cgi-bin/webscr?cmd=_donations\u0026business=voidex%40live%2ecom\u0026lc=US\u0026no_note=0\u0026currency_code=USD\u0026bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHostedGuest"],"categories":[],"sub_categories":[],"readme":"# hsdev\n\n[![Hackage version](https://img.shields.io/hackage/v/hsdev.svg?style=flat)](http://hackage.haskell.org/package/hsdev) [![Build Status](https://travis-ci.org/mvoidex/hsdev.png)](https://travis-ci.org/mvoidex/hsdev) [![Join the chat at https://gitter.im/mvoidex/hsdev](https://badges.gitter.im/mvoidex/hsdev.svg)](https://gitter.im/mvoidex/hsdev?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge) [![PayPal][paypal-donate-image]][paypal-donate-link] [![Flattr this git repo][flattr-donate-image]][flattr-donate-link]\n\n[paypal-donate-image]: https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif\n[paypal-donate-link]: https://www.paypal.com/cgi-bin/webscr?cmd=_donations\u0026business=voidex%40live%2ecom\u0026lc=US\u0026no_note=0\u0026currency_code=USD\u0026bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHostedGuest\n[flattr-donate-image]: http://api.flattr.com/button/flattr-badge-large.png\n[flattr-donate-link]: https://flattr.com/submit/auto?user_id=voidex\u0026url=https://github.com/mvoidex/hsdev\u0026title=hsdev\u0026language=\u0026tags=github\u0026category=software\n\nHaskell development library and tool with support of autocompletion, symbol info, go to declaration, find references, hayoo search etc.\nUses [fsnotify](http://hackage.haskell.org/package/fsnotify) to watch for changes.\n\n## Installation\n\n#### Stack\n\nTo install latest version with LTS resolver (14.10 should be fine), add these extra packages to your global stack project:\n\u003cpre\u003e\nresolver: lts-14.10\nextra-deps:\n- hsdev-0.3.3.5\n- haddock-api-2.21.0  # not required if you disable `docs` flag\n- hdocs-0.5.3.1  # not required if you disable `docs` flag\n\u003c/pre\u003e\n\nAnd install with `stack install hsdev`\n\nIf you want to use latest nightly resolver and `ghc-8.8`, then there are some more extra deps required:\n\u003cpre\u003e\nresolver: nightly-2019-10-19\nextra-deps:\n- hsdev-0.3.3.5\n- Cabal-3.0.0.0\n- haddock-api-2.23.0  # for `docs` flag\n- haddock-library-1.8.0  # for `docs` flag\n- hdocs-0.5.4.0  # for `docs` flag\n- direct-sqlite-2.3.24\n- git: https://github.com/mvoidex/sqlite-simple  # actual version is broken\n  commit: cc94f6e303b19aeaed2ac21cbccf6f5c7b74274d\n- semigroups-0.18.5\n\u003c/pre\u003e\n\nInstall with `stack install hsdev`\n\nAlternatively, you can `git clone https://github.com/mvoidex/hsdev` and install with `stack install` or `stack install --stack-yaml nightly.yaml`\n\n#### Cabal\n\n\u003cpre\u003e\n$ cabal sandbox init\n$ cabal new-install hsdev\n\u003c/pre\u003e\n\n## Usage\n\nMain idea is to hold in memory scanned sourced and installed modules, so that getting info about symbols and modules is fast.\nIt also doesn't require much work to integrate with some editor:\n\n1. Create `hsdev run ...` process\n2. Connect to it via socket\n3. Send `scan` command with paths/files once\n4. Use other commands to get completions, modules and symbols info; check and lint sources\n\n##### Editors\n\n1. [SublimeText](https://www.sublimetext.com/): [SublimeHaskell](https://packagecontrol.io/packages/SublimeHaskell) plugin\n2. [Atom](https://atom.io/): work in progress, [atom-haskell-hsdev](https://github.com/mvoidex/atom-haskell-hsdev) plugin\n\n## Start server\n\nUse `hsdev start` to start remote server.  \nIf you installed `hsdev` with `stack`, run server with `stack exec -- hsdev start` command, so that correct `$GHC_PACKAGE_PATH` is set where `hsdev` library installed.  \nClient commands then doesn't require running them with `stack exec`.  \nSpecify `--db file.db`, where `hsdev` will store information (SQLite database, see [hsdev.sql](data/hsdev.sql) for schema).  \nThen you can connect to server and send requests (see [requests/responses](API.md)) or you can use `hsdev` itself. It will send command to server and outputs the response.\nScan sources, installed modules and you're ready to request various information: scope, completions, info about symbols etc.\n\nTypical usage is:\n\u003cpre\u003e\nPS\u003e stack exec -- hsdev start\nServer started at port 4567\nPS\u003e hsdev scan project ~/projects/hsdev --stack --silent\n[]\nPS\u003e hsdev complete runC -f ./src/HsDev/Server/Commands.hs | jq -r '.[] | .id.name + \\\" :: \\\" + .info.type'\nrunClientM :: ServerM (ReaderT CommandOptions m) a\nrunConcurrently :: Concurrently a -\u003e IO a\n\u003c/pre\u003e\n\n## Stack support\n\n`hsdev` uses `stack` to build dependencies and to get corresponding package-dbs. As long as `hsdev` uses `ghc` as library, it passes `--compiler` and `--arch` options (since `0.1.7.2`) to `stack` in order to get compatible package-dbs built with same compiler.\n\n## Building without `haddock`/`hdocs` dependency\n\nDisable flag `docs` to build without these dependencies: `cabal configure -f-docs` or `stack install --flag hsdev:-docs`\n\n### Commands\n\nRun `hsdev -?` to get list of all commands or `hsdev \u003ccommand\u003e -?` (`hsdev help \u003ccommand\u003e`) to get detailed info.\n\n* `version` — returns version number\n* `start`, `run` and `stop` — server commands, start remote server, run server or stop remote server.\n* `connect` — connect to server to send commands from command line (for debug)\n* `ping` — ping server\n* `listen` — connect to server and listen for its log (for debug)\n* `set-log` — set log level\n* `scan` — scan installed modules, cabal projects and files\n* `scan project`, `scan file`, `scan package-dbs` — same as above, but with additional options\n* `set-file-contents` — set data to use as file contents, used to work with unsaved files\n* `docs`, `infer` — scan docs or infer types for sources\n* `remove`, `remove-all` — unload data\n* `packages`, `projects`, `sandboxes` — list information about specified modules, packages, projects or sandboxes\n* `symbol`, `module`, `project`, `sandbox` — get info about symbol, module, project or sandbox\n* `whoat`, `whois`, `lookup` — find project-visible or imported symbol\n* `scope`, `scope modules` — get modules or declarations, accessible from file\n* `usages` — find usages of symbol\n* `complete` — get completions for file and input\n* `hayoo` — search in hayoo\n* `cabal list` — search packages info\n* `lint`, `check`, `lint-check` — lint or check source files. These commands have some advantages over `ghc-mod` ones: `lint` uses `hlint` as library, `check` returns more precise source position and also uses project description to pass `-package` flags, these commands also can accept file contents\n* `types` — get types for all source spans\n* `flags`, `langs` — list ghc flags and language extensions\n* `ghc eval` — evaluate expression\n* `ghc type` — get type of expression\n* `autofixes` — get suggestions to fix some warnings and errors\n* `rename` — get regions to rename some symbol\n* `refactor` — apply suggestions/renames from previous commands\n\n#### TODO: Detailed commands description with examples\n\n#### Scan\n\nYou can scan package-dbs, projects and files.\n\nTo scan global and user package-dbs, run\n\u003cpre\u003e\nPS\u003e hsdev scan package-dbs --global-db --user-db --silent\n[]\nPS\u003e hsdev module -h -m System.IO | jq -r '.[].location.package'\nbase-4.12.0.0\n\u003c/pre\u003e\n\nTo scan project use `scan project`, which will also scan dependens package-dbs (unless `--no-deps` flag set)\n\u003cpre\u003e\nPS\u003e hsdev scan project ~/projects/hsdev --stack --silent\n[]\nPS\u003e hsdev module -f ~/projects/hsdev/src/HsDev/Client/Commands.hs | jq -r '.[].exports[] | .id.name + \\\" :: \\\" + .info.type'\nrunClient :: (ToJSON a, ServerMonadBase m) =\u003e CommandOptions -\u003e ClientM m a -\u003e ServerM m Result\nrunCommand :: ServerMonadBase m =\u003e Command -\u003e ClientM m Value\n\u003c/pre\u003e\n\nTo scan file use `scan file`:\n\u003cpre\u003e\nPS\u003e hsdev scan file ~/projects/hs/Main.hs --stack --silent\n[]\nPS\u003e hsdev module -f ~/projects/hs/Main.hs | jq -r '.[].exports[] | .id.name + \\\" :: \\\" + .info.type'\nmain :: IO ()\n\u003c/pre\u003e\n\n#### Whois/whoat\n\nGet information for symbol in context of source file. Understand qualified names and also names qualified with module shortcut (`import ... as`), note `M.` qualified for `map`, and local definition `toResult`:\n\u003cpre\u003e\nPS\u003e dev whois M.lookup --file .\\src\\HsDev\\Client\\Commands.hs | json | % { $_.id.name + ' :: ' + $_.info.type }\nlookup :: Ord k =\u003e k -\u003e Map k a -\u003e Maybe a\nPS\u003e hsdev whoat 64 1 -f .\\src\\HsDev\\Client\\Commands.hs | json | % { $_.id.name + ' :: ' + $_.info.type }\ntoValue :: m a -\u003e m Value\nPS\u003e hsdev whoat 55 32 -f .\\src\\HsDev\\Client\\Commands.hs | json | % { $_.id.name + ' :: ' + $_.info.type }\ntoResult :: ReaderT CommandOptions m a -\u003e m Result\n\u003c/pre\u003e\n\n#### Usages\n\nReturns all places where symbol is used\n\u003cpre\u003e\nPS\u003e hsdev usages Data.Map.toList | json | % { $_.in.name, $_.at.line, $_.at.column -join ':' }\nData.Deps:33:90\nData.Deps:57:62\nHsDev.Symbols.Types:93:12\nHsDev.Symbols.Types:95:54\nHsDev.Symbols.Types:104:74\nHsDev.Symbols.Types:104:94\n...\n\u003c/pre\u003e\n\n#### AutoFixes/Rename/Refactor\n\nAutofix commands used to assist for automatic fix of some warnings and hints from `hlint`. `autofixes` command parses `check` and `lint` command output, and returns `corrections` — data with regions and suggestions to fix. `refactor` command perform fix of selected corrections and also updates positions of other corrections, such that they stay relevant. These updated corrections can be used to pass them to `refactor` again.\nExample of interactive command, based on this command in SublimeHaskell:\n![autofix](https://raw.githubusercontent.com/SublimeHaskell/SublimeHaskell/hsdev/Commands/AutoFix.gif)\n\nRename generates corrections to rename symbol\n\n\u003cpre\u003e\n# Get corrections\nPS\u003e $corrs = hsdev check-lint ..\\haskell\\Test.hs | hsdev autofixes --stdin\n# Apply first correction, other corrections passed as --rest param to update their positions\n# Result is updated --rest corrections, which can be used again\nPS\u003e $corrs2 = ($corrs | jq '[.[1]]' -c -r) | hsdev refactor --pure --rest (escape ($corrs | jq '.[1:5]' -c -r)) --stdin\n# One more\nPS\u003e $corrs2 | hsdev refactor --stdin --pure\n\u003c/pre\u003e\n\n\n### Examples\n\n\u003cpre\u003e\nPS\u003e hsdev start --db hsdev.db\nServer started at port 4567\nPS\u003e hsdev scan --cabal\n{}\nPS\u003e hsdev scan --project hsdev\n{}\nPS\u003e hsdev module --project hsdev -h | json | % { $_.name } | select -first 3\nHsDev.Database.Update\nHsDev.Client.Commands\nHsDev.Scan\nPS\u003e hsdev symbol enumProject --src | json | % { $_.id.name + ' :: ' + $_.info.type }\nenumProject :: Project -\u003e m ScanContents\nPS\u003e hsdev complete tr -f .\\tools\\hsdev.hs | json | % { $_.id.name }\ntraverse\ntraverseDirectory\n...\nPS\u003e hsdev stop\n{}\n\u003c/pre\u003e\n\n### Hayoo in GHCi\n\nYou can use this `ghci.conf` to allow search from `ghci`:\n\n\u003cpre\u003e\n:set prompt \"λ\u003e \"\n\nimport Control.Monad.Error\nimport HsDev.Tools.Hayoo\nimport Data.List (intercalate)\n\n:{\nlet\n    showHayooFunction f =\n        (hayooName f ++ \" :: \" ++ hayooSignature f) :\n        (map ('\\t':) $\n            lines (untagDescription (hayooDescription f)) ++\n            [\"-- Defined in '\" ++ intercalate \", \" (hayooModules f) ++ \"', \" ++ hayooPackage f])\n    showHayoo = concatMap showHayooFunction . resultResult\n:}\n\n:def hayoo \\s -\u003e return $ \"runErrorT (hayoo \\\"\" ++ s ++ \"\\\" Nothing) \u003e\u003e= (mapM_ putStrLn) . either (return . (\\\"Error: \\\" ++)) showHayoo\"\n\u003c/pre\u003e\n\nUsage:\n\n\u003cpre\u003e\nλ\u003e :hayoo (a -\u003e c) -\u003e (b -\u003e c)\nquery :: (a -\u003e c) -\u003e b -\u003e c\n        query f x walks the structure x (bottom up) and applies f\n         to every a, appending the results.\n        -- Defined in 'Text.Pandoc.Walk', pandoc-types\n...\n\u003c/pre\u003e\n\n### JSON\n\n#### PowerShell\n\nI'm using PowerShell and `json` function from [PSUtils](https://github.com/mvoidex/PSUtils) to parse JSON output, which returns `PSObject`, that can be inspected in common way:\n\n\u003cpre\u003e\nPS\u003e hsinspect module GHC -g \"-package ghc\" | json | % { $_.module.declarations } | % { $_.name + ' :: ' + $_.decl.type } | select -first 5\nABE :: id -\u0026gt; id -\u0026gt; HsWrapper -\u0026gt; TcSpecPrags -\u0026gt; ABExport id\nABExport :: data ABExport id\nACoAxiom :: CoAxiom Branched -\u0026gt; TyThing\nAConLike :: ConLike -\u0026gt; TyThing\nATyCon :: TyCon -\u0026gt; TyThing\n\u003c/pre\u003e\n\n#### [jq](http://stedolan.github.io/jq/)\n\nAnother way is to use [jq](http://stedolan.github.io/jq/) tool, which is pretty simple:\n\n\u003cpre\u003e\nPS\u003e hsinspect module GHC -g \"-package ghc\" | jq -r '.module.declarations[range(0;5)] | .name + \\\" :: \\\" + .decl.type'\nABE :: id -\u0026gt; id -\u0026gt; HsWrapper -\u0026gt; TcSpecPrags -\u0026gt; ABExport id\nABExport :: data ABExport id\nACoAxiom :: CoAxiom Branched -\u0026gt; TyThing\nAConLike :: ConLike -\u0026gt; TyThing\nATyCon :: TyCon -\u0026gt; TyThing\n\u003c/pre\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmvoidex%2Fhsdev","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmvoidex%2Fhsdev","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmvoidex%2Fhsdev/lists"}