1262 lines
41 KiB
Org Mode
1262 lines
41 KiB
Org Mode
#+TITLE: Phundrak’s executable scripts
|
||
#+AUTHOR: Lucien "Phundrak” Cartier-Tilet
|
||
#+EMAIL: phundrak@phundrak.fr
|
||
#+OPTIONS: H:4 broken_links:mark email:t ^:{} auto-id:t
|
||
|
||
# ### LaTeX ####################################################################
|
||
#+LATEX_CLASS: conlang
|
||
#+LaTeX_CLASS_OPTIONS: [a4paper,twoside]
|
||
#+LATEX_HEADER_EXTRA: \usepackage{tocloft} \setlength{\cftchapnumwidth}{3em}
|
||
#+LATEX_HEADER_EXTRA: \usepackage{xltxtra,fontspec,xunicode,svg}
|
||
#+LATEX_HEADER_EXTRA: \usepackage[total={17cm,24cm}]{geometry}
|
||
#+LATEX_HEADER_EXTRA: \setromanfont{Charis SIL}
|
||
#+LATEX_HEADER_EXTRA: \usepackage{xcolor}
|
||
#+LATEX_HEADER_EXTRA: \usepackage{hyperref}
|
||
#+LATEX_HEADER_EXTRA: \hypersetup{colorlinks=true,linkbordercolor=red,linkcolor=blue,pdfborderstyle={/S/U/W 1}}
|
||
#+LATEX_HEADER_EXTRA: \usepackage{multicol}
|
||
#+LATEX_HEADER_EXTRA: \usepackage{indentfirst}
|
||
#+LATEX_HEADER_EXTRA: \sloppy
|
||
|
||
# ### HTML #####################################################################
|
||
#+HTML_DOCTYPE: html5
|
||
#+HTML_HEAD_EXTRA: <meta name="description" content="Phundrak's executable scripts" />
|
||
#+HTML_HEAD_EXTRA: <meta property="og:title" content="Phundrak's executable scripts" />
|
||
#+HTML_HEAD_EXTRA: <meta property="og:description" content="Phundrak’s executable scripts explained" />
|
||
#+HTML_HEAD_EXTRA: <script src="https://kit.fontawesome.com/4d42d0c8c5.js"></script>
|
||
#+HTML_HEAD_EXTRA: <script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>
|
||
#+HTML_HEAD_EXTRA: <link rel="shortcut icon" href="https://cdn.phundrak.fr/img/mahakala-128x128.png" type="img/png" media="screen" />
|
||
#+HTML_HEAD_EXTRA: <link rel="shortcut icon" href="https://cdn.phundrak.fr/img/favicon.ico" type="image/x-icon" media="screen" />
|
||
#+HTML_HEAD_EXTRA: <meta property="og:image" content="https://cdn.phundrak.fr/img/rich_preview.png" />
|
||
#+HTML_HEAD_EXTRA: <meta name="twitter:card" content="summary" />
|
||
#+HTML_HEAD_EXTRA: <meta name="twitter:site" content="@phundrak" />
|
||
#+HTML_HEAD_EXTRA: <meta name="twitter:creator" content="@phundrak" />
|
||
#+HTML_HEAD_EXTRA: <style>.org-svg{width:auto}</style>
|
||
#+INFOJS_OPT: view:info toc:1 home:https://phundrak.fr/ toc:t
|
||
#+HTML_HEAD_EXTRA: <link rel="stylesheet" href="https://langue.phundrak.fr/css/htmlize.min.css"/>
|
||
#+HTML_HEAD_EXTRA: <link rel="stylesheet" href="https://langue.phundrak.fr/css/main.css"/>
|
||
#+HTML_HEAD_EXTRA: <script src="https://langue.phundrak.fr/js/jquery.min.js"></script>
|
||
#+HTML_HEAD_EXTRA: <script defer src="https://langue.phundrak.fr/js/main.js"></script>
|
||
|
||
* Table of Contents :TOC_4_gh:noexport:
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-400070eb-725f-4416-a4c6-da3053df750b
|
||
:END:
|
||
- [[#presentation][Presentation]]
|
||
- [[#4chandl][4chandl]]
|
||
- [[#askpass][Askpass]]
|
||
- [[#backup][Backup]]
|
||
- [[#cppnew][Cppnew]]
|
||
- [[#cnew][Cnew]]
|
||
- [[#dmenu][Dmenu]]
|
||
- [[#emoji-picker][Emoji picker]]
|
||
- [[#polybar-launch][Polybar-launch]]
|
||
- [[#rofi-mount][Rofi-mount]]
|
||
- [[#get-the-mountable-elements][Get the mountable elements]]
|
||
- [[#get-the-mount-point][Get the mount point]]
|
||
- [[#mount-a-usb-drive-hard-drive-or-partition][Mount a USB drive, hard drive or partition]]
|
||
- [[#mount-an-android-device][Mount an Android device]]
|
||
- [[#mount-a-cd-drive][Mount a CD drive]]
|
||
- [[#ask-what-type-of-drive-we-want-to-mount][Ask what type of drive we want to mount]]
|
||
- [[#launch-the-mounting-functions][Launch the mounting functions]]
|
||
- [[#rofi-pass][Rofi-pass]]
|
||
- [[#rofi-umount][Rofi-umount]]
|
||
- [[#get-the-unmountable-drives][Get the unmountable drives]]
|
||
- [[#unmount-disk-partitions][Unmount disk partitions]]
|
||
- [[#unmount-android-device][Unmount Android device]]
|
||
- [[#unmount-cd-drive][Unmount CD drive]]
|
||
- [[#ask-what-type-of-drive-to-unmount][Ask what type of drive to unmount]]
|
||
- [[#launch-the-unmounting-functions][Launch the unmounting functions]]
|
||
- [[#starwars][Starwars]]
|
||
- [[#wacom-setup][Wacom setup]]
|
||
- [[#set-our-variables][Set our variables]]
|
||
- [[#select-our-screen][Select our screen]]
|
||
- [[#adjust-the-tablet][Adjust the tablet]]
|
||
- [[#lauch-the-functions][Lauch the functions]]
|
||
- [[#yadm][Yadm]]
|
||
|
||
* Presentation
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-309d8596-c35e-4700-a174-13f40884940d
|
||
:END:
|
||
This file will present all the executable scripts I wrote. It is also their
|
||
original source code, all the following code snippets are exported and tangled
|
||
from this file to the actual executables.
|
||
|
||
Please do not forget to run the following before tangling files from this file
|
||
to make sure the tangled files will be executables.
|
||
#+begin_src emacs-lisp :exports code :results silent
|
||
(defun phundrak/make-tangled-files-executable ()
|
||
(set-file-modes (buffer-file-name) #o755))
|
||
(add-hook 'org-babel-post-tangle-hook 'phundrak/make-tangled-files-executable)
|
||
#+end_src
|
||
|
||
* 4chandl
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-39e14885-9da7-4cba-b24e-c3b181ef5f6b
|
||
:HEADER-ARGS: :tangle 4chandl :exports code
|
||
:END:
|
||
Usage: =4chandl [ URL TO THREAD ]=
|
||
|
||
I made this small script to download the attached files of 4chan threads.
|
||
First of all, let’s declare it as a fish script.
|
||
#+BEGIN_SRC fish
|
||
#!/usr/bin/env fish
|
||
#+END_SRC
|
||
|
||
Now, let’s check if any arguments were passed to the executable. If none were
|
||
passed, the script should be aborted.
|
||
#+BEGIN_SRC fish
|
||
if ! count $argv > /dev/null
|
||
echo 'No URL specified! Give the URL to thread as the only argument.'
|
||
exit 1
|
||
end
|
||
#+END_SRC
|
||
|
||
Now, let’s store the regex we use to get the link to the attached files.
|
||
#+BEGIN_SRC fish
|
||
set regex_4cdn '\/\/is2\.4chan\.org\/[a-z]+\/[A-Za-z0-9]+\.[A-Za-z]{3,4}'
|
||
#+END_SRC
|
||
|
||
We’ll use a thread counter to get a visual indication on how the download is
|
||
going.
|
||
#+BEGIN_SRC fish
|
||
set thread_counter 1
|
||
#+END_SRC
|
||
|
||
Now, we will use each of the arguments passed as a URL to download the files
|
||
from.
|
||
#+BEGIN_SRC fish
|
||
for url in $argv
|
||
#+END_SRC
|
||
|
||
As a visual indicator, let’s get the amount of elements we are going to
|
||
download from the current thread and print it.
|
||
#+BEGIN_SRC fish
|
||
set file_total (curl -ks $url | grep -oE $regex_4cdn | uniq | wc -l)
|
||
echo total files to download in current thread: $file_total
|
||
#+END_SRC
|
||
|
||
Let’s set a file counter so we can visualize the download progress.
|
||
#+BEGIN_SRC fish
|
||
set file_counter 1
|
||
#+END_SRC
|
||
|
||
Now, let’s download each file from the current thread.
|
||
#+BEGIN_SRC fish
|
||
for image_url in (curl -k -s $url | grep -Eo $regex_4cdn | uniq | sed 's/^/https:/')
|
||
echo -n Downloading image $counter of $total...
|
||
wget --no-check-certificate -q -nc $image_url
|
||
echo ' Done (thread: $thread_counter/thread_total\tfile: $file_counter/file_total)'
|
||
set file_counter (math $file_counter + 1)
|
||
end
|
||
#+END_SRC
|
||
|
||
Let’s increment the thread counter.
|
||
#+BEGIN_SRC fish
|
||
set thread_counter (math $thread_counter + 1)
|
||
#+END_SRC
|
||
|
||
Let’s now close the for loop.
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
* Askpass
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-b2bef089-69e3-4efb-ac2f-a5eb6a3a80e8
|
||
:HEADER-ARGS: :tangle askpass :exports code
|
||
:END:
|
||
Askpass is a simple script that invokes =rofi= as a way to get from a GUI the
|
||
user’s sudo password. It is inspired by [[https://github.com/ODEX-TOS/tools/blob/master/rofi/askpass][this original tool]], rewritten in fish
|
||
and with [[https://wiki.archlinux.org/index.php/Rofi][rofi]] support instead of [[https://wiki.archlinux.org/index.php/Dmenu][dmenu]]. As you can see, this is a oneliner if
|
||
we ignore the initial shebang. This executable is pointed at by the
|
||
#+BEGIN_SRC fish :exports code
|
||
#!/usr/bin/env fish
|
||
rofi -dmenu -font 'DejaVu Sans 10' -password -no-fixed-num-lines \
|
||
-p (printf $argv[1] | sed s/://)
|
||
#+END_SRC
|
||
|
||
* Backup
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-30cb6655-382f-492a-a005-df15512ab7a5
|
||
:HEADER-ARGS: :tangle backup :exports code
|
||
:END: =backup= is a very simple, oneliner script that will create a local copy of a
|
||
file and add the date at which it was copied in the filename. You can see its
|
||
source code here:
|
||
#+BEGIN_SRC fish
|
||
#!/usr/bin/env fish
|
||
cp $argv[1] $argv[1].bak.(date +"%Y%m%d%H%M%S")
|
||
#+END_SRC
|
||
|
||
* Cppnew
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-264945df-fe7a-4f9d-845a-9cc26c196f4b
|
||
:HEADER-ARGS: :tangle cppnew :exports code
|
||
:END: =cppnew= is a small utility that helps you create a new C++ project. Several
|
||
templates are available, the default one using CMake, and three others that
|
||
are a bit more advances, based on:
|
||
- CMake + [[https://conan.io/][Conan]]
|
||
- [[https://mesonbuild.com/][Meson]] + [[https://ninja-build.org/][Ninja]]
|
||
- Meson + Ninja + Conan
|
||
There is also a default [[http://doxygen.nl/][Doxygen]] file included for your documentation, ready to
|
||
go. I even made it so that you can execute it as an executable file, like =./doc/Doxyfile= from the project root.
|
||
|
||
The choice is given to the user which of them to use with options that will be
|
||
given to =cppnew=.
|
||
|
||
* Cnew
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-a4ccdc0f-6813-4207-9479-4d68296f5fdb
|
||
:HEADER-ARGS: :tangle cnew :exports code
|
||
:END: =cnew= is a small utility script similar to but simpler than [[#cppnew][cppnew]] that
|
||
creates a CMake template C project from the template that already exists in
|
||
[[file:~/dev/templateC][~/dev/templateC]]. This script is a fish script, so let’s insert the shebang.
|
||
#+BEGIN_SRC fish
|
||
#!/usr/bin/env fish
|
||
#+END_SRC
|
||
|
||
If no argument was passed, display an error message and exit.
|
||
#+BEGIN_SRC fish
|
||
if ! count $argv > /dev/null
|
||
echo "Missing argument: PROJECT" && return -1
|
||
end
|
||
#+END_SRC
|
||
|
||
Pass the first argument to a switch statement.
|
||
#+BEGIN_SRC fish
|
||
switch "$argv[1]"
|
||
#+END_SRC
|
||
|
||
If the argument is =-h= or =--help=, then display the help message and exit
|
||
the script normally.
|
||
#+BEGIN_SRC fish
|
||
case -h --help
|
||
man ~/dev/fishfunctions/cnew.man
|
||
exit 0
|
||
#+END_SRC
|
||
|
||
Else, the argument is the name of the project the user wants to create.
|
||
#+BEGIN_SRC fish
|
||
case '*'
|
||
set -g project_name $argv[1]
|
||
#+END_SRC
|
||
|
||
Let’s close the switch statement.
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
Now, let’s copy the template where the user is executing =cnew= from, give it
|
||
the name of the project and move to the project.
|
||
#+BEGIN_SRC fish
|
||
cp -r ~/dev/templateC $argv[1]
|
||
cd $argv[1]
|
||
#+END_SRC
|
||
|
||
The default files have a placeholder for the name of the project. Let’s
|
||
replace these placeholders with the project’s name.
|
||
#+BEGIN_SRC fish
|
||
sed -i "s/PROJECTNAME/$argv[1]/g" CMakeLists.txt
|
||
sed -i "s/PROJECTNAME/$argv[1]/g" README.org
|
||
sed -i "s/CPROJECTNAME/$argv[1]/g" doc/Doxyfile
|
||
#+END_SRC
|
||
|
||
Now, let’s create a git repository and initialize it.
|
||
#+BEGIN_SRC fish
|
||
git init
|
||
git add .
|
||
git commit -m "initial commit"
|
||
#+END_SRC
|
||
|
||
And we’re done!
|
||
|
||
* Dmenu
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-50623ecd-b633-4af7-9cc4-5a032f01d1ee
|
||
:HEADER-ARGS: :tangle dmenu :exports code
|
||
:END:
|
||
I wrote this very simple script in order to replace =dmenu= with rofi’s
|
||
emulation of dmenu, since I prefer rofi’s appearance. It basically calls
|
||
rofi’s dmenu emulation with the arguments initially passed to dmenu.
|
||
#+BEGIN_SRC fish
|
||
#!/usr/bin/env fish
|
||
rofi -dmenu $argv
|
||
#+END_SRC
|
||
|
||
* Emoji picker
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-477cd486-c9a6-4d59-bd9d-62d8f08ee62d
|
||
:HEADER-ARGS: :tangle rofi-emoji :exports code
|
||
:END:
|
||
The emoji picker is a simple fish script that uses rofi and
|
||
[[file:~/.config/emoji.txt][~/.config/emoji.txt]] to provide a small, local search for emojis. Once the
|
||
emoji is selected, it is copied to the clipboard using =xclipboard=.
|
||
#+BEGIN_SRC fish
|
||
#!/usr/bin/env fish
|
||
grep -v "#" ~/.config/emoji.txt | rofi -dmenu -i | awk '{print $1}' | tr -d '\n' | xclip -selection clipboard
|
||
#+END_SRC
|
||
|
||
Also, let’s send a notification telling the user the emoji has been copied!
|
||
#+BEGIN_SRC fish
|
||
set emoji (xclip -o -selection clipboard | tr -d '\n')
|
||
test -z "$emoji" && notify-send "No emoji copied" && exit
|
||
set -a emoji "copied to clipboard"
|
||
pgrep -x dunst >/dev/null && notify-send $emoji
|
||
#+END_SRC
|
||
|
||
It is inspired from [[https://www.youtube.com/watch?v=UCEXY46t3OA][this video]] from [[https://lukesmith.xyz/][Luke Smith]], rewritten in Fish.
|
||
|
||
* Polybar-launch
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-68587918-879b-42db-b304-901d01233f95
|
||
:HEADER-ARGS: :tangle polybar-launch :exports code
|
||
:END:
|
||
This scripts allows the user to kill polybar and relaunch it, or to simply
|
||
launch it if polybar isn’t launched yet. This script is a bash script, so
|
||
let’s declare its shebang.
|
||
#+BEGIN_SRC bash
|
||
#!/usr/bin/env bash
|
||
#+END_SRC
|
||
|
||
First thing to do is kill all polybar processes.
|
||
#+BEGIN_SRC bash
|
||
killall -q polybar
|
||
#+END_SRC
|
||
|
||
Now we have to wait untill all polybar processes have been shut down.
|
||
#+BEGIN_SRC bash
|
||
while pgrep -u $UID -x polybar >/dev/null; do sleep 1; done
|
||
#+END_SRC
|
||
|
||
Now that our system isn’t running polybar anymore, we’ll launch it again on
|
||
all of our screens. By the way, I have two bars, so I’ll have to lauch them
|
||
both.
|
||
#+BEGIN_SRC bash
|
||
if type "xrandr"; then
|
||
for m in $(xrandr --query | grep " connected" | cut -d" " -f1); do
|
||
MONITOR=$m polybar --reload top &
|
||
MONITOR=$m polybar --reload bottom &
|
||
done
|
||
else
|
||
polybar --reload top &
|
||
polybar --reload bottom &
|
||
fi
|
||
#+END_SRC
|
||
|
||
And we’re done! Let’s just launch a notification polybar has been relaunched.
|
||
#+BEGIN_SRC bash
|
||
notify-send "Polybar restarted!" -a "polybar-launch"
|
||
#+END_SRC
|
||
|
||
* Rofi-mount
|
||
:PROPERTIES:
|
||
:HEADER-ARGS: :tangle rofi-mount :exports code
|
||
:CUSTOM_ID: h-32ee4a66-e7fb-4abf-a168-fa259efdb1f4
|
||
:END: =rofimount= is a script inspired by [[https://github.com/ihebchagra/dotfiles/blob/master/.local/bin/dmount][this one]], based on dmenu, which
|
||
interactively asks the user what to mount, and where to mount it. What I did
|
||
was replace dmenu with rofi, and fix a couple of bugs I encountered in the
|
||
original script. For the record, this is a fish script. Let’s declare our
|
||
shebang.
|
||
#+BEGIN_SRC fish
|
||
#!/usr/bin/env fish
|
||
#+END_SRC
|
||
|
||
** Get the mountable elements
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-2307005f-385e-4149-b885-55e699c822bb
|
||
:END:
|
||
#+BEGIN_SRC fish
|
||
begin
|
||
#+END_SRC
|
||
What the script does first is detect everything that can be mounted. Between
|
||
a =begin= and =end=, let’s set =LFS= as a local variable. This si in order to
|
||
get sane variables in the current block.
|
||
#+BEGIN_SRC fish
|
||
set -l LFS
|
||
#+END_SRC
|
||
|
||
Now, let’s detect the amount of mountable Android filesystems, and if any are
|
||
detected, let’s read them into a global variable.
|
||
#+BEGIN_SRC fish
|
||
set -l a (math (jmtpfs -l | wc -l) - 2)
|
||
test $a -ge 0 && jmtpfs -l 2> /dev/null | tail -n $a | read -zg anddrives
|
||
#+END_SRC
|
||
|
||
We’ll do the same for external and internal drives and partitions that can be
|
||
mounted here.
|
||
#+BEGIN_SRC fish
|
||
lsblk -rpo "name,type,size,mountpoint" | \
|
||
awk '$2=="part"&&$4==""{printf "%s (%s)\n",$1,$3}' | \
|
||
read -zg usbdrives
|
||
#+END_SRC
|
||
|
||
Finally, we look for any CD drive that could be mounted on our device.
|
||
#+BEGIN_SRC fish
|
||
blkid /dev/sr0 | awk '{print $1}' | sed 's/://' | read -z cddrives
|
||
#+END_SRC
|
||
|
||
And that’s the end of our first block!
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
Alright, we’ll save what kind on drives we can mount in a temporary file
|
||
called =/tmp/drives=. We’ll make sure it’s blank by erasing it then creating
|
||
it again with =touch=, like so. The =-f= flag on =rm= is here so we get no
|
||
error if we try to delete a file that doesn’t exist (yet).
|
||
#+BEGIN_SRC fish
|
||
set -g TMPDRIVES /tmp/drives
|
||
rm -f $TMPDRIVES
|
||
touch $TMPDRIVES
|
||
#+END_SRC
|
||
|
||
Now, let’s write what type of drives we can mount in this temporary file.
|
||
#+BEGIN_SRC fish
|
||
test -n "$usbdrives" && echo "USB" >> $TMPDRIVES
|
||
test -n "$cddrives" && echo "CD" >> $TMPDRIVES
|
||
test -n "$anddrives" && echo "Android" >> $TMPDRIVES
|
||
#+END_SRC
|
||
|
||
Now, we want to declare where to look for mount directories. For now, we’ll
|
||
only look in =/media=, but you can add more if you wish.
|
||
#+BEGIN_SRC fish
|
||
set -g basemount /media
|
||
#+END_SRC
|
||
|
||
** Get the mount point
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-a17825bd-96e2-4c90-99ef-b0f2895cffb6
|
||
:END:
|
||
Now, let’s declare a function that will allow us to chose the drive we want
|
||
to mount.
|
||
#+BEGIN_SRC fish
|
||
function getmount
|
||
#+END_SRC
|
||
|
||
First, we want to get our mount point. We’ll run a =find= command on each of
|
||
the directories listed in =$basemount= to look for folders on which our drive
|
||
could be mounted. This list will be passed to rofi from which we will chose
|
||
our mount point.
|
||
#+BEGIN_SRC fish
|
||
set -g mp (for d in $basemount
|
||
find $d -maxdepth 5 -type d
|
||
end | rofi -dmenu -i -p 'Type in mount point.')
|
||
#+END_SRC
|
||
|
||
We should verify that something has been actually selected, otherwise we
|
||
should abort the script.
|
||
#+BEGIN_SRC fish
|
||
if test -z $mp || test $mp = ""
|
||
return 1
|
||
end
|
||
#+END_SRC
|
||
|
||
Now, if the selected mount point does not exist, we’ll ask the user whether
|
||
the directory should be created. If no, the script will abort. If yes, an
|
||
attempt will be made at creating the directory as the user; if that fails, a
|
||
new attempt will be made as sudo.
|
||
#+BEGIN_SRC fish
|
||
if test ! -d $mp
|
||
switch (printf "No\\nYes" | rofi -dmenu -i -p "$mp does not exist. Create it?")
|
||
case 'Yes'
|
||
mkdir -p $mp || sudo -A mkdir -p $mp
|
||
case '*'
|
||
return 1
|
||
end
|
||
end
|
||
#+END_SRC
|
||
|
||
Finally, let’s close the function
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
** Mount a USB drive, hard drive or partition
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-72781187-ebf2-418c-99b3-bba44922fc60
|
||
:END:
|
||
Alright, we want to mount a partition that answers by the name of =/dev/sdXX=, how do we do that? Let’s create first the function =mountusb=
|
||
that will take care of it for us.
|
||
#+BEGIN_SRC fish
|
||
function mountusb
|
||
#+END_SRC
|
||
|
||
Now, the first thing we want to do is select the partition we want to mount.
|
||
Remember, we stored those in =$usbdrives= earlier, so let’s pipe them into
|
||
rofi so we can chose from it. Also, =awk= will get their path in =/dev=.
|
||
#+BEGIN_SRC fish
|
||
set -g chosen (echo $usbdrives | \
|
||
rofi -dmenu -i -p "Mount which drive?" | \
|
||
awk '{print $1}')
|
||
#+END_SRC
|
||
|
||
As usual after a user selection, let’s verify something has actually been
|
||
selected. If not, let’s abort the script.
|
||
#+BEGIN_SRC fish
|
||
test -z $chosen && return 1
|
||
#+END_SRC
|
||
|
||
Now, let’s select the mount point of our partition. We’ll call the function =getmount= described in [[#get-the-drive-to-mount][Get the drive to mount]] to select it.
|
||
#+BEGIN_SRC fish
|
||
getmount
|
||
#+END_SRC
|
||
|
||
Let’s verify the variable =mp= set in =getmount= is not empty, otherwise
|
||
abort the script.
|
||
#+BEGIN_SRC fish
|
||
test -z $mp && return 1
|
||
#+END_SRC
|
||
|
||
Now, let’s mount it! We’ll use a switch which will detect the filesystem used
|
||
so we know how to mount the partition.
|
||
#+BEGIN_SRC fish
|
||
switch (lsblk -no "fstype" $chosen)
|
||
#+END_SRC
|
||
|
||
We have two named case: =vfat= filesystems.
|
||
#+BEGIN_SRC fish
|
||
case "vfat"
|
||
sudo -A mount -t vfat $chosen $mp -o rw,umask=0000
|
||
#+END_SRC
|
||
|
||
And =ntfs= filesystems.
|
||
#+BEGIN_SRC fish
|
||
case "ntfs"
|
||
sudo -A mount -t ntfs $chosen $mp -o rw,umask=0000
|
||
#+END_SRC
|
||
|
||
Else, we’ll let =mount= determine which filesystem is used by the partition
|
||
(generally =ext4=).
|
||
#+BEGIN_SRC fish
|
||
case '*'
|
||
sudo -A mount $chosen $mp
|
||
#+END_SRC
|
||
|
||
We’ll also run a =chown= on this newly mounted filesystem so the user can
|
||
access it without any issues.
|
||
#+BEGIN_SRC fish
|
||
sudo -A chown -R $USER:(id -g $USER) $mp
|
||
#+END_SRC
|
||
|
||
Let’s close the switch block and send a notification the partition has been
|
||
mounted.
|
||
#+BEGIN_SRC fish
|
||
end && notify-send -a "dmount" "💻 USB mounting" "$chosen mounted to $mp."
|
||
#+END_SRC
|
||
|
||
And let’s close the function.
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
** Mount an Android device
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-af36260f-2c00-43b7-9383-5235ebac9b51
|
||
:END:
|
||
The function that manages to mount Android filesystems is =mountandroid=.
|
||
Let’s declare it.
|
||
#+BEGIN_SRC fish
|
||
function mountandroid -d "Mount an Android device"
|
||
#+END_SRC
|
||
|
||
We’ll select which Android we want to mount. We will be asked through rofi.
|
||
#+BEGIN_SRC fish
|
||
set chosen (echo $anddrives | rofi -dmenu -i -p "Which Android device?" | awk '{print $1 $2}' | sed 's/,$//')
|
||
#+END_SRC
|
||
|
||
Now, we need to get the bus of the Android device we want to mount. It will
|
||
be useful later, after we authorized mounting from our device, to get the
|
||
path to our partition.
|
||
#+BEGIN_SRC fish
|
||
set bus (echo $chosen | sed 's/,.*//')
|
||
#+END_SRC
|
||
|
||
Let’s temporarily mount our device.
|
||
#+BEGIN_SRC fish
|
||
jmtpfs -device=$chosen $mp
|
||
#+END_SRC
|
||
|
||
Now, we need to allow our computer to mount our Android device. Depending on
|
||
the Android version it is running on, we either need to specify our device is
|
||
USB connected in order to exchange files, or Android will explicitely ask us
|
||
if it is OK for our computer to access it. Let’s inform the user of that.
|
||
#+BEGIN_SRC fish
|
||
echo "OK" | \
|
||
rofi -dmenu -i -p "Press (Allow) on your phone screen, or set your USB settings to allow file transfert"
|
||
#+END_SRC
|
||
|
||
Now, let’s get the actual path of our Android filesystem we wish to mount,
|
||
and let’s unmount the previous temporary filesystem.
|
||
#+BEGIN_SRC fish
|
||
set newchosen (jmtpfs -l | grep $bus | awk '{print $1 $2}' | sed 's/,$//')
|
||
sudo -A umount $mp
|
||
#+END_SRC
|
||
|
||
Now we cam mount the new filesystem and send a notification if everything
|
||
went well.
|
||
#+BEGIN_SRC fish
|
||
jmtpfs -device=$newchosen $mp && \
|
||
notify-send -a "dmount" "🤖 Android Mounting" "Android device mounted to $mp."
|
||
#+END_SRC
|
||
|
||
And now, we can close our function.
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
** Mount a CD drive
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-73ff10ea-10aa-4044-9315-2321fff73c3f
|
||
:END:
|
||
This part is way easier than the previous functions. As we will see, the
|
||
function =mountcd='s body is only three lines long. First, let’s declare the
|
||
function.
|
||
#+BEGIN_SRC fish
|
||
function mountcd
|
||
#+END_SRC
|
||
|
||
Now, let’s chose the CD drive we want to mount using =rofi=.
|
||
#+BEGIN_SRC fish
|
||
set chosen (echo $cddrives | rofi -dmenu -i -p "Which CD drive?")
|
||
#+END_SRC
|
||
|
||
We’ll also get the mountpoint thanks to the =getmount= function described
|
||
earlier.
|
||
#+BEGIN_SRC fish
|
||
getmount
|
||
#+END_SRC
|
||
|
||
And finally, let’s mount it and send the notification everything went well.
|
||
#+BEGIN_SRC fish
|
||
sudo -A mount $chosen $mp && \
|
||
notify-send -a "dmount" "💿 CD mounting" "$chosen mounted."
|
||
#+END_SRC
|
||
|
||
Finally, let’s close our function.
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
** Ask what type of drive we want to mount
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-0bc6ffba-5c45-44e5-a3d3-039a8ea43905
|
||
:END:
|
||
The first thing we will be asked if different types of drives are detected is
|
||
which of these types the user wishes to mount. This is done with the function =asktype= which is declared below.
|
||
#+BEGIN_SRC fish
|
||
function asktype
|
||
#+END_SRC
|
||
|
||
We will use a switch statement which will use our anwser to rofi about what
|
||
we wish to mount.
|
||
#+BEGIN_SRC fish
|
||
switch (cat $TMPDRIVES | rofi -dmenu -i -p "Mount which drive?")
|
||
#+END_SRC
|
||
|
||
If we chose the option "USB", we’ll mount a hard drive, partition or USB
|
||
drive. In which case we’ll call the =mountusb= function.
|
||
#+BEGIN_SRC fish
|
||
case "USB"
|
||
mountusb
|
||
#+END_SRC
|
||
|
||
If we chose the "Android" option, the =mountandroid= function is called.
|
||
#+BEGIN_SRC fish
|
||
case "Android"
|
||
mountandroid
|
||
#+END_SRC
|
||
|
||
Else if we chose the "CD" option, we’ll call the =mountcd= function.
|
||
#+BEGIN_SRC fish
|
||
case "CD"
|
||
mountcd
|
||
#+END_SRC
|
||
If nothing is selected, the function will naturally exit. Now, let’s close
|
||
our switch statement and our function.
|
||
#+BEGIN_SRC fish
|
||
end
|
||
end
|
||
#+END_SRC
|
||
|
||
** Launch the mounting functions
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-646dc678-4d87-4fec-8130-5d7d0fc16756
|
||
:END:
|
||
Now that we have declared our functions and set our variables, we’ll read the
|
||
temporary file described in [[#get-the-mountable-elements][Get the mountable elements]]. The amount of lines
|
||
is passed in a switch statement.
|
||
#+BEGIN_SRC fish
|
||
switch (wc -l < $TMPDRIVES)
|
||
#+END_SRC
|
||
|
||
If the file has no lines, i.e. it is empty, we have no mountable media. Let’s
|
||
inform our user this is the case.
|
||
#+BEGIN_SRC fish
|
||
case 0
|
||
notify-send "No USB drive or Android device or CD detected" -a "dmount"
|
||
#+END_SRC
|
||
|
||
If we only have one line, we have only one type of mountable media. We’ll
|
||
pass this line to a second switch statement.
|
||
#+BEGIN_SRC fish
|
||
case 1
|
||
switch (cat $TMPDRIVES)
|
||
#+END_SRC
|
||
This will allow the script to automatically detect what type of media it is,
|
||
and mount the corresponding function.
|
||
#+BEGIN_SRC fish
|
||
case "USB"
|
||
mountusb
|
||
case "Android"
|
||
mountandroid
|
||
case "CD"
|
||
mountCD
|
||
#+END_SRC
|
||
Let’s close this nested switch case.
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
If we have more than one line, we’ll have to ask the user what type of media
|
||
they want to mount.
|
||
#+BEGIN_SRC fish
|
||
case '*'
|
||
asktype
|
||
#+END_SRC
|
||
|
||
Now, let’s end our switch statement!
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
Finally, we’ll delete our temporary file.
|
||
#+BEGIN_SRC fish
|
||
rm -f $TMPDRIVES
|
||
#+END_SRC
|
||
|
||
And with that, this is the end of our script!
|
||
|
||
* Rofi-pass
|
||
:PROPERTIES:
|
||
:HEADER-ARGS: :tangle rofi-pass :exports code
|
||
:CUSTOM_ID: h-a52876ed-351b-400a-b250-d93aab27e0c8
|
||
:END: =rofi-pass= is a simple utility that gets a password stored in the [[https://www.passwordstore.org/][=pass=]]
|
||
password manager with rofi as its interface, and then stores the password in
|
||
the clipboard. It is a fish script, so let’s declare it as one.
|
||
#+BEGIN_SRC fish
|
||
#!/usr/bin/env fish
|
||
#+END_SRC
|
||
|
||
Let’s parse all the arguments passed to the script. If one of them is =--type=, =-t= or =type=, the script will attempt to type the password to the
|
||
text area already selected without pasting the password to the clipboard.
|
||
#+BEGIN_SRC fish
|
||
for arg in $argv
|
||
switch $arg
|
||
case '--type'
|
||
set -g TYPE "yes"
|
||
case '-t'
|
||
set -g TYPE "yes"
|
||
case 'type'
|
||
set -g TYPE "yes"
|
||
case '*'
|
||
printf 'Unknown argument: %s\n.' $arg
|
||
exit 1
|
||
end
|
||
end
|
||
#+END_SRC
|
||
|
||
Now, let’s get the list of the passwords that exist in our =pass= repository.
|
||
#+BEGIN_SRC fish
|
||
set passwords (find $HOME/.password-store -type f -name "*.gpg" | \
|
||
string replace -r ".*.password-store/" "" | \
|
||
string replace -r ".gpg" "" | sort)
|
||
#+END_SRC
|
||
|
||
Let the user choose which password they wish to select.
|
||
#+BEGIN_SRC fish
|
||
set password (for elem in $passwords
|
||
echo $elem
|
||
end | rofi -dmenu -i -p "Select your password")
|
||
#+END_SRC
|
||
|
||
Let’s verify we actually selected a password and not just exited. If no
|
||
password was selected, let’s simply exit the script.
|
||
#+BEGIN_SRC fish
|
||
if test -z $password
|
||
exit
|
||
end
|
||
#+END_SRC
|
||
|
||
Depending on the arguments passed earlier, we might want some different
|
||
behavior.
|
||
#+BEGIN_SRC fish :noweb yes
|
||
if test $TYPE = "yes"
|
||
<<rofi-pass-type>>
|
||
else
|
||
<<rofi-pass-copy>>
|
||
end
|
||
#+END_SRC
|
||
|
||
The default behavior is to copy the password to the clipboard for 45 seconds,
|
||
so let’s do that.
|
||
#+NAME: rofi-pass-copy
|
||
#+BEGIN_SRC fish :noweb yes :tangle no
|
||
pass show -c $password 2> /dev/null
|
||
#+END_SRC
|
||
|
||
Else, if we passed =--type=, =-t= or =type= as an argument of the script, we
|
||
want it to attempt to type our password in the currently selected text input.
|
||
Let’s do that.
|
||
#+NAME: rofi-pass-type
|
||
#+BEGIN_SRC fish :noweb yes :tangle no
|
||
set -l IFS
|
||
<<rofi-pass-type-get-password>>
|
||
printf %s $pass | xvkbd -file -
|
||
#+END_SRC
|
||
|
||
To correctly get the password from =pass=, we need to parse the output and
|
||
only get the first line, hence the following command.
|
||
#+NAME: rofi-pass-type-get-password
|
||
#+BEGIN_SRC fish :tangle no
|
||
set pass (pass show $password | string split -n \n)[1]
|
||
#+END_SRC
|
||
|
||
* Rofi-umount
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-68a1f671-5dc6-4120-81c8-c94fffa7d7a3
|
||
:HEADER-ARGS: :tangle rofi-umount :exports code
|
||
:END: =rofiumount= is the counterpart of =rofimount= for unmounting our mounted
|
||
partitions. It is a fish script, so let’s declare it as that with its shebang.
|
||
#+BEGIN_SRC fish
|
||
#!/usr/bin/env fish
|
||
#+END_SRC
|
||
|
||
** Get the unmountable drives
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-dab41471-4f69-4be8-8d77-58ccc604e4e2
|
||
:END:
|
||
First, we will need to list all the drives that can be safely unmounted.
|
||
Let’s run this.
|
||
#+BEGIN_SRC fish
|
||
set -g drives (lsblk -nrpo "name,type,size,mountpoint" | \
|
||
awk '$2=="part"&&$4!~/\/boot|\/home$|SWAP/&&length($4)>1{printf "%s (%s)\n",$4,$3}')
|
||
#+END_SRC
|
||
|
||
Now, let’s get the android devices that are mounted.
|
||
#+BEGIN_SRC fish
|
||
set -g androids (awk '/jmtpfs/ {print $2}' /etc/mtab)
|
||
#+END_SRC
|
||
|
||
And let’s get the CD drives that are mounted.
|
||
#+BEGIN_SRC fish
|
||
set -g cds (awk '/sr0/ {print $2}' /etc/mtab)
|
||
#+END_SRC
|
||
|
||
We’ll store all of our information in a temporary file, =/tmp/undrives=.
|
||
#+BEGIN_SRC fish
|
||
set -g undrivefile /tmp/undrives
|
||
#+END_SRC
|
||
|
||
Let’s make sure we begin with a clean, empty file.
|
||
#+BEGIN_SRC fish
|
||
rm -f $undrivefile
|
||
touch $undrivefile
|
||
#+END_SRC
|
||
|
||
Depending on if the related variables are set, write the different types of
|
||
mounted drives in the temporary file.
|
||
#+BEGIN_SRC fish
|
||
test -n "$drives" && echo "USB" >> $undrivefile
|
||
test -n "$cds" && echo "CD" >> $undrivefile
|
||
test -n "$androids" && echo "Android" >> $undrivefile
|
||
#+END_SRC
|
||
|
||
** Unmount disk partitions
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-01c37335-5ae8-484f-911a-a08cc4679398
|
||
:END:
|
||
The function =unmountusb= will take care of unmounting any drive we can
|
||
safely unmount. First, let’s declare the function.
|
||
#+BEGIN_SRC fish
|
||
function unmountusb
|
||
#+END_SRC
|
||
|
||
Let’s chose the drive to unmount with rofi.
|
||
#+BEGIN_SRC fish
|
||
set chosen (echo $drives | \
|
||
rofi -dmenu -i -p "Unmount which drive?" | \
|
||
awk '{print $1}')
|
||
#+END_SRC
|
||
|
||
Let’s verify if the user actually selected any drive. If no, let’s abort the
|
||
script.
|
||
#+BEGIN_SRC fish
|
||
test -z "$chosen" && exit 0
|
||
#+END_SRC
|
||
|
||
Now, let’s unmount the chosen drive and send a notification if it has been
|
||
done.
|
||
#+BEGIN_SRC fish
|
||
sudo -A umount $chosen && \
|
||
notify-send "💻 USB unmounting" "$chosen unmounted." -a "dumount"
|
||
#+END_SRC
|
||
|
||
Now, let’s close the function.
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
** Unmount Android device
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-d7d2a12e-c759-4dbe-a17b-bb90c514dca2
|
||
:END:
|
||
The function =unmountandroid= will take care of unmounting any mounted
|
||
Android device. First, let’s declare our function.
|
||
#+BEGIN_SRC fish
|
||
function unmountandroid
|
||
#+END_SRC
|
||
|
||
Let the user choose which Android device to unmount.
|
||
#+BEGIN_SRC fish
|
||
set chosen (echo $androids | rofi -dmenu -i -p "Unmount which device?")
|
||
#+END_SRC
|
||
|
||
We’ll verify the user chose any device.
|
||
#+BEGIN_SRC fish
|
||
test -z "$chosen" && exit 0
|
||
#+END_SRC
|
||
|
||
If a device has been chosen, let’s unmount it and send a notification it has
|
||
been successfuly unmounted.
|
||
#+BEGIN_SRC fish
|
||
sudo -A umount -l $chosen && \
|
||
notify-send "🤖 Android unmounting" "$chosen unmounted." -a "dumount"
|
||
#+END_SRC
|
||
|
||
Finally, let’s close the function.
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
** Unmount CD drive
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-ae7a8a83-f022-493c-8410-ad99abf42b89
|
||
:END: =unmountcd= will take care of unmounting any mounted CD drive. Let’s declare
|
||
this function.
|
||
#+BEGIN_SRC fish
|
||
function unmountcd
|
||
#+END_SRC
|
||
|
||
As before, let the user chose which CD drive to unmount.
|
||
#+BEGIN_SRC fish
|
||
set chosen (echo "$cds" | rofi -dmenu -i -p "Unmount which CD?")
|
||
#+END_SRC
|
||
|
||
We’ll verify the user chose any device.
|
||
#+BEGIN_SRC fish
|
||
test -z "$chosen" && exit 0
|
||
#+END_SRC
|
||
|
||
If a drive has been chosen, let’s unmount it and send a notification it has
|
||
been successfuly unmounted.
|
||
#+BEGIN_SRC fish
|
||
sudo -A umount -l $chosen && \
|
||
notify-send "💿 CD unmounting" "$chosen unmounted." -a "dumount"
|
||
#+END_SRC
|
||
|
||
Now, let’s close the function.
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
** Ask what type of drive to unmount
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-4320a68b-8369-4ac5-a049-cfb12435e45e
|
||
:END:
|
||
If several types of unmountable drives are available, let’s ask the user
|
||
which type to unmount based on the content of the temporary file declared in
|
||
[[#get-the-unmountable-drives][Get the unmountable drives]]. First, let’s declare the function.
|
||
#+BEGIN_SRC fish
|
||
function asktype
|
||
#+END_SRC
|
||
|
||
Let’s create a switch statement to which will be passed the selection of the
|
||
user from rofi.
|
||
#+BEGIN_SRC fish
|
||
switch (cat $undrivefile | rofi -dmenu -i -p "Unmount which type of device?")
|
||
#+END_SRC
|
||
|
||
Three types of values can be returned: "USB", "CD", or "Android". These
|
||
values will be used to launch their corresponding function.
|
||
#+BEGIN_SRC fish
|
||
case 'USB'
|
||
unmountusb
|
||
case 'CD'
|
||
unmountcd
|
||
case 'Android'
|
||
unmountandroid
|
||
#+END_SRC
|
||
|
||
Let’s close the switch statement.
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
Let’s now close the function.
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
** Launch the unmounting functions
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-5880963f-1403-41dc-ae7a-3958e2013fa9
|
||
:END:
|
||
Now back to the body of our script, let’s input in a switch case the number
|
||
of lines contained in our temporary file.
|
||
#+BEGIN_SRC fish
|
||
switch (wc -l < $undrivefile)
|
||
#+END_SRC
|
||
|
||
If the file containes no lines. i.e. it is empty, nothing is to be unmounted.
|
||
Let’s inform the user of that.
|
||
#+BEGIN_SRC fish
|
||
case 0
|
||
notify-send "No USB drive or Android device or CD to unmount" -a "dumount"
|
||
#+END_SRC
|
||
|
||
Else, if there is only one type of drive, we’ll automatically let our script
|
||
choose based on the content of this sole line.
|
||
#+BEGIN_SRC fish
|
||
case 1
|
||
switch (cat $undrivefile)
|
||
case 'USB'
|
||
unmountusb
|
||
case 'CD'
|
||
unmountcd
|
||
case 'Android'
|
||
unmountandroid
|
||
end
|
||
#+END_SRC
|
||
|
||
And if there are more types than one, let’s ask the user.
|
||
#+BEGIN_SRC fish
|
||
case '*'
|
||
asktype
|
||
#+END_SRC
|
||
|
||
Let’s close our main switch statement.
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
And finally, let’s delete our temporary file.
|
||
#+BEGIN_SRC fish
|
||
rm -f $undrivefile
|
||
#+END_SRC
|
||
|
||
* Starwars
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-127de2b2-d84b-4508-89d2-b4577e8dbece
|
||
:HEADER-ARGS: :tangle starwars :exports code
|
||
:END:
|
||
This is a one-liner that allows you to watch Star Wars episode 4 in ASCII art
|
||
in your terminal. Here is the code:
|
||
#+BEGIN_SRC fish
|
||
#!/usr/bin/env fish
|
||
telnet towel.blinkenlights.nl
|
||
#+END_SRC
|
||
|
||
* Wacom setup
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-e407ceef-2f14-4474-916b-6b687cf9f2e9
|
||
:HEADER-ARGS: :tangle wacom-setup :exports code
|
||
:END:
|
||
I made a small and quick utility to set up my Wacom tablet so it is only bound
|
||
to one screen. This is a fish script, so let’s insert the sheband.
|
||
#+BEGIN_SRC fish
|
||
#!/usr/bin/env fish
|
||
#+END_SRC
|
||
|
||
** Set our variables
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-c46f0eaf-ae46-4595-8d7a-944bc789cc06
|
||
:END:
|
||
Let’s first declare our function that will be called to set our variables.
|
||
#+BEGIN_SRC fish
|
||
function set_device
|
||
#+END_SRC
|
||
|
||
We need some variables in order to correctly set our tablet. First, let’s get
|
||
declare what the name of our tablet is, and what the name of its touchpad is.
|
||
#+BEGIN_SRC fish
|
||
set -g DEVICE "Wacom USB Bamboo PAD Pen stylus"
|
||
set -g DEVICETOUCH "Wacom USB Bamboo PAD Finger touch"
|
||
#+END_SRC
|
||
|
||
We will also modify two settings: the speed of the cursor on the touchpad,
|
||
and the scroll speed. Let’s declare the name of these two settings.
|
||
#+BEGIN_SRC fish
|
||
set -g WACOMPROPTOUCHSPEED "Device Accel Velocity Scaling"
|
||
set -g WACOMPROPSCROLLPSEED "ScrollDistance"
|
||
#+END_SRC
|
||
|
||
To get the correct values for the area it can cover, we’ll need to reset our
|
||
tablet.
|
||
#+BEGIN_SRC fish
|
||
xsetwacom set "$DEVICE" ResetArea
|
||
#+END_SRC
|
||
|
||
Now we can get the X and Y areas.
|
||
#+BEGIN_SRC fish
|
||
set -l AREATOT (xsetwacom get "$DEVICE" Area)
|
||
set -g AREAX (echo $AREATOT | awk '{print $3}')
|
||
set -g AREAY (echo $AREATOT | awk '{print $4}')
|
||
#+END_SRC
|
||
|
||
Now let’s close our function.
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
** Select our screen
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-c81850ec-b2dd-4c57-8570-aca14ca4061b
|
||
:END:
|
||
This function will allow us to select the screen on which the tablet will be
|
||
active. We can also select the option “desktop” so that all screens are
|
||
selected. Let’s declare our function.
|
||
#+BEGIN_SRC fish
|
||
function set_screen
|
||
#+END_SRC
|
||
|
||
First, let’s set what screens are available, including the desktop option.
|
||
#+BEGIN_SRC fish
|
||
set CONNECTED_DISPLAYS (xrandr -q --current | \
|
||
sed -n 's/^\([^ ]\+\) connected .*/\1/p') desktop
|
||
#+END_SRC
|
||
|
||
Now, let’s select the one we wish to use using rofi.
|
||
#+BEGIN_SRC fish
|
||
set -g SCREEN (for d in $CONNECTED_DISPLAYS
|
||
echo $d
|
||
end | rofi -dmenu -i -p "Select your dispaly" | tr -d '\n')
|
||
#+END_SRC
|
||
|
||
Now, let’s get the resolution of our selected screen.
|
||
#+BEGIN_SRC fish
|
||
set -l LINE (xrandr -q --current | if [ "$SCREEN" = "desktop" ]
|
||
sed -n 's/^Screen 0:.*, current \([0-9]\+\) x \([0-9]\+\),.*/\1 \2/p'
|
||
else
|
||
sed -n "s/^$SCREEN"' connected \(primary \)\{0,1\}\([0-9]\+\)x\([0-9]\+\)+.*/\2 \3/p'
|
||
end)
|
||
#+END_SRC
|
||
|
||
From that, let’s get the vertical and horizontal resolution of our screen.
|
||
#+BEGIN_SRC fish
|
||
echo $LINE | read -g WIDTH HEIGHT
|
||
#+END_SRC
|
||
|
||
If any of our =WIDTH= ou =HEIGHT= it empty, we’ll have to abort the script.
|
||
#+BEGIN_SRC fish
|
||
if test -z $WIDTH || test -z $HEIGHT
|
||
exit 1
|
||
end
|
||
#+END_SRC
|
||
|
||
Let’s close our function now.
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
** Adjust the tablet
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-7e7bcdd1-dce8-43aa-b26e-cc4f38be2a1b
|
||
:END:
|
||
This function will take care of adjusting our tablet to our screen. Let’s
|
||
declare our function.
|
||
#+BEGIN_SRC fish
|
||
function adjust_device
|
||
#+END_SRC
|
||
|
||
If our screen is too high or too wide for our tablet, we will have to adjust
|
||
the height or width of the area used by the tablet. So let’s get the
|
||
theoretical new height and width of the area.
|
||
#+BEGIN_SRC fish
|
||
set RATIOAREAY (math ceil \($AREAX \* $HEIGHT \/ $WIDTH\))
|
||
set RATIOAREAX (math ceil \($AREAY \* $WIDTH \/ $HEIGHT\))
|
||
#+END_SRC
|
||
|
||
Now, if the current height of the tablet’s area is greater than the
|
||
theoretical new area, it means the current area is too high. Otherwise, it
|
||
should be the other way around. Let’s set =NEWAREAX= and =NEWAREAY= that will
|
||
be used to set the new area for the tablet.
|
||
|
||
#+BEGIN_SRC fish
|
||
if test $AREAY -gt $RATIOAREAY
|
||
set -g NEWAREAX $AREAX
|
||
set -g NEWAREAY $RATIOAREAY
|
||
else
|
||
set -g NEWAREAX $RATIOAREAX
|
||
set -g NEWAREAY $AREAY
|
||
end
|
||
#+END_SRC
|
||
|
||
Alright, now let’s set the new area with these new variables.
|
||
#+BEGIN_SRC fish
|
||
xsetwacom set "$DEVICE" Area 0 0 $NEWAREAX $NEWAREAY
|
||
xsetwacom set "$DEVICE" MapToOutput "$SCREEN"
|
||
#+END_SRC
|
||
|
||
Let’s slow down the cursor’s speed on the touchpad.
|
||
#+BEGIN_SRC fish
|
||
xinput set-float-prop $DEVICETOUCH $WACOMPROPTOUCHSPEED 0.5
|
||
#+END_SRC
|
||
|
||
Let’s also slow down the scroll speed of the touchpad.
|
||
#+BEGIN_SRC fish
|
||
xsetwacom set $DEVICETOUCH $WACOMPROPSCROLLPSEED "90"
|
||
#+END_SRC
|
||
|
||
Now, let’s close the function.
|
||
#+BEGIN_SRC fish
|
||
end
|
||
#+END_SRC
|
||
|
||
** Lauch the functions
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-e8699018-acf1-42f9-9ce7-4f7bd1a83f9c
|
||
:END:
|
||
Back to the main body of the script, we can now launch the functions
|
||
sequencially.
|
||
#+BEGIN_SRC fish
|
||
set_device
|
||
set_screen
|
||
adjust_device
|
||
#+END_SRC
|
||
|
||
* Yadm
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h-9535957b-7559-4244-a5e0-d056c4770fea
|
||
:HEADER-ARGS: :tangle yadm :exports code
|
||
:END:
|
||
For some reason, =yadm= won’t stop making polybar crash. So, I created this
|
||
script that will wrap yadm with a call to yadm, and then a call to =polybar-launch= declared in [[#polybar-launch][Polybar-launch]]. This is a oneliner, as you can
|
||
see below:
|
||
#+BEGIN_SRC fish
|
||
#!/usr/bin/env fish
|
||
/usr/bin/yadm $argv; polybar-launch 2>/dev/null >/dev/null
|
||
#+END_SRC
|