Source

js-elisp / js-ocaml.el

Full commit
;; This file helps emacs work with OCaml.  It should be loaded by all
;; Jane Street ocaml developers because it defines certain
;; company-wide coding standards.


;; File loading

;; Used by everyone
(require 'compile)
(require 'tuareg)
(progn
  ;; We used to do (require 'ocamlspot), but that will load bytecode-compiled files if
  ;; they exist.  That caused problems on some platforms.  So, to force loading the source
  ;; files and not bytecode-compiled, we explcitly do (load-library "ocamlspot.el").
  (load-library "ocamlspot.el")
  (custom-set-variables
   ;; This is a wrapper script for ocamlspot that greps the OMakeroot to determine the
   ;; correct ocamlspot executable to use.
   '(ocamlspot-command "/mnt/global/base/bin/ocamlspot"))
  ;; 2012-02-27 sweeks: emacs-ocamlspot stopped working for people because emacs was
  ;; passing a full path name to ocamlspot, whereas ocamlspot was expecting a basename.
  ;; The full path is unnecessary because emacs alread cd's to the correct directory.  So,
  ;; I tweaked ocamlspot-query-string-at-cursor to strip the directory.
  (defun ocamlspot-query-string-at-cursor ()
    (format "%s:l%dc%d"
            (file-name-nondirectory (buffer-file-name))
            (ocamlspot-lines-of-point)
            (ocamlspot-bytes-of-line-to-point))))
(require 'caml-types)

;; Some people may use these, but don't load by default.

(autoload 'camldebug "camldebug" "Run the Caml debugger" t)
(autoload 'caml-help "caml-help" "Find documentation for OCaml qualified identifiers." t)
(autoload 'caml-cmigrep-complete "cmigrep" nil t)
(autoload 'caml-cmigrep-complete-module "cmigrep" nil t)


;; Variables

;; The syntax entry for _ is difficult to control in tuareg-mode.  Setting
;; it is ineffective, as it keeps getting set back for some mysterious reason.
;; Copy the syntax table and set the syntax of _ once and for all

;; Syntax table for navigation
(defvar js-tuareg-navigation-syntax-table
  (copy-syntax-table tuareg-mode-syntax-table))
;; . needs punctuation syntax for dabbrev expansion to work
(modify-syntax-entry ?. "." js-tuareg-navigation-syntax-table)
(modify-syntax-entry ?_ "w" js-tuareg-navigation-syntax-table)

;; Syntax table for indentation
(defvar js-tuareg-indent-syntax-table
  (copy-syntax-table tuareg-mode-syntax-table))
(modify-syntax-entry ?_ "w" js-tuareg-indent-syntax-table)

;; CR cfalls: Make these properly named (Jane.<foo>) and documented micro-features.

(defun Js.underscore-is-word ()
  (interactive)
  (modify-syntax-entry ?_ "w" js-tuareg-navigation-syntax-table))

(defun Js.underscore-is-punctuation ()
  (interactive)
  (modify-syntax-entry ?_ "." js-tuareg-navigation-syntax-table))

(defun Js.tuareg-indent-line-with-syntax (&optional from-leading-star)
  (interactive)
  (with-syntax-table js-tuareg-indent-syntax-table
    (tuareg-indent-command from-leading-star)))

;; Jane Street coding conventions
(custom-set-variables
 '(comment-style 'multi-line) ; for better comment-region
 '(require-final-newline t) ; every file has a newline at the end
 '(indent-tabs-mode nil) ; indent via spaces, not tabs
 '(tuareg-in-indent 0)
 '(tuareg-with-indent 0)
 '(tuareg-type-indent 0)
 '(tuareg-leading-star-in-doc t)
 '(tuareg-display-buffer-on-eval nil))

(defvar jane-make-command "jomake -j 12 -P -w")

(defun jane-tuareg-mode-hook ()
  (auto-fill-mode 1)
  (setq fill-column 90)
  (set-syntax-table js-tuareg-navigation-syntax-table)
  (setq whitespace-line-column 90)
  (set (make-local-variable 'compile-command) jane-make-command)
  (setq whitespace-style '(lines-tail tabs tab-mark trailing))
  (add-hook 'before-save-hook 'whitespace-cleanup)
  (setq indent-line-function 'Js.tuareg-indent-line-with-syntax)
  (let ((mycaml (expand-file-name "mycaml" default-directory)))
    (when (file-exists-p mycaml)
      (set (make-local-variable 'tuareg-interactive-program) mycaml))))

(add-hook 'tuareg-mode-hook 'jane-tuareg-mode-hook)
;; (setq tuareg-mode-hook nil)


;; Keybindings

(defun jane-tuareg-load-hook ()
  (define-key tuareg-mode-map "\C-c;" 'ocamlspot-query)
  (define-key tuareg-mode-map "\C-ct" 'ocamlspot-type)
  (define-key tuareg-mode-map "\C-cu" 'ocamlspot-use)
  (define-key tuareg-mode-map "\C-c\C-b" 'tuareg-eval-region)
  (define-key tuareg-mode-map "\C-c\C-i" 'caml-cmigrep-complete)
  (define-key tuareg-mode-map "\C-c\C-m" 'caml-cmigrep-complete-module)
  (define-key tuareg-mode-map "\C-c\C-t" 'ocamlspot-type)
  (define-key tuareg-mode-map "\C-c\C-y" 'ocamlspot-type-and-copy)
  (define-key tuareg-mode-map "\C-cc" 'comment-dwim)
  (define-key tuareg-mode-map "\C-ch" 'caml-help)
  )

(add-hook 'tuareg-mode-hook 'jane-tuareg-load-hook)
;;(setq tuareg-mode-hook nil)


(provide 'js-ocaml)

;; Support for pa_ounit

(defconst tuareg-pa_ounit-keywords
  (concat "\\<" (regexp-opt '("TEST" "TEST_UNIT" "TEST_MODULE" "TEST_FAIL") t) "\\>")
  "Regexp for keywords used for new definitions with pa_ounit")

(font-lock-add-keywords
 'tuareg-mode
 `((,tuareg-pa_ounit-keywords . tuareg-font-lock-governing-face)))

(eval-after-load "tuareg"
  '(setq tuareg-governing-phrase-regexp
         (concat tuareg-governing-phrase-regexp
                 "\\|"
                 tuareg-pa_ounit-keywords)))

(provide 'pa_ounit-tuareg)