You could use pathshorten()
on the results of expand('%:h')
to shorten only the path up to the containing folder (the head).
For a path of /home/dev/.vim/ftplugin/c.vim
:
expand('%:h') -> /home/dev/.vim/ftplugin
pathshorten(expand('%:h')) -> /h/d/.v/ftplugin
Then, you can use expand('%:t')
to get just the tail of the path (in this example, c.vim
) and concatenate with the shortened head:
pathshorten(expand('%:h')) . '/' . expand('%:t') -> /h/d/.v/ftplugin/c.vim
This will work 99% of the time, and you could stop there and probably never encounter the other 1%:
What if the only component of the path is the tail?
Take for instance the path /foo
. The result of the above for this path would be //foo
(due to the /
concatenated between the shortened head /
and the
tail foo
). This is a contrived example, sure, but for the sake of completeness you could check if expand('%:h') == '/'
(indicative of our edge case) when adding the shortened head before the tail of the path.
In this snippet, I'm using a conditional expression:
(expand('%:h') == '/' ? '' : pathshorten(expand('%:h'))) . '/' . expand('%:t')
This will now correctly show the path /foo
, covering our edge case.
This is kind of hard to understand at a glance though, especially within a statusline item with %{}
.
It may be better to move this to it's own function, where the logic can be expressed more clearly, as well as decluttering our variable assignment:
function! CondensedPath() abort
if expand(':h') == '/'
return '/' . expand('%:t')
else
return pathshorten(expand('%:h')) . '/' . expand('%:t')
endif
endfunction
let g:airline_section_c='%{CondensedPath()}'