How to get the parent directory of a path string

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:

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

Answers (2)

Kent
Kent

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.

  • if your string ending with separator
  • if you used :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

Peter Rincker
Peter Rincker

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

Related Questions