Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
A modified version of gnu source-highlight's that also works with piped files and files with no extensions. It uses the file command to guess the language. This means you can use source-highlight in conjunction with commands like "git show"
#! /bin/bash
# Based on
# by Lorenzo Bettini
# Modified by Jay Caines-Gooby to support piped files
# @jaygooby
# Typically called by setting:
# export LESSOPEN="|-/path/to/ %s"
# export LESS=-R
# If we're less-ing a file, %s will be replaced by the name of the file. If
# there's no file and we're reading from a pipe, then %s is set to -
# This script differs from the original
# in that it can handle pipes and files with no extensions and will
# attempt to guess their language using the file command.
# So as well as invoking on regular files:
# less some.rb
# less
# It will should be able to work on:
# less no-extension-but-contains-perl
# and even with more complex examples (my original motivation
# git show master:some.rb
# It uses bashisms to do this, so is no longer a pure POSIX sh script.
set -eu
# Users can override the guessed language by setting SRCLANG:
# SRCLANG=c git show master:app/views/layouts/application.html.erb
guess_language() {
lang=$(echo -e ${1:-} | file - | cut -d" " -f2)
echo $(tr [A-Z] [a-z] <<< "$lang")
# check if the language passed as $1 is known to source-highlight
# In an earlier version of this script I set a fallback (c.lang)
# but this causes issues with paging man pages etc
check_language_is_known() {
lang=$(source-highlight --lang-list | cut -d' ' -f1 | grep "${1:-}" || true)
echo $lang
for source in "$@"; do
case $source in
source-highlight --failsafe -f esc --lang-def=changelog.lang -i "$source" ;;
source-highlight --failsafe -f esc --lang-def=makefile.lang -i "$source" ;;
lesspipe "$source" ;;
# naive check for a file extension; let source-highlight infer language
# but only when source isn't - (ie. from a piped file)
if [[ "$source" != "-" && $(basename "$source") =~ \. ]]; then
source-highlight --failsafe --infer-lang -f esc -i "$source"
# We're being piped to, or the filename doesn't have an extension
# so guess the language.
# When we're being piped to, we cat stdin, but when it's a file
# without an extension, we cat the file instead.
# unset IFS so line breaks are preserved and capture the file's contents
# (will only work for files up to bash's available memory). There should
# be a better way to replicate this with tee or process substitution...
IFS= file=$([ "source" = "-" ] && cat || cat "$source")
lang=$(guess_language $file)
lang=$(check_language_is_known $lang)
# Don't call if source-highlight doesn't know the language
# BUT also let users override the guessed lang if the environment
# variable SRCLANG is set. This can help where you know e.g. your
# source code is c-like, but source-highlight has no specific syntax
# definition for your code
# SRCLANG=c git show master:app/views/layouts/application.html.erb
[ -n "$SRCLANG" ] && lang="$SRCLANG"
if [ -n "$lang" ]; then
echo $file | source-highlight --failsafe -f esc --src-lang=$lang
echo $file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment