Home

Awesome

NOTE: THIS IS A MIRROR

Please submit issues, feature requests and PRs to https://gitlab.com/gopiandcode/gopcaml-mode

Gopcaml Ocaml Emacs Major Mode

The ultimate ocaml editing mode.

Features

ast-code-navigation

ast-code-transform

move-to-defun

jump-to-type-hole

automatic-let-bindings

mark-sexp

move-to-param

move-to-let-def

extract-expression

Installation

Gopcaml mode is implemented using a mixture of ocaml and elisp.

Make sure your emacs is compiled with dynamic modules support (you may need to build emacs from source with the --with-modules option).

Note: If you get an error about ELF headers this means that your emacs doesn't support dynamic modules - you'll need to build emacs from source (takes ~5 minutes usually).

opam install gopcaml-mode
 (let ((opam-share (ignore-errors (car (process-lines "opam" "config" "var" "share")))))
	   (when (and opam-share (file-directory-p opam-share))
	     ;; Register Gopcaml mode
	     (add-to-list 'load-path (expand-file-name "emacs/site-lisp" opam-share))
         (autoload 'gopcaml-mode "gopcaml-mode" nil t nil)
         (autoload 'tuareg-mode "tuareg" nil t nil)
         (autoload 'merlin-mode "merlin" "Merlin mode" t)
	     ;; Automatically start it in OCaml buffers
	     (setq auto-mode-alist
		   (append '(("\\.ml[ily]?$" . gopcaml-mode)
			     ("\\.topml$" . gopcaml-mode))
			   auto-mode-alist))
	     ))

Enjoy your ultimate editing experience.

Extras

Development

If you want to tinker with this project/extend it/build your own version, see below:

Project Structure

The core project laid out as follows:

├── gopcaml.ml
├── gopcaml_state.ml
├── ast_zipper.ml
├── ast_analysis.ml
├── ast_transformer.ml
├── gopcaml-mode.el
├── gopcaml-multiple-cursors.el
└── gopcaml-smartparens.el

The purpose of each file is defined as follows (in the order in which you'd probably want to look at them):

Architecture

Setting up the development environment

Being an emacs plugin, the development environment setup is tailored for emacs.

(add-to-list
	'command-switch-alist
	(cons "gopdev"  (lambda (__) nil)))
	
(if (member "-gopdev" command-line-args) (setq gopcaml-dev-mode t))

(if (or (not (boundp 'gopcaml-dev-mode)) (not gopcaml-dev-mode))
   ... ;; run normal gopcaml initialization code (i.e from the install instructions)
)

Note: My typical development setup is to have a command prompt open in the background and execute dune build && emacs -gopdev ./<some-file>.ml. I make some changes, use merlin to ensure there are no issues, exit and press up on my terminal to reload the prior command and press enter.

Note*: The reason for the complicated setup is that gopcaml-mode uses dynamic modules to call out to ocaml mode from emacs, and dynamic modules can only be loaded into an emacs instance once - thus each time you make a change, you'll need to restart emacs.