Skip to content
Enno edited this page Mar 7, 2026 · 24 revisions

If you have lesspipe.sh, lesspipe (as is the default on Debian and derivatives, such as Ubuntu, but falls short, among others, displaying archives) or run-mailcap (with a suitable ~/.mailcap file) installed, as by default on Debian (and derivatives such as Ubuntu), add a file plugin/lesspipe.vim into your vimfiles folder ~/.vim or $XDG_CONFIG_HOME/vim reading

if &compatible || exists('g:loaded_lesspipe') | finish | endif
let g:loaded_lesspipe = 1

if exists('g:lesspipe_cmd')
  let s:lesspipe_cmd = g:lesspipe_cmd
elseif executable('lesspipe.sh')
  let s:lesspipe_cmd = 'LESSQUIET=1 lesspipe.sh'
elseif executable('lesspipe')
  let s:lesspipe_cmd = 'lesspipe'
elseif executable('run-mailcap')
  let s:lesspipe_cmd = 'run-mailcap --action=cat'
endif
let s:executable_file = executable('file')

" Require a usable lesspipe command.
if !exists('s:lesspipe_cmd') || !executable('file') | finish | endif

" Optional upper bound to avoid expensive conversions; override as needed.
if !exists('g:lesspipe_max_bytes')
  let g:lesspipe_max_bytes = 80 * 1024 * 1024  " 80 MiB
endif

function! s:IsTextMime(path) abort
  if !s:executable_file | return 0 | endif
  let mime = trim(system('file -b --mime-type ' . shellescape(a:path)))
  if v:shell_error != 0 | return 0 | endif
  if mime =~# '\v^%(text|message)/' | return 1 | endif
  if mime =~# '\v%(json|xml|javascript|ecmascript|x-(%(ba|c|k|z)?sh|shellscript)|yaml|toml)$' | return 1 | endif
  return 0
endfunction

function! s:Lesspipe() abort
  " Skip if already transformed or unsuitable buffer types.
  if exists('b:lesspipe_done') | return | endif
  " Respect existing filetype detection.
  let force = get(b:, 'lesspipe_force', 0)
  if !force && (!empty(&l:filetype) || did_filetype()) | return | endif

  if !empty(&l:buftype) || &l:binary | return | endif

  " Resolve absolute path; require a regular readable file.
  let abs = resolve(expand('%:p'))
  if getftype(abs) !=# 'file' | return | endif
  if !filereadable(abs) | return | endif
  " Skip URLs such as vim's netrw.
  if abs =~# '^\w\+://' | return | endif

  " Size guard to avoid heavy processing.
  let sz = getfsize(abs)
  if sz == 0 | echomsg 'lesspipe: skipping empty file ' . abs | return | endif
  if sz > g:lesspipe_max_bytes | echomsg 'lesspipe: skipping large file ' . abs | return | endif

  if !force && s:IsTextMime(abs) | return | endif

  " Apply lesspipe, then lock the buffer down for viewing.
  let save = [ &l:modifiable, &l:readonly, &l:binary, &l:buftype ]
  try
    if force | setlocal buftype= nobinary | endif
    setlocal modifiable noreadonly fileencoding=utf-8
    " Use keepjumps/keepmarks to avoid disturbing user state.
    execute 'silent keepjumps keepmarks %!' s:lesspipe_cmd shellescape(abs)
    setlocal nomodifiable readonly
    setlocal buftype=nowrite bufhidden=hide noswapfile
    setlocal filetype=text
    let b:lesspipe_done = 1
  catch /.*/
    let [ &l:modifiable, &l:readonly, &l:binary, &l:buftype ] = save
    echomsg $"lesspipe: failed for {abs}: {v:exception}"
  endtry
endfunction

augroup lesspipe
  autocmd!
  autocmd BufReadPost *   call s:Lesspipe()
  "  Vim sets a filetype for pdf files; force lesspipe on them.
  " autocmd BufReadCmd *.{PDF,pdf} if filereadable(resolve(expand('<afile>:p'))) | let b:lesspipe_force = 1 | doautocmd lesspipe BufReadPost
augroup END

To ensure that Vim displays the text contained in a Microsoft Office or EPUB document instead of listing the files it archives (by the zipPlugin, see :help zip), edit your .vimrc choosing one of these 2 options:

  • either exclude these file types from those handled by zipPlugin
  • or disable the 'zipPlugin' altogether

Example of how to exclude some file types from those handled by zipPlugin

Check what is currently handled by the zipPlugin:

echo g:zipPlugin_ext
*.aar,*.apk,*.celzip,*.crtx,*.docm,*.docx,*.dotm,*.dotx,*.ear,*.epub,*.gcsx,*.glox,*.gqsx,*.ja,*.jar,*.kmz,*.odb,*.odc,*.od
f,*.odg,*.odi,*.odm,*.odp,*.ods,*.odt,*.otc,*.otf,*.otg,*.oth,*.oti,*.otp,*.ots,*.ott,*.oxt,*.potm,*.potx,*.ppam,*.ppsm,*.p
psx,*.pptm,*.pptx,*.sldx,*.thmx,*.vdw,*.war,*.wsz,*.xap,*.xlam,*.xlam,*.xlsb,*.xlsm,*.xlsx,*.xltm,*.xltx,*.xpi,*.zip

Remove the desired extensions, for example, jar?|epub|doc[xm]|xls[xmb]|pp[st][xm], so that they can be handled by lesspipe inside vim

" Remove extensions jar?|epub|doc[xm]|xls[xmb]|pp[st][xm] from g:zipPlugin_ext
" from Sep 13, 2016 and afterwards add back whenever converter unavailable
let g:zipPlugin_ext='*.apk,*.celzip,*.crtx,*.ear,*.gcsx,*.glox,*.gqsx,*.kmz,*.oxt,*.potm,*.potx,*.ppam,*.sldx,*.thmx,*.vdw,*.war,*.wsz,*.xap,*.xlam,*.xlam,*.xltm,*.xltx,*.xpi,*.zip'

Example of disabling it altogether

  let g:loaded_gzip = v:true

See also the vim-office plug-in to display meaningful text of a binary files read by Vim but without lesspipe.

Clone this wiki locally