I have an exe program that checks for certain errors in a text file.

I want to create a shortcut (like \+M) to run that exe file against the text file.

My exe file's path is C:\Users\xyz\Documents\Checker\manager.exe, the text file's path is C:\Users\xyz\Desktop\mytextfile.txt.

The manager just needs the following command:

check [full filepath to the text file

Here is what I have tried in the VIM plugin file.

function! ExecuteManagerCheck(file)
    execute ':!start cmd /k "C:\Users\xyz\Documents\checker\manager check " g:file'

nmap <leader>m :call ExecuteManagerCheck(expand('%:p')) <cr>

Can someone please help me get the full file path to the current text file open in Vim?

  • 2
    That should probably be a:file and not g:file – D. Ben Knoble Jun 15 '18 at 20:54
  • 1
    Your expand('%:p') should work, according to eval.txt, but the quotemarks in "C:\...\manager check " don't make sense. Do you see any error messages when you try to run the plugin? – JigglyNaga Sep 13 '18 at 15:44

The problem is with the quotes around your :execute command. You want to close the single quote and then concatenate the a:file argument there. Then close the double quotes for the cmd /k execution.

Oh and like @D.BenKnoble mentioned in the comments, it's a:file (to refer to the argument passed to the function) rather than g:file (which refers to a global variable by that name.)

It's likely you might also need escaping, for this to still work if your filename contains special characters. I'm not too familiar with Windows to be able to tell you which one is right for you there, please experiment with escape() and friends.

function! ExecuteManagerCheck(file)
    execute ':!start cmd /k "C:\Users\xyz\Documents\checker\manager check '.a:file.'"'

nmap <leader>m :call ExecuteManagerCheck(expand('%:p'))<cr>

(And for escaping, I think escape(a:file, ' "\') might be the one you need...)

  • 1
    Using double quotes together with a backslash won't work. You need to escape the backslashes in this case. – Christian Brabandt Sep 6 '19 at 7:38

filenameescape() is supposed to be the solution. And yet, I've cooked my own solution 2 decades ago and it's still working fine so far.

function! lh#path#fix(pathname, ...) abort
  " Parameters       {{{4
  " Ignore the last slash or backslash character, if any
  let pathname   = matchstr(a:pathname, '^.*[^/\\]')
  " Default value for the quote character
  let quote_char = ''
  " Determine if 'shellslash' exists (dos-like platforms)
  if lh#os#OnDOSWindows()
    if lh#os#system_detected() == 'msdos'
      let shellslash = 0
      let shellslash = &shellslash
  else "unix
    let shellslash = 1
  " Determine if we will use slashes or backslashes to distinguish directories
  if a:0 >= 1   "
    let shellslash = a:1
    if a:0 >= 2
      let quote_char = a:2

  " Smart definition of quote chars for $COMSPEC
  if (lh#os#system_detected() == 'msdos') && !shellslash && (''==quote_char)
    if (&shell =~ 'command\.com')
      if pathname =~ ' '
        " should also test long directory-names...
        " Best: AVOID command.com !!!
        if &verbose >= 1
          call lh#common#error_msg('lh#path#fix: '.
                \ 'Problem expected because of the space in <'.pathname.'>')
        let quote_char = ''
      let quote_char = '"'

  " Fix the pathname {{{4
  if shellslash
    let res = substitute(
          \ substitute(pathname, '\\\([^ ]\|$\)', '/\1', 'g'),
          \ '\(^\|[^\\]\) ', '\1\\ ', 'g')
    let res = substitute(
          \ substitute(pathname, '\\ ', ' ', 'g'),
          \ '/', '\\', 'g')
  " Note: problem to take care (that explains the complex substition schemes):
  " sometimes the path passed to the function mix the two writtings, e.g.:
  " "c:\Program Files/longpath/some\ spaces/foo"
  " }}}4
  return quote_char . res . quote_char

Yeah. It's horrible. I should probably simplify it but... it works!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy