Search code examples
vimscriptingconsolecommandsudo

how to execute a sudo command using vim function as a parameter (inside vim)


My path is something like /home/me/projects/project_name/the_part/i_wanna/keep.yestheextensiontoo

I wrote this fuction:

function! CurrentPath()
  let filepath = expand("%")
  let spl = split(filepath, '/')
  let short = spl[4:-1]
  let newpath = join(short, '/')
  return newpath 
endfunction

I want to pass the resulting trimmed path the_part/i_wanna/keep.yestheextensiontoo to a sudo command

I would like to have something like this working:

nnoremap <F4> :w !sudo bin/test CurrentPath()<CR>

Ideally similar to how rspec-vim works where you run the command in a console (that replaces your vim session) and then when you hit enter (after the command is executed) you go back to your vim session.


Solution

  • The mapping:

    nnoremap <F4> :w !sudo bin/test CurrentPath()<CR>
    

    After ! everything is passed to the shell with the exception of some special items like % or # (see :help cmdline-special), so you can't really expect CurrentPath() to be evaluated, here.

    The simplest way to make this work is to use an "expression mapping", where the whole right-hand-side of the mapping is evaluated at runtime:

    nnoremap <expr> <F4> ':w !sudo bin/test ' .. CurrentPath() .. '<CR>'
    

    When you press <F4>, CurrentPath() is evaluated and concatenated with the rest, then the whole thing is sent to your shell.