Add commands to switch to and from a utop buffer
Those are extremely common in Emacs modes and allow people to quickly jump to a REPL and back to the last source buffer they were editing, while using the same keybinding. I've modeled the implementation here after that of inf-clojure (a similar mode written by me). I've also implemented a mode menu for utop-minor-mode, so it's easier for the users to discover its functionality.
This commit is contained in:
parent
09d26a7509
commit
2a405226f2
|
@ -219,12 +219,13 @@ You can start utop inside Emacs with: `M-x utop`.
|
||||||
`utop.el` also ships with a minor mode that has the following key-bindings:
|
`utop.el` also ships with a minor mode that has the following key-bindings:
|
||||||
|
|
||||||
| key-binding | function | Description |
|
| key-binding | function | Description |
|
||||||
|-------------|-------------------|------------------------------|
|
|-------------|---------------------|------------------------------|
|
||||||
| C-c C-s | utop | Start a utop buffer |
|
| C-c C-s | utop | Start a utop buffer |
|
||||||
| C-x C-e | utop-eval-phrase | Evaluate the current phrase |
|
| C-x C-e | utop-eval-phrase | Evaluate the current phrase |
|
||||||
| C-x C-r | utop-eval-region | Evaluate the selected region |
|
| 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-b | utop-eval-buffer | Evaluate the current buffer |
|
||||||
| C-c C-k | utop-kill | Kill a running utop process |
|
| C-c C-k | utop-kill | Kill a running utop process |
|
||||||
|
| C-c C-z | utop-switch-to-repl | Switch to utop process |
|
||||||
|
|
||||||
You can enable the minor mode using `M-x utop-minor-mode`, or you can
|
You can enable the minor mode using `M-x utop-minor-mode`, or you can
|
||||||
have it enabled by default with the following configuration:
|
have it enabled by default with the following configuration:
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
(require 'easymenu)
|
(require 'easymenu)
|
||||||
(require 'pcase)
|
(require 'pcase)
|
||||||
|
(require 'seq)
|
||||||
(require 'tabulated-list)
|
(require 'tabulated-list)
|
||||||
(require 'tuareg)
|
(require 'tuareg)
|
||||||
|
|
||||||
|
@ -885,6 +886,32 @@ If ADD-TO-HISTORY is t then the input will be added to history."
|
||||||
(goto-char utop-prompt-max)
|
(goto-char utop-prompt-max)
|
||||||
(move-beginning-of-line 1))))
|
(move-beginning-of-line 1))))
|
||||||
|
|
||||||
|
;; +-----------------------------------------------------------------+
|
||||||
|
;; | Switch to REPL |
|
||||||
|
;; +-----------------------------------------------------------------+
|
||||||
|
|
||||||
|
(defun utop-switch-to-repl (eob-p)
|
||||||
|
"Switch to the inferior utop process buffer.
|
||||||
|
With prefix argument EOB-P, positions cursor at end of buffer."
|
||||||
|
(interactive "P")
|
||||||
|
(if (get-buffer-process utop-buffer-name)
|
||||||
|
(pop-to-buffer utop-buffer-name)
|
||||||
|
(call-interactively #'utop))
|
||||||
|
(when eob-p
|
||||||
|
(push-mark)
|
||||||
|
(goto-char (point-max))))
|
||||||
|
|
||||||
|
(defun utop-switch-to-recent-buffer ()
|
||||||
|
"Switch to the most recently used `utop-minor-mode' buffer."
|
||||||
|
(interactive)
|
||||||
|
(let ((recent-utop-minor-mode-buffer (seq-find (lambda (buf)
|
||||||
|
(with-current-buffer buf (bound-and-true-p utop-minor-mode)))
|
||||||
|
(buffer-list))))
|
||||||
|
(if recent-utop-minor-mode-buffer
|
||||||
|
(pop-to-buffer recent-utop-minor-mode-buffer)
|
||||||
|
(message "utop: No recent OCaml buffer found."))))
|
||||||
|
|
||||||
|
|
||||||
;; +-----------------------------------------------------------------+
|
;; +-----------------------------------------------------------------+
|
||||||
;; | Process control |
|
;; | Process control |
|
||||||
;; +-----------------------------------------------------------------+
|
;; +-----------------------------------------------------------------+
|
||||||
|
@ -1100,6 +1127,25 @@ See https://github.com/ocaml-community/utop for configuration information."))
|
||||||
(define-key map (kbd "C-x C-r") #'utop-eval-region)
|
(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-b") #'utop-eval-buffer)
|
||||||
(define-key map (kbd "C-c C-k") #'utop-kill)
|
(define-key map (kbd "C-c C-k") #'utop-kill)
|
||||||
|
(define-key map (kbd "C-c C-z") #'utop-switch-to-repl)
|
||||||
|
(easy-menu-define
|
||||||
|
utop-minor-mode-menu map
|
||||||
|
"utop menu."
|
||||||
|
'("utop"
|
||||||
|
["Start utop" utop t]
|
||||||
|
["Switch to utop" utop-switch-to-repl t]
|
||||||
|
["Interrupt utop" utop-interrupt :active (utop-is-running)]
|
||||||
|
["Kill utop" utop-kill :active (utop-is-running)]
|
||||||
|
["Exit utop gracefully" utop-exit :active (utop-is-running)]
|
||||||
|
"---"
|
||||||
|
["Evaluate phrase" utop-eval-phrase :active (and (utop-is-running) (eq utop-state 'edit))]
|
||||||
|
["Evaluate region" utop-eval-region :active (and (utop-is-running) (eq utop-state 'edit))]
|
||||||
|
["Evaluate buffer" utop-eval-buffer :active (and (utop-is-running) (eq utop-state 'edit))]
|
||||||
|
"---"
|
||||||
|
["Customize utop" (customize-group 'utop) t]
|
||||||
|
"---"
|
||||||
|
["About" utop-about t]
|
||||||
|
["Help" utop-help t]))
|
||||||
map)
|
map)
|
||||||
;; Load local file variables
|
;; Load local file variables
|
||||||
(add-hook 'hack-local-variables-hook 'utop-hack-local-variables))
|
(add-hook 'hack-local-variables-hook 'utop-hack-local-variables))
|
||||||
|
@ -1128,11 +1174,13 @@ See https://github.com/ocaml-community/utop for configuration information."))
|
||||||
utop-menu utop-mode-map
|
utop-menu utop-mode-map
|
||||||
"utop menu."
|
"utop menu."
|
||||||
'("utop"
|
'("utop"
|
||||||
["Start OCaml" utop t]
|
["Start utop" utop t]
|
||||||
["Interrupt OCaml" utop-interrupt :active (utop-is-running)]
|
["Interrupt utop" utop-interrupt :active (utop-is-running)]
|
||||||
["Kill OCaml" utop-kill :active (utop-is-running)]
|
["Kill utop" utop-kill :active (utop-is-running)]
|
||||||
["Exit utop gracefully" utop-exit :active (utop-is-running)]
|
["Exit utop gracefully" utop-exit :active (utop-is-running)]
|
||||||
|
"---"
|
||||||
["Evaluate Phrase" utop-eval-input-auto-end :active (and (utop-is-running) (eq utop-state 'edit))]
|
["Evaluate Phrase" utop-eval-input-auto-end :active (and (utop-is-running) (eq utop-state 'edit))]
|
||||||
|
["Switch to OCaml source buffer" utop-switch-to-recent-buffer t]
|
||||||
"---"
|
"---"
|
||||||
["Customize utop" (customize-group 'utop) t]
|
["Customize utop" (customize-group 'utop) t]
|
||||||
"---"
|
"---"
|
||||||
|
|
Loading…
Reference in New Issue