6

In the command-line mode or in a vimscript I can use the following to duplicate a line:

normal! Yp

Now let's says that I map my leader key to do that: nnoremap <Leader>a Yp. If I use this key combination the following command will interpret litterally the characters or <leader>:

normal! <Leader>a

How can I use a key combination including <leader> in a normal command?

Note that other keys like <Right> or <F3> doesn't work neither.

Edit Some side notes:

  • Using normal or normal! doesn't seem to change something to the problem
  • The point of the question is to be able to use <Leader> and not replace it by its value for two 2 reasons:
    • It is more portable if I use it in a script and want to distribute it.
    • My leader is <Space> so even if I replace <Leader> by its value I still have the same problem. (Note that I could maybe escape a space character but that is not the point of the question)
4
  • 1
    Since you want your map to be used, you will need normal instead of normal!. My leader is \​, and I can use normal \a to execute the mapping, but I don't know how to keep it generic wrt leader. May 13, 2016 at 8:13
  • @PhilippFrank: Thanks for your comment, please see my update: Replacing <leader> by its value is not really what I'm looking for.
    – statox
    May 13, 2016 at 8:20
  • Do you mind using and external command/function for this?
    – nobe4
    May 13, 2016 at 8:20
  • @Nobe4: I'd like a solution as straightforward as possible but if it is the only solution that will be ok :-)
    – statox
    May 13, 2016 at 8:27

1 Answer 1

7

I made up a solution to extract the leader, handle the special <space> case and execute the normal command.

The space is a special case, because the normal command does not accept expressions starting with a space:

:h normal

{commands} cannot start with a space.  Put a count of
1 (one) before it, "1 " is one space.

Here is the function and command:

function! ExecuteLeader(suffix)
  let l:leader = get(g:,"mapleader","\\")

  if l:leader == ' '
    let l:leader = '1' . l:leader
  endif

  execute "normal ".l:leader.a:suffix
endfunction

command! -nargs=1 NormLead call ExecuteLeader(<f-args>)

You can use it this way:

:NormLead a
-> will execute `normal <leader>a`

(Thanks @statox for the update): If you want a one-liner command, without function, you can use the following:

command! -nargs=1 NormLead  let leader=get(g:,"mapleader","\\") | exec "normal " . (leader==' '?"1":leader).<f-args>

This is just for the leader key, but if you want to extend to any kind of key I think you need to use execute anyway.

In the normal help:

An alternative is to use :execute, which uses a
expression as argument.  This allows the use of
printable characters to represent special characters.

Example:
    :exe "normal \<c-w>\<c-w>"
{not in Vi, of course}
2
  • 1
    Thanks for your solution! I made it a one-liner to avoid the use of the function: command! -nargs=1 NormLead execute "normal " . (get(g:,"mapleader","\\")==' ' ? "1" : get(g:,"mapleader","\\")) . <f-args>: it is still not perfect (doesn't work with special keys or with combinations beginning with 2 leaders) but that's something
    – statox
    May 13, 2016 at 9:19
  • 1
    Nice, I'll add this to the answer
    – nobe4
    May 13, 2016 at 9:20

Your Answer

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

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