mirror of
https://github.com/eth-p/bat-extras.git
synced 2024-12-13 17:50:56 +01:00
Initial commit.
This commit is contained in:
commit
248d7077f4
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# System
|
||||||
|
.DS_Store
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Project
|
||||||
|
.download
|
||||||
|
bin
|
||||||
|
|
49
README.md
Normal file
49
README.md
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# bat-extras
|
||||||
|
|
||||||
|
Bash scripts that integrate [bat](https://github.com/sharkdp/bat) with various command line tools.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
- [`batgrep`](doc/batgrep.md) (ripgrep + bat)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
The scripts in this repository are designed to run as-is, provided that they aren't moved around.
|
||||||
|
This means that you're free to just symlink `src/[script].sh` to your local bin folder.
|
||||||
|
|
||||||
|
If you would rather have self-contained scripts that you can place any run anywhere, you can use the `build.sh` script to create (and optionally install) them.
|
||||||
|
|
||||||
|
**Build:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./build.sh [OPTIONS...]
|
||||||
|
```
|
||||||
|
|
||||||
|
This will combine and preprocess each script under the `src` directory, and create corresponding self-contained scripts in the `bin` folder. Any library scripts that are sourced using `source "${LIB}/[NAME].sh"` will be embedded automatically.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**Minification:**
|
||||||
|
|
||||||
|
There are three different options for minification:
|
||||||
|
|
||||||
|
| Option | Description |
|
||||||
|
| --------------- | ---------------------------------------------------- |
|
||||||
|
| `--minify=none` | Nothing will be minified. |
|
||||||
|
| `--minify=lib` | Embedded library scripts will be minified. [default] |
|
||||||
|
| `--minify=all` | Everything will be minified. |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
This uses [bash_minifier](https://github.com/precious/bash_minifier) to perform minification, and requires Python 2 to be installed as either `python2` or `python`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**Installation:**
|
||||||
|
|
||||||
|
You can also specify `--install` and `--prefix=PATH` to have the build script automatically install the scripts for all users on the system. You may need to run the build script as root.
|
||||||
|
|
239
build.sh
Executable file
239
build.sh
Executable file
@ -0,0 +1,239 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# bat-extras | Copyright (C) 2019 eth-p | MIT License
|
||||||
|
#
|
||||||
|
# Repository: https://github.com/eth-p/bat-extras
|
||||||
|
# Issues: https://github.com/eth-p/bat-extras/issues
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
DL="$HERE/.download"
|
||||||
|
BIN="$HERE/bin"
|
||||||
|
SRC="$HERE/src"
|
||||||
|
LIB="$HERE/lib"
|
||||||
|
source "${LIB}/print.sh"
|
||||||
|
source "${LIB}/opt.sh"
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Runs the next build step.
|
||||||
|
#
|
||||||
|
# Arguments:
|
||||||
|
# 1 -- The build step function name.
|
||||||
|
# @ -- The function arguments.
|
||||||
|
#
|
||||||
|
# Input:
|
||||||
|
# The unprocessed file data.
|
||||||
|
#
|
||||||
|
# Output:
|
||||||
|
# The processed file data.
|
||||||
|
next() {
|
||||||
|
local buffer="$(cat)"
|
||||||
|
"$@" <<< "$buffer"
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prints a build step message.
|
||||||
|
smsg() {
|
||||||
|
case "$2" in
|
||||||
|
"SKIP") printc " %{YELLOW} %{DIM}%s [skipped]%{CLEAR}\n" "$1" 1>&2;;
|
||||||
|
*) printc " %{YELLOW} %s...%{CLEAR}\n" "$1" 1>&2;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build step: read
|
||||||
|
# Reads the file from its source.
|
||||||
|
#
|
||||||
|
# Arguments:
|
||||||
|
# 1 -- The source file.
|
||||||
|
#
|
||||||
|
# Output:
|
||||||
|
# The file contents.
|
||||||
|
step_read() {
|
||||||
|
smsg "Reading"
|
||||||
|
cat "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build step: preprocess
|
||||||
|
# Preprocesses the script.
|
||||||
|
#
|
||||||
|
# This will embed library scripts.
|
||||||
|
#
|
||||||
|
# Input:
|
||||||
|
# The original file contents.
|
||||||
|
#
|
||||||
|
# Output:
|
||||||
|
# The processed file contents.
|
||||||
|
step_preprocess() {
|
||||||
|
smsg "Preprocessing"
|
||||||
|
|
||||||
|
local line
|
||||||
|
while IFS='' read -r line; do
|
||||||
|
# Skip certain lines.
|
||||||
|
[[ "$line" =~ ^LIB=.*$ ]] && continue
|
||||||
|
|
||||||
|
# Embed library scripts.
|
||||||
|
if [[ "$line" =~ ^[[:space:]]*source[[:space:]]+[\"\']\$\{?LIB\}/([a-z-]+\.sh)[\"\'] ]]; then
|
||||||
|
echo "# --- BEGIN LIBRARY FILE: ${BASH_REMATCH[1]} ---"
|
||||||
|
cat "$LIB/${BASH_REMATCH[1]}" | {
|
||||||
|
if [[ "$OPT_MINIFY" = "lib" ]]; then
|
||||||
|
pp_strip_comments | pp_minify
|
||||||
|
else
|
||||||
|
cat
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
echo "# --- END LIBRARY FILE ---"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Forward data.
|
||||||
|
echo "$line"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build step: minify
|
||||||
|
# Minifies the output script.
|
||||||
|
#
|
||||||
|
# Input:
|
||||||
|
# The original file contents.
|
||||||
|
#
|
||||||
|
# Output:
|
||||||
|
# The minified file contents.
|
||||||
|
step_minify() {
|
||||||
|
if [[ "$OPT_MINIFY" != "all" ]]; then
|
||||||
|
smsg "Minifying" "SKIP"
|
||||||
|
cat
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
smsg "Minifying"
|
||||||
|
printf "#!/usr/bin/env bash\n"
|
||||||
|
pp_minify
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build step: write
|
||||||
|
# Writes the output script to a file.
|
||||||
|
#
|
||||||
|
# Arguments:
|
||||||
|
# 1 -- The file to write to.
|
||||||
|
#
|
||||||
|
# Input:
|
||||||
|
# The file contents.
|
||||||
|
#
|
||||||
|
# Output:
|
||||||
|
# The file contents.
|
||||||
|
step_write() {
|
||||||
|
smsg "Building"
|
||||||
|
tee "$1"
|
||||||
|
chmod +x "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build step: write
|
||||||
|
# Optionally writes the output script to a file.
|
||||||
|
#
|
||||||
|
# Arguments:
|
||||||
|
# 1 -- The file to write to.
|
||||||
|
#
|
||||||
|
# Input:
|
||||||
|
# The file contents.
|
||||||
|
#
|
||||||
|
# Output:
|
||||||
|
# The file contents.
|
||||||
|
|
||||||
|
step_write_install() {
|
||||||
|
if [[ "$OPT_INSTALL" != true ]]; then
|
||||||
|
smsg "Installing" "SKIP"
|
||||||
|
cat
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
smsg "Installing"
|
||||||
|
tee "$1"
|
||||||
|
chmod +x "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Preprocessor.
|
||||||
|
|
||||||
|
# Strips comments from a Bash source file.
|
||||||
|
pp_strip_comments() {
|
||||||
|
sed '/^[[:space:]]*#.*$/d'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Minify a Bash source file.
|
||||||
|
# https://github.com/precious/bash_minifier
|
||||||
|
pp_minify() {
|
||||||
|
local python="python"
|
||||||
|
if command -v python2 &>/dev/null; then
|
||||||
|
python="python2"
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$python" "$DL/minifier.py"
|
||||||
|
printf "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Options.
|
||||||
|
OPT_INSTALL=false
|
||||||
|
OPT_MINIFY="lib"
|
||||||
|
OPT_PREFIX="/usr/local"
|
||||||
|
|
||||||
|
while shiftopt; do
|
||||||
|
case "$OPT" in
|
||||||
|
--install) OPT_INSTALL=true;;
|
||||||
|
--prefix) shiftval; OPT_PREFIX="$OPT_VAL";;
|
||||||
|
--minify) shiftval; OPT_MINIFY="$OPT_VAL";;
|
||||||
|
|
||||||
|
*) printc "%{RED}%s: unknown option '%s'%{CLEAR}" "$PROGRAM" "$OPT";
|
||||||
|
exit 1;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$OPT_INSTALL" = true ]]; then
|
||||||
|
printc "%{YELLOW}Installing to %{MAGENTA}%s%{YELLOW}.%{CLEAR}\n" "$OPT_PREFIX" 1>&2
|
||||||
|
else
|
||||||
|
printc "%{YELLOW}This will not install the script.%{CLEAR}\n" 1>&2
|
||||||
|
printc "%{YELLOW}Use %{BLUE}--install%{YELLOW} for a global install.%{CLEAR}\n\n" 1>&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Download resources.
|
||||||
|
|
||||||
|
[[ -d "$DL" ]] || mkdir "$DL"
|
||||||
|
[[ -d "$BIN" ]] || mkdir "$BIN"
|
||||||
|
|
||||||
|
if [[ "$OPT_MINIFY" != "none" ]] && ! [[ -f "$DL/minifier.py" ]]; then
|
||||||
|
printc "%{YELLOW}Downloading %{BLUE}https://github.com/precious/bash_minifier%{YELLOW}...%{CLEAR}\n" 1>&2
|
||||||
|
curl -sL "https://gitcdn.xyz/repo/precious/bash_minifier/master/minifier.py" > "$DL/minifier.py"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Find files.
|
||||||
|
|
||||||
|
SOURCES=()
|
||||||
|
|
||||||
|
printc "%{YELLOW}Preparing scripts...%{CLEAR}\n" 1>&2
|
||||||
|
for file in "$SRC"/*.sh; do
|
||||||
|
SOURCES+=("$file")
|
||||||
|
done
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Build files.
|
||||||
|
|
||||||
|
|
||||||
|
printc "%{YELLOW}Building scripts...%{CLEAR}\n" 1>&2
|
||||||
|
file_i=0
|
||||||
|
file_n="${#SOURCES[@]}"
|
||||||
|
for file in "${SOURCES[@]}"; do
|
||||||
|
((file_i++))
|
||||||
|
|
||||||
|
filename="$(basename "$file" .sh)"
|
||||||
|
|
||||||
|
printc " %{YELLOW}[%s/%s] %{MAGENTA}%s%{CLEAR}\n" "$file_i" "$file_n" "$file" 1>&2
|
||||||
|
step_read "$file" |\
|
||||||
|
next step_preprocess |\
|
||||||
|
next step_minify |\
|
||||||
|
next step_write "${BIN}/${filename}" |\
|
||||||
|
next step_write_install "${OPT_PREFIX}/bin/${filename}" |\
|
||||||
|
cat >/dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
|
66
doc/batgrep.md
Normal file
66
doc/batgrep.md
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# bat-extras: batgrep
|
||||||
|
|
||||||
|
A script that combines [ripgrep](https://github.com/burntsushi/ripgrep) with bat's syntax highlighting and output formatting.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Command Line
|
||||||
|
|
||||||
|
**Synopsis:**
|
||||||
|
|
||||||
|
- `batgrep [OPTIONS] PATTERN [PATH...] `
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**Options:**
|
||||||
|
|
||||||
|
| Short | Long | Description |
|
||||||
|
| ----- | -------------------------- | ---------------------------------------------------------- |
|
||||||
|
| `-i` | `--ignore-case` | Use case insensitive searching. |
|
||||||
|
| `-A` | `--after-context=[LINES]` | Display the next *n* lines after a matched line. |
|
||||||
|
| `-B` | `--before-context=[LINES]` | Display the previous `n` lines before a matched line. |
|
||||||
|
| `-C` | `--context=[LINES]` | A combination of `--after-context` and `--before-context`. |
|
||||||
|
| | `--no-follow` | Do not follow symlinks. |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**Options (Passthrough)**:
|
||||||
|
The following options are passed directly to ripgrep, and are not handled by this script.
|
||||||
|
|
||||||
|
| Short | Long | Notes |
|
||||||
|
| ----- | -------------------------- | ------------------------------------------------------------ |
|
||||||
|
| `-F` | `--fixed-strings` | |
|
||||||
|
| `-U` | `--multiline` | |
|
||||||
|
| `-P` | `--pcre2` | |
|
||||||
|
| `-z` | `--search-zip` | |
|
||||||
|
| `-w` | `--word-regexp` | |
|
||||||
|
| | `--one-file-system` | |
|
||||||
|
| | `--multiline-dotall` | |
|
||||||
|
| | `--ignore` / `--no-ignore` | |
|
||||||
|
| | `--crlf` / `--no-crlf` | |
|
||||||
|
| | `--hidden` / `--no-hidden` | |
|
||||||
|
| `-E` | `--encoding` | This is unsupported by `bat`, and may cause issues when trying to display unsupported encodings. |
|
||||||
|
| `-g` | `--glob` | |
|
||||||
|
| `-t` | `--type` | |
|
||||||
|
| `-T` | `--type-not` | |
|
||||||
|
| `-m` | `--max-count` | |
|
||||||
|
| | `--max-depth` | |
|
||||||
|
| | `--iglob` | |
|
||||||
|
| | `--ignore-file` | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Caveats
|
||||||
|
|
||||||
|
**Differences from ripgrep:**
|
||||||
|
|
||||||
|
- `--follow` is enabled by default for `batgrep`.
|
||||||
|
|
||||||
|
- Not all the `ripgrep` options are supported.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Issues?
|
||||||
|
|
||||||
|
If you find an issue or have a feature suggestion, make a pull request or issue through GitHub!
|
||||||
|
Contributions are always welcome.
|
69
lib/opt.sh
Normal file
69
lib/opt.sh
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# bat-extras | Copyright (C) 2019 eth-p | MIT License
|
||||||
|
#
|
||||||
|
# Repository: https://github.com/eth-p/bat-extras
|
||||||
|
# Issues: https://github.com/eth-p/bat-extras/issues
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
PROGRAM="$(basename "${BASH_SOURCE[0]}")"
|
||||||
|
|
||||||
|
# Gets the next option passed to the script.
|
||||||
|
#
|
||||||
|
# Variables:
|
||||||
|
# OPT -- The option name.
|
||||||
|
#
|
||||||
|
# Returns:
|
||||||
|
# 0 -- An option was read.
|
||||||
|
# 1 -- No more options were read.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# while shiftopt; do
|
||||||
|
# shiftval
|
||||||
|
# echo "$OPT = $OPT_VAL"
|
||||||
|
# done
|
||||||
|
shiftopt() {
|
||||||
|
# Ensure _ARGV exists and has the program arguments.
|
||||||
|
if [[ -z ${_ARGV+x} ]]; then
|
||||||
|
_ARGV=("${BASH_ARGV[@]}")
|
||||||
|
_ARGV_INDEX="$((${#_ARGV[@]} - 1))"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Read the top of _ARGV.
|
||||||
|
[[ "$_ARGV_INDEX" -lt 0 ]] && return 1
|
||||||
|
OPT="${_ARGV[$_ARGV_INDEX]}"
|
||||||
|
unset OPT_VAL
|
||||||
|
|
||||||
|
if [[ "$OPT" =~ ^--[a-zA-Z-]+=.* ]]; then
|
||||||
|
OPT_VAL="${OPT#*=}"
|
||||||
|
OPT="${OPT%%=*}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Pop array.
|
||||||
|
((_ARGV_INDEX--))
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Gets the value for the current option.
|
||||||
|
#
|
||||||
|
# Variables:
|
||||||
|
# OPT_VAL -- The option value.
|
||||||
|
#
|
||||||
|
# Returns:
|
||||||
|
# 0 -- An option value was read.
|
||||||
|
# EXIT 1 -- No option value was available.
|
||||||
|
shiftval() {
|
||||||
|
# Skip if a value was already provided.
|
||||||
|
if [[ -z "${ARG_VAL+x}" ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
OPT_VAL="${_ARGV[$_ARGV_INDEX]}"
|
||||||
|
((_ARGV_INDEX--))
|
||||||
|
|
||||||
|
# Error if no value is provided.
|
||||||
|
if [[ "$OPT_VAL" =~ -.* ]]; then
|
||||||
|
printc "%{RED}%s: '%s' requires a value%{CLEAR}\n" "$PROGRAM" "$ARG"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
67
lib/print.sh
Normal file
67
lib/print.sh
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# bat-extras | Copyright (C) 2019 eth-p | MIT License
|
||||||
|
#
|
||||||
|
# Repository: https://github.com/eth-p/bat-extras
|
||||||
|
# Issues: https://github.com/eth-p/bat-extras/issues
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Printf, but with optional colors.
|
||||||
|
# This uses the same syntax and arguments as printf.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# printc "%{RED}This is red %s.%{CLEAR}\n" "text"
|
||||||
|
#
|
||||||
|
printc() {
|
||||||
|
printf "$(sed "$_PRINTC_PATTERN" <<< "$1")" "${@:2}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Initializes the color tags for printc.
|
||||||
|
#
|
||||||
|
# Arguments:
|
||||||
|
# color=on -- Turns on color output.
|
||||||
|
# color=off -- Turns off color output.
|
||||||
|
printc_init() {
|
||||||
|
case "$1" in
|
||||||
|
color=on) _PRINTC_PATTERN="$_PRINTC_PATTERN_ANSI";;
|
||||||
|
color=off) _PRINTC_PATTERN="$_PRINTC_PATTERN_PLAIN";;
|
||||||
|
|
||||||
|
"") {
|
||||||
|
_PRINTC_PATTERN_ANSI=""
|
||||||
|
_PRINTC_PATTERN_PLAIN=""
|
||||||
|
|
||||||
|
local name
|
||||||
|
local ansi
|
||||||
|
while read -r name ansi; do
|
||||||
|
if [[ -z "${name}" && -z "${ansi}" ]] || [[ "${name:0:1}" = "#" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
ansi="$(sed 's/\\/\\\\/' <<< "$ansi")"
|
||||||
|
|
||||||
|
_PRINTC_PATTERN_PLAIN="${_PRINTC_PATTERN_PLAIN}s/%{${name}}//g;"
|
||||||
|
_PRINTC_PATTERN_ANSI="${_PRINTC_PATTERN_ANSI}s/%{${name}}/${ansi}/g;"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -t 1 ]; then
|
||||||
|
_PRINTC_PATTERN="$_PRINTC_PATTERN_ANSI"
|
||||||
|
else
|
||||||
|
_PRINTC_PATTERN="$_PRINTC_PATTERN_PLAIN"
|
||||||
|
fi
|
||||||
|
};;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# Initialization.
|
||||||
|
printc_init <<END
|
||||||
|
CLEAR \x1B[0m
|
||||||
|
RED \x1B[31m
|
||||||
|
GREEN \x1B[32m
|
||||||
|
YELLOW \x1B[33m
|
||||||
|
BLUE \x1B[34m
|
||||||
|
MAGENTA \x1B[35m
|
||||||
|
CYAN \x1B[36m
|
||||||
|
|
||||||
|
DIM \x1B[2m
|
||||||
|
END
|
||||||
|
|
135
src/batgrep.sh
Normal file
135
src/batgrep.sh
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# bat-extras | Copyright (C) 2019 eth-p | MIT License
|
||||||
|
#
|
||||||
|
# Repository: https://github.com/eth-p/bat-extras
|
||||||
|
# Issues: https://github.com/eth-p/bat-extras/issues
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
LIB="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/../lib"
|
||||||
|
source "${LIB}/print.sh"
|
||||||
|
source "${LIB}/opt.sh"
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
SEP="$(printc "%{DIM}%$(tput cols)s%{CLEAR}" | tr ' ' '─')"
|
||||||
|
RG_ARGS=()
|
||||||
|
BAT_ARGS=()
|
||||||
|
PATTERN=
|
||||||
|
FILES=()
|
||||||
|
OPT_CONTEXT_BEFORE=2
|
||||||
|
OPT_CONTEXT_AFTER=2
|
||||||
|
OPT_FOLLOW=true
|
||||||
|
|
||||||
|
# Parse arguments.
|
||||||
|
while shiftopt; do
|
||||||
|
case "$OPT" in
|
||||||
|
|
||||||
|
# Ripgrep Options
|
||||||
|
-i|--ignore-case) RG_ARGS+=("--ignore-case");;
|
||||||
|
-A|--after-context) shiftval; OPT_CONTEXT_AFTER="$OPT_VAL";;
|
||||||
|
-B|--before-context) shiftval; OPT_CONTEXT_BEFORE="$OPT_VAL";;
|
||||||
|
-C|--context) shiftval; OPT_CONTEXT_BEFORE="$OPT_VAL";
|
||||||
|
OPT_CONTEXT_AFTER="$OPT_VAL";;
|
||||||
|
|
||||||
|
-F|--fixed-strings|\
|
||||||
|
-U|--multiline|\
|
||||||
|
-P|--pcre2|\
|
||||||
|
-z|--search-zip|\
|
||||||
|
-w|--word-regexp|\
|
||||||
|
--one-file-system|\
|
||||||
|
--multiline-dotall|\
|
||||||
|
--ignore|--no-ignore|\
|
||||||
|
--crlf|--no-crlf|\
|
||||||
|
--hidden|--no-hidden) RG_ARGS+=("$OPT");;
|
||||||
|
|
||||||
|
-E|--encoding|\
|
||||||
|
-g|--glob|\
|
||||||
|
-t|--type|\
|
||||||
|
-T|--type-not|\
|
||||||
|
-m|--max-count|\
|
||||||
|
--max-depth|\
|
||||||
|
--iglob|\
|
||||||
|
--ignore-file) shiftval; RG_ARGS+=("$OPT" "$OPT_VAL");;
|
||||||
|
|
||||||
|
# Bat Options
|
||||||
|
|
||||||
|
# Script Options
|
||||||
|
--no-follow) OPT_FOLLOW=false;;
|
||||||
|
|
||||||
|
# ???
|
||||||
|
-*) {
|
||||||
|
printc "%{RED}%s: unknown option '%s'%{CLEAR}\n" "$PROGRAM" "$OPT" 1>&2
|
||||||
|
exit 1
|
||||||
|
};;
|
||||||
|
|
||||||
|
# Search
|
||||||
|
*) {
|
||||||
|
if [ -z "$PATTERN" ]; then
|
||||||
|
PATTERN="$OPT"
|
||||||
|
else
|
||||||
|
FILES+=("$OPT")
|
||||||
|
fi
|
||||||
|
};;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -z "$PATTERN" ]]; then
|
||||||
|
printc "%{RED}%s: no pattern provided%{CLEAR}\n" "$PROGRAM" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if "$OPT_FOLLOW"; then
|
||||||
|
RG_ARGS+=("--follow")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Invoke ripgrep.
|
||||||
|
FOUND_FILES=()
|
||||||
|
FOUND=0
|
||||||
|
FIRST_PRINT=true
|
||||||
|
LAST_LR=()
|
||||||
|
LAST_LH=()
|
||||||
|
LAST_FILE=''
|
||||||
|
|
||||||
|
do_print() {
|
||||||
|
[[ -z "$LAST_FILE" ]] && return 0
|
||||||
|
|
||||||
|
# Print the separator.
|
||||||
|
"$FIRST_PRINT" && echo "$SEP"
|
||||||
|
FIRST_PRINT=false
|
||||||
|
|
||||||
|
# Print the file.
|
||||||
|
unset LAST_LR[0]
|
||||||
|
unset LAST_LH[0]
|
||||||
|
bat "${BAT_ARGS[@]}" \
|
||||||
|
"${LAST_LR[@]}" \
|
||||||
|
"${LAST_LH[@]}" \
|
||||||
|
--style="header,numbers" \
|
||||||
|
"$LAST_FILE"
|
||||||
|
|
||||||
|
# Print the separator.
|
||||||
|
echo "$SEP"
|
||||||
|
}
|
||||||
|
|
||||||
|
while IFS=':' read -r file line column; do
|
||||||
|
((FOUND++))
|
||||||
|
|
||||||
|
if [[ "$LAST_FILE" != "$file" ]]; then
|
||||||
|
do_print
|
||||||
|
LAST_FILE="$file"
|
||||||
|
LAST_LR=''
|
||||||
|
LAST_LH=''
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Calculate the context line numbers.
|
||||||
|
line_start=$((line - OPT_CONTEXT_BEFORE))
|
||||||
|
line_end=$((line + OPT_CONTEXT_AFTER))
|
||||||
|
[[ "$line_start" -gt 0 ]] || line_start=''
|
||||||
|
|
||||||
|
LAST_LR+=("--line-range=${line_start}:${line_end}")
|
||||||
|
LAST_LH+=("--highlight-line=${line}")
|
||||||
|
done < <(rg --with-filename --vimgrep "${RG_ARGS[@]}" --sort path "$PATTERN" "${FILES[@]}")
|
||||||
|
do_print
|
||||||
|
|
||||||
|
# Exit.
|
||||||
|
if [[ "$FOUND" -eq 0 ]]; then
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
Loading…
Reference in New Issue
Block a user