{"id":51452565,"url":"https://github.com/jcmfernandes/go-ginkgo.el","last_synced_at":"2026-07-05T22:03:37.333Z","repository":{"id":368058193,"uuid":"1283346118","full_name":"jcmfernandes/go-ginkgo.el","owner":"jcmfernandes","description":"Run Ginkgo specs straight from a Go buffer in Emacs.","archived":false,"fork":false,"pushed_at":"2026-06-28T22:12:17.000Z","size":41,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-28T23:05:12.256Z","etag":null,"topics":["elisp","emacs","ginkgo","golang","testing"],"latest_commit_sha":null,"homepage":"","language":"Emacs Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jcmfernandes.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,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-28T20:34:40.000Z","updated_at":"2026-06-28T22:12:21.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jcmfernandes/go-ginkgo.el","commit_stats":null,"previous_names":["jcmfernandes/go-ginkgo.el"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/jcmfernandes/go-ginkgo.el","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcmfernandes%2Fgo-ginkgo.el","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcmfernandes%2Fgo-ginkgo.el/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcmfernandes%2Fgo-ginkgo.el/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcmfernandes%2Fgo-ginkgo.el/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jcmfernandes","download_url":"https://codeload.github.com/jcmfernandes/go-ginkgo.el/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcmfernandes%2Fgo-ginkgo.el/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35170545,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-05T02:00:06.290Z","response_time":100,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["elisp","emacs","ginkgo","golang","testing"],"created_at":"2026-07-05T22:03:36.904Z","updated_at":"2026-07-05T22:03:37.314Z","avatar_url":"https://github.com/jcmfernandes.png","language":"Emacs Lisp","funding_links":[],"categories":[],"sub_categories":[],"readme":"# go-ginkgo\n\n[![Tests](https://github.com/jcmfernandes/go-ginkgo.el/actions/workflows/test.yml/badge.svg)](https://github.com/jcmfernandes/go-ginkgo.el/actions/workflows/test.yml)\n\nRun [Ginkgo](https://onsi.github.io/ginkgo/) (BDD) specs straight from a Go\nbuffer in Emacs. `go-ginkgo` drives the `ginkgo` CLI through `compilation-mode`\nand is **tree-sitter native**: it finds the spec at point by walking the Go\nsyntax tree, not by scanning text.\n\nIt is a modern rework of the unmaintained, Ginkgo-v1-era\n[`ginkgo-mode`](https://github.com/garslo/ginkgo-mode).\n\n## Why\n\n- **Tree-sitter spec finding.** Walks up the buffer's Go parser to the enclosing\n  container/spec `call_expression` and reads its description. Understands the\n  full Ginkgo v2 node set — `Describe`/`Context`/`When`/`It`/`Specify`/\n  `DescribeTable`/`Entry` and the `F` (focused) and `P`/`X` (pending) decorator\n  variants — and the real call nesting, so a stray `It(` in a comment or string\n  never confuses it.\n- **RE2-correct `--focus`.** `ginkgo --focus` takes a Go (RE2) regexp. A\n  description with metacharacters — e.g. the parens in `handles (key) lookups` —\n  passed verbatim would match nothing and *silently run zero specs*. `go-ginkgo`\n  escapes the description as an RE2 literal first. (Emacs's own `regexp-quote`\n  is wrong for this: it leaves `(` `)` `{` `}` unescaped, since they are literal\n  in Emacs regexp syntax.)\n- **Precise nested focus.** By default it joins the *full ancestry* of\n  descriptions, so focusing a deeply nested `It` runs that one spec rather than\n  every spec that shares its innermost text.\n- **Real compilation buffer.** Navigable (`RET` / `C-x \\``), re-runnable (`g`),\n  ANSI-coloured output.\n\n## Requirements\n\n- Emacs 29.1+ (tree-sitter).\n- The **Go tree-sitter grammar** (e.g. via `M-x treesit-install-language-grammar`\n  or `treesit-auto`), and a Go major mode that creates a parser, such as the\n  built-in `go-ts-mode`.\n- The **`ginkgo` CLI** on `exec-path`\n  (`go install github.com/onsi/ginkgo/v2/ginkgo@latest`).\n\n## Installation\n\nWith `use-package` + a recent Emacs (`:vc`):\n\n```elisp\n(use-package go-ginkgo\n  :vc (:url \"https://github.com/jcmfernandes/go-ginkgo.el\")\n  :hook (go-ts-mode . go-ginkgo-mode)\n  :custom (go-ginkgo-keymap-prefix \"C-c G\"))\n```\n\nWith `straight.el`:\n\n```elisp\n(use-package go-ginkgo\n  :straight (:host github :repo \"jcmfernandes/go-ginkgo.el\")\n  :hook (go-ts-mode . go-ginkgo-mode)\n  :init (setq go-ginkgo-keymap-prefix \"C-c G\"))\n```\n\nOr clone it onto your `load-path` and `(require 'go-ginkgo)`.\n\n## Usage\n\nEnable `go-ginkgo-mode` in Go buffers (the hooks above do this). With\n`go-ginkgo-keymap-prefix` set, `go-ginkgo-command-map` is bound under it:\n\n| Key (after prefix) | Command                     | Action                                            |\n|--------------------|-----------------------------|---------------------------------------------------|\n| `s`                | `go-ginkgo-run-spec`        | Run the container/spec at point (`--focus`)       |\n| `f`                | `go-ginkgo-run-file`        | Run specs in the current file (`--focus-file`)    |\n| `p`                | `go-ginkgo-run-package`     | Run the suite in the current directory            |\n| `j`                | `go-ginkgo-run-project`     | Run every suite in the project (`-r`)             |\n| `L`                | `go-ginkgo-run-labels`      | Run by label filter (`--label-filter`)            |\n| `l`                | `go-ginkgo-run-last`        | Re-run the last invocation                        |\n| `w`                | `go-ginkgo-watch`           | `ginkgo watch` the current package                |\n| `b`                | `go-ginkgo-bootstrap`       | `ginkgo bootstrap`                                |\n| `n`                | `go-ginkgo-generate`        | `ginkgo generate` for the current file            |\n| `d`                | `go-ginkgo-toggle-dry-run`  | Toggle `--dry-run`                                |\n\nPrefer to bind it yourself? `go-ginkgo-command-map` is a prefix command:\n\n```elisp\n(keymap-set go-ts-mode-map \"C-c G\" 'go-ginkgo-command-map)\n```\n\nAll commands are also available via `M-x` and are autoloaded.\n\n## Customization\n\n- `go-ginkgo-binary` — name/path of the executable (default `\"ginkgo\"`).\n- `go-ginkgo-extra-args` — args always added to spec runs and `watch` (e.g.\n  build tags `(\"--tags\" \"integration\")`).\n- `go-ginkgo-parallel` — `nil` (serial), `t` (`-p`, auto), or an integer\n  (`--procs N`).\n- `go-ginkgo-dry-run` — when non-nil, add `--dry-run` (list without running).\n- `go-ginkgo-focus-strategy` — `full-path` (default, precise) or `innermost`.\n- `go-ginkgo-container-nodes` — the constructor names treated as containers;\n  extend it if you wrap Ginkgo's nodes in your own helpers.\n- `go-ginkgo-buffer-name` — name of the compilation buffer.\n\n## Development\n\nA [devenv](https://devenv.sh) shell provides Emacs, the `ginkgo` CLI, Go, and\nthe toolchain the grammar build needs (git, a C compiler, make):\n\n```sh\ndevenv shell                      # drop into the dev environment\ndevenv shell -- make grammar all  # grammar + full CI gate, non-interactively\n```\n\nInside the shell, the Makefile drives the gate: install the grammar, then\n`make all` (compile + checkdoc + test). CI runs the same targets across an\nEmacs matrix, selecting the build with `$EMACS_PKG`:\n\n```sh\nEMACS_PKG=emacs29 devenv shell -- make grammar all   # 29.4 (pinned nixos-24.05; the floor)\nEMACS_PKG=emacs30 devenv shell -- make grammar all   # 30.x (current stable; the default)\n```\n\nWith [direnv](https://direnv.net), `direnv allow` loads it automatically on\n`cd`. The included `.envrc` is portable — it only needs `devenv` on `PATH`.\n\nThe Makefile targets work in or out of the shell:\n\n```sh\nmake compile     # byte-compile, warnings are errors\nmake checkdoc    # doc/style lint\nmake grammar     # install the Go grammar (for the tree-sitter tests)\nmake test        # run the ERT suite\nmake all         # the full CI gate\n```\n\n`make grammar` installs the Go grammar into a project-local `.emacs.d/`\ndirectory (not your real `~/.emacs.d`), and `make test` looks there\nautomatically — so the tree-sitter tests just work after one `make grammar`.\nTests skip themselves when the grammar is unavailable, so the non-grammar\ntests run anywhere. The grammar is pinned to an ABI-14 tag (`GRAMMAR_REV`) so\nit loads on Emacs 29 as well as 30/31 — master is ABI 15, which Emacs 29\ncannot load.\n\nOverride `EMACS_HOME` to install elsewhere (e.g. your shared `~/.emacs.d`), or\npoint `make test` at a grammar you installed some other way with\n`TREESIT_EXTRA`:\n\n```sh\nmake grammar EMACS_HOME=~/.emacs.d\nmake test    TREESIT_EXTRA=/path/to/dir/with/libtree-sitter-go.so\n```\n\n## License\n\nGPL-3.0-or-later. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcmfernandes%2Fgo-ginkgo.el","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjcmfernandes%2Fgo-ginkgo.el","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcmfernandes%2Fgo-ginkgo.el/lists"}