Skip to content

Instantly share code, notes, and snippets.

@b0o
Created June 6, 2020 19:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save b0o/a9c647d3ce7d04edd54f40b5cf935f10 to your computer and use it in GitHub Desktop.
Save b0o/a9c647d3ce7d04edd54f40b5cf935f10 to your computer and use it in GitHub Desktop.
#!/bin/bash
# iqalc = fzf + qalc ^ love
#
# (c) 2020 Maddison Hellstrom (github.com/b0o)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
set -euo pipefail
declare -g prog="${BASH_SOURCE[0]}"
declare -g hist="${XDG_CONFIG_HOME:-$HOME/.config}/qalculate/qalc.history"
declare -g flag_interactive
flag_interactive="$(mktemp -u "${XDG_CONFIG_HOME:-$HOME/.config}/qalculate/qalc-i-flag_XXXXXX")"
trap 'rm $flag_interactive &>/dev/null || true' EXIT
function run_fzf() {
local -i interactive=0
local -a res
local _res
_res="$(
fzf --tac --no-sort --print-query --query="$*" \
--bind 'ctrl-d:delete-char,ctrl-c:clear-query,ctrl-o:replace-query,ctrl-i:execute(printf "%s\n" {q} {..} > '"$flag_interactive"')+abort' \
--preview-window=down --preview "$prog"' -q {q} {..}' < "$hist"
)"
local c=$?
[[ $c -le 1 ]] || {
if [[ -f "$flag_interactive" ]]; then
interactive=1
mapfile -t res < "$flag_interactive"
rm "$flag_interactive"
else
return $c
fi
}
[[ -v res ]] || mapfile -t res <<< "$_res"
[[ ${#res[@]} -ge 1 ]] || return 0
local expr="${res[0]}"
if [[ -z "$expr" && ${#res[@]} -ge 2 ]]; then
expr="${res[1]}"
fi
echo "$expr"
echo "$expr" >> "$hist"
if [[ $interactive -eq 1 ]]; then
run_qalc -i "$expr" "$expr"
return 0
fi
}
function run_qalc() {
local -a qalc_opts=()
local -i OPTIND
local OPTARG opt
while getopts "i" opt "$@"; do
case "$opt" in
i)
qalc_opts+=(-i)
;;
\?)
return 1
;;
esac
done
shift $((OPTIND - 1))
# [[ $# -eq 2 ]] || {
# echo "-q: expected 2 arguments, got $#" >&2
# return 1
# }
local -a expr=()
if [[ $# -eq 1 && -n "$1" ]]; then
expr=("$1")
elif [[ $# -eq 2 ]]; then
expr=("$2")
if [[ -n $1 ]]; then
expr=("$1")
fi
fi
qalc "${qalc_opts[@]}" "${expr[@]}"
}
function main() {
local fn=(run_fzf)
local -i repeat=1
local -i OPTIND
local OPTARG opt
while getopts "hqQ1" opt "$@"; do
case "$opt" in
h)
echo "usage: $(basename "$prog") [-h] [-1] [expr]" >&2
echo "" >&2
echo "fzf keybindings:" >&2
echo " <C-n> or <C-j> to select next line" >&2
echo " <C-p> or <C-k> to select prev line" >&2
echo " <C-o> to use selected line as query" >&2
echo " <C-i> to open qalc in interactive mode" >&2
echo " <C-q> or <C-g> to exit iqalc entirely" >&2
echo " <C-c> to clear current query" >&2
echo " <C-d> to delete character" >&2
echo "" >&2
echo "qalc interactive mode keybindings:" >&2
echo " <C-n> to select next history item" >&2
echo " <C-p> to select prev history item" >&2
echo " <C-d> to exit back to fzf" >&2
echo " <C-c> to exit iqalc entirely" >&2
return 0
;;
q)
repeat=0
fn=(run_qalc)
;;
Q)
repeat=0
fn=(run_qalc -i)
;;
1)
repeat=0
;;
\?)
exit 1
;;
esac
done
shift $((OPTIND - 1))
while "${fn[@]}" "$@"; do
[[ $repeat -eq 1 ]] || return 0
[[ $# -eq 0 ]] || shift $#
done
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment