Search code examples
vimmakefile

How to make vim understand env variable between parenthesis'()' in makefile?


I am trying to use gf on a file path with parenthesis like below

$(env_var)/aaa/bbb/foo.txt

Even though I set isfname but it seems Vim takes it as a whitespace set isfname -=(,)

When I used isfname like below, it seems parentheses are read by Vim but it doesn't work set isfname +=(,)

Is there any way to use gf with env var inside of parenthesis?


Solution

  • To do more sophisticated substitutions on gf, you can use includeexpr. It provides a fallback for gf as documented in :help gf.

    First, you need to add parentheses to isfname as you have already done to capture $(env_var)

    Then you can write a tiny, substituting function.

    To use it only on makefiles, you can put the following code in ~/.vim/after/ftplugin/make.vim:

    setlocal isfname+=(,)
    setlocal includeexpr=substitute(v:fname,'\\$(\\(.\\{-}\\))','\\=getenv(submatch(1))','g')
    

    This will look through the file name below the cursor and replace the string $(env_var) with the result of getenv(env_var). The regular expression looks a bit intimidating because backslashes have to be escaped twice. It is roughly equivalent to $(.*) and captures anything inside the parentheses non-greedily as a submatch. That submatch is then fed into getenv().

    See :help 'includeexpr' and :help substitute() for reference.

    For Vim to source a filetype plugin, you will also need to set (at least) :filetype plugin on as explained in :help :filetype-plugin-on.

    Keep in mind that env_var may have a completely different value when you're editing and when you're running your file.

    A more orthodox alternative would be to add wherever env_var points to to the path option. See :help 'path'.