Skip to main content
1 of 2
romainl
  • 42.3k
  • 5
  • 87
  • 118

What could I be doing wrong?

Inventing terminology would be one thing: "leader command" and "leader entries" are meaningless, for example.

Focusing on irrelevant details would be another: the "leader" mechanism is totally irrelevant.

And cramming too much functionality into a one-liner would be yet another.

First, let's clean up your original mappings:

nnoremap <leader>zs <Cmd>let @+ =substitute(substitute(join(filter(getline(1,'$'),'v:val=~"^source:"'),"\n"),'^\(source:\s*\)\(.*\)$','\2',''),'^\s*\(.*\)$','\1','')<CR>
nnoremap <leader>zd <Cmd>let @+ =getline('.')<CR>

and make <leader>zs more palatable:

function! GetTextFollowingSource()
    return getline(1, '$')
        \ ->filter('v:val=~"^source:"')
        \ ->join("\n")
        \ ->substitute('^\(source:\s*\)\(.*\)$','\2','')
        \ ->substitute('^\s*\(.*\)$','\1','')
endfunction
nnoremap <leader>zs <Cmd>let @+ = GetTextFollowingSource()<CR>
nnoremap <leader>zd <Cmd>let @+ = getline('.')<CR>

Now, in theory, you should be able to combine them like this:

nmap <key> <leader>zs<leader>zd

or like this:

nnoremap <key> <Cmd>let @+ = GetTextFollowingSource()<CR><Cmd>let @+ = getline('.')<CR>

which should have the same outcome.

They do, actually, but only if you use internal registers:

nnoremap <leader>zs <Cmd>let @a = GetTextFollowingSource()<CR>
nnoremap <leader>zd <Cmd>let @b = getline('.')<CR>

which gives you the "text following source" in register a and the current line in register b. So the problem is elsewhere.

Your assessment that there might be a timing issue can be tested easily outside of your specific mappings with the following command:

:let @+ = 1|let @+ = 2|let @+ = 3

which, in my clipboard manager (not Parcellite), gives me this:

3

which points to only the last invocation having any effect.

Adding delay:

:let @+ = 1|sleep 1|let @+ = 2|sleep 1|let @+ = 3

seems to help, here:

123

Applied to the case at hand:

nmap <key> <leader>zsgs<leader>zd

I get this, which I think is the desired outcome:

success

It also works with the other method:

nnoremap <key> <Cmd>let @+ = GetTextFollowingSource()<CR>gs<Cmd>let @+ = getline('.')<CR>

Now, which method to choose?

The first one is short and sweet, but:

  • the three parts of the RHS (<leader>zs, gs, and <leader>zd) are not clearly delimited, which impacts readability,
  • the value of :help mapleader can be changed between two <leader> expansions so this <leader> might not be the one used for the original mappings.

The second one is easier to follow and immune to <leader> shadowing, but it is starting to become too long for my taste. YMMV.

If you want to keep the original individual mappings, then both methods are fine.

If you don't care about the original individual mappings, then the second method is best.

romainl
  • 42.3k
  • 5
  • 87
  • 118