From 52c6605a029fb8c1c7f909ce05353fcd91c01016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulysse=20G=C3=A9rard?= Date: Tue, 20 Jul 2021 17:12:42 +0200 Subject: [PATCH] Merge pull request #1364 from ocaml/locate-state-reset [locate] reset state from entry points Tests adapted to >4.08 <4.11 --- CHANGES.md | 5 +++ emacs/merlin.el | 11 +++++ vim/merlin/autoload/merlin.py | 75 ++++++++++++++++++++-------------- vim/merlin/autoload/merlin.vim | 6 ++- 4 files changed, 66 insertions(+), 31 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 1cac42a13b..df32a987dd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,11 @@ git version + merlin binary - fix -cmt-path dirs mistakenly added to build path (#1330) + + editor modes + to show more or less deep results. (#1318) + - vim: add support for the `merlin-locate-type` command: + `MerlinLocateType` (#1359) + - emacs: add support for the `merlin-locate-type` command. (#1359) merlin 3.5.0 ============ diff --git a/emacs/merlin.el b/emacs/merlin.el index 07021915cd..9935aa3079 100644 --- a/emacs/merlin.el +++ b/emacs/merlin.el @@ -1396,6 +1396,17 @@ loading" (interactive) (merlin--locate-result (merlin-call-locate))) +(defun merlin-locate-type () + "Locate the type of the expression under point." + (interactive) + (let ((result (merlin/call "locate-type" + "-position" (merlin/unmake-point (point))))) + (unless result + (error "Not found. (Check *Messages* for potential errors)")) + (unless (listp result) + (error "%S" result)) + (merlin--goto-file-and-point result))) + (defun merlin-pop-stack () "Go back to the last position where the user did a locate." (interactive) diff --git a/vim/merlin/autoload/merlin.py b/vim/merlin/autoload/merlin.py index 4dd31884fd..9bff993977 100644 --- a/vim/merlin/autoload/merlin.py +++ b/vim/merlin/autoload/merlin.py @@ -250,6 +250,38 @@ def differs_from_current_file(path): def vim_fnameescape(s): return vim.eval("fnameescape('%s')" % s.replace("'","''")) +def goto_file_and_point(pos_or_err): + if not isinstance(pos_or_err, dict): + print(pos_or_err) + else: + l = pos_or_err['pos']['line'] + c = pos_or_err['pos']['col'] + split_method = vim.eval('g:merlin_split_method') + # save the current position in the jump list + vim.command("normal! m'") + if "file" in pos_or_err and differs_from_current_file(pos_or_err['file']): + fname = vim_fnameescape(pos_or_err['file']) + if split_method == "never": + vim.command(":keepjumps e %s" % fname) + elif "tab" in split_method: + if "always" in split_method: + vim.command(":keepjumps tab split %s" % fname) + else: + vim.command(":keepjumps tab drop %s" % fname) + elif "vertical" in split_method: + vim.command(":keepjumps vsplit %s" % fname) + else: + vim.command(":keepjumps split %s" % fname) + elif "always" in split_method: + if "tab" in split_method: + vim.command(":tab split") + elif "vertical" in split_method: + vim.command(":vsplit") + else: + vim.command(":split") + # TODO: move the cursor using vimscript, so we can :keepjumps? + vim.current.window.cursor = (l, c) + def command_locate(path, pos): try: choice = vim.eval('g:merlin_locate_preference') @@ -260,36 +292,16 @@ def command_locate(path, pos): pos_or_err = command("locate", "-look-for", choice, "-position", fmtpos(pos)) else: pos_or_err = command("locate", "-prefix", path, "-look-for", choice, "-position", fmtpos(pos)) - if not isinstance(pos_or_err, dict): - print(pos_or_err) - else: - l = pos_or_err['pos']['line'] - c = pos_or_err['pos']['col'] - split_method = vim.eval('g:merlin_split_method') - # save the current position in the jump list - vim.command("normal! m'") - if "file" in pos_or_err and differs_from_current_file(pos_or_err['file']): - fname = vim_fnameescape(pos_or_err['file']) - if split_method == "never": - vim.command(":keepjumps e %s" % fname) - elif "tab" in split_method: - if "always" in split_method: - vim.command(":keepjumps tab split %s" % fname) - else: - vim.command(":keepjumps tab drop %s" % fname) - elif "vertical" in split_method: - vim.command(":keepjumps vsplit %s" % fname) - else: - vim.command(":keepjumps split %s" % fname) - elif "always" in split_method: - if "tab" in split_method: - vim.command(":tab split") - elif "vertical" in split_method: - vim.command(":vsplit") - else: - vim.command(":split") - # TODO: move the cursor using vimscript, so we can :keepjumps? - vim.current.window.cursor = (l, c) + goto_file_and_point(pos_or_err) + except MerlinExc as e: + try_print_error(e) + + +def command_locate_type(pos): + try: + pos_or_err = command("locate-type", "-position", fmtpos(pos)) + goto_file_and_point(pos_or_err) + except MerlinExc as e: try_print_error(e) @@ -434,6 +446,9 @@ def vim_locate_at_cursor(path): def vim_locate_under_cursor(): vim_locate_at_cursor(None) +def vim_locate_type_at_cursor(): + command_locate_type(vim.current.window.cursor) + # Jump and Phrase motion def vim_jump_to(target): command_motion("jump", target, vim.current.window.cursor) diff --git a/vim/merlin/autoload/merlin.vim b/vim/merlin/autoload/merlin.vim index 524f122958..c9aacc6e12 100644 --- a/vim/merlin/autoload/merlin.vim +++ b/vim/merlin/autoload/merlin.vim @@ -393,6 +393,10 @@ function! merlin#Locate(...) endif endfunction +function! merlin#LocateType() + MerlinPy merlin.vim_locate_type_at_cursor() +endfunction + function! merlin#LocateImpl(...) let l:pref = g:merlin_locate_preference let g:merlin_locate_preference = 'implementation' @@ -596,7 +600,7 @@ function! merlin#Register() command! -buffer -complete=customlist,merlin#ExpandPrefix -nargs=? MerlinLocateImpl call merlin#LocateImpl() command! -buffer -complete=customlist,merlin#ExpandPrefix -nargs=? MerlinLocateIntf call merlin#LocateIntf() command! -buffer -nargs=0 MerlinILocate call merlin#InteractiveLocate() - + command! -buffer -nargs=0 MerlinLocateType call merlin#LocateType() if !exists('g:merlin_disable_default_keybindings') || !g:merlin_disable_default_keybindings nmap gd :MerlinLocate