{"id":13837507,"url":"https://github.com/Simspace/simformat","last_synced_at":"2025-07-10T18:33:30.799Z","repository":{"id":40403428,"uuid":"103278597","full_name":"Simspace/simformat","owner":"Simspace","description":"Formats haskell import lists","archived":false,"fork":false,"pushed_at":"2023-06-23T08:26:29.000Z","size":101,"stargazers_count":5,"open_issues_count":0,"forks_count":6,"subscribers_count":48,"default_branch":"master","last_synced_at":"2025-04-09T22:40:49.133Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Simspace.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,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-09-12T14:06:47.000Z","updated_at":"2023-10-19T17:26:36.000Z","dependencies_parsed_at":"2024-01-13T17:10:43.024Z","dependency_job_id":"a940f6a2-70d6-4fca-8f75-a41b0f6e1540","html_url":"https://github.com/Simspace/simformat","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Simspace/simformat","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Simspace%2Fsimformat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Simspace%2Fsimformat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Simspace%2Fsimformat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Simspace%2Fsimformat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Simspace","download_url":"https://codeload.github.com/Simspace/simformat/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Simspace%2Fsimformat/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264631212,"owners_count":23640941,"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":[],"created_at":"2024-08-04T15:01:12.048Z","updated_at":"2025-07-10T18:33:30.457Z","avatar_url":"https://github.com/Simspace.png","language":"Haskell","funding_links":[],"categories":["Haskell"],"sub_categories":[],"readme":"# SimFormat\n\n[![Build Status](https://travis-ci.com/simspace/simformat.svg?branch=master)](https://travis-ci.com/simspace/simformat)\n\nFormats Haskell import lists.\n\nIt produces import lists that look like this:\n\n```haskell\nimport Range.Shared.Types\n  ( ExternalRef(..), Imports(Imports), SomeExternalRef(SomeExternalRef), SpecEntity(..)\n  , SpecRef(SpecRefExternal, SpecRefLocal), ExternalEntities, IsSpecEntity, ResolvedSpec\n  , SpecEntities, VmRepetitionGroup, VmRgTag, importsConfigModuleDefs, importsOperatingSystems\n  , importsVmTemplates, specEntitiesConfigModuleDefs, specEntitiesOperatingSystems\n  , specEntitiesVmTemplates, specEntity, specificationEntities\n  )\n```\n\n## Usage\n\nBy default, `simformat` formats an entire git repository using a `.simformatrc` config file in the repo root to identify\nfiles to include. To bypass this behavior you can call it with `simformat \u003cfile\u003e` which will format the file regardless of\nwhether it's in the configuration. It should always succeed: if it cannot find any import blocks, it will simply pass\nthe text on unchanged. You can always run `simformat --help` for more command-line options.\n\n```\n$ stack install\n```\n\n### Emacs\n\nFrom within Emacs, assuming you have the `haskell-mode` and `stylish-haskell` packages installed and working, `(setq\nhaskell-mode-stylish-haskell-path \"simformat -e\")` and `(setq haskell-stylish-on-save t)` should automatically reformat\nyour import list on every save.\n\nIf you prefer not to run code on save, you can use `shell-command-on-region` with a region active and the prefix\nargument set, i.e. `C-u M-| simformat`\n\n### Vim\n\nIf you use [`null-ls.nvim`](https://github.com/jose-elias-alvarez/null-ls.nvim/) an excellent plugin for integrating external tools for formatting / diagnostics in a way compatible with neovim's builtin LSP you can use this snippet to register a source that will format Haskell files using `simformat`:\n```viml\nlua \u003c\u003c EOF\nlocal null_ls = require('null-ls')\nlocal simformat = {\n  name = 'simformat',\n  method = null_ls.methods.FORMATTING,\n  filetypes = {'haskell'},\n  generator = require('null-ls.helpers').formatter_factory {\n    command = 'simformat',\n    args = {'-e'},\n    to_stdin = true,\n  },\n}\nnull_ls.register(simformat)\nEOF\n```\n\n\n\nOne possible vim solution is to add this to your `.vimrc` file:\n\n```\nfunction! s:RunSimformat()\n  if \u0026filetype == 'haskell'\n    let cmd = 'simformat -e'\n    let stdin = join(getline(1, '$'), \"\\n\")\n    let output = system(cmd, stdin)\n    if v:shell_error != 0\n      echom output\n    else\n      call s:OverwriteBuffer(output)\n    endif\n  endif\nendfunction\n\nfunction! s:OverwriteBuffer(output)\n  if \u0026modifiable\n    let l:curw=winsaveview()\n    try | silent undojoin | catch | endtry\n    let splitted = split(a:output, '\\n')\n    if line('$') \u003e len(splitted)\n      execute len(splitted) .',$delete'\n    endif\n    call setline(1, splitted)\n    call winrestview(l:curw)\n  else\n    echom \"Cannot write to non-modifiable buffer\"\n  endif\nendfunction\n\naugroup Simformat\n  autocmd!\n  autocmd BufWritePre * call \u003cSID\u003eRunSimformat()\naugroup END\n```\n\nTo format without running on save, run `:!simformat` (to format all files that are children of the `pwd`) or run `:%!simformat -e` (to format just the current file).\n\n### VSCode\n\nAdd this to `~/Library/Application Support/Code/User/settings.json` once you have installed the [Run on Save](https://github.com/pucelle/vscode-run-on-save) extension.\n\n```json\n    \"runOnSave.statusMessageTimeout\": 3000,\n    \"runOnSave.commands\": [\n        {\n            \"match\": \".*\\\\.hs$\",\n            \"notMatch\": \"[\\\\\\\\\\\\/]_[^\\\\\\\\\\\\/]*\\\\.hs$\",\n            \"command\": \"simformat ${file}\",\n            \"runIn\": \"backend\",\n            \"runningStatusMessage\": \"Formatting ${fileBasename}\",\n            \"finishStatusMessage\": \"${fileBasename} formatted\"\n        }\n    ]\n```\n\n## .simformatrc example\n\nThe config file, `.simformatrc`, is expected to live in the directory where the `simformat` executable is being run.\nIt's a YAML file containing two keys: `files` and `whitelist`, each with a list of filepaths. If `.simformatrc` is not\npresent, it will interpret `files` to be all files, and `whitelist` to be empty.\n\n```yaml\nfiles:\n  - foo\nwhitelist:\n  - foo/bar\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSimspace%2Fsimformat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSimspace%2Fsimformat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSimspace%2Fsimformat/lists"}