Reputation: 383984
I want to do the same thing as the bash dirname
command or python os.path.split()[0]
in vimscript for any path string (not necessarily the path of the current file).
Sample desired behaviour:
/a/b/
-> /a
/a/b
-> /a
I have tried fnamemodify()
but to me its output seems to depend on whether dirs exist or not:
:ec fnamemodify( '/usr/idontexist', ':p:h')
gives:
/usr
which is good, but:
:ec fnamemodify( '/usr/bin', ':p:h')
gives:
/usr/bin
which is not what I want, and I can't figure out what it is doing.
I hope to find a cross platform solution.
Upvotes: 11
Views: 8356
Reputation: 195209
have you read this part of the description of :h
:
When the file name ends in a path separator, only the path
separator is removed. Thus ":p:h" on a directory name results
on the directory name itself (without trailing slash).
that's the reason of:
:ec fnamemodify( '/usr/bin/', ':p:h') "directory, ending with /
-> /usr/bin
:ec fnamemodify( '/usr/bin/', ':h') "directory, ending with /
-> /usr/bin
:ec fnamemodify( '/usr/bin', ':p:h') "directory, not ending with /
-> /usr/bin
:ec fnamemodify( '/usr/bin', ':h') "directory, not ending with /
-> /usr
so there are two factors to decide the output.
separator
:p
to achieve your goal, you may remove the last char if the string is ending with /
(or \ in win?)
, then pass to the function without :p
Upvotes: 21
Reputation: 45157
fnamemodify( '/usr/idontexist', ':h')
The :p
modifier will expand a path to a full path. Therefore it must be a real path. Just don't use :p
if you are not messing with real paths.
See
:h filename-modifiers
Upvotes: 5