Reputation: 4888
I have my .vimrc
in a different path, that I source from my main ~/.vimrc
(so I can share same settings across Windows, bash on Windows, etc).
I'm trying to write something in the .vimrc
in question, that would make a hotkey for editing said .vimrc
, without hard coding the path.
What I currently have is this:
let g:vimrc_path = expand('<sfile>')
:map <Leader>v exec(":e " + g:vimrc_path + "<CR>")
But this doesn't seem to do anything. I've verified that g:vimrc_path
is the right value, and that the <Leader>v
ends up being called by subbing in echo messages, but I'm not wrapping my head around why the variable I'm trying to define doesn't get expanded correctly.
Upvotes: 1
Views: 378
Reputation: 7679
Strings in vimscript are concatenated with .
, not with +
. For example:
:echo "Hello"." world!"
will echo
Hello world!
If you were to type
:echo "Hello" + " world!"
vim would echo
0
This is because the +
operator is only for numbers, so vim attempts to cast these strings to numbers. If you were to run
:echo "3" + "1"
vim would echo "4".
So basically, you just need to change
:map <Leader>v exec(":e " + g:vimrc_path + "<CR>")
to
:map <Leader>v exec(":e ".g:vimrc_path."<CR>")
Another problem you might have not seen is that "<CR>"
evaluates to the literal text "<CR>"
, so it only messes up your function. If you want a literal carriage return, you would need a backslash. However, you definitely do not want to do this! Seriously, try it out and see.
You can see the issue. It looks for a file that has a literal carriage return at the end of the filename! There is a very simple fix though. Remove the "\<cr>"
completely. Since :exec
runs ex commands by default, the carriage return (and the colon too for that matter) are unnecessary.
Also, as a nitpick,
The parenthesis are not needed for the "exec" function, and
Use nnoremap
instead to avoid recursive mappings.
Taking all of this into consideration, I would simplify it to
:nnoremap <Leader>v :exec "e ".g:vimrc_path<cr>
Upvotes: 0
Reputation: 172570
.
, not with +
, which performs coercion into numbers and addition. But :execute
takes multiple arguments (which it space-separates), so you don't actually need this here.:noremap
; it makes the mapping immune to remapping and recursion.:help map-modes
), so define this just for normal mode.:exec[ute
is an Ex command, so for a normal-mode mapping, you need to first enter command-line mode. So :exec 'edit'
instead of exec ':edit'
.execute()
), so the parentheses are superfluous.<silent>
avoids the printing of the whole command (you'll notice the loading of the vimrc file, anyway); it's optional.fnameescape()
ensures that pathological path names are also handled; probably not necessary here.let g:vimrc_path = expand('<sfile>')
nnoremap <silent> <Leader>v :execute 'edit' fnameescape(g:vimrc_path)<CR>
As the script path is static, you can move the variable interpolation from runtime (mapping execution) to mapping definition, and get rid of the variable:
execute 'nnoremap <Leader>v :edit' fnameescape(expand('<sfile>')) . '<CR>'
Upvotes: 3