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()}'
:h expandrather than:h pathshorten, that would've led me to the list of modifiers and:hfor 'head'. – Rich Churcher Nov 03 '20 at 07:16