#!/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 . 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 " or to select next line" >&2 echo " or to select prev line" >&2 echo " to use selected line as query" >&2 echo " to open qalc in interactive mode" >&2 echo " or to exit iqalc entirely" >&2 echo " to clear current query" >&2 echo " to delete character" >&2 echo "" >&2 echo "qalc interactive mode keybindings:" >&2 echo " to select next history item" >&2 echo " to select prev history item" >&2 echo " to exit back to fzf" >&2 echo " 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 "$@"