2

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?

statox
  • 49,782
  • 19
  • 148
  • 225
lluke
  • 219
  • 2
  • 9
  • 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 09:54
  • I believe the esc in the middle is throwing an error and interrupting the map. – Spidey Sep 29 '18 at 14:36

1 Answers1

4

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)
statox
  • 49,782
  • 19
  • 148
  • 225
  • 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