I am coding Ocaml under Emacs...
I would like to know if there is a shortcut to jump to the definition of a function (where the cursor is). At the moment, to do so I have to search the name of the function in the whole file, or look for let the_name_of_the_function
and let rec the_name_of_the_function
and and the_name_of_the_function
which is obviously tedious...
By the way, I have alreay the file .annot
.
Could anyone help? Thank you!
My ctags(1)
(from the exuberant-ctags
package) supports the OCaml language and Emacs supports ctags
when it is executed as etags
.
So try: cd /path/to/Ocaml/sources/ && etags -R .
to build an index, and then within emacs
, M-.ret to search for the tag under the cursor.
The problem could be solved with merlin (https://github.com/the-lambda-church/merlin). Merlin can be installed easily with opam:
opam install merlin
Follow the instructions provided by opam to configure ~/.emacs file. To finish the configuration you will have to provide a .merlin file that tells merlin where the source files and build files are located and which packages are used in the project. A brief overview of the .merlin file is given in https://github.com/the-lambda-church/merlin/wiki/emacs-from-scratch#configuring-your-project
Now, to jump to the function definition in Emacs:
C-c C-l
To move back to the function call:
C-c &
While you are waiting for a better solution (of which there are some, see for example OCamlSpotter) you can use the poor-man commands listed below. Assumes tuareg-mode.
(defun camldev-identifier-at-point ()
(interactive)
(save-excursion
(goto-char (1+ (point)))
(let* ((beg (re-search-backward "[^A-Za-z0-9_'][A-Za-z0-9_'`]"))
(beg (1+ beg)))
(goto-char (1+ beg))
(let* ((end (re-search-forward "[^A-Za-z0-9_']"))
(end (1- end)))
(buffer-substring beg end)))))
(defun camldev-goto-def ()
"Search for definition of word around point."
(interactive)
(let (goal (word (camldev-identifier-at-point)))
(save-excursion
(re-search-backward (concat "\\(let \\([^=]*[^A-Za-z0-9_']\\|\\)"
word "\\([^A-Za-z0-9_'][^=]*\\|\\)=\\|"
"fun \\([^-]*[^A-Za-z0-9_']\\|\\)"
word "\\([^A-Za-z0-9_'][^-]*\\|\\)->\\|"
"and \\([^=]*[^A-Za-z0-9_']\\|\\)"
word "\\([^A-Za-z0-9_'][^=]*\\|\\)=\\)"
))
(re-search-forward (concat "[^A-Za-z0-9_']" word "[^A-Za-z0-9_']"))
(setq goal (1+ (match-beginning 0))))
(push-mark)
(goto-char goal)
))
(defun camldev-goto-spec ()
"Search for specification in mli/ml file of word around point in ml/mli file."
(interactive)
(let* (goal
(word (camldev-identifier-at-point))
(search-expr (concat "\\(val [^:\n]*"
word "[^:]*:\\|"
"let [^=\n]*"
word "[^=]*=\\|"
"type [^=\n]*"
word "[^=]*=\\)"
)))
(tuareg-find-alternate-file)
(save-excursion
(goto-char (point-min))
(re-search-forward search-expr)
(setq goal (match-beginning 0)))
(push-mark)
(goto-char goal)
))
(define-key tuareg-mode-map (kbd "C-c C-d") 'camldev-goto-def)
(define-key tuareg-mode-map (kbd "C-c C-S-d") 'camldev-goto-spec)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With