Compare commits

..

7 Commits

25 changed files with 1131 additions and 2048 deletions
+2 -7
View File
@@ -18,14 +18,9 @@ Each `.org` file contains source code blocks like:
The `:tangle <path>` header arg specifies the destination file. When tangled from Emacs, the code blocks are extracted and written to those paths.
**To tangle a single file** (from within Emacs):
```
M-x org-babel-tangle (or C-c C-v t)
```
**To tangle all files** (from the command line):
**To tangle a single file:**
```bash
emacs --batch --eval "(require 'org)" --eval '(org-babel-tangle-file "file.org")'
emacsclient -e '(org-babel-tangle-file "/home/thomas/.config/literate-dotfiles/file.org")'
```
## Key Conventions
+3 -96
View File
@@ -106,76 +106,17 @@ alias tmux='tmux -f $XDG_CONFIG_HOME/tmux/tmux.conf'
alias mbsync='mbsync -c $XDG_CONFIG_HOME/isync/mbsyncrc'
#+END_SRC
*** One letter aliases
#+BEGIN_SRC bash
alias y="yazi"
alias t="tmux"
alias v="nvim"
alias sv='sudo -E nvim'
alias g="git"
alias m="neomutt"
alias o="xdg-open"
#+END_SRC
*** Neovim
#+begin_src bash
command -v nvim >/dev/null && alias vim="nvim" vimdiff="nvim -d" # Use neovim for vim if present.
#+end_src
*** Vim-like
#+BEGIN_SRC bash
alias :q=exit
alias :e=nvim
#+END_SRC
*** Print each PATH entry on a separate line
#+BEGIN_SRC bash
alias path='echo -e ${PATH//:/\\n}'
#+END_SRC
** Functions
*** =colors= - Display colors
#+BEGIN_SRC bash
colors() {
local fgc bgc vals seq0
printf "Color escapes are %s\n" '\e[${value};...;${value}m'
printf "Values 30..37 are \e[33mforeground colors\e[m\n"
printf "Values 40..47 are \e[43mbackground colors\e[m\n"
printf "Value 1 gives a \e[1mbold-faced look\e[m\n\n"
# foreground colors
for fgc in {30..37}; do
# background colors
for bgc in {40..47}; do
fgc=${fgc#37} # white
bgc=${bgc#40} # black
vals="${fgc:+$fgc;}${bgc}"
vals=${vals%%;}
seq0="${vals:+\e[${vals}m}"
printf " %-9s" "${seq0:-(default)}"
printf " ${seq0}TEXT\e[m"
printf " \e[${vals:+${vals+$vals;}}1mBOLD\e[m"
done
echo; echo
done
}
#+END_SRC
*** =tre= - Tree display
=tre= is a shorthand for =tree= with hidden files and color enabled, ignoring
the =.git= directory, listing directories first. The output gets piped into
=less= with options to preserve color and line numbers, unless the output is
small enough for one screen.
#+BEGIN_SRC bash
function tre() {
tree -aC -I '.git|node_modules|bower_components' --dirsfirst "$@" | less -FRNX;
}
#+END_SRC
*** =mkd= - Create a new directory and enter it
#+BEGIN_SRC bash
function mkd() {
@@ -183,29 +124,6 @@ function mkd() {
}
#+END_SRC
*** =fs= - Filesize of directory
#+BEGIN_SRC bash
function fs() {
if du -b /dev/null > /dev/null 2>&1; then
local arg=-sbh;
else
local arg=-sh;
fi
if [[ -n "$@" ]]; then
du $arg -- "$@";
else
du $arg .[^.]* ./*;
fi;
}
#+END_SRC
*** =nullify= - Redirect both standard output and standard error, as well as sending to background
#+BEGIN_SRC bash
function nullify() {
"$@" >/dev/null 2>&1
}
#+END_SRC
** Bash History
Undocumented feature which sets the size to "unlimited". http://stackoverflow.com/questions/9457233/unlimited-bash-history
@@ -276,7 +194,7 @@ export SUDO_ASKPASS=~/.local/bin/askpass-rofi
** Export some default applications
#+begin_src bash
export EDITOR="nvim"
export TERMINAL="kitty -1"
export TERMINAL="kitty"
export BROWSER="qutebrowser"
export READER="zathura"
export FILE="yazi"
@@ -326,21 +244,10 @@ export LINKDING_TOKEN=`pass nas/linkding_token`
*** Restic
#+begin_src bash
if [ "$(hostname)" = "ldehaeze" ]; then
export RESTIC_REPOSITORY=sftp:thomas@homelab:/srv/storage/Backups/esrf-laptop
export RESTIC_PASSWORD_COMMAND="pass show restic"
#+end_src
*** Go
#+begin_src bash
export GOPATH=$HOME/.config/go
#+end_src
*** Japanese input
#+begin_src bash
# Japanese input
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
export GTK_IM_MODULE=fcitx
fi
#+end_src
** Path
+181
View File
@@ -0,0 +1,181 @@
#+TITLE: Binaries specific to my ESRF Laptop
#+SETUPFILE: ./setup/org-setup-file.org
#+PROPERTY: header-args:bash :comments both :mkdirp yes
#+PROPERTY: header-args:bash+ :shebang "#!/usr/bin/env bash"
#+PROPERTY: header-args:bash+ :tangle-mode (identity #o555)
* =phonebook= ESRF phone-book
:PROPERTIES:
:CUSTOM_ID: phonebook
:END:
*Old phonebook*: The phone-list is taken from =scp rnice@esrf.fr:/mnt/multipath-shares/sware/pub/phonelist/share/annuaire.txt /home/thomas/.local/data/annuaire.txt=
*new phonebook*: Use the =etd= script
#+begin_src bash :tangle ~/.local/bin/phonebook
cat ~/.local/data/annuaire.txt | fzf --header="NAME Surname Phone Office Room Email"
#+end_src
#+begin_src bash :tangle ~/.local/bin/phonebook-gui
$TERMINAL --title esrf-phonebook -e phonebook
#+end_src
#+begin_src bash :tangle ~/.local/bin/etd
#!/bin/bash
ROOT_URL='https://phonedirectory.esrf.fr'
API_ENDPOINT="$ROOT_URL/api"
USAGE="
ESRF Telephone Directory
CLI to search $ROOT_URL
Usage :
# Search for <search term> in first name or last name
$0 <search term>
"
function fail {
echo "$1" >&2
exit 1
}
function json_curl { curl --get --fail --silent --show-error -H "Content-Type:application/json" -H "Accept: application/json" "$@"; }
function lspersons {
# List users and output result in csv
json_curl --data-urlencode "search=$1" "$API_ENDPOINT/searchUsers" |\
jq -r '. | (map(keys) | add | unique | sort) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $rows[] | @csv' 2>/dev/null
}
if [ $# -eq 0 ]; then
fail "$USAGE"
fi
# Print the list of persons as a table
lspersons $1 | awk 'BEGIN { FS=OFS="," }; {print $4,$3,$5,$1,$6,$2,$7}' | sed 's/"//g' | column -t -s "," | sort
exit $?
#+end_src
* =contacts= Personnal phone-book
:PROPERTIES:
:CUSTOM_ID: contacts
:END:
#+begin_src bash :tangle ~/.local/bin/contacts
khard | fzf --header="Index Name Phone E-Mail"
#+end_src
#+begin_src bash :tangle ~/.local/bin/contacts-gui
$TERMINAL --title esrf-phonebook -e contacts
#+end_src
* =wake-on-lan= - Wake on LAN
:PROPERTIES:
:CUSTOM_ID: wake-on-lan
:END:
#+begin_src bash :tangle ~/.local/bin/wake-on-lan
computer=$(echo -e 'ZOTAC' | rofi -i -dmenu -p 'Computer:' -l 20);
if [[ -z "$computer" ]]; then
exit 1
fi
dunstify --replace=99425 'Wake On Lan' "${computer}..."
case "$computer" in
"ZOTAC")
ssh homelab 'wakeonlan 00:01:2E:A2:42:9C' ;;
esac
#+end_src
* =screen-select= - Xrandr pre-defined scripts
:PROPERTIES:
:CUSTOM_ID: screen-select
:END:
#+begin_src bash :tangle ~/.local/bin/screen-select
option=$(echo -e "Work\nLaptop\nHome\nAouste" | rofi -i -dmenu -no-custom -p 'Screen:' -l 20)
if [[ -z "$option" ]]; then
exit 1
fi
after_screen_change () {
# Fix background if screen size/arangement has changed.
setbg
# Kill polybar
killall -q polybar
# Wait until the processes have been shut down
while pgrep -u $UID -x polybar >/dev/null; do sleep 1; done
# Launch bars
polybar top &
}
case "$option" in
"Work")
xrandr --output eDP-1 --off \
--output DP-3-2 --primary --mode 2560x1440 --pos 0x0 --rotate normal \
--output DP-3-1 --primary --mode 2560x1440 --pos 2560x0 --rotate normal && \
after_screen_change
;;
"Laptop")
xrandr --output DP-1-1 --off \
--output DP-1-2 --off \
--output DP-3-1 --off \
--output DP-3-2 --off \
--output HDMI-1 --off \
--output eDP-1 --primary --mode 1920x1200 --pos 0x0 --rotate normal && \
after_screen_change
;;
"Home")
xrandr --output eDP-1 --off \
--output DP-3-1 --off \
--output DP-3-2 --off \
--output HDMI-1 --off \
--output DP-1-2 --primary --mode 2560x1440 --pos 0x0 --rotate normal && \
after_screen_change
;;
"Aouste")
xrandr --output eDP-1 --off \
--output HDMI-1 --primary --mode 2560x1440 --pos 0x0 --rotate normal && \
after_screen_change
;;
,*)
echo "== ! missing or invalid argument ! =="
exit 2
esac
exit 0
#+end_src
* =print-esrf= - Print on Rnice
:PROPERTIES:
:CUSTOM_ID: print-esrf
:END:
- To list printers =lpstat -p -d=
#+begin_src bash :tangle ~/.local/bin/print-esrf
nbpage=$(echo -e '1\n2\n4' | rofi -dmenu -no-custom -p 'Number of pages per sheet' -l 20);
sides=$(echo -e 'one-sided\ntwo-sided-long-edge\ntwo-sided-short-edge' | rofi -dmenu -no-custom -p 'Two Sided:' -l 20);
media=$(echo -e 'A4\nA3' | rofi -dmenu -no-custom -p 'Size:' -l 20);
printer=$(echo -e 'ctb127c1u\nctb110c1u' | rofi -dmenu -no-custom -p 'Size:' -l 20);
if [[ -z "$nbpage" || -z "$sides" || -z "$media" || -z "$printer" ]]; then
exit 1
fi
rsync -zaP "$1" dehaeze@rnice:/home/esrf/dehaeze/Downloads/to-be-printed.pdf && \
ssh rnice "lpr -o media=$media -o sides=$sides -o number-up=$nbpage -P $printer /home/esrf/dehaeze/Downloads/to-be-printed.pdf";
#+end_src
+35 -189
View File
@@ -5,75 +5,6 @@
#+PROPERTY: header-args:bash+ :shebang "#!/usr/bin/env bash"
#+PROPERTY: header-args:bash+ :tangle-mode (identity #o555)
* =phonebook= ESRF phone-book
:PROPERTIES:
:CUSTOM_ID: phonebook
:END:
*Old phonebook*: The phone-list is taken from =scp rnice@esrf.fr:/mnt/multipath-shares/sware/pub/phonelist/share/annuaire.txt /home/thomas/.local/data/annuaire.txt=
*new phonebook*: Use the =etd= script
#+begin_src bash :tangle ~/.local/bin/phonebook
cat ~/.local/data/annuaire.txt | fzf --header="NAME Surname Phone Office Room Email"
#+end_src
#+begin_src bash :tangle ~/.local/bin/phonebook-gui
$TERMINAL --title esrf-phonebook -e phonebook
#+end_src
#+begin_src bash :tangle ~/.local/bin/etd
#!/bin/bash
ROOT_URL='https://phonedirectory.esrf.fr'
API_ENDPOINT="$ROOT_URL/api"
USAGE="
ESRF Telephone Directory
CLI to search $ROOT_URL
Usage :
# Search for <search term> in first name or last name
$0 <search term>
"
function fail {
echo "$1" >&2
exit 1
}
function json_curl { curl --get --fail --silent --show-error -H "Content-Type:application/json" -H "Accept: application/json" "$@"; }
function lspersons {
# List users and output result in csv
json_curl --data-urlencode "search=$1" "$API_ENDPOINT/searchUsers" |\
jq -r '. | (map(keys) | add | unique | sort) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $rows[] | @csv' 2>/dev/null
}
if [ $# -eq 0 ]; then
fail "$USAGE"
fi
# Print the list of persons as a table
lspersons $1 | awk 'BEGIN { FS=OFS="," }; {print $4,$3,$5,$1,$6,$2,$7}' | sed 's/"//g' | column -t -s "," | sort
exit $?
#+end_src
* =contacts= Personnal phone-book
:PROPERTIES:
:CUSTOM_ID: contacts
:END:
#+begin_src bash :tangle ~/.local/bin/contacts
khard | fzf --header="Index Name Phone E-Mail"
#+end_src
#+begin_src bash :tangle ~/.local/bin/contacts-gui
$TERMINAL --title esrf-phonebook -e contacts
#+end_src
* =remote-desktop= - Remote Desktop Connect
:PROPERTIES:
:CUSTOM_ID: remote-desktop
@@ -124,27 +55,6 @@ case "$computer" in
esac
#+end_src
* =wake-on-lan= - Wake on LAN
:PROPERTIES:
:CUSTOM_ID: wake-on-lan
:END:
#+begin_src bash :tangle ~/.local/bin/wake-on-lan
computer=$(echo -e 'ZOTAC' | rofi -i -dmenu -p 'Computer:' -l 20);
if [[ -z "$computer" ]]; then
exit 1
fi
dunstify --replace=99425 'Wake On Lan' "${computer}..."
case "$computer" in
"ZOTAC")
ssh homelab 'wakeonlan 00:01:2E:A2:42:9C' ;;
esac
#+end_src
* =mount-dir= - Mount/Unmout directories
#+begin_src text :tangle no
# <file system> <mount point> <type> <options> <dump> <pass>
@@ -267,105 +177,47 @@ fi
# sshfs -o allow_other,user,uid=1000,gid=1000,default_permissions $remote_loc /home/thomas/mnt/$drive
#+end_src
#+begin_src bash :tangle ~/.local/bin/umount-dir
if [ $# -eq 0 ]; then
# Takes a lot of time with tmp_14_days is mounted...
# drive=$(ls ~/mnt/ | rofi -dmenu -no-custom -p 'Drive:' -l 20);
drive=$(find ~/mnt/* -maxdepth 0 -type d -not -empty -printf '%f\n' | rofi -dmenu -no-custom -p 'Drive:' -l 20);
if [[ -z "$drive" ]]; then
exit 1
Unmounts all mounted directories under =~/mnt/=, skipping empty/unmounted ones.
Sends a =dunstify= notification listing what was unmounted, and a critical alert
for any failures.
#+begin_src bash :tangle ~/.local/bin/umount-dirs
mnt_dir="$HOME/mnt"
unmounted=()
failed=()
for dir in "$mnt_dir"/*/; do
[ -d "$dir" ] || continue
# Skip directories that are not mount points
if ! mountpoint -q "$dir"; then
continue
fi
if umount "$dir" 2>/dev/null; then
unmounted+=("$(basename "$dir")")
else
exit 1
failed+=("$(basename "$dir")")
fi
done
if [ ${#failed[@]} -gt 0 ]; then
dunstify --urgency=critical "umount-dirs" "Failed to unmount:\n$(printf '• %s\n' "${failed[@]}")"
fi
umount /home/thomas/mnt/$drive
#+end_src
* =screen-select= - Xrandr pre-defined scripts
:PROPERTIES:
:CUSTOM_ID: screen-select
:END:
#+begin_src bash :tangle ~/.local/bin/screen-select
option=$(echo -e "Work\nLaptop\nHome\nAouste" | rofi -i -dmenu -no-custom -p 'Screen:' -l 20)
if [[ -z "$option" ]]; then
exit 1
if [ ${#unmounted[@]} -gt 0 ]; then
dunstify "umount-dirs" "Unmounted:\n$(printf '• %s\n' "${unmounted[@]}")"
elif [ ${#failed[@]} -eq 0 ]; then
dunstify "umount-dirs" "Nothing was mounted"
fi
after_screen_change () {
# Fix background if screen size/arangement has changed.
setbg
# Kill polybar
killall -q polybar
# Wait until the processes have been shut down
while pgrep -u $UID -x polybar >/dev/null; do sleep 1; done
# Launch bars
polybar top &
}
case "$option" in
"Work")
xrandr --output eDP-1 --off \
--output DP-3-2 --primary --mode 2560x1440 --pos 0x0 --rotate normal \
--output DP-3-1 --primary --mode 2560x1440 --pos 2560x0 --rotate normal && \
after_screen_change
;;
"Laptop")
xrandr --output DP-1-1 --off \
--output DP-1-2 --off \
--output DP-3-1 --off \
--output DP-3-2 --off \
--output HDMI-1 --off \
--output eDP-1 --primary --mode 1920x1200 --pos 0x0 --rotate normal && \
after_screen_change
;;
"Home")
xrandr --output eDP-1 --off \
--output DP-3-1 --off \
--output DP-3-2 --off \
--output HDMI-1 --off \
--output DP-1-2 --primary --mode 2560x1440 --pos 0x0 --rotate normal && \
after_screen_change
;;
"Aouste")
xrandr --output eDP-1 --off \
--output HDMI-1 --primary --mode 2560x1440 --pos 0x0 --rotate normal && \
after_screen_change
;;
,*)
echo "== ! missing or invalid argument ! =="
exit 2
esac
exit 0
#+end_src
* =print-esrf= - Print on Rnice
:PROPERTIES:
:CUSTOM_ID: print-esrf
:END:
- To list printers =lpstat -p -d=
#+begin_src bash :tangle ~/.local/bin/print-esrf
nbpage=$(echo -e '1\n2\n4' | rofi -dmenu -no-custom -p 'Number of pages per sheet' -l 20);
sides=$(echo -e 'one-sided\ntwo-sided-long-edge\ntwo-sided-short-edge' | rofi -dmenu -no-custom -p 'Two Sided:' -l 20);
media=$(echo -e 'A4\nA3' | rofi -dmenu -no-custom -p 'Size:' -l 20);
printer=$(echo -e 'ctb127c1u\nctb110c1u' | rofi -dmenu -no-custom -p 'Size:' -l 20);
if [[ -z "$nbpage" || -z "$sides" || -z "$media" || -z "$printer" ]]; then
exit 1
fi
rsync -zaP "$1" dehaeze@rnice:/home/esrf/dehaeze/Downloads/to-be-printed.pdf && \
ssh rnice "lpr -o media=$media -o sides=$sides -o number-up=$nbpage -P $printer /home/esrf/dehaeze/Downloads/to-be-printed.pdf";
* =torrent-add= - Add Torrent using =stig=
Used to add notification when a torrent is added.
#+begin_src bash :tangle ~/.local/bin/torrent-add
stig add $@ && \
dunstify --replace=22221 "Stif" 'Torrent Added' || \
dunstify --replace=22221 --urgency=critical "Stif" 'Failed'
#+end_src
* =readbib= - Open Bibliography File
:PROPERTIES:
:CUSTOM_ID: readbib
@@ -388,10 +240,4 @@ List all =pdf= files and open selected one with zathura.
cd ~/Cloud/brain/pdfs/ && ls *.pdf | rofi -dmenu -lines 20 | xargs -I {} zathura {}
#+end_src
* =torrent-add= - Add Torrent using =stig=
Used to add notification when a torrent is added.
#+begin_src bash :tangle ~/.local/bin/torrent-add
stig add $@ && \
dunstify --replace=22221 "Stif" 'Torrent Added' || \
dunstify --replace=22221 --urgency=critical "Stif" 'Failed'
#+end_src
+4 -181
View File
@@ -5,50 +5,6 @@
#+PROPERTY: header-args:bash+ :shebang "#!/usr/bin/env bash"
#+PROPERTY: header-args:bash+ :tangle-mode (identity #o555)
* =dmenukill= - Kill program using Dmenu
:PROPERTIES:
:CUSTOM_ID: dmenukill
:END:
#+begin_src bash :tangle ~/.local/bin/dmenukill
ps_line=$(ps -u $USER k -size -o pid=,%mem=,%cpu=,comm= | dmenu -i -l 15)
if [ ! -z "$ps_line" ]; then
pid=$(echo $ps_line | awk '{print $1}')
name=$(echo $ps_line | awk '{print $4}')
kill -15 $pid && \
dunstify "Kill" "$name (PID $pid)" &
fi
#+end_src
* =nordvpn-toggle= - Connect to VPN using NordVPN
:PROPERTIES:
:CUSTOM_ID: nordvpn-toggle
:END:
To use this this, =nordvpn= must be installed: =yay -S nordvpn-bin=.
In order to populate the country list, =nordvpn countries | tr '\t' '\n' | sed -r '/^\s*$/d' > ~/.local/data/nordvpn_countries.txt=.
#+begin_src bash :tangle ~/.local/bin/nordvpn-toggle
tmpfile="/tmp/vpnstatus";
if [[ $(nordvpn status) == *"Connected"* ]]; then
nordvpn disconnect && \
dunstify --replace=23198 "VPN" "Disconnected" && \
echo "off" > $tmpfile;
else
# Select Country to connect to
country=`cat ~/.local/data/nordvpn_countries.txt | rofi -i -dmenu | sed 's/\s/_/g'`;
dunstify --replace=23198 "VPN" "Connecting to $country...";
nordvpn connect $country && \
dunstify --replace=23198 "VPN" "Connected to $country" && \
echo "on" > $tmpfile;
fi
#+end_src
* =i3exit= - Manage lock, suspend, reboot, ...
:PROPERTIES:
:CUSTOM_ID: i3exit
@@ -165,41 +121,6 @@ case "$status" in
esac
#+end_src
* =network-toggle= - Toggle Network
:PROPERTIES:
:CUSTOM_ID: network-toggle
:END:
Minimal network manager to just toggle the Wifi or Ethernet connection.
#+begin_src bash :tangle ~/.local/bin/network-toggle
result=$(nmcli device | sed '1d' | dmenu -l 20);
interface=$(echo $result | awk -F ' ' '{print $1}');
status=$(echo $result | awk -F ' ' '{print $3}');
if [ $status == 'disconnected' ]; then
nmcli device connect $interface
else
nmcli device disconnect $interface
fi
#+end_src
* =make-gif= - Convert an =MP4= video to =GIF=
:PROPERTIES:
:CUSTOM_ID: make-gif
:END:
First argument is the =mp4= file and the second argument is the output =gif= file.
#+begin_src bash :tangle ~/.local/bin/make-gif
palette="/tmp/palette.png"
filters="fps=15,scale=320:-1:flags=lanczos"
ffmpeg -v warning -i $1 -vf "$filters,palettegen" -y $palette
ffmpeg -v warning -i $1 -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y $2
#+end_src
* =yt-audio= - Download-Audio from youtube
:PROPERTIES:
:CUSTOM_ID: yt-audio
@@ -269,20 +190,10 @@ fi
The list of emojis is available [[file:data.org::#emojis][here]].
#+begin_src bash :tangle ~/.local/bin/insert-unicode
# Must have xclip installed to even show menu.
xclip -h 2>/dev/null || exit 1
chosen=$(cut -d ';' -f1 ~/.local/data/emojis | rofi -dmenu -i -l 20 | sed "s/ .*//")
[ "$chosen" != "" ] || exit
# If you run this command with an argument, it will automatically insert the character.
if [ -n "$1" ]; then
xdotool key Shift+Insert
else
echo "$chosen" | tr -d '\n' | xsel -ib
dunstify "'$chosen' copied to clipboard." &
fi
xdotool type --clearmodifiers "$chosen"
#+end_src
* =insert-nerd-fonts= - Insert Nerd Font Icon
@@ -293,20 +204,10 @@ fi
The list of emojis is available [[file:data.org::#nerd-fonts][here]].
#+begin_src bash :tangle ~/.local/bin/insert-nerd-fonts
# Must have xsel installed to even show menu.
xsel -h 2>/dev/null || exit 1
chosen=$(cat ~/.local/data/nerd-fonts | rofi -dmenu -i -l 20 | sed "s/ .*//")
chosen=$(cut -d ';' -f1 ~/.local/data/emojis | rofi -dmenu -i -l 20 | sed "s/ .*//")
[ "$chosen" != "" ] || exit
# If you run this command with an argument, it will automatically insert the character.
if [ -n "$1" ]; then
xdotool key Shift+Insert
else
echo "$chosen" | tr -d '\n' | xsel -ib
dunstify "'$chosen' copied to clipboard." &
fi
xdotool type --clearmodifiers "$chosen"
#+end_src
* =linkhandler= - Open any URL with Default application
@@ -384,74 +285,6 @@ i3lock --ignore-empty-password --nofork --image=$temp_file && \
killall -SIGUSR2 dunst && echo "on" > /tmp/dunststatus
#+end_src
* =mopidy-restart= - Restart Mopidy
:PROPERTIES:
:CUSTOM_ID: mopidy-restart
:END:
Sometimes =mopidy= need to be restarted...
#+begin_src bash :tangle ~/.local/bin/mopidy-restart
pids=( $(pgrep -f mopidy) )
for pid in "${pids[@]}"; do
if [[ $pid != $$ ]]; then
kill "$pid"
fi
done
echo "Killed mopidy."
echo "Restarting mopidy..."
~/.local/soft/mopidy-jellyfin/env/bin/mopidy -v >/tmp/mopidy.log 2>&1 &
echo "Done"
#+end_src
* =upload= - Upload Script
:PROPERTIES:
:CUSTOM_ID: upload
:END:
Upload a file to https://0x0.st/ and copy the generated url.
#+begin_src bash :tangle ~/.local/bin/upload
if [ $TMUX ]; then
tmux split -v -l 1 "curl --progress-bar -F\"file=@$1\" https://0x0.st | xsel -ib;" && tmux select-pane -U
else
curl --progress-bar -F"file=@$1" https://0x0.st | xsel -ib && \
dunstify 'Upload' 'Successful' || \
dunstify --urgency=critical 'Upload' 'Failed'
fi
#+end_src
* =weather= - Display Weather in terminal
:PROPERTIES:
:CUSTOM_ID: weather
:END:
Get the weather from http://wttr.in/.
#+begin_src bash :tangle ~/.local/bin/weather
if [ -n "$*" ]; then
address="wttr.in/"
address+=$*
else
address="wttr.in/"
fi
if type nsxiv > /dev/null 2>&1; then
address+=".png"
wget -qO- "$address" > /tmp/weather.png && \
nsxiv -b /tmp/weather.png
elif type feh > /dev/null 2>&1; then
address+=".png"
wget -qO- "$address" | feh -
else
curl "$address"
fi
#+end_src
* =convert-file= - Convert any file to another filetype
:PROPERTIES:
:CUSTOM_ID: convert-file
@@ -1429,17 +1262,6 @@ printf "$pass" | xclip -sel clip && \
dunstify 'Password' 'Generated'
#+end_src
* =sxhkd-help= - List of keybindings using Rofi
:PROPERTIES:
:CUSTOM_ID: sxhkd-help
:END:
#+begin_src bash :tangle ~/.local/bin/sxhkd-help
awk '/^[a-z]/ && last {print "<small>",$0,"\t",last,"</small>"} {last=""} /^#/{last=$0}' ~/.config/sxhkd/sxhkdrc{,.i3} |
column -t -s $'\t' |
rofi -dmenu -i -markup-rows -no-show-icons -width 1000 -lines 15 -yoffset 40
#+end_src
* =qrdecode= - Decode QRcode by taking screenshot
To install:
#+begin_src bash :tangle no
@@ -1479,3 +1301,4 @@ dunstify "qrshot" "$decoded_text"
# Cleaning up the trash that was left behind
rm $image_file
#+end_src
+1 -1
View File
@@ -55,7 +55,7 @@ conflict_resolution = "a wins"
type = "google_calendar"
token_file = "~/.local/share/calendars/google/credentials.txt"
client_id = "188415318767-802h28ig8gromo0f72blrbg6cgcop6m8.apps.googleusercontent.com"
client_secret = <<get-password(passname="google_calendar_client_secret")>>
client_secret = "<<get-password(passname='google_calendar_client_secret')>>"
[storage google_calendar_local]
type = "filesystem"
+1 -1
View File
@@ -53,7 +53,7 @@ Host rnice
#+end_src
#+begin_src bash :tangle ~/.ssh/esrf-test :comments none :mkdirp yes :shebang "#!/usr/bin/env bash" :tangle-mode (identity #o555)
test -n "$(ping -c1 -W1 -q proxy.esrf.fr. &> /dev/null )"
ping -c1 -W1 -q proxy.esrf.fr &> /dev/null
#+end_src
* Font
+85 -6
View File
@@ -14,6 +14,50 @@
#+property: header-args:emacs-lisp :tangle ~/.config/doom/config.el :results none :padline no
:END:
* Installation
:PROPERTIES:
:header-args:bash: :tangle scripts/install-emacs.sh :shebang "#!/bin/bash" :mkdirp yes
:END:
#+begin_src bash
set -euo pipefail
DOTFILES="${HOME}/.config/literate-dotfiles"
DOOM="${HOME}/.config/emacs/bin/doom"
#+end_src
** Packages
#+begin_src bash
echo "==> Emacs packages"
paru -S --needed emacs aspell aspell-en aspell-fr
#+end_src
** Doom Emacs
#+begin_src bash
echo "==> Installing Doom Emacs"
git clone --depth 1 https://github.com/doomemacs/doomemacs ~/.config/emacs
"${DOOM}" install --no-config
#+end_src
** Tangle Configuration
Tangle =doom.org= to generate =config.el=, =init.el= and =packages.el=:
#+begin_src bash
echo "==> Tangling doom.org"
emacsclient -e "(org-babel-tangle-file \"${DOTFILES}/doom.org\")" \
|| emacs --batch -l org --eval "(org-babel-tangle-file \"${DOTFILES}/doom.org\")"
#+end_src
** Sync
#+begin_src bash
echo "==> Running doom sync"
"${DOOM}" sync
#+end_src
* Introduction and Resources
https://medium.com/urbint-engineering/emacs-doom-for-newbies-1f8038604e3b
https://noelwelsh.com/posts/2019-01-10-doom-emacs.html
@@ -1273,7 +1317,7 @@ https://kitchingroup.cheme.cmu.edu/blog/2016/11/07/Better-equation-numbering-in-
(counter -1)
(numberp))
(setq results (loop for (begin . env) in
(setq results (cl-loop for (begin . env) in
(org-element-map (org-element-parse-buffer) 'latex-environment
(lambda (env)
(cons
@@ -1283,20 +1327,20 @@ https://kitchingroup.cheme.cmu.edu/blog/2016/11/07/Better-equation-numbering-in-
(cond
((and (string-match "\\\\begin{equation}" env)
(not (string-match "\\\\tag{" env)))
(incf counter)
(cl-incf counter)
(cons begin counter))
((string-match "\\\\begin{align}" env)
(prog2
(incf counter)
(cl-incf counter)
(cons begin counter)
(with-temp-buffer
(insert env)
(goto-char (point-min))
;; \\ is used for a new line. Each one leads to a number
(incf counter (count-matches "\\\\$"))
(cl-incf counter (count-matches "\\\\$"))
;; unless there are nonumbers.
(goto-char (point-min))
(decf counter (count-matches "\\nonumber")))))
(cl-decf counter (count-matches "\\nonumber")))))
(t
(cons begin nil)))))
@@ -3019,12 +3063,38 @@ Provides nice functions such as:
)
#+end_src
* Claude Code
#+begin_src emacs-lisp
(use-package! agent-shell
:config
(setq agent-shell-anthropic-authentication
(agent-shell-anthropic-make-authentication :login t))
(setq agent-shell-preferred-agent-config (agent-shell-anthropic-make-claude-code-config))
;; Evil state-specific RET behavior: insert mode = newline, normal mode = send
(evil-define-key 'insert agent-shell-mode-map (kbd "M-RET") #'newline)
(evil-define-key 'insert agent-shell-mode-map (kbd "RET") #'comint-send-input)
(evil-define-key 'normal agent-shell-mode-map (kbd "RET") #'comint-send-input)
;; n and p are bound in agent-shell-mode-map; restore self-insert in insert mode
(evil-define-key 'insert agent-shell-mode-map (kbd "n") #'self-insert-command)
(evil-define-key 'insert agent-shell-mode-map (kbd "p") #'self-insert-command)
(evil-define-key 'normal agent-shell-diff-mode-map (kbd "C-c C-o") #'agent-shell-diff-open-file)
(evil-define-key 'normal agent-shell-diff-mode-map (kbd "C-c C-a") #'agent-shell-diff-accept-all)
;; Configure *agent-shell-diff* buffers to start in Emacs state
(add-hook 'diff-mode-hook
(lambda ()
(when (string-match-p "\\*agent-shell-diff\\*" (buffer-name))
(evil-emacs-state)))))
#+end_src
* Doom =init.el=
#+begin_src emacs-lisp :tangle ~/.config/doom/init.el
(doom! :completion
company ; the ultimate code completion backend
(corfu +orderless) ; complete with cap(f), cape and a flying feather!
helm ; the *other* search engine for love and life
;;helm ; the *other* search engine for love and life
;;ido ; the other *other* search engine...
;;ivy ; a search engine for love and life
vertico ; the search engine of the future
@@ -3209,6 +3279,8 @@ https://github.com/doomemacs/doomemacs/issues/6478
#+begin_src emacs-lisp
;; Org-mode modules for citations, cross-references, bibliographies
(package! org-ref)
;; helm-bibtex (declared explicitly since the helm Doom module is not used)
(package! helm-bibtex)
#+end_src
#+begin_src emacs-lisp
@@ -3261,6 +3333,13 @@ https://github.com/doomemacs/doomemacs/issues/6478
:files ("resources" "*.el")))
#+end_src
** Claude Code
#+begin_src emacs-lisp
(package! shell-maker)
(package! acp)
(package! agent-shell)
#+end_src
** Not used anymore :noexport:
:PROPERTIES:
:header-args:emacs-lisp: :tangle no
+11
View File
@@ -373,6 +373,17 @@ Add an entry for the new user.
Restart the container with =docker-compose restart authelia=.
Ask the new user to go to https://login.tdehaeze.xyz/ to reset his password.
** Update Matrix
https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/maintenance-upgrading-services.md
#+begin_src bash
cd ~/Cloud/programming/matrix-docker-ansible-deploy/
git pull
# Look at CHANGELOG.md
just update
ansible-playbook -K -i inventory/hosts setup.yml --tags=setup-all,ensure-matrix-users-created,start
#+end_src
* Docker-Compose
:PROPERTIES:
:header-args: :tangle /ssh:thomas@homelab:~/docker/docker-compose.yaml
+29 -5
View File
@@ -72,6 +72,7 @@ workspace_layout default
* Focus Configuration
#+begin_src conf
focus_follows_mouse no
focus_on_window_activation none
#+end_src
* Settings for i3-gaps
@@ -210,10 +211,10 @@ bindsym $mod+y sticky toggle
** focus/swap
#+begin_src conf
# Focus/swap the node in the given direction
bindsym $mod+h focus left
bindsym $mod+j focus down
bindsym $mod+k focus up
bindsym $mod+l focus right
bindsym $mod+h exec --no-startup-id i3-msg focus left && i3-focus-sync
bindsym $mod+j exec --no-startup-id i3-msg focus down && i3-focus-sync
bindsym $mod+k exec --no-startup-id i3-msg focus up && i3-focus-sync
bindsym $mod+l exec --no-startup-id i3-msg focus right && i3-focus-sync
bindsym $mod+Shift+h move left
bindsym $mod+Shift+j move down
@@ -227,7 +228,7 @@ bindsym $mod+p workspace prev
bindsym $mod+n workspace next
# Focus the last Desktop
bindsym $mod+b workspace back_and_forth
bindsym $mod+b exec --no-startup-id i3-msg workspace back_and_forth && i3-focus-sync
# Focus to the given desktop
bindsym $mod+1 workspace 1
@@ -286,6 +287,29 @@ bindsym $mod+$alt+k resize shrink height 10 px or 10 ppt
bindsym $mod+$alt+l resize grow width 10 px or 10 ppt
#+end_src
* Fix focus for =WM_TAKE_FOCUS= applications
Some applications (e.g. OnlyOffice, Electron apps) use the =WM_TAKE_FOCUS= protocol and
fail to release X11 keyboard focus when i3 moves focus elsewhere.
This keybinding forces X11 focus to the window i3 currently considers focused.
#+begin_src bash :tangle ~/.local/bin/i3-focus-sync :comments none :mkdirp yes :shebang "#!/usr/bin/env bash" :tangle-mode (identity #o755)
win=$(i3-msg -t get_tree | python3 -c "
import json, sys
def find_focused(node):
if node.get('focused') and node.get('window'):
return node['window']
for child in node.get('nodes', []) + node.get('floating_nodes', []):
r = find_focused(child)
if r is not None:
return r
return None
w = find_focused(json.load(sys.stdin))
if w is not None: print(w)
" 2>/dev/null)
[ -n "$win" ] && xdotool windowfocus --sync "$win" 2>/dev/null
#+end_src
* Run Polybar and SXHKD
#+begin_src conf
# exec --no-startup-id sxhkd -m 1 -c ~/.config/sxhkd/sxhkdrc.i3
+378 -1446
View File
File diff suppressed because it is too large Load Diff
+35
View File
@@ -6,6 +6,40 @@ Installation:
paru -S mbsync msmtp neomutt lynx urlview
#+end_src
* Claude Code — Email Assistant
#+begin_src markdown :tangle ~/.config/neomutt/CLAUDE.md :comments none :mkdirp yes
# Email Refinement Assistant
You are helping refine professional emails composed in Neomutt.
The file you receive is a raw email in RFC 2822 format: a header block
(lines like `From:`, `To:`, `Subject:`, `Cc:`) followed by a blank line,
then the body text.
## Your task
When asked to "refine" (or similar), edit the file directly so that a diff
can be reviewed. Apply all of the following:
- **Subject**: if it starts with `Re:`, this is a reply — do not change it; otherwise make it specific, informative and professional (avoid vague subjects like "Question" or "Update")
- **Grammar & spelling**: fix all errors
- **Clarity**: remove ambiguity; one idea per sentence
- **Conciseness**: cut filler words, redundant phrases and unnecessary
preamble; get to the point quickly
- **Tone**: professional but natural; avoid overly formal or stiff language
- **Structure**: ensure a proper greeting, clear body paragraphs and a
polite closing
- **Signature**: do not modify anything from the `-- ` line onwards (dash dash space — the trailing space is required by RFC 3676 and must not be removed)
- **Line breaks**: write one sentence per line in the body
## Constraints
- Preserve the header block exactly (do not reorder or remove headers),
only edit the `Subject:` value, and of course the main code text
- **Single edit**: you MUST apply every change (subject, grammar, tone, structure) in one single call to the file edit tool — do not make multiple sequential edits
- Do not invent facts or add content that was not implied by the original
- Preserve the author's intent and voice
#+end_src
* =mbsync= - Synchronize Mailboxes
:PROPERTIES:
:header-args:conf: :tangle ~/.config/isync/mbsyncrc
@@ -1685,3 +1719,4 @@ application/msword; onlyoffice-desktopeditors '%s'; copiousoutput
application/wordperfect; onlyoffice-desktopeditors '%s'; copiousoutput
text/rtf; onlyoffice-desktopeditors '%s'; copiousoutput
#+end_src
+1 -1
View File
@@ -1020,7 +1020,7 @@ fi
#+begin_src bash
~/.local/bin/lockscreen &
xset s activate
sleep 1 && xset s activate &
#+end_src
* Network
+1 -1
View File
@@ -419,7 +419,7 @@ config.bind(',q', 'QRcode')
** Create a new password
#+begin_src bash :tangle ~/.config/qutebrowser/userscripts/add-passowrd.sh
url=$(echo "$QUTE_URL" | awk -F[/:] '{print $4}' | rofi -i -p "URL" -dmenu -lines 1)
url=$(echo "$QUTE_URL" | awk -F[/:] '{print $4}' | grep -oP '[\w-]+\.[\w-]+$' | rofi -i -p "URL" -dmenu -lines 1)
username=$(echo -e "dehaeze.thomas@gmail.com\nthomas.dehaeze@esrf.fr\ntdehaeze" | rofi -p "Username" -dmenu -lines 5)
password=$(rofi -p "Password" -dmenu -password -lines 1)
+9
View File
@@ -0,0 +1,9 @@
#!/bin/bash
set -euo pipefail
echo "==> Calendar and contacts packages"
paru -S --needed \
vdirsyncer \
khal \
khard \
mu
+41
View File
@@ -0,0 +1,41 @@
#!/bin/bash
set -euo pipefail
DOTFILES="${HOME}/.config/literate-dotfiles"
tangle() {
emacsclient -e "(org-babel-tangle-file \"${DOTFILES}/$1\")" \
|| emacs --batch -l org --eval "(org-babel-tangle-file \"${DOTFILES}/$1\")"
}
echo "==> Desktop packages"
paru -S --needed \
i3-wm \
sxhkd \
polybar \
picom \
dunst \
rofi rofi-calc dmenu \
kitty \
bash bash-completion \
zoxide \
nerd-fonts-hack noto-fonts-emoji \
xorg-xrandr arandr \
xautocfg \
arc-gtk-theme xcursor-breeze \
feh xwallpaper
echo "==> Tangling desktop configs"
tangle "xconfig.org" # ~/.Xresources, ~/.xprofile, ~/.config/X11/xinitrc
tangle "bash.org" # ~/.bashrc, ~/.bash_profile, ~/.profile
tangle "kitty.org" # ~/.config/kitty/kitty.conf
tangle "i3.org" # ~/.config/i3/config
tangle "sxhkd.org" # ~/.config/sxhkd/sxhkdrc
tangle "polybar.org" # ~/.config/polybar/config.ini + scripts
tangle "compositor.org" # ~/.config/picom/picom.conf
tangle "rofi.org" # ~/.config/rofi/config.rasi
tangle "binaries.org" # ~/.local/bin/* scripts
tangle "binaries-private.org" # ~/.local/bin/* scripts
echo "==> Reloading desktop"
i3-msg restart 2>/dev/null || echo " (i3 not running, config will apply on next login)"
+19
View File
@@ -0,0 +1,19 @@
#!/bin/bash
set -euo pipefail
DOTFILES="${HOME}/.config/literate-dotfiles"
DOOM="${HOME}/.config/emacs/bin/doom"
echo "==> Emacs packages"
paru -S --needed emacs aspell aspell-en aspell-fr
echo "==> Installing Doom Emacs"
git clone --depth 1 https://github.com/doomemacs/doomemacs ~/.config/emacs
"${DOOM}" install --no-config
echo "==> Tangling doom.org"
emacsclient -e "(org-babel-tangle-file \"${DOTFILES}/doom.org\")" \
|| emacs --batch -l org --eval "(org-babel-tangle-file \"${DOTFILES}/doom.org\")"
echo "==> Running doom sync"
"${DOOM}" sync
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
set -euo pipefail
echo "==> Laptop power management"
paru -S --needed \
powertop \
tlp \
thermald
sudo systemctl enable --now tlp
sudo systemctl enable --now tlp-sleep
sudo systemctl enable --now thermald
sudo tlp start
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
set -euo pipefail
echo "==> LaTeX packages"
paru -S --needed \
texlive-most tllocalmgr-git \
biber
+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash
set -euo pipefail
echo "==> Mail packages"
paru -S --needed \
isync \
msmtp \
neomutt \
mu \
lynx urlview
+113
View File
@@ -0,0 +1,113 @@
#!/bin/bash
set -euo pipefail
echo "==> Shell and Terminal"
paru -S --needed \
bash bash-completion zsh \
kitty \
tmux
echo "==> Fonts"
paru -S --needed \
nerd-fonts-hack \
noto-fonts-emoji
echo "==> Text Editors"
paru -S --needed \
neovim python-pynvim \
emacs \
aspell aspell-en aspell-fr
echo "==> GnuPG and Pass"
paru -S --needed \
gnupg gnome-keyring \
pass rofi-pass pass-git-helper
echo "==> Window Manager and Desktop"
paru -S --needed \
i3-wm \
sxhkd \
polybar \
picom \
dunst \
rofi rofi-calc dmenu \
xautocfg \
xorg-xrandr arandr
echo "==> File Manager"
paru -S --needed yazi
echo "==> Terminal Utilities"
paru -S --needed \
fd ripgrep fzf \
xclip xsel \
atool unzip \
trash-cli \
man-db \
neofetch
echo "==> Browser"
paru -S --needed \
qutebrowser python-adblock pdfjs \
firefox-developer-edition passff-host
echo "==> Media"
paru -S --needed \
mpv \
jellyfin-tui \
nsxiv \
zathura zathura-pdf-mupdf zathura-djvu zathura-ps zathura-cb \
pdfpc \
gst-plugins-ugly gst-plugins-good gst-plugins-base-libs gst-plugins-base gst-plugins-bad gst-libav
echo "==> PipeWire"
paru -S --needed \
pipewire pipewire-alsa pipewire-audio pipewire-jack pipewire-pulse \
wireplumber \
pwvucontrol
echo "==> PDF and Image Utilities"
paru -S --needed \
pdf2svg pdftk pdfarranger \
imagemagick \
maim flameshot \
unclutter \
poppler
echo "==> Office"
paru -S --needed \
onlyoffice-bin \
libreoffice-fresh libreoffice-fresh-fr \
inkscape
echo "==> System Utilities"
paru -S --needed \
udiskie \
blueman \
sshfs \
xwallpaper \
sof-firmware \
usbutils \
xautolock \
npm \
xorg-xkill \
syncthing \
wireguard-tools \
gotify-dunst-git \
gomuks \
yt-dlp \
python ipython python-pip
echo "==> GTK Theme"
paru -S --needed \
lxappearance \
arc-gtk-theme \
xcursor-breeze \
gtk2fontsel
echo "==> Misc Utilities"
paru -S --needed \
screenkey \
xwallpaper \
highlight-pointer-git \
mpd
+18
View File
@@ -0,0 +1,18 @@
#!/bin/bash
set -euo pipefail
DOTFILES="${HOME}/.config/literate-dotfiles"
echo "==> Neovim packages"
paru -S --needed neovim python-pynvim nodejs-neovim
echo "==> Installing vim-plug"
sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
echo "==> Tangling vim.org"
emacsclient -e "(org-babel-tangle-file \"${DOTFILES}/vim.org\")" \
|| emacs --batch -l org --eval "(org-babel-tangle-file \"${DOTFILES}/vim.org\")"
echo "==> Installing neovim plugins"
nvim --headless +PlugInstall +UpdateRemotePlugins +qa
+5 -100
View File
@@ -125,7 +125,7 @@ super + z
#+begin_src conf
# Start Terminal
super + Return
$TERMINAL
$TERMINAL --instance-group 9
# Start Terminal (floating)
super + shift + Return
@@ -173,6 +173,10 @@ super + shift + s
super + shift + p
rofi-pass
# Umount all directories
super + shift + u
~/.local/bin/umount-dirs
# Fill ESRF password
super + shift + f
xdotool key $(pass esrf.fr/dehaeze | head -n 1 | sed 's/./& /g' | sed 's/}/braceright/g')
@@ -204,102 +208,3 @@ super + space ; p
super + space ; t
$TERMINAL -e tmux new-session -A -s stig stig
#+end_src
* I3 related
:PROPERTIES:
:header-args:conf+: :tangle ~/.config/sxhkd/sxhkdrc.i3
:END:
** Kill Window
#+begin_src conf
# close and kill
super + q
i3-msg kill
#+end_src
** Set the window State
#+begin_src conf
# Set the window to full-screen
super + f
i3-msg fullscreen toggle
# Set the window to floating
super + s
i3-msg floating toggle
# Alternate between the tiled and normal layout
super + t
i3-msg layout toggle tabbed split
# Change focus between tiling / floating windows
super + c
i3-msg focus mode_toggle
# Sticky window
super + y
i3-msg sticky toggle
#+end_src
** focus/swap
#+begin_src conf
# Focus/swap the node in the given direction
super + {_,shift + }{h,Left}
i3-msg {focus,move} left
super + {_,shift + }{j,Down}
i3-msg {focus,move} down
super + {_,shift + }{k,Up}
i3-msg {focus,move} up
super + {_,shift + }{l,Right}
i3-msg {focus,move} right
#+end_src
#+begin_src conf
# Focus the next/previous desktop in the current monitor
super + {p,n}
i3-msg workspace {prev,next}
# Focus the last Desktop
super + b
i3-msg workspace back_and_forth
# Focus to the given desktop
super + {1-9}
i3-msg workspace '{1-9}'
# Send to the given desktop
super + ctrl + {1-9}
i3-msg move container to workspace '{1-9}'
# Focus and Send to the given desktop
super + shift + {1-9}
WP={1-9} && i3-msg move container to workspace $WP && i3-msg workspace $WP
#+end_src
** Preselect
Preselect the direction
#+begin_src conf
# Set Horizontal Layout
super + ctrl + {h,l,Left,Right}
i3-msg split h
# Set Vertical Layout
super + ctrl + {j,k,Up,Down}
i3-msg split v
#+end_src
** Resize
Expand/Shrink a window
#+begin_src conf
# Horizontal Shrink
super + alt + h
i3-msg resize shrink width 10 px or 10 ppt
# Vertical Grow
super + alt + j
i3-msg resize grow height 10 px or 10 ppt
# Vertical Shrink
super + alt + k
i3-msg resize shrink height 10 px or 10 ppt
# Horizontal Grow
super + alt + l
i3-msg resize grow width 10 px or 10 ppt
#+end_src
+105
View File
@@ -4,6 +4,49 @@
#+PROPERTY: header-args+ :mkdirp yes
#+PROPERTY: header-args+ :tangle ~/.config/nvim/init.vim
* Installation
:PROPERTIES:
:header-args:bash: :tangle scripts/install-neovim.sh :shebang "#!/bin/bash" :mkdirp yes
:END:
#+begin_src bash
set -euo pipefail
DOTFILES="${HOME}/.config/literate-dotfiles"
#+end_src
** Packages
#+begin_src bash
echo "==> Neovim packages"
paru -S --needed neovim python-pynvim nodejs-neovim
#+end_src
** vim-plug
#+begin_src bash
echo "==> Installing vim-plug"
sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
#+end_src
** Tangle Configuration
Tangle =vim.org= to generate =~/.config/nvim/init.vim=:
#+begin_src bash
echo "==> Tangling vim.org"
emacsclient -e "(org-babel-tangle-file \"${DOTFILES}/vim.org\")" \
|| emacs --batch -l org --eval "(org-babel-tangle-file \"${DOTFILES}/vim.org\")"
#+end_src
** Install Plugins
#+begin_src bash
echo "==> Installing neovim plugins"
nvim --headless +PlugInstall +UpdateRemotePlugins +qa
#+end_src
* Plugins Install
** Plug start
#+BEGIN_SRC vimrc
@@ -131,6 +174,12 @@ Plug 'nvim-telescope/telescope-ui-select.nvim'
Plug 'folke/which-key.nvim'
#+end_src
** Claude Code
#+begin_src vimrc
Plug 'folke/snacks.nvim'
Plug 'coder/claudecode.nvim'
#+end_src
** Plug End
#+begin_src vimrc
call plug#end()
@@ -526,6 +575,13 @@ snoremap <C-K> <Esc>b[sviw<C-G>
#+begin_src vimrc
autocmd FileType mail set spell spelllang=en_us,fr
autocmd FileType mail set textwidth=0
autocmd FileType mail lcd %:p:h
" Start Claude: save, open Claude, add current buffer, then ask to refine
autocmd FileType mail nnoremap <buffer> <leader>ae <cmd>lua ClaudeMailRefine()<cr>
" Finish: accept diff, close Claude pane, save and quit
autocmd FileType mail nnoremap <buffer> <leader>aq <cmd>ClaudeCodeDiffAccept<cr><cmd>ClaudeCode<cr>
function! Mailcomplete(findstart, base)
if a:findstart == 1
@@ -788,6 +844,55 @@ lua << EOF
EOF
#+end_src
** Diff wrap
#+begin_src vimrc
autocmd OptionSet diff if v:option_new | setlocal wrap linebreak | endif
#+end_src
** =claudecode=
#+begin_src vimrc
lua << EOF
require('claudecode').setup({
split_side = "right",
split_width_percentage = 0.35,
})
function ClaudeMailRefine()
local win = vim.api.nvim_get_current_win()
vim.cmd('w')
vim.cmd('ClaudeCode')
vim.defer_fn(function()
if vim.api.nvim_win_is_valid(win) then
vim.api.nvim_set_current_win(win)
end
vim.cmd('ClaudeCodeAdd %')
vim.defer_fn(function()
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
local name = vim.api.nvim_buf_get_name(buf)
if name:match('claude') then
local job_id = vim.b[buf].terminal_job_id
if job_id then
vim.api.nvim_chan_send(job_id, "Refine this email using a single file edit tool call: fix the subject, grammar, clarity and tone all at once. Do not make multiple edits.\r")
break
end
end
end
end, 500)
end, 1000)
end
EOF
nnoremap <leader>ac <cmd>ClaudeCode<cr>
nnoremap <leader>af <cmd>ClaudeCodeFocus<cr>
nnoremap <leader>ar <cmd>ClaudeCode --resume<cr>
nnoremap <leader>aC <cmd>ClaudeCode --continue<cr>
nnoremap <leader>am <cmd>ClaudeCodeSelectModel<cr>
nnoremap <leader>ab <cmd>ClaudeCodeAdd %<cr>
vnoremap <leader>as <cmd>ClaudeCodeSend<cr>
nnoremap <leader>aa <cmd>ClaudeCodeDiffAccept<cr>
nnoremap <leader>ad <cmd>ClaudeCodeDiffDeny<cr>
#+end_src
* Key Bindings
** Quit
#+begin_src vimrc
+21 -11
View File
@@ -132,6 +132,24 @@ fi
exec i3
#+end_src
* =setup-display= Script
:PROPERTIES:
:header-args:bash: :tangle ~/.local/bin/setup-display :mkdirp yes :tangle-mode (identity #o755) :comments none
:END:
Detects connected outputs and applies the appropriate =xrandr= configuration.
#+begin_src bash :shebang "#!/bin/bash"
# Desktop: DP-5 connected
if xrandr | grep -q "^DP-5 connected"; then
xrandr --output DP-5 --mode 2560x1440 --dpi 192
# Laptop: eDP-1 connected
elif xrandr | grep -q "^eDP-1 connected"; then
xrandr --output eDP-1 --mode 1920x1200 --dpi 192
fi
#+end_src
* =~/.xprofile=
:PROPERTIES:
:header-args: :tangle ~/.xprofile
@@ -149,7 +167,7 @@ setxkbmap -layout us -variant intl -option caps:escape &
Start programs related to display:
#+begin_src bash
# Screen options
xrandr --output eDP-1 --mode 1920x1200 --dpi 192 &
~/.local/bin/setup-display &
# Set random wallpaper
setbg ~/.local/data/wallpapers/ &
@@ -159,7 +177,8 @@ pgrep -xu "$USER" unclutter >/dev/null || \
unclutter --timeout 5 &
# Autolock screen after x minutes
xautolock -locker "~/.local/bin/lockscreen" -detectsleep -time 30 -notify 60 -notifier "notify-send -u critical -t 10000 -- 'Locking Screen' '60 seconds'" &
pgrep -xu "$USER" xautolock >/dev/null || \
xautolock -locker "~/.local/bin/lockscreen" -detectsleep -time 30 -notify 60 -notifier "dunstify --replace=31846 -u critical -t 10000 -- 'Locking Screen' '60 seconds'" &
# Redshift
pgrep -xu "$USER" redshift >/dev/null || \
@@ -176,15 +195,6 @@ blueman-applet &
# Udiskie - Automatic USB mount
udiskie --notify --automount --tray &
# Japanese input
# fcitx -d &
#+end_src
Manually start =mopidy= as it seems to not start automatically:
#+begin_src bash
# Mopidy
~/.local/soft/mopidy-jellyfin/env/bin/mopidy >/tmp/mopidy.log 2>&1 &
#+end_src
Finally, run SXHKD for the key bindings: