3

I currently have the following auto-command (in my vimrc) -

autocmd BufEnter *.c nmap <F5> :Makexec<CR> 
  \:if findfile( expand("%:p:r").".exe" ,expand("%:p:h") ) != ""<CR>
  \    :!%:p:r.exe<CR>
  \:else<CR>
  \    :vert topleft cwin<CR>
  \    :vert resize 50<CR>
  \:endif<CR> 

What is Makexec?
Not relevant in my opinion, however if necessary see below *

I want to convert this auto-command such that it executes a single string where the string contains the above commands chained together.

  • Attempt 1

    let g:c_exe_str="Makexec | if findfile(expand(\"%:p:r\").\".exe\", expand(\"%:p:h\")) != \"\" | !%:p:r.exe | else | vert topleft cwin | vert resize 50 | endif"
    
    autocmd BufEnter *.c nmap <F5> :execute g:c_exe_str<CR>
    

    This didn't work as I had expected, I get the following error at the shell -

    C:\windows\system32\cmd.exe /c D:\NewFolder\c_experiments.exe | else | vert topleft cwin | vert resize 50 | endif
    'else' is not recognized as an internal or external command, operable program or batch file.

  • Attempt 2

    let g:c_exe_str="Makexec | if findfile(expand(\"%:p:r\").\".exe\", expand(\"%:p:h\")) != \"\" | echo system(expand(\"%:p:r\").\".exe\") | else | vert topleft cwin | vert resize 50 | endif"
    
    autocmd BufEnter *.c nmap <F5> :execute g:c_exe_str<CR>
    

    This kinda (sic) works but without displaying the executable's output in a shell window; basically it doesn't work the same way as the original auto-command.

How do I go about exactly mimicking the original auto-command's steps using execute()?

* command -nargs=? Makexec :w | :silent exe "!rm -f %:p:r.exe" | :let &makeprg='gcc -Wall -Werror -o %< % <args>' | :make!

7
  • 2
    Create a function, then a command that executes the function, then map the command.
    – VanLaser
    Dec 23, 2015 at 10:44
  • 2
    Yep. This is the job of functions.
    – muru
    Dec 23, 2015 at 10:45
  • 1
    @VanLaser - What does :!%:p:r.exe<CR> translate into in a vimrc function?
    – work.bin
    Dec 23, 2015 at 10:48
  • 1
    Should be the same thing ... execute in the shell the root component of the current edited filename, with .exe suffix appended. See :h filename-modifiers.
    – VanLaser
    Dec 23, 2015 at 10:55
  • Why do you want to change the existing auto-command? It's certainly not how I'd achieve the same functionality, but if it works, what is your goal in changing it? Why specifically do you want your solution to use :execute?
    – Rich
    Jan 5, 2016 at 10:11

1 Answer 1

1

It looks like the end goal is simply to have your F5 be mapped to certain functionality when you are in a C source file.

Presuming you already have file type detection switched on (:help filetype), the way I would achieve this is to:

  1. Create a function to run the code,
  2. Create a mapping to call the function when F5 is pressed,
  3. Place the code for both of these in the file ~/.vim/after/ftplugin/c.vim, which will cause the mapping to be created whenever a file of type C is edited. (See :help ftplugin-overrule for more details.)

    function! s:f5()
      Makexec 
      if findfile( expand("%:p:r").".exe" ,expand("%:p:h") ) != ""
        !%:p:r.exe
      else
        vert topleft cwin
        vert resize 50
      endif
    endfunction
    
    nnoremap <buffer> <silent> <F5> :call <SID>f5()<CR>
    

N.B.

  1. The s: and <SID> prefixes to the function name mean that the function is only defined within that script, preventing it from clashing with similarly named functions elsewhere, (:help <SID>)
  2. <buffer> causes the mapping only to apply to the individual buffer, so if you switch to a file with a different filetype, the F5 key won't erroneously call the function,
  3. <silent> just means that the mapping contents (:call...) won't be echoed to the screen when the mapping is invoked,
  4. If you don't have file type detection switched on, and for some reason you don't want to switch it on, you could of course use an autocommand to create the mapping, similar to what you had before:

    autocmd BufEnter *.c nnoremap <buffer> <silent> <F5> :call <SID>f5()<CR>
    

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.