Merge pull request #124 from mads379/refactor-major-mode-use
Refactor major mode use
This commit is contained in:
commit
0d606f6dae
34
README.md
34
README.md
|
@ -135,21 +135,35 @@ you can copy-paste this code into you `~/.emacs` file:
|
|||
|
||||
Then you can execute utop inside emacs with: `M-x utop`.
|
||||
|
||||
Integration with the tuareg/typerex mode
|
||||
----------------------------------------
|
||||
utop also ships with a minor mode that has the following key-bindings
|
||||
|
||||
You can replace the default toplevel used by the tuareg or typerex
|
||||
mode by utop, for that add the following lines to your `~/.emacs` file:
|
||||
| key-binding | function | Description |
|
||||
|-------------|-------------------|------------------------------|
|
||||
| C-c C-s | utop | Start a utop buffer |
|
||||
| C-x C-e | utop-eval-phrase | Evaluate the current phrase |
|
||||
| C-x C-r | utop-eval-region | Evaluate the selected region |
|
||||
| C-c C-b | utop-eval-buffer | Evaluate the current buffer |
|
||||
| C-c C-k | utop-kill | Kill a running utop process |
|
||||
|
||||
You can enable the minor mode using `M-x utop-minor-mode`, or you can
|
||||
have it enabled by default with the following configuration
|
||||
|
||||
```scheme
|
||||
(autoload 'utop-setup-ocaml-buffer "utop" "Toplevel for OCaml" t)
|
||||
(add-hook 'tuareg-mode-hook 'utop-setup-ocaml-buffer)
|
||||
(add-hook 'typerex-mode-hook 'utop-setup-ocaml-buffer)
|
||||
(autoload 'utop-minor-mode "utop" "Minor mode for utop" t)
|
||||
(add-hook 'tuareg-mode-hook 'utop-minor-mode)
|
||||
```
|
||||
|
||||
You can also complete text in a tuareg or typerex buffer using the
|
||||
environment of the toplevel. For that bind the function
|
||||
`utop-edit-complete` to the key you want.
|
||||
If you plan to use utop with another major-mode than tuareg,
|
||||
e.g. typerex, then you will need the following configuration instead
|
||||
|
||||
```scheme
|
||||
(autoload 'utop-minor-mode "utop" "Minor mode for utop" t)
|
||||
(add-hook 'typerex-mode-hook 'utop-minor-mode)
|
||||
```
|
||||
|
||||
You can also complete text in a buffer using the environment of the
|
||||
toplevel. For that bind the function `utop-edit-complete` to the key
|
||||
you want.
|
||||
|
||||
Common error
|
||||
------------
|
||||
|
|
167
src/top/utop.el
167
src/top/utop.el
|
@ -207,16 +207,63 @@ before the end of prompt.")
|
|||
"The position of the cursor in the phrase sent to OCaml (where
|
||||
to add the newline character if it is not accepted).")
|
||||
|
||||
(defvar utop-package-list nil
|
||||
"List of packages to load when visiting OCaml buffer.
|
||||
Useful as file variable.")
|
||||
(make-variable-buffer-local
|
||||
(defvar utop-package-list nil
|
||||
"List of packages to load when visiting OCaml buffer.
|
||||
Useful as file variable."))
|
||||
|
||||
(defvar utop-ocaml-preprocessor nil
|
||||
"Name of preprocesor. Currently supported camlp4o, camlp4r.
|
||||
Useful as file variable.")
|
||||
(make-variable-buffer-local
|
||||
(defvar utop-ocaml-preprocessor nil
|
||||
"Name of preprocesor. Currently supported camlp4o, camlp4r.
|
||||
Useful as file variable."))
|
||||
|
||||
(defvar utop-skip-blank-and-comments 'compat-skip-blank-and-comments
|
||||
"The function used to skip blanks and comments.")
|
||||
|
||||
(defvar utop-skip-to-end-of-phrase 'compat-skip-to-end-of-phrase
|
||||
"The function used to find the end of a phrase")
|
||||
|
||||
(defvar utop-discover-phrase 'compat-discover-phrase
|
||||
"The function used to discover a phrase")
|
||||
|
||||
(defvar utop-skip-after-eval-phrase t
|
||||
"Whether to skip to next phrase after evaluation.
|
||||
|
||||
Non-nil means skip to the end of the phrase after evaluation in the
|
||||
Caml toplevel")
|
||||
|
||||
;; +-----------------------------------------------------------------+
|
||||
;; | Compability |
|
||||
;; | Compability with different ocaml major modes |
|
||||
;; +-----------------------------------------------------------------+
|
||||
|
||||
(defun utop-compat-resolve (symbol)
|
||||
"Resolve a symbol based on the current major mode."
|
||||
(cond
|
||||
((eq major-mode 'tuareg-mode)
|
||||
(intern (concat "tuareg-" symbol)))
|
||||
((eq major-mode 'typerex-mode)
|
||||
(intern (concat "typerex-" symbol)))
|
||||
((eq major-mode 'caml-mode)
|
||||
(intern (concat "caml-" symbol)))
|
||||
((require 'tuareg nil t)
|
||||
(intern (concat "tuareg-" symbol)))
|
||||
((require 'typerex nil t)
|
||||
(intern (concat "typerex-" symbol)))
|
||||
((require 'caml nil t)
|
||||
(intern (concat "caml-" symbol)))
|
||||
(error (concat "unsupported mode: " (symbol-name major-mode) ", utop support only caml, tuareg and typerex modes"))))
|
||||
|
||||
(defun compat-skip-blank-and-comments ()
|
||||
(funcall (utop-compat-resolve "skip-blank-and-comments")))
|
||||
|
||||
(defun compat-skip-to-end-of-phrase ()
|
||||
(funcall (utop-compat-resolve "skip-to-end-of-phrase")))
|
||||
|
||||
(defun compat-discover-phrase ()
|
||||
(funcall (utop-compat-resolve "discover-phrase")))
|
||||
|
||||
;; +-----------------------------------------------------------------+
|
||||
;; | Compability with previous emacs version |
|
||||
;; +-----------------------------------------------------------------+
|
||||
|
||||
(unless (featurep 'tabulated-list)
|
||||
|
@ -740,36 +787,9 @@ If ADD-TO-HISTORY is t then the input will be added to history."
|
|||
(buffer-substring-no-properties utop-prompt-max (point)))))
|
||||
|
||||
;; +-----------------------------------------------------------------+
|
||||
;; | Caml/Tuareg/Typerex integration |
|
||||
;; | Eval |
|
||||
;; +-----------------------------------------------------------------+
|
||||
|
||||
(defun utop-choose (symbol)
|
||||
"Be best at resolving caml, tuareg or typerex dependencies even
|
||||
when byte-compiling."
|
||||
(cond
|
||||
((eq major-mode 'tuareg-mode)
|
||||
(intern (concat "tuareg-" symbol)))
|
||||
((eq major-mode 'typerex-mode)
|
||||
(intern (concat "typerex-" symbol)))
|
||||
((eq major-mode 'caml-mode)
|
||||
(intern (concat "caml-" symbol)))
|
||||
((require 'tuareg nil t)
|
||||
(intern (concat "tuareg-" symbol)))
|
||||
((require 'typerex nil t)
|
||||
(intern (concat "typerex-" symbol)))
|
||||
((require 'caml nil t)
|
||||
(intern (concat "caml-" symbol)))
|
||||
(error (concat "unsupported mode: " (symbol-name major-mode) ", utop support only caml, tuareg and typerex modes"))))
|
||||
|
||||
(defmacro utop-choose-symbol (symbol)
|
||||
(utop-choose symbol))
|
||||
|
||||
(defmacro utop-choose-call (symbol &rest args)
|
||||
`(,(utop-choose symbol) ,@args))
|
||||
|
||||
(defmacro utop-choose-defun (symbol &rest args)
|
||||
`(defun ,(utop-choose symbol) ,@args))
|
||||
|
||||
(defun utop-prepare-for-eval ()
|
||||
"Prepare utop for evaluation."
|
||||
(save-excursion
|
||||
|
@ -814,18 +834,15 @@ when byte-compiling."
|
|||
|
||||
(defun utop-eval (start end &optional mode)
|
||||
"Eval the given region in utop."
|
||||
;; From tuareg
|
||||
(unless (eq major-mode 'caml-mode)
|
||||
(set (utop-choose "interactive-last-phrase-pos-in-source") start))
|
||||
;; Select the text of the region
|
||||
(let ((text
|
||||
(save-excursion
|
||||
;; Search the start and end of the current paragraph
|
||||
(goto-char start)
|
||||
(utop-choose-call "skip-blank-and-comments")
|
||||
(funcall utop-skip-blank-and-comments)
|
||||
(setq start (point))
|
||||
(goto-char end)
|
||||
(utop-choose-call "skip-to-end-of-phrase")
|
||||
(funcall utop-skip-to-end-of-phrase)
|
||||
(setq end (point))
|
||||
(buffer-substring-no-properties start end))))
|
||||
(utop-eval-string text mode)))
|
||||
|
@ -842,11 +859,11 @@ when byte-compiling."
|
|||
(utop-prepare-for-eval)
|
||||
(let ((end))
|
||||
(save-excursion
|
||||
(let ((pair (utop-choose-call "discover-phrase")))
|
||||
(setq end (nth 2 pair))
|
||||
(utop-eval (nth 0 pair) (nth 1 pair))))
|
||||
(if (utop-choose-symbol "skip-after-eval-phrase")
|
||||
(goto-char end))))
|
||||
(let ((pair (funcall utop-discover-phrase)))
|
||||
(setq end (nth 2 pair))
|
||||
(utop-eval (nth 0 pair) (nth 1 pair))))
|
||||
(if utop-skip-after-eval-phrase
|
||||
(goto-char end))))
|
||||
|
||||
(defun utop-eval-buffer ()
|
||||
"Send the buffer to utop."
|
||||
|
@ -860,7 +877,7 @@ when byte-compiling."
|
|||
;; Find the start of the current phrase
|
||||
(save-excursion
|
||||
(let* ((end (point))
|
||||
(start (nth 0 (utop-choose-call "discover-phrase")))
|
||||
(start (nth 0 (funcall utop-discover-phrase)))
|
||||
(input (buffer-substring-no-properties start end))
|
||||
(edit-buffer (current-buffer)))
|
||||
;; Start utop if needed
|
||||
|
@ -881,42 +898,6 @@ when byte-compiling."
|
|||
;; Send the phrase to complete
|
||||
(utop-complete-input input)))))))
|
||||
|
||||
(defun utop-setup-ocaml-buffer ()
|
||||
"Override caml/tuareg/typerex interactive functions by utop ones.
|
||||
|
||||
You can call this function after loading the caml/tuareg/typerex
|
||||
mode to let it use utop instead of its builtin support for
|
||||
interactive toplevel.
|
||||
|
||||
To automatically do that just add these lines to your .emacs:
|
||||
|
||||
(autoload 'utop-setup-ocaml-buffer \"utop\" \"Toplevel for OCaml\" t)
|
||||
(add-hook 'caml-mode-hook 'utop-setup-ocaml-buffer)
|
||||
(add-hook 'tuareg-mode-hook 'utop-setup-ocaml-buffer)
|
||||
(add-hook 'typerex-mode-hook 'utop-setup-ocaml-buffer)"
|
||||
(interactive)
|
||||
;; Redefine caml/tuareg/typerex functions
|
||||
(utop-choose-defun "eval-phrase" () (interactive) (utop-eval-phrase))
|
||||
(utop-choose-defun "eval-region" (start end) (interactive "r") (utop-eval-region start end))
|
||||
(utop-choose-defun "eval-buffer" () (interactive) (utop-eval-buffer))
|
||||
(utop-choose-defun "interrupt-caml" () (interactive) (utop-interrupt))
|
||||
(utop-choose-defun "kill-caml" () (interactive) (utop-kill))
|
||||
(utop-choose-defun "run-caml" () (interactive) (utop))
|
||||
|
||||
;; Redefine this variable so menu will work
|
||||
(set (utop-choose "interactive-buffer-name") utop-buffer-name)
|
||||
|
||||
;; Package list for this file
|
||||
(make-local-variable 'utop-package-list)
|
||||
|
||||
;; Preprocessor to use
|
||||
(make-local-variable 'utop-ocaml-preprocessor)
|
||||
|
||||
;; Load local file variables
|
||||
(add-hook 'hack-local-variables-hook 'utop-hack-local-variables)
|
||||
|
||||
nil)
|
||||
|
||||
;; +-----------------------------------------------------------------+
|
||||
;; | Edition functions |
|
||||
;; +-----------------------------------------------------------------+
|
||||
|
@ -998,7 +979,7 @@ defaults to 0."
|
|||
(define-derived-mode utop-list-packages-mode tabulated-list-mode "OCaml package list"
|
||||
"Major mode for listing the findlib OCaml packages."
|
||||
(setq tabulated-list-format [("Name" 32 t)
|
||||
("Version" 32 t)])
|
||||
("Version" 32 t)])
|
||||
(setq tabulated-list-sort-key (cons "Name" nil))
|
||||
(setq tabulated-list-printer 'utop-package-printer)
|
||||
(add-hook 'tabulated-list-revert-hook 'utop-list-packages--refresh nil t)
|
||||
|
@ -1164,6 +1145,25 @@ defaults to 0."
|
|||
(utop-insert "\nRestarting...\n\n")
|
||||
(utop-start arguments)))
|
||||
|
||||
(defun utop-setup-ocaml-buffer ()
|
||||
"Deprecated"
|
||||
(error "This function is deprecated. See https://github.com/diml/utop for configuration information."))
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode utop-minor-mode
|
||||
"Minor mode for utop."
|
||||
:lighter " utop"
|
||||
:keymap (let ((map (make-sparse-keymap)))
|
||||
(define-key map (kbd "C-c C-s") 'utop)
|
||||
(define-key map (kbd "C-x C-e") 'utop-eval-phrase)
|
||||
(define-key map (kbd "C-x C-r") 'utop-eval-region)
|
||||
(define-key map (kbd "C-c C-b") 'utop-eval-buffer)
|
||||
(define-key map (kbd "C-c C-k") 'utop-kill)
|
||||
map)
|
||||
;; Load local file variables
|
||||
(add-hook 'hack-local-variables-hook 'utop-hack-local-variables))
|
||||
|
||||
;;;###autoload
|
||||
(define-derived-mode utop-mode fundamental-mode "utop"
|
||||
"Set the buffer mode to utop."
|
||||
|
||||
|
@ -1239,6 +1239,7 @@ Special keys for utop:
|
|||
(with-current-buffer buf (utop-mode)))))
|
||||
buf))
|
||||
|
||||
(provide 'utop-minor-mode)
|
||||
(provide 'utop)
|
||||
|
||||
;;; utop.el ends here
|
||||
|
|
Loading…
Reference in New Issue