{"id":20910099,"url":"https://github.com/viperproject/gobra-mode","last_synced_at":"2026-04-03T10:36:35.348Z","repository":{"id":63346403,"uuid":"561235391","full_name":"viperproject/gobra-mode","owner":"viperproject","description":"Support for Gobra in emacs","archived":false,"fork":false,"pushed_at":"2024-08-13T14:40:30.000Z","size":84,"stargazers_count":1,"open_issues_count":2,"forks_count":1,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-01-19T15:23:18.151Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Emacs Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/viperproject.png","metadata":{"files":{"readme":"README.org","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}},"created_at":"2022-11-03T08:51:42.000Z","updated_at":"2024-08-13T14:40:09.000Z","dependencies_parsed_at":"2024-11-18T14:14:04.480Z","dependency_job_id":"a1477af6-9d14-41dc-8c05-2dc2746b9da9","html_url":"https://github.com/viperproject/gobra-mode","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viperproject%2Fgobra-mode","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viperproject%2Fgobra-mode/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viperproject%2Fgobra-mode/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viperproject%2Fgobra-mode/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/viperproject","download_url":"https://codeload.github.com/viperproject/gobra-mode/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243302385,"owners_count":20269499,"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-11-18T14:13:54.223Z","updated_at":"2025-12-26T10:51:28.284Z","avatar_url":"https://github.com/viperproject.png","language":"Emacs Lisp","funding_links":[],"categories":[],"sub_categories":[],"readme":"* Gobra-mode for Emacs\n\nAdds support to Emacs for [[https://www.pm.inf.ethz.ch/research/gobra.html][Gobra]]. Features include:\n- Syntax highlighting for Gobra keywords.\n- Interface to the Gobra executable.\n- Error highlighting after running Gobra.\n- Jump to error functionality.\n- Interface for manipulating Gobra parameters.\n- Various manipulations of ghost code blocks in ~.go~ files.\n\n* Installation\n\nThis package is under development (many changes may be non backwards compatible). Thus, it is not published in any package archives.\n\nTo install it, one must clone the repository:\n\n#+BEGIN_SRC shell\n  git clone git@github.com:viperproject/gobra-mode.git\n#+END_SRC\n\nThen, add the following lines in your init file.\n\n#+BEGIN_SRC emacs-lisp\n  (add-to-list 'load-path \"\u003cgobra-mode repo path\u003e\")\n  (use-package gobra-mode)\n  (setq gobra-jar-path \"\u003cgobra jar file path\u003e\")\n  (setq gobra-z3-path \"\u003cZ3 executable path\u003e\")\n#+END_SRC\n* Usage\n\nDefault keybindings provided by the gobra minor mode:\n- ~C-c g v~: Verifies the file corresponding to the current buffer.\n- ~C-c g c~: Opens the generated Viper code in a new buffer.\n- ~C-c g a~: Spawns a construction buffer through which the parameters passed to gobra are manipulated.\n- ~C-c g s~: Gobra mode creates the command that Gobra should run serializing the parameters and copying it to the kill-ring. Useful if working with the sbt shell of Gobra directly.\n- ~C-c g b~: Gobra mode defines a hook called ~gobra-verification-hook~. Anything added to that will be called when verification finishes if the variable ~gobra-enable-verification-hook~ is non-nil. Useful if you want to be notified after a large verification task finishes. This command toggles the variable ~gobra-enable-verification-hook~.\n- ~C-c g k~: Toggles the popping up of the verification buffer when verifying something. Useful if you need the verification buffer on a frame on a different monitor.\n- ~C-c g l~: Verify the function under the cursor only. This assumes the parameters explicitly have the current file for verification (not its directory or package).\n- ~C-c g h~: Fold or unfold ghost code chunk under cursor (works for ~.go~ files where the comment syntax (~// @~) is used.\n- ~C-c g j~: Unfold every folded piece of ghost code in the current buffer.\n- ~C-c g f~: Format the ghost code chunk under cursor. This currently converts ~//@~ annotations to ~// @~ annotations and aligns the arguments of the keywords ~preserves~, ~requires~ and ~ensures~ in function contracts.\n- ~C-c g C-f~: Format ghost code in the whole buffer.\n- ~C-c g p~: Jump to previous ghost code chunk.\n- ~C-c g n~: Jump to next ghost code chunk.\n\nIf [[https://github.com/abo-abo/hydra][Hydra]] is installed, pressing ~C-c g~ will spawn a hydra menu with all these commands available.\n\nThe construction buffer for the parameters can be used to set, unset or modify the existing parameters of Gobra. It contains a checklist of possible Gobra parameters for which the following operations are defined:\n\n- ~c~: Set or unset the current parameter. If the parameter has itself arguments, the user is prompted to fill them.\n- ~a~: Add arguments to an already set parameter.\n- ~d~: Delete the current argument of a parameter.\n- ~?~: Print documentation about the current parameter.\n- ~s~: Save the current set of parameters (and their arguments) to a file.\n- ~l~: Load a configuration from a file.\n- ~q~: Exit and return to the Gobra buffer.\n- ~j~: Jump to a specific parameter.\n- ~n~ - ~p~: Move up and down.\n\nWhen the verifier is running, it lives in an async command in a buffer by default called ~*Gobra Command Output*~. That buffer also supports some extra functionality, namely:\n\n- ~n~: Go to the next reported error.\n- ~p~: Go to the previous reported error.\n- ~RET~: Go to the location of the error reported under the cursor at the corresponding file. If the file is not open, it is opened. If the cursor is over an error of the Gobra implementation, ~RET~ opens the corresponding file where the exception was raised. This only works if ~gobra-development-path~ is set to point to the src directory of Gobra.\n\nWhen the Gobra command terminates, the errors are highlighted in the already open buffers that are getting verified.\n\n* Minor mode\n\nThe minor mode can be enabled automatically when a ~.go~ file is opened with:\n\n#+begin_src emacs-lisp\n  (add-hook 'go-mode-hook 'gobra-minor-mode)\n#+end_src\n\nNote that the minor mode is responsible for almost everything so it should be enabled for ~.gobra~ files as well. ~gobra-mode~ however is a major mode deriving from ~go-mode~ so hooking the minor mode to ~go-mode~ will enable it for Gobra buffers as well.\n\n* Overriding Go mode hooks\n\n~gobra-mode~ is a derived mode from ~go-mode~. This means that when opening a ~.gobra~ file the ~go-mode-hook~ functions will be invoked. This creates a problem for example with the use of LSP mode if it is configured to start automatically for go files because there is no LSP backend for Gobra. To override that hook, a local variable ~gobra-actions-before-go-mode~ is defined which holds a function with stuff to do before the ~go-mode~ hooked functions run. The following hack is then possible to stop LSP from starting in a Gobra buffer:\n\nFirst define a buffer-local variable:\n#+begin_src emacs-lisp\n  (defvar-local my/conditional-lsp-flag t)\n#+end_src\n\nThen define a function starting LSP when that variable is true:\n#+begin_src emacs-lisp\n  (defun my/conditional-lsp ()\n    (when my/conditional-lsp-flag\n      (lsp)))\n#+end_src\n\nHook this to ~go-mode~ instead of just LSP:\n#+begin_src emacs-lisp\n  (add-hook go-mode-hook 'my/conditional-lsp)\n#+end_src\n\nUse the ~gobra-actions-before-go-mode~ variable to turn the local variable to nil:\n#+begin_src emacs-lisp\n  (setq gobra-actions-before-go-mode\n        (lambda ()\n          (setq-local my/conditional-lsp-flag nil)))\n#+end_src\n\nNow whenever a ~.gobra~ file is opened, ~lsp~ won't be invoked.\n\n* Who do I talk to?\nThis project is maintained by [[https://github.com/Dspil][Dionisios Spiliopoulos]]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviperproject%2Fgobra-mode","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fviperproject%2Fgobra-mode","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviperproject%2Fgobra-mode/lists"}