From 4dd3568a67be123c14a5db716331b334612d40ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulysse=20G=C3=A9rard?= Date: Fri, 2 Jul 2021 10:26:18 +0200 Subject: [PATCH 1/4] Add Emacs support for `merlin-locte-type` Co-authored-by: Leo White --- emacs/merlin.el | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/emacs/merlin.el b/emacs/merlin.el index 050990dc66..f71f3ab0bf 100644 --- a/emacs/merlin.el +++ b/emacs/merlin.el @@ -1512,6 +1512,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) From 276ec3123d7722f55f4e4d84d02e1eb691bca403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulysse=20G=C3=A9rard?= Date: Fri, 2 Jul 2021 10:32:32 +0200 Subject: [PATCH 2/4] Add vim support for `merlin-locate-type` --- vim/merlin/autoload/merlin.py | 75 ++++++++++++++++++++-------------- vim/merlin/autoload/merlin.vim | 6 ++- 2 files changed, 50 insertions(+), 31 deletions(-) diff --git a/vim/merlin/autoload/merlin.py b/vim/merlin/autoload/merlin.py index 17a5619ba2..dca0fd61be 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) @@ -444,6 +456,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 0af1d551f5..6591cd44f1 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' @@ -711,7 +715,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 From af2861d33906b710135a2b02f08127f555ce888f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulysse=20G=C3=A9rard?= Date: Fri, 2 Jul 2021 11:01:20 +0200 Subject: [PATCH 3/4] Add multi-files test for `merlin-locate-type` --- tests/test-dirs/locate-type.t/a.ml | 4 ++++ tests/test-dirs/locate-type.t/b.ml | 2 ++ tests/test-dirs/locate-type.t/run.t | 27 +++++++++++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 tests/test-dirs/locate-type.t/b.ml diff --git a/tests/test-dirs/locate-type.t/a.ml b/tests/test-dirs/locate-type.t/a.ml index d992ea5a3b..4136ae4bb7 100644 --- a/tests/test-dirs/locate-type.t/a.ml +++ b/tests/test-dirs/locate-type.t/a.ml @@ -5,3 +5,7 @@ end module Y = struct let y = T.X 1 end + +let z = Y.y + +let z2 = B.x diff --git a/tests/test-dirs/locate-type.t/b.ml b/tests/test-dirs/locate-type.t/b.ml new file mode 100644 index 0000000000..fd9d36c81b --- /dev/null +++ b/tests/test-dirs/locate-type.t/b.ml @@ -0,0 +1,2 @@ +type foo = string option +let x : foo = None diff --git a/tests/test-dirs/locate-type.t/run.t b/tests/test-dirs/locate-type.t/run.t index b501ec8254..f25f2f42db 100644 --- a/tests/test-dirs/locate-type.t/run.t +++ b/tests/test-dirs/locate-type.t/run.t @@ -1,3 +1,4 @@ + $ $OCAMLC b.ml -bin-annot -c $ $MERLIN single locate-type -position 6:6 -filename ./a.ml < ./a.ml { @@ -11,3 +12,29 @@ }, "notifications": [] } + + $ $MERLIN single locate-type -workdir . -position 9:11 -filename a.ml < ./a.ml + { + "class": "return", + "value": { + "file": "$TESTCASE_ROOT/a.ml", + "pos": { + "line": 2, + "col": 2 + } + }, + "notifications": [] + } + + $ $MERLIN single locate-type -position 11:12 -filename ./a.ml < ./a.ml + { + "class": "return", + "value": { + "file": "$TESTCASE_ROOT/b.ml", + "pos": { + "line": 1, + "col": 0 + } + }, + "notifications": [] + } From 980b53e5d6ec3711410bfdd2fd4f8bd2e785902b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulysse=20G=C3=A9rard?= Date: Fri, 2 Jul 2021 11:04:17 +0200 Subject: [PATCH 4/4] Add CHANGES entry --- CHANGES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index c5df94e1d3..64fdc922cd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,8 +21,11 @@ git version - vim: add a simple interface to the new `construct` command: `MerlinConstruct`. When several results are suggested, `` and `` to show more or less deep results. (#1318) + - vim: add support for the `merlin-locate-type` command: + `MerlinLocateType` (#1359) - emacs: add a simple interface to the new `construct` command: `merlin-construct`. (#1352) + - emacs: add support for the `merlin-locate-type` command. (#1359) + test suite - cover the new `construct` command (#1318)