5

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)
  • 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. – PhilippFrank May 13 '16 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 '16 at 8:20
  • Do you mind using and external command/function for this? – nobe4 May 13 '16 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 '16 at 8:27
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}
  • 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 '16 at 9:19
  • 1
    Nice, I'll add this to the answer – nobe4 May 13 '16 at 9:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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