From: Simon Ruderich Date: Sat, 30 Jun 2012 13:27:53 +0000 (+0200) Subject: vimrc: Use replacement for %f in statusline which uses relative paths. X-Git-Url: https://ruderich.org/simon/gitweb/?p=config%2Fdotfiles.git;a=commitdiff_plain;h=1cb1ea3259c5c74ab28ba4cc923a806a1848394c vimrc: Use replacement for %f in statusline which uses relative paths. --- diff --git a/vimrc b/vimrc index 81c8f1b..e8e945e 100644 --- a/vimrc +++ b/vimrc @@ -270,12 +270,79 @@ if has('statusline') endif endfunction + " Like %f but use relative filename if it's shorter than the absolute path + " (e.g. '../../file' vs. '~/long/path/to/file'). fnamemodify()'s ':.' is + " not enough because it doesn't create '../'s. + function! StatuslineRelativeFilename() + " Display only filename for help files. + if &buftype == 'help' + return expand('%:t') + endif + " Special case for scratch files. + if &buftype == 'nofile' + return '[Scratch]' + endif + + let l:path = expand('%') + " No file. + if l:path == '' + return '[No Name]' + endif + " Path is already relative, nothing to do. + if stridx(l:path, '/') != 0 + return l:path + endif + + " Absolute path to this file. + let l:path = expand('%:p') + " Shortened path to this file, thanks to bairui in #vim on Freenode + " (2012-06-23 00:54) for the tip to use fnamemodify(). This is what + " Vim normally uses as %f (minus some exceptions). + let l:original_path = fnamemodify(l:path, ':~') + " Absolute path to the current working directory. + let l:cwd = getcwd() + + " Working directory completely contained in path, replace it with a + " relative path. Happens for example when opening a file with netrw. + " %f displays this as absolute path, but we want a relative path of + " course. + if stridx(l:path, l:cwd) == 0 + return strpart(l:path, strlen(l:cwd) + 1) + endif + + let l:path_list = split(l:path, '/') + let l:cwd_list = split(l:cwd, '/') + + " Remove the common path. + while l:path_list[0] == l:cwd_list[0] + call remove(l:path_list, 0) + call remove(l:cwd_list, 0) + endwhile + + " Add as many '..' as necessary for the relative path and join the + " path. Thanks to Raimondi in #vim on Freenode (2012-06-23 01:13) for + " the hint to use repeat() instead of a loop. + let l:path = repeat('../', len(l:cwd_list)) . join(l:path_list, '/') + + " Use the shorter path, either relative or absolute. + if strlen(l:path) < strlen(l:original_path) + return l:path + else + return l:original_path + endif + endfunction + set statusline= " on the left set statusline+=%02n " buffer number set statusline+=%{StatuslineBufferCount()} " highest buffer number set statusline+=: - set statusline+=%f\ " path to current file in buffer + if has('modify_fname') + set statusline+=%{StatuslineRelativeFilename()} " path to current file + set statusline+=\ " space after path + else + set statusline+=%f\ " path to current file in buffer + endif set statusline+=%h " [help] if buffer is help file set statusline+=%w " [Preview] if buffer is preview buffer set statusline+=%m " [+] if buffer was modified,