3

I use the following mapping to send code to a REPL using vim-slime and tmux:

nmap <buffer> <S-CR> <Plug>SlimeLineSend

How can I perform an action after I invoque this mapping?. For example, I would like to move down one line (j) after the <Plug>SlimeLineSend is executed. This does not work:

nmap <buffer> <S-CR> <Plug>SlimeLineSend j

3 Answers 3

4

This almost works for me:

nmap <buffer> <S-CR> <Plug>SlimeLineSendj

The reason it actually doesn't work is that my terminal Vim actually doesn't recognize the <S-CR> sequence as different from a simple <CR>, so whenever I press <S-CR> Vim just moves to the next line and doesn't really trigger the mapping... If I do the same using a different trigger, it works fine:

nmap <buffer> <LocalLeader>s <Plug>SlimeLineSendj

Whenever expanding a mapping, Vim will look for the longest sequence of characters that matches a mapping. In this case, this will be <Plug>SlimeLineSend, which will trigger the action. The j is still on the buffer, so Vim will use this command as a motion to go down one line.

(Many plug-ins create their <Plug> mappings with a set of parens around the "command" part, so that it's clear where it ends. Also, that allows them to create commands that are prefixes of other commands. For example, emmet.vim has <Plug>(emmet-toggle-comment), Command-T has <Plug>(CommandT), etc.)

1
  • 1
    Yes, this works! Hmm, I thought I tried your approach without success. Apparently I was doing something different. This is cleaner than my answer. Thanks.
    – mroavi
    Commented Aug 19, 2020 at 23:18
1

Another advantage to mroavi solution

There is another advantage to @mroavi solution.

If you do:

nmap <buffer> <LocalLeader>s <Plug>SlimeLineSendj

as @filbranden suggested, vim will insert the j at the first occasion.

If you use kitty, vim-slime will ask in the command prompt the listening socket, and will fill the answer with a default value. With this solution, vim will append j to that default value, which then you will have to cancel in order for vim-slime to correctly detect the socket and works

kitty listen on ($KITTY_LISTEN_ON): unix:/tmp/mykitty-12100j

Instead, with:

nmap <buffer> <S-CR> :execute "normal \<Plug>SlimeLineSend"<CR>j

as @mroavi suggested, the j is inserted after the command ended, that is, after vim-slime have sent the text over (so it will in effect go down one line).

LUA implementation of @mroavi answer

The LUA version requires escaping the double quotes and the backslash, leading to something like:

vim.api.nvim_set_keymap("n", "<Leader>s", ":execute \"normal \\<Plug>SlimeSendCell\"<CR>}j", {noremap = true})
0

I came up with a solution based on this answer: https://stackoverflow.com/a/18547013/1706778

nmap <buffer> <S-CR> :execute "normal \<Plug>SlimeLineSend"<CR>j
2
  • 3
    In that case, you don't nmap and nnoremap suffices
    – D. Ben Knoble
    Commented Aug 19, 2020 at 23:20
  • 1
    @Ben Yes! In fact this is one of the advantages of this approach. That you can use nnoremap in this case and the parts outside the <Plug> are never recursively expanded. If you use nnoremap here and you map j to go up, this mapping will still go down. But with the one I suggested, if you remap j, you'll get the remapped j behavior there...
    – filbranden
    Commented Aug 19, 2020 at 23:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.