Monitoring files with vim
November 17th, 2015
No comments
It turns out that monitoring a file with vim
is harder than it should be. Scripts such as Tail-Bundle
and WatchForChanges
rely on vim’s CursorHold
events which only trigger once. Unlike tail -f
, they only work if you’re active in that vim
session and pressing keys to cause CursorHold to re-arm.
tail -f
works well, but lacks the syntax highlighting and other features from vim
.
Some other options require 2 terminals, or 2 separate scripts.
The solution below is very similar to tail -f
. The primary difference is that it only monitors a single file at a time.
Get the latest version from: https://gist.github.com/4a334b61e1c34b438ccd.git
#!/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. # 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. NAME="TAIL$$" doForever() { # Give the vim server a chance to start sleep 2 # Move to the end of the file $VI --servername $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 $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 --servername $NAME --remote-silent "$1" # Nothing below here executes until the `tail` server exits.