My scripts for startup, dmenu, and the command line
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

438 lines
11 KiB

  1. #!/bin/sh
  2. browser_cmd="brave-browser"
  3. browser_new_cmd="brave-browser --new-window"
  4. launch() {
  5. app=$(printf "Notes
  6. Files
  7. Edit
  8. Editor
  9. Open
  10. Pick
  11. Choose
  12. Terminal
  13. Multiplexer
  14. LBRY
  15. Chat
  16. Music
  17. Equalizer
  18. Browser
  19. Hidden browser
  20. Email
  21. Page
  22. Go page
  23. Package info
  24. Images
  25. Play clipboard
  26. Play downloads
  27. Processes" | tr -d '\t' |
  28. dmenu -i -p "Launcher")
  29. case $app in
  30. Notes) st -t "Notes" -e vim "+cd ~/notes/text" "+CtrlP";;
  31. Files) st -t "Files" -e sh -lc nnn;;
  32. Edit) editor;;
  33. Editor) st -t "Editor" -e vim "+CtrlPMRUFiles";;
  34. Open) opener;;
  35. Pick) pick;;
  36. Choose) choose;;
  37. Terminal) st -t "Terminal";;
  38. Page) pages pager "$(printf "1\n2\n3\n" | dmenu -p 'page')";;
  39. Multiplexer) st -t "Multiplexer" -e tmux attach-session -t 0 || st -t "Multiplexer" -e tmux new-session -s 0;;
  40. LBRY) lbry;;
  41. 'Go page') num=$(go_page); pages pager $num;;
  42. Chat) element-desktop;;
  43. Music) st -t "Music" -e ncmpcpp;;
  44. Browser) $browser_cmd;;
  45. 'Hidden browser') $browser_cmd --incognito;;
  46. Email) st -t 'Email' -e neomutt;;
  47. Images) view_images;;
  48. 'Play clipboard') mpv "$(xclip -o -selection clipboard)";;
  49. 'Play downloads') mpv "$HOME/downloads/tmp/$(ls ~/downloads/tmp/ | dmenu -i -l 10 -p 'play')";;
  50. 'Equalizer') qpaeq;;
  51. Processes) st -t "Processes" -e htop;;
  52. esac
  53. }
  54. action() {
  55. action=$(printf "Toggle Music
  56. Pause Music
  57. Play Music
  58. Single on
  59. Command
  60. Command to clipboard
  61. Select VPN
  62. Disable VPN
  63. Enable VPN
  64. VPN Status
  65. Rebind Keys
  66. Show calender
  67. Disable Bar
  68. Password
  69. Username
  70. Alternate password
  71. Select song
  72. Download
  73. Download music
  74. Update cache
  75. Enable Bar
  76. Exit" | tr -d '\t' |
  77. dmenu -i -p "Actions")
  78. case $action in
  79. 'Play Music') mpc play ;;
  80. 'Pause Music') mpc pause ;;
  81. 'Toggle Music') mpc toggle;;
  82. 'Single on') mpc toggle;;
  83. 'Rebind Keys') setup-xbindkeys;;
  84. 'Disable Bar') tmux set -g status off;;
  85. 'Enable Bar') tmux set -g status on;;
  86. 'Command') cmd;;
  87. 'Command to clipboard') cmd_clip;;
  88. 'Username') username;;
  89. 'Password') password;;
  90. 'Alternate password') other_password;;
  91. 'Show calender') notify-send 'Calender' "\n\n$(cal)";;
  92. 'Update cache') { mru update; mru updatedirs; };;
  93. 'Select song') select_song;;
  94. 'Exit') do_exit;;
  95. #This should check for an error code and confirm that download has started
  96. 'Download') download;;
  97. 'Download music') download_music;;
  98. esac
  99. }
  100. login() {
  101. choice=$(printf "Auto
  102. Username
  103. Password
  104. Alternate
  105. Show
  106. Edit" | tr -d '\t' | dmenu -i -p "login")
  107. case $choice in
  108. Username) username;;
  109. Password) password;;
  110. Alternate) other_password;;
  111. Show) show_password;;
  112. esac
  113. }
  114. do_search() {
  115. type=$(printf "Manual
  116. DDG
  117. Definition
  118. Godocs
  119. Mojeek
  120. Package
  121. Github" | tr -d '\t' | dmenu -i -p "Search")
  122. case "$type" in
  123. Manual) p=$(man -k '' | dmenu -l 20 -p 'Manual' | cut -d' ' -f1); if [ -z $p ]; then exit; fi; st -t "Manual - $p" -e man "$p";;
  124. Github) github;;
  125. Godocs) godoc;;
  126. DDG) ddg;;
  127. Package) package;;
  128. Definition) word=$(printf '' | dmenu -p 'word'); if [ -z "$word" ]; then exit; fi; st -e sh -lc "dict \"$word\" | less";;
  129. esac
  130. }
  131. download() {
  132. youtube-dl --add-metadata --no-progress -o "$HOME/downloads/%(title)s.%(ext)s" "$(xclip -selection clipboard -o)"
  133. notify-send -u low -t 3000 "Download complete"
  134. }
  135. download_music() {
  136. youtube-dl -x --add-metadata --no-progress --audio-format mp3 -o \
  137. "$HOME/music/%(track)s - %(artist)s.%(ext)s" "$(xclip -selection clipboard -o)"
  138. if [ ! $? ]; then
  139. youtube-dl -x --no-progress --audio-format mp3 -o \
  140. "$HOME/music/%(title)s - %(artist)s.%(ext)s" "$(xclip -selection clipboard -o)"
  141. fi
  142. notify-send -u low -t 3000 "Download complete"
  143. }
  144. view_images() {
  145. d=$(mru listdirs | dmenu -l 20 -i -p 'where?')
  146. if [ -z "$d" ]; then exit; fi
  147. sxiv -r "$d"
  148. }
  149. package() {
  150. type=$(printf "search\ninfo" | dmenu -p 'package')
  151. if [ -z "$type" ]; then
  152. exit
  153. elif [ "$type" = "info" ]; then
  154. s=$(dmenu_path | dmenu -i -p 'package info')
  155. st -e sh -lc "apt-cache show $s"
  156. else
  157. s=$(dmenu -i -p 'package search')
  158. st -e sh -lc "apt search \"$s\""
  159. fi
  160. }
  161. editor() {
  162. #handle spacing in filenames bug
  163. file=$(mru list | dmenu -i -l 10 -p 'edit file')
  164. if [ -z "$file" ]; then exit; fi
  165. first=$(printf "$file" | head -n1 -)
  166. d=$(dirname "$first")
  167. files=$(printf "$file" | tr '\n' ' ')
  168. printf "files: $files"
  169. st -t 'Editor' -e vim "+cd $d" $files
  170. }
  171. opener() {
  172. mru list | dmenu -i -l 20 -p 'open' | while read f; do xdg-open "$f"; done
  173. }
  174. screenshot() {
  175. method=$(printf "clipboard
  176. file
  177. both" |
  178. dmenu -i -p "Screenshot")
  179. if [ $method = "file" ]; then
  180. scrot --note "-f 'LiterationSans Nerd Font Book/11' -x 10 -y 20 -c 255,0,0,255 -t 'Hi'"\
  181. -s ~/Pictures/screenshots/screenshot-%Y-%m-%d_$wx$h.png
  182. fi
  183. if [ $method = "clipboard" ]; then
  184. scrot --note "-f 'LiterationSans Nerd Font Book/11' -x 10 -y 20 -c 255,0,0,255 -t 'Hi'"\
  185. -s ~/Pictures/screenshots/screenshot-%Y-%m-%d_$wx$h.png\
  186. -e "xclip $f; rm $f"
  187. fi
  188. if [ $method = "both" ]; then
  189. scrot --note "-f 'LiterationSans Nerd Font Book/11' -x 10 -y 20 -c 255,0,0,255 -t 'Hi'"\
  190. -s ~/Pictures/screenshots/screenshot-%Y-%m-%d_$wx$h.png\
  191. -e "xclip $f;"
  192. fi
  193. }
  194. search_type() {
  195. search_string="$(printf "New window\nBookmarks\nHistory" | dmenu -p "$1")"
  196. search_mode='tab'
  197. case "$search_string" in
  198. 'New window') search_mode='window'; search_string=$(printf '' | dmenu -p "new $1");;
  199. 'Bookmarks');;
  200. 'History') ;;
  201. # *) printf "Invalid argument";;
  202. esac
  203. printf "$search_string|$search_mode"
  204. }
  205. brave_search() {
  206. search_prefix="$1"
  207. search_info="$(search_type "$2")"
  208. search_string=$(printf "$search_info" | cut -d'|' -f1)
  209. search_mode=$(printf "$search_info" | cut -d'|' -f2)
  210. if [ -z "$search_string" ]; then exit; fi
  211. new_string=$(rawurlencode "$search_string")
  212. search="$search_prefix$new_string"
  213. case "$search_mode" in
  214. tab) $browser_cmd "$search";;
  215. window) $browser_new_cmd "$search";;
  216. esac
  217. }
  218. rawurlencode() {
  219. #Takes the first argument and encodes it
  220. search_string="$1"
  221. string_length=$(expr length "$search_string")
  222. char=''; new_string='';
  223. i=1
  224. while [ $i -le $string_length ]
  225. do
  226. char=$(expr substr "$search_string" $i 1)
  227. # new_string="$new_string$(rawurlencode "$char")"
  228. case "$char" in
  229. [-_.~a-zA-Z0-9] ) new_string="$new_string$char";;
  230. * ) new_string="$new_string%$(printf '%%%02x' "'$char")";;
  231. esac
  232. i=$(expr $i + 1)
  233. done
  234. printf "$new_string"
  235. }
  236. ddg() {
  237. brave_search "https://duckduckgo.com/?q=" "ddg"
  238. }
  239. github() {
  240. brave_search "https://github.com/search?q=" "github"
  241. }
  242. godoc() {
  243. brave_search "https://golang.org/pkg/" "godoc"
  244. }
  245. manual() {
  246. search=$(printf '' | dmenu -p 'manual')
  247. result=$(man "$search")
  248. printf "$result" | enscript -p - | ps2pdf - | zathura -
  249. }
  250. goinfo() {
  251. #Maybe this can also show recent searches
  252. search=$(printf "Window\nNotify" | dmenu -p 'goinfo')
  253. case $search in
  254. Window) search=$(printf '' | dmenu -p 'goinfo'); result=$(go doc "$search"); infowindow "$result"; exit;;
  255. Notify) search=$(printf '' | dmenu -p 'goinfo'); result=$(go doc "$search"); notify-send -u low -t 0 "Go documentation" "$result"; exit;;
  256. esac
  257. result=$(go doc "$search"); notify-send -u low -t 0 "Go documentation" "$result";
  258. }
  259. go_page() {
  260. name=$(printf "1\n2\n3\n4" | dmenu -p "page name")
  261. go doc "$(printf "" | dmenu -p 'go doc search')" > /tmp/pages-$name
  262. printf "$name"
  263. }
  264. infowindow() {
  265. printf "$1" | enscript -p - | ps2pdf - | zathura -
  266. }
  267. cmd() {
  268. c="$(printf '' | dmenu -i -p 'cmd')"
  269. output=$( $c )
  270. notify-send -u low 'command output' "$output"
  271. }
  272. cmd_clip() {
  273. value=$(cmd)
  274. show_value="$(expr substr "$value" 1 200)\n..."
  275. notify-send -u low -t 2000 "Items cliped" "$show_value"
  276. printf "%s" "$value" | xclip -selection clipboard
  277. }
  278. sel_account() {
  279. account=$(
  280. find ~/.password-store/[!\.]* -type f |
  281. sed -e "s:$HOME/.password-store/::" -e "s:\.gpg::" |
  282. dmenu -p 'account'
  283. )
  284. if [ -z "$account" ]; then exit; fi
  285. printf "$account"
  286. }
  287. username() {
  288. account=$(sel_account)
  289. if [ -z "$account" ]; then exit; fi
  290. name=$(pass show "$account" | sed -n -e "s/^username: //p" |
  291. dmenu -p 'which username' | xclip -f -selection clipboard)
  292. if [ -z "$name" ]; then exit; fi
  293. notify-send -u low -t 2000 "username copied" "$account: $name"
  294. }
  295. password() {
  296. rm prompt-login-*
  297. touch /tmp/prompt-login-$$
  298. account=$(find ~/.password-store/[!\.]* -type f |
  299. sed -e "s:$HOME/.password-store/::" -e "s:\.gpg::" |
  300. dmenu -p 'which service')
  301. pass -c $account
  302. notify-send -u low -t 1000 'password copied' "Copied $account"
  303. }
  304. # Giving multiple accounts for the same service the same username may cause problems.
  305. # It assumes that the password is always the first line of the account's section,
  306. # and the username is always the second
  307. other_password() {
  308. account=$(sel_account)
  309. name=$(pass show "$account" | sed -n -e "s/^username: //p" |
  310. dmenu -i -p 'which user password')
  311. if [ -z "$name" ]; then exit; fi
  312. copy=$(pass show $account | grep -B 1 "^username: $name" | head -n1 | tr -d '\n')
  313. printf "$copy" | xclip -selection clipboard
  314. notify-send -u low -t 2000 "password copied" "$account: $name"
  315. sleep 30s
  316. new_copy=$(xclip -o -selection clipboard)
  317. if [ "$copy" = $newcopy ]; then
  318. printf '' | xclip -selection clipboard
  319. fi
  320. }
  321. show_password() {
  322. account=$(sel_account)
  323. info=$(pass show "$account")
  324. st -e sh -lc "printf '$info' | less"
  325. }
  326. edit_password() {
  327. account=$(sel_account)
  328. if [ -z "$account" ]; then exit; fi
  329. error=$(st -e pass edit "$account" 2>&1)
  330. if [ -n "$error" ]; then notify-send -u low -t 3000 "password edit error" "$error"; fi
  331. }
  332. # Execute a command with the specified file or directory as it's argument
  333. choose() {
  334. d=$(mru listdirs | dmenu -i -l 20 -p 'from')
  335. if [ -z "$d" ]; then exit; fi
  336. f=$(
  337. (printf "$d\n"; find "$d" -type f -not \( -path '*/.*/*' -o -path '*node_modules/*' -o -ipath '*backups/my-plugins*' -o -ipath '*/.uuid' -ipath '*.swp*' \)) |
  338. dmenu -i -l 20 -p 'choose file'
  339. )
  340. if [ -z "$f" ]; then exit; fi
  341. c=$(dmenu_path | dmenu -i -p 'operation')
  342. if [ -z $c ]; then exit; fi
  343. $c "$f"
  344. }
  345. vpn() {
  346. ls
  347. }
  348. # It finds all the current files in a known directory without needing to update the mru list of files
  349. # If the directory is chosen instead of the file within it, it opens the directory with nnn
  350. pick() {
  351. d=$(mru listdirs | dmenu -i -l 20 -p 'from')
  352. if [ -z "$d" ]; then exit; fi
  353. f=$(
  354. (printf "$d\n"; find "$d" -type f -not \( -path '*/.*/*' -o -path '*node_modules/*' -o -ipath '*backups/my-plugins*' -o -ipath '*/.uuid' -ipath '*.swp*' \)) |
  355. dmenu -i -l 20 -p 'pick file'
  356. )
  357. if [ -z "$f" ]; then exit; fi
  358. if [ "$d" = "$f" ]; then st -t 'Files' -e sh -lc "nnn '$f'"; exit; fi
  359. xdg-open "$f"
  360. }
  361. do_exit() {
  362. choice=$(printf "Shutdown
  363. Reboot"| dmenu -i -p 'Exit')
  364. case $choice in
  365. Shutdown) ls;;
  366. Reboot) ls;;
  367. esac
  368. }
  369. select_song() {
  370. song=$(mpc playlist | dmenu -i -l 20 -p 'song')
  371. num=$(mpc playlist | sed -n "/$song/=")
  372. mpc play $num
  373. }
  374. case $1 in
  375. launch ) launch;;
  376. action) action;;
  377. pick) pick;;
  378. cmd) cmd;;
  379. cmd_clip) cmd_clip;;
  380. login) login;;
  381. search) do_search;;
  382. open) opener;;
  383. choose) choose;;
  384. vpn) vpn;;
  385. download) download;;
  386. download_music) download_music;;
  387. *) printf "Invalid argument";;
  388. esac