Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/alhassy/org-agda-mode
An Emacs mode for working with Agda code in an Org-mode like fashion, more or less.
https://github.com/alhassy/org-agda-mode
agda emacs literate-programming minor-mode org-mode
Last synced: 3 months ago
JSON representation
An Emacs mode for working with Agda code in an Org-mode like fashion, more or less.
- Host: GitHub
- URL: https://github.com/alhassy/org-agda-mode
- Owner: alhassy
- Created: 2018-10-30T02:39:33.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2021-11-08T10:39:58.000Z (over 3 years ago)
- Last Synced: 2024-10-11T21:51:25.411Z (4 months ago)
- Topics: agda, emacs, literate-programming, minor-mode, org-mode
- Language: Emacs Lisp
- Size: 85.9 KB
- Stars: 17
- Watchers: 5
- Forks: 7
- Open Issues: 1
-
Metadata Files:
- Readme: README.org
Awesome Lists containing this project
README
# Created 2019-10-03 Thu 11:13
#+OPTIONS: toc:nil d:nil
#+OPTIONS: html-postamble:nil
#+TITLE: Better Org-mode support for Literate Agda
#+DATE: 2018-11-03
#+AUTHOR: Musa Al-hassy & Mark Armstrong
#+DESCRIPTION: Major mode for working with literate Org Agda files
#+export_file_name: README.org
#+Property: header-args :tangle org-agda-mode.el* Introduction
# This paragraph is copied below in [[Package header]]
# Note the DESCRIPTION is also echoed there.
An Emacs major mode for editing Agda code embedded in Org files
(~.lagda.org~ files.)
See the
[[https://agda.readthedocs.io/en/v2.6.1/tools/literate-programming.html#literate-org][Agda manual]]
for more information.An older version of this support is documented in a
[[https://alhassy.github.io/literate/][blog post]].
The current version is a complete departure, motivated by
- the support in recent Agda versions (> 2.6) for literate files with
~.lagda.org~ extensions, and
- the ability to work in multiple Emacs modes at once via the Polymode package.* Package header :noexport:
#+begin_src emacs-lisp
;;; org-agda-mode.el --- Major mode for working with literate Org Agda files
;;; -*- lexical-binding: t;;; Commentary:
;; A Major mode for editing Agda code embedded in Org files (.lagda.org files.)
;; See the Agda manual for more information:
;; https://agda.readthedocs.io/en/v2.6.1/tools/literate-programming.html#literate-org;;; Code:
#+end_src* Installation
Simply place ~org-agda-mode.el~ in your Emacs load path,
and add
#+begin_src emacs-lisp
(require 'org-agda-mode)
#+end_src
to your Emacs initialisation file.Alternatively, if you use straight.el and use-package, then this package can be installed by adding the following to your emacs configuration.
#+BEGIN_SRC emacs-lisp
(use-package polymode)
(use-package org-agda-mode
:straight (:host github
:repo "alhassy/org-agda-mode"
:branch "master"
:files ("org-agda-mode.el")
)
)
#+END_SRC* Background
** Polymode
Polymode allows us to use more than one major mode in a buffer,
something usually impossible in Emacs.
Note there do exist several other solutions for this, such as MMM;
Polymode seemed the best candidate for what I want during my
(admittedly rather brief) search for solutions.[[https://polymode.github.io/][Read the docs]]!
* Prerequisite packages
#+begin_src emacs-lisp
(require 'polymode)
(require 'agda2-mode)
#+end_src* Customisations
#+begin_src emacs-lisp
(defgroup org-agda-mode nil
"org-agda-mode customisations"
:group 'languages)
#+end_srcNaturally, users will often want to use Agda input mode
to enter unicode characters in their literate documentation.
Do note that it's also possible to enable this input mode
globally in your Emacs init.
#+begin_src emacs-lisp
(defcustom use-agda-input t
"Whether to use Agda input mode in non-Agda parts of the file."
:group 'org-agda-mode
:type 'boolean)
#+end_src* Org-Agda mode definition
Org is our hostmode.
#+begin_src emacs-lisp
(define-hostmode poly-org-agda-hostmode
:mode 'org-mode
:keep-in-mode 'host)
#+end_srcAgda is our inner mode, delimited by Org source blocks.
#+begin_src emacs-lisp
(define-innermode poly-org-agda-innermode
:mode 'agda2-mode
:head-matcher "#\\+begin_src agda2"
:tail-matcher "#\\+end_src"
;; Keep the code block wrappers in Org mode, so they can be folded, etc.
:head-mode 'org-mode
:tail-mode 'org-mode
;; Disable font-lock-mode, which interferes with Agda annotations,
;; and undo the change to indent-line-function Polymode makes.
:init-functions '((lambda (_) (font-lock-mode 0))
(lambda (_) (setq indent-line-function #'indent-relative))))
#+end_src
:TODO: rather than ~indent-relative~, we should probably use the user's default.Now we define the polymode using the above host and inner modes.
#+begin_src emacs-lisp
(define-polymode org-agda-mode
:hostmode 'poly-org-agda-hostmode
:innermodes '(poly-org-agda-innermode)
(when use-agda-input (set-input-method "Agda")))
#+end_src* Prevent Agda from applying annotations to the literate Org portion
Agda's highlighting mode makes use of ~annotate~ to apply syntax highlighting
throughout the buffer, including the literate portion,
which ~agda2-highlight~ identifies as “background”.
Older versions of Agda would highlight the background using
~font-lock-comment-face~ (so, making them the same colour as comments).
Newer versions (since
[[https://github.com/agda/agda/commit/8bee8727fff1a87c708c28b02edc38931c91f1fb#diff-4b761ced0541ba9fd4efbe58fd37ba7f][this]]
commit) simply apply Emacs' default face.Since we're using Org mode for the literate portion,
we don't want Agda to apply any annotation there.
We can achieve this by simply removing the setting for background
from the Agda highlight faces attribute list.
#+begin_src emacs-lisp
(assq-delete-all 'background agda2-highlight-faces)
#+end_src:TODO: This is not a full fix for the syntax highlighting issues.
There is a greater conflict between ~annotate~ and ~font-lock~
that we need to fix.* Automatically use ~org-agda-mode~ for ~.lagda.org~ files
Finally, add our new mode to the auto mode list.
#+begin_src emacs-lisp
;;;###autoload
(add-to-list 'auto-mode-alist '("\\.lagda.org" . org-agda-mode))
#+end_src* Package footer
#+begin_src emacs-lisp
(provide 'org-agda-mode)
;;; org-agda-mode ends here
#+end_src* TODO Improvements
- Enable Agda loading, and more generally all the agda keybindings,
anywhere in .lagda.org files.
- At least the important ones that don't obviously clash with Org bindings.
- I've tried loading via ~M-x agda2-load~ from the Org portion,
and it works (yay!), but it loses the Agda syntax highlighting?
- To enable monolith ~.lagda.org~ files
(large literate files which tangle several individual clean source files),
we need a way to strip one level of indentation after tangling.
- Actually it's not /needed/; Agda does allow the contents
of the toplevel module (so, the remainder of the file)
to be indented; but it breaks /convention/.** Documentation
- Discover the exact version of Agda that added support for
interactive programming in ~.lagda.org~ files.* COMMENT The original ~org-agda-mode~
Github recognizes ~.org~ files;
Agda colouring is determined by typechecking,
so Github will not provide certain colours.-----
# toc: headlines 2
# description: An Org-mode utility for Agda.
# description: An Emacs mode for working with Agda code in an Org-mode like fashion, more or less.
# startup: indent
# categories: Agda Org Emacs
# image: ../assets/img/org_logo.png
# source: https://raw.githubusercontent.com/alhassy/org-agda-mode/master/literate.lagda# property: header-args :tangle no
#+begin_center
*Abstract*
#+end_center[[https://en.wikipedia.org/wiki/Literate_programming][Literate Programming]] is essentially the idea that code is enclosed in documentation
rather than the comments being surrounded by code. The idea is that software
ought to be written like an essay to be read by a human; from this, code for the
machine can then be extracted.The articles on this blog are meant to be in such a format and as such
I 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.This article aims to produce an Org-friendly approach to working
with the [[http://wiki.portal.chalmers.se/agda/pmwiki.php][Agda language]], which is special in comparison to many other languages:
Coding is interactive via holes and it permits almost any sequence of characters
as a legal lexeme thereby rendering a static highlighting theme impossible.The result of this Elisp exploration is that by ~C-x C-a~
we can toggle into Agda-mode and use its interactive features to construct our program;
then return to an Org-mode literate programming style afterwards with
another ~C-x C-a~
---/both translations remember the position we're working at and allow the editing features of their respective modes!/
Moreover, we also allow user-defined colouring.Jump to [[#installation]] to quickly get and use the setup.
( Thanks to [[https://github.com/armkeh][Mark Armstrong]] for significant testing and contributions! )
#+begin_quote
- [[#abstract][Abstract]]
- [[#agda-now-supports-org-files----not-really][“Agda now supports org files” ---Not Really]]
- [[#agda-syntax-highlighting][Agda Syntax Highlighting]]
- [[#keywords][Keywords]]
- [[#the-generic-mode-definition][The ~generic-mode~ Definition]]
- [[#user-defined-colouring][User-defined Colouring]]
- [[#lagda-to-org-and-org-to-lagda][(~lagda-to-org~) and (~org-to-lagda~)]]
- [[#example-fragments][Example Fragments]]
- [[#summary][Summary]]
- [[#installation][Installation]]
- [[#sources-consulted][Sources Consulted]]
#+end_quote** “Agda now supports org files” ---Not Really
As of Agda 2.6.0 ---which came after this article was originally written---
there is now support for literate Org-mode support using ~agda2~ org-src blocks.The [[https://github.com/agda/agda/pull/3548][pull request]] was by one of my then students who found the use of this ‘org-agda’
setup to be sufficiently useful to be appreciated by the whole Agda community out-of-the-box.Unfortunately, currently working with a ~myfile.lagda.org~
comes with discouraging compromises between the Org- and Agda-modes. Namely:
1. Interactivity with Agda holes is /not/ supported.
2. The full editorial capabilities of Org-mode are limited since some
features clash with those of Agda-mode.The solution outlined here is not to limit nor compromise each role, but rather
provide both and instead allow the user, you, to control when you would like
to be /documenting vs. developing/ ---the resulting system is sufficiently fast
to toggle between the modes; e.g., the somewhat large categorical development
[[https://alhassy.github.io/PathCat/][Graphs are to categories as lists are to monoids]] is written literately using org-agda.Besides the core capability to switch between the different modes, we also provide
an elementary yet /extensible/ syntax colouring mechanism for Agda's non-standard highlighting.** Agda Syntax Highlighting
We produce a new mode, calling it ~ob-agda-mode~,
so that Org-mode blocks marked with ~ob-agda~ will have Agda /approximated/
syntax. By default, if an Emacs major-mode ~-mode~ exists,
then blocks marked with ~~ use that major-mode for editing.#+begin_src emacs-lisp
;; To use generic-mode later below.
(require 'generic-x)
#+end_srcThe “ob” is short for “org-babel” since we also wish to provide
Babel support for Agda. Using ~ob-agda~ marked blocks is awkward and exposes
some of our implementation, we will instead support an alias ~agda~ which refers to ~ob-agda~.We can use the ~org-src-lang-modes~ variable to map any ---possibly more friendly or suggestive--- identifier to a language major mode.
#+begin_src emacs-lisp
(add-to-list 'org-src-lang-modes '("agda" . ob-agda))
#+end_src*** Keywords
We look at the ~agda2-highlight.el~ source file from the Agda repository
for colours of keywords and reserved symbols such as ==, λ, ∀=, etc.#+begin_src emacs-lisp
(defface agda2-highlight-keyword-face
'((t (:foreground "DarkOrange3")))
"The face used for keywords."
:group 'font-lock-faces)(setq font-lock-keyword-face 'agda2-highlight-keyword-face)
(defface agda2-highlight-symbol-face
'((((background light)) (:foreground "gray25"))
(((background dark)) (:foreground "gray75")))
"The face used for symbols like forall, =, as, ->, etc."
:group 'font-lock-faces)
#+end_srcFrom 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:
#+begin_src emacs-lisp
(setq org-agda-keywords
'("=" "|" "->" "→" ":" "?" "\\" "λ" "∀" ".." "..." "abstract" "codata"
"coinductive" "constructor" "data" "do" "eta-equality" "field"
"forall" "hiding" "import" "in" "inductive" "infix" "infixl"
"infixr" "instance" "let" "macro" "module" "mutual" "no-eta-equality"
"open" "overlap" "pattern" "postulate" "primitive" "private" "public"
"quote" "quoteContext" "quoteGoal" "quoteTerm" "record" "renaming"
"rewrite" "Set" "syntax" "tactic" "unquote" "unquoteDecl" "unquoteDef"
"using" "where" "with"))
#+end_src*** The ~generic-mode~ Definition
Agda colouring is approximated as defined below, but a convention is made:
Function symbols begin with a lower case letter, whereas type symbols begin
with a capital letter. Otherwise, I would need to resort to Agda's mechanism
for determining whether a name is a type or not:
#+begin_center
/Parsing is Typechecking!/
#+end_center#+begin_src emacs-lisp
; (defvar org-agda-extra-word-colours nil
; "other words that user of org-mode wants coloured, along with their specified font-lock-type-face");; When exporting to .lagda files, I overwrite these to "".
(defvar ob-agda-comment-start "{-")
(defvar ob-agda-comment-end "{-")(define-generic-mode
'ob-agda-mode ;; name of the mode
(list (cons ob-agda-comment-start ob-agda-comment-end)) ;; comments delimiter
org-agda-keywords
;; font lock list: Order of colouring matters;
;; the numbers refer to the subpart, or the whole(0), that should be coloured.(-concat ;; ★★★ org-agda-extra-word-colours is a free variable, ★★★
;; ★★★ user should define it /before/ loading org-agda-mode ★★★
(if (boundp (quote org-agda-extra-word-colours)) org-agda-extra-word-colours nil)
(list;; To begin with, after "module" or after "import" should be purple
;; Note the SPACE below.
'("\\(module\\|import\\) \\([a-zA-Z0-9\-_\.]+\\)" 2 '((t (:foreground "purple"))));; Agda special symbols: as
'(" as" 0 'agda2-highlight-symbol-face);; Type, and constructor, names begin with a capital letter --personal convention.
;; They're preceded by either a space or an open delimiter character.
'("\\( \\|\s(\\)\\([A-Z]+\\)\\([a-zA-Z0-9\-_]*\\)" 0 'font-lock-type-face)
'("ℕ" 0 'font-lock-type-face);; variables & function names, as a personal convention, begin with a lower case
'("\\([a-z]+\\)\\([a-zA-Z0-9\-_]*\\)" 0 '((t (:foreground "medium blue"))));; colour numbers
'("\\([0-9]+\\)" 1 '((t (:foreground "purple"))));; other faces to consider:
;; 'font-lock-keyword-face 'font-lock-builtin-face 'font-lock-function-name-face
;; 'font-lock-variable-name-face 'font-lock-constant-face
));; files that trigger this mode
nil;; any other functions to call
nil;; doc string
"My custom Agda highlighting mode for use *within* Org-mode."
)
#+end_srcI do not insist that ~org-agda-mode~ be activated on any particular files by default.
Here is an example code block that obtains this colouring schema.
#+begin_src agda
module literate wheredata ℕ : Set where
Zero : ℕ
Succ : ℕ → ℕdouble : ℕ → ℕ
double Zero = Zero
double (Succ n) = Succ (Succ (double n)){- lengthy
multiline
comment -}{- No one line comment colouring … Yet -}
open import Data.Nat as Lib
camelCaseIdentifier-01 : Lib.ℕ
camelCaseIdentifier-01 = let it = 1234 in it
#+end_srcNext, we turn to supporting Agda interactivity with holes.
*** User-defined ColouringSince true Agda colouring requires type-checking, it is desirable to allow the user to
input colouring for their own identifiers. Such <<>> will be
via the delightful org-mode interface: A super simple intuitive table ♥‿♥#+begin_quote
For now, the user-defined Agda colouring mentioned here only serves for an enjoyable
literate programming experience. It currently is not picked up by the Org-mode LaTeX backend
nor the HTML backend.
#+end_quoteAnywhere in their buffer, the user should have a table with a column for identifiers
and the colours they should have, as follows.
#+begin_src org
,#+RESULTS: ob-agda/colours
| one | keyword |
| two | builtin |
| three | function-name |
| four | variable-name |
| five | constant |
#+end_srcWhich yields the following colouring,
#+begin_src agda
one = Set
two = Set
three = Set
four = Set
five = Set
#+end_srcWe implement this as follows. We produce a function that realises such colouring assignments:
#+begin_src emacs-lisp
(defun ob-agda/add-colour (word colour)
"Refresh the ob-agda-mode to have the new ‘colour’ for ‘word’ in agda blocks.+ ‘word’ is a string representing an Agda identifier.
+ ‘colour’ is either a symbol from ‘keyword’, ‘builtin’, ‘function-name’,
‘variable-name’, ‘constant’."
;; We only declare org-agda-extra-word-colours if the user needs it.
;; If we declare it in the file, as nil, then it will always be nil before
;; the ob-agda-mode is defined and so later changes to this variable will not take effect.
;;
(unless (boundp (quote org-agda-extra-word-colours)) (setq org-agda-extra-word-colours nil));; Discard existing colour-scheme.
(unload-feature 'ob-agda-mode);; Add new colour
(if (-contains? '(keyword builtin function-name variable-name constant) colour)
(add-to-list 'org-agda-extra-word-colours
`(,word 0 ,(intern (concat "font-lock-" (symbol-name colour) "-face"))))
(message-box "colour %s" colour)
(add-to-list 'org-agda-extra-word-colours
`(,word 0 ,colour)));; Load the new altered scheme.
(require 'ob-agda-mode "~/.emacs.d/literate.el"))
#+end_src
Then lookup that user provided table, if it is there, and use it.
#+begin_src emacs-lisp
(defun ob-agda/update-colours ()
"Searchs current buffer for an ob-agda/colours named result table
then uses that to update the colour scheme.
"
(interactive)
(ignore-errors
(save-excursion
(org-babel-goto-named-result "ob-agda/colours")
(forward-line)
;; (setq _it (org-table-to-lisp))
(dolist (elem (org-table-to-lisp) org-agda-extra-word-colours)
(ob-agda/add-colour (car elem) (intern (cadr elem)))))))
#+end_src** (~lagda-to-org~) and (~org-to-lagda~)
Previously, Agda would not typecheck a non-~lagda~, or non-~agda~, file therefore
I could not use Org-mode multiple mode settings.Recent versions of Agda will typecheck files with other extensions,
but as of 2.6.0, the interactive mode does not work on such files.I will instead merely
swap the syntax of the modes then reload the desired mode.
--it may not be ideal, but it does what I want in a fast enough fashion.In order to maintain position when switching back to Org-mode,
I define a function which not only goes to the appropriate line,
but unfolds the document to show that line.#+begin_src emacs-lisp
(defun org-goto-line (line)
"Go to the indicated line, unfolding the parent Org header.Implementation: Go to the line, then look at the 1st previous
org header, now we can unfold it whence we do so, then we go
back to the line we want to be at."
(goto-line line)
(org-back-to-heading 1)
(org-cycle)
(goto-line line))
#+end_srcBelow we put together a way to make rewrites ~⟨pre⟩⋯⟨post⟩ ↦ ⟨newPre⟩⋯⟨newPost⟩~
then use that with the rewrite tokens being ~#+BEGIN_SRC~ and ~╲begin{code}~ for
literate Agda, as well as their closing partners.#+begin_src emacs-lisp
(defun rewrite-ends (pre post new-pre new-post)
"Perform the following in-buffer rewrite: ⟨pre⟩⋯⟨post⟩ ↦ ⟨newPre⟩⋯⟨newPost⟩.
For example, for rewriting begin-end code blocks from Org-mode to something
else, say a language's default literate mode.The search for the string ⟨pre⟩⋯⟨post⟩ is non-greedy, i.e. will find
(in order) the minimal strings matching ⟨pre⟩⋯⟨post⟩.We insist that the ends occur at the start of a newline; otherwise no
rewrite is made. Note the “^” regexp marker below.In the arguments, only symbol `\` needs to be escaped."
(let ((rx-pre (concat "\\(^" (regexp-quote pre) "\\)"))
(rx-post (concat "\\(^" (regexp-quote post) "\\)"))
;; Code to match any characters (including newlines)
;; based on https://www.emacswiki.org/emacs/MultilineRegexp
;; This version requires we end in a newline,
;; and uses the “non-greedy” * operator, *?, so we will match the minimal string.
(body "\\(.*\n\\)*?"))
(goto-char (point-min))
(while (re-search-forward (concat rx-pre body rx-post) nil t) ;; nil to search whole buffer, t to not error
;; Matched string 1 is the pre, matched string 3 is the post.
;; Optionals: fixed-case, literal, use buffer, substring
(replace-match new-pre t t nil 1)
(replace-match new-post t t nil 3))))
#+end_srcThe two rewriting utilities:
#+begin_src emacs-lisp
(defun lagda-to-org ()
"Transform literate Agda blocks into Org-mode source blocks.
Use haskell as the Org source block language since I do not have nice colouring otherwise."
(interactive)
(let ((here-line (line-number-at-pos)) ;; remember current line
(here-column (current-column))
(enable-local-variables :safe))
(rewrite-ends "\\begin{code}" "\\end{code}"
"#+BEGIN_SRC agda" "#+END_SRC")
(rewrite-ends "\\begin{spec}" "\\end{spec}"
"#+BEGIN_EXAMPLE agda" "#+END_EXAMPLE")
(org-mode)
(org-goto-line here-line) ;; defined above
(move-to-column here-column))
(message "Welcome to Org-mode, %s!" user-full-name))(defun org-to-lagda ()
"Transform Org-mode source blocks into literate Agda blocks.
Use haskell as the Org source block language since I do not have nice colouring otherwise."
(interactive)
(let ((here-line (line-number-at-pos)) ;; remember current line
(here-column (current-column)) ;; and current column
(enable-local-variables :safe))(rewrite-ends "#+BEGIN_SRC agda" "#+END_SRC"
"\\begin{code}" "\\end{code}")
(rewrite-ends "#+BEGIN_EXAMPLE agda" "#+END_EXAMPLE"
"\\begin{spec}" "\\end{spec}")
(agda2-mode)
(sit-for 0.1) ;; necessary for the slight delay between the agda2 commands
(agda2-load)
(goto-line here-line)
(move-to-column here-column))
(message "Welcome to Agda-mode, %s!" user-full-name))
#+end_src*Notice!* The toggling utilities automatically enable all /safe/ local variables
in an file ---c.f., the ~(enable-local-variables :all)~ lines above.
Many of our files tend to have local variables and that is the reason
we allow us.Handy-dandy shortcuts, which are alternated on mode change:
#+begin_src emacs-lisp
(add-hook 'org-mode-hook
(lambda () (local-set-key (kbd "C-x C-a") 'org-to-lagda)))(add-hook 'agda2-mode-hook
(lambda ()
(local-set-key (kbd "C-x C-a") 'lagda-to-org)
(local-set-key (kbd "C-c C-v C-d")
(lambda (prefix)
(interactive "P") ;; Places value of universal argument into: current-prefix-arg
(insert (if (identity current-prefix-arg)
"\n\\begin{spec}\n\n\\end{spec}"
"\n\\begin{code}\n\n\\end{code}"))
(forward-line -1)))))
#+end_srcOrg-mode, by default, lets us create a source block using ~C-c C-v C-d~, so we bring
this incantation to Agda-mode as well as having ~C-u C-c C-v C-d~ produce a ~spec~-environment.** Summary
We now have the utility functions:
| _Command_ | _Action_ |
| ~C-x C-a~ | transform org ~org-agda~ blocks to literate Agda blocs |
| ~C-x C-a~ | transform literate Agda code delimiters to org ~org-agda~ src |This was fun: I learned a lot of elisp!
Hopefully I can make use of this, in the small, if not in the large
--in which case I'll need to return to the many ~COMMENT~-ed out sections
in this document.** Installation
1. Add the following to the top of your Emacs configuration file, i.e., the =/.emacs= file.
#+begin_src emacs-lisp
(progn(require 'package)
(push '("melpa-stable" . "http://stable.melpa.org/packages/") package-archives)
(package-initialize)
(package-refresh-contents);; Obtain & setup installation interface.
(unless (package-installed-p 'use-package)
(package-install 'use-package))
(require 'use-package)
(setq use-package-always-ensure t);; Necessary libraries for producing the system.
(use-package s) ;; “The long lost Emacs string manipulation library”.
(use-package dash) ;; “A modern list library for Emacs”.;; Next, obtain the Elisp file, load it, and attach it to Agda.
;; (shell-command "cp ~/org-agda-mode/literate.el ~/.emacs.d/literate.el")
(unless (file-exists-p "~/.emacs.d/literate.el")
(shell-command (concat "curl "
"https://raw.githubusercontent.com/alhassy/org-agda-mode/master/literate.el"
">> ~/.emacs.d/literate.el")))
(load-file "~/.emacs.d/literate.el")
;; (add-hook 'agda2-mode-hook (lambda () (load-file "~/.emacs.d/literate.el")));; Uncomment out the last line above if you want support for literate org-agda blocks
;; to ALWAYS be active on .lagda files.;; You likely have this in your ~/.emacs file already
(load-file (let ((coding-system-for-read 'utf-8))
(shell-command-to-string "/usr/local/bin/agda-mode locate")))) ;; ends the progn at the top.
#+end_src2. Make a new ~test.lagda~ file.
#+begin_src org
# -*- org -*-
#
# (load-file "~/.emacs.d/literate.el")Here's some sample fragments, whose editing can be turned on with ~C-x C-a~.
,* Example src
Press C-c C-v C-d to make src code blocks.
hello
\begin{code}
module test wherehole : Set₁
hole = {!!}
\end{code}
there,* Example spec
A literate Agda ~spec~-ification environment, which corresponds to an Org-mode ~EXAMPLE~ block.
my
\begin{spec}
e : τ
\end{spec}
friendsIn Agda mode, press C-u C-c C-v C-d to make spec blocks.
#+end_src3. Load the ~literate.el~ file.
4. Now ~C-x C-a~ to switch to Agda mode and load the module.
** Sources Consulted
- [[http://www.ergoemacs.org/emacs/elisp_syntax_coloring.html][How to Write a Emacs Major Mode for Syntax Coloring]]
- [[https://stackoverflow.com/questions/3887372/simplest-emacs-syntax-highlighting-tutorial][Simplest Emacs Syntax Highlighting Tutorial]]
- [[https://stackoverflow.com/questions/1063115/a-hello-world-example-for-a-major-mode-in-emacs][“Hello World” for Emacs' Major Mode Creation]]
- [[http://www.wilfred.me.uk/blog/2015/03/19/adding-a-new-language-to-emacs/][Adding A New Language to Emacs]]
- [[https://nullprogram.com/blog/2013/02/06/][How to Make an Emacs Minor Mode]]
- [[https://www.offerzen.com/blog/literate-programming-empower-your-writing-with-emacs-org-mode][Literate Programming: Empower Your Writing with Emacs Org-Mode]]
- An elegant overview of literate programming, with Org-mode, and the capabilities it offers.
- [[http://howardism.org/Technical/Emacs/literate-programming-tutorial.html][Introduction to Literate Programming]]
- A nearly /comprehensive/ workshop on the fundamentals of literate programming with Org-mode.