summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfilip <“filip.rabiega@gmail.com”>2026-01-18 11:44:26 +0100
committerfilip <“filip.rabiega@gmail.com”>2026-01-18 11:44:26 +0100
commit83954961af8b6337da100e038561f2fd975ac1fe (patch)
tree33a45dbf91cc4c0b8975287b9537db8aa272505f
parentafd02bfcce54e3252d356f34c25a155c855f3612 (diff)
downloadchadscripts-83954961af8b6337da100e038561f2fd975ac1fe.tar.gz
chadscripts-83954961af8b6337da100e038561f2fd975ac1fe.tar.bz2
chadscripts-83954961af8b6337da100e038561f2fd975ac1fe.zip
huge changesHEADmaster
-rwxr-xr-xaskpass6
-rwxr-xr-xbatterylow14
-rwxr-xr-xbmks52
-rwxr-xr-xbrightness7
-rwxr-xr-xcht.sh823
-rwxr-xr-xdbdb2
-rwxr-xr-xdictloop18
-rwxr-xr-xdmenu-translate150
-rwxr-xr-xdpass5
-rwxr-xr-xdtrans146
-rwxr-xr-xdz-feed7
-rwxr-xr-xechovol10
-rwxr-xr-xengadd3
-rwxr-xr-xextract_pdfs33
-rwxr-xr-xinpath50
-rwxr-xr-xlogrm8
-rwxr-xr-xlsn4
-rwxr-xr-xmaimpick2
-rwxr-xr-xmounter119
-rwxr-xr-xnewnote22
-rwxr-xr-xnewscript26
-rwxr-xr-xremaps2
-rwxr-xr-xrmw16
-rwxr-xr-xrotdir12
-rwxr-xr-xrssadd4
-rwxr-xr-xrssget117
-rwxr-xr-xsaferm30
-rwxr-xr-xscan6
-rwxr-xr-xsysact36
-rwxr-xr-xtodo16
-rwxr-xr-xtst3
-rwxr-xr-xunix4
-rwxr-xr-xvia18
-rwxr-xr-xvia-feed15
-rwxr-xr-xvia-menu2
-rwxr-xr-xvia-open100
-rwxr-xr-xviaup7
-rwxr-xr-xvolume8
-rwxr-xr-xwrocwttr10
39 files changed, 1591 insertions, 322 deletions
diff --git a/askpass b/askpass
new file mode 100755
index 0000000..2c14e6f
--- /dev/null
+++ b/askpass
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# This script is the SUDO_ASKPASS variable, meaning that it will be used as a
+# password prompt if needed.
+
+dmenu -fn Monospace-18 -P -p "$1" <&- && echo
diff --git a/batterylow b/batterylow
new file mode 100755
index 0000000..cf081d1
--- /dev/null
+++ b/batterylow
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+# those variables may be unnecessary
+export DISPLAY=:0
+export HOME=/home/filipek
+
+percentage=$(upower -i "$(upower -e | grep BAT)" |
+ awk '/percentage/ {gsub(/%/, "", $2); print $2}')
+
+if [ "$percentage" -le 5 ]; then
+ notify-send "Battery very low."
+elif [ "$percentage" -ge 14 ] && [ "$percentage" -le 15 ]; then
+ notify-send "Battery low."
+fi
diff --git a/bmks b/bmks
index 45bd38e..1239e7c 100755
--- a/bmks
+++ b/bmks
@@ -10,7 +10,7 @@ URL_FILE_PATH="$HOME/.config/bmks"
URL_FILE_NAME="urls"
show_usage() {
- printf "bmks: unix bookmark management that sucks less
+ printf "bmks: unix bookmark management that sucks less
usage:
bmks help
@@ -32,47 +32,47 @@ If you would prefer to have your bookmarks stored in alternate location there ar
}
bmks_add() {
- [ -z "$url" ] && printf "Error: url must be provided\n\n" && show_usage && exit 0
- printf "Description: "
- read -r description
- [ -z "$description" ] && echo "$url" >> $URL_FILE_PATH/$URL_FILE_NAME
- [ -n "$description" ] && echo "$description - $url" >> $URL_FILE_PATH/$URL_FILE_NAME
+ [ -z "$url" ] && printf "Error: url must be provided\n\n" && show_usage && exit 0
+ printf "Description: "
+ read -r description
+ [ -z "$description" ] && echo "$url" >> $URL_FILE_PATH/$URL_FILE_NAME
+ [ -n "$description" ] && echo "$description - $url" >> $URL_FILE_PATH/$URL_FILE_NAME
}
bmks_ls() {
- bmks_check
- cat $URL_FILE_PATH/$URL_FILE_NAME | sort
+ bmks_check
+ cat $URL_FILE_PATH/$URL_FILE_NAME | sort
}
bmks_del() {
- bmks_check
- case $PREFERED_LAUNCHER in
- dmenu) sed -i "/$(cat $URL_FILE_PATH/$URL_FILE_NAME | sort | dmenu -i -l 15 )/d" $URL_FILE_PATH/$URL_FILE_NAME ;;
- fzf) sed -i "/$(cat $URL_FILE_PATH/$URL_FILE_NAME | sort | fzf)/d" $URL_FILE_PATH/$URL_FILE_NAME ;;
- esac
+ bmks_check
+ case $PREFERED_LAUNCHER in
+ dmenu) sed -i "/$(cat $URL_FILE_PATH/$URL_FILE_NAME | sort | dmenu -i -l 15 )/d" $URL_FILE_PATH/$URL_FILE_NAME ;;
+ fzf) sed -i "/$(cat $URL_FILE_PATH/$URL_FILE_NAME | sort | fzf)/d" $URL_FILE_PATH/$URL_FILE_NAME ;;
+ esac
}
bmks_display() {
- bmks_check
- case $PREFERED_LAUNCHER in
- dmenu) cat $URL_FILE_PATH/$URL_FILE_NAME | sort | dmenu -i -l 15 | awk '{print $(NF)}' | xargs -I '{}' $BROWSER {} ;;
- fzf) cat $URL_FILE_PATH/$URL_FILE_NAME | sort | fzf | awk '{print $(NF)}' | xargs -I '{}' $BROWSER {} ;;
- esac
+ bmks_check
+ case $PREFERED_LAUNCHER in
+ dmenu) cat $URL_FILE_PATH/$URL_FILE_NAME | sort | dmenu -i -l 15 | awk '{print $(NF)}' | xargs -I '{}' $BROWSER {} ;;
+ fzf) cat $URL_FILE_PATH/$URL_FILE_NAME | sort | fzf | awk '{print $(NF)}' | xargs -I '{}' $BROWSER {} ;;
+ esac
}
bmks_check() {
- [ ! -s $URL_FILE_PATH/$URL_FILE_NAME ] && printf "Error: No bookmarks found to display. Try adding some!\n\n" && show_usage && exit 0
+ [ ! -s $URL_FILE_PATH/$URL_FILE_NAME ] && printf "Error: No bookmarks found to display. Try adding some!\n\n" && show_usage && exit 0
}
[ ! -d $URL_FILE_PATH ] && mkdir $URL_FILE_PATH
[ ! -f $URL_FILE_PATH/$URL_FILE_NAME ] && touch $URL_FILE_PATH/$URL_FILE_NAME
case "$1" in
- "help") show_usage ;;
- "add") url=$2; bmks_add ;;
- "del") bmks_del ;;
- "ls") bmks_ls ;;
- "dmenu") PREFERED_LAUNCHER=$1; bmks_display ;;
- "fzf") PREFERED_LAUNCHER=$1; bmks_display ;;
- *) bmks_display ;;
+ "help") show_usage ;;
+"add") url=$2; bmks_add ;;
+"del") bmks_del ;;
+"ls") bmks_ls ;;
+"dmenu") PREFERED_LAUNCHER=$1; bmks_display ;;
+"fzf") PREFERED_LAUNCHER=$1; bmks_display ;;
+*) bmks_display ;;
esac
diff --git a/brightness b/brightness
index 8835859..fc152f3 100755
--- a/brightness
+++ b/brightness
@@ -1,5 +1,6 @@
#!/bin/sh
-monitor="eDP-1"
-
-xrandr --output $monitor --brightness "$1"
+case "$1" in
+ up) sudo brightnessctl s "10%+" ;;
+ down) sudo brightnessctl s "10%-" ;;
+esac
diff --git a/cht.sh b/cht.sh
new file mode 100755
index 0000000..f3d2bc0
--- /dev/null
+++ b/cht.sh
@@ -0,0 +1,823 @@
+#!/bin/bash
+# shellcheck disable=SC1117,SC2001
+#
+# [X] open section
+# [X] one shot mode
+# [X] usage info
+# [X] dependencies check
+# [X] help
+# [X] yank/y/copy/c
+# [X] Y/C
+# [X] eof problem
+# [X] more
+# [X] stealth mode
+#
+# here are several examples for the stealth mode:
+#
+# zip lists
+# list permutation
+# random list element
+# reverse a list
+# read json from file
+# append string to a file
+# run process in background
+# count words in text counter
+# group elements list
+
+__CHTSH_VERSION=0.0.4
+__CHTSH_DATETIME="2021-04-25 12:30:30 +0200"
+
+# cht.sh configuration loading
+#
+# configuration is stored in ~/.cht.sh/ (can be overridden with CHTSH env var.)
+#
+CHTSH_HOME=${CHTSH:-"$HOME"/.cht.sh}
+[ -z "$CHTSH_CONF" ] && CHTSH_CONF=$CHTSH_HOME/cht.sh.conf
+# shellcheck disable=SC1090,SC2002
+[ -e "$CHTSH_CONF" ] && source "$CHTSH_CONF"
+[ -z "$CHTSH_URL" ] && CHTSH_URL=https://cht.sh
+
+# currently we support only two modes:
+# * lite = access the server using curl
+# * auto = try standalone usage first
+CHTSH_MODE="$(cat "$CHTSH_HOME"/mode 2>/dev/null)"
+[ "$CHTSH_MODE" != lite ] && CHTSH_MODE=auto
+CHEATSH_INSTALLATION="$(cat "$CHTSH_HOME/standalone" 2>/dev/null)"
+
+export LESSSECURE=1
+STEALTH_MAX_SELECTION_LENGTH=5
+
+case "$(uname -s)" in
+ Darwin) is_macos=yes ;;
+ *) is_macos=no ;;
+esac
+
+# for KSH93
+# shellcheck disable=SC2034,SC2039,SC2168
+if echo "$KSH_VERSION" | grep -q ' 93' && ! local foo 2>/dev/null; then
+ alias local=typeset
+fi
+
+fatal() {
+ echo "ERROR: $*" >&2
+ exit 1
+}
+
+_say_what_i_do() {
+ [ -n "$LOG" ] && echo "$(date '+[%Y-%m-%d %H:%M%S]') $*" >>"$LOG"
+
+ local this_prompt="\033[0;1;4;32m>>\033[0m"
+ printf "\n${this_prompt}%s\033[0m\n" " $* "
+}
+
+cheatsh_standalone_install() {
+ # the function installs cheat.sh with the upstream repositories
+ # in the standalone mode
+ local installdir
+ installdir="$1"
+ local default_installdir="$HOME/.cheat.sh"
+
+ [ -z "$installdir" ] && installdir=${default_installdir}
+
+ if [ "$installdir" = help ]; then
+ cat <<EOF
+Install cheat.sh in the standalone mode.
+
+After the installation, cheat.sh can be used locally, without accessing
+the public cheat.sh service, or it can be used in the server mode,
+where the newly installed server could be accessed by external clients
+in the same fashion as the public cheat.sh server.
+
+During the installation, cheat.sh code as well as the cheat.sh upstream
+cheat sheets repositories will be fetched.
+
+It takes approximately 1G of the disk space.
+
+Default installation location: ~/.cheat.sh/
+It can be overridden by a command line parameter to this script:
+
+ ${0##*/} --standalone-install DIR
+
+See cheat.sh/:standalone or https://github.com/chubin/cheat.sh/README.md
+for more information:
+
+ cht.sh :standalone
+ curl cheat.sh/:standalone
+
+After the installation is finished, the cht.sh shell client is switched
+to the auto mode, where it uses the local cheat.sh installation if possible.
+You can switch the mode with the --mode switch:
+
+ cht.sh --mode lite # use https://cheat.sh/ only
+ cht.sh --mode auto # use local installation
+
+For intallation and standalone usage, you need \`git\`, \`python\`,
+and \`virtualenv\` to be installed locally.
+EOF
+ return
+ fi
+
+ local _exit_code=0
+
+ local dependencies=(python git virtualenv)
+ for dep in "${dependencies[@]}"; do
+ command -v "$dep" >/dev/null ||
+ {
+ echo "DEPENDENCY: \"$dep\" is needed to install cheat.sh in the standalone mode" >&2
+ _exit_code=1
+ }
+ done
+ [ "$_exit_code" -ne 0 ] && return "$_exit_code"
+
+ while true; do
+ local _installdir
+ echo -n "Where should cheat.sh be installed [$installdir]? "
+ read -r _installdir
+ [ -n "$_installdir" ] && installdir=$_installdir
+
+ if [ "$installdir" = y ] ||
+ [ "$installdir" = Y ] ||
+ [ "$(echo "$installdir" | tr "[:upper:]" "[:lower:]")" = yes ]; then
+ echo Please enter the directory name
+ echo If it was the directory name already, please prepend it with \"./\": "./$installdir"
+ else
+ break
+ fi
+ done
+
+ if [ -e "$installdir" ]; then
+ echo "ERROR: Installation directory [$installdir] exists already"
+ echo "Please remove it first before continuing"
+ return 1
+ fi
+
+ if ! mkdir -p "$installdir"; then
+ echo "ERROR: Could not create the installation directory \"$installdir\""
+ echo "ERROR: Please check the permissions and start the script again"
+ return 1
+ fi
+
+ local space_needed=700
+ local space_available
+ space_available=$(($(df -k "$installdir" | awk '{print $4}' | tail -1) / 1024))
+
+ if [ "$space_available" -lt "$space_needed" ]; then
+ echo "ERROR: Installation directory has no enough space (needed: ${space_needed}M, available: ${space_available}M"
+ echo "ERROR: Please clean up and start the script again"
+ rmdir "$installdir"
+ return 1
+ fi
+
+ _say_what_i_do Cloning cheat.sh locally
+ local url=https://github.com/chubin/cheat.sh
+ rmdir "$installdir"
+ git clone "$url" "$installdir" || fatal Could not clone "$url" with git into "$installdir"
+ cd "$installdir" || fatal "Cannot cd into $installdir"
+
+ # after the repository cloned, we may have the log directory
+ # and we can write our installation log into it
+ mkdir -p "log/"
+ LOG="$PWD/log/install.log"
+
+ # we use tee everywhere so we should set -o pipefail
+ set -o pipefail
+
+ # currently the script uses python 2,
+ # but cheat.sh supports python 3 too
+ # if you want to switch it to python 3
+ # set PYTHON2 to NO:
+ # PYTHON2=NO
+ #
+ PYTHON2=NO
+ if [[ $PYTHON2 == YES ]]; then
+ python="python2"
+ pip="pip"
+ virtualenv_python3_option=()
+ else
+ python="python3"
+ pip="pip3"
+ virtualenv_python3_option=(-p python3)
+ fi
+
+ _say_what_i_do Creating virtual environment
+ virtualenv "${virtualenv_python3_option[@]}" ve ||
+ fatal "Could not create virtual environment with 'virtualenv ve'"
+
+ export CHEATSH_PATH_WORKDIR=$PWD
+
+ # rapidfuzz does not support Python 2,
+ # so if we are using Python 2, install fuzzywuzzy instead
+ if [[ $PYTHON2 == YES ]]; then
+ sed -i s/rapidfuzz/fuzzywuzzy/ requirements.txt
+ echo "python-Levenshtein" >>requirements.txt
+ fi
+
+ _say_what_i_do Installing python requirements into the virtual environment
+ ve/bin/"$pip" install -r requirements.txt >"$LOG" ||
+ {
+
+ echo "ERROR:"
+ echo "---"
+ tail -n 10 "$LOG"
+ echo "---"
+ echo "See $LOG for more"
+ fatal Could not install python dependencies into the virtual environment
+ }
+ echo "$(ve/bin/"$pip" freeze | wc -l) dependencies were successfully installed"
+
+ _say_what_i_do Fetching the upstream cheat sheets repositories
+ ve/bin/python lib/fetch.py fetch-all | tee -a "$LOG"
+
+ _say_what_i_do Running self-tests
+ (
+ cd tests || exit
+
+ if CHEATSH_TEST_STANDALONE=YES \
+ CHEATSH_TEST_SKIP_ONLINE=NO \
+ CHEATSH_TEST_SHOW_DETAILS=NO \
+ PYTHON=../ve/bin/python bash run-tests.sh | tee -a "$LOG"; then
+ printf "\033[0;32m%s\033[0m\n" "SUCCESS"
+ else
+ printf "\033[0;31m%s\033[0m\n" "FAILED"
+ echo "Some tests were failed. Run the tests manually for further investigation:"
+ echo " cd $PWD; bash run-tests.sh)"
+ fi
+ )
+
+ mkdir -p "$CHTSH_HOME"
+ echo "$installdir" >"$CHTSH_HOME/standalone"
+ echo auto >"$CHTSH_HOME/mode"
+
+ _say_what_i_do Done
+
+ local v1
+ v1=$(printf "\033[0;1;32m")
+ local v2
+ v2=$(printf "\033[0m")
+
+ cat <<EOF | sed "s/{/$v1/; s/}/$v2/"
+
+{ _ }
+{ \\ \\ } The installation is successfully finished.
+{ \\ \\ }
+{ / / } Now you can use cheat.sh in the standalone mode,
+{ /_/ } or you can start your own cheat.sh server.
+
+
+Now the cht.sh shell client is switched to the auto mode, where it uses
+the local cheat.sh installation if possible.
+You can switch the mode with the --mode switch:
+
+ cht.sh --mode lite # use https://cheat.sh/ only
+ cht.sh --mode auto # use local installation
+
+You can add your own cheat sheets repository (config is in \`etc/config.yaml\`),
+or create new cheat sheets adapters (in \`lib/adapters\`).
+
+To update local copies of cheat sheets repositores on a regular basis,
+add the following line to your user crontab (crontab -e):
+
+ 10 * * * * $installdir/ve/bin/python $installdir/lib/fetch.py update-all
+
+All cheat sheets will be automatically actualized each hour.
+
+If you are running a server reachable from the Internet, it can be instantly
+notified via a HTTP request about any cheat sheets changes. For that, please
+open an issue on the cheat.sh project repository [github.com/chubin/cheat.sh]
+with the ENTRY-POINT from the URL https://ENTRY-POINT/:actualize specified
+EOF
+}
+
+chtsh_mode() {
+ local mode="$1"
+
+ local text
+ text=$(
+ echo " auto use the standalone installation first"
+ echo " lite use the cheat sheets server directly"
+ )
+
+ if [ -z "$mode" ]; then
+ echo "current mode: $CHTSH_MODE ($(printf "%s" "$text" | grep "$CHTSH_MODE" | sed "s/$CHTSH_MODE//; s/^ *//; s/ \+/ /"))"
+ if [ -d "$CHEATSH_INSTALLATION" ]; then
+ echo "cheat.sh standalone installation: $CHEATSH_INSTALLATION"
+ else
+ echo 'cheat.sh standalone installation not found; falling back to the "lite" mode'
+ fi
+ elif [ "$mode" = auto ] || [ "$mode" = lite ]; then
+ if [ "$mode" = "$CHTSH_MODE" ]; then
+ echo "The configured mode was \"$CHTSH_MODE\"; nothing changed"
+ else
+ mkdir -p "$CHTSH_HOME"
+ echo "$mode" >"$CHTSH_HOME/mode"
+ echo "Configured mode: $mode"
+ fi
+ else
+ echo "Unknown mode: $mode"
+ echo Supported modes:
+ echo " auto use the standalone installation first"
+ echo " lite use the cheat sheets server directly"
+ fi
+}
+
+get_query_options() {
+ local query="$*"
+ if [ -n "$CHTSH_QUERY_OPTIONS" ]; then
+ case $query in
+ *\?*) query="$query&${CHTSH_QUERY_OPTIONS}" ;;
+ *) query="$query?${CHTSH_QUERY_OPTIONS}" ;;
+ esac
+ fi
+ printf "%s" "$query"
+}
+
+do_query() {
+ local query="$*"
+ local b_opts=
+ local uri="${CHTSH_URL}/\"\$(get_query_options $query)\""
+
+ if [ -e "$CHTSH_HOME/id" ]; then
+ b_opts='-b "$CHTSH_HOME/id"'
+ fi
+
+ eval curl "$b_opts" -s "$uri" >"$TMP1"
+
+ if [ -z "$lines" ] || [ "$(wc -l "$TMP1" | awk '{print $1}')" -lt "$lines" ]; then
+ cat "$TMP1"
+ else
+ ${PAGER:-$defpager} "$TMP1"
+ fi
+}
+
+prepare_query() {
+ local section="$1"
+ shift
+ local input="$1"
+ shift
+ local arguments="$1"
+
+ local query
+ if [ -z "$section" ] || [ x"${input}" != x"${input#/}" ]; then
+ query=$(printf %s "$input" | sed 's@ @/@; s@ @+@g')
+ else
+ query=$(printf %s "$section/$input" | sed 's@ @+@g')
+ fi
+
+ [ -n "$arguments" ] && arguments="?$arguments"
+ printf %s "$query$arguments"
+}
+
+get_list_of_sections() {
+ curl -s "${CHTSH_URL}"/:list | grep -v '/.*/' | grep '/$' | xargs
+}
+
+gen_random_str() (
+ len=$1
+ if command -v openssl >/dev/null; then
+ openssl rand -base64 $((len * 3 / 4)) | awk -v ORS='' //
+ else
+ rdev=/dev/urandom
+ for d in /dev/{srandom,random,arandom}; do
+ test -r "$d" && rdev=$d
+ done
+ if command -v hexdump >/dev/null; then
+ hexdump -vn $((len / 2)) -e '1/1 "%02X" 1 ""' "$rdev"
+ elif command -v xxd >/dev/null; then
+ xxd -l $((len / 2)) -ps "$rdev" | awk -v ORS='' //
+ else
+ cd /tmp || {
+ echo Cannot cd into /tmp >&2
+ exit 1
+ }
+ s=
+ # shellcheck disable=SC2000
+ while [ "$(echo "$s" | wc -c)" -lt "$len" ]; do
+ s="$s$(mktemp -u XXXXXXXXXX)"
+ done
+ printf "%.${len}s" "$s"
+ fi
+ fi
+)
+
+if [ "$CHTSH_MODE" = auto ] && [ -d "$CHEATSH_INSTALLATION" ]; then
+ curl() {
+ # ignoring all options
+ # currently the standalone.py does not support them anyway
+ local opt
+ while getopts "b:s" opt; do
+ :
+ done
+ shift $((OPTIND - 1))
+
+ local url
+ url="$1"
+ shift
+ PYTHONIOENCODING=UTF-8 "$CHEATSH_INSTALLATION/ve/bin/python" "$CHEATSH_INSTALLATION/lib/standalone.py" "${url#"$CHTSH_URL"}" "$@"
+ }
+elif [ "$(uname -s)" = OpenBSD ] && [ -x /usr/bin/ftp ]; then
+ # any better test not involving either OS matching or actual query?
+ curl() {
+ local opt args="-o -"
+ while getopts "b:s" opt; do
+ case $opt in
+ b) args="$args -c $OPTARG" ;;
+ s) args="$args -M -V" ;;
+ *)
+ echo "internal error: unsupported cURL option '$opt'" >&2
+ exit 1
+ ;;
+ esac
+ done
+ shift $((OPTIND - 1))
+ /usr/bin/ftp "$args" "$@"
+ }
+else
+ command -v curl >/dev/null || {
+ echo 'DEPENDENCY: install "curl" to use cht.sh' >&2
+ exit 1
+ }
+ _CURL=$(command -v curl)
+ if [ x"$CHTSH_CURL_OPTIONS" != x ]; then
+ curl() {
+ $_CURL "${CHTSH_CURL_OPTIONS}" "$@"
+ }
+ fi
+fi
+
+if [ "$1" = --read ]; then
+ read -r a || a="exit"
+ printf "%s\n" "$a"
+ exit 0
+elif [ x"$1" = x--help ] || [ -z "$1" ]; then
+
+ n=${0##*/}
+ s=$(echo "$n" | sed "s/./ /"g)
+
+ cat <<EOF
+Usage:
+
+ $n [OPTIONS|QUERY]
+
+Options:
+
+ QUERY process QUERY and exit
+
+ --help show this help
+ --shell [LANG] shell mode (open LANG if specified)
+
+ --standalone-install [DIR|help]
+ install cheat.sh in the standalone mode
+ (by default, into ~/.cheat.sh/)
+
+ --mode [auto|lite] set (or display) mode of operation
+ * auto - prefer the local installation
+ * lite - use the cheat sheet server
+
+EOF
+ exit 0
+elif [ x"$1" = x--shell ]; then
+ shell_mode=yes
+ shift
+elif [ x"$1" = x--standalone-install ]; then
+ shift
+ cheatsh_standalone_install "$@"
+ exit "$?"
+elif [ x"$1" = x--mode ]; then
+ shift
+ chtsh_mode "$@"
+ exit "$?"
+fi
+
+prompt="cht.sh"
+opts=""
+input=""
+for o; do
+ if [ x"$o" != x"${o#-}" ]; then
+ opts="${opts}${o#-}"
+ else
+ input="$input $o"
+ fi
+done
+query=$(echo "$input" | sed 's@ *$@@; s@^ *@@; s@ @/@; s@ @+@g')
+
+if [ "$shell_mode" != yes ]; then
+ curl -s "${CHTSH_URL}"/"$(get_query_options "$query")"
+ exit 0
+else
+ new_section="$1"
+ valid_sections=$(get_list_of_sections)
+ valid=no
+ for q in $valid_sections; do [ "$q" = "$new_section/" ] && {
+ valid=yes
+ break
+ }; done
+
+ if [ "$valid" = yes ]; then
+ section="$new_section"
+ # shellcheck disable=SC2001
+ this_query="$(echo "$input" | sed 's@ *[^ ]* *@@')"
+ this_prompt="\033[0;32mcht.sh/$section>\033[0m "
+ else
+ this_query="$input"
+ this_prompt="\033[0;32mcht.sh>\033[0m "
+ fi
+ if [ -n "$this_query" ] && [ -z "$CHEATSH_RESTART" ]; then
+ printf "$this_prompt$this_query\n"
+ curl -s "${CHTSH_URL}"/"$(get_query_options "$query")"
+ fi
+fi
+
+if [ "$is_macos" != yes ]; then
+ if [ "$XDG_SESSION_TYPE" = wayland ]; then
+ command -v wl-copy >/dev/null || echo 'DEPENDENCY: please install "wl-copy" for "copy"' >&2
+ else
+ command -v xsel >/dev/null || echo 'DEPENDENCY: please install "xsel" for "copy"' >&2
+ fi
+fi
+command -v rlwrap >/dev/null || {
+ echo 'DEPENDENCY: install "rlwrap" to use cht.sh in the shell mode' >&2
+ exit 1
+}
+
+mkdir -p "$CHTSH_HOME/"
+lines=$(tput lines)
+
+if command -v less >/dev/null; then
+ defpager="less -R"
+elif command -v more >/dev/null; then
+ defpager="more"
+else
+ defpager="cat"
+fi
+
+cmd_cd() {
+ if [ $# -eq 0 ]; then
+ section=""
+ else
+ new_section=$(echo "$input" | sed 's/cd *//; s@/*$@@; s@^/*@@')
+ if [ -z "$new_section" ] || [ ".." = "$new_section" ]; then
+ section=""
+ else
+ valid_sections=$(get_list_of_sections)
+ valid=no
+ for q in $valid_sections; do [ "$q" = "$new_section/" ] && {
+ valid=yes
+ break
+ }; done
+ if [ "$valid" = no ]; then
+ echo "Invalid section: $new_section"
+ echo "Valid sections:"
+ echo "$valid_sections" |
+ xargs printf "%-10s\n" |
+ tr ' ' . |
+ xargs -n 10 |
+ sed 's/\./ /g; s/^/ /'
+ else
+ section="$new_section"
+ fi
+ fi
+ fi
+}
+
+cmd_copy() {
+ if [ -z "$DISPLAY" ]; then
+ echo copy: supported only in the Desktop version
+ elif [ -z "$input" ]; then
+ echo copy: Make at least one query first.
+ else
+ curl -s "${CHTSH_URL}"/"$(get_query_options "$query"?T)" >"$TMP1"
+ if [ "$is_macos" != yes ]; then
+ if [ "$XDG_SESSION_TYPE" = wayland ]; then
+ wl-copy <"$TMP1"
+ else
+ xsel -bi <"$TMP1"
+ fi
+ else
+ pbcopy <"$TMP1"
+ fi
+ echo "copy: $(wc -l "$TMP1" | awk '{print $1}') lines copied to the selection"
+ fi
+}
+
+cmd_ccopy() {
+ if [ -z "$DISPLAY" ]; then
+ echo copy: supported only in the Desktop version
+ elif [ -z "$input" ]; then
+ echo copy: Make at least one query first.
+ else
+ curl -s "${CHTSH_URL}"/"$(get_query_options "$query"?TQ)" >"$TMP1"
+ if [ "$is_macos" != yes ]; then
+ if [ "$XDG_SESSION_TYPE" = wayland ]; then
+ wl-copy <"$TMP1"
+ else
+ xsel -bi <"$TMP1"
+ fi
+ else
+ pbcopy <"$TMP1"
+ fi
+ echo "copy: $(wc -l "$TMP1" | awk '{print $1}') lines copied to the selection"
+ fi
+}
+
+cmd_exit() {
+ exit 0
+}
+
+cmd_help() {
+ cat <<EOF
+help - show this help
+hush - do not show the 'help' string at start anymore
+cd LANG - change the language context
+copy - copy the last answer in the clipboard (aliases: yank, y, c)
+ccopy - copy the last answer w/o comments (cut comments; aliases: cc, Y, C)
+exit - exit the cheat shell (aliases: quit, ^D)
+id [ID] - set/show an unique session id ("reset" to reset, "remove" to remove)
+stealth - stealth mode (automatic queries for selected text)
+update - self update (only if the scriptfile is writeable)
+version - show current cht.sh version
+/:help - service help
+QUERY - space separated query staring (examples are below)
+ cht.sh> python zip list
+ cht.sh/python> zip list
+ cht.sh/go> /python zip list
+EOF
+}
+
+cmd_hush() {
+ mkdir -p "$CHTSH_HOME/" && touch "$CHTSH_HOME/.hushlogin" && echo "Initial 'use help' message was disabled"
+}
+
+cmd_id() {
+ id_file="$CHTSH_HOME/id"
+
+ if [ id = "$input" ]; then
+ new_id=""
+ else
+ new_id=$(echo "$input" | sed 's/id *//; s/ *$//; s/ /+/g')
+ fi
+ if [ "$new_id" = remove ]; then
+ if [ -e "$id_file" ]; then
+ rm -f -- "$id_file" && echo "id is removed"
+ else
+ echo "id was not set, so you can't remove it"
+ fi
+ return
+ fi
+ if [ -n "$new_id" ] && [ reset != "$new_id" ] && [ "$(/bin/echo -n "$new_id" | wc -c)" -lt 16 ]; then
+ echo "ERROR: $new_id: Too short id. Minimal id length is 16. Use 'id reset' for a random id"
+ return
+ fi
+ if [ -z "$new_id" ]; then
+ # if new_id is not specified check if we have some id already
+ # if yes, just show it
+ # if not, generate a new id
+ if [ -e "$id_file" ]; then
+ awk '$6 == "id" {print $NF}' <"$id_file" | tail -n 1
+ return
+ else
+ new_id=reset
+ fi
+ fi
+ if [ "$new_id" = reset ]; then
+ new_id=$(gen_random_str 12)
+ else
+ echo WARNING: if someone gueses your id, he can read your cht.sh search history
+ fi
+ if [ -e "$id_file" ] && grep -q '\tid\t[^\t][^\t]*$' "$id_file" 2>/dev/null; then
+ sed -i 's/\tid\t[^\t][^\t]*$/ id '"$new_id"'/' "$id_file"
+ else
+ if ! [ -e "$id_file" ]; then
+ printf '#\n\n' >"$id_file"
+ fi
+ printf ".cht.sh\tTRUE\t/\tTRUE\t0\tid\t$new_id\n" >>"$id_file"
+ fi
+ echo "$new_id"
+}
+
+cmd_query() {
+ query=$(prepare_query "$section" "$input")
+ do_query "$query"
+}
+
+cmd_stealth() {
+ if [ "$input" != stealth ]; then
+ arguments=$(echo "$input" | sed 's/stealth //; s/ /\&/')
+ fi
+ trap break INT
+ if [ "$is_macos" = yes ]; then
+ past=$(pbpaste)
+ else
+ if [ "$XDG_SESSION_TYPE" = wayland ]; then
+ past=$(wl-paste -p)
+ else
+ past=$(xsel -o)
+ fi
+ fi
+ printf "\033[0;31mstealth:\033[0m you are in the stealth mode; select any text in any window for a query\n"
+ printf "\033[0;31mstealth:\033[0m selections longer than $STEALTH_MAX_SELECTION_LENGTH words are ignored\n"
+ if [ -n "$arguments" ]; then
+ printf "\033[0;31mstealth:\033[0m query arguments: ?$arguments\n"
+ fi
+ printf "\033[0;31mstealth:\033[0m use ^C to leave this mode\n"
+ while true; do
+ if [ "$is_macos" = yes ]; then
+ current=$(pbpaste)
+ else
+ if [ "$XDG_SESSION_TYPE" = wayland ]; then
+ current=$(wl-paste -p)
+ else
+ current=$(xsel -o)
+ fi
+ fi
+ if [ "$past" != "$current" ]; then
+ past=$current
+ current_text="$(echo $current | tr -c '[a-zA-Z0-9]' ' ')"
+ if [ "$(echo "$current_text" | wc -w)" -gt "$STEALTH_MAX_SELECTION_LENGTH" ]; then
+ printf "\033[0;31mstealth:\033[0m selection length is longer than $STEALTH_MAX_SELECTION_LENGTH words; ignoring\n"
+ continue
+ else
+ printf "\n\033[0;31mstealth: \033[7m $current_text\033[0m\n"
+ query=$(prepare_query "$section" "$current_text" "$arguments")
+ do_query "$query"
+ fi
+ fi
+ sleep 1
+ done
+ trap - INT
+}
+
+cmd_update() {
+ [ -w "$0" ] || {
+ echo "The script is readonly; please update manually: curl -s ${CHTSH_URL}/:cht.sh | sudo tee $0"
+ return
+ }
+ TMP2=$(mktemp /tmp/cht.sh.XXXXXXXXXXXXX)
+ curl -s "${CHTSH_URL}"/:cht.sh >"$TMP2"
+ if ! cmp "$0" "$TMP2" >/dev/null 2>&1; then
+ if grep -q ^__CHTSH_VERSION= "$TMP2"; then
+ # section was vaildated by us already
+ args=(--shell "$section")
+ cp "$TMP2" "$0" && echo "Updated. Restarting..." && rm "$TMP2" && CHEATSH_RESTART=1 exec "$0" "${args[@]}"
+ else
+ echo "Something went wrong. Please update manually"
+ fi
+ else
+ echo "cht.sh is up to date. No update needed"
+ fi
+ rm -f "$TMP2" >/dev/null 2>&1
+}
+
+cmd_version() {
+ insttime=$(ls -l -- "$0" | sed 's/ */ /g' | cut -d ' ' -f 6-8)
+ echo "cht.sh version $__CHTSH_VERSION of $__CHTSH_DATETIME; installed at: $insttime"
+ TMP2=$(mktemp /tmp/cht.sh.XXXXXXXXXXXXX)
+ if curl -s "${CHTSH_URL}"/:cht.sh >"$TMP2"; then
+ if ! cmp "$0" "$TMP2" >/dev/null 2>&1; then
+ echo "Update needed (type 'update' for that)".
+ else
+ echo "Up to date. No update needed"
+ fi
+ fi
+ rm -f "$TMP2" >/dev/null 2>&1
+}
+
+TMP1=$(mktemp /tmp/cht.sh.XXXXXXXXXXXXX)
+trap 'rm -f $TMP1 $TMP2' EXIT
+trap 'true' INT
+
+if ! [ -e "$CHTSH_HOME/.hushlogin" ] && [ -z "$this_query" ]; then
+ echo "type 'help' for the cht.sh shell help"
+fi
+
+while true; do
+ if [ "$section" != "" ]; then
+ full_prompt="$prompt/$section> "
+ else
+ full_prompt="$prompt> "
+ fi
+
+ input=$(
+ rlwrap -H "$CHTSH_HOME/history" -pgreen -C cht.sh -S "$full_prompt" bash "$0" --read | sed 's/ *#.*//'
+ )
+
+ cmd_name=${input%% *}
+ cmd_args=${input#* }
+ case $cmd_name in
+ "") continue ;; # skip empty input lines
+ '?' | h | help) cmd_name=help ;;
+ hush) cmd_name=hush ;;
+ cd) cmd_name="cd" ;;
+ exit | quit) cmd_name="exit" ;;
+ copy | yank | c | y) cmd_name=copy ;;
+ ccopy | cc | C | Y) cmd_name=ccopy ;;
+ id) cmd_name=id ;;
+ stealth) cmd_name=stealth ;;
+ update) cmd_name=update ;;
+ version) cmd_name=version ;;
+ *)
+ cmd_name="query"
+ cmd_args="$input"
+ ;;
+esac
+"cmd_$cmd_name" $cmd_args
+done
diff --git a/dbdb b/dbdb
index 238c057..2fb1581 100755
--- a/dbdb
+++ b/dbdb
@@ -14,5 +14,5 @@ while [ ! -z "$chosen" ]; do
DOTFs=$( ls -a1p | grep -P '^\.[^\$/]+$' | awk -vRS="\n" -vORS=" \t" '1')
clear && printf "\e[1;7;33m $(pwd) \e[0m\n$FILEs\n\e[0;38;5;238m$DOTFs\e[0m\n"
chosen=`( ( echo -e "$DIRs$DOTDs" | awk -vRS="\t" -vORS="\n" '1' ) | dmenu -i )`
- cd "$chosen"
+ cd "$chosen"
done
diff --git a/dictloop b/dictloop
index a47e98c..738b3c0 100755
--- a/dictloop
+++ b/dictloop
@@ -4,21 +4,21 @@ setopt aliases
source "$ZDOTDIR/aliasrc"
[ "$#" -ne 1 ] && {
- echo "Usage: dictloop <dict>" >&2
- exit 1
+ echo "Usage: dictloop <dict>" >&2
+ exit 1
}
dict="$1" # a command-line dictionary
while true; do
- echo "Enter a word: "
- read -r word
+ echo "Enter a word: "
+ read -r word
- if [ -z "$word" ] || [ "$word" = "exit" ]; then
- echo "Exiting..."
- exit 0
- fi
+ if [ -z "$word" ] || [ "$word" = "exit" ]; then
+ echo "Exiting..."
+ exit 0
+ fi
- "$dict" "$word"
+ "$dict" "$word"
done
exit 0
diff --git a/dmenu-translate b/dmenu-translate
new file mode 100755
index 0000000..766ad51
--- /dev/null
+++ b/dmenu-translate
@@ -0,0 +1,150 @@
+#!/bin/sh
+
+echo_err() {
+ notify-send -u critical "$0 error" "$1"
+}
+
+err() {
+ echo_err "$1"
+ exit 1
+}
+
+check_dep() {
+ command -v "$1" > /dev/null || err "$1 is required: $2"
+}
+
+# We don't check if dmenu is installed because someone
+# may want to replace it via DMENU vars
+check_dep trans https://github.com/soimort/translate-shell
+check_dep notify-send
+
+load_config() {
+ config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/dmenu-translate"
+ [ -d "$config_dir" ] || mkdir -p "$config_dir"
+
+ config_file="$config_dir/config.sh"
+ [ -f "$config_file" ] || touch "$config_file"
+
+ old_config_file="$config_dir/config.conf"
+ [ -f "$old_config_file" ] && notify-send "dmenu-translate warning" "Found old configuration file at <code>$old_config_file</code>, which is no longer supported. Please move your settings to a new file at <code>$config_file</code> and delete the old one."
+
+ . "$config_file"
+
+ # Check others
+ if [ -n "$WAYLAND_DISPLAY" ]; then
+ : "${CLIP_COPY:=wl-copy -n}"
+ : "${CLIP_PASTE_CLIP:=wl-paste}"
+ : "${CLIP_PASTE_PRIM:=wl-paste -p}"
+ : "${DMENU:=wmenu}"
+ : "${TERMINAL=foot}"
+ else
+ : "${CLIP_COPY:=xclip -i -r -selection clipboard}"
+ : "${CLIP_PASTE_CLIP:=xclip -o -selection clipboard}"
+ : "${CLIP_PASTE_PRIM:=xclip -o -selection primary}"
+ : "${DMENU:=dmenu}"
+ : "${TERMINAL=xterm}"
+ fi
+
+ # Default values
+ : "${TRANS_LANGS:=:ru :en}"
+ : "${DMENU_TEXT:=${DMENU} -i -p 'Translate: Text'}"
+ : "${DMENU_LANG:=${DMENU} -i -p 'Translate: Into'}"
+ : "${DMENU_NEXT:=${DMENU} -i -p 'Translate: Next?'}"
+}
+
+formatmenu() {
+ echo "$1" | tr '\n' ' ' | sed 's/\s\{3,\}//g; s/^\(.\{30\}\).\+/\1.../; s/$/\n/'
+}
+
+get_selection() {
+ [ -n "$1" ] && eval "$CLIP_PASTE_CLIP" || eval "$CLIP_PASTE_PRIM"
+}
+
+clip_menu() {
+ { formatmenu "$1"; formatmenu "$2"; } |
+ sed 's/^\s*$//; 1s/^./Primary: &/; 2s/^./Clipboard: &/' |
+ sed '/^$/d'
+}
+
+lang_menu() {
+ echo "$TRANS_LANGS" | sed 's/\s\+/\n/g' | sed '/:/!s/^/:/'
+ echo '[Define]'
+}
+
+choose_next() {
+ t="$1"
+ shift
+ if [ -n "$ALWAYS_COPY" ]; then
+ echo 'Copy'
+ else
+ eval "$DMENU_NEXT" "$@" <<-EOF
+ Copy: $(formatmenu "$t")
+ Copy temp file name
+ View
+ EOF
+ fi
+}
+
+save_file() (
+ tmp="$(mktemp --tmpdir 'dmenu-translate.XXXXXX')"
+ echo "$1" > "$tmp"
+ echo "$tmp"
+)
+
+open_term() {
+ ${TERMINAL} -e ${PAGER:-'less'} "$(save_file "$1")"
+}
+
+get_text() {
+ echo "$2" | while IFS= read -r clip; do
+ [ "$1" = "$clip" ] && {
+ type="$(echo "$clip" | sed 's/^\(\w\+\):.*/\1/')"
+ case "$type" in
+ Primary) echo "$primary" ;;
+ Clipboard) echo "$clipboard" ;;
+ esac
+ exit 10
+ }
+ done
+
+ # If not found, just echo text
+ [ $? -ne 10 ] && echo "$1"
+}
+
+# Config
+load_config
+
+# Get selections
+clipboard="$(get_selection clip)"
+primary="$(get_selection)"
+
+clip_menu="$(clip_menu "$primary" "$clipboard")"
+
+# Enter text
+text="$(printf '%s' "$clip_menu" | eval "$DMENU_TEXT" "$@")" || exit 0
+text="$(get_text "$text" "$clip_menu")"
+
+# Choose target language
+target="$(lang_menu | eval "$DMENU_LANG" "$@")" || exit 0
+
+# If Define chosen, define term and exit
+[ "$target" = '[Define]' ] && {
+ dict="$(trans -dictionary "$text")"
+ open_term "$(trans -dictionary "$text")"
+ exit 0
+}
+
+# Translate text
+translation="$(trans -b "$target" "$text")"
+[ -z "$translation" ] && err 'Failed to translate'
+
+case "$(choose_next "$translation" "$@")" in
+ 'View') open_term "$translation"; exit 0 ;;
+'Copy temp file name') output="$(save_file "$translation")" ;;
+'Copy'*) output="$translation" ;;
+*) exit 0 ;;
+esac
+
+echo "$output" | eval "$CLIP_COPY" || err 'Failed to copy! Is CLIP_COPY setting set properly?'
+
+notify-send 'dmenu-translate' 'Translation copied to clipboard!'
diff --git a/dpass b/dpass
index 464b959..4458d59 100755
--- a/dpass
+++ b/dpass
@@ -1,5 +1,6 @@
#!/bin/sh
-password=$(find ~/.password-store/ -type f -name '*.gpg' |
- sed 's/.*\/\(.*\)\.gpg$/\1/' | dmenu -i -p "Pass:")
+dir="${PASSWORD_STORE_DIR:-$HOME/.password-store}"
+password=$(find "$dir" -type f -name '*.gpg' |
+sed 's/.*\/\(.*\)\.gpg$/\1/' | dmenu -i -p "Pass:")
[ -n "$password" ] && pass show -c "$password"
diff --git a/dtrans b/dtrans
index 5f4ced1..766ad51 100755
--- a/dtrans
+++ b/dtrans
@@ -1,16 +1,16 @@
#!/bin/sh
echo_err() {
- notify-send -u critical "$0 error" "$1"
+ notify-send -u critical "$0 error" "$1"
}
err() {
- echo_err "$1"
- exit 1
+ echo_err "$1"
+ exit 1
}
check_dep() {
- command -v "$1" > /dev/null || err "$1 is required: $2"
+ command -v "$1" > /dev/null || err "$1 is required: $2"
}
# We don't check if dmenu is installed because someone
@@ -19,96 +19,96 @@ check_dep trans https://github.com/soimort/translate-shell
check_dep notify-send
load_config() {
- config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/dmenu-translate"
- [ -d "$config_dir" ] || mkdir -p "$config_dir"
-
- config_file="$config_dir/config.sh"
- [ -f "$config_file" ] || touch "$config_file"
-
- old_config_file="$config_dir/config.conf"
- [ -f "$old_config_file" ] && notify-send "dmenu-translate warning" "Found old configuration file at <code>$old_config_file</code>, which is no longer supported. Please move your settings to a new file at <code>$config_file</code> and delete the old one."
-
- . "$config_file"
-
- # Check others
- if [ -n "$WAYLAND_DISPLAY" ]; then
- : "${CLIP_COPY:=wl-copy -n}"
- : "${CLIP_PASTE_CLIP:=wl-paste}"
- : "${CLIP_PASTE_PRIM:=wl-paste -p}"
- : "${DMENU:=wmenu}"
- : "${TERMINAL=foot}"
- else
- : "${CLIP_COPY:=xclip -i -r -selection clipboard}"
- : "${CLIP_PASTE_CLIP:=xclip -o -selection clipboard}"
- : "${CLIP_PASTE_PRIM:=xclip -o -selection primary}"
- : "${DMENU:=dmenu}"
- : "${TERMINAL=xterm}"
- fi
-
- # Default values
- : "${TRANS_LANGS:=:ru :en}"
- : "${DMENU_TEXT:=${DMENU} -i -p 'Translate: Text'}"
- : "${DMENU_LANG:=${DMENU} -i -p 'Translate: Into'}"
- : "${DMENU_NEXT:=${DMENU} -i -p 'Translate: Next?'}"
+ config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/dmenu-translate"
+ [ -d "$config_dir" ] || mkdir -p "$config_dir"
+
+ config_file="$config_dir/config.sh"
+ [ -f "$config_file" ] || touch "$config_file"
+
+ old_config_file="$config_dir/config.conf"
+ [ -f "$old_config_file" ] && notify-send "dmenu-translate warning" "Found old configuration file at <code>$old_config_file</code>, which is no longer supported. Please move your settings to a new file at <code>$config_file</code> and delete the old one."
+
+ . "$config_file"
+
+ # Check others
+ if [ -n "$WAYLAND_DISPLAY" ]; then
+ : "${CLIP_COPY:=wl-copy -n}"
+ : "${CLIP_PASTE_CLIP:=wl-paste}"
+ : "${CLIP_PASTE_PRIM:=wl-paste -p}"
+ : "${DMENU:=wmenu}"
+ : "${TERMINAL=foot}"
+ else
+ : "${CLIP_COPY:=xclip -i -r -selection clipboard}"
+ : "${CLIP_PASTE_CLIP:=xclip -o -selection clipboard}"
+ : "${CLIP_PASTE_PRIM:=xclip -o -selection primary}"
+ : "${DMENU:=dmenu}"
+ : "${TERMINAL=xterm}"
+ fi
+
+ # Default values
+ : "${TRANS_LANGS:=:ru :en}"
+ : "${DMENU_TEXT:=${DMENU} -i -p 'Translate: Text'}"
+ : "${DMENU_LANG:=${DMENU} -i -p 'Translate: Into'}"
+ : "${DMENU_NEXT:=${DMENU} -i -p 'Translate: Next?'}"
}
formatmenu() {
- echo "$1" | tr '\n' ' ' | sed 's/\s\{3,\}//g; s/^\(.\{30\}\).\+/\1.../; s/$/\n/'
+ echo "$1" | tr '\n' ' ' | sed 's/\s\{3,\}//g; s/^\(.\{30\}\).\+/\1.../; s/$/\n/'
}
get_selection() {
- [ -n "$1" ] && eval "$CLIP_PASTE_CLIP" || eval "$CLIP_PASTE_PRIM"
+ [ -n "$1" ] && eval "$CLIP_PASTE_CLIP" || eval "$CLIP_PASTE_PRIM"
}
clip_menu() {
- { formatmenu "$1"; formatmenu "$2"; } |
- sed 's/^\s*$//; 1s/^./Primary: &/; 2s/^./Clipboard: &/' |
- sed '/^$/d'
+ { formatmenu "$1"; formatmenu "$2"; } |
+ sed 's/^\s*$//; 1s/^./Primary: &/; 2s/^./Clipboard: &/' |
+ sed '/^$/d'
}
lang_menu() {
- echo "$TRANS_LANGS" | sed 's/\s\+/\n/g' | sed '/:/!s/^/:/'
- echo '[Define]'
+ echo "$TRANS_LANGS" | sed 's/\s\+/\n/g' | sed '/:/!s/^/:/'
+ echo '[Define]'
}
choose_next() {
- t="$1"
- shift
- if [ -n "$ALWAYS_COPY" ]; then
- echo 'Copy'
- else
- eval "$DMENU_NEXT" "$@" <<-EOF
+ t="$1"
+ shift
+ if [ -n "$ALWAYS_COPY" ]; then
+ echo 'Copy'
+ else
+ eval "$DMENU_NEXT" "$@" <<-EOF
Copy: $(formatmenu "$t")
Copy temp file name
View
EOF
- fi
+ fi
}
save_file() (
- tmp="$(mktemp --tmpdir 'dmenu-translate.XXXXXX')"
- echo "$1" > "$tmp"
- echo "$tmp"
+ tmp="$(mktemp --tmpdir 'dmenu-translate.XXXXXX')"
+ echo "$1" > "$tmp"
+ echo "$tmp"
)
open_term() {
- ${TERMINAL} -e ${PAGER:-'less'} "$(save_file "$1")"
+ ${TERMINAL} -e ${PAGER:-'less'} "$(save_file "$1")"
}
get_text() {
- echo "$2" | while IFS= read -r clip; do
- [ "$1" = "$clip" ] && {
- type="$(echo "$clip" | sed 's/^\(\w\+\):.*/\1/')"
- case "$type" in
- Primary) echo "$primary" ;;
- Clipboard) echo "$clipboard" ;;
- esac
- exit 10
- }
- done
-
- # If not found, just echo text
- [ $? -ne 10 ] && echo "$1"
+ echo "$2" | while IFS= read -r clip; do
+ [ "$1" = "$clip" ] && {
+ type="$(echo "$clip" | sed 's/^\(\w\+\):.*/\1/')"
+ case "$type" in
+ Primary) echo "$primary" ;;
+ Clipboard) echo "$clipboard" ;;
+ esac
+ exit 10
+ }
+ done
+
+ # If not found, just echo text
+ [ $? -ne 10 ] && echo "$1"
}
# Config
@@ -129,9 +129,9 @@ target="$(lang_menu | eval "$DMENU_LANG" "$@")" || exit 0
# If Define chosen, define term and exit
[ "$target" = '[Define]' ] && {
- dict="$(trans -dictionary "$text")"
- open_term "$(trans -dictionary "$text")"
- exit 0
+ dict="$(trans -dictionary "$text")"
+ open_term "$(trans -dictionary "$text")"
+ exit 0
}
# Translate text
@@ -139,10 +139,10 @@ translation="$(trans -b "$target" "$text")"
[ -z "$translation" ] && err 'Failed to translate'
case "$(choose_next "$translation" "$@")" in
- 'View') open_term "$translation"; exit 0 ;;
- 'Copy temp file name') output="$(save_file "$translation")" ;;
- 'Copy'*) output="$translation" ;;
- *) exit 0 ;;
+ 'View') open_term "$translation"; exit 0 ;;
+'Copy temp file name') output="$(save_file "$translation")" ;;
+'Copy'*) output="$translation" ;;
+*) exit 0 ;;
esac
echo "$output" | eval "$CLIP_COPY" || err 'Failed to copy! Is CLIP_COPY setting set properly?'
diff --git a/dz-feed b/dz-feed
index e11402b..3e90102 100755
--- a/dz-feed
+++ b/dz-feed
@@ -3,10 +3,9 @@
cache="$HOME/.cache/dz"
if [ "$1" = "-r" ] || [ ! -e "$cache" ]; then
- find "$HOME" -mindepth 1 \( -name ".*" -o -path "$HOME/cell" -o -path "$HOME/phone/*" \) -prune -o -print | \
- sed '/\.pdf$/!d' | sort > "$cache"
-
- notify-send "dz cache updated."
+ find "$HOME" -mindepth 1 \( -name ".*" -o -path "$HOME/cell" -o -path "$HOME/phone/*" \) -prune -o -print | \
+ sed '/\.pdf$/!d' | sort > "$cache"
+ # notify-send "dz cache updated."
fi
cat "$cache"
diff --git a/echovol b/echovol
new file mode 100755
index 0000000..9845a55
--- /dev/null
+++ b/echovol
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+volume=$(pactl list sinks | grep -A 15 'Sink #0' | grep 'Volume:' | awk '{print $5}' | tr -d '%' | head -1)
+mute=$(pactl list sinks | grep -A 15 'Sink #0' | grep 'Mute' | awk '{print $2}')
+
+if [ "$mute" = "yes" ]; then
+ echo "mute"
+else
+ echo "$volume%"
+fi
diff --git a/engadd b/engadd
new file mode 100755
index 0000000..27d5fd1
--- /dev/null
+++ b/engadd
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+echo "$1" >> "$HOME"/langs/english/obscure_words
diff --git a/extract_pdfs b/extract_pdfs
deleted file mode 100755
index 2fb0d49..0000000
--- a/extract_pdfs
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/zsh
-
-if [ "$#" -ne 2 ]; then
- echo "Usage: extract_pdfs /path/to/source /path/to/destination"
- exit 1
-fi
-
-SOURCE_DIR="$1"
-DEST_DIR="$2"
-
-if [ ! -d "$SOURCE_DIR" ]; then
- notify-send "Source directory does not exist: $SOURCE_DIR"
- exit 1
-fi
-
-mkdir -p "$DEST_DIR"
-
-find "$SOURCE_DIR" -type f -iname "*.pdf" | while read -r pdf; do
- filename=$(basename "$pdf")
-
- dest_file="$DEST_DIR/$filename"
- if [ -e "$dest_file" ]; then
- i=1
- while [ -e "$DEST_DIR/${filename%.*}_$i.pdf" ]; do
- ((i++))
- done
- dest_file="$DEST_DIR/${filename%.*}_$i.pdf"
- fi
-
- cp "$pdf" "$dest_file"
-done
-
-notify-send "PDF extraction complete. Files copied to: $DEST_DIR"
diff --git a/inpath b/inpath
index b8bf568..71bfeb9 100755
--- a/inpath
+++ b/inpath
@@ -1,43 +1,43 @@
#!/bin/sh
in_path() {
- cmd=$1 path=$2 res=1
- IFS=":"
+ cmd=$1 path=$2 res=1
+ IFS=":"
- for dir in $path; do
- if [ -x "$dir/$cmd" ]; then
- res=0
- break
- fi
- done
+ for dir in $path; do
+ if [ -x "$dir/$cmd" ]; then
+ res=0
+ break
+ fi
+ done
- return $res
+ return $res
}
cmd_in_path() {
- var=$1
-
- if [ -n "$var" ]; then
- if [ "$(echo "$var" | cut -c 1)" = "/" ]; then
- if [ ! -x "$var" ]; then
- return 1
- fi
- elif ! in_path "$var" "$PATH"; then
- return 2
- fi
- fi
+ var=$1
+
+ if [ -n "$var" ]; then
+ if [ "$(echo "$var" | cut -c 1)" = "/" ]; then
+ if [ ! -x "$var" ]; then
+ return 1
+ fi
+ elif ! in_path "$var" "$PATH"; then
+ return 2
+ fi
+ fi
}
if [ $# -ne 1 ]; then
- echo "Usage: $0 <command>" >&2
- exit 1
+ echo "Usage: $0 <command>" >&2
+ exit 1
fi
cmd_in_path "$1"
case $? in
-0) echo "$1 found in PATH" ;;
-1) echo "$1 not found or not executable" ;;
-2) echo "$1 not found in PATH" ;;
+ 0) echo "$1 found in PATH" ;;
+ 1) echo "$1 not found or not executable" ;;
+ 2) echo "$1 not found in PATH" ;;
esac
exit 0
diff --git a/logrm b/logrm
index f139f82..e760bcc 100755
--- a/logrm
+++ b/logrm
@@ -3,14 +3,14 @@
removelog="/var/log/remove.log"
if [ $# -eq 0 ]; then
- echo "Usage: $0 [-s] list of files or directories" >&2
- exit 1
+ echo "Usage: $0 [-s] list of files or directories" >&2
+ exit 1
fi
if [ "$1" = "-s" ]; then
- shift
+ shift
else
- echo "$(date): ${USER}: $*" >>$removelog
+ echo "$(date): ${USER}: $*" >>$removelog
fi
rm -i "$@"
diff --git a/lsn b/lsn
index b3f07ea..426d71b 100755
--- a/lsn
+++ b/lsn
@@ -1,9 +1,9 @@
#!/bin/sh
# New and better ls
-# TODO: fix simlinks, flags break them for some reason
+# TODO: fix simlinks, flags break them for some reason, maybe switch to eza
ls_new() {
- LC_ALL=C $(which ls) -lAFh --color=always "$1" | awk '{
+ LC_ALL=C $(which ls) -lAFh --color=always "$1" | awk '{
name = $9;
for (i = 10; i <= NF; i++) name = name " " $i;
print $1, $5, name
diff --git a/maimpick b/maimpick
index 388a51d..83effed 100755
--- a/maimpick
+++ b/maimpick
@@ -8,7 +8,7 @@ xclip_cmd="xclip -sel clip -t image/png"
ocr_cmd="xclip -sel clip"
case "$(printf 'a selected area\ncurrent window\nfull screen\na selected area (copy)\ncurrent window (copy)\nfull screen (copy)\ncopy selected image to text' | dmenu -l 7 -i -p "Screenshot which area?")" in
-"a selected area") maim -u -s pic-selected-"${output}" ;;
+ "a selected area") maim -u -s pic-selected-"${output}" ;;
"current window") maim -B -q -d 0.2 -i "$(xdotool getactivewindow)" pic-window-"${output}" ;;
"full screen") maim -q -d 0.2 pic-full-"${output}" ;;
"a selected area (copy)") maim -u -s | ${xclip_cmd} ;;
diff --git a/mounter b/mounter
new file mode 100755
index 0000000..969412b
--- /dev/null
+++ b/mounter
@@ -0,0 +1,119 @@
+#!/bin/bash
+
+# Mounts Android Phones and USB drives (encrypted or not). This script will
+# replace the older `dmenumount` which had extra steps and couldn't handle
+# encrypted drives.
+# TODO: Try decrypt for drives in crtypttab
+# TODO: Add some support for connecting iPhones (although they are annoying).
+
+IFS='
+'
+# Function for escaping cell-phone names.
+escape(){ echo "$@" | iconv -cf UTF-8 -t ASCII//TRANSLIT | tr -d '[:punct:]' | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | sed "s/-\+/-/g;s/\(^-\|-\$\)//g" ;}
+
+# Check for phones.
+phones="$(simple-mtpfs -l 2>/dev/null | sed "s/^/📱/")"
+mountedphones="$(grep "simple-mtpfs" /etc/mtab)"
+# If there are already mounted phones, remove them from the list of mountables.
+[ -n "$mountedphones" ] && phones="$(for phone in $phones; do
+ for mounted in $mountedphones; do
+ escphone="$(escape "$phone")"
+ [[ "$mounted" =~ "$escphone" ]] && break 1
+ done && continue 1
+ echo "$phone"
+done)"
+
+# Check for drives.
+lsblkoutput="$(lsblk -rpo "uuid,name,type,size,label,mountpoint,fstype")"
+# Get all LUKS drives
+allluks="$(echo "$lsblkoutput" | grep crypto_LUKS)"
+# Get a list of the LUKS drive UUIDs already decrypted.
+decrypted="$(find /dev/disk/by-id/dm-uuid-CRYPT-LUKS2-* | sed "s|.*LUKS2-||;s|-.*||")"
+# Functioning for formatting drives correctly for dmenu:
+filter() { sed "s/ /:/g" | awk -F':' '$7==""{printf "%s%s (%s) %s\n",$1,$3,$5,$6}' ; }
+
+# Get only LUKS drives that are not decrypted.
+unopenedluks="$(for drive in $allluks; do
+ uuid="${drive%% *}"
+ uuid="${uuid//-}" # This is a bashism.
+ [ -n "$decrypted" ] && for open in $decrypted; do
+ [ "$uuid" = "$open" ] && break 1
+ done && continue 1
+ echo "🔒 $drive"
+done | filter)"
+
+# Get all normal, non-encrypted or decrypted partitions that are not mounted.
+normalparts="$(echo "$lsblkoutput"| grep -v crypto_LUKS | grep 'part\|rom\|crypt' | sed "s/^/💾 /" | filter )"
+
+# Add all to one variable. If no mountable drives found, exit.
+alldrives="$(echo "$phones
+$unopenedluks
+$normalparts" | sed "/^$/d;s/ *$//")"
+
+# Quit the script if a sequential command fails.
+set -e
+
+test -n "$alldrives"
+
+# Feed all found drives to dmenu and get user choice.
+chosen="$(echo "$alldrives" | dmenu -p "Mount which drive?" -i)"
+
+# Function for prompting user for a mountpoint.
+getmount(){
+ mp="$(find /mnt /media /mount /home -maxdepth 1 -type d 2>/dev/null | dmenu -i -p "Mount this drive where?")"
+ test -n "$mp"
+ if [ ! -d "$mp" ]; then
+ mkdiryn=$(printf "No\\nYes" | dmenu -i -p "$mp does not exist. Create it?")
+ [ "$mkdiryn" = "Yes" ] && (mkdir -p "$mp" || sudo -A mkdir -p "$mp")
+ fi
+}
+
+attemptmount(){
+ # Attempt to mount without a mountpoint, to see if drive is in fstab.
+ sudo -A mount "$chosen" || return 1
+ notify-send "💾Drive Mounted." "$chosen mounted."
+ exit
+}
+
+case "$chosen" in
+ 💾*)
+ chosen="${chosen%% *}"
+ chosen="${chosen:1}" # This is a bashism.
+ parttype="$(echo "$lsblkoutput" | grep "$chosen")"
+ attemptmount || getmount
+ case "${parttype##* }" in
+ vfat) sudo -A mount -t vfat "$chosen" "$mp" -o rw,umask=0000 ;;
+ btrfs) sudo -A mount "$chosen" "$mp" ;;
+ *) sudo -A mount "$chosen" "$mp" -o uid="$(id -u)",gid="$(id -g)" ;;
+ esac
+ notify-send "💾Drive Mounted." "$chosen mounted to $mp."
+ ;;
+
+ 🔒*)
+ chosen="${chosen%% *}"
+ chosen="${chosen:1}" # This is a bashism.
+ # Number the drive.
+ while true; do
+ [ -f "/dev/mapper/usb$num" ] || break
+ num="$(printf "%02d" "$((num +1))")"
+ done
+
+ # Decrypt in a terminal window
+ ${TERMINAL:-st} -n floatterm -g 60x1 -e sudo cryptsetup open "$chosen" "usb$num"
+ # Check if now decrypted.
+ test -b "/dev/mapper/usb$num"
+
+ attemptmount || getmount
+ sudo -A mount "/dev/mapper/usb$num" "$mp" -o uid="$(id -u)",gid="$(id -g)"
+ notify-send "🔓Decrypted drive Mounted." "$chosen decrypted and mounted to $mp."
+ ;;
+
+ 📱*)
+ notify-send "❗Note" "Remember to allow file access on your phone now."
+ getmount
+ number="${chosen%%:*}"
+ number="${chosen:1}" # This is a bashism.
+ sudo -A simple-mtpfs -o allow_other -o fsname="simple-mtpfs-$(escape "$chosen")" --device "$number" "$mp"
+ notify-send "🤖 Android Mounted." "Android device mounted to $mp."
+ ;;
+esac
diff --git a/newnote b/newnote
index da68221..6e40235 100755
--- a/newnote
+++ b/newnote
@@ -3,20 +3,20 @@
dir="$OBSIDIAN_HOME"
newnote() {
- file="$dir/$1.md"
- [ -f "$file" ] && {
- echo "Note with the same name already exists, exiting" >&2
- exit 1
- }
- touch "$file" && "$EDITOR" +2 "$file"
- if [ "$(wc -l "$file" | awk '{print $1}')" -lt 2 ]; then
- rm -f "$file"
- fi
+ file="$dir/$1.md"
+ [ -f "$file" ] && {
+ echo "Note with the same name already exists, exiting" >&2
+ exit 1
+ }
+ touch "$file" && "$EDITOR" +2 "$file"
+ if [ "$(wc -l "$file" | awk '{print $1}')" -lt 2 ]; then
+ rm -f "$file"
+ fi
}
[ "$#" -ne 1 ] && {
- echo "Usage: newnote <note-name>" >&2
- exit 1
+ echo "Usage: newnote <note-name>" >&2
+ exit 1
}
newnote "$1"
diff --git a/newscript b/newscript
index f6d11b0..154d2fb 100755
--- a/newscript
+++ b/newscript
@@ -1,22 +1,22 @@
#!/bin/sh
newscript() {
- file="$HOME/.scripts/$1"
- [ -f "$file" ] && {
- echo "Script with the same name already exists, exiting" >&2
- exit 1
- }
- touch "$file" && printf "#!/bin/sh\n\n" >"$file" && "$EDITOR" +2 "$file"
- if [ "$(wc -l "$file" | awk '{print $1}')" -lt 3 ]; then
- rm -f "$file"
- else
- chmod +x "$file"
- fi
+ file="$HOME/.scripts/$1"
+ [ -f "$file" ] && {
+ echo "Script with the same name already exists, exiting" >&2
+ exit 1
+ }
+ touch "$file" && printf "#!/bin/sh\n\n" >"$file" && "$EDITOR" +2 "$file"
+ if [ "$(wc -l "$file" | awk '{print $1}')" -lt 3 ]; then
+ rm -f "$file"
+ else
+ chmod +x "$file"
+ fi
}
[ "$#" -ne 1 ] && {
- echo "Usage: newscript <script-name>" >&2
- exit 1
+ echo "Usage: newscript <script-name>" >&2
+ exit 1
}
newscript "$1"
diff --git a/remaps b/remaps
index c18a9b9..39e1018 100755
--- a/remaps
+++ b/remaps
@@ -1,7 +1,7 @@
#!/bin/sh
# Increase key speed
-xset r rate 200 50
+xset r rate 200 80
# Switch caps and esc
setxkbmap us -option caps:swapescape
diff --git a/rmw b/rmw
index 6331204..f84689f 100755
--- a/rmw
+++ b/rmw
@@ -1,24 +1,24 @@
#!/bin/sh
if [ "$#" -gt 1 ]; then
- echo "Usage: rm_whitespaces <dir>" >&2
- exit 1
+ echo "Usage: rm_whitespaces <dir>" >&2
+ exit 1
fi
if [ "$#" -eq 0 ]; then
- dir="$(pwd)"
+ dir="$(pwd)"
else
- dir="$1"
+ dir="$1"
fi
cd "$dir" || {
- echo "Couldn't cd to directory. Exiting..." >&2
- exit 1
+ echo "Couldn't cd to directory. Exiting..." >&2
+ exit 1
}
for file in "$dir"/*; do
- newname="$(echo "$file" | sed -e 's/["`”“-]*//g' -e 's/[ \t]+/\_/g')"
- mv "$file" "$newname"
+ newname="$(echo "$file" | sed -e 's/["`”“-]*//g' -e 's/[ \t]+/\_/g')"
+ mv "$file" "$newname"
done
exit 0
diff --git a/rotdir b/rotdir
new file mode 100755
index 0000000..d171f29
--- /dev/null
+++ b/rotdir
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# When I open an image from the file manager in nsxiv (the image viewer), I want
+# to be able to press the next/previous keys to key through the rest of the
+# images in the same directory. This script "rotates" the content of a
+# directory based on the first chosen file, so that if I open the 15th image,
+# if I press next, it will go to the 16th etc. Autistic, I know, but this is
+# one of the reasons that nsxiv is great for being able to read standard input.
+
+[ -z "$1" ] && echo "usage: rotdir regex 2>&1" && exit 1
+base="$(basename "$1")"
+ls "$PWD" | awk -v BASE="$base" 'BEGIN { lines = ""; m = 0; } { if ($0 == BASE) { m = 1; } } { if (!m) { if (lines) { lines = lines"\n"; } lines = lines""$0; } else { print $0; } } END { print lines; }'
diff --git a/rssadd b/rssadd
index bf39558..140774a 100755
--- a/rssadd
+++ b/rssadd
@@ -1,9 +1,9 @@
#!/bin/sh
if echo "$1" | grep -q "https*://\S\+\.[A-Za-z]\+\S*"; then
- url="$1"
+ url="$1"
else
- url="$(grep -Eom1 '<[^>]+(rel="self"|application/[a-z]+\+xml)[^>]+>' "$1" |
+ url="$(grep -Eom1 '<[^>]+(rel="self"|application/[a-z]+\+xml)[^>]+>' "$1" |
grep -o 'https?://[^" ]')"
echo "$url" | grep -q "https*://\S\+\.[A-Za-z]\+\S*" ||
diff --git a/rssget b/rssget
new file mode 100755
index 0000000..10fbbf0
--- /dev/null
+++ b/rssget
@@ -0,0 +1,117 @@
+#!/bin/bash
+
+# Searches the website for RSS feeds and adds them to newsboat url list. Can
+# also find hidden RSS feeds on various websites, namely Youtube, Reddit,
+# Vimeo, Github, Gitlab and Medium. Gets site url as $1 or (if not present)
+# from X clipboard. Gets tags as $2. If it finds more than one feed, calls
+# dmenu for the user to choose which one to add. I have bound it to a keyboard
+# shortcut so i copy a site link and easily add its feed to the reader.
+
+# Inspired by and based on the logic of this extension:
+# https://github.com/shevabam/get-rss-feed-url-extension
+
+# This script requires rssadd to add feeds to the list.
+
+getlink () {
+ local url="$1"
+ feeds="$(curl -s "$url" | grep -Ex '.*type=.*(rss|rdf|atom).*' | sed 's/ //g')"
+ url="$(echo $url | sed 's|^\(https://[^/]*/\).*|\1|')"
+
+ for rsspath in $feeds; do
+ rsspath="$(echo $rsspath | sed -n "s|.*href=['\"]\([^'\"]*\)['\"].*|\1|p")"
+ if echo "$rsspath" | grep "http" > /dev/null; then
+ link="$rsspath"
+ elif echo "$rsspath" | grep -E "^/" > /dev/null; then
+ link="$url$(echo $rsspath | sed 's|^/||')"
+ else
+ link="$url$rsspath"
+ fi
+ echo $link
+ done
+}
+
+getRedditRss() {
+ echo "${1%/}.rss"
+}
+
+getYoutubeRss() {
+ local url="$1"
+ path=$(echo "$url" | sed -e 's|^http[s]*://||')
+ case "$path" in
+ *"/channel/"*) channel_id="$(echo $path | sed -r 's|.*channel/([^/]*).*|\1|')" && feed="https://www.youtube.com/feeds/videos.xml?channel_id=${channel_id}" ;;
+ *"/c/"*|*"/user/"*)
+ feed=$(wget -q "$url" -O tmp_rssget_yt \
+ && sed -n 's|.*\("rssUrl":"[^"]*\).*|\1|; p' tmp_rssget_yt \
+ | grep rssUrl \
+ | sed 's|"rssUrl":"||') ;;
+ esac
+ echo "$feed"
+}
+
+getVimeoRss() {
+ local url="$1"
+ if echo "$url" | grep -q "/videos$"; then
+ feed_url=$(echo "$url" | sed 's/\/videos$//' | sed 's/\/$/\/rss/')
+ else
+ feed_url="${url}/videos/rss"
+ fi
+ echo "$feed_url"
+}
+
+getGithubRss () {
+ local url="${1%/}"
+ if echo $url | grep -E "github.com/[^/]*/[a-zA-Z0-9].*" >/dev/null ; then
+ echo "${url}/commits.atom"
+ echo "${url}/releases.atom"
+ echo "${url}/tags.atom"
+ elif echo $url | grep -E "github.com/[^/]*(/)" >/dev/null ; then
+ echo "${url}.atom"
+ fi
+}
+
+getGitlabRss () {
+ local url="${1%/}"
+ echo "${url}.atom"
+}
+
+getMediumRss () {
+ echo $1 | sed 's|/tag/|/feed/|'
+}
+
+
+if [ -n "$1" ] ; then
+ url="$1"
+else
+ url="$(xclip -selection clipboard -o)"
+ [ -z "$url" ] && echo "usage: $0 url 'tag1 tag2 tag3'" && exit 1
+fi
+
+declare -a list=()
+
+yt_regex="^(http(s)?://)?((w){3}\.)?(youtube\.com|invidio\.us|invidious\.flokinet\.to|invidious\.materialio\.us|iv\.datura\.network|invidious\.perennialte\.ch|invidious\.fdn\.fr|invidious\.private\.coffee|invidious\.protokolla\.fi|invidious\.privacyredirect\.com|yt\.artemislena\.eu|yt\.drgnz\.club|invidious\.incogniweb\.net|yewtu\.be|inv\.tux\.pizza|invidious\.reallyaweso\.me|iv\.melmac\.space|inv\.us\.projectsegfau\.lt|inv\.nadeko\.net|invidious\.darkness\.services|invidious\.jing\.rocks|invidious\.privacydev\.net|inv\.in\.projectsegfau\.lt|invidious\.drgns\.space)/(channel|user|c).+"
+reddit_regex="^(http(s)?://)?((w){3}\.)?reddit\.com.*"
+vimeo_regex="^(http(s)?://)?((w){3}.)?vimeo\.com.*"
+if echo $url | grep -Ex "$yt_regex" >/dev/null ; then
+ list="$(getYoutubeRss "$url")"
+elif echo $url | grep -Ex "$reddit_regex" >/dev/null ; then
+ list="$(getRedditRss "$url")"
+# vimeo actually works with getlink
+elif echo $url | grep -E "$vimeo_regex" >/dev/null ; then
+ list="$(getVimeoRss "$url")"
+elif echo $url | grep -E "github.com" >/dev/null ; then
+ list="$(getGithubRss "$url")"
+# gitlab also works with getlink
+elif echo $url | grep -E "gitlab.com/[a-zA-Z0-9].*" >/dev/null ; then
+ list="$(getGitlabRss "$url")"
+elif echo $url | grep -E "medium.com/tag" >/dev/null ; then
+ list="$(getMediumRss "$url")"
+else
+ list="$(getlink "$url")"
+fi
+
+[ "$(echo "$list" | wc -l)" -eq 1 ] && chosen_link="$list" || chosen_link=$(printf '%s\n' "${list[@]}" | dmenu -p "Choose a feed:")
+tags="$2"
+if which rssadd;
+ then rssadd "$chosen_link" "$tags"
+fi
+echo "$chosen_link" "$tags"
diff --git a/saferm b/saferm
index ca49554..c27b143 100755
--- a/saferm
+++ b/saferm
@@ -5,33 +5,33 @@ realrm="$(which rm)"
copy="$(which cp) -R"
if [ $# -eq 0 ]; then
- exec $realrm
+ exec $realrm
fi
flags=""
while getopts "dfiPRrvW" opt; do
- case $opt in
- f) exec $realrm "$@" ;;
- *) flags="$flags -$opt" ;;
- esac
+ case $opt in
+ f) exec $realrm "$@" ;;
+ *) flags="$flags -$opt" ;;
+ esac
done
shift $((OPTIND - 1))
if [ ! -d "$archive" ]; then
- if [ ! -w "$HOME" ]; then
- echo "$0 failed: can't create $archive in $HOME" >&2
- exit 1
- fi
- mkdir "$archive"
- chmod 700 "$archive"
+ if [ ! -w "$HOME" ]; then
+ echo "$0 failed: can't create $archive in $HOME" >&2
+ exit 1
+ fi
+ mkdir "$archive"
+ chmod 700 "$archive"
fi
for arg; do
- newname="$archive/$(date "+%S.%M.%H.%d.%m").$(basename "$arg")"
- if [ -f "$arg" ] || [ -d "$arg" ]; then
- $copy "$arg" "$newname"
- fi
+ newname="$archive/$(date "+%S.%M.%H.%d.%m").$(basename "$arg")"
+ if [ -f "$arg" ] || [ -d "$arg" ]; then
+ $copy "$arg" "$newname"
+ fi
done
exec $realrm "$flags" "$@"
diff --git a/scan b/scan
index c35798f..f06d5a4 100755
--- a/scan
+++ b/scan
@@ -5,7 +5,7 @@ file=$(find . -mindepth 2 -type f 2>/dev/null | sed 's|^\./||' | sort | dmenu -i
# If a file was selected
if [ -n "$file" ]; then
- echo "You selected: $file"
- # Do something with the selected file here, like open it:
- # xdg-open "$file" # Uncomment if desired
+ echo "You selected: $file"
+ # Do something with the selected file here, like open it:
+ # xdg-open "$file" # Uncomment if desired
fi
diff --git a/sysact b/sysact
new file mode 100755
index 0000000..f1ac203
--- /dev/null
+++ b/sysact
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+# A dmenu wrapper script for system functions.
+export WM="dwm"
+case "$(readlink -f /sbin/init)" in
+ *systemd*) ctl='systemctl' ;;
+ *) ctl='loginctl' ;;
+esac
+
+wmpid(){ # This function is needed if there are multiple instances of the window manager.
+ tree="$(pstree -ps $$)"
+ tree="${tree#*$WM(}"
+ echo "${tree%%)*}"
+}
+
+lock(){
+ mpc pause
+ pauseallmpv
+ wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
+ kill -44 $(pidof dwmblocks)
+ slock
+ wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
+ kill -44 $(pidof dwmblocks)
+}
+
+case "$(printf "🔒 lock\n🚪 leave $WM\n♻️ renew $WM\n🐻 hibernate\n🔃 reboot\n🖥️shutdown\n💤 sleep\n📺 display off" | dmenu -i -p 'Action: ')" in
+ '🔒 lock') lock ;;
+"🚪 leave $WM") kill -TERM "$(wmpid)" ;;
+"♻️ renew $WM") kill -HUP "$(wmpid)" ;;
+'🐻 hibernate') slock $ctl hibernate -i ;;
+'💤 sleep') slock $ctl suspend -i ;;
+'🔃 reboot') $ctl reboot -i ;;
+'🖥️shutdown') $ctl poweroff -i ;;
+'📺 display off') xset dpms force off ;;
+*) exit 1 ;;
+esac
diff --git a/todo b/todo
index fbb893b..ecabbc7 100755
--- a/todo
+++ b/todo
@@ -13,16 +13,16 @@ prompt="Add/delete a task: "
cmd=$(dmenu -l "$height" -p "$prompt" "$@" < "$file")
while [ -n "$cmd" ]; do
- if grep -q "^$cmd\$" "$file"; then
- grep -v "^$cmd\$" "$file" > "$file.$$"
- mv "$file.$$" "$file"
+ if grep -q "^$cmd\$" "$file"; then
+ grep -v "^$cmd\$" "$file" > "$file.$$"
+ mv "$file.$$" "$file"
height=$(( height - 1 ))
- else
- echo "$cmd" >> "$file"
- height=$(( height + 1 ))
- fi
+ else
+ echo "$cmd" >> "$file"
+ height=$(( height + 1 ))
+ fi
- cmd=$(dmenu -l "$height" -p "$prompt" "$@" < "$file")
+ cmd=$(dmenu -l "$height" -p "$prompt" "$@" < "$file")
done
exit 0
diff --git a/tst b/tst
deleted file mode 100755
index 8734d35..0000000
--- a/tst
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-tabbed -c st -w
diff --git a/unix b/unix
index 54745b0..6634f48 100755
--- a/unix
+++ b/unix
@@ -6,12 +6,12 @@
cat <<'eof'
,_ ,_==▄▂
, ▂▃▄▄▅▅▅▂▅¾. / /
- ▄▆<´ "»▓▓▓%\ / / / /
+▄▆<´ "»▓▓▓%\ / / / /
,▅7" ´>▓▓▓% / / > / >/%
▐¶▓ ,»▓▓¾´ /> %/%// / /
▓▃▅▅▅▃,,▄▅▅▅Æ\// ///>// />/ /
V║«¼.;→ ║<«.,`=// />//%/% / /
- //╠<´ -²,)(▓~"-╝/¾/ %/>/ />
+//╠<´ -²,)(▓~"-╝/¾/ %/>/ />
/ / / ▐% -./▄▃▄▅▐, /7//;//% / /
/ ////`▌▐ %zWv xX▓▇▌//&;% / /
/ / / %//%/¾½´▌▃▄▄▄▄▃▃▐¶\/& /
diff --git a/via b/via
index eeb3477..75f19ef 100755
--- a/via
+++ b/via
@@ -3,13 +3,13 @@
PATH="$HOME/.config/via:$PATH"
case "$1" in
- -r) # rebuild cache first
- via-feed -r | via-menu | via-open
- ;;
- -ro) # rebuild cache only
- via-feed -r >/dev/null
- ;;
- *)
- via-feed | via-menu | via-open
- ;;
+ -r) # rebuild cache first
+ via-feed -r | via-menu | via-open
+ ;;
+ -ro) # rebuild cache only
+ via-feed -r >/dev/null
+ ;;
+ *)
+ via-feed | via-menu | via-open
+ ;;
esac
diff --git a/via-feed b/via-feed
index 4d1935f..ff9701d 100755
--- a/via-feed
+++ b/via-feed
@@ -3,10 +3,15 @@
cache="$HOME/.cache/via"
if [[ "$1" == "-r" ]] || [[ ! -e "$cache" ]]; then
- cat "$HOME/.config/via/shortcuts" > "$cache"
- cat "$HOME/.config/via/websites" >> "$cache"
- find "$HOME" -mindepth 1 \( -name ".*" -o -path "$HOME/cell" -o -path "$HOME/phone/*" \) -prune -o -print | sort >> "$cache"
+ cat "$HOME/.config/via/shortcuts" > "$cache"
+ cat "$HOME/.config/via/websites" >> "$cache"
+ find "$HOME" -mindepth 1 \( -type d -name ".*" ! -path "$HOME/.scripts" -o -path "$HOME/cell" -o -path "$HOME/phone/*" \) -prune -o -print | sort >> "$cache"
+ # notify-send "via cache updated."
fi
-wmctrl -xl | sed "s/^[^.]*\.//;s/ \+\S\+ \+/ /;s/^/w /;s/ \+/ /g"
-cat "$cache"
+if [ "$CRON" = "1" ]; then
+ exit 0
+else
+ wmctrl -xl | sed "s/^[^.]*\.//;s/ \+\S\+ \+/ /;s/^/w /;s/ \+/ /g"
+ cat "$cache"
+fi
diff --git a/via-menu b/via-menu
index e3cc35e..36f792e 100755
--- a/via-menu
+++ b/via-menu
@@ -1,3 +1,3 @@
#!/bin/bash
-dmenu -p "via" -i -l 15
+dmenu -p "via" -i -l 30
diff --git a/via-open b/via-open
index e768459..0da2642 100755
--- a/via-open
+++ b/via-open
@@ -3,54 +3,54 @@
exec &> /dev/null
while read -r arg; do
- # first try matching by filename or pathname
- case "${arg,,}" in
- w\ *)
- target=$(echo "$arg"|cut -d ' ' -f 3-)
- wmctrl -a "$target"
- ;;
- http*)
- $BROWSER "$arg" &
- ;;
- [^/]*) # doesn't start with '/'
- sh -c "$arg"
- ;;
- *.txt)
- tabbed -c -r 2 $TERMINAL -w '' -e $EDITOR "$arg" &
- # $TERMINAL $EDITOR "$arg" &
- ;;
- *.pdf | *.epub)
- zathura "$arg" &
- ;;
- *.mp3)
- $TERMINAL mpg123 -opulse "$arg" &
- ;;
- *.od[tsp]|*.doc|*.docx|*.ppt|*.pptx|*.xls|*.xlsx)
- libreoffice "$arg" &
- ;;
- *)
- # then try matching by mimetype
- mimetype=$(file -Lb --mime-type "$arg")
- case "$mimetype" in
- text/html)
- $BROWSER "$arg" &
- ;;
- text/* | inode/x-empty | message/rfc822)
- tabbed -c -r 2 $TERMINAL -w '' -e $EDITOR "$arg" &
- # $TERMINAL $EDITOR "$arg" &
- ;;
- inode/directory)
- cd "$arg" || exit
- $TERMINAL &
- cd - || exit
- ;;
- image/*)
- sxiv "$arg" &
- ;;
- *)
- exit 1
- ;;
- esac
- ;;
- esac
+ # first try matching by filename or pathname
+ case "${arg,,}" in
+ w\ *)
+ target=$(echo "$arg"|cut -d ' ' -f 3-)
+ wmctrl -a "$target"
+ ;;
+ http*)
+ $BROWSER "$arg" &
+ ;;
+ [^/]*) # doesn't start with '/'
+ sh -c "$arg"
+ ;;
+ *.txt)
+ # tabbed -c -r 2 $TERMINAL -w '' -e $EDITOR "$arg" &
+ $TERMINAL $EDITOR "$arg" &
+ ;;
+ *.pdf | *.epub)
+ zathura "$arg" &
+ ;;
+ *.mp3)
+ $TERMINAL mpg123 -opulse "$arg" &
+ ;;
+ *.od[tsp]|*.doc|*.docx|*.ppt|*.pptx|*.xls|*.xlsx)
+ libreoffice "$arg" &
+ ;;
+ *)
+ # then try matching by mimetype
+ mimetype=$(file -Lb --mime-type "$arg")
+ case "$mimetype" in
+ text/html)
+ $BROWSER "$arg" &
+ ;;
+ text/* | inode/x-empty | message/rfc822)
+ # tabbed -c -r 2 $TERMINAL -w '' -e $EDITOR "$arg" &
+ $TERMINAL $EDITOR "$arg" &
+ ;;
+ inode/directory)
+ cd "$arg" || exit
+ $TERMINAL &
+ cd - || exit
+ ;;
+ image/*)
+ sxiv "$arg" &
+ ;;
+ *)
+ exit 1
+ ;;
+ esac
+ ;;
+ esac
done
diff --git a/viaup b/viaup
new file mode 100755
index 0000000..cd5642a
--- /dev/null
+++ b/viaup
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+export HOME=/home/filipek
+
+via-feed -r > /dev/null
+
+notify-send "via cache updated."
diff --git a/volume b/volume
index 3da8d8f..7047805 100755
--- a/volume
+++ b/volume
@@ -2,8 +2,8 @@
# TODO: see if pulseaudio is running
case "$1" in
- up) pactl set-sink-volume @DEFAULT_SINK@ "+5%" ;;
- down) pactl set-sink-volume @DEFAULT_SINK@ "-5%" ;;
- mute) pactl set-sink-mute @DEFAULT_SINK@ toggle ;;
- *) pactl set-sink-volume @DEFAULT_SINK@ "$1" ;;
+ up) pactl set-sink-volume @DEFAULT_SINK@ "+5%" && notify-send "Volume increased by 5%" ;;
+ down) pactl set-sink-volume @DEFAULT_SINK@ "-5%" && notify-send "Volume decreased by 5%" ;;
+ mute) pactl set-sink-mute @DEFAULT_SINK@ toggle && notify-send "Volume muted/unmuted" ;;
+ *) pactl set-sink-volume @DEFAULT_SINK@ "$1" && notify-send "Volume increased by $1%" ;;
esac
diff --git a/wrocwttr b/wrocwttr
index b1bb3af..4aa5b3a 100755
--- a/wrocwttr
+++ b/wrocwttr
@@ -1,10 +1,12 @@
#!/bin/sh
-export DISPLAY=:0.0
-export HOME=/home/filipek
+# export DISPLAY=:0.0
+# export HOME=/home/filipek
-temp=$(curl wttr.in/Wrocław?format=1 | awk '{print $2}')
+# ł is URL-encoded
+temp=$(curl "wttr.in/Wroc%C5%82aw?format=1" | awk '{print $2}')
file="$HOME/.cache/weather/wroc.txt"
+[ -z "$temp" ] && exit 1
echo "$temp" > "$file"
-notify-send "Temperature updated."
+# notify-send "Temperature updated."