I have following command:

map <Leader>ntd :execute ":tabe! ". g:path ."l_todo.txt"<CR><ESC> :execute ":vsplit! ".g:path ."u_todo.txt"<CR>

Both tabe! and vsplit! commands works fine as separate remapings. I want to join those commands into one remaping.

How to make the above command to work?

  • 2
    You should try using only once execute call with a pipe | to chain the commands like nnoremap <leader>a :execute "tabnew \| vsplit"<CR>. I didn't test it but I think your command should be map <Leader>ntd :execute "tabe! ". g:path ."l_todo.txt \| vsplit! ".g:path ."u_todo.txt"<CR> (Also use nore and a mode in your map command i.e. nnoremap, this is a good practice and can save you a lot of debugging`) – statox Sep 25 '18 at 9:54
  • I believe the esc in the middle is throwing an error and interrupting the map. – Spidey Sep 29 '18 at 14:36

You don't need to use two different execute() calls, you can simply call both commands in execute() like this:

nnoremap <Leader>ntd :execute "tabe! ". g:path . "l_todo.txt \| vsplit! " . g:path . "u_todo.txt"<CR>

Note the escaped piped character (\|) it is escaped so that vim understands that it is part of the command fed to execute.

Otherwise, when you source your vimrc, Vim would try to execute first nnoremap <Leader>ntd :execute ":tabe! ". g:path . "l_todo.txt followed by vsplit! " . g:path . "u_todo.txt"<CR> which is not what you want.

You could also improve the readability of your code like this:

let firstCommand="tabe! ". getcwd() . "/l_todo.txt"
let secondCommand="vsplit! " . getcwd() . "/u_todo.txt"
nnoremap <Leader>ntd :execute firstCommand . "\|" . secondCommand<CR>

Here we separate the different part of the string give to execute() to see the two actions executed.

We also use :h getcwd() to get the current working directory so that we don't need a global variable to get the path.

Several other points about your code:

  • You don't need the : in the commands you feed to execute()
  • Always use the non recurcive version of map (i.e. noremap) unless you know what you're doing
  • Always specify a mode to map (see :h map-modes)
  • 1
    With your refactoring, I believe changing g:path mid-session wont be reflected in the mapping. Id make first and second functions instead. – D. Ben Knoble Sep 25 '18 at 13:58
  • 1
    @D.BenKnoble You're perfectly right, I guess one could also use :h getcwd() instead of g:path depending on what the variable is meant to contain. – statox Sep 25 '18 at 14:08

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.