Last active
February 14, 2017 04:12
-
-
Save gburca/4a334b61e1c34b438ccd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Usage: vim-tail.sh <filename> | |
# | |
# This script turns vim into a `tail -f` equivalent, but with syntax | |
# highlighting and all the other goodies. | |
# | |
# A version of vim compiled with +clientserver is required. | |
# Run `vim --version` to see what options were compiled in. | |
# On Ubuntu 14.04, vim.tiny, vim.basic and vim.nox won't work. | |
# vim.gtk is compiled with +clientserver, so `apt-get install vim-gtk` | |
# | |
# Author: Gabriel Burca <gburca dash github at ebixio dot com> | |
# Pick one of: vim|view|gvim|gview, etc... | |
VI=vim.gtk | |
# A unique name for the server, in case we monitor multiple files. | |
SERVER_NAME="TAIL$$" | |
hash inotifywait &> /dev/null || { echo "I require 'inotifywait' to be installed (apt-get install inotify-tools)"; exit 1; } | |
hash $VI &> /dev/null || { echo "I require '$VI' to be installed (apt-get install vim-gtk)"; exit 1; } | |
$VI --version | fgrep -q '+clientserver' || { echo "I require $VI to be compiled with '+clientserver'"; exit 1; } | |
# In VIM clientserver, the communication between the server and the client goes | |
# through the X server. That means we need a DISPLAY and permissions to connect | |
# to it. | |
if [ -z "$DISPLAY" ]; then | |
echo "I require the DISPLAY environment variable to be set" | |
exit 1 | |
fi | |
# See if we have access to the display | |
if ! xhost > /dev/null 2>&1 ; then | |
if [ -n "$SUDO_USER" ]; then | |
export XAUTHORITY=/home/$SUDO_USER/.Xauthority | |
elif [ "$USER" == "root" ]; then | |
su -c 'xhost SI:localuser:root > /dev/null' $SUDO_USER | |
else | |
echo "Display access needed." | |
echo "Try: xhost SI:localuser:$USER" | |
exit 2 | |
fi | |
fi | |
doForever() { | |
# Give the vim server a chance to start | |
sleep 2 | |
# Move to the end of the file | |
$VI -X --servername $SERVER_NAME --remote-send '<C-\><C-N>:edit!<CR>G' > /dev/null 2>&1 || exit | |
while true; do | |
# This blocks until the file changes, or the timeout expires | |
inotifywait --quiet --quiet --timeout 10 --event modify "$1" | |
# 0 = the file was modified | |
# 2 = the timeout expired | |
if (( $? == 0 || $? == 2 )); then | |
$VI --servername $SERVER_NAME --remote-send '<C-\><C-N>:edit!<CR>G' > /dev/null 2>&1 || exit | |
else | |
exit 1 | |
fi | |
# It's possible for the file to be modified before we loop back to | |
# `inotifywait`, but we'll pick it up on the next round. | |
done | |
} | |
# Kick off the vim client script in the background | |
coproc doForever "$1" | |
# Now start the server | |
$VI -X -R --servername $SERVER_NAME --remote-silent "$1" | |
# Nothing below here executes until the `tail` server exits. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment