justinmk / vim-dirvish

Directory viewer for Vim :zap:
Other
1.19k stars 64 forks source link

Display file metadata in the command line. #114

Closed skywind3000 closed 6 years ago

skywind3000 commented 6 years ago

Just like what ranger does, file size , attributes and timestamps will be displayed in the command line.

Dirvish is great, but I always want to know the file size and modified time when I am using dirvish, any way to achieve this ?

justinmk commented 6 years ago

Just need a good mapping..

skywind3000 commented 6 years ago

For example?

lacygoill commented 6 years ago

FWIW, I use this code:

In ~/.vim/after/ftplugin/dirvish.vim:

nno  <buffer><nowait><silent>  !m  :<c-u>call my_dirvish#show_metadata('manual')<cr>
nno  <buffer><nowait><silent>  !M  :<c-u>call my_dirvish#show_metadata('auto')<cr>

let b:undo_ftplugin =         get(b:, 'undo_ftplugin', '')
                    \ .(empty(get(b:, 'undo_ftplugin', '')) ? '' : '|')
                    \ ."
                    \   unlet! b:my_dirvish_last_line
                    \ | exe 'sil! au! dirvish_show_metadata * <buffer>'
                    \ | exe 'nunmap <buffer> !m'
                    \ | exe 'nunmap <buffer> !M'
                    \  "

In ~/.vim/autoload/my_dirvish.vim:

fu! my_dirvish#show_metadata(mode) abort
    if a:mode is# 'auto'
        if !exists('#dirvish_show_metadata')
            call s:auto_metadata()
            augroup dirvish_show_metadata_and_persist
                au!
                au FileType dirvish call s:auto_metadata()
            augroup END
        else
            unlet! b:my_dirvish_last_line
            sil! au!  dirvish_show_metadata
            sil! aug! dirvish_show_metadata
            sil! au!  dirvish_show_metadata_and_persist
            sil! aug! dirvish_show_metadata_and_persist
            return
        endif
    endif

    let file = getline('.')
    let file = substitute(file, '/$', '', '')
    let metadata = expand('`ls -lhd --time-style=long-iso '.shellescape(file).'`')
    let metadata = substitute(metadata, '\V'.escape(file, '\'), '', '')
    redraw
    echon metadata

    let ftype = getftype(file)
    if ftype !~# '^\Cfile$\|^dir$'
        echohl WarningMsg
        echon ' '.ftype
        echohl NONE
    endif
endfu

fu! s:auto_metadata() abort
    augroup dirvish_show_metadata
        au! * <buffer>
        au CursorMoved <buffer> if get(b:, 'my_dirvish_last_line', 0) !=# line('.')
        \ |                         let b:my_dirvish_last_line = line('.')
        \ |                         call my_dirvish#show_metadata('manual')
        \ |                     endif
    augroup END
endfu

It installs the !m mapping which, when pressed, shows some metadata about the file/directory under the cursor. !M does the same thing, but automatically as you move your cursor from a file to another. If you press !M again, the autocmd showing the metadata will be removed.


If you use Windows, you will need to replace this line:

    let metadata = expand('`ls -lhd --time-style=long-iso '.shellescape(file).'`')

Because it uses the Linux $ ls command, and I don't know what is the equivalent command on Windows, nor its syntax.

You may also need to replace this one:

    let file = substitute(file, '/$', '', '')
    "                            ^

Because it assumes that a forward slash is a separator between two path components.


You can get the output of a shell command with 3 Vim functions:

system('your shell cmd')
get(systemlist('your shell cmd'), 0, '')
expand('`your shell cmd`')

system() will return a string, but append a newline at the end. systemlist() won't, but will return a list (which may be empty, hence the use of get()), every line being an item. expand() will return the same thing as system(), without appending a newline at the end.


And you can get some metadata about a file with the getfperm(), getfsize(), getftype(), getftime() functions:

:echo getfperm(getline('.'))
:echo getfsize(getline('.'))
:echo getftype(getline('.'))
:echo strftime('%c', getftime(getline('.')))

They should give you, respectively, the permissions, the size, the type (file, directory, symlink, socket, ...) and the time of last modification of the path under the cursor.

See also :h strftime() to format the time as you want.


If you need to support both environment (Linux + Windows), you can test it with these statements:

if has('unix')
if has('win32')
if has('win32unix')
if has('win64')
if has('win95')

See :h has() and :h feature-list for their meanings.