Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Easy way to go to the definition of a function (Emacs, Ocaml)

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!

like image 605
SoftTimur Avatar asked Nov 14 '11 08:11

SoftTimur


3 Answers

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.

like image 177
sarnold Avatar answered Nov 09 '22 10:11

sarnold


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 &
like image 32
krips Avatar answered Nov 09 '22 11:11

krips


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)
like image 39
lukstafi Avatar answered Nov 09 '22 12:11

lukstafi