{"id":16313427,"url":"https://github.com/alhassy/org-agda-mode","last_synced_at":"2025-03-22T20:35:27.735Z","repository":{"id":46194006,"uuid":"155313377","full_name":"alhassy/org-agda-mode","owner":"alhassy","description":"An Emacs mode for working with Agda code in an Org-mode like fashion, more or less.","archived":false,"fork":false,"pushed_at":"2021-11-08T10:39:58.000Z","size":88,"stargazers_count":17,"open_issues_count":1,"forks_count":7,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-10-11T21:51:25.411Z","etag":null,"topics":["agda","emacs","literate-programming","minor-mode","org-mode"],"latest_commit_sha":null,"homepage":null,"language":"Emacs Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alhassy.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-10-30T02:39:33.000Z","updated_at":"2024-06-19T08:32:44.000Z","dependencies_parsed_at":"2022-09-08T11:30:08.566Z","dependency_job_id":null,"html_url":"https://github.com/alhassy/org-agda-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/alhassy%2Forg-agda-mode","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alhassy%2Forg-agda-mode/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alhassy%2Forg-agda-mode/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alhassy%2Forg-agda-mode/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alhassy","download_url":"https://codeload.github.com/alhassy/org-agda-mode/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221839342,"owners_count":16889603,"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":["agda","emacs","literate-programming","minor-mode","org-mode"],"created_at":"2024-10-10T21:51:13.196Z","updated_at":"2024-10-28T14:19:23.683Z","avatar_url":"https://github.com/alhassy.png","language":"Emacs Lisp","readme":"# Created 2019-10-03 Thu 11:13\n#+OPTIONS: toc:nil d:nil\n#+OPTIONS: html-postamble:nil\n#+TITLE: Better Org-mode support for Literate Agda\n#+DATE: 2018-11-03\n#+AUTHOR: Musa Al-hassy \u0026 Mark Armstrong\n#+DESCRIPTION: Major mode for working with literate Org Agda files\n#+export_file_name: README.org\n#+Property: header-args :tangle org-agda-mode.el\n\n* Introduction\n\n# This paragraph is copied below in [[Package header]]\n# Note the DESCRIPTION is also echoed there.\nAn Emacs major mode for editing Agda code embedded in Org files\n(~.lagda.org~ files.)\nSee the\n[[https://agda.readthedocs.io/en/v2.6.1/tools/literate-programming.html#literate-org][Agda manual]]\nfor more information.\n\nAn older version of this support is documented in a\n[[https://alhassy.github.io/literate/][blog post]].\nThe current version is a complete departure, motivated by\n- the support in recent Agda versions (\u003e 2.6) for literate files with\n  ~.lagda.org~ extensions, and\n- the ability to work in multiple Emacs modes at once via the Polymode package.\n\n* Package header                                :noexport:\n\n#+begin_src emacs-lisp\n;;; org-agda-mode.el --- Major mode for working with literate Org Agda files\n;;; -*- lexical-binding: t\n\n;;; Commentary:\n\n;; A Major mode for editing Agda code embedded in Org files (.lagda.org files.)\n;; See the Agda manual for more information:\n;; https://agda.readthedocs.io/en/v2.6.1/tools/literate-programming.html#literate-org\n\n;;; Code:\n#+end_src\n\n* Installation\n\nSimply place ~org-agda-mode.el~ in your Emacs load path,\nand add\n#+begin_src emacs-lisp\n(require 'org-agda-mode)\n#+end_src\nto your Emacs initialisation file.\n\nAlternatively, if you use straight.el and use-package, then this package can be installed by adding the following to your emacs configuration.\n#+BEGIN_SRC emacs-lisp\n(use-package polymode)\n(use-package org-agda-mode\n  :straight (:host github\n\t\t   :repo \"alhassy/org-agda-mode\"\n\t\t   :branch \"master\"\n\t\t   :files (\"org-agda-mode.el\")\n\t\t   )\n  )\n#+END_SRC\n\n* Background\n\n** Polymode\n\nPolymode allows us to use more than one major mode in a buffer,\nsomething usually impossible in Emacs.\nNote there do exist several other solutions for this, such as MMM;\nPolymode seemed the best candidate for what I want during my\n(admittedly rather brief) search for solutions.\n\n[[https://polymode.github.io/][Read the docs]]!\n\n* Prerequisite packages\n\n#+begin_src emacs-lisp\n(require 'polymode)\n(require 'agda2-mode)\n#+end_src\n\n* Customisations\n\n#+begin_src emacs-lisp\n(defgroup org-agda-mode nil\n  \"org-agda-mode customisations\"\n  :group 'languages)\n#+end_src\n\nNaturally, users will often want to use Agda input mode\nto enter unicode characters in their literate documentation.\nDo note that it's also possible to enable this input mode\nglobally in your Emacs init.\n#+begin_src emacs-lisp\n(defcustom use-agda-input t\n  \"Whether to use Agda input mode in non-Agda parts of the file.\"\n  :group 'org-agda-mode\n  :type 'boolean)\n#+end_src\n\n* Org-Agda mode definition\n\nOrg is our hostmode.\n#+begin_src emacs-lisp\n(define-hostmode poly-org-agda-hostmode\n  :mode 'org-mode\n  :keep-in-mode 'host)\n#+end_src\n\nAgda is our inner mode, delimited by Org source blocks.\n#+begin_src emacs-lisp\n(define-innermode poly-org-agda-innermode\n  :mode 'agda2-mode\n  :head-matcher \"#\\\\+begin_src agda2\"\n  :tail-matcher \"#\\\\+end_src\"\n  ;; Keep the code block wrappers in Org mode, so they can be folded, etc.\n  :head-mode 'org-mode\n  :tail-mode 'org-mode\n  ;; Disable font-lock-mode, which interferes with Agda annotations,\n  ;; and undo the change to indent-line-function Polymode makes.\n  :init-functions '((lambda (_) (font-lock-mode 0))\n                    (lambda (_) (setq indent-line-function #'indent-relative))))\n#+end_src\n:TODO: rather than ~indent-relative~, we should probably use the user's default.\n\nNow we define the polymode using the above host and inner modes.\n#+begin_src emacs-lisp\n(define-polymode org-agda-mode\n  :hostmode 'poly-org-agda-hostmode\n  :innermodes '(poly-org-agda-innermode)\n  (when use-agda-input (set-input-method \"Agda\")))\n#+end_src\n\n* Prevent Agda from applying annotations to the literate Org portion\n\nAgda's highlighting mode makes use of ~annotate~ to apply syntax highlighting\nthroughout the buffer, including the literate portion,\nwhich ~agda2-highlight~ identifies as “background”.\nOlder versions of Agda would highlight the background using\n~font-lock-comment-face~ (so, making them the same colour as comments).\nNewer versions (since\n[[https://github.com/agda/agda/commit/8bee8727fff1a87c708c28b02edc38931c91f1fb#diff-4b761ced0541ba9fd4efbe58fd37ba7f][this]]\ncommit) simply apply Emacs' default face.\n\nSince we're using Org mode for the literate portion,\nwe don't want Agda to apply any annotation there.\nWe can achieve this by simply removing the setting for background\nfrom the Agda highlight faces attribute list.\n#+begin_src emacs-lisp\n(assq-delete-all 'background agda2-highlight-faces)\n#+end_src\n\n:TODO: This is not a full fix for the syntax highlighting issues.\nThere is a greater conflict between ~annotate~ and ~font-lock~\nthat we need to fix.\n\n* Automatically use ~org-agda-mode~ for ~.lagda.org~ files\n\nFinally, add our new mode to the auto mode list.\n#+begin_src emacs-lisp\n;;;###autoload\n(add-to-list 'auto-mode-alist '(\"\\\\.lagda.org\" . org-agda-mode))\n#+end_src\n\n* Package footer\n\n#+begin_src emacs-lisp\n(provide 'org-agda-mode)\n;;; org-agda-mode ends here\n#+end_src\n\n* TODO Improvements\n\n- Enable Agda loading, and more generally all the agda keybindings,\n  anywhere in .lagda.org files.\n  - At least the important ones that don't obviously clash with Org bindings.\n  - I've tried loading via ~M-x agda2-load~ from the Org portion,\n    and it works (yay!), but it loses the Agda syntax highlighting?\n- To enable monolith ~.lagda.org~ files\n  (large literate files which tangle several individual clean source files),\n  we need a way to strip one level of indentation after tangling.\n  - Actually it's not /needed/; Agda does allow the contents\n    of the toplevel module (so, the remainder of the file)\n    to be indented; but it breaks /convention/.\n\n** Documentation\n\n- Discover the exact version of Agda that added support for\n  interactive programming in ~.lagda.org~ files.\n\n* COMMENT The original ~org-agda-mode~\n\nGithub recognizes ~.org~ files;\nAgda colouring is determined by typechecking,\nso Github will not provide certain colours.\n\n-----\n\n# toc: headlines 2\n\n# description: An Org-mode utility for Agda.\n# description: An Emacs mode for working with Agda code in an Org-mode like fashion, more or less.\n# startup: indent\n# categories: Agda Org Emacs\n# image: ../assets/img/org_logo.png\n# source: https://raw.githubusercontent.com/alhassy/org-agda-mode/master/literate.lagda\n\n# property: header-args :tangle no\n\n#+begin_center\n*Abstract*\n#+end_center\n\n[[https://en.wikipedia.org/wiki/Literate_programming][Literate Programming]] is essentially the idea that code is enclosed in documentation\nrather than the comments being surrounded by code. The idea is that software\nought to be written like an essay to be read by a human; from this, code for the\nmachine can then be extracted.\n\nThe articles on this blog are meant to be in such a format and as such\nI use [[https://www.offerzen.com/blog/literate-programming-empower-your-writing-with-emacs-org-mode][Org-mode]] as my markup for producing the HTMLs and PDFs.\n\nThis article aims to produce an Org-friendly approach to working\nwith the [[http://wiki.portal.chalmers.se/agda/pmwiki.php][Agda language]], which is special in comparison to many other languages:\nCoding is interactive via holes and it permits almost any sequence of characters\nas a legal lexeme thereby rendering a static highlighting theme impossible.\n\nThe result of this Elisp exploration is that by ~C-x C-a~\nwe can toggle into Agda-mode and use its interactive features to construct our program;\nthen return to an Org-mode literate programming style afterwards with\nanother ~C-x C-a~\n---/both translations remember the position we're working at and allow the editing features of their respective modes!/\nMoreover, we also allow user-defined colouring.\n\nJump to [[#installation]] to quickly get and use the setup.\n\n( Thanks to [[https://github.com/armkeh][Mark Armstrong]] for significant testing and contributions! )\n\n#+begin_quote\n- [[#abstract][Abstract]]\n- [[#agda-now-supports-org-files----not-really][“Agda now supports org files” ---Not Really]]\n- [[#agda-syntax-highlighting][Agda Syntax Highlighting]]\n  - [[#keywords][Keywords]]\n  - [[#the-generic-mode-definition][The ~generic-mode~ Definition]]\n  - [[#user-defined-colouring][User-defined Colouring]]\n- [[#lagda-to-org-and-org-to-lagda][(~lagda-to-org~) and (~org-to-lagda~)]]\n- [[#example-fragments][Example Fragments]]\n- [[#summary][Summary]]\n- [[#installation][Installation]]\n- [[#sources-consulted][Sources Consulted]]\n#+end_quote\n\n** “Agda now supports org files” ---Not Really\n\nAs of Agda 2.6.0 ---which came after this article was originally written---\nthere is now support for literate Org-mode support using ~agda2~ org-src blocks.\n\nThe [[https://github.com/agda/agda/pull/3548][pull request]] was by one of my then students who found the use of this ‘org-agda’\nsetup to be sufficiently useful to be appreciated by the whole Agda community out-of-the-box.\n\nUnfortunately, currently working with a ~myfile.lagda.org~\ncomes with discouraging compromises between the Org- and Agda-modes. Namely:\n1. Interactivity with Agda holes is /not/ supported.\n2. The full editorial capabilities of Org-mode are limited since some\n   features clash with those of Agda-mode.\n\nThe solution outlined here is not to limit nor compromise each role, but rather\nprovide both and instead allow the user, you, to control when you would like\nto be /documenting vs. developing/ ---the resulting system is sufficiently fast\nto toggle between the modes; e.g., the somewhat large categorical development\n[[https://alhassy.github.io/PathCat/][Graphs are to categories as lists are to monoids]] is written literately using org-agda.\n\nBesides the core capability to switch between the different modes, we also provide\nan elementary yet /extensible/ syntax colouring mechanism for Agda's non-standard highlighting.\n\n** Agda Syntax Highlighting\n\nWe produce a new mode, calling it ~ob-agda-mode~,\nso that Org-mode blocks marked with ~ob-agda~ will have Agda /approximated/\nsyntax. By default, if an Emacs major-mode ~\u003clang\u003e-mode~ exists,\nthen blocks marked with ~\u003clang\u003e~ use that major-mode for editing.\n\n#+begin_src emacs-lisp\n;; To use generic-mode later below.\n(require 'generic-x)\n#+end_src\n\nThe “ob” is short for “org-babel” since we also wish to provide\nBabel support for Agda. Using ~ob-agda~ marked blocks is awkward and exposes\nsome of our implementation, we will instead support an alias ~agda~ which refers to ~ob-agda~.\n\nWe can use the ~org-src-lang-modes~ variable to map any ---possibly more friendly or suggestive--- identifier to a language major mode.\n#+begin_src emacs-lisp\n(add-to-list 'org-src-lang-modes '(\"agda\" . ob-agda))\n#+end_src\n\n*** Keywords\n\nWe look at the ~agda2-highlight.el~ source file from the Agda repository\nfor colours of keywords and reserved symbols such as ==, λ, ∀=, etc.\n\n#+begin_src emacs-lisp\n(defface agda2-highlight-keyword-face\n  '((t (:foreground \"DarkOrange3\")))\n  \"The face used for keywords.\"\n    :group 'font-lock-faces)\n\n(setq font-lock-keyword-face 'agda2-highlight-keyword-face)\n\n(defface agda2-highlight-symbol-face\n  '((((background light)) (:foreground \"gray25\"))\n    (((background dark))  (:foreground \"gray75\")))\n  \"The face used for symbols like forall, =, as, -\u003e, etc.\"\n  :group 'font-lock-faces)\n#+end_src\n\nFrom Agda's [[https://agda.readthedocs.io/en/v2.5.4.1/language/lexical-structure.html?highlight=keywords][“read the docs”]] website, we obtain the keywords for the language:\n\n#+begin_src emacs-lisp\n(setq org-agda-keywords\n  '(\"=\" \"|\" \"-\u003e\" \"→\" \":\" \"?\" \"\\\\\" \"λ\" \"∀\" \"..\" \"...\" \"abstract\" \"codata\"\n  \"coinductive\" \"constructor\" \"data\" \"do\" \"eta-equality\" \"field\"\n  \"forall\" \"hiding\" \"import\" \"in\" \"inductive\" \"infix\" \"infixl\"\n  \"infixr\" \"instance\" \"let\" \"macro\" \"module\" \"mutual\" \"no-eta-equality\"\n  \"open\" \"overlap\" \"pattern\" \"postulate\" \"primitive\" \"private\" \"public\"\n  \"quote\" \"quoteContext\" \"quoteGoal\" \"quoteTerm\" \"record\" \"renaming\"\n  \"rewrite\" \"Set\" \"syntax\" \"tactic\" \"unquote\" \"unquoteDecl\" \"unquoteDef\"\n  \"using\" \"where\" \"with\"))\n#+end_src\n\n*** The ~generic-mode~ Definition\n\nAgda colouring is approximated as defined below, but a convention is made:\nFunction symbols begin with a lower case letter, whereas type symbols begin\nwith a capital letter. Otherwise, I would need to resort to Agda's mechanism\nfor determining whether a name is a type or not:\n#+begin_center\n/Parsing is Typechecking!/\n#+end_center\n\n#+begin_src emacs-lisp\n; (defvar org-agda-extra-word-colours nil\n; \"other words that user of org-mode wants coloured, along with their specified font-lock-type-face\")\n\n;; When exporting to .lagda files, I overwrite these to \"\".\n(defvar ob-agda-comment-start \"{-\")\n(defvar ob-agda-comment-end \"{-\")\n\n(define-generic-mode\n\n    'ob-agda-mode                      ;; name of the mode\n\n    (list (cons ob-agda-comment-start ob-agda-comment-end))               ;; comments delimiter\n\n    org-agda-keywords\n\n    ;; font lock list: Order of colouring matters;\n    ;; the numbers refer to the subpart, or the whole(0), that should be coloured.\n\n    (-concat  ;; ★★★ org-agda-extra-word-colours is a free variable,      ★★★\n              ;; ★★★ user should define it /before/ loading org-agda-mode ★★★\n               (if (boundp (quote org-agda-extra-word-colours)) org-agda-extra-word-colours nil)\n    (list\n\n     ;; To begin with, after \"module\" or after \"import\" should be purple\n     ;; Note the SPACE below.\n     '(\"\\\\(module\\\\|import\\\\) \\\\([a-zA-Z0-9\\-_\\.]+\\\\)\" 2 '((t (:foreground \"purple\"))))\n\n     ;; Agda special symbols: as\n     '(\" as\" 0 'agda2-highlight-symbol-face)\n\n     ;; Type, and constructor, names begin with a capital letter  --personal convention.\n     ;; They're preceded by either a space or an open delimiter character.\n     '(\"\\\\( \\\\|\\s(\\\\)\\\\([A-Z]+\\\\)\\\\([a-zA-Z0-9\\-_]*\\\\)\" 0 'font-lock-type-face)\n     '(\"ℕ\" 0 'font-lock-type-face)\n\n     ;; variables \u0026 function names, as a personal convention, begin with a lower case\n     '(\"\\\\([a-z]+\\\\)\\\\([a-zA-Z0-9\\-_]*\\\\)\" 0 '((t (:foreground \"medium blue\"))))\n\n     ;; colour numbers\n     '(\"\\\\([0-9]+\\\\)\" 1   '((t (:foreground \"purple\"))))\n\n     ;; other faces to consider:\n     ;; 'font-lock-keyword-face 'font-lock-builtin-face 'font-lock-function-name-face\n     ;; 'font-lock-variable-name-face 'font-lock-constant-face\n     ))\n\n     ;; files that trigger this mode\n     nil\n\n     ;; any other functions to call\n     nil\n\n     ;; doc string\n     \"My custom Agda highlighting mode for use *within* Org-mode.\"\n)\n#+end_src\n\nI do not insist that ~org-agda-mode~ be activated on any particular files by default.\n\nHere is an example code block that obtains this colouring schema.\n#+begin_src agda\nmodule literate where\n\ndata ℕ : Set where\n  Zero : ℕ\n  Succ : ℕ → ℕ\n\ndouble : ℕ → ℕ\ndouble Zero = Zero\ndouble (Succ n) = Succ (Succ (double n))\n\n{- lengthy\n      multiline\n        comment -}\n\n{- No one line comment colouring … Yet -}\n\nopen import Data.Nat as Lib\n\ncamelCaseIdentifier-01 : Lib.ℕ\ncamelCaseIdentifier-01 = let it = 1234 in it\n#+end_src\n\nNext, we turn to supporting Agda interactivity with holes.\n*** User-defined Colouring\n\nSince true Agda colouring requires type-checking, it is desirable to allow the user to\ninput colouring for their own identifiers. Such \u003c\u003c\u003cuser-defined colouring\u003e\u003e\u003e will be\nvia the delightful org-mode interface: A super simple intuitive table ♥‿♥\n\n#+begin_quote\nFor now, the user-defined Agda colouring mentioned here only serves for an enjoyable\nliterate programming experience. It currently is not picked up by the Org-mode LaTeX backend\nnor the HTML backend.\n#+end_quote\n\nAnywhere in their buffer, the user should have a table with a column for identifiers\nand the colours they should have, as follows.\n#+begin_src org\n,#+RESULTS: ob-agda/colours\n| one   | keyword       |\n| two   | builtin       |\n| three | function-name |\n| four  | variable-name |\n| five  | constant      |\n#+end_src\n\nWhich yields the following colouring,\n#+begin_src agda\none   = Set\ntwo   = Set\nthree = Set\nfour  = Set\nfive  = Set\n#+end_src\n\nWe implement this as follows. We produce a function that realises such colouring assignments:\n#+begin_src emacs-lisp\n(defun ob-agda/add-colour (word colour)\n   \"Refresh the ob-agda-mode to have the new ‘colour’ for ‘word’ in agda blocks.\n\n    + ‘word’ is a string representing an Agda identifier.\n\n    + ‘colour’ is either a symbol from ‘keyword’, ‘builtin’, ‘function-name’,\n       ‘variable-name’, ‘constant’.\"\n   ;; We only declare org-agda-extra-word-colours if the user needs it.\n   ;; If we declare it in the file, as nil, then it will always be nil before\n   ;; the ob-agda-mode is defined and so later changes to this variable will not take effect.\n   ;;\n   (unless (boundp (quote org-agda-extra-word-colours)) (setq org-agda-extra-word-colours nil))\n\n   ;; Discard existing colour-scheme.\n   (unload-feature 'ob-agda-mode)\n\n   ;; Add new colour\n   (if (-contains? '(keyword builtin function-name variable-name constant) colour)\n       (add-to-list 'org-agda-extra-word-colours\n                    `(,word 0 ,(intern (concat \"font-lock-\" (symbol-name colour) \"-face\"))))\n     (message-box \"colour %s\" colour)\n     (add-to-list 'org-agda-extra-word-colours\n                  `(,word 0 ,colour)))\n\n   ;; Load the new altered scheme.\n   (require 'ob-agda-mode \"~/.emacs.d/literate.el\"))\n#+end_src\nThen lookup that user provided table, if it is there, and use it.\n#+begin_src emacs-lisp\n(defun ob-agda/update-colours ()\n \"Searchs current buffer for an ob-agda/colours named result table\n  then uses that to update the colour scheme.\n \"\n (interactive)\n (ignore-errors\n   (save-excursion\n     (org-babel-goto-named-result \"ob-agda/colours\")\n     (forward-line)\n     ;; (setq _it (org-table-to-lisp))\n     (dolist (elem (org-table-to-lisp) org-agda-extra-word-colours)\n       (ob-agda/add-colour (car elem) (intern (cadr elem)))))))\n#+end_src\n\n** (~lagda-to-org~) and (~org-to-lagda~)\n\nPreviously, Agda would not typecheck a non-~lagda~, or non-~agda~, file therefore\nI could not use Org-mode multiple mode settings.\n\nRecent versions of Agda will typecheck files with other extensions,\nbut as of 2.6.0, the interactive mode does not work on such files.\n\nI will instead merely\nswap the syntax of the modes then reload the desired mode.\n--it may not be ideal, but it does what I want in a fast enough fashion.\n\nIn order to maintain position when switching back to Org-mode,\nI define a function which not only goes to the appropriate line,\nbut unfolds the document to show that line.\n\n#+begin_src emacs-lisp\n(defun org-goto-line (line)\n  \"Go to the indicated line, unfolding the parent Org header.\n\n   Implementation: Go to the line, then look at the 1st previous\n   org header, now we can unfold it whence we do so, then we go\n   back to the line we want to be at.\"\n  (goto-line line)\n  (org-back-to-heading 1)\n  (org-cycle)\n  (goto-line line))\n#+end_src\n\nBelow we put together a way to make rewrites ~⟨pre⟩⋯⟨post⟩ ↦ ⟨newPre⟩⋯⟨newPost⟩~\nthen use that with the rewrite tokens being ~#+BEGIN_SRC~ and ~╲begin{code}~ for\nliterate Agda, as well as their closing partners.\n\n#+begin_src emacs-lisp\n(defun rewrite-ends (pre post new-pre new-post)\n  \"Perform the following in-buffer rewrite: ⟨pre⟩⋯⟨post⟩ ↦ ⟨newPre⟩⋯⟨newPost⟩.\n  For example, for rewriting begin-end code blocks from Org-mode to something\n  else, say a language's default literate mode.\n\n  The search for the string ⟨pre⟩⋯⟨post⟩ is non-greedy, i.e. will find\n  (in order) the minimal strings matching ⟨pre⟩⋯⟨post⟩.\n\n  We insist that the ends occur at the start of a newline; otherwise no\n  rewrite is made. Note the “^” regexp marker below.\n\n  In the arguments, only symbol `\\` needs to be escaped.\"\n  (let ((rx-pre  (concat \"\\\\(^\" (regexp-quote pre)  \"\\\\)\"))\n        (rx-post (concat \"\\\\(^\" (regexp-quote post) \"\\\\)\"))\n        ;; Code to match any characters (including newlines)\n        ;; based on https://www.emacswiki.org/emacs/MultilineRegexp\n        ;; This version requires we end in a newline,\n        ;; and uses the “non-greedy” * operator, *?, so we will match the minimal string.\n        (body \"\\\\(.*\\n\\\\)*?\"))\n    (goto-char (point-min))\n    (while (re-search-forward (concat rx-pre body rx-post) nil t) ;; nil to search whole buffer, t to not error\n      ;; Matched string 1 is the pre, matched string 3 is the post.\n      ;; Optionals: fixed-case, literal, use buffer, substring\n      (replace-match new-pre  t t nil 1)\n      (replace-match new-post t t nil 3))))\n#+end_src\n\nThe two rewriting utilities:\n#+begin_src emacs-lisp\n(defun lagda-to-org ()\n  \"Transform literate Agda blocks into Org-mode source blocks.\n   Use haskell as the Org source block language since I do not have nice colouring otherwise.\"\n  (interactive)\n  (let ((here-line (line-number-at-pos)) ;; remember current line\n        (here-column (current-column))\n        (enable-local-variables :safe))\n    (rewrite-ends \"\\\\begin{code}\"          \"\\\\end{code}\"\n                  \"#+BEGIN_SRC agda\"       \"#+END_SRC\")\n    (rewrite-ends \"\\\\begin{spec}\"          \"\\\\end{spec}\"\n                  \"#+BEGIN_EXAMPLE agda\"   \"#+END_EXAMPLE\")\n    (org-mode)\n    (org-goto-line here-line) ;; defined above\n    (move-to-column here-column))\n  (message \"Welcome to Org-mode, %s!\" user-full-name))\n\n(defun org-to-lagda ()\n  \"Transform Org-mode source blocks into literate Agda blocks.\n   Use haskell as the Org source block language since I do not have nice colouring otherwise.\"\n  (interactive)\n  (let ((here-line (line-number-at-pos)) ;; remember current line\n        (here-column (current-column))  ;; and current column\n        (enable-local-variables :safe))\n\n    (rewrite-ends \"#+BEGIN_SRC agda\"       \"#+END_SRC\"\n                  \"\\\\begin{code}\"          \"\\\\end{code}\")\n    (rewrite-ends \"#+BEGIN_EXAMPLE agda\"   \"#+END_EXAMPLE\"\n                  \"\\\\begin{spec}\"          \"\\\\end{spec}\")\n    (agda2-mode)\n    (sit-for 0.1) ;; necessary for the slight delay between the agda2 commands\n    (agda2-load)\n    (goto-line here-line)\n    (move-to-column here-column))\n  (message \"Welcome to Agda-mode, %s!\" user-full-name))\n#+end_src\n\n*Notice!* The toggling utilities automatically enable all /safe/ local variables\nin an file ---c.f., the ~(enable-local-variables :all)~ lines above.\nMany of our files tend to have local variables and that is the reason\nwe allow us.\n\nHandy-dandy shortcuts, which are alternated on mode change:\n#+begin_src emacs-lisp\n(add-hook 'org-mode-hook\n          (lambda () (local-set-key (kbd \"C-x C-a\") 'org-to-lagda)))\n\n(add-hook 'agda2-mode-hook\n          (lambda ()\n            (local-set-key (kbd \"C-x C-a\") 'lagda-to-org)\n            (local-set-key (kbd \"C-c C-v C-d\")\n                           (lambda (prefix)\n                             (interactive \"P\") ;; Places value of universal argument into: current-prefix-arg\n                             (insert (if (identity current-prefix-arg)\n                                         \"\\n\\\\begin{spec}\\n\\n\\\\end{spec}\"\n                                       \"\\n\\\\begin{code}\\n\\n\\\\end{code}\"))\n                             (forward-line -1)))))\n#+end_src\n\nOrg-mode, by default, lets us create a source block using ~C-c C-v C-d~, so we bring\nthis incantation to Agda-mode as well as having ~C-u C-c C-v C-d~ produce a ~spec~-environment.\n\n** Summary\n\nWe now have the utility functions:\n\n| _Command_ | _Action_                                                      |\n| ~C-x C-a~ | transform org ~org-agda~ blocks to literate Agda blocs        |\n| ~C-x C-a~ | transform literate Agda code delimiters to org ~org-agda~ src |\n\nThis was fun: I learned a lot of elisp!\nHopefully I can make use of this, in the small, if not in the large\n--in which case I'll need to return to the many ~COMMENT~-ed out sections\nin this document.\n\n** Installation\n1. Add the following to the top of your Emacs configuration file, i.e., the =/.emacs= file.\n   #+begin_src emacs-lisp\n   (progn\n\n   (require 'package)\n   (push '(\"melpa-stable\" . \"http://stable.melpa.org/packages/\") package-archives)\n   (package-initialize)\n   (package-refresh-contents)\n\n   ;; Obtain \u0026 setup installation interface.\n   (unless (package-installed-p 'use-package)\n     (package-install 'use-package))\n   (require 'use-package)\n   (setq use-package-always-ensure t)\n\n   ;; Necessary libraries for producing the system.\n   (use-package s)                  ;; “The long lost Emacs string manipulation library”.\n   (use-package dash)               ;; “A modern list library for Emacs”.\n\n   ;; Next, obtain the Elisp file, load it, and attach it to Agda.\n   ;; (shell-command \"cp ~/org-agda-mode/literate.el ~/.emacs.d/literate.el\")\n   (unless (file-exists-p \"~/.emacs.d/literate.el\")\n     (shell-command (concat \"curl \"\n       \"https://raw.githubusercontent.com/alhassy/org-agda-mode/master/literate.el\"\n       \"\u003e\u003e ~/.emacs.d/literate.el\")))\n   (load-file \"~/.emacs.d/literate.el\")\n   ;; (add-hook 'agda2-mode-hook (lambda () (load-file \"~/.emacs.d/literate.el\")))\n\n   ;; Uncomment out the last line above if you want support for literate org-agda blocks\n   ;; to ALWAYS be active on .lagda files.\n\n   ;; You likely have this in your ~/.emacs file already\n   (load-file (let ((coding-system-for-read 'utf-8))\n                   (shell-command-to-string \"/usr/local/bin/agda-mode locate\")))\n\n   ) ;; ends the progn at the top.\n   #+end_src\n\n2. Make a new ~test.lagda~ file.\n   #+begin_src org\n   # -*- org -*-\n   #\n   # (load-file \"~/.emacs.d/literate.el\")\n\n   Here's some sample fragments, whose editing can be turned on with ~C-x C-a~.\n\n   ,* Example src\n\n   Press C-c C-v C-d to make src code blocks.\n\n   hello\n   \\begin{code}\n   module test where\n\n   hole : Set₁\n   hole = {!!}\n   \\end{code}\n   there\n\n   ,* Example spec\n\n   A literate Agda ~spec~-ification environment, which corresponds to an Org-mode ~EXAMPLE~ block.\n\n   my\n   \\begin{spec}\n   e : τ\n   \\end{spec}\n   friends\n\n   In Agda mode, press C-u C-c C-v C-d to make spec blocks.\n   #+end_src\n\n3. Load the ~literate.el~ file.\n\n4. Now ~C-x C-a~ to switch to Agda mode and load the module.\n\n** Sources Consulted\n\n- [[http://www.ergoemacs.org/emacs/elisp_syntax_coloring.html][How to Write a Emacs Major Mode for Syntax Coloring]]\n- [[https://stackoverflow.com/questions/3887372/simplest-emacs-syntax-highlighting-tutorial][Simplest Emacs Syntax Highlighting Tutorial]]\n- [[https://stackoverflow.com/questions/1063115/a-hello-world-example-for-a-major-mode-in-emacs][“Hello World” for Emacs' Major Mode Creation]]\n- [[http://www.wilfred.me.uk/blog/2015/03/19/adding-a-new-language-to-emacs/][Adding A New Language to Emacs]]\n- [[https://nullprogram.com/blog/2013/02/06/][How to Make an Emacs Minor Mode]]\n- [[https://www.offerzen.com/blog/literate-programming-empower-your-writing-with-emacs-org-mode][Literate Programming: Empower Your Writing with Emacs Org-Mode]]\n  - An elegant overview of literate programming, with Org-mode, and the capabilities it offers.\n- [[http://howardism.org/Technical/Emacs/literate-programming-tutorial.html][Introduction to Literate Programming]]\n  - A nearly /comprehensive/ workshop on the fundamentals of literate programming with Org-mode.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falhassy%2Forg-agda-mode","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falhassy%2Forg-agda-mode","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falhassy%2Forg-agda-mode/lists"}