Browse code

Add manpager workarounds

Patches the built-in Vim runtime files `plugin/manpager.vim` and
`ftplugin/man.vim` to work around tree issues:

1. `nocompatible` is set unconditionally, overriding options in the
vimrc. Fix it to only set it if necessary.
2. `col` fails with `col: write error` when Vim is invoked through
`man` with `$MANPAGER` (but not when starting Vim normally and
running `:Man`). The reason is unknown. Piping through `cat` fixes
the issue.
3. `man` likes to issue a lot of formatting warnings when output is
not a terminal (or when `MAN_KEEP_STDERR` is set) and the default
`shellredir` captures this. The fix is to temporarily set
`shellredir` to ignore `stderr`.

The patch:

for file in plugin/manpager.vim ftplugin/man.vim
do
diff -u $VIMRUNTIME/$file .vim/after/$file
done

--- $VIMRUNTIME/plugin/manpager.vim
+++ .vim/after/plugin/manpager.vim
@@ -5,7 +5,9 @@
command! -nargs=0 MANPAGER call s:ManPager() | delcommand MANPAGER

function! s:ManPager()
- set nocompatible
+ if &compatible
+ set nocompatible
+ endif
if exists('+viminfofile')
set viminfofile=NONE
endif

--- $VIMRUNTIME/ftplugin/man.vim
+++ .vim/after/ftplugin/man.vim
@@ -209,8 +209,11 @@
endif
let env_cmd = s:env_has_u ? 'env -u MANPAGER' : 'env MANPAGER=cat'
let env_cmd .= ' GROFF_NO_SGR=1'
- let man_cmd = env_cmd . ' man ' . s:GetCmdArg(sect, page) . ' | col -b'
+ let man_cmd = env_cmd . ' man ' . s:GetCmdArg(sect, page) . ' | col -b | cat'
+ let old_srr = &shellredir
+ let &shellredir = '>'
silent exec "r !" . man_cmd
+ let &shellredir = old_srr

if unsetwidth
let $MANWIDTH = ''

Robert Cranston authored on 20/06/2022 02:58:07
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,32 @@
1
+" Vim plugin for using Vim as manpager.
2
+" Maintainer: Enno Nagel <ennonagel+vim@gmail.com>
3
+" Last Change: 2018 Feb 04
4
+
5
+command! -nargs=0 MANPAGER call s:ManPager() | delcommand MANPAGER
6
+
7
+function! s:ManPager()
8
+  if &compatible
9
+    set nocompatible
10
+  endif
11
+  if exists('+viminfofile')
12
+    set viminfofile=NONE
13
+  endif
14
+  set noswapfile 
15
+
16
+  setlocal ft=man
17
+  runtime ftplugin/man.vim
18
+  setlocal buftype=nofile bufhidden=hide iskeyword+=: modifiable
19
+
20
+  " Emulate 'col -b'
21
+  silent keepj keepp %s/\v(.)\b\ze\1?//ge
22
+
23
+  " Remove empty lines above the header
24
+  call cursor(1, 1)
25
+  let n = search(".*(.*)", "c")
26
+  if n > 1
27
+    exe "1," . n-1 . "d"
28
+  endif
29
+  setlocal nomodified readonly
30
+
31
+  syntax on
32
+endfunction