Use mpv
for webcam. ffplay
could also be used, but mpv
is easier for shortcuts.
no-osc To remove on-screen bar
low-latency Removed the stutter from default play of video
video-align Brings the top margin down
video-zoom Zooms the video, so face and certain region is well covered.
title To give, so useful to set window rules in WindowManager
mpv av://v4l2:/dev/video0 --profile=low-latency --no-osc --untimed --video-align-y=0.6 --video-zoom=1.5 --title=webcam " $@ "
Window rule with hyprland
windowrulev2 = rounding 120,title:^(webcam)$
# windowrulev2 = bordercolor rgba(2e8b57ff) rgba(2e8b57ff), title:webcam
windowrule = size 17% 27%, title:webcam
windowrulev2 = move 82% 71%, title:webcam
bind = SUPER, F7, exec, d-webcam
# setup
connect () {
ip=" $( adb shell ip route | awk ' {print $9}' ) "
adb devices && adb tcpip 5555 && adb connect " $ip " :5555
# Run `adb disconnect` once you're done
}
# audio recording
audio () {
[ -d ~ /music/audio/ ] || mkdir -p ~ /music/audio/
scrcpy --no-video --audio-source=mic \
--audio-bit-rate=128K \
--record=" $( xdg-user-dir MUSIC) /audio/$( date +%d_%b_%I:%M) -recording.opus"
}
# works like a charm
camera () {
scrcpy --video-source=camera \
--audio-source=mic \
--camera-facing=back \
--camera-fps=40
}
# sound in earphone - fix mic
game () {
scrcpy --no-video --audio-output-buffer=10
}
# Call the functions based on user input
if [ " $1 " = " connect" ]; then
connect
elif [ " $1 " = " audio" ]; then
audio
elif [ " $1 " = " camera" ]; then
camera
elif [ " $1 " = " game" ]; then
game
else
exit 1
fi
Script to bookmark link into org-mode file.
source d-var.conf
bookmark=" ${1:- $(printf " %s\n%s" " $( wl-paste -p) " " $( wl-paste) " | $D_MENU -i -p ' ' )} "
# file="$HOME/.local/share/dict/bookmarks"
file=" $HOME /d-sync/notes/bookmarks.org"
# Just a variable to show as prompt while adding name (confirmation)
site=" $( echo " ${bookmark} " | sed ' s/ //g' ) "
if [[ -z " $site " ]]; then
exit 0
elif grep -qF " $site " " $file " ; then
notify-send " Oops.. $site " " Already in bookmark!"
exit 0
fi
# Eg names so you can quickly name
# notify-send
examples=(" reddit" " twitter" " git-linux" " git-emacs" " git-droid" " TODO" )
title=" $( printf ' %s\n' " ${examples[@]} " | $W_MENU -l 2 -p " ${site} => Title" | sed ' s/ /-/g' ) "
# Add your org mode file path here (headings are in level 2 in my file)
getheadings=" $( rg " ^\*\* " " ${file} " | sed ' /** gnus/q' | awk ' {print $2 }' ) "
# ^ prints heading upto "** elfeed"
# i have added rest as rss feeds so
tags=" $( rg -o " __([[:alnum:][:nonascii:]_-]*)" " $file " | uniq | sed ' s/__//g' | $D_MENU -p " ${title} => " | sed ' s/ /_/g' ) "
# Prints out the heading text, so `sed` can append it to that heading level
[[ -n " ${title} " ]] && section=" $( printf " %s" " $getheadings " | $D_MENU -p ' Heading' | sed ' s/ //g' ) "
mark-print ()
{
# Sed appends the link in a clean way
sed -i " /$section $/a + [[$site ][${title} __${tags} ]]" " $file " &&
notify-send " Bookmark added!" " $site is now saved under ==> $section "
}
if grep -qF " $site " " $file " ; then
notify-send " Oops.. $site " " Already in bookmark!"
elif [[ -n " ${section} " ]]; then
mark-print
else
notify-send " Give a title & section to add mark"
fi
To toggle capslock with control
# hyprctl keyword input:kb_options ctrl:nocaps
hyprctl keyword input:kb_options caps:caps
Picker using hyprpicker
To insert the colors in hex value
source d-var.conf
a1=" Pick a colour (HEX)"
a2=" 🍎 Choose a Colorname"
a3=" 🎨 Pick a Colour (RGB)"
pick_or_treat=$( printf " $a1 \n$a2 \n$a3 " | $D_MENU -i -p " 🎃 " )
case $pick_or_treat in
$a1 )
hyprpicker -a -f hex
;;
$a2 )
chosen=$( bat ~ /d-git/d-bin/treasure/colors | $UNI_MENU -i -p ' 🎨 ' | grep -o " #.*" )
;;
$a3 )
hyprpicker -a -f rgb
;;
* )
exit 0
;;
esac
# Exit if none chosen.
[ -z " $chosen " ] && exit
# If you run this command with an argument, it will automatically insert the
# character. Otherwise, show a message that the emoji has been copied.
if [ -n " $1 " ]; then
# Replace with xdotool or ydotool
wtype " $chosen "
else
# replace with xclip or xsel or x11
printf " $chosen " | wl-copy
# Replace with xdotool for X11
wtype " $chosen "
# Tbh not required
# notify-send "'$chosen' copied to clipboard." &
fi
# some cool dep :
# enchant --- spell check
# espeak-ng -- text-to-speech
word=$( echo " $( bat ~ /.local/share/dict/hist ~ /.local/share/dict/vocab | uniq) " | $menu -p ' Meaning for' )
# echo "$word" >> /home/i/.local/share/dict/hist
# printf '\n%s\n' "$word" >> /home/i/.local/share/dict/hist
online () {
res=$( curl -s " https://api.dictionaryapi.dev/api/v2/entries/en_US/$word " )
regex=$' "definition":"\K(.*?)(?=")'
definitions=$( echo $res | grep -Po " $regex " )
separatedDefinition=$( sed ' :a;N;$!ba;s/\n/\n\n/g' <<< " $definitions" )
notify-send -t 15000 " $word " " $separatedDefinition "
}
offlinewn () {
output=$( sdcv -n0u wn $word )
notify-send -t 15000 " $word " " $output "
sdcv -n0u wn $word | rofi -dmenu -i -theme-str ' window {height:50%; width:50%;}'
}
offlineco () {
output=$( sdcv -n0u collins $word )
notify-send -t 15000 " $word " " $output "
sdcv -n0u collins $word | rofi -dmenu -i -theme-str ' window {height:50%; width:50%;}'
}
offlinedd () {
output=$( sdcv -n0u dictd $word )
notify-send -t 15000 " $word " " $output "
sdcv -n0u dictd $word | rofi -dmenu -i -theme-str ' window {height:50%; width:50%;}'
}
offlinejp () {
output=$( sdcv -n0u enjp $word )
notify-send -t 15000 " $word " " $output "
sdcv -n0u enjp $word | rofi -dmenu -i -theme-str ' window {height:50%; width:50%;}'
}
offlinesl () {
output=$( sdcv -n0u Collin $word )
notify-send -t 15000 " $word " " $output "
sdcv -n0u Collin $word | rofi -dmenu -i -theme-str ' window {height:50%; width:50%;}'
}
offlinefr () {
output=$( sdcv -n0u enfr $word )
notify-send -t 15000 " $word " " $output "
sdcv -n0u enfr $word | rofi -dmenu -i -theme-str ' window {height:50%; width:50%;}'
}
offlinesp () {
output=$( sdcv -n0u ensp $word )
notify-send -t 15000 " $word " " $output "
sdcv -n0u ensp $word | rofi -dmenu -i -theme-str ' window {height:50%; width:50%;}'
}
a1=" WordNet Dictionary"
a2=" 📖 Collins Dictionary"
a3=" 📘 General Dict"
a4=" 🈚 Japanese Word Translate"
a5=" 📔 Simple Dictionary"
a6=" 🍟 French Word Translate"
a7=" 🎯 Spanish Word Translate"
b1=" Search Online"
# chose=$(printf "📖 Offline dictionary\n📗 Oxford\n📘 Dict gcide\n📙 japanese dict\n📑 Online dictionary" | rofi -rofi -dmenu -i -theme-str 'window {height:50%; width:50%;}' -i -p '📑 Choose your Thesaurus ' -theme-str 'window {width: 30%;height: 40%;}')
chose=$( printf " $a5 \n$a1 \n$a2 \n$a3 \n$a4 \n$a6 \n$a7 \n$b1 " | $menu -i -l 10 -p ' Choose Thesaurus ' )
case $chose in
" $a1 " ) offlinewn ;;
" $a2 " ) offlineco ;;
" $a3 " ) offlinedd ;;
" $b1 " ) online ;;
" $a4 " ) offlinejp ;;
" $a5 " ) offlinesl ;;
" $a6 " ) offlinefr ;;
" $a7 " ) offlinesp ;;
esac
Extract
Extract utility on most compressed files.
Usage d-ext <files>
for fi in " $@ " ; do
if [ -f " $fi " ] ; then
case $fi in
* .tar.bz2) tar xjf " $fi " ;;
* .tar.gz) tar xzf " $fi " ;;
* .bz2) bunzip2 " $fi " ;;
* .rar) unrar x " $fi " ;;
* .gz) gunzip " $fi " ;;
* .tar) tar xf " $fi " ;;
* .tbz2) tar xjf " $fi " ;;
* .tgz) tar xzf " $fi " ;;
* .zip) unzip " $fi " ;;
* .7z) 7z x " $fi " ;;
* .tar.xz) tar xf " $fi " ;;
* .tar.zst) unzstd " $fi " ;;
* ) echo " '$fi ' cannot be extracted via ex()" ;;
esac
else
echo " '$fi ' is not a valid file"
fi ;
done
Toggle touchpad in wayland
HYPRLAND_DEVICE=" elan0522:01-04f3:31c3-touchpad"
if [ -z " $XDG_RUNTIME_DIR " ]; then
export XDG_RUNTIME_DIR=/run/user/$( id -u)
fi
export STATUS_FILE=" $XDG_RUNTIME_DIR /touchpad.status"
enable_touchpad () {
printf " true" > " $STATUS_FILE "
notify-send -u normal " Enabling Touchpad"
hyprctl keyword " device:$HYPRLAND_DEVICE :enabled" true
}
disable_touchpad () {
printf " false" > " $STATUS_FILE "
notify-send -u normal " Disabling Touchpad"
hyprctl keyword " device:$HYPRLAND_DEVICE :enabled" false
}
if ! [ -f " $STATUS_FILE " ]; then
disable_touchpad
else
if [ $( cat " $STATUS_FILE " ) = " true" ]; then
disable_touchpad
elif [ $( cat " $STATUS_FILE " ) = " false" ]; then
enable_touchpad
fi
fi
To run idle timeout function when audio is running or not.
Useful to avoid suspending or locking screen.
# only suspend if audio isn't running
if [ " $( pw-cli i all | rg running) " ]; then
eval " $1 "
else
eval " $2 "
fi
Menu Launcher
Generic menu launcher for scripts.
To index all scripts.
source d-var.conf
menuopts=(" Powermenu" " Change Wallpaper" " Handle Stuffs" " Music Menu" " Pirate Mode" " Insert Emoji/Icons" " Dictionary" " Set Reminder" " ⏲ Time & Date Now" " System Stats" " YouTube" " TODO" " Web Search" )
chosen=$( printf ' %s\n' " ${menuopts[@]} " | $D_MENU )
case " $chosen " in
" ${menuopts[0]} " ) d-power ;;
" ${menuopts[1]} " ) d-walls ;;
" ${menuopts[2]} " ) d-stuff ;;
" ${menuopts[3]} " ) d-mpdplay ;;
" ${menuopts[4]} " ) d-pirt ;;
" ${menuopts[5]} " ) d-unicodes ;;
" ${menuopts[6]} " ) d-dict ;;
" ${menuopts[7]} " ) d-remind ;;
" ${menuopts[8]} " ) d-time ;;
" ${menuopts[9]} " ) d-stats ;;
" ${menuopts[10]} " ) ytfzf -D ;;
" ${menuopts[11]} " ) d-todo ;;
" ${menuopts[12]} " ) d-search ;;
* ) exit 1 ;;
esac
Music Player Menu
An script to play mpd music.
MPC=" mpc --quiet -p ${1:- 6600} "
pidof -x mpd || mpd
source d-var.conf
DMENU () {
# Vertical menu if $3 is given
printf ' %s\n' " $1 " | $L_MENU -p " $2 "
}
get_playlist () {
$MPC -f " %position% - %artist% - %album% - %title%" playlist
}
select_from () {
DMENU " $1 " " Select $2 " $height
}
add () {
all=" [ALL]"
local artist=$( select_from " $( $MPC list Artist) \n$all " " artist" )
if [ " $artist " = " $all " ]; then
$MPC listall | $MPC add;
elif [ -n " $artist " ]; then
local albums=$( $MPC list Album Artist " $artist " )
local album=$( select_from " $albums \n$all " " album" )
if [ " $album " = " $all " ]; then
$MPC findadd Artist " $artist "
elif [ -n " $album " ]; then
local songs=$( $MPC list Title Album " $album " )
local song=$( select_from " $songs \n$all " " song" )
if [ " $song " = " $all " ]; then
$MPC findadd Album " $album "
elif [ -n " $song " ]; then
$MPC findadd Title " $song "
fi
fi
fi
}
remove () {
local playlist=$( get_playlist)
local song=$( select_from " $playlist " " song" )
[ -n " $song " ] && $MPC del " ${song%% \ * } "
}
queue () {
nowp=$( mpc status | head -n1)
nextp=$( mpc queued)
notify-send " Now: $nowp " " Next: $nextp "
}
jump () {
local playlist=$( get_playlist)
local song=$( select_from " $playlist " " song" )
[ -n " $song " ] && $MPC play " ${song%% \ * } "
}
toggle (){
$MPC toggle
}
play (){
$MPC findadd Title " $( $MPC list title | $L_MENU ) "
$MPC play
}
pause (){
$MPC pause
}
stop (){
$MPC stop
}
next (){
$MPC next
}
prev (){
$MPC prev
}
ytmusic () {
$MPC add " $( yt-dlp -f bestaudio -g " $( ytfzf -LD --ii=' y.com.sb' ) " ) "
}
menuopts=( " Clear" " Add" " Remove" " Jump" " Toggle" " Play" " Pause" " Stop" " Next" " Prev" " Queued" " YT Music" )
while true ; do
action=$( printf ' %s\n' " ${menuopts[@]} " | $L_MENU -p " Do you want to" )
case $action in
" ${menuopts[0]} " ) $MPC clear ;;
" ${menuopts[1]} " ) add ;;
" ${menuopts[2]} " ) remove ;;
" ${menuopts[3]} " ) jump ;;
" ${menuopts[4]} " ) toggle ;;
" ${menuopts[5]} " ) play ;;
" ${menuopts[6]} " ) pause ;;
" ${menuopts[7]} " ) stop ;;
" ${menuopts[8]} " ) next ;;
" ${menuopts[9]} " ) prev ;;
" ${menuopts[10]} " ) queue ;;
" ${menuopts[11]} " ) ytmusic ;;
" " ) exit 0;;
esac
done
Script to get the free stuffs.
# Dependencies - Deluge, mpv
source d-var.conf
mkdir -p $HOME /.cache/notflix
DOWNLOAD_DIR=" $HOME /Documents/Torrent"
baseurl=" https://www.1337x.to"
cachedir=" $HOME /.cache/notflix"
LOG_FILE=" $HOME /.cache/notflix/notflix_history"
[[ -f " $LOG_FILE " ]] && LS=" $( cat $LOG_FILE ) "
[[ -z " $LS " ]] && LS=" "
PAGE=1
scrape ()
{
S_QRY=" $( echo " $QUER_Y " | sed ' s/[[:space:]]/_/g' ) "
# menu="fzf --no-preview --cycle --layout=reverse --header-first --header=Torrent-Results:($S_QRY/Page-$PAGE)"
menu=" $L_MENU -i -p $PAGE *"
[[ -z " $QUER_Y " ]] && exit
query=" $( echo " $QUER_Y " | sed ' s/ /+/g' ) "
b1=" general page"
b2=" movie page"
b3=" latest page"
b4=" top 100"
b5=" trending"
b6=" documentary"
b7=" music"
b8=" free"
chose=$( printf " $b1 \n$b2 \n$b3 \n$b4 \n$b5 \n$b6 \n$b7 \n$b8 " | $D_MENU -l 18 -p ' ' )
case $chose in
" $b1 " ) curl -s $baseurl /search/$query /$PAGE / --compressed > $cachedir /tmp.html ;;
" $b2 " ) curl -s $baseurl /category-search/$query /Movies/1/ --compressed > $cachedir /tmp.html ;;
" $b3 " ) curl -s $baseurl /sort-search/$query /time/desc/$PAGE / --compressed > $cachedir /tmp.html ;;
" $b5 " ) curl -s $baseurl /trending --compressed > $cachedir /tmp.html ;;
" $b4 " ) curl -s $baseurl /top-100 --compressed > $cachedir /tmp.html ;;
" $b6 " ) curl -s $baseurl /cat/Documentaries/$PAGE / --compressed > $cachedir /tmp.html ;;
" $b7 " ) curl -s $baseurl /popular-music-week --compressed > $cachedir /tmp.html ;;
" $b8 " ) curl -s $baseurl /popular-xxx-week --compressed > $cachedir /tmp.html ;;
esac
# Get Titles
grep -o ' <a href="/torrent/.*</a>' $cachedir /tmp.html | sed ' s/<[^>]*>//g' > $cachedir /titles.bw
result_count=$( wc -l $cachedir /titles.bw | awk ' {print $1}' )
if [ " $result_count " -lt 1 ]; then
echo " No Result found!"
exit 0
fi
# Seeders and Leechers
grep -o ' <td class="coll-2 seeds.*</td>\|<td class="coll-3 leeches.*</td>' $cachedir /tmp.html |
sed ' s/<[^>]*>//g' | sed ' N;s/\n/ /' > $cachedir /seedleech.bw
# Size
grep -o ' <td class="coll-4 size.*</td>' $cachedir /tmp.html |
sed ' s/<span class="seeds">.*<\/span>//g' |
sed -e ' s/<[^>]*>//g' > $cachedir /size.bw
# Links
grep -E ' /torrent/' $cachedir /tmp.html |
sed -E ' s#.*(/torrent/.*)/">.*/#\1#' |
sed ' s/td>//g' > $cachedir /links.bw
# Clearning up some data to display
sed ' s/\./ /g; s/\-/ /g' $cachedir /titles.bw |
sed ' s/[^A-Za-z0-9 ]//g' | tr -s " " > $cachedir /tmp && mv $cachedir /tmp $cachedir /titles.bw
awk ' {print NR " - ["$0"]"}' $cachedir /size.bw > $cachedir /tmp && mv $cachedir /tmp $cachedir /size.bw
awk ' {print "[S:"$1 ", L:"$2"]" }' $cachedir /seedleech.bw > $cachedir /tmp && mv $cachedir /tmp $cachedir /seedleech.bw
[[ " $PAGE " > 1 ]] && echo " Previous Page" >> $cachedir /titles.bw
echo " Next Page" >> $cachedir /titles.bw
# Getting the line number
LINEO=$( paste -d\ $cachedir /size.bw $cachedir /seedleech.bw $cachedir /titles.bw | sed ' s/^ //g' | $L_MENU -p ' ' )
LINE=$( echo " $LINEO " | cut -d\- -f1 | awk ' {$1=$1; print}' )
if [ -z " $LINE " ]; then
exit 0
fi
# Next Page
[[ " $LINE " = " Next Page" ]] && PAGE=$(( $PAGE + 1 )) && scrape
# Previous Page
[[ " $LINE " = " Previous Page" ]] && PAGE=" $(( $PAGE - 1 )) " && scrape
url=$( head -n $LINE $cachedir /links.bw | tail -n +$LINE )
fullURL=" ${baseurl}${url} /"
# Requesting page for magnet link
curl -s $fullURL > $cachedir /tmp.html
magnet=" $( grep -Po " magnet:\?xt=urn:btih:[a-zA-Z0-9]*" $cachedir /tmp.html | head -n 1) "
[[ -z " $magnet " ]] && echo " Can't Get the Link!" && exit
PROMPTO=" $( echo -e " Deluge\nAria Daemon\nCopyUrl" | sort | $D_MENU -p ' magnet to' ) "
LOG ()
{
echo " $LINEO " > $LOG_FILE
}
case $PROMPTO in
Deluge)
deluge-console add " $magnet "
notify-send " 🛫 Downloading Torrent"
exit
;;
" Aria Daemon" )
curl http://localhost:6800/jsonrpc -d ' {"jsonrcp":"2.0","id":"someID","method":"aria2.addUri","params":["token:ariatest",["' ${magnet} ' "]]}'
notify-send " Added download"
;;
CopyUrl)
echo " $magnet " | wl-copy
notify-send " 🧲 Copied Magnet"
exit
;;
* )
;;
esac
exit
}
seqr=" $( echo -e " complete\nhashminer\nmusafir\nPSA\nBONE" | $D_MENU -l 10 -p ' ' ) "
[[ -z " $@ " ]] &&
QUER_Y=" $seqr " && scrape
# [[ -z "$@" ]] && read -r -p "Last Torrent: $LS
# Search Torrent: " $seqr && scrape || QUER_Y="$seqr" && scrape
To type note in emacs buffer, and input it into some input place.
pgrep emacs || (notify-send " Are you running emacs daemon?" & exit 1)
source d-var.conf
a1=" Browser Input"
a2=" Capture Note/Thought"
output=$( date +' %d-%a->%H:%M:%S' )
filename=" BrowserInput"
choice=$( printf " $a1 \n$a2 " | $D_MENU -p ' ' )
browser_input () {
touch /tmp/${filename} .md &&
emacsclient -c -F " ((name . \" ${filename} \" ))" /tmp/${filename} .md &&
# pandoc -t markdown -o /tmp/${filename}.md /tmp/${filename}.org &&
# wtype -s 1 "$(bat /tmp/${filename}.md)" >/dev/null &&
mkdir -p /tmp/browse-inputs
mv /tmp/${filename} .md /tmp/browse-inputs/${filename} -${output} .md > /dev/null
}
capture_note () {
emacsclient -c -F " ((name . \" ${filename} \" ))" -e ' (org-capture nil "jj")' -e ' (delete-other-windows)'
}
case $choice in
$a1 ) browser_input ;;
$a2 ) capture_note ;;
* ) exit 1 ;;
esac
Power Menu
source d-var.conf
wifi_m=" Wifi Menu"
power_m=" Power Menu"
sshot_m=" Screen Shot"
lock=" Lock/Suspend"
brightn=" Brightness"
volume=" Change Volume"
poweroff=" Power Off"
reboot=" Reboot"
screenoff=" Screen Off"
brightup=" Increase Brightness"
brightdown=" Decrease Brightness"
volup=" Increase Volume"
voldown=" Decrease Volume"
mute=" Mute"
chosen=" $( printf " $wifi_m \n$power_m \n$sshot_m \n$lock \n$brightn \n$volume " | sort | $S_MENU -p ' ' ) "
case " $chosen " in
" $power_m " )
power=" $( printf " $poweroff \n$reboot \n$screenoff " | sort | $S_MENU -p ' ' ) "
case " $power " in
" $poweroff " ) poweroff ;;
" $reboot " ) reboot ;;
" $screenoff " ) hyprctl dispatch dpms off ;;
esac
;;
" $wifi_m " ) d-wifi ;;
" $lock " ) hyprlock ;;
" $brightn " )
bright=" $( printf " $brightup \n$brightdown " | sort | $D_MENU ) "
case " $bright " in
" $brightup " ) brightnessctl set +2% ;;
" $brightdown " ) brightnessctl set 2%- ;;
esac
;;
" $sshot_m " ) d-sshot ;;
" $volume " )
vol=" $( printf " $volup \n$voldown \n$mute " | sort | $D_MENU -p ' ' ) "
case " $vol " in
" $volup " ) pamixer -ui 5 ;;
" $voldown " ) pamixer -ud 5 ;;
" $mute " ) pamixer -t ;;
esac
;;
* ) exit 1 ;;
esac
Script to read ppt files as pdf.
Requires: soffice | ebook-convert | md2pdf
# zaread cache path
ZADIR=" $HOME " ' /.cache/zaread/'
# reader with which we'll open pdf, epub and converted files
reader=" sioyek"
# here we have the execs we use to convert. if you want to use a custom exec,
# then set it here, and go down in the script to find (and edit) the proper command
MOBI_CMD=" ebook-convert"
OFFICE_CMD=" soffice"
MD_CMD=" md2pdf"
# if $ZADIR doesn't exist, we create it.
if [[ ! -d " $ZADIR " ]]; then
mkdir -p " $ZADIR "
mkdir " $ZADIR " cksum
fi
# if no arguments exit.
if [[ -z $@ ]]; then exit 1; fi
# if zathura is not installed, we force the user to choose a pdf reader
# after three wrong commands, the script exits 1
# if the user inserts a command that exists but is not a pdf reader then... then fuck him.
counter=0
while [[ -z ` command -v " $reader " ` ]]; do
if [ $counter -gt 3 ]; then exit 1; fi
let counter+=1
echo " Seems that you don't have zathura installed. Please choose an installed PDF reader:"
read reader
done
echo " We'll read PDF with $reader ."
# # create position and file variables ##
# complete file name (path excluded):
file=` echo " $@ " | rev | cut -d' /' -f1 | rev`
# complete directory path:
# if it has been inserted absolute path ($@ starts with '/')
if [[ $@ =~ ^/ ]]; then
directory=` echo " $@ " | rev | cut -d' /' -f2- | rev` " /"
# else (relative path inserted)
else
dir=` pwd` " /" ` echo " $@ " | sed ' s|.[^/]*$||' ` " /"
directory=` echo " $dir " | sed ' s|//|/|' `
fi
echo " $directory " " $file "
# get file type
# if the file is itself a pdf or an epub, or we already have a pdf converted version,
# then we don't need a converter. But if it's an already converted document, then
# file position is different: we must distinguish between original and converted files
file_converter=" "
file_mt=` file --mime-type " $directory$file " | sed ' s/^.*: //' `
echo " $file_mt "
cd " $directory "
# $pdffile is a string composed this way: __$file.[pdf,epub]
# if the converted file exists, then it's named like $pdffile
pdffile=` cksum " $file " | sed -r ' s/^([0-9]+) ([0-9]+) (.*)$/\1_\2_\3.pdf/' `
# if the file is a pdf or an epub
if [[ $file_mt == " application/pdf" ]] || [[ $file_mt == " application/epub+zip" ]]; then
file_converter=" none_original"
# if the converted file exists
elif [[ ( -f " $ZADIR$pdffile " ) ]]; then
file_converter=" none_converted"
# if the file is an office file (ooxml or the old format or an opendocument)
elif [[ $file_mt == " application/vnd.openxmlformats-officedocument.wordprocessingml.document" ]] || \
[[ $file_mt == " application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ]] || \
[[ $file_mt == " application/vnd.openxmlformats-officedocument.presentationml.presentation" ]] || \
[[ $file_mt == " application/msword" ]] || \
[[ $file_mt == " application/vnd.ms-excel" ]] || \
[[ $file_mt == " application/vnd.ms-powerpoint" ]] || \
[[ $file_mt == " application/vnd.oasis.opendocument.text" ]] || \
[[ $file_mt == " application/vnd.oasis.opendocument.spreadsheet" ]] || \
[[ $file_mt == " application/vnd.oasis.opendocument.presentation" ]] || \
[[ $file_mt == " text/csv" ]]
then
file_converter=$OFFICE_CMD
# if the file is a mubi ebook
elif [[ $file_mt == " application/octet-stream" ]] && [[ " $file " =~ ^.* \. mobi$ ]] ; then
file_converter=$MOBI_CMD
# if the file is a markdown
elif [[ $file_mt == " text/plain" ]] && [[ " $file " =~ ^.* \. md$ ]] ; then
file_converter=$MD_CMD
fi
# if we don't have a capable converter, we exit
if [[ -z $file_converter ]]; then
echo " The file format is unsupported."
exit 2
# if the file a pdf or an epub, we just open it
elif [[ $file_converter == " none_original" ]]; then
echo " The file is already in PDF format. We just open it."
$reader " $directory$file "
# if we have a converted file, we just open it (the only difference with the case above
# is that the converted file is into cache directory and has a different name)
elif [[ $file_converter == " none_converted" ]]; then
echo " We already converted this file. We just open it."
$reader " $ZADIR$pdffile "
# else, then the file is not a pdf or an epub, and it doesn't exist a converted version,
# but its format is convertible
else
# first, we check if we have the proper converter installed
we_can_convert=` whereis $file_converter | cut -d" :" -f2`
# if we don't have it, we can't do anything, so we exit
if [[ -z $we_can_convert ]]; then
echo " The command we need to convert, $file_converter , doesn't exist on this machine."
exit 4
# else we process the file, and we put the converted version under $zadir$pdffile
else
echo " We are starting to convert the file $file using $file_converter "
if [[ $file_converter == " $OFFICE_CMD " ]]; then
libreoffice --convert-to pdf " $directory$file " --headless --outdir " $ZADIR "
tmpfile=` echo " $file " | sed -r ' s/.[^\.]*$//' ` " .pdf"
mv " $ZADIR$tmpfile " " $ZADIR$pdffile "
elif [[ $file_converter == " $MOBI_CMD " ]]; then
ebook-convert " $directory " " $file " " $ZADIR$pdffile "
elif [[ $file_converter == " $MD_CMD " ]]; then
md2pdf " $directory " " $file " -o " $ZADIR " " $pdffile "
fi
fi
echo " Now we can open the file $ZADIR$pdffile "
# ...and after the conversion we open the file
$reader " $ZADIR$pdffile "
fi
#! /usr/bin/env bash
RED=' \033[0;31m'
BLUE=' \033[0;34m'
NC=' \033[0m'
jq --help > /dev/null 2>&1
if [ $? -eq 127 ]
then
echo " fatal - Please install jq :("
exit 1
fi
json=$( curl -s " https://api.quotable.io/random?maxLength=110" )
if [ -z " $json " ]
then
echo -en " Cannot connect to host. :("
echo
else
echo $json | jq ' .content' > $HOME /.cache/qwote.txt
echo $json | jq ' .author' | cut -d ' "' -f 2 > $HOME /.cache/author.txt
fi
echo -en " ${RED} \e[3m❤ $( cat $HOME /.cache/qwote.txt) ❤\e[0m${NC} "
echo -en " \n${BLUE} \e[3m- $( cat $HOME /.cache/author.txt) \e[0m${NC} "
echo
echo ===================================================
echo
fortune
An efficient, minimal screen recording script.
wl-screenrec
is alot efficient, and fast (rust) than wf-screenrecorder.
source d-var.conf
menuopts=(" Record Video + Audio" " Record Webcam and screen" " Only Video" " Record Small Area in Mouse" " Kill Recording" )
action=$( printf ' %s\n' " ${menuopts[@]} " | $D_MENU -p ' ' )
command=" wl-screenrec "
opts=" --codec=av1"
refreshbar=" pkill -RTMIN+8 waybar"
case " $action " in
" ${menuopts[0]} " ) $command $opts --audio -f ~ /screen-$( date ' +%a-%d-%b@%H:%M:%S' ) .mp4 & $refreshbar ;;
" ${menuopts[1]} " ) d-webcam & $command $opts --audio -f ~ /visual-$( date ' +%a-%d-%b@%H:%M:%S' ) .mp4 & $refreshbar ;;
" ${menuopts[2]} " ) $command $opts -f ~ /visual-$( date ' +%a-%d-%b@%H:%M:%S' ) .mp4 & $refreshbar ;;
" ${menuopts[3]} " ) $command $opts -g " $( slurp) " -f ~ /capture-$( date ' +%a-%d-%b@%H:%M:%S' ) .mp4 & $refreshbar ;;
" ${menuopts[4]} " ) pkill -INT $command && $refreshbar ;;
* ) exit 1 ;;
esac
Simple notifier as reminder using at
source d-var.conf
menuopts=(" now + 5 minutes" " now + 10 minutes" " now + 15 minutes" " now + 25 minutes" " now + 2 hour" " 19:45 today" " 16:30 tomorrow" " 4pm + 1 days" " 10am Jul 31" )
remindopt=(
" Short break Over!"
" Long break done!"
" Drink Water!"
" Stop wasting time & Read something"
" Learn the market"
)
info_remind=" Time - Date ? Like Eg -- hh:mm Jul 10"
# notify-send -t 4000 "${info_remind}"
# define variable for time and text
time=" ${1:- $(printf ' %s\n' " ${menuopts[@]} " | $L_MENU -i -p ' ' )} " && \
text=" $( printf " %s\n" " ${remindopts[@]} " | $L_MENU -p ' ' ) "
# check if both arg given
if [[ " $time " ]]; then
echo " notify-send -u critical ' 🔔 Reminder 💡' '$text '" | at " $time "
else
notify-send " Please set the time and clock"
fi
# txt2regex.sh - Regular Expressions "wizard" made with Bash builtins
#
# Website : https://aurelio.net/projects/txt2regex/
# Author : Aurelio Jargas (verde@aurelio.net)
# License : GPL
# Requires: bash >= 3.0
#
# shellcheck disable=SC1117,SC2034
# SC1117 because it was obsoleted in shellcheck >0.5
# SC2034 because it considers unused vars that I load with eval (ax_*)
#
# Please, read the README file.
#
# $STATUS:
# 0 beginning of the regex
# 1 defining regex
# 12 choosing subregex
# 2 defining quantifier
# 3 really quit?
# 4 choosing session programs
# 9 end of the regex
#
# 20001019 ** 1st version
# 20001026 ++ lots of changes and tests
# 20001028 ++ improvements, public release
# 20001107 ++ bash version check (thanks eliphas)
# 20001113 ++ php support, Progs command
# 20010223 ++ i18n, --all, freshmeat announce (oh no!)
# 20010223 v0.1
# 20010420 ++ id.po, \lfunction_name, s/regexp/regex/ig
# 20010423 ++ --nocolor, --history, Usage(), doNextHist{,Args}()
# ++ flags: interactive, color, allprogs
# ++ .oO(¤user parameters history)
# 20010424 v0.2
# 20010606 ++ option --whitebg
# -- grep from $progs to fit on 24 lines by default
# 20010608 -- clear command (not bash), ++ Clear()
# -- stty command (not bash), ++ $LINES
# -- *Progs*(), ++ Choice(), ChoiceRefresh()
# ++ POSIX character classes [[:abc:]]
# ++ special combinations inside []
# ++ $HUMAN improved with getString, getNumber, Choice
# ++ detailed --help, moved to sourceforge
# 20010613 v0.3
# 20010620 -- seq command (not bash), ++ sek()
# 20010613 v0.3.1
# 20010731 ++ Reset: "RegEx prog :" with automatic length
# ++ new progs: postgres, javascript, vbscript, procmail
# ++ ax_prog: new item: escape char - escape is ok now
# ++ improved meta knowledge on perl, tcl and gawk
# 20010802 v0.4
# 20010821 ++ ShowMeta(), new option: --showmeta
# 20010824 ++ getMeta(), ShowInfo(), new option: --showinfo, $cR color
# 20010828 ++ getItemIndex(), getLargestItem()
# <> Clear(): using \033c, ALL: using for((;;)) ksh syntax
# <> vi == Nvi
# 20010828 v0.5
# 20010831 ++ group & or support- cool!, clearN()
# ++ nice groups balance check -> ((2)), use $COLUMNS
# <> TopTitle(): BLOAT, 3 lines, smart, arrays
# <> Menu(): s/stupid recursion/while/
# ++ Z status to handle 0,menu,0 situation
# <> s/eval/${!var}/
# 20010903 <> Choice: fixed outrange answers
# ++ trapping ^c do clearEnd, ++ new prog: mysql
# ++ history now works with Choice() menus
# ++ history appears when quitting
# 20010905 v0.6
# 20020225 ++ "really quit?" message, ++ --version
# 20020304 <> --history just shows final RE on STDOUT
# ++ --make, --prog, printError()
# ++ groups are now quantifiable
# ++ ready_(date[123], hour[123], number[123])
# 20020304 v0.7
# 20040928 <> bash version test (works in 3.x and newer)
# 20040928 v0.8
# 20040929 <> --help split into individual messages (helps i18n)
# 20051229 <> fixed bug on bash3 for eval contents (thanks Marcus Habermehl)
# 20121221 ** moved to GitHub, please see the Git history from now on
# Every command in this script is a Bash builtin. This is by design.
# Make sure we don't break that rule in future code by strictly
# disallowing any system command.
export PATH=
TEXTDOMAIN=txt2regex
TEXTDOMAINDIR=po
VERSION=0.10b
printError () {
printf ' %s: ' $" ERROR"
# shellcheck disable=SC2059
printf " $@ "
exit 1
}
case " $BASH_VERSION " in
[3-9].* )
: # do nothing
;;
* )
printError ' Bash version >=3.0 required, but you have %s\n' " $BASH_VERSION "
;;
esac
Usage () {
# Ugly code, but isolates in $"..." only the strings that need
# translation and tries to keep the option descriptions aligned even
# when long words are used as meta vars.
printf ' %s txt2regex [--nocolor|--whitebg] [--all|--prog %s]\n' \
$" usage:" $" PROGRAMS"
printf ' %s txt2regex --showmeta\n' \
$" usage:"
printf ' %s txt2regex --showinfo %s [--nocolor]\n' \
$" usage:" $" PROGRAM"
printf ' %s txt2regex --history %s [--all|--prog %s]\n' \
$" usage:" $" VALUE" $" PROGRAMS"
printf ' %s txt2regex --make %s [--all|--prog %s]\n' \
$" usage:" $" LABEL" $" PROGRAMS"
printf ' \n'
printf ' %s\n' $" Options:"
printf ' %-22s%s\n' ' --all' \
$" Select all the available programs"
printf ' %-22s%s\n' ' --nocolor' \
$" Do not use colors"
printf ' %-22s%s\n' ' --whitebg' \
$" Adjust colors for white background terminals"
printf ' %-22s%s\n' ' --prog ' $" PROGRAMS" \
$" Specify which programs to use, separated by commas"
printf ' \n'
printf ' %-22s%s\n' ' --showmeta' \
$" Print a metacharacters table featuring all the programs"
printf ' %-22s%s\n' ' --showinfo ' $" PROGRAM" \
$" Print regex-related info about the specified program"
printf ' %-22s%s\n' ' --history ' $" VALUE" \
$" Print a regex from the given history data"
printf ' %-22s%s\n' ' --make ' $" LABEL" \
$" Print a ready regex for the specified label"
printf ' \n'
printf ' %-22s%s\n' ' -V, --version' \
$" Print the program version and quit"
printf ' %-22s%s\n' ' -h, --help' \
$" Print the help message and quit"
printf ' \n'
exit " ${1:- 0} " # $1 is the exit code (default is 0)
}
# The defaults
is_interactive=1
use_colors=1
has_white_background=0
has_not_supported=0
mode_show_meta=0
mode_show_info=0
GRP1=0
GRP2=0
# Here's the default list of programs shown.
# Edit here or use --prog to overwrite it.
progs=(python egrep grep sed vim emacs)
# ## IMPORTANT DATA ###
# To generate this array:
# grep version: tests/regex-tester.txt | sort | cut -d ' ' -f 1
allprogs=(
awk
chicken
ed
egrep
emacs
expect
find
gawk
grep
javascript
lex
mawk
mysql
perl
php
postgres
procmail
python
sed
tcl
vi
vim
)
# To generate this array:
# grep version: tests/regex-tester.txt | sort | sed "s/.* version: //;s/.*/'&'/"
allversions=(
' awk version 20121220'
' CHICKEN 4.12.0'
' GNU Ed 1.10'
' grep (GNU grep) 3.1'
' GNU Emacs 25.2.2'
' expect version 5.45.4'
' find (GNU findutils) 4.7.0-git'
' GNU Awk 4.1.4'
' grep (GNU grep) 3.1'
' node v8.10.0'
' flex 2.6.4'
' mawk 1.3.3 Nov 1996'
' mysql Ver 14.14 Distrib 5.7.29'
' perl v5.26.1'
' PHP 7.2.24-0ubuntu0.18.04.4'
' psql (PostgreSQL) 10.12'
' procmail v3.23pre 2001/09/13'
' Python 3.6.9'
' sed (GNU sed) 4.4'
' tcl 8.6'
' nvi 1.81.6-13'
' VIM - Vi IMproved 8.0 (2016 Sep 12)'
)
label_names=(
date
date2
date3
hour
hour2
hour3
number
number2
number3
)
label_descriptions=(
' date LEVEL 1: mm/dd/yyyy: matches from 00/00/0000 to 99/99/9999'
' date LEVEL 2: mm/dd/yyyy: matches from 00/00/1000 to 19/39/2999'
' date LEVEL 3: mm/dd/yyyy: matches from 00/00/1000 to 12/31/2999'
' hour LEVEL 1: hh:mm: matches from 00:00 to 99:99'
' hour LEVEL 2: hh:mm: matches from 00:00 to 29:59'
' hour LEVEL 3: hh:mm: matches from 00:00 to 23:59'
' number LEVEL 1: integer, positive and negative'
' number LEVEL 2: level 1 plus optional float point'
' number LEVEL 3: level 2 plus optional commas, like: 34,412,069.90'
)
label_data=(
# date
' 26521652165¤:2¤2¤/¤:2¤2¤/¤:2¤4'
' 24161214161214165¤01¤:2¤/¤0123¤:2¤/¤12¤:2¤3'
' 2(2161|2141)121(2161|4161|2141)1214165¤0¤:2¤1¤012¤/¤0¤:2¤12¤:2¤3¤01¤/¤12¤:2¤3'
# hour
' 2652165¤:2¤2¤:¤:2¤2'
' 24161214161¤012¤:2¤:¤012345¤:2'
' 2(4161|2141)1214161¤01¤:2¤2¤0123¤:¤012345¤:2'
# number
' 24264¤+-¤:2'
' 24264(2165)2¤+-¤:2¤.¤:2¤2'
' 24266(2165)3(2165)2¤+-¤:2¤3¤,¤:2¤3¤.¤:2¤2'
)
# date3 : perl: (0[0-9]|1[012])/(0[0-9]|[12][0-9]|3[01])/[12][0-9]{3}
# hour3 : perl: ([01][0-9]|2[0123]):[012345][0-9]
# number3: perl: [+-]?[0-9]{1,3}(,[0-9]{3})*(\.[0-9]{2})?
# ## -- ###
getItemIndex () { # item, array_items
local item=" $1 "
local i=0
shift
while [ -n " $1 " ]; do
[ " $1 " == " $item " ] && printf ' %d\n' " $i " && return
i=$(( i + 1 ))
shift
done
}
validateProgramNames () {
local name
for name in " $@ " ; do
[ -z " $( getItemIndex " $name " " ${allprogs[@]} " ) " ] &&
printError ' %s: %s\n' $" unknown program" " $name "
done
}
# Parse command line options
while [ $# -gt 0 ]; do
case " $1 " in
--history)
[ -z " $2 " ] && Usage 1
history=" $2 "
shift
is_interactive=0
use_colors=0
hists=" 0${history%% ¤* } "
histargs=" ¤${history#* ¤} "
[ " ${hists# 0} " == " ${histargs# ¤} " ] && unset histargs
;;
--make)
shift
is_interactive=0
use_colors=0
label_name=" ${1% 1} " # final 1 is optional (date1 == date)
label_index=$( getItemIndex " $label_name " " ${label_names[@]} " )
# Sanity check
[ -z " $label_index " ] &&
printError ' %s: "%s": %s\n%s %s\n' \
' --make' " $1 " $" invalid argument" \
$" valid names:" " ${label_names[*]} "
# Set history data
hist=" ${label_data[$label_index]} "
hists=" 0${hist%% ¤* } "
histargs=" ¤${hist#* ¤} "
printf ' \n### %s\n\n' " ${label_descriptions[$label_index]} "
;;
--prog)
[ -z " $2 " ] && Usage 1
shift
eval " progs=(${1// ,/ } )"
validateProgramNames " ${progs[@]} "
;;
--nocolor)
use_colors=0
;;
--whitebg)
has_white_background=1
;;
--showmeta)
mode_show_meta=1
;;
--showinfo)
[ -z " $2 " ] && Usage 1
infoprog=" $2 "
shift
mode_show_info=1
validateProgramNames " $infoprog "
;;
--all)
progs=(" ${allprogs[@]} " )
;;
-V | --version)
printf ' txt2regex %s\n' " $VERSION "
exit 0
;;
-h | --help)
Usage 0
;;
* )
printf ' %s: %s\n\n' " $1 " $" invalid option"
Usage 1
;;
esac
shift
done
set -o noglob
# ## The Regex show
S0_txt=(
$" start to match"
$" on the line beginning"
$" in any part of the line"
)
S0_re=(
' '
' ^'
' '
)
S1_txt=(
$" followed by"
$" any character"
$" a specific character"
$" a literal string"
$" an allowed characters list"
$" a forbidden characters list"
$" a special combination"
$" a POSIX combination (locale aware)"
$" a ready regex (not implemented)"
$" anything"
)
S1_re=(
' '
' .'
' '
' '
' '
' '
' '
' '
' '
' .*'
)
S2_txt=(
$" how many times (repetition)"
$" one"
$" zero or one (optional)"
$" zero or more"
$" one or more"
$" exactly N"
$" up to N"
$" at least N"
)
# COMBO
combo_txt=(
$" uppercase letters"
$" lowercase letters"
$" numbers"
$" underscore"
$" space"
$" TAB"
)
combo_re=(
' A-Z'
' a-z'
' 0-9'
' _'
' '
' @'
)
# TODO use all posix components?
posix_txt=(
$" letters"
$" lowercase letters"
$" uppercase letters"
$" numbers"
$" letters and numbers"
$" hexadecimal numbers"
$" whitespaces (space and TAB)"
$" graphic chars (not-whitespace)"
)
posix_re=(
' alpha'
' lower'
' upper'
' digit'
' alnum'
' xdigit'
' blank'
' graph'
)
# Title (line 1)
# shellcheck disable=SC2256
tit1_txt=(
$" quit"
$" reset"
$" color"
$" programs"
' '
' '
' '
' '
' '
' ^txt2regex$'
)
tit1_cmd=(
' .'
' 0'
' *'
' /'
' '
' '
' '
' '
' '
' '
)
# Title (line 2-3)
tit2_txt=(
$" or"
$" open group"
$" close group"
' '
' '
' '
' '
' '
' '
$" not supported"
)
tit2_cmd=(
' |'
' ('
' )'
' '
' '
' '
' '
' '
' '
' !!'
)
# S2_* arrays: The list of quantifiers (to be used when STATUS=2)
# Every array will be named S2_<prog>: S2_awk, S2_ed, S2_egrep, ...
# The array index refers to the menu item in the "repetition" screen.
# To update this data:
# make test-regex
# grep ' S2 .*OK$' tests/regex-tester.txt
#
while read -r prog_id data; do
# Set the S2_<prog> array for each line. Example:
# S2_egrep=('-' '-' '?' '*' '+' '{@}' '{1,@}' '{@,}')
read -r -a " S2_$prog_id " <<< " $data"
done << 'EOD '
awk - - ? * + !! !! !!
chicken - - ? * + {@} {1,@} {@,}
ed - - \? * \+ \{@\} \{1,@\} \{@,\}
egrep - - ? * + {@} {1,@} {@,}
emacs - - ? * + \\{@\\} \\{1,@\\} \\{@,\\}
expect - - ? * + {@} {1,@} {@,}
find - - ? * + {@} {1,@} {@,}
gawk - - ? * + {@} {1,@} {@,}
grep - - \? * \+ \{@\} \{1,@\} \{@,\}
javascript - - ? * + {@} {1,@} {@,}
lex - - ? * + {@} {1,@} {@,}
mawk - - ? * + !! !! !!
mysql - - ? * + {@} {1,@} {@,}
perl - - ? * + {@} {1,@} {@,}
php - - ? * + {@} {1,@} {@,}
postgres - - ? * + {@} {1,@} {@,}
procmail - - ? * + !! !! !!
python - - ? * + {@} {1,@} {@,}
sed - - \? * \+ \{@\} \{1,@\} \{@,\}
tcl - - ? * + {@} {1,@} {@,}
vi - - \{0,1\} * \{1,\} \{@\} \{1,@\} \{@,\}
vim - - \= * \+ \{@} \{1,@} \{@,}
EOD
# ax_* arrays: Extra regex-related data for all the programs.
# Every array will be named ax_<prog>: ax_awk, ax_ed, ax_egrep, ...
# To check how this data is used in this source code, search for
# something like 'ax_.*5'.
#
# To update this data:
# make test-regex
# grep -E ' ax123 .+OK$' tests/regex-tester.txt # 1,2,3
# grep -E ' a\.b +OK$' tests/regex-tester.txt # 4
# grep -E ' ax5 .+OK$' tests/regex-tester.txt # 5
# grep -E ' ax6 ' tests/regex-tester.txt # 6
# grep -E ' ax7 ' tests/regex-tester.txt # 7
# grep -E ' ax8 ' tests/regex-tester.txt # 8
#
# In PHP, we're using \\ instead of \ as the escape metacharacter
# because it works consistently, being it inside single or double
# quotes. Using only \ would work in some cases, but not in others:
# The literal + is matched by: \+ \\+ [+] [\+] [\\+]
# The literal \ is matched by: \\\\ [\\\\]
#
while read -r prog_id data; do
# Set the ax_<prog> array for each line. Example:
# ax_awk=('' '|' '(' ')' '\' '\.*[---()|+?^$' '\' 'P' '\t')
read -r -a " ax_$prog_id " <<< " $data"
done << 'EOD '
awk - | ( ) \ \.*[---()|+?^$ \ P \t
chicken - | ( ) \\ \.*[---()|+?^$ \ P \t
ed - \| \( \) \ \.*[---------- - P -
egrep - | ( ) \ \.*[-{-(-|+?^$ - P -
emacs - \\| \\( \\) \\ \.*[------+?-- \ P \t
expect - | ( ) \ \.*[-{}()|+?^$ \ P \t
find - | ( ) \ \.*[-{-(-|+?^$ - P -
gawk - | ( ) \ \.*[---(-|+?^$ \ P \t
grep - \| \( \) \ \.*[---------- - P -
javascript - | ( ) \ \.*[---()|+?^$ \ - \t
lex - | ( ) \ \.*[-{}()|+?-- \ P \t
mawk - | ( ) \ \.*[---()|+?^$ \ - \t
mysql - | ( ) \\ \.*[---(-|+?^$ \ P \t
perl - | ( ) \ \.*[-{-()|+?^$ \ P \t
php - | ( ) \\ \.*[-{-()|+?^$ \ P \t
postgres - | ( ) \ \.*[---()|+?^$ \ P \t
procmail - | ( ) \ \.*[---()|+?^$ - - -
python - | ( ) \ \.*[-{-()|+?^$ \ - \t
sed - \| \( \) \ \.*[---------- - P \t
tcl - | ( ) \ \.*[-{}()|+?^$ \ P \t
vi - !! \( \) \ \.*[---------- - P -
vim - \| \( \) \ \.*[---------- \ P \t
EOD
# \.*[]{}()|+?^$ -=false
# [0] Unused
# [1] Which is the metacharacter for alternatives?
# [2,3] Which are the metacharacters for grouping?
# [4] Which is the escape metacharacter?
# [5] Which chars of \.*[]{}()|+?^$ need to be escaped to be matched as
# literals? Note that txt2regex has menus to insert all of those as
# metacharacters (except $), so in user input they will always be
# literal. For ^ and $, some tools consider them literal when not in
# their special start/end position (marked here as -).
# [6] To match '\' inside [], do you need to escape it? If yes, use '\'.
# [7] Has support for [[:POSIX:]] character classes? If yes, use 'P'.
# [8] Does \t inside [] match a tab? If yes, use '\t'.
ColorOnOff () {
# The colors: Normal, Prompt, Bold, Important
[ " $use_colors " -eq 0 ] && return
if [ -n " $cN " ]; then
unset cN cP cB cI cR
elif [ " $has_white_background " -eq 0 ]; then
cN=$( printf ' \033[m' ) # normal
cP=$( printf ' \033[1;31m' ) # red
cB=$( printf ' \033[1;37m' ) # white
cI=$( printf ' \033[1;33m' ) # yellow
cR=$( printf ' \033[7m' ) # reverse
else
cN=$( printf ' \033[m' ) # normal
cP=$( printf ' \033[31m' ) # red
cB=$( printf ' \033[32m' ) # green
cI=$( printf ' \033[34m' ) # blue
cR=$( printf ' \033[7m' ) # reverse
fi
}
# Emulate the 'seq N' command
sek () {
local z=" $1 "
local a=1
while [ " $a " -le " $z " ]; do
printf ' %d\n' " $a "
a=$(( a + 1 ))
done
}
# Is the $1 char present in the $2 text?
charInText () {
local char=" $1 "
local text=" $2 "
local i
for (( i = 0 ; i < ${# text} ; i++ )) ; do
[ " ${text: $i : 1} " == " $char " ] && return 0
done
return 1
}
# Remove all duplicated chars from the $1 text
uniqChars () {
local text=" $1 "
local text_uniq=' '
local i
for (( i = 0 ; i < ${# text} ; i++ )) ; do
charInText " ${text: $i : 1} " " $text_uniq " ||
text_uniq=" $text_uniq ${text: $i : 1} "
done
printf ' %s\n' " $text_uniq "
}
# Escape each $1 in $2 using $3
escapeChars () {
local special_chars=" $1 "
local text=" $2 "
local escape_char=" ${3:- \\ } "
local escaped_text
local i
local this_char
for (( i = 0 ; i < ${# text} ; i++ )) ; do
this_char=${text: $i : 1}
if charInText " $this_char " " $special_chars " ; then
if [ " $this_char$this_char " == " $escape_char " ]; then
# Special case: this_char=\ and escape_char=\\
# The normal escaping (see the next else) would make \\\
# (which is wrong). Here we ensure \\\\ is produced.
escaped_text=" $escaped_text$escape_char$escape_char "
else
# normal escaping
escaped_text=" $escaped_text$escape_char$this_char "
fi
else
# no escaping
escaped_text=" $escaped_text$this_char "
fi
done
printf ' %s\n' " $escaped_text "
}
getLargestItem () {
local largest
while [ -n " $1 " ]; do
[ ${# 1} -gt ${# largest} ] && largest=" $1 "
shift
done
printf ' %s\n' " $largest "
}
# Used to get values from the S2_* and ax_* metachar arrays
getMeta () { # var-name index
local m=" $1 [$2 ]"
m=${! m}
# Remove all non-metacharacters: @ ! -
# Those are used only internally as markers
m=${m// [@!-]/ }
# Remove when getting '?' or '+' for 'vi', since they are unsupported
# and the current values are workarounds using '{}'
[ " $1 " == S2_vi ] && { [ " $2 " -eq 2 ] || [ " $2 " -eq 4 ]; } && m=' '
printf ' %s\n' " $m "
}
ShowMeta () {
local i g1 g2 prog progsize
progsize=$( getLargestItem " ${allprogs[@]} " )
for (( i = 0 ; i < ${# allprogs[@]} ; i++ )) ; do
prog=${allprogs[$i]}
g1=$( getMeta " ax_$prog " 2)
g2=$( getMeta " ax_$prog " 3)
printf " \n%-${# progsize} s" " $prog " # name
printf ' %7s' " $( getMeta " S2_$prog " 4) " # +
printf ' %7s' " $( getMeta " S2_$prog " 2) " # ?
printf ' %7s' " $( getMeta " S2_$prog " 5) " # {}
printf ' %7s' " $( getMeta " ax_$prog " 1) " # |
printf ' %8s' " $g1$g2 " # ()
printf ' %s' " ${allversions[$i]} " # version
done
printf ' \n\n%s\n\n' $" NOTE: . [] [^] and * are the same on all programs."
}
ShowInfo () {
local prog=" $1 "
local escmeta
local index
local i
local metas
local needesc
local posix=$" NO"
local tabinlist=$" NO"
local txtsize
local ver
local -a data
local -a txt
# Getting data
index=$( getItemIndex " $prog " " ${allprogs[@]} " )
ver=" ${allversions[$index]} "
escmeta=$( getMeta " ax_$prog " 4)
needesc=$( getMeta " ax_$prog " 5)
[ " $( getMeta " ax_$prog " 7) " == ' P' ] && posix=$" YES"
[ " $( getMeta " ax_$prog " 8) " == ' \t' ] && tabinlist=$" YES"
# Metacharacters list
# printf arguments: + ? {} | ( )
metas=" $(
printf ' . [] [^] * %s %s %s %s %s%s' \
" $( getMeta " S2_$prog " 4) " \
" $( getMeta " S2_$prog " 2) " \
" $( getMeta " S2_$prog " 5) " \
" $( getMeta " ax_$prog " 1) " \
" $( getMeta " ax_$prog " 2) " \
" $( getMeta " ax_$prog " 3) "
) "
# Populating cool i18n arrays
# shellcheck disable=SC2256
txt=(
$" program"
$" metas"
$" esc meta"
$" need esc"
$" \t in []"
' [:POSIX:]'
)
data=(
" $prog : $ver "
" $metas "
" $escmeta "
" ${needesc// -/ } "
" $tabinlist "
" $posix "
)
# Show me! show me! show me!
ColorOnOff
printf ' \n'
txtsize=$( getLargestItem " ${txt[@]} " )
for (( i = 0 ; i < ${# txt[@]} ; i++ )) ; do
printf " %s %${# txtsize} s %s %s\n" \
" $cR " " ${txt[$i]} " " ${cN:-: } " " ${data[$i]} "
done
printf ' \n'
}
if [ " $mode_show_meta " -eq 1 ]; then
ShowMeta
exit 0
fi
if [ " $mode_show_info " -eq 1 ]; then
ShowInfo " $infoprog "
exit 0
fi
# Screen size/positioning issues
ScreenSize () {
# Note that those are all global variables
x_regex=1
y_regex=4
x_hist=3
y_hist=$(( y_regex + ${# progs[*]} + 1 ))
x_prompt=3
y_prompt=$(( y_regex + ${# progs[*]} + 2 ))
x_menu=3
y_menu=$(( y_prompt + 2 ))
x_prompt2=15
y_max=$(( y_menu + ${# S1_txt[*]} ))
# The defaults case not exported
: ${LINES:= 25}
: ${COLUMNS:= 80}
# TODO automatic check when selecting programs
if [ " $is_interactive " -eq 1 ] && [ $LINES -lt " $y_max " ]; then
printError ' \n%s\n%s\n%s\n' \
" $(
printf \
$" Your terminal has %d lines, but txt2regex needs at least %d lines." \
" $LINES " " $y_max "
) " \
$" Increase the number of lines or select less programs using --prog." \
$" If this line number detection is incorrect, export the LINES variable."
fi
}
_eol=$( printf ' \033[0K' ) # clear trash until EOL
# The cool control chars functions
gotoxy () {
[ " $is_interactive " -eq 1 ] && printf ' \033[%d;%dH' " $2 " " $1 "
}
clearEnd () {
[ " $is_interactive " -eq 1 ] && printf ' \033[0J'
}
clearN () {
[ " $is_interactive " -eq 1 ] && printf ' \033[%dX' " $1 "
}
Clear () {
[ " $is_interactive " -eq 1 ] && printf ' \033c'
}
# Ideas: tab between, $cR on cmd, yellow-white-yellow
printTitleCmd () {
printf ' [%s%s%s]%s ' " $cI " " $1 " " $cN " " $2 "
}
TopTitle () {
gotoxy 1 1
local color
local cmd
local i
local j
local showme
local txt
[ " $is_interactive " -eq 0 ] && return
# 1st line: aplication commands
for (( i = 0 ; i < 10 ; i++ )) ; do
showme=0
txt=${tit1_txt[$i]}
cmd=${tit1_cmd[$i]}
case $i in
[01])
showme=1
;;
2)
[ " $use_colors " -eq 1 ] && showme=1
;;
3)
[ " $STATUS " -eq 0 ] && showme=1
;;
9)
gotoxy $(( COLUMNS - ${# txt} )) 1
printf ' %s\n' " $txt "
;;
esac
if [ $showme -eq 1 ]; then
printTitleCmd " $cmd " " $txt "
else
clearN $(( ${# txt} + 3 ))
fi
done
# 2nd line: grouping and or
if [ " $STATUS " -eq 0 ]; then
printf %s " $_eol "
else
if [ " $STATUS " -eq 1 ]; then
for i in 0 1 2; do
txt=${tit2_txt[$i]}
cmd=${tit2_cmd[$i]}
showme=1
[ $i -eq 2 ] && [ $GRP1 -eq $GRP2 ] && showme=0
if [ $showme -eq 1 ]; then
printTitleCmd " $cmd " " $txt "
else
clearN $(( ${# txt} + 3 ))
fi
done
else # delete commands only
clearN $(( ${# tit2_txt[0]} + 5 + ${# tit2_txt[1]} + 5 + ${# tit2_txt[2]} + 5 ))
fi
# open groups
gotoxy $(( COLUMNS - GRP1 - GRP2 - ${# GRP1} )) 2
color=" $cP "
[ " $GRP1 " -eq " $GRP2 " ] && color=" $cB "
for (( j = 0 ; j < GRP1 ; j++ )) ; do printf ' %s(%s' " $color " " $cN " ; done
[ $GRP1 -gt 0 ] && printf %s " $GRP1 "
for (( j = 0 ; j < GRP2 ; j++ )) ; do printf ' %s)%s' " $color " " $cN " ; done
fi
# 3rd line: legend
txt=${tit2_txt[9]}
cmd=${tit2_cmd[9]}
gotoxy $(( COLUMNS - ${# txt} - ${# cmd} - 1 )) 3
if [ " $has_not_supported " -eq 1 ]; then
printf ' %s%s%s %s' " $cB " " $cmd " " $cN " " $txt "
else
clearN $(( ${# txt} + ${# cmd} + 1 ))
fi
}
doMenu () {
local i
local -a Menui
eval " Menui=(\"\$ {$1 [@]}\" )"
menu_n=$(( ${# Menui[*]} - 1 )) # ini (global var)
if [ " $is_interactive " -eq 1 ]; then
# history
gotoxy $x_hist $y_hist
printf ' %s.oO(%s%s%s)%s%s(%s%s%s)%s%s\n' \
" $cP " " $cN " " $REPLIES " " $cP " " $cN " \
" $cP " " $cN " " $uins " " $cP " " $cN " \
" $_eol "
# title
gotoxy $x_menu $y_menu
printf ' %s%s:%s%s\n' " $cI " " ${Menui[0]} " " $cN " " $_eol "
# itens
for i in $( sek $menu_n ) ; do
printf ' %s%d%s) %s%s\n' " $cB " " $i " " $cN " " ${Menui[$i]} " " $_eol "
i=$(( i + 1 ))
done
clearEnd
# prompt
gotoxy $x_prompt $y_prompt
printf ' %s[1-%d]:%s %s' " $cP " " $menu_n " " $cN " " $_eol "
read -r -n 1
else
doNextHist
REPLY=$hist
fi
}
Menu () {
local name=" $1 "
local ok=0
while [ $ok -eq 0 ]; do
doMenu " $name "
case " $REPLY " in
[1-9])
[ " $REPLY " -gt " $menu_n " ] && continue
ok=1
REPLIES=" $REPLIES$REPLY "
;;
.)
ok=1
LASTSTATUS=$STATUS
STATUS=3
;;
0)
ok=1
STATUS=Z
;;
\* )
ColorOnOff
TopTitle
;;
[\(\)\| ])
[ " $STATUS " -ne 1 ] && continue
[ " $REPLY " == ' )' ] &&
{ [ $GRP1 -gt 0 ] && [ $GRP1 -eq $GRP2 ] || [ $GRP1 -eq 0 ]; } &&
continue
[ " $REPLY " == ' )' ] && STATUS=2
ok=1
REPLIES=" $REPLIES$REPLY "
;;
/)
ok=1
STATUS=4
;;
esac
done
}
doNextHist () {
hists=${hists# ?} # deleting previous item
hist=${hists: 0: 1}
: " ${hist:= .} " # if last, quit
}
doNextHistArg () {
histargs=${histargs#* ¤}
histarg=${histargs%% ¤* }
}
getChar () {
gotoxy $x_prompt2 $y_prompt
if [ " $is_interactive " -eq 1 ]; then
printf ' %s%s%s ' " $cP " $" which one?" " $cN "
read -n 1 -r USERINPUT
uin=" $USERINPUT "
else
doNextHistArg
uin=$histarg
fi
uins=" ${uins} ¤$uin "
F_ESCCHAR=1
}
getCharList () {
gotoxy $x_prompt2 $y_prompt
if [ " $is_interactive " -eq 1 ]; then
printf ' %s%s%s ' " $cP " $" which?" " $cN "
read -r USERINPUT
uin=" $USERINPUT "
else
doNextHistArg
uin=$histarg
fi
# dedup is safe because $uin contains only literal chars (no ranges)
uin=" $( uniqChars " $uin " ) "
uins=" ${uins} ¤$uin "
# putting not special chars in not special places: [][^-]
[ " ${uin# ^} " != " $uin " ] && uin=" ${uin# ^} ^" # move leading ^ to the end
[ " ${uin# ?* -} " != " $uin " ] && uin=" ${uin/ -/ } -" # move non-leading - to the end
[ " ${uin/ ]/ } " != " $uin " ] && uin=" ]${uin/ ]/ } " # move ] to the start
# if any $1, negated list
[ -n " $1 " ] && uin=" ^$uin "
# make it a list
uin=" [$uin ]"
F_ESCCHARLIST=1
}
getString () {
gotoxy $x_prompt2 $y_prompt
if [ " $is_interactive " -eq 1 ]; then
printf ' %stxt:%s ' " $cP " " $cN "
read -r USERINPUT
uin=" $USERINPUT "
else
doNextHistArg
uin=$histarg
fi
uins=" ${uins} ¤$uin "
F_ESCCHAR=1
}
getNumber () {
gotoxy $x_prompt2 $y_prompt
if [ " $is_interactive " -eq 1 ]; then
printf ' %sN=%s%s' " $cP " " $cN " " $_eol "
read -r USERINPUT
uin=" $USERINPUT "
else
doNextHistArg
uin=$histarg
fi
# Remove !numbers
uin=" ${uin// [^0-9]/ } "
# ee
if [ " ${uin/ 666/ x} " == ' x' ]; then
gotoxy 36 1
printf ' %s]:|%s\n' " $cP " " $cN "
fi
if [ -n " $uin " ]; then
uins=" ${uins} ¤$uin "
else
getNumber # there _must_ be a number
fi
}
getPosix () {
local psx
local rpl
unset SUBHUMAN
if [ " $is_interactive " -eq 1 ]; then
Choice --reset " ${posix_txt[@]} "
else
ChoiceAuto
fi
for rpl in $CHOICEREPLY ; do
psx=" ${psx} [:${posix_re[$rpl]} :]"
SUBHUMAN=" $SUBHUMAN , ${posix_txt[$rpl]/ (* )/ } "
done
SUBHUMAN=${SUBHUMAN# , }
F_POSIX=1
uin=" [$psx ]"
uins=" ${uins} ¤:${CHOICEREPLY// / } "
}
getCombo () {
local cmb
local rpl
unset SUBHUMAN
if [ " $is_interactive " -eq 1 ]; then
Choice --reset " ${combo_txt[@]} "
else
ChoiceAuto
fi
for rpl in $CHOICEREPLY ; do
cmb=" $cmb ${combo_re[$rpl]} "
SUBHUMAN=" $SUBHUMAN , ${combo_txt[$rpl]} "
done
# In this menu, @ is used as a placeholder for the tab char
# It will have to be replaced later, so let's set the flag
charInText @ " $cmb " && F_GETTAB=1
SUBHUMAN=${SUBHUMAN# , }
uin=" [$cmb ]"
uins=" ${uins} ¤:${CHOICEREPLY// / } "
}
getREady () { # TODO
unset SUBHUMAN
uin=' '
}
# convert [@] -> [\t] or [<TAB>] based on ax_*[8] value
getListTab () {
local x
if [ " $( getMeta " ax_${progs[$1]} " 8) " == ' \t' ]; then
x=' \t'
else
x=' <TAB>'
fi
uin=" ${uin/@/ $x } "
}
# Set $uin to !! when POSIX character classes are not supported
getHasPosix () {
[ " $( getMeta " ax_${progs[$1]} " 7) " == ' P' ] || uin=' !!'
}
# Escape possible metachars in user input so they will be matched literally
escChar () {
local index=" $1 "
local escape_metachar
local special_chars
escape_metachar=$( getMeta " ax_${progs[$index]} " 4)
special_chars=$( getMeta " ax_${progs[$index]} " 5)
uin=$( escapeChars " $special_chars " " $uin " " $escape_metachar " )
}
# Escape user input: maybe '\' inside [] needs to be escaped
escCharList () {
local escape_metachar
# shellcheck disable=SC1003
if [ " $( getMeta " ax_${progs[$1]} " 6) " == ' \' ]; then
escape_metachar=$( getMeta " ax_${progs[$1]} " 4)
if [[ ${BASH_VERSINFO[0]} -lt 5 ]]; then
uin=" ${uin/ \\ / $escape_metachar$escape_metachar } "
else
uin=" ${uin/ \\ / " $escape_metachar$escape_metachar " } "
fi
fi
}
Reset () {
local p
# It's all global variables in this function
gotoxy $x_regex $y_regex
unset REPLIES uins HUMAN " Regex[*]"
has_not_supported=0
GRP1=0
GRP2=0
maxprogname=$( getLargestItem " ${progs[@]} " ) # global var
for p in " ${progs[@]} " ; do
[ " $is_interactive " -eq 1 ] &&
printf " Regex %-${# maxprogname} s: %s\n" " $p " " $_eol "
done
}
showRegex () {
gotoxy $x_regex $y_regex
local i
local new_part
local save=" $uin "
# For each program
for (( i = 0 ; i < ${# progs[@]} ; i++ )) ; do
[ " $F_ESCCHAR " == 1 ] && escChar " $i "
[ " $F_ESCCHARLIST " == 1 ] && escCharList " $i "
[ " $F_GETTAB " == 1 ] && getListTab " $i "
[ " $F_POSIX " == 1 ] && getHasPosix " $i "
# Check status
case " $1 " in
ax | S2)
eval new_part=" \$ {$1 _${progs[$i]} [$REPLY ]/@/$uin }"
[ " $new_part " == ' -' ] && new_part=' '
Regex[$i ]=" ${Regex[$i]} $new_part "
[ " $new_part " == ' !!' ] && has_not_supported=1
;;
S0)
Regex[$i ]=" ${Regex[$i]}${S0_re[$REPLY]} "
;;
S1)
Regex[$i ]=" ${Regex[$i]}${uin:- ${S1_re[$REPLY]} } "
# When a program does not support POSIX character classes, $uin
# will be set to !! by getHasPosix(). Also check $REPLY to avoid
# a false positive when the user wants to match the !! string.
[ " $REPLY " -eq 7 ] && [ " $uin " == ' !!' ] && has_not_supported=1
;;
esac
[ " $is_interactive " -eq 1 ] &&
printf " Regex %-${# maxprogname} s: %s\n" " ${progs[$i]} " " ${Regex[$i]} "
uin=" $save "
done
unset uin USERINPUT F_ESCCHAR F_ESCCHARLIST F_GETTAB F_POSIX
}
#
# ## And now the cool-smart-MSclippy choice menu/prompt
#
# number of items <= 10, 1 column
# number of items > 10, 2 columns
# maximum number of items = 26 (a-z)
#
# Just refresh the selected item on the screen
ChoiceRefresh () {
local xy=$1
local a=$2
local stat=$3
local opt=$4
# colorizing case status is ON
[ " $stat " == ' +' ] && stat=" $cI$stat$cN "
gotoxy " ${xy#* ;} " " ${xy% ;* } "
printf ' %s%s%s) %s%s ' " $cB " " $a " " $cN " " $stat " " $opt "
}
# --reset resets the stat array
Choice () {
local choicereset=0
[ " $1 " == ' --reset' ] && shift && choicereset=1
local alf
local alpha
local cols
local i
local line
local lines
local numopts=$#
local op
local opt
local opts
local optxy
local rpl
alpha=(a b c d e f g h i j k l m n o p q r s t u v w x y z)
# Reading options and filling default status (off)
i=0
for opt in " $@ " ; do
opts[$i ]=" $opt "
[ " $choicereset " -eq 1 ] && stat[$i ]=' -'
i=$(( i + 1 ))
done
# Checking our number of items limit
[ " $numopts " -gt " ${# alpha[*]} " ] &&
printError ' too much itens (>%d)' " ${# alpha[*]} "
# The header
Clear
printTitleCmd ' .' $" exit"
printf ' | %s' $" press the letters to (un)select the items"
# We will need 2 columns?
cols=1
[ " $numopts " -gt 10 ] && cols=2
# And how much lines? (remember: odd number of items, requires one more line)
lines=$(( numopts / cols))
[ " $(( numopts % cols)) " -eq 1 ] && lines=$(( lines + 1 ))
# Filling the options screen's position array (+3 = header:2, sek:1)
for (( line = 0 ; line < lines; line++ )) ; do
# Column 1
optxy[$line ]=" $(( line + 3 )) ;1"
# Column 2
[ " $cols " == 2 ] && optxy[$(( line + lines)) ]=" $(( line + 3 )) ;40"
done
# Showing initial status for all options
for (( op = 0 ; op < numopts; op++ )) ; do
ChoiceRefresh " ${optxy[$op]} " " ${alpha[$op]} " " ${stat[$op]} " " ${opts[$op]} "
done
# And now the cool invisible prompt
while : ; do
read -s -r -n 1 CHOICEREPLY
case " $CHOICEREPLY " in
[a-z])
# Inverting the option status
for (( alf = 0 ; alf < numopts; alf++ )) ; do
if [ " ${alpha[$alf]} " == " $CHOICEREPLY " ]; then
if [ " ${stat[$alf]} " == ' +' ]; then
stat[$alf ]=' -'
else
stat[$alf ]=' +'
fi
break
fi
done
# Showing the change
[ -z " ${opts[alf]} " ] && continue
ChoiceRefresh " ${optxy[$alf]} " " ${alpha[$alf]} " \
" ${stat[$alf]} " " ${opts[$alf]} "
;;
.)
# Getting the user choices and exiting
unset CHOICEREPLY
for (( rpl = 0 ; rpl < numopts; rpl++ )) ; do
[ " ${stat[$rpl]} " == ' +' ] && CHOICEREPLY=" $CHOICEREPLY $rpl "
done
break
;;
esac
done
}
# Non-interative, just return the answers
ChoiceAuto () {
local i
local z
unset CHOICEREPLY
doNextHistArg
z=${histarg#: } # marker
for (( i = 0 ; i < ${# z} ; i++ )) ; do
CHOICEREPLY=" $CHOICEREPLY ${z: $i : 1} "
done
}
# Fills the stat array with the actual active programs ON
statActiveProgs () {
local i
local p
local ps=" ${progs[*]} "
# For each program
for (( i = 0 ; i < ${# allprogs[@]} ; i++ )) ; do
# Default OFF
p=" ${allprogs[$i]} "
stat[$i ]=' -'
# Case found, turn ON
[ " ${ps/ $p / } " != " $ps " ] && stat[$i ]=' +'
done
}
# ##############################################################################
# ######################## ariel, ucla, vamos! #################################
# ##############################################################################
STATUS=0 # default status
Clear
ScreenSize
ColorOnOff # turning color ON
trap " clearEnd; echo; exit" SIGINT
while : ; do
case ${STATUS:= 0} in
0 | Z)
STATUS=${STATUS/ Z/ 0}
Reset
TopTitle
Menu S0_txt
[ -z " ${STATUS/ [Z34]/ } " ] && continue # 0,3,4: escape status
HUMAN=" ${S0_txt[0]} ${S0_txt[$REPLY]} "
showRegex S0
STATUS=1
;;
1)
TopTitle
Menu S1_txt
[ -z " ${STATUS/ [Z34]/ } " ] && continue # 0,3,4: escape status
if [ -n " ${REPLY/ [1-9]/ } " ]; then
HUMAN=" $HUMAN $REPLY "
if [ " $REPLY " == ' |' ]; then
REPLY=1
elif [ " $REPLY " == ' (' ]; then
REPLY=2
GRP1=$(( GRP1 + 1 ))
elif [ " $REPLY " == ' )' ]; then
REPLY=3
GRP2=$(( GRP2 + 1 ))
else
printf ' \n\n'
printError ' unknown reply type "%s"\n' " $REPLY "
fi
showRegex ax
else
HUMAN=" $HUMAN , ${S1_txt[0]} ${S1_txt[$REPLY]/ (* )/ } "
case " $REPLY " in
1)
STATUS=2
;;
2)
STATUS=2
getChar
;;
3)
STATUS=1
getString
HUMAN=" $HUMAN {$uin }"
;;
4)
STATUS=2
getCharList
;;
5)
STATUS=2
getCharList negated
;;
[678])
STATUS=12
continue
;;
9)
STATUS=1
;;
esac
showRegex S1
fi
;;
12)
[ " $REPLY " -eq 6 ] && STATUS=2 && getCombo
[ " $REPLY " -eq 7 ] && STATUS=2 && getPosix
[ " $REPLY " -eq 8 ] && STATUS=1 && getREady
Clear
TopTitle
HUMAN=" $HUMAN {$SUBHUMAN }"
showRegex S1
;;
2)
TopTitle
Menu S2_txt
[ -z " ${STATUS/ [Z34]/ } " ] && continue # 0,3,4: escape status
rep_middle=$" repeated"
rep_txt=" ${S2_txt[$REPLY]} "
rep_txtend=$" times"
[ " $REPLY " -ge 5 ] && getNumber && rep_txt=${rep_txt/ N/ $uin }
HUMAN=" $HUMAN , $rep_middle ${rep_txt/ (* )/ } $rep_txtend "
showRegex S2
STATUS=1
;;
3)
[ " $is_interactive " -eq 0 ] && STATUS=9 && continue
warning=$" Really quit?"
read -r -n 1 -p " ..$cB $warning [.] $cN "
STATUS=$LASTSTATUS
[ " $REPLY " == ' .' ] && STATUS=9
;;
4)
statActiveProgs
Choice " ${allprogs[@]} "
i=0
unset progs
# Rewriting the progs array with the user choices
for rpl in $CHOICEREPLY ; do
progs[$i ]=${allprogs[$rpl]}
i=$(( i + 1 ))
done
ScreenSize
Clear
STATUS=0
;;
9)
gotoxy $x_hist $y_hist
clearEnd
if [ " $is_interactive " -eq 1 ]; then
noregex_txt=$" no regex"
printf " %stxt2regex --history '%s%s'%s\n\n" \
" $cB " " $REPLIES " " $uins " " $cN "
printf ' %s.\n' " ${HUMAN:- $noregex_txt } "
else
for (( i = 0 ; i < ${# progs[@]} ; i++ )) ; do # for each program
printf " Regex %-${# maxprogname} s: %s\n" \
" ${progs[$i]} " " ${Regex[$i]} "
done
printf ' \n'
fi
exit 0
;;
* )
printError ' STATUS = "%s"\n' " $STATUS "
;;
esac
done
Rssfeed
# usage: d-rssfeed https://blogsite.com
for path in $( echo {,feed/,feeds/,rss/,blog/}{,all,atom,feed,index,posts,posts/default,rss,en,default,rssfeed,blog}{,.rss,.atom,.rss2}{,.xml,? feed=rss2,? format=atom}) ; do
LINE=$( curl -L -s " $1 /$path " | head -1)
if printf " %s" " $LINE " | grep -v xhtml | grep -q -E " feed|xml" ;
then
# show canonical redirect location
curl -sLI -o /dev/null -w ' %{url_effective}' " $1 /$path "
echo
exit
fi
done
exit 1
Rss for YT
Rss feed for youtube channels
rofm=" rofi -dmenu "
mymem=$rofm
# Give the link and it will throw the feed url in YouTube.
# You can choose invidious link too
ytlink=" ${1:- $(printf " %s" | $mymem -p ' youtube link' )} "
fetchyt=$( curl -s $ytlink | grep -Po ' "channelId":".+?"' | cut -d \" -f 4 | head -n 1)
ytfeed=" https://www.youtube.com/feeds/videos.xml?channel_id=${fetchyt} "
invfeed=" https://yt.funami.tech/feed/channel/${fetchyt} "
choose=$( printf " Youtube\nInvious" | $mymem -p ' rss link' )
case $choose in
" Youtube" ) echo " $ytfeed " | wl-copy ;;
" Invfeed" ) echo " $invfeed " | wl-copy ;;
esac
Generic script acts as a search engine for sites.
# Script to search terms in search engines
source d-var.conf
query=" ${1:- $(printf " $( wl-paste -p) \n$( wl-paste) " | $D_MENU -i -p ' ' )} "
echo " $feed " | wl-copy -n
# For prompt/notify on chosen link
shortquery=" $( echo ${feed} | cut -d ' /' -f3,4,5,6 ) "
browsertab=(" Firefox" " Librewolf" " Brave" " MullVad" )
enginestab=(
" 🔗 Website/URL" # 0
" Brave" # 1
" Google Scholar" # 2
" Reddit" # 3
" NixPkgs" # 4
" MyNixOS" # 5
" Nixhub - pkgver" # 6
" NCBI" # 7
" BioConductor" # 8
" Arch-Wiki" # 9
" Libgen-Zlib-Books" # 10
" GitHub" # 11
" AnimeTosho" # 12
" NyaaSi" # 13
" Getty Images" # 14
" DuckDuckGo" # 15
" 1337 Torrent" # 16
)
viabrowser () {
echo " Opening ${nowsearch} in $nowbrowser "
setsid -f $nowbrowser " ${nowsearch} " > /dev/null 2>&1
}
getbrowser=" $( printf ' %s\n' " ${browsertab[@]} " | $D_MENU -p " ${shortfeed} " ) "
case $getbrowser in
" ${browsertab[0]} " ) nowbrowser=" firefox" ;;
" ${browsertab[1]} " ) nowbrowser=" librewolf" ;;
" ${browsertab[2]} " ) nowbrowser=" brave" ;;
" ${browsertab[3]} " ) nowbrowser=" mullvad" ;;
esac
dosearch=" $( printf ' %s\n' " ${enginestab[@]} " | $D_MENU -p " ${shortfeed} " ) "
case $dosearch in
" ${enginestab[0]} " ) nowsearch=" ${query} " ;;
" ${enginestab[1]} " ) nowsearch=" https://search.brave.com/search?q=$query " ;;
" ${enginestab[2]} " ) nowsearch=" https://scholar.google.com/scholar?&q=$query " ;;
" ${enginestab[3]} " ) nowsearch=" https://old.reddit.com/search?q=$query " ;;
" ${enginestab[4]} " ) nowsearch=" https://search.nixos.org/packages?channel=unstable&from=0&size=50&sort=relevance&type=packages&query=$query " ;;
" ${enginestab[5]} " ) nowsearch=" https://mynixos.com/search?q=$query " ;;
" ${enginestab[6]} " ) nowsearch=" https://www.nixhub.io/search?q=$query " ;;
" ${enginestab[7]} " ) nowsearch=" https://www.ncbi.nlm.nih.gov/search/all/?term=$query " ;;
" ${enginestab[8]} " ) nowsearch=" https://www.bioconductor.org/help/search/index.html?q=$query " ;;
" ${enginestab[9]} " ) nowsearch=" https://wiki.archlinux.org/index.php?search=$query " ;;
" ${enginestab[10]} " ) nowsearch=" https://libgen.rs/search.php?req=$query " ;;
" ${enginestab[11]} " ) nowsearch=" https://github.com/search?q=$query &type=repositories" ;;
" ${enginestab[12]} " ) nowsearch=" https://animetosho.org/search?q=$query " ;;
" ${enginestab[13]} " ) nowsearch=" https://nyaa.si/?f=0&c=0_0&q=$query " ;;
" ${enginestab[14]} " ) nowsearch=" https://www.gettyimages.in/search/2/image?family=creative&phrase=$query " ;;
" ${enginestab[15]} " ) nowsearch=" https://duckduckgo.com/?q=$query " ;;
" ${enginestab[16]} " ) nowsearch=" https://1337x.to/search/$query /1" ;;
esac
viabrowser
Script to capture screenshot.
source d-var.conf
menuopts=(" Select Area in Mouse" " Copy Area of Screen" " Full Display" " Copy Whole Display" " Active Window" )
nameopts=(
" notes-refer"
" receipt-"
" ppt-pic"
" share-detail"
)
sleep_for=' sleep 0.5'
temp_pic=' /tmp/thescr.png'
ident=$( date +%Y%m%dT%H%M%S)
gimme () {
output=$( date +' %d-%a %H:%M:%S' )
picname=$( printf ' %s\n' " ${nameopts[@]} " | ${D_MENU} -l 5 -i -p ' ' || echo $output )
tagname=$( echo " " | ${D_MENU} -l 5 -i -p ' ' )
cp $temp_pic ~ /pics/sshots/" ${ident} -${picname} _${tagname} .png"
}
sshot=$( printf ' %s\n' " ${menuopts[@]} " | sort | $D_MENU -p ' Snap ScreenShot of ' )
case " $sshot " in
# "${menuopts[0]}") $sleep_for && grim -g "$(slurp)" "${temp_pic}" && gimme ;;
# "${menuopts[1]}") $sleep_for && grim -g "$(slurp)" - | wl-copy --type image/png ;;
# "${menuopts[2]}") $sleep_for && grim -c "${temp_pic}" && gimme ;;
# "${menuopts[3]}") $sleep_for && grim -c - | wl-copy --type image/pngi ;;
# "${menuopts[4]}") $sleep_for && grim -g \
# "$(hyprctl activewindow -j | jq -r '"\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"')" "${temp_pic}" && gimme ;;
# # *) sleep 0.5 && grim "/tmp/thescr.png" || exit ;;
" ${menuopts[0]} " ) grimblast save area " ${temp_pic} " && gimme ;;
" ${menuopts[1]} " ) grimblast copy area ;;
" ${menuopts[2]} " ) grimblast save output " ${temp_pic} " && gimme;;
" ${menuopts[3]} " ) grimblast copy output ;;
" ${menuopts[4]} " ) grimblast save active " ${temp_pic} " && gimme;;
esac
Status on system as notification.
notify-send -t 8000 " $(
free -m | awk ' NR==2{printf "🐏 Usage: %s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }'
top -bn1 | grep load | awk ' {printf "🧠 Load: %.2f\n", $(NF-2)}'
echo " 🔋 Battery: " " $( cat /sys/class/power_supply/BAT1/capacity) " " %"
) "
# acpi
Give a menu prompt to input the password in places where no pasting is allowed.
source d-var.conf
sleepfor=$( printf " 1\n2\n3\n4\n5" | $D_MENU -p " Sleep for" )
typetool=" dotoolc"
password=$( printf " %s" " $( wl-paste -p) " | $D_MENU -x -p " password: " )
sleep " ${sleepfor} " && echo type " $password " | " $typetool "
Stuff, and all link handler.
Most used, universal way.
# Link handler for every thinkable purpose
# I use `nq` for task scheduling with mpv
source d-var.conf
feed=" ${1:- $(printf " $( wl-paste -p) \n$( wl-paste) " | $D_MENU -i -p ' ' )} "
# echo "$feed" | wl-copy -n
# For prompt/notify on chosen link
shortfeed=" $( echo ${feed} | cut -d ' /' -f3,4,5,6 ) "
# Aria2 for torrents (acts on rpc server)
aria_tor () {
curl ' http://localhost:6800/jsonrpc' || setsid aria2c --enable-rpc --rpc-listen-all &
sleep 4 && curl http://localhost:6800/jsonrpc -d ' {"jsonrcp":"2.0","id":"someID","method":"aria2.addUri","params":["token:ariatest",["' ${feed} ' "]]}'
}
audio_podcast () {
case " $( printf " Song\nPodcast" | $D_MENU -p ' ' ) " in
" Podcast" ) mpc pause; NQDIR=/tmp/podcast nq mpv --force-window --geometry=15% --title=podcast --vid=1 " ${feed} " > /dev/null 2>&1 ;;
" Song" ) pgrep mpd || mpd; mpc add " $( yt-dlp -f bestaudio -g " ${feed} " ) " ;;
* ) exit 1 ;;
esac
}
menuopts=(" Copy Url"
" Fire Fox"
" Download Files"
" YT Vid Download"
" Audio Music Download"
" Podcast Listen Stream"
" View Image"
" Play Watch Stream"
" Misc Download"
" Bookmark"
" Brave"
" Mullvad"
" Chromium"
" Torrent Aria"
" YT Music"
" Search Engine"
" Document Viewer"
" LibreWolf"
" Transmission"
)
case " $( printf ' %s\n' " ${menuopts[@]} " | sort | $D_MENU -p ${shortfeed} ) " in
" ${menuopts[0]} " ) echo " ${feed} " | wl-copy -p ;;
" ${menuopts[1]} " ) setsid -f firefox " ${feed} " > /dev/null 2>&1 ;;
" ${menuopts[2]} " ) setsid aria2c -j 6 -x 16 -c -d ~ /dloads " ${feed} " > /dev/null 2>&1 ;;
" ${menuopts[3]} " ) NQDIR=/tmp/yt-vid nq yt-dlp --embed-metadata --embed-subs -f " bestvideo[height<=1080]+bestaudio" -P ~ /vids/yt " ${feed} " > /dev/null 2>&1 ;;
" ${menuopts[4]} " ) NQDIR=/tmp/yt-music nq yt-dlp -P ~ /d-sync/music/yt/ -icx --embed-metadata " ${feed} " && pidof -x mpd || mpd && mpc update ;;
" ${menuopts[5]} " ) audio_podcast ;;
" ${menuopts[6]} " ) (wget " ${feed} " --output-document=/tmp/image && imv /tmp/image) || imv " ${feed} " ;;
" ${menuopts[7]} " ) NQDIR=/tmp/stream nq mpv -quiet " ${feed} " > /dev/null 2>&1 ;;
" ${menuopts[8]} " ) aria2c -j 6 -x 10 -c -d ~ /vids/documentary/.cache/clean.db/ " ${feed} " ;;
" ${menuopts[9]} " ) d-bookmark " ${feed} " ;;
" ${menuopts[10]} " ) setsid brave " ${feed} " ;;
" ${menuopts[11]} " ) setsid mullvad-browser " ${feed} " ;;
" ${menuopts[12]} " ) setsid chromium " ${feed} " ;;
" ${menuopts[13]} " ) aria_tor ;;
" ${menuopts[14]} " ) pgrep mpd || mpd; mpc add " $( yt-dlp -f bestaudio -g " $( ytfzf -LD ${feed} ) " ) " && mpc play ;;
" ${menuopts[15]} " ) d-search ;;
" ${menuopts[16]} " ) sioyek ${feed} ;;
" ${menuopts[17]} " ) setsid librewolf " ${feed} " ;;
" ${menuopts[18]} " ) transmission-remote -a " ${feed} " ;;
* ) exit 1 ;;
esac
notify-send -t 3500 " $( date ' +%a %b %e %r' ) "
file=" $HOME /.todo.org"
touch " $file "
height=$( wc -l " $file " | awk ' {print $1}' )
prompt=" Add/delete a task: "
cmd=$( rofi -dmenu -l " $height " -config ~ /.config/rofi/list.rasi -p " $prompt " " $@ " < " $file " )
while [ -n " $cmd " ]; do
if grep -q " ^$cmd \$ " " $file " ; then
grep -v " ^$cmd \$ " " $file " > " $file .$$ "
mv " $file .$$ " " $file "
height=$(( height - 1 ))
else
echo " * TODO $cmd " >> " $file "
height=$(( height + 1 ))
fi
cmd=$( rofi -dmenu -l " $height " -config ~ /.config/rofi/list.rasi -p " $prompt " " $@ " < " $file " )
done
exit 0
Script to give choice and display unicodes.
M-x insert-char
in Emacs.
# Script to Insert and copy the unicode char
source d-var.conf
# The famous "get a menu of emojis to copy" script.
# You can the icons for this script in icons/ directory here
chosen=$( bat ~ /d-git/d-bin/treasure/unicodes/* | $UNI_MENU -i -p ' ' | awk ' {print $1}' )
# Exit if none chosen.
[ -z " $chosen " ] && exit
# If you run this command with an argument, it will automatically insert the
# character. Otherwise, show a message that the emoji has been copied.
if [ -n " $1 " ]; then
wtype " $chosen "
else
# replace with xclip or xsel or x11
printf " $chosen " | wl-copy
# Replace with xdotool for X11
wtype " $chosen "
# not required tho
# notify-send "'$chosen' copied to clipboard." &
fi
Insert the chosen URL from bookmark file.
# Simple script which show the bookmarks from org-file which are inserted via d-bookmark
# We can select and it insert the link
source d-var.conf
file=" $HOME /d-sync/notes/bookmarks.org"
echo type " $( rg ' ^\+' ${file} | sed ' s/+ //g' | ${L_MENU} | rg -o ' (http|https)://[a-zA-Z0-9./?=_%&:-]*' ) " | dotoolc
# search for links and show list in menu and type the link of selected item
Script to get clip history and select via dmenu
source d-var.conf
cliphist list | $L_MENU | cliphist decode | wl-copy
Variable to define the choice of launcher configuration.
# Just a file to put variable for $mymem for all scripts.
# So we can unify the menu launcher for all here.
# Options are : rofi, bemenu/dmenu, wofi(search is too slow), fuzzel
# ############# Dynamic menu for common scripts ##############
D_MENU=" fuzzel -d"
W_MENU=" fuzzel -d -w 120"
# ############# Menu for emoji/icons picker ##############
UNI_MENU=" fuzzel -d -l 8"
# ############# Menu for listing ##############
L_MENU=" fuzzel -d -w 85% -l 22"
# L_MENU="bemenu -l 20 -W 0.85"
# L_MENU="rofi -dmenu -i"
# for short width menu
# S_MENU="bemenu -l 5 -c -W 0.14"
S_MENU=" fuzzel -d -w 30%"
To get notification and interactive volume as slider.
# mixercli="pamixer --allow-boost"
volume=$( wpctl get-volume @DEFAULT_AUDIO_SINK@)
volcli=" wpctl set-volume @DEFAULT_AUDIO_SINK@"
togglecli=" wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
down () {
$mixercli -d 5
# volume=$(pamixer --get-volume)
# [ $volume -gt 0 ] && volume=`expr $volume`
# notify-send " Volume Decreased to $volume%" -h int:value:"$volume" -i audio -r 2593 -u normal
}
up () {
$mixercli -i 5
# volume=$(pamixer --get-volume)
# [ $volume -lt 100 ] && volume=`expr $volume`
# notify-send " Volume Increased to $volume%" -h int:value:"$volume" -i audio -r 2593 -u normal
}
toggle () {
muted=" $( pamixer --get-mute) "
if $muted ; then
$mixercli -u
notify-send " Volume Unmuted"
else
$mixercli -m
notify-send " Volume Muted"
fi
}
case " $1 " in
up) up;;
down) down;;
toggle) toggle;;
esac
Script to change random wallpaper.
# Path to wallpapers directory
wall_dir=~ /d-git/d-wallpapers/walls/
if [ -z " $1 " ]; then
wall=" $( find " $wall_dir " | shuf -n1) "
else
wall=" $1 "
fi
rsync " $wall " ~ /.local/share/bg.jpg
# ########## If you use pywal (If not use feh)
# wal -c
# wal -n -i ~/.local/share/bg.jpg
# wal -R
# ##########################
# For wayland users
pkill swaybg
swaybg -i ~ /.local/share/bg.jpg &
Wifi Menu
source d-var.conf
a1=" Disable Wi-Fi"
a2=" Enable Wi-Fi"
# Starts a scan of available broadcasting SSIDs
# nmcli dev wifi rescan
notify-send " Getting list of available Wi-Fi networks..."
wifi_list=$( nmcli --fields " SECURITY,SSID" device wifi list | sed 1d | sed ' s/ */ /g' | sed -E " s/WPA*.?\S/ /g" | sed " s/^--/ /g" | sed " s/ //g" | sed " /--/d" )
# Gives a list of known connections so we can parse it later
connected=$( nmcli -fields WIFI g)
if [[ " $connected " =~ " enabled" ]]; then
toggle=" $a1 "
elif [[ " $connected " =~ " disabled" ]]; then
toggle=" $a2 "
fi
chosen_network=$( echo -e " $toggle \n$wifi_list " | uniq -u | $D_MENU " Wi-Fi SSID: " )
chosen_id=$( echo " ${chosen_network: 3} " | xargs)
# Parses the list of preconfigured connections to see if it already contains the chosen SSID. This speeds up the connection process
if [ " $chosen_network " = " " ]; then
exit
elif [ " $chosen_network " = " $a2 " ]; then
nmcli radio wifi on
elif [ " $chosen_network " = " $a1 " ]; then
nmcli radio wifi off
else
# Message to show when connection is activated successfully
success_message=" You are now connected to the Wi-Fi network \" $chosen_id \" ."
# Get known connections
saved_connections=$( nmcli -g NAME connection)
if [[ $( echo " $saved_connections " | grep -w " $chosen_id " ) = " $chosen_id " ]]; then
nmcli connection up id " $chosen_id " | grep " successfully" && notify-send " Connection Established" " $success_message "
else
if [[ " $chosen_network " =~ " " ]]; then
wifi_password=$( echo ' ' | $D_MENU -password " Password: " )
fi
nmcli device wifi connect " $chosen_id " password " $wifi_password " | grep " successfully" && notify-send " Connection Established" " $success_message "
fi
fi
script to just play the notifying sound
audio=${1:- " /home/idlip/music/yt/misc/linux-notify.ogg" }
ffplay -nodisp -autoexit -loglevel quiet $audio
# mpv --speed=1.0 $audio