{"id":13895734,"url":"https://github.com/mrcjkb/neotest-haskell","last_synced_at":"2025-04-10T04:59:42.191Z","repository":{"id":54725700,"uuid":"522633361","full_name":"mrcjkb/neotest-haskell","owner":"mrcjkb","description":"Neotest adapter for Haskell (cabal or stack) with support for Sydtest, Hspec and Tasty","archived":false,"fork":false,"pushed_at":"2025-03-30T00:27:21.000Z","size":521,"stargazers_count":57,"open_issues_count":14,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-30T01:29:20.352Z","etag":null,"topics":["haskell","hspec","neovim","neovim-plugin","sydtest","tasty","testing","treesitter"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mrcjkb.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"mrcjkb"}},"created_at":"2022-08-08T16:50:32.000Z","updated_at":"2025-03-30T00:27:23.000Z","dependencies_parsed_at":"2023-11-19T01:27:42.303Z","dependency_job_id":"b8e3da70-c1e7-4ec4-bb35-f58a6a55b12d","html_url":"https://github.com/mrcjkb/neotest-haskell","commit_stats":{"total_commits":299,"total_committers":8,"mean_commits":37.375,"dds":"0.14715719063545152","last_synced_commit":"de447c36c80e9310a129a3223d634699e9f46f5f"},"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrcjkb%2Fneotest-haskell","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrcjkb%2Fneotest-haskell/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrcjkb%2Fneotest-haskell/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrcjkb%2Fneotest-haskell/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrcjkb","download_url":"https://codeload.github.com/mrcjkb/neotest-haskell/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248161267,"owners_count":21057554,"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":["haskell","hspec","neovim","neovim-plugin","sydtest","tasty","testing","treesitter"],"created_at":"2024-08-06T18:02:25.946Z","updated_at":"2025-04-10T04:59:42.165Z","avatar_url":"https://github.com/mrcjkb.png","language":"Lua","funding_links":["https://github.com/sponsors/mrcjkb"],"categories":["Lua"],"sub_categories":[],"readme":"\u003c!-- markdownlint-disable --\u003e\n\u003cbr /\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://github.com/mrcjkb/neotest-haskell\"\u003e\n    \u003cimg src=\"./logo.svg\" alt=\"neotest-haskell\"\u003e\n  \u003c/a\u003e\n  \u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/mrcjkb/neotest-haskell/issues\"\u003eReport Bug\u003c/a\u003e\n  \u003c/p\u003e\n  \u003cp\u003e\n    \u003cstrong\u003e\n      A \u003ca href=\"https://github.com/nvim-neotest/neotest\"\u003eneotest\u003c/a\u003e adapter for Haskell.\n    \u003c/strong\u003e\n  \u003c/p\u003e\n  \u003cp\u003e🦥\u003c/p\u003e\n\n[![Neovim][neovim-shield]][neovim-url]\n[![Lua][lua-shield]][lua-url]\n[![Haskell][haskell-shield]][haskell-url]\n[![Nix][nix-shield]][nix-url]\n\n[![GPL2 License][license-shield]][license-url]\n[![Issues][issues-shield]][issues-url]\n[![Build Status][ci-shield]][ci-url]\n[![LuaRocks][luarocks-shield]][luarocks-url]\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n[![All Contributors](https://img.shields.io/badge/all_contributors-9-purple.svg?style=for-the-badge)](#contributors-)\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-restore --\u003e\n\n## Quick links\n\n- [Features](#features)\n- [Installation](#installation)\n- [Configuration](#configuration)\n- [Examples](#examples)\n- [TODO](#todo)\n- [Troubleshooting](#troubleshooting)\n- [Recommendations](#recommendations)\n\n## Features\n\n- [x] Supports [Cabal](https://www.haskell.org/cabal/) (single/multi-package) projects.\n- [x] Supports [Stack](https://docs.haskellstack.org/en/stable/)\n      (single/multi-package) projects.\n- [x] Parses [Hspec](https://hackage.haskell.org/package/hspec)\n      and [Sydtest](https://hackage.haskell.org/package/sydtest)\n      `--match` filters for the cursor's position using tree-sitter.\n- [x] Parses [Tasty](https://hackage.haskell.org/package/tasty)\n      `--pattern` filters for the cursor's position using tree-sitter.\n- [x] Parses test results and displays error messages as diagnostics.\n\n\u003c!-- markdownlint-disable --\u003e\nhttps://user-images.githubusercontent.com/12857160/224197351-8ca64bd5-8d89-4689-8c40-18d1d018896e.mp4\n\u003c!-- markdownlint-restore --\u003e\n\n## Installation\n\n### rocks.nvim\n\n```vim\n:Rocks install neotest-haskell\n```\n\nrocks.nvim will install all dependencies if not\nalready installed (including tree-sitter-haskell).\n\n### Other plugin managers\n\nSee also: [neotest installation instructions](https://github.com/nvim-neotest/neotest#installation).\n\n- Requires the tree-sitter parser for haskell to be installed.\n\nThe following example uses [`lazy.nvim`](https://github.com/folke/lazy.nvim):\n\n```lua\n{\n  'nvim-neotest/neotest',\n  dependencies = {\n    -- ...,\n    'mrcjkb/neotest-haskell',\n    'nvim-lua/plenary.nvim',\n  }\n}\n```\n\n## Configuration\n\nMake sure the Haskell parser for tree-sitter is installed,\nyou can do so via [`nvim-treesitter`](https://github.com/nvim-treesitter/nvim-treesitter)\nlike so:\n\n```lua\nrequire('nvim-treesitter.configs').setup {\n  ensure_installed = {\n    'haskell',\n    --...,\n  },\n}\n```\n\nAdd `neotest-haskell` to your `neotest` adapters:\n\n```lua\nrequire('neotest').setup {\n  -- ...,\n  adapters = {\n    -- ...,\n    require('neotest-haskell')\n  },\n}\n```\n\nYou can also pass a config to the setup. The following are the defaults:\n\n```lua\nrequire('neotest').setup {\n  adapters = {\n    require('neotest-haskell') {\n      -- Default: Use stack if possible and then try cabal\n      build_tools = { 'stack', 'cabal' },\n      -- Default: Check for tasty first and then try hspec\n      frameworks = { 'tasty', 'hspec', 'sydtest' },\n    },\n  },\n}\n```\n\n\u003e [!NOTE]\n\u003e\n\u003e If you were to use `build_tools = { 'cabal', 'stack' }`, then cabal will almost\n\u003e always be chosen, because almost all stack projects can be built with cabal.\n\nAlternately, you can pair each test framework with a list of modules,\nused to identify the respective framework in a test file:\n\n```lua\nrequire('neotest').setup {\n  adapters = {\n    require('neotest-haskell') {\n      frameworks = {\n        { framework = 'tasty', modules = { 'Test.Tasty', 'MyTestModule' }, },\n        'hspec',\n        'sydtest',\n      },\n    },\n  },\n}\n```\n\nThis can be useful if you have test files that do not import one of the default modules\nused for framework identification:\n\n- `tasty`: `modules = { 'Test.Tasty' }`\n- `hspec`: `modules = { 'Test.Hspec' }`\n- `sydtest`: `modules = { 'Test.Syd' }`\n\n## Advanced configuration\n\nThis plugin uses tree-sitter queries in files that match\n`\u003cruntimepath\u003e/queries/haskell/\u003cframework\u003e-positions.scm`\n\nFor example, to add position queries for this plugin for `tasty`, without\nhaving to fork this plugin, you can add them to\n`$XDG_CONFIG_HOME/nvim/after/queries/haskell/tasty-positions.scm`.\n\n\u003e [!NOTE]\n\u003e\n\u003e - `:h runtimepath`\n\u003e - See examples in [`queries/haskell/`](./queries/haskell/).\n\n## Examples\n\n```haskell\nmodule FixtureSpec ( spec ) where\nimport Test.Hspec\nimport Test.Hspec.QuickCheck\nimport Control.Exception ( evaluate )\n\nspec :: Spec\nspec = describe \"Prelude.head\" $ do\n  it \"returns the first element of a list\" $ head [23 ..] `shouldBe` (23 :: Int)\n\n  prop \"returns the first element of an *arbitrary* list\" $ \\x xs -\u003e\n    head (x : xs) `shouldBe` (x :: Int)\n\n  describe \"Empty list\" $\n    it \"throws an exception if used with an empty list\"\n      $             evaluate (head [])\n      `shouldThrow` anyException\n```\n\nIn the above listing, calling `:lua require('neotest').run.run()`\nwith the cursor on the line...\n\n```haskell\n  describe \"Empty list\" $\n```\n\n...will run the tests with the following Cabal command:\n\n```console\n# Assuming a Cabal package called \"my_package\"\ncabal test my_package --test-option -m --test-option \"/Prelude.head/Empty list/\"\n```\n\n...or with the following Stack command:\n\n```console\n# Assuming a Stack package called \"my_package\"\nstack test my_package --ta \"--match \\\"/Prelude.head/Empty list/\\\"\"\n```\n\n...which will run the `\"throws an exception if used with an empty list\"` test.\n\nCalling `:lua require('neotest').run.run()`\nwith the cursor on the line...\n\n```haskell\nspec = describe \"Prelude.head\" $ do\n```\n\n...will run the tests with the following Cabal command:\n\n```console\n# Assuming a Cabal package called \"my_package\"\ncabal test my_package --test-option -m --test-option \"/Prelude.head/\"\n```\n\n...or with the following Stack command:\n\n```console\n# Assuming a Stack package called \"my_package\"\nstack test my_package --ta \"--match \\\"/Prelude.head/\\\"\"\n```\n\n...which will run all tests in the module.\n\n## TODO\n\nSee [issues](https://github.com/mrcjkb/neotest-haskell/issues).\n\n## Troubleshooting\n\nTo run a health check, run `:checkhealth neotest-haskell` in Neovim.\n\n## Limitations\n\n- To run `sydtest` tests of type `'file'`, `sydtest \u003e= 0.13.0.4` is required,\n  if the file has more than one top-level namespace (`describe`, `context`, ..).\n\n## Recommendations\n\nHere are some other plugins I recommend for Haskell development:\n\n- [mrcjkb/haskell-tools.nvim](https://github.com/mrcjkb/haskell-tools.nvim):\n  Toolset to improve the Haskell experience in Neovim.\n- [haskell-snippets.nvim](https://github.com/mrcjkb/haskell-snippets.nvim)\n  Collection of Haskell snippets for [LuaSnip](https://github.com/L3MON4D3/LuaSnip).\n- [luc-tielen/telescope_hoogle](https://github.com/luc-tielen/telescope_hoogle):\n  Hoogle search.\n\n## Contributors ✨\n\nThanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/Trouble-Truffle\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/90542764?v=4?s=100\" width=\"100px;\" alt=\"Perigord\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003ePerigord\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/mrcjkb/neotest-haskell/commits?author=Trouble-Truffle\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/saep\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/1560366?v=4?s=100\" width=\"100px;\" alt=\"Sebastian Witte\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eSebastian Witte\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/mrcjkb/neotest-haskell/commits?author=saep\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"#infra-saep\" title=\"Infrastructure (Hosting, Build-Tools, etc)\"\u003e🚇\u003c/a\u003e \u003ca href=\"https://github.com/mrcjkb/neotest-haskell/commits?author=saep\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/andy-bell101\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/13719403?v=4?s=100\" width=\"100px;\" alt=\"Andy Bell\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAndy Bell\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/mrcjkb/neotest-haskell/commits?author=andy-bell101\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://cs-syd.eu\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/3521180?v=4?s=100\" width=\"100px;\" alt=\"Tom Sydney Kerckhove\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eTom Sydney Kerckhove\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#mentoring-NorfairKing\" title=\"Mentoring\"\u003e🧑‍🏫\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/shinzui\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/519?v=4?s=100\" width=\"100px;\" alt=\"Nadeem Bitar\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eNadeem Bitar\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/mrcjkb/neotest-haskell/issues?q=author%3Ashinzui\" title=\"Bug reports\"\u003e🐛\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/MangoIV\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/40720523?v=4?s=100\" width=\"100px;\" alt=\"Mango The Fourth\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMango The Fourth\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/mrcjkb/neotest-haskell/issues?q=author%3AMangoIV\" title=\"Bug reports\"\u003e🐛\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://glitchbra.in\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/29253044?v=4?s=100\" width=\"100px;\" alt=\"Hécate Moonlight\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eHécate Moonlight\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/mrcjkb/neotest-haskell/issues?q=author%3AKleidukos\" title=\"Bug reports\"\u003e🐛\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/amaanq\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/29718261?v=4?s=100\" width=\"100px;\" alt=\"Amaan Qureshi\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAmaan Qureshi\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/mrcjkb/neotest-haskell/commits?author=amaanq\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://bitsbybrad.com\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/15267511?v=4?s=100\" width=\"100px;\" alt=\"Brad Sherman\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eBrad Sherman\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/mrcjkb/neotest-haskell/commits?author=bradsherman\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors)\nspecification. Contributions of any kind welcome!\n\n\u003c!-- MARKDOWN LNIKS \u0026 IMAGES --\u003e\n\u003c!-- markdownlint-disable --\u003e\n[neovim-shield]: https://img.shields.io/badge/NeoVim-%2357A143.svg?\u0026style=for-the-badge\u0026logo=neovim\u0026logoColor=white\n[neovim-url]: https://neovim.io/\n[lua-shield]: https://img.shields.io/badge/lua-%232C2D72.svg?style=for-the-badge\u0026logo=lua\u0026logoColor=white\n[lua-url]: https://www.lua.org/\n[nix-shield]: https://img.shields.io/badge/nix-0175C2?style=for-the-badge\u0026logo=NixOS\u0026logoColor=white\n[nix-url]: https://nixos.org/\n[haskell-shield]: https://img.shields.io/badge/Haskell-5e5086?style=for-the-badge\u0026logo=haskell\u0026logoColor=white\n[haskell-url]: https://www.haskell.org/\n[issues-shield]: https://img.shields.io/github/issues/mrcjkb/neotest-haskell.svg?style=for-the-badge\n[issues-url]: https://github.com/mrcjkb/neotest-haskell/issues\n[license-shield]: https://img.shields.io/github/license/mrcjkb/neotest-haskell.svg?style=for-the-badge\n[license-url]: https://github.com/mrcjkb/neotest-haskell/blob/master/LICENSE\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/mrcjkb/neotest-haskell/nix-build.yml?style=for-the-badge\n[ci-url]: https://github.com/mrcjkb/neotest-haskell/actions/workflows/nix-build.yml\n[luarocks-shield]: https://img.shields.io/luarocks/v/MrcJkb/neotest-haskell?logo=lua\u0026color=purple\u0026style=for-the-badge\n[luarocks-url]: https://luarocks.org/modules/MrcJkb/neotest-haskell\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrcjkb%2Fneotest-haskell","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrcjkb%2Fneotest-haskell","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrcjkb%2Fneotest-haskell/lists"}