[[https://melpa.org/#/merlin-eldoc][file:https://melpa.org/packages/merlin-eldoc-badge.svg]]
This package provides a merlin backend for eldoc. Its goal is to automatically (without using keybindings) provide information for the value under point in OCaml and ReasonML files. It also provides hints when calling a function. This information is obtained from merlin.
Please see the [[file:CHANGES.org][changelog]] for recent improvements and list of changes between versions.
Features
display type
display documentation
highlight occurrences
jump to other occurrences
provide the list of expected arguments (and their types) when calling a function
Installation
** use-package
Add this code to ~init.el~
(use-package merlin-eldoc :ensure t :hook ((reason-mode tuareg-mode caml-mode) . merlin-eldoc-setup))
** Quelpa
With quelpa already installed and configured:
(quelpa '(merlin-eldoc :fetcher github :repo "Khady/merlin-eldoc")) ;; Add a hook to start the mode automatically for OCaml and Reason (add-hook 'tuareg-mode-hook 'merlin-eldoc-setup) (add-hook 'reason-mode-hook 'merlin-eldoc-setup)
** The more manual way
First the package has to be installed:
~M-x package-install RET merlin-eldoc RET~
Then this code should be added to ~init.el~
(require 'merlin-eldoc) (add-hook 'tuareg-mode-hook 'merlin-eldoc-setup) (add-hook 'reason-mode-hook 'merlin-eldoc-setup)
If a hook has been configured, then there is nothing to do. The eldoc mode should be launched automatically when an OCaml file is visited. And merlin will provide type information when available.
Otherwise, it can be launched by executing ~M-x merlin-eldoc-setup~.
Once this is done, as soon as the point is on a word which is not a keyword, a type should be displayed in the echo area when the cursor doesn't move for some time.
It is possible to configure the shape of the results using both eldoc and merlin-eldoc configurations. It allows to choose on how many lines the result will fit, if the documentation can be truncated, how to concatenate type and documentation...
For eldoc, the value to configure is ~eldoc-echo-area-use-multiline-p~.
For merlin-eldoc, the easiest way it so use the customize interface to get access to all the possible values and the corresponding documentation.
M-x merlin-eldoc-customize RET
The main values are:
If highlighting of occurrences is enabled, two functions are povided to jump to the previous or next occurrence of value under the point:
They can be binded to keys for more convenient usage.
** use-package
(use-package merlin-eldoc :after merlin :ensure t :custom (eldoc-echo-area-use-multiline-p t) ; use multiple lines when necessary (merlin-eldoc-max-lines 8) ; but not more than 8 (merlin-eldoc-type-verbosity 'min) ; don't display verbose types (merlin-eldoc-function-arguments nil) ; don't show function arguments (merlin-eldoc-doc nil) ; don't show the documentation :bind (:map merlin-mode-map ("C-c m p" . merlin-eldoc-jump-to-prev-occurrence) ("C-c m n" . merlin-eldoc-jump-to-next-occurrence)) :hook ((tuareg-mode reason-mode) . merlin-eldoc-setup))
** Quelpa
(quelpa '(merlin-eldoc :repo "Khady/merlin-eldoc" :fetcher github))
;; use multiple lines when necessary (setq eldoc-echo-area-use-multiline-p t)
;; but not more than 10 (setq merlin-eldoc-max-lines 10)
;; don't dedicate a line to the documentation (setq merlin-eldoc-max-lines-doc 'fit)
;; start merlin-eldoc when editing ocaml and reason files (add-hook 'tuareg-mode-hook #'merlin-eldoc-setup) (add-hook 'reason-mode-hook #'merlin-eldoc-setup)
In the following examples, the cursor is at ~<-!->~. After the requisite idle time, eldoc will fire and show the corresponding information in the minibuffer.
Type of a function
let my<-!->add ~f ~i = f +. (float i)
The information in the minibuffer will be:
f:float -> i:int -> float
Type and documentation of a function
(* [myadd f i] add f and i ) let my<-!->add ~f ~i = f +. (float i)
With type and doc enabled, it shows:
f:float -> i:int -> float ( [myadd f i] add f and i )
Type and documentation of ~List.map~ limited to one line
List.map<-!->
The exact result will depend on the width of the Emacs frame.
('a -> 'b) -> 'a list -> 'b list ( [List.map f [a1; ...; an]] applies function [f] to [a1, ..., an], and builds... )
Type and documentation of ~List.map~ on multiple lines
List.map<-!->
If at least 4 lines are allowed:
( [List.map f [a1; ...; an]] applies function [f] to [a1, ..., an], and builds the list [[f a1; ...; f an]] with the results returned by [f]. Not tail-recursive. ) ('a -> 'b) -> 'a list -> 'b list
Function application and argument types
let apply ~f ~i op = op @@ f +. (float i)
let v = apply <-!->
( expected type: ) float -> 'a ( labels: ) ~f:float -> ~i:int
Depending on the value of ~merlin-eldoc-max-lines-function-arguments~ it can also be displayed on one line.
( expected type: ) float -> 'a ( labels: ) ~f:float -> ~i:int
Function application and argument types, with some arguments already given
let apply ~f ~i op = op @@ f +. (float i)
let v = apply ~i:3 <-!->
( expected type: ) float -> 'a ( labels: ) ~f:float
Type expected by a label
let apply ~f ~i op = op @@ f +. (float i)
let v = apply ~i:<-!->
( expected type: ) int
Two videos are played bellow for a more visual demonstration.
Video showing the following features provided by this package:
All those operations are automatically called by ~eldoc~ when the cursor is idle for 0.5s.
[[https://d.khady.info/merlin-eldoc-long.ogv][file:full-demo.gif]]
Short video of demonstration with only type and documentation enabled:
[[https://d.khady.info/merlin-eldoc.ogv][file:demo.gif]]
Note that merlin is never called explicitly in this video. The only action is to move the pointer from one place to another.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.