#!/bin/sh

# Script for using ViM as a PAGER.
# Based on Bram's less.sh.
# Version 1.5.7
# git://github.com/rkitover/vimpager.git

# Just pass through if not on a tty
if [ ! -t 1 ]; then
	exec cat "$@"
fi

case `uname -s` in
	Linux) linux=1 ;;
	SunOS) solaris=1 ;;
        Darwin) osx=1; bsd=1 ;;
	CYGWIN*) cygwin=1 ;;
	MINGW*) msys=1 ;;
	*) bsd=1 ;;
esac

less_vim() {
	if [ -z "$msys" ]; then
		(vim --noplugin -X -e -c 'let vimpager_use_gvim' -c q < /dev/tty) \
		   | cut -d\# -f2 | head -1 | awk '$1 ~ /^1/ {t=1} END { exit 1-t }' \
		   && use_gvim=1
	else
		# The above doesn't work on msys for some reason, so we use
		# grep.
		use_gvim=`grep '^[ \t]*\<let[ \t]\+vimpager_use_gvim[ \t]\+=[ \t]\+1' ~/_vimrc 2>/dev/null | head -1`
		[ -n "$use_gvim" ] || use_gvim=`grep '^[ \t]*\<let[ \t]\+vimpager_use_gvim[ \t]\+=[ \t]\+1' ~/.vimrc 2>/dev/null | head -1`

		# msys may not be installed with an msys vim, and if we're
		# not in a real console the native Windows vim will not
		# work, so we have to use gvim.

		if [ "x$TERM" != "xdumb" -a "x$TERM" != "xcygwin" -a "x$TERM" != "x" ]; then
			if [ \( ! -x /bin/vim \) -a \( ! -x /usr/bin/vim \) -a \( ! -x /usr/local/bin/vim \) ]; then
				use_gvim=1
			fi
		fi
	fi

        if [ -n "$use_gvim" ]; then
                if [ -n "$osx" ]; then
			if [ -z "$SSH_CONNECTION" ] && command -v mvim >/dev/null; then
				vim_cmd="mvim -R"
			else
				vim_cmd="vim -X -R"
			fi
		elif [ -n "$cygwin" ]; then
			if command -v gvim >/dev/null; then
				# The Cygwin gvim uses X
				if ldd `command -v gvim` 2>/dev/null \
				   | awk '$1 ~ /cygwin/ {t=1} END { exit 1-t }'; then
					if [ -z "$DISPLAY" ]; then
						vim_cmd="vim -X -R"
					else
						vim_cmd='gvim -R'
					fi
				elif [ -z "$SSH_CONNECTION" ]; then
					vim_cmd='gvim -R'
				else
					vim_cmd="vim -X -R"
				fi
			else
				vim_cmd="vim -X -R"
			fi
		elif [ -n "$msys" ]; then
			if [ -z "$SSH_CONNECTION" ] && command -v gvim >/dev/null; then
				vim_cmd='gvim -R'
			else
				vim_cmd="vim -X -R"
			fi
		elif [ -z "$DISPLAY" ]; then
			vim_cmd='vim -X -R'
		else
			if command -v gvim >/dev/null; then
				vim_cmd='gvim -R'
			else
				vim_cmd="vim -X -R"
			fi
		fi
	else
	        vim_cmd='vim -X -R'
	fi

	rm -f gvim.exe.stackdump # for cygwin gvim, which can be part of vim

	vimrc=""

	if [ -n "$VIMPAGER_RC" ]; then
		vimrc=$VIMPAGER_RC
	elif [ -f ~/.vimpagerrc ]; then
		vimrc=~/.vimpagerrc
	elif [ -f ~/_vimpagerrc ]; then
		vimrc=~/_vimpagerrc
	fi

	case $vim_cmd in
		vim*)
			if [ -n "$vimrc" ]; then
				$vim_cmd \
				--cmd 'let vimpager=1' \
				-u $vimrc \
				-c 'set scrolloff=5 | runtime! macros/less.vim | set foldlevel=999 | set nonu' \
				-c 'nmap <ESC>u :nohlsearch<cr>' \
				"${@:--}"
			else
				$vim_cmd \
				--cmd 'let vimpager=1' \
				-c 'set scrolloff=5 | runtime! macros/less.vim | set foldlevel=999 | set nonu' \
				-c 'nmap <ESC>u :nohlsearch<cr>' \
				"${@:--}"
			fi
			;;
		*) # gvim or mvim GUI
			if [ -f ~/.gvimrc ]; then
				gvimrc=~/.gvimrc
			elif [ -f ~/_gvimrc ]; then
				gvimrc=~/_gvimrc
			elif [ -n "$cygwin" ]; then
# this from Corinna at http://cygwin.com/ml/cygwin/2010-08/msg00246.html
				_sid=$(grep "^$USER:" /etc/passwd | sed -e 's/[^:]*:[^:]*:[^:]*:[^:]*:[^:]*,\(S-1-5-[^:]*\):.*/\1/')
				_prof=$(cat /proc/registry/HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows\ NT/CurrentVersion/ProfileList/${_sid}/ProfileImagePath)
				
				if [ -f "${_prof}/_gvimrc" ]; then
					gvimrc="${_prof}/_gvimrc"
				elif [ -f "${_prof}/.gvimrc" ]; then
					gvimrc="${_prof}/.gvimrc"
				fi

				unset _sid
				unset _prof
			fi

			[ -n "$gvimrc" ] && colors=`grep guifg $gvimrc 2>/dev/null | head -1`

			# Check if the user maximized the window in ~/_gvimrc on Win32, if
			# so restore on startup.
			if [ -n "$gvimrc" -a \( -n "$cygwin" -o -n "$msys" \) ]; then
				simalt=`grep simalt $gvimrc 2>/dev/null | head -1`

				if [ -n "$simalt" ]; then
					restore="simalt ~r"
				fi
			fi

			if command -v tput > /dev/null; then
				# this is the only way it works on Cygwin
				tput cols  > /tmp/vimpager_cols_$$
				tput lines > /tmp/vimpager_lines_$$

				cols=`cat /tmp/vimpager_cols_$$`
				lines=`cat /tmp/vimpager_lines_$$`

				rm -f /tmp/vimpager_cols_$$ /tmp/vimpager_lines_$$
			fi

			# msys has no tput, this doesn't work on Cygwin by the way
			if [ -z "$cols" ] && command -v bash >/dev/null; then
				cols=`bash -i -c 'echo $COLUMNS'`
				lines=`bash -i -c 'echo $LINES'`
			fi

			# If we are unable to detect lines/columns, maximize
			# the window.
			if [ -z "$cols" ]; then
				cols=999
				lines=999
			fi

			if [ -n "$vimrc" ]; then
				$vim_cmd \
				--cmd 'let vimpager=1' \
				-u $vimrc \
				-c 'set scrolloff=5 | runtime! macros/less.vim | set foldlevel=999 | set nonu' \
				-c 'nmap <ESC>u :nohlsearch<cr>' \
				-c "${colors:-echo}" \
				-c "${restore:-echo}" \
				-c "set lines=$lines | set columns=$cols" \
				"${@:--}" &
			else
				$vim_cmd \
				--cmd 'let vimpager=1' \
				-c 'set scrolloff=5 | runtime! macros/less.vim | set foldlevel=999 | set nonu' \
				-c 'nmap <ESC>u :nohlsearch<cr>' \
				-c "${colors:-echo}" \
				-c "${restore:-echo}" \
				-c "set lines=$lines | set columns=$cols" \
				"${@:--}" &
			fi
			;;
	esac

	rm -f gvim.exe.stackdump # for cygwin gvim, which can be part of vim
}

awk_pstree() {
	awk -v mypid=$1 '{
		cmd[$1]=$3
		ppid[$1]=$2
	}
	END {
		while (mypid != 1 && cmd[mypid]) {
			ptree=mypid " " cmd[mypid] "\n" ptree
			mypid=ppid[mypid]
		}
		print ptree
	}'
}

do_ptree() {
	if [ -n "$solaris" ]; then
		# Tested on Solaris 8 and 10
		ptree $$
	elif [ -n "$cygwin" -o -n "$msys" ]; then
		ps | awk '{ print $1 "\t" $2 "\t" $NF }' | awk_pstree $$
	else
		# Tested on Linux and OS X
		ps awo pid=,ppid=,comm= | awk_pstree $$
	fi
}

# Check if called from man, perldoc or pydoc
if do_ptree | awk '$2 ~ /(^|\/)(man|perl(doc)?([0-9.]*)?|py(thon|doc|doc2))/ {t=1} END { exit 1-t }'; then
	extra_cmd="set ft=man"
fi

trap "rm -rf /tmp/vimpager_$$" HUP INT QUIT ILL TRAP KILL BUS TERM

mkdir /tmp/vimpager_$$

filename=${@:-stdin}
filename=`echo "$filename" | tr '/' '_'`
filename="/tmp/vimpager_${$}/$filename"

case "$@" in
	*.gz) gunzip -c "$@" | sed -e 's/\[[^m]*m//g' -e 's/.//g' > "$filename" ;;
	*.Z) uncompress -c "$@" | sed -e 's/\[[^m]*m//g' -e 's/.//g' > "$filename" ;;
	*) sed -e 's/\[[^m]*m//g' -e 's/.//g' "$@" > "$filename" ;;
esac

# if file is zero length, exit immediately
if [ ! -s "$filename" ]; then
	exit
fi

# On cygwin it might be the win32 gvim, but windows paths work for cygwin
# vim just fine as well.
if [ -n "$cygwin" ]; then
	filename=`cygpath -w "$filename"`
fi

less_vim -c "${extra_cmd:-echo}" "$filename" </dev/tty

# terminal vim on OSX can screw up the terminal
# (but doesn't anymore for some reason...)
#if [ -n "$osx" ]; then
#	case $vim_cmd in
#		vim*)
#			reset
#			clear
#			;;
#	esac
#fi

# Give gvim/mvim time to open the file.
# On Cygwin we must also wait for the process to exit before the file can
# be deleted.
(
	while [ -d /tmp/vimpager_$$ ]; do
		sleep 3
		rm -rf /tmp/vimpager_$$ 2>/dev/null
		rm -f gvim.exe.stackdump 2>/dev/null
	done
) &

# CONTRIBUTORS:
#
# Rafael Kitover
# Antonio Ospite
# Jean-Marie Gaillourdet
# Perry Hargrave
# Koen Smits
# Ivan S. Freitas <ivansichfreitas@gmail.com>
# Wout Mertens (Solaris compatibility, less processes)
# Jacobo de Vera (add -X option for faster startup)
# Damien Pollet <damien.pollet@gmail.com>

# vim:noet ts=8 sts=8 sw=8:
