#!/bin/bash

# Usage:
#   grepl [OPTIONS] [GREP-OPTIONS] PATTERN FILE

help() {
  cat <<EOF
Usage: grepl [OPTIONS] [GREP-OPTIONS] PATTERN FILE

Options:

-k, --length         Specify the number of characters around the
                     searching keyword to be shown.
-H, --with-filename  Display file names on each line.
--help               Show this help message.

Please note that some grep options such as "-r" will break this script.
Specify FILE as a dash ("-") to read from stdin.
EOF

  exit
}

# Postprocess the output: prepend file names if required.
postprocess() {
  local show="$1"
  local filename="$2"

  if [ "$show" = true ]; then
    sed -e "s|^|${filename}: |"
  else
    cat
  fi
}

# How many characters around the searching keyword should be shown?
context_length=10
# Should file names be printed for each matched line?
show_file_names=false

while :
do
  # Allow the length to be overridden on the command line by specifying -C=N.
  case $1 in
    --help)
      help
      ;;
    -k|--length)
      context_length="$2"
      shift 2
      ;;
    -H|--with-filename)
      show_file_names=true
      shift
      ;;
    *)
      break
      ;;
  esac
done

# What is the length of the control character for the color before and after the matching string?
# This is mostly determined by the environmental variable GREP_COLORS.
control_length_before=$(($(echo a | grep --color=always a | cut -d a -f '1' | wc -c)-1))
control_length_after=$(($(echo a | grep --color=always a | cut -d a -f '2' | wc -c)-1))

# The second last argument is the pattern.
pattern=${@: -2:1}

grep -E --color=always "$@" | \
  grep --color=none -oE ".{0,$(($control_length_before + $context_length))}${pattern}.{0,$(($control_length_after + $context_length))}" | \
  postprocess ${show_file_names} ${@: -1}
