2

While I was answering another question, I noticed an odd behaviour in the functions finddir() and findfile(). According to the help page, both of these functions will return the full path to the first match unless the match is found in a directory beneath the specified directory. Is there some way of forcing both of them to return a full path?

  • 3
    Call fnamemodify(..., ':p') on the results? – Sato Katsura Dec 10 '15 at 6:16
  • AFAICT, you can not with current implementation of findfile(). – cuonglm Dec 10 '15 at 7:45
  • @SatoKatsura I'll accept that if you post it as an answer. – EvergreenTree Dec 10 '15 at 17:59
  • Then you'd be wrong to do it. A real answer would have to distinguish between finddir() / findfile() returning a string, and returning a list. :) – Sato Katsura Dec 11 '15 at 9:54
3

As far as I know it is impossible to force findfile()/finddir() to return full paths, but it is possible to convert them to full paths using the fnamemodify() function. It takes two arguments: the path you want to modify, and the modifiers. In this case, the modifier we are interested in is the :p modifier. This will take the given path and convert it to a full path. This can then be used on the outputs of the findfile() and finddir() functions, though it is a little trickier since we must account for the fact that they may return a list instead of just a string. Here is the solution I have come up with:

" Use ... to capture any and all arguments passed to this function
function! FindFileFP(...)
    " Use the call function to call a function with all of the captured arguments
    " as arguments to the specified function.
    let result = call(findfile, a:000)
    " Check to see if the result is a list
    if type(result) == type([])
        " Apply the fnamemodify function to every item in the list
        map(result, 'fnamemodify(v:val, ":%p")')
    else
        " Otherwise, just set the variable to the result of fnamemodify
        result = fnamemodify(result, ':%p')
    endif
    return result
endfunction

Note that you can create a counterpart for the finddir() function by simply changing all references to findfile().

For more help, see :help fnamemodify() and :help filename-modifiers.

NOTE:

There may be a shorter way of doing this, improvements welcome.

Your Answer

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

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