2514 lines
79 KiB
Bash
2514 lines
79 KiB
Bash
# /etc/zsh/zshrc ou ~/.zshrc
|
||
# Fichier de configuration principal de zsh, lu au lancement des shells interactifs
|
||
# (et non des shells d'interprétation de fichier)
|
||
# Formation Debian GNU/Linux par Alexis de Lattre
|
||
# http://formation-debian.via.ecp.fr/
|
||
|
||
################
|
||
# 1. Les alias #
|
||
################
|
||
|
||
# Gestion du 'ls' : couleur & ne touche pas aux accents
|
||
alias ls='ls --classify --tabsize=0 --literal --color=auto --show-control-chars --human-readable'
|
||
|
||
# Copie en récursif et qui garde la date des fichiers copiés
|
||
#alias cp='cp -Rp'
|
||
alias cp='cp -R' # **cp** copy files and directories recursively # TEST
|
||
|
||
# Copie distante, ajout de la récursivité tout le temps:
|
||
alias scp='scp -r'
|
||
|
||
# Demande confirmation avant d'écraser un fichier
|
||
alias cP='cp --interactive'
|
||
alias mv='mv --interactive'
|
||
alias rm='rm --interactive'
|
||
|
||
# ls shortcut {{{
|
||
if [ ! $(command -v exa) ]; then
|
||
## with ls {{{
|
||
alias ll='ls -l'
|
||
## Show hidden files
|
||
alias la='ll --almost-all'
|
||
## Show hidden only
|
||
alias lla='la --directory .*'
|
||
alias l.='ls --directory .*'
|
||
alias llh='ll | head'
|
||
alias llp='ll | $PAGER'
|
||
alias llw='ll | wc --lines'
|
||
## Sort by date
|
||
alias lll='ls -l -t --human-readable --reverse'
|
||
alias llll='ls -l -t --human-readable --reverse'
|
||
alias lld='ls -l --directory */ --human-readable'
|
||
alias lr='ls --recursive | grep ":$" | sed -e '\''s/:$//'\'' -e '\''s/[^-][^\/]*\//--/g'\'' -e '\''s/^/ /'\'' -e '\''s/-/|/'\'''
|
||
## }}}
|
||
## with exa {{{
|
||
else
|
||
alias ll='exa --color=always --long --group --git'
|
||
## Show hidden files
|
||
alias la='ll --all --sort .name'
|
||
## Show hidden only
|
||
alias lla='ll --list-dirs .*'
|
||
alias l.='ls --directory .*'
|
||
alias llh='ll | head'
|
||
alias llp='ll | $PAGER'
|
||
alias llw='ll | wc --lines'
|
||
## Sort by date
|
||
alias lll='ll --sort=modified'
|
||
alias llll='ll --sort=modified'
|
||
## Give a tree of current directory
|
||
alias llt='ll --tree'
|
||
alias lld='ll --group-directories-first'
|
||
alias lr='ls --recursive | grep ":$" | sed -e '\''s/:$//'\'' -e '\''s/[^-][^\/]*\//--/g'\'' -e '\''s/^/ /'\'' -e '\''s/-/|/'\'''
|
||
## }}}
|
||
fi
|
||
# }}}
|
||
|
||
# cat with number on output lines
|
||
alias ca='cat --number'
|
||
# docker related
|
||
alias d='docker'
|
||
# Correct ip command
|
||
alias ipa='ip a'
|
||
# less with raw character
|
||
alias less='less --raw‐control‐chars'
|
||
#alias less='less --quiet'
|
||
# Call last command
|
||
alias pp='fc -e -'
|
||
# Call last command in edit mode
|
||
alias ppe='fc'
|
||
# Call last command with sudo
|
||
alias pps='sudo $(fc -ln -1)'
|
||
|
||
# fdfind
|
||
## disregard vcs ignore files (.gitignore…) as homedir is a git repository…
|
||
alias fd='fd --no-ignore-vcs'
|
||
|
||
# sudo
|
||
## Please consider using "Defaults env_keep+=HOME" configuration in sudoers {{{
|
||
### This is Ubuntu default behaviour.
|
||
### This will allow to share user's homedir/dotfiles with root throught sudo commands
|
||
## }}}
|
||
## Ensure sudo can use aliases (end whitespace) {{{
|
||
### `man zshall` partie Aliasing: "If the text ends with a space, the next word in the shell input is treated as though it were in command position for
|
||
### purposes of alias expansion. "
|
||
alias s='sudo '
|
||
## }}}
|
||
## sudo aliases {{{
|
||
if [ ${USER} != "root" ]; then
|
||
alias sc='sudo systemctl '
|
||
alias scu='systemctl --user'
|
||
alias sd='sudo docker'
|
||
alias si='sudo iptables -L -vn '
|
||
alias sj='sudo journalctl '
|
||
alias sn='sudo nft list ruleset'
|
||
alias sv='sudo vi '
|
||
alias sz='sudo zsh'
|
||
else
|
||
alias sc='systemctl '
|
||
alias scu='systemctl --user'
|
||
alias sd='docker'
|
||
alias si='iptables -L -vn '
|
||
alias sj='journalctl '
|
||
alias sn='nft list ruleset'
|
||
alias vi='vi -S ~/.vim/vimrc '
|
||
alias sv='vi -S ~/.vim/vimrc '
|
||
fi
|
||
## }}}
|
||
|
||
# Envoyer une notification via libnotify-bin (fin d'une commande, ...)
|
||
# Nécessite le paquet libnotify-bin
|
||
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
|
||
|
||
# Nettoyage de l'écran
|
||
alias c='clear'
|
||
# Liste le contenu du dossier
|
||
alias dir='dir --color=always'
|
||
|
||
# Page de manuel en anglais
|
||
alias mane="LANG=C man "
|
||
|
||
# Afficher les lignes trop longues sur la ligne suivante plutot que de remplacer par un "$":
|
||
alias most='most -w'
|
||
|
||
# APT|Aptitude|… commands {{{
|
||
if [ -d /etc/apt ]; then
|
||
alias acle='sudo aptitude clean'
|
||
alias afil='apt-file search --'
|
||
alias aful='sudo aptitude full-upgrade'
|
||
alias ains='sudo aptitude install'
|
||
alias alis='apt list --upgradable'
|
||
alias apol='apt-cache policy'
|
||
alias apur="sudo aptitude purge '~c'"
|
||
alias aupd='sudo apt update'
|
||
alias aupg='sudo aptitude upgrade'
|
||
alias arem='sudo aptitude remove'
|
||
alias apts='apt search'
|
||
alias asea='aptitude search --'
|
||
alias asho='aptitude show'
|
||
alias aver='apt-show-versions'
|
||
alias awhy='aptitude why'
|
||
alias insexperimental='sudo aptitude --target-release experimental install'
|
||
fi
|
||
# }}}
|
||
|
||
# Grep aliases {{{
|
||
alias grep='grep --color=always --ignore-case '
|
||
alias gerp='grep --ignore-case'
|
||
alias Grep='\grep '
|
||
alias gdpkg='dpkg --list | grep --extended-regexp -- '
|
||
alias gmount='mount | grep --extended-regexp -- '
|
||
alias gdf='df | grep --extended-regexp -- '
|
||
# }}}
|
||
|
||
# Espace disque
|
||
alias df='df --block-size=1K --print-type --human-readable'
|
||
alias dus='du --total --human-readable | sort --human-numeric-sort'
|
||
alias dua='du --all --total --human-readable | sort --human-numeric-sort'
|
||
alias ncdu='gdu'
|
||
|
||
# Gestion des processus:
|
||
# Si htop n'est pas installé sur la machine:
|
||
if [ ! -f "`which htop`" ]; then
|
||
alias htop=top
|
||
fi
|
||
|
||
# Qu'est-ce qui consomme de la mémoire vive sur le système
|
||
alias wotgobblemem='ps -o time,ppid,pid,nice,pcpu,pmem,user,comm -A | sort --numeric-sort --key=6 | tail -15'
|
||
|
||
# ps aliases
|
||
alias px='ps faux|grep --inverse-match -- grep|grep --extended-regexp --ignore-case --regexp=VSZ -e '
|
||
## ps with fzf
|
||
alias fpx="ps -ef | fzf --bind 'ctrl-r:reload(ps -ef)' --header 'Press CTRL-R to reload' --header-lines=1 --color fg:188,bg:233,hl:103,fg+:222,bg+:234,hl+:104"
|
||
alias pxf="ps -ef | fzf --bind 'ctrl-r:reload(ps -ef)' --header 'Press CTRL-R to reload' --header-lines=1 --color fg:188,bg:233,hl:103,fg+:222,bg+:234,hl+:104"
|
||
## ps last entries with watch|tail|grep
|
||
alias wps="watch \"ps faux | tail --lines=30 -- | grep --invert-match --extended-regexp '(tail|ps faux|grep)' --\""
|
||
alias psw="watch \"ps faux | tail --lines=30 -- | grep --invert-match --extended-regexp '(tail|ps faux|grep)' --\""
|
||
|
||
# Décompression
|
||
alias untargz='tar --gzip --extract --verbose -f'
|
||
alias untarbz2='tar --bzip2 --extract --verbose -f'
|
||
|
||
# Terminal multiplexer
|
||
alias ta='tmux a || tmux'
|
||
alias td='tmux detach'
|
||
|
||
# Send the content of a file to a privatebin
|
||
# Needs cpaste or any other Third party clients for PrivateBin
|
||
# https://github.com/PrivateBin/PrivateBin/wiki/Third-party-clients
|
||
alias pbin='~/repos/cpaste/cpaste --sourcecode --expire 1week --file '
|
||
|
||
## Git aliases − Try to prefix with 'gg' {{{
|
||
### Get status of the repo
|
||
alias ggstatus='git status'
|
||
### Show differences between changes and index and ensure to display colors even with a pipe
|
||
alias ggdiff='git diff --color=always'
|
||
### Show differences between changes and index WITHOUT any colors
|
||
alias ggnocolordiff='git diff --color=never'
|
||
### Show only words/characters differences
|
||
alias ggwdiff='git diff --color-words=. --patience'
|
||
### Add changes to index
|
||
alias ggadd='git add'
|
||
### Restore changes to be committed
|
||
alias ggrestore='git restore --staged'
|
||
### Remove files from the index
|
||
alias ggrm='git rm'
|
||
### Move or rename file
|
||
alias ggmv='git mv'
|
||
### Cancel changes
|
||
alias ggcheckout='git checkout --'
|
||
### Print lines matching a pattern
|
||
alias ggrep='git grep --color --line-number --perl-regexp'
|
||
alias gggrep='git grep --color --line-number --perl-regexp'
|
||
### Show commit logs
|
||
alias gglog="git log --graph --full-history --all --color --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'"
|
||
### Show last 20 commits with graph
|
||
alias gglg="git --no-pager log --graph --pretty=tformat:'%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%an %ar)%Creset' -20"
|
||
### Show all commits with graph
|
||
alias ggllg="git log --graph --pretty=tformat:'%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%an %ar)%Creset'"
|
||
### Display all commits/changes of a file
|
||
alias ggchanges="git log --follow --perl-regexp --"
|
||
|
||
### Commands that might require a valid gpg-agent
|
||
#### Download any new commits
|
||
alias ggpull='load-gpg-agent && git pull'
|
||
#### Commit changes
|
||
alias ggco='load-gpg-agent && git commit'
|
||
alias ggcommit='load-gpg-agent && git commit'
|
||
#### Amend changes
|
||
alias ggamend='load-gpg-agent && git commit --amend'
|
||
#### Update remote repository
|
||
alias ggpush='load-gpg-agent && git push'
|
||
## }}}
|
||
|
||
# Lister les fichiers de configuration inutiles
|
||
alias purge='grep-status --no-field-names --show-field=Package --field=Status config-files'
|
||
|
||
## Piped alias
|
||
alias -g H='| head'
|
||
alias -g T='tail --follow'
|
||
alias -g G='| grep --invert-match grep -- | grep --extended-regexp'
|
||
alias -g L='| less'
|
||
alias -g M="| most"
|
||
alias -g S="| sort"
|
||
alias -g V="| vimmanpager"
|
||
alias -g W="| wc --lines"
|
||
alias -g X="| xclip -selection clipboard"
|
||
alias -g TM="| tmux load-buffer -- -"
|
||
alias -g B="&|"
|
||
alias -g HL="--help"
|
||
alias -g MM="2>&1 | most"
|
||
alias -g LL="2>&1 | less"
|
||
alias -g CA="2>&1 | cat --show-all"
|
||
alias -g NE="2> /dev/null"
|
||
alias -g NUL="> /dev/null 2>&1"
|
||
|
||
## Affichage de l'historique
|
||
if [ "$PAGER" = "most" ]; then
|
||
# En commencant par la fin avec most (bidouillage, on est pas sensé avoir):
|
||
alias hist="fc -El 0 | most +$HISTSIZE"
|
||
# Une fois dans un fichier avec most, la touche 'B' permet d'aller à la fin du fichier
|
||
else
|
||
# En commencant par la fin avec less:
|
||
alias hist="fc -El 0 | $PAGER +G"
|
||
#alias hist="less +G ~/.zsh/history"
|
||
fi
|
||
alias ghist='fc -El 0 | grep --'
|
||
|
||
## Gestion des répertoires
|
||
alias u='cd ..'
|
||
alias uuu='cd ../../..'
|
||
alias cd..='cd ..'
|
||
alias ..='cd ..'
|
||
alias ...='cd ../..'
|
||
alias ....='cd ../../..'
|
||
# Revenir dans le dossier dans lequel on se trouvait précédemment
|
||
alias cd-='cd -'
|
||
alias uu='cd -'
|
||
# Afficher la pile des dossiers:
|
||
alias dirs='dirs -v'
|
||
# Créer les répertoires précédents si ils n'existent pas
|
||
alias mkdir='mkdir --parents'
|
||
# Affiche l'arborescence du répertoire courant
|
||
#alias tree="find . | sed 's/[^/]*\//| /g;s/| *\([^| ]\)/+--- \1/'"
|
||
#La commande tree "basique" fait ça très bien ...
|
||
|
||
# Affiche la variable $PATH ligne par ligne
|
||
alias path='printf %s $PATH | tr ":" "\n"'
|
||
|
||
# Edite le dernier fichier d'un dossier
|
||
## Fonctionement:
|
||
## (. correspond au fichier
|
||
## om les classent par date de modification
|
||
## [1] choisit le premier
|
||
## désactive les options GLOB_DOTS
|
||
alias vil='vi *(.om[1]^D)'
|
||
# Lancer vi pour qu'il ne conserve aucune trace du fichier
|
||
## Faire précéder la commande d'un espace empêche l'enregistrement dans l'historique du shell
|
||
alias vnb='vi -n "+set noundofile" "+set nobackup"'
|
||
|
||
# Différence entre deux fichiers
|
||
alias diff='colordiff -u'
|
||
alias diffs='\diff --side-by-side'
|
||
|
||
# Recherche toutes les occurences de l'arguments passé en paramètre dans l'historique des commandes
|
||
alias param='fc -l 0 | grep --'
|
||
|
||
# Multimédia
|
||
##Extraire la piste audio d'un .avi
|
||
alias avi2wav='mplayer -vc dummy -vo null -ao pcm:file=video.wav'
|
||
##Modifie la bar de progression du gestionnaire de téléchargement Axel
|
||
alias axel='axel -a --num-connection=20'
|
||
## List video file's subtitles
|
||
alias ff.list.subs='ffprobe -loglevel error -select_streams s -show_entries stream=index:stream_tags=language -of csv=p=0'
|
||
## List video file's audio stream
|
||
alias ff.list.audio='ffprobe -loglevel error -select_streams a -show_entries stream=index:stream_tags=language -of csv=p=0'
|
||
|
||
# Calculatrice en ligne de commande
|
||
alias caltos='bc'
|
||
|
||
#alias df='df --human-readable'
|
||
#alias du='du --human-readable'
|
||
alias m='mutt -y'
|
||
alias md='mkdir'
|
||
alias rd='rmdir'
|
||
|
||
#Internet
|
||
## Minimal webserver from current directory and available at http://IP.AD.RE.SS:8002
|
||
## See : https://docs.python.org/3/library/http.server.html
|
||
alias httpserv='python3 -m http.server -b $(hostname -i) 8002'
|
||
## Minimal webserver with upload option and storage in dedicated directory
|
||
alias httpup="mkdir --parent -- /tmp/http.upload.directory && cd -- /tmp/http.upload.directory && python3 ${HOME}/bin/upload-http-server.py --listen $(hostname -i) --port 8004"
|
||
|
||
## Limite l'envoi à 3 requêtes pour ping
|
||
alias ping="ping -c 3"
|
||
alias ping6="ping6 -c 3"
|
||
|
||
## JOSM
|
||
alias josm="java -jar -Xmx2048M /opt/josm-tested.jar"
|
||
|
||
# Khard
|
||
alias kemail='khard email'
|
||
alias kmail='khard email'
|
||
alias kphone='khard phone'
|
||
alias ktel='khard phone'
|
||
|
||
# SSH {{{
|
||
#########
|
||
|
||
# Load ssh-agent with a fix socket path {{{
|
||
## This function can be used :
|
||
## 1. in zlogin (for a new shell)
|
||
## 2. with recossh alias to load a new ssh-agent
|
||
function load-ssh-agent() {
|
||
# If a ssh-key is available
|
||
if find "${HOME}/.ssh" -maxdepth 1 -type f -iname "id_*" | grep --quiet -- .; then
|
||
## If ssh-agent is not already launched
|
||
if ! ps -x | grep --invert-match -- grep | grep --fixed-strings --quiet -- "ssh-agent -a ${SSH_AGENT_SOCK}"; then
|
||
### Remove any previous socket and environment files
|
||
rm --force -- "${SSH_AGENT_SOCK}" "${SSH_AGENT_ENV}"
|
||
### Start ssh-agent with a specified socket path
|
||
### AND store informations in a file
|
||
ssh-agent -a "${SSH_AGENT_SOCK}" > "${SSH_AGENT_ENV}"
|
||
fi
|
||
## Load content of ssh-agent environment file
|
||
source "${SSH_AGENT_ENV}"
|
||
fi
|
||
}
|
||
# }}}
|
||
# Add ed25519 ssh-key to ssh-agent {{{
|
||
function load-ssh-ed25519() {
|
||
# If a ED25519 ssh-key is available
|
||
# AND not already loaded in ssh-agent
|
||
if [ -f "${SSH_ED25519_KEY}" ] &&
|
||
! ssh-add -l | grep --quiet --ignore-case -- "(ed25519)"; then
|
||
ssh-add "${SSH_ED25519_KEY}"
|
||
fi
|
||
}
|
||
# }}}
|
||
# Add rsa ssh-key to ssh-agent {{{
|
||
function load-ssh-rsa() {
|
||
# If a RSA ssh-key is available
|
||
# AND not already loaded in ssh-agent
|
||
if [ -f "${SSH_RSA_KEY}" ] &&
|
||
! ssh-add -l | grep --quiet --ignore-case -- "(rsa)"; then
|
||
ssh-add "${SSH_RSA_KEY}"
|
||
fi
|
||
}
|
||
# }}}
|
||
# Clear old entries in known_hosts {{{
|
||
function clearsshkey() {
|
||
sed -i "${1}d" ~/.ssh/known_hosts
|
||
}
|
||
# }}}
|
||
|
||
# recossh will:
|
||
# (re)load ssh-agent informations
|
||
# run the previous ssh command
|
||
alias recossh='load-ssh-agent &&
|
||
$(fc -lr 4900 | \grep --max-count=1 --extended-regexp "[0-9]{1,4} ssh " | cut --delimiter=" " --fields=4-)'
|
||
|
||
# For development and tests
|
||
alias sshdev='ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=accept-new'
|
||
alias scpdev='scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=accept-new'
|
||
|
||
# }}}
|
||
|
||
# GPG {{{
|
||
#########
|
||
|
||
# (re)Load gpg-agent {{{
|
||
## This function can be used :
|
||
## 1. with aliases (git commit,…)
|
||
function load-gpg-agent() {
|
||
## If a gpg key is available
|
||
if [ -f "${GPG_PRIV_KEY}" ]; then
|
||
## Remove any previous test file
|
||
rm --force -- "${GPG_TEST_FILE}"
|
||
## Run a gpg command on the test file
|
||
gpg --quiet --for-your-eyes-only --decrypt "${GPG_TEST_FILE}.gpg" > /dev/null
|
||
fi
|
||
}
|
||
# }}}
|
||
|
||
# }}}
|
||
|
||
# Taskwarrior {{{
|
||
## Aliases
|
||
alias t="task"
|
||
### Most recent tasks first
|
||
alias tarecent="task simple limit:page"
|
||
alias taold="task oldest limit:page"
|
||
### All pending tasks
|
||
alias tapending="task rc._forcecolor:on +PENDING all | less"
|
||
### Filter by tag
|
||
alias tawork="task rc._forcecolor:on +work | head"
|
||
alias taperso="task rc._forcecolor:on +perso | head"
|
||
alias tarm=tadel
|
||
|
||
## Functions
|
||
## search in pending tasks by task's name (case INsensitive) {{{
|
||
function tase() {
|
||
local search=""
|
||
for i; do; search="$search /$i/"; done;
|
||
task rc.search.case.sensitive:no +PENDING $search all || return 0
|
||
}
|
||
## }}}
|
||
## search in pending tasks by task's name (case SENSITIVE) {{{
|
||
function tasec() {
|
||
local search=""
|
||
for i; do; search="$search /$i/"; done;
|
||
task $search +PENDING all || return 0
|
||
}
|
||
## }}}
|
||
## search in all tasks by task's name (case INsensitive) {{{
|
||
function tall() {
|
||
local search=""
|
||
for i; do; search="$search /$i/"; done;
|
||
task rc.search.case.sensitive:no $search all || return 0
|
||
}
|
||
## }}}
|
||
## Delete a task {{{
|
||
function tadel() {
|
||
local tadel_task_id
|
||
local tadel_task_desc
|
||
local tadel_confirmation
|
||
|
||
# Verify argument
|
||
if [ "${#}" -eq 1 ]; then
|
||
## Get the first arg as task ID
|
||
tadel_task_id="${1}"
|
||
else
|
||
## If no argument or more than one
|
||
## Ask the user to choose an ID in the 20 more recents tasks {{{
|
||
task newest limit:20 || return 0
|
||
|
||
printf '%b' "Enter the ${MAGENTAB}ID${RESET} of the task to remove : "
|
||
read -r tadel_task_id
|
||
## }}}
|
||
fi
|
||
|
||
# If no task with this ID exists, exit function {{{
|
||
if ! task "${tadel_task_id}" | grep --quiet -- "^ID *${tadel_task_id}"; then
|
||
printf '%b' "No available task with ${REDB}${tadel_task_id}${RESET} ID."
|
||
return 1
|
||
fi
|
||
# }}}
|
||
|
||
# Get task's description
|
||
tadel_task_desc=$(task "${tadel_task_id}" | sed --quiet "s/^Description *\(.*\)/\1/p")
|
||
|
||
printf '%b' "Delete the task \"${MAGENTAB}${tadel_task_id} − ${tadel_task_desc}${RESET}\" [Y/n] ? "
|
||
read -r tadel_confirmation
|
||
|
||
# Check confirmation
|
||
if printf -- '%s' "${tadel_confirmation:=y}" | grep --quiet --word-regexp -- "y"; then
|
||
task rc.confirmation:no "${tadel_task_id}" delete
|
||
printf '%b' "\"${MAGENTAB}${tadel_task_id} − ${tadel_task_desc}${RESET}\" task was removed.\n"
|
||
fi
|
||
|
||
# Also offer to purge this task
|
||
tapurge "${tadel_task_desc}"
|
||
}
|
||
## }}}
|
||
## Mark a task as done {{{
|
||
function tadone() {
|
||
local tadone_task_regexp
|
||
local tadone_task_id
|
||
local tadone_task_desc
|
||
local tadone_confirmation
|
||
|
||
# Verify argument
|
||
if [ "${#}" -eq 0 ]; then
|
||
## If no argument
|
||
## Ask the user to choose a task description from the last week Timewarrior activities {{{
|
||
timew summary :week :ids || return 0
|
||
|
||
printf '%b' "Enter the ${MAGENTAB}a pattern${RESET} matching the expected task to mark as complete : "
|
||
read -r tadone_task_regexp
|
||
else
|
||
## Merge all args into one var
|
||
tadone_task_regexp="${*}"
|
||
## }}}
|
||
fi
|
||
|
||
#printf '%b' "Pattern to search a task is ${REDB}${tadone_task_regexp}${RESET}.\n"
|
||
tadone_task_id=$(task "${tadone_task_regexp}" simpleid | grep --after-context=2 -- ID | tail --lines=1 || return 0)
|
||
|
||
# If no task with this ID exists, exit function {{{
|
||
if [ -z "${tadone_task_id}" ]; then
|
||
printf '%b' "No available task with ${REDB}${tadone_task_regexp}${RESET} pattern."
|
||
return 1
|
||
fi
|
||
# }}}
|
||
|
||
# Get task's description
|
||
tadone_task_desc=$(task "${tadone_task_id}" | sed --quiet "s/^Description *\(.*\)/\1/p")
|
||
|
||
printf '%b' "Mark the task \"${MAGENTAB}${tadone_task_id} − ${tadone_task_desc}${RESET}\" as done [Y/n] ? "
|
||
read -r tadone_confirmation
|
||
|
||
# Check confirmation
|
||
if printf -- '%s' "${tadone_confirmation:=y}" | grep --quiet --word-regexp -- "y"; then
|
||
task "${tadone_task_id}" done
|
||
printf '%b' "\"${MAGENTAB}${tadone_task_id} − ${tadone_task_desc}${RESET}\" task is now complete."
|
||
fi
|
||
}
|
||
## }}}
|
||
## Purge an old task {{{
|
||
function tapurge() {
|
||
local tapurge_task_regexp
|
||
local tapurge_task_desc
|
||
local tapurge_confirmation
|
||
|
||
# Verify argument
|
||
if [ "${#}" -eq 0 ]; then
|
||
## If no argument
|
||
## Ask the user to choose a task description from the deleted tasks list {{{
|
||
task all status:deleted || return 0
|
||
|
||
printf '%b' "Enter few ${MAGENTAB}words matching the description${RESET} of the expected task to purge : "
|
||
read -r tapurge_task_regexp
|
||
else
|
||
## Merge all args into one var
|
||
tapurge_task_regexp="${*}"
|
||
## }}}
|
||
fi
|
||
|
||
tapurge_task_desc=$(task "${tapurge_task_regexp}" simpledeleted | grep --after-context=2 -- "^Description" | tail --lines=1 || return 0)
|
||
|
||
# If no task with this Description exists, exit function {{{
|
||
if [ -z "${tapurge_task_desc}" ]; then
|
||
printf '%b' "No available task with ${REDB}${tapurge_task_regexp}${RESET} pattern."
|
||
return 1
|
||
fi
|
||
# }}}
|
||
|
||
printf '%b' "Completly purge the task \"${MAGENTAB}${tapurge_task_desc}${RESET}\" [Y/n] ? "
|
||
read -r tapurge_confirmation
|
||
|
||
# Check confirmation
|
||
if printf -- '%s' "${tapurge_confirmation:=y}" | grep --quiet --word-regexp -- "y"; then
|
||
task rc.confirmation:no "${tapurge_task_desc}" purge
|
||
printf '%b' "\"${MAGENTAB}${tapurge_task_desc}${RESET}\" was purged."
|
||
fi
|
||
}
|
||
## }}}
|
||
## Take note for a task {{{
|
||
function tanote() {
|
||
local tanote_task_regexp
|
||
local tanote_task_id
|
||
local tanote_task_desc
|
||
local tanote_confirmation
|
||
|
||
# Verify argument
|
||
if [ "${#}" -eq 0 ]; then
|
||
## If no argument
|
||
## Ask the user to choose a task description from the recent tasks {{{
|
||
task simple limit:page || return 0
|
||
|
||
printf '%b' "Enter ${MAGENTAB}a pattern${RESET} matching the expected task that need notes : "
|
||
read -r tanote_task_regexp
|
||
else
|
||
## Merge all args into one var
|
||
tanote_task_regexp="${*}"
|
||
## }}}
|
||
fi
|
||
|
||
tanote_task_id=$(task "${tanote_task_regexp}" simpleid | grep --after-context=2 -- ID | tail --lines=1 || return 0)
|
||
|
||
# If no task with this ID exists, exit function {{{
|
||
if [ -z "${tanote_task_id}" ]; then
|
||
printf '%b' "No available task with ${REDB}${tanote_task_regexp}${RESET} pattern."
|
||
return 1
|
||
fi
|
||
# }}}
|
||
|
||
# Get task's description
|
||
tanote_task_desc=$(task "${tanote_task_id}" | sed --quiet "s/^Description *\(.*\)/\1/p")
|
||
|
||
printf '%b' "Add notes to \"${MAGENTAB}${tanote_task_id} − ${tanote_task_desc}${RESET}\" task [Y/n] ? "
|
||
read -r tanote_confirmation
|
||
|
||
# Check confirmation
|
||
if printf -- '%s' "${tanote_confirmation:=y}" | grep --quiet --word-regexp -- "y"; then
|
||
task note "${tanote_task_id}"
|
||
fi
|
||
}
|
||
## }}}
|
||
|
||
## Completion {{{
|
||
zstyle ':completion:*:*:task:*' verbose yes
|
||
zstyle ':completion:*:*:task:*:descriptions' format '%U%B%d%b%u'
|
||
zstyle ':completion:*:*:task:*' group-name ''
|
||
## }}}
|
||
# }}}
|
||
# Timewarrior {{{
|
||
## Aliases
|
||
alias tid="tiday"
|
||
alias tiw="tiweek"
|
||
alias tim="timonth"
|
||
alias timv="timove"
|
||
alias tiresize="tiduration"
|
||
|
||
## Functions
|
||
## Display tasks of today {{{
|
||
function tiday() {
|
||
if [ "${#}" -eq 0 ]; then
|
||
timew summary :day :ids || return 0
|
||
else
|
||
timew summary :day :ids "${*}" || return 0
|
||
fi
|
||
}
|
||
## }}}
|
||
## Display tasks of last day {{{
|
||
function tilastday() {
|
||
if [ "${#}" -eq 0 ]; then
|
||
timew summary :yesterday :ids || return 0
|
||
else
|
||
timew summary :yesterday :ids "${*}" || return 0
|
||
fi
|
||
}
|
||
## }}}
|
||
## Display tasks of this week {{{
|
||
function tiweek() {
|
||
if [ "${#}" -eq 0 ]; then
|
||
timew summary :week :ids || return 0
|
||
else
|
||
timew summary :week :ids "${*}" || return 0
|
||
fi
|
||
}
|
||
## }}}
|
||
## Display tasks of last week {{{
|
||
function tilastweek() {
|
||
if [ "${#}" -eq 0 ]; then
|
||
timew summary :lastweek :ids || return 0
|
||
else
|
||
timew summary :lastweek :ids "${*}" || return 0
|
||
fi
|
||
}
|
||
## }}}
|
||
## Display tasks of this month {{{
|
||
function timonth() {
|
||
if [ "${#}" -eq 0 ]; then
|
||
timew summary :month :ids || return 0
|
||
else
|
||
timew summary :month :ids "${*}" || return 0
|
||
fi
|
||
}
|
||
## }}}
|
||
## Display tasks of last month {{{
|
||
function tilastmonth() {
|
||
if [ "${#}" -eq 0 ]; then
|
||
timew summary :lastmonth :ids || return 0
|
||
else
|
||
timew summary :lastmonth :ids "${*}" || return 0
|
||
fi
|
||
}
|
||
## }}}
|
||
## Display tasks of this year {{{
|
||
function tiyear() {
|
||
if [ "${#}" -eq 0 ]; then
|
||
timew summary :year :ids || return 0
|
||
else
|
||
timew summary :year :ids "${*}" || return 0
|
||
fi
|
||
}
|
||
## }}}
|
||
## Display tasks of last year {{{
|
||
function tilastyear() {
|
||
if [ "${#}" -eq 0 ]; then
|
||
timew summary :lastyear :ids || return 0
|
||
else
|
||
timew summary :lastyear :ids "${*}" || return 0
|
||
fi
|
||
}
|
||
## }}}
|
||
## Double spent time on a task {{{
|
||
## "double" cause by default my tasks runs for 25 minutes
|
||
function tidouble() {
|
||
# Default duration time to add to a task
|
||
local tidouble_extra_time="25mins"
|
||
local tidouble_task_id
|
||
local tidouble_confirmation
|
||
local tidouble_task_desc
|
||
|
||
# Verify argument
|
||
if [ "${#}" -eq 1 ]; then
|
||
## Get the first arg as task ID
|
||
tidouble_task_id="${1}"
|
||
else
|
||
## If no argument or more than one
|
||
## Ask the user to choose an ID in tasks from the yesterday {{{
|
||
timew summary from yesterday :ids || return 0
|
||
|
||
printf '%b' "Enter the ${MAGENTAB}ID${RESET} of the task to double spent time should be doubled : "
|
||
read -r tidouble_task_id
|
||
## }}}
|
||
fi
|
||
|
||
# If no task with this ID exists, exit function {{{
|
||
if ! timew summary :year :ids | grep --quiet -- " @${tidouble_task_id} "; then
|
||
printf '%b' "No available task in the last year with ${REDB}${tidouble_task_id}${RESET} ID."
|
||
return 1
|
||
fi
|
||
# }}}
|
||
|
||
# Get task's description from all task of this year
|
||
tidouble_task_desc=$(timew summary :year :ids | sed --quiet "s/.*@\(${tidouble_task_id} .*\)/\1/p" | sed 's/ */ − /g')
|
||
|
||
printf '%b' "Add ${tidouble_extra_time} to \"${MAGENTAB}${tidouble_task_desc}${RESET}\" [Y/n] ? "
|
||
read -r tidouble_confirmation
|
||
|
||
# Check confirmation
|
||
if printf -- '%s' "${tidouble_confirmation:=y}" | grep --quiet --word-regexp -- "y"; then
|
||
timew lengthen @"${tidouble_task_id}" "${tidouble_extra_time}" || return 0
|
||
timew split @"${tidouble_task_id}" || return 0
|
||
printf '%b' "${tidouble_extra_time} were added to \"${MAGENTAB}${tidouble_task_desc}${RESET}\" task."
|
||
fi
|
||
}
|
||
## }}}
|
||
## Delete a time tracking {{{
|
||
function tirm() {
|
||
local tirm_task_id
|
||
local tirm_task_desc
|
||
local tirm_confirmation
|
||
|
||
# Verify argument
|
||
if [ "${#}" -eq 1 ]; then
|
||
## Get the first arg as task ID
|
||
tirm_task_id="${1}"
|
||
else
|
||
## If no argument or more than one
|
||
## Ask the user to choose an ID in tasks from the yesterday {{{
|
||
timew summary from yesterday :ids || return 0
|
||
|
||
printf '%b' "Enter the ${MAGENTAB}ID${RESET} of the task to delete : "
|
||
read -r tirm_task_id
|
||
## }}}
|
||
fi
|
||
|
||
# If no task with this ID exists, exit function {{{
|
||
if ! timew summary :year :ids | grep --quiet -- " @${tirm_task_id} "; then
|
||
printf '%b' "No available task in the last year with ${REDB}${tirm_task_id}${RESET} ID."
|
||
return 1
|
||
fi
|
||
# }}}
|
||
|
||
# Get task's description from all task of this year
|
||
tirm_task_desc=$(timew summary :year :ids | sed --quiet "s/.*@\(${tirm_task_id} .*\)/\1/p" | sed 's/ */ − /g')
|
||
|
||
printf '%b' "Delete to \"${MAGENTAB}${tirm_task_desc}${RESET}\" [Y/n] ? "
|
||
read -r tirm_confirmation
|
||
|
||
# Check confirmation
|
||
if printf -- '%s' "${tirm_confirmation:=y}" | grep --quiet --word-regexp -- "y"; then
|
||
timew delete @"${tirm_task_id}" || return 0
|
||
printf '%b' "${tirm_task_desc} was deleted"
|
||
fi
|
||
}
|
||
## }}}
|
||
## Modify the start of a time tracking {{{
|
||
function tistart() {
|
||
|
||
# Define new_start empty by default
|
||
local tistart_time_new_start=""
|
||
local tistart_time_id
|
||
local tistart_time_desc
|
||
local tistart_time_start_day
|
||
local tistart_confirmation
|
||
|
||
# Verify argument
|
||
case "${#}" in
|
||
1 )
|
||
## Get the first arg as time ID
|
||
tistart_time_id="${1}"
|
||
;;
|
||
2 )
|
||
## Get the first arg as time ID
|
||
tistart_time_id="${1}"
|
||
|
||
## Get the second arg as new start time for this track
|
||
tistart_time_new_start="${2}"
|
||
;;
|
||
* )
|
||
## Ask the user to choose an ID in time tracking from the yesterday {{{
|
||
timew summary from yesterday :ids || return 0
|
||
|
||
printf '%b' "Enter the ${MAGENTAB}ID${RESET} of the time tracking to modify : "
|
||
read -r tistart_time_id
|
||
## }}}
|
||
;;
|
||
esac
|
||
|
||
# If no time tracking exists with this ID, exit function {{{
|
||
if ! timew summary :year :ids | grep --quiet -- " @${tistart_time_id} "; then
|
||
printf '%b' "No available time tracking in the last year with ${REDB}${tistart_time_id}${RESET} ID."
|
||
return 1
|
||
fi
|
||
# }}}
|
||
|
||
# Get time tracking's description from all time tracking of this year
|
||
tistart_time_desc=$(timew summary :year :ids | sed --quiet "s/.*@\(${tistart_time_id} .*\)/\1/p" | sed 's/ */ − /g')
|
||
|
||
# Get time tracking's start day from all time tracking
|
||
tistart_time_start_day=$(timew export | sed --quiet --regexp-extended "s/^\{\"id\":${tistart_time_id},\"start\":\"([0-9]{4})([0-9]{2})([0-9]{2})T.*end.*/\1-\2-\3/p")
|
||
|
||
# Check or ask for new start time {{{
|
||
if [ -z "${tistart_time_new_start}" ]; then
|
||
printf '%b' "Enter the ${MAGENTAB}new start time${RESET} (or new date 'YYYY-MM-DD${REDB}T${RESET}HH:MM:SS'; default day is ${tistart_time_start_day}) for this time tracking : "
|
||
read -r tistart_time_new_start
|
||
fi
|
||
# }}}
|
||
|
||
printf '%b' "Change start time of \"${MAGENTAB}${tistart_time_desc}${RESET}\" to ${REDB}=> ${tistart_time_new_start} <=${RESET} [Y/n] ? "
|
||
read -r tistart_confirmation
|
||
|
||
# Check confirmation
|
||
if printf -- '%s' "${tistart_confirmation:=y}" | grep --quiet --word-regexp -- "y"; then
|
||
## If the new start time entered by user contains a "T" (user enter a dateTtime)
|
||
if printf -- '%s' "${tistart_time_new_start}" | grep --quiet -- "T"; then
|
||
printf '%b' "start time of ${tistart_time_desc} is now ${tistart_time_new_start}."
|
||
timew modify start @"${tistart_time_id}" "${tistart_time_new_start}" || return 0
|
||
else
|
||
printf '%b' "start time of ${tistart_time_desc} is now ${tistart_time_start_day}T${tistart_time_new_start}."
|
||
timew modify start @"${tistart_time_id}" "${tistart_time_start_day}T${tistart_time_new_start}" || return 0
|
||
fi
|
||
fi
|
||
}
|
||
## }}}
|
||
## Modify the end of a time tracking {{{
|
||
function tiend() {
|
||
|
||
# Define new_end empty by default
|
||
local tiend_time_new_end=""
|
||
local tiend_time_id
|
||
local tiend_time_new_end
|
||
local tiend_time_desc
|
||
local tiend_time_start_day
|
||
local tiend_confirmation
|
||
|
||
# Verify argument
|
||
case "${#}" in
|
||
1 )
|
||
## Get the first arg as time ID
|
||
tiend_time_id="${1}"
|
||
;;
|
||
2 )
|
||
## Get the first arg as time ID
|
||
tiend_time_id="${1}"
|
||
|
||
## Get the second arg as new end time for this track
|
||
tiend_time_new_end="${2}"
|
||
;;
|
||
* )
|
||
## Ask the user to choose an ID in time tracking from the yesterday {{{
|
||
timew summary from yesterday :ids || return 0
|
||
|
||
printf '%b' "Enter the ${MAGENTAB}ID${RESET} of the time tracking to modify : "
|
||
read -r tiend_time_id
|
||
## }}}
|
||
;;
|
||
esac
|
||
|
||
# If no time tracking exists with this ID, exit function {{{
|
||
if ! timew summary :year :ids | grep --quiet -- " @${tiend_time_id} "; then
|
||
printf '%b' "No available time tracking in the last year with ${REDB}${tiend_time_id}${RESET} ID."
|
||
return 1
|
||
fi
|
||
# }}}
|
||
|
||
# Get time tracking's description from all time tracking of this year
|
||
tiend_time_desc=$(timew summary :year :ids | sed --quiet "s/.*@\(${tiend_time_id} .*\)/\1/p" | sed 's/ */ − /g')
|
||
|
||
# Get time tracking's start day from all time tracking
|
||
tiend_time_start_day=$(timew export | sed --quiet --regexp-extended "s/^\{\"id\":${tiend_time_id},\"start\":\"([0-9]{4})([0-9]{2})([0-9]{2})T.*end.*/\1-\2-\3/p")
|
||
|
||
# Check or ask for new end time {{{
|
||
if [ -z "${tiend_time_new_end}" ]; then
|
||
printf '%b' "Enter the ${MAGENTAB}new end time${RESET} (or new date 'YYYY-MM-DD${REDB}T${RESET}HH:MM:SS'; default day is ${tiend_time_start_day}) for this time tracking : "
|
||
read -r tiend_time_new_end
|
||
fi
|
||
# }}}
|
||
|
||
printf '%b' "Change end time of \"${MAGENTAB}${tiend_time_desc}${RESET}\" to ${REDB}=> ${tiend_time_new_end} <=${RESET} [Y/n] ? "
|
||
read -r tiend_confirmation
|
||
|
||
# Check confirmation
|
||
if printf -- '%s' "${tiend_confirmation:=y}" | grep --quiet --word-regexp -- "y"; then
|
||
## If the new end time entered by user contains a "T" (user enter a dateTtime)
|
||
if printf -- '%s' "${tiend_time_new_end}" | grep --quiet -- "T"; then
|
||
timew modify end @"${tiend_time_id}" "${tiend_time_new_end}" || return 0
|
||
printf '%b' "End time of ${tiend_time_desc} is now ${tiend_time_new_end}."
|
||
else
|
||
timew modify end @"${tiend_time_id}" "${tiend_time_start_day}T${tiend_time_new_end}" || return 0
|
||
printf '%b' "End time of ${tiend_time_desc} is now ${tiend_time_start_day}T${tiend_time_new_end}."
|
||
fi
|
||
fi
|
||
}
|
||
## }}}
|
||
## Modify the duration of a time tracking {{{
|
||
function tiduration() {
|
||
|
||
# Define new_duration empty by default
|
||
local tiduration_time_new_duration=""
|
||
local tiduration_time_id
|
||
local tiduration_time_new_duration
|
||
local tiduration_time_desc
|
||
local tiduration_confirmation
|
||
|
||
# Verify argument
|
||
case "${#}" in
|
||
1 )
|
||
## Get the first arg as time ID
|
||
tiduration_time_id="${1}"
|
||
;;
|
||
2 )
|
||
## Get the first arg as time ID
|
||
tiduration_time_id="${1}"
|
||
|
||
## Get the second arg as new end time for this track
|
||
tiduration_time_new_duration="${2}"
|
||
;;
|
||
* )
|
||
## Ask the user to choose an ID in time tracking from the yesterday {{{
|
||
timew summary from yesterday :ids || return 0
|
||
|
||
printf '%b' "Enter the ${MAGENTAB}ID${RESET} of the time tracking to modify : "
|
||
read -r tiduration_time_id
|
||
## }}}
|
||
;;
|
||
esac
|
||
|
||
# If no time tracking exists with this ID, exit function {{{
|
||
if ! timew summary :year :ids | grep --quiet -- " @${tiduration_time_id} "; then
|
||
printf '%b' "No available time tracking in the last year with ${REDB}${tiduration_time_id}${RESET} ID."
|
||
return 1
|
||
fi
|
||
# }}}
|
||
|
||
# Get time tracking's description from all time tracking of this year
|
||
tiduration_time_desc=$(timew summary :year :ids | sed --quiet "s/.*@\(${tiduration_time_id} .*\)/\1/p" | sed 's/ */ − /g')
|
||
|
||
# Check or ask for new end time {{{
|
||
if [ -z "${tiduration_time_new_duration}" ]; then
|
||
printf '%b' "Enter the ${MAGENTAB}new duration${RESET} (eg. 25mins, 1hour…) for this time tracking : "
|
||
read -r tiduration_time_new_duration
|
||
fi
|
||
# }}}
|
||
|
||
printf '%b' "Change duration of \"${MAGENTAB}${tiduration_time_desc}${RESET}\" to ${REDB}=> ${tiduration_time_new_duration} <=${RESET} [Y/n] ? "
|
||
read -r tiduration_confirmation
|
||
|
||
# Check confirmation
|
||
if printf -- '%s' "${tiduration_confirmation:=y}" | grep --quiet --word-regexp -- "y"; then
|
||
timew resize @"${tiduration_time_id}" "${tiduration_time_new_duration}" || return 0
|
||
printf '%b' "Duration of ${tiduration_time_desc} is now ${tiduration_time_new_duration}."
|
||
fi
|
||
}
|
||
## }}}
|
||
## Move a time tracking {{{
|
||
function timove() {
|
||
|
||
# Define new_start empty by default
|
||
local timove_time_new_start=""
|
||
local timove_time_id
|
||
local timove_time_new_start
|
||
local timove_time_desc
|
||
local timove_time_start_day
|
||
local timove_confirmation
|
||
|
||
# Verify argument
|
||
case "${#}" in
|
||
1 )
|
||
## Get the first arg as task ID
|
||
timove_time_id="${1}"
|
||
;;
|
||
2 )
|
||
## Get the first arg as task ID
|
||
timove_time_id="${1}"
|
||
|
||
## Get the second arg as new start time for the task
|
||
timove_time_new_start="${2}"
|
||
;;
|
||
* )
|
||
## Ask the user to choose an ID in tasks from the yesterday {{{
|
||
timew summary from yesterday :ids || return 0
|
||
|
||
printf '%b' "Enter the ${MAGENTAB}ID${RESET} of the task to move : "
|
||
read -r timove_time_id
|
||
## }}}
|
||
;;
|
||
esac
|
||
|
||
# If no task with this ID exists in the last month, exit function {{{
|
||
if ! timew summary :month :ids | grep --quiet -- " @${timove_time_id} "; then
|
||
printf '%b' "No available task in the last month with ${REDB}${timove_time_id}${RESET} ID."
|
||
return 1
|
||
fi
|
||
# }}}
|
||
|
||
# Get task's description from all task of this month
|
||
timove_time_desc=$(timew summary :month :ids | sed --quiet "s/.*@\(${timove_time_id} .*\)/\1/p" | sed 's/ */ − /g')
|
||
|
||
# Get time tracking's start day from all time tracking
|
||
timove_time_start_day=$(timew export | sed --quiet --regexp-extended "s/^\{\"id\":${timove_time_id},\"start\":\"([0-9]{4})([0-9]{2})([0-9]{2})T.*end.*/\1-\2-\3/p")
|
||
|
||
# Check or ask for new start time {{{
|
||
if [ -z "${timove_time_new_start}" ]; then
|
||
printf '%b' "Enter the ${MAGENTAB}new start time${RESET} (or new date 'YYYY-MM-DD${REDB}T${RESET}HH:MM:SS'; default day is ${timove_time_start_day}) for this task : "
|
||
read -r timove_time_new_start
|
||
fi
|
||
# }}}
|
||
|
||
printf '%b' "Move \"${MAGENTAB}${timove_time_desc}${RESET}\" to ${REDB}=> ${timove_time_new_start} <=${RESET} [Y/n] ? "
|
||
read -r timove_confirmation
|
||
|
||
# Check confirmation
|
||
if printf -- '%s' "${timove_confirmation:=y}" | grep --quiet --word-regexp -- "y"; then
|
||
|
||
## If the new start time entered by user contains a "T" (user enter a dateTtime)
|
||
if printf -- '%s' "${timove_time_new_start}" | grep --quiet -- "T"; then
|
||
timew move @"${timove_time_id}" "${timove_time_new_start}" || return 0
|
||
printf '%b' "${timove_time_desc} was moved to ${timove_time_new_start}."
|
||
else
|
||
timew move @"${timove_time_id}" "${timove_time_start_day}T${timove_time_new_start}" || return 0
|
||
printf '%b' "start time of ${timove_time_desc} is now ${timove_time_start_day}T${timove_time_new_start}."
|
||
fi
|
||
fi
|
||
}
|
||
## }}}
|
||
|
||
# }}}
|
||
|
||
# DebOps {{{
|
||
## Source DebOps user environment file {{{
|
||
if [ -f "${HOME}/.config/debops/environment" ]; then
|
||
source "${HOME}/.config/debops/environment"
|
||
fi
|
||
## }}}
|
||
## Direct access to DebOps's directories
|
||
alias dero="cd ${DEBOPS_VENV_ROLES:-/dev/null}"
|
||
alias deplay="cd ${DEBOPS_VENV_PLAYBOOKS:-/dev/null}"
|
||
|
||
## Apply full config to a define host(s)/group(s) {{{
|
||
function debhost() {
|
||
if [ ${ANS_HOST} ]; then
|
||
debops run site --limit "${ANS_HOST}"
|
||
else
|
||
printf '%b' "${MAGENTA}ANS_HOST${RESET} vars is ${REDB}not${RESET} define !\n"
|
||
fi
|
||
}
|
||
## }}}
|
||
## Apply a role to a define host(s)/group(s) {{{
|
||
function debrole() {
|
||
if [ ${ANS_HOST} ]; then
|
||
debops run site --limit "${ANS_HOST}" --tags "role::${1:-/dev/null}"
|
||
else
|
||
printf '%b' "${MAGENTA}ANS_HOST${RESET} vars is ${REDB}not${RESET} define !\n"
|
||
fi
|
||
}
|
||
## }}}
|
||
## Apply the role from a service to a define host(s)/group(s) {{{
|
||
function debserv() {
|
||
if [ ${ANS_HOST} ]; then
|
||
debops run service/"${1:-/dev/null}" --limit "${ANS_HOST}" --tags "role::${1:-/dev/null}"
|
||
else
|
||
printf '%b' "${MAGENTA}ANS_HOST${RESET} vars is ${REDB}not${RESET} define !\n"
|
||
fi
|
||
}
|
||
## }}}
|
||
## Apply a role from a service to a define host(s)/group(s) {{{
|
||
function debservice() {
|
||
if [ ${ANS_HOST} ]; then
|
||
debops run service/"${1:-/dev/null}" --limit "${ANS_HOST}"
|
||
else
|
||
printf '%b' "${MAGENTA}ANS_HOST${RESET} vars is ${REDB}not${RESET} define !\n"
|
||
fi
|
||
}
|
||
## }}}
|
||
## Apply a playbook to a define host(s)/group(s) {{{
|
||
function debplay() {
|
||
if [ ${ANS_HOST} ]; then
|
||
if [ ! ${2} ]; then
|
||
debops run "${1:-/dev/null}" --limit "${ANS_HOST}"
|
||
else
|
||
debops run "${1:-/dev/null}" --limit "${ANS_HOST}" --tags "role::${2:-/dev/null}"
|
||
fi
|
||
else
|
||
printf '%b' "${MAGENTA}ANS_HOST${RESET} vars is ${REDB}not${RESET} define !\n"
|
||
fi
|
||
}
|
||
## }}}
|
||
|
||
## Check full config to a define host(s)/group(s) {{{
|
||
function debchost() {
|
||
if [ ${ANS_HOST} ]; then
|
||
debops check site --limit "${ANS_HOST}"
|
||
else
|
||
printf '%b' "${MAGENTA}ANS_HOST${RESET} vars is ${REDB}not${RESET} define !\n"
|
||
fi
|
||
}
|
||
## }}}
|
||
## Check a role to a define host(s)/group(s) {{{
|
||
function debcrole() {
|
||
if [ ${ANS_HOST} ]; then
|
||
debops check site --limit "${ANS_HOST}" --tags "role::${1:-/dev/null}"
|
||
else
|
||
printf '%b' "${MAGENTA}ANS_HOST${RESET} vars is ${REDB}not${RESET} define !\n"
|
||
fi
|
||
}
|
||
## }}}
|
||
## Check the role from a service to a define host(s)/group(s) {{{
|
||
function debcserv() {
|
||
if [ ${ANS_HOST} ]; then
|
||
debops check service/"${1:-/dev/null}" --limit "${ANS_HOST}" --tags "role::${1:-/dev/null}"
|
||
else
|
||
printf '%b' "${MAGENTA}ANS_HOST${RESET} vars is ${REDB}not${RESET} define !\n"
|
||
fi
|
||
}
|
||
## }}}
|
||
## Check a role from a service to a define host(s)/group(s) {{{
|
||
function debcservice() {
|
||
if [ ${ANS_HOST} ]; then
|
||
debops check service/"${1:-/dev/null}" --limit "${ANS_HOST}"
|
||
else
|
||
printf '%b' "${MAGENTA}ANS_HOST${RESET} vars is ${REDB}not${RESET} define !\n"
|
||
fi
|
||
}
|
||
## }}}
|
||
## Check a playbook to a define host(s)/group(s) {{{
|
||
function debcplay() {
|
||
if [ ${ANS_HOST} ]; then
|
||
if [ ! ${2} ]; then
|
||
debops run "${1:-/dev/null}" --limit "${ANS_HOST}"
|
||
else
|
||
debops run "${1:-/dev/null}" --limit "${ANS_HOST}" --tags "role::${2:-/dev/null}"
|
||
fi
|
||
else
|
||
printf '%b' "${MAGENTA}ANS_HOST${RESET} vars is ${REDB}not${RESET} define !\n"
|
||
fi
|
||
}
|
||
## }}}
|
||
# }}}
|
||
# Web apps {{{
|
||
# Get weather
|
||
function meteo {
|
||
if command -v curl > /dev/null; then
|
||
curl http://fr.wttr.in/${*}
|
||
elif command -v wget > /dev/null; then
|
||
wget --quiet --output-document=- http://wttr.in/${*}
|
||
else
|
||
printf '%b' "Please ${REDB}install one of this tools :${RESET} curl or wget.\n"
|
||
fi
|
||
}
|
||
# }}}
|
||
|
||
#######################################
|
||
#Ouverture d'un programme en fonction
|
||
#de l'extension du fichier
|
||
#######################################
|
||
alias -s txt='$PAGER '
|
||
alias -s odt='libreoffice --writer '
|
||
alias -s rtf='libreoffice --writer '
|
||
alias -s doc='libreoffice --writer '
|
||
alias -s docx='libreoffice --writer '
|
||
alias -s ods='libreoffice --calc '
|
||
alias -s xls='libreoffice --calc '
|
||
alias -s html=$BROWSER
|
||
alias -s org=$BROWSER
|
||
alias -s php=$BROWSER
|
||
alias -s com=$BROWSER
|
||
alias -s net=$BROWSER
|
||
alias -s png='mirage '
|
||
alias -s jpg='mirage '
|
||
alias -s gif='mirage '
|
||
alias -s mp4='smplayer '
|
||
alias -s avi='smplayer '
|
||
alias -s flv='smplayer '
|
||
alias -s log='tail --follow'
|
||
alias -s conf='vim '
|
||
alias -s gz='gunzip '
|
||
alias -s bz2='bzip2'
|
||
|
||
|
||
#######################################
|
||
# Raccourcis pour les dossier
|
||
# Pour y accéder, faire ~NOM_DU_RACCOURCIS
|
||
#######################################
|
||
hash -d apt="/etc/apt"
|
||
hash -d zsh="/etc/zsh"
|
||
hash -d dl="/media/udata/download/"
|
||
hash -d sid="/media/udata/config_debian"
|
||
hash -d smb="/etc/samba/"
|
||
|
||
|
||
# Inutile mais fun :p
|
||
##Affiche le calendrier et le jour courant en couleur
|
||
#alias ccal='var=$(cal -m); echo "${var/$(date +%-d)/$(echo -e "\033[1;31m$(date +%-d)\033[0m")}"'
|
||
alias ccal='var=$(cal); echo "${var/$(date +%-d)/$(echo -e "\033[1;31m$(date +%-d)\033[0m")}"'
|
||
|
||
##Commande utilisant cowsay (ou PONYSAY!!) pour afficher un message
|
||
function bonjour() {
|
||
local MIN_TIME=$(date +%M)
|
||
local MODULO_MIN=$(($MIN_TIME % 2))
|
||
if [ $(command -v bash_quote) ] && [ $(command -v cowsay) ]; then
|
||
if [ $MODULO_MIN -eq 0 ]; then
|
||
#echo Bonjour $USER, nous sommes le `date +"%A %e %B %Y"`, et il est : `date +"%H"` h `date +"%M"` | cowsay -f $(/bin/ls /usr/share/cowsay/cows -1 | head -n $(expr $$$(date +%s) % $(ls /usr/share/cowsay/cows | wc -w) + 1) | tail -n 1)
|
||
command bash_quote | cowsay -f $(/bin/ls /usr/share/cowsay/cows -1 | head -n $(expr $$$(date +%s) % $(ls /usr/share/cowsay/cows | wc --words) + 1) | tail --lines=1)
|
||
else
|
||
#echo Bonjour $USER, nous sommes le `date +"%A %e %B %Y"`, et il est : `date +"%H"` h `date +"%M"` | ponythink
|
||
command bash_quote | ponythink
|
||
fi
|
||
else
|
||
printf '%b' "${WHITEB}bonjour function${RESET}: One of the prerequesites is unavailable.\nFor bash_quote please see: https://git.101010.fr/dotfiles-gardouille/scripts/blob/master/bash_quote\n"
|
||
fi
|
||
}
|
||
|
||
##Affiche quelques statistiques à propos de l'ordinateur
|
||
alias stat_sys="echo ' ' && uname --all && echo ' '&& uptime &&echo ' '&& df && echo ' '"
|
||
|
||
#####################################
|
||
#####FONCTIONS
|
||
######################################
|
||
|
||
## Verrouiller le shell avec vlock
|
||
#function TRAPALRM() { vlock }
|
||
|
||
##Cree le repertoire et va dedans
|
||
function mkcd() {
|
||
mkdir -- $1 && cd $_
|
||
}
|
||
|
||
|
||
#liste les alias et functions
|
||
function listalias(){
|
||
cat /etc/zsh/zshrc | egrep "alias|function" | grep --invert-match "^#" -- | $PAGER
|
||
}
|
||
|
||
# Get real address behind a shorten URL {{{
|
||
# Require a function because the given argument need to be passed to curl
|
||
function unshorten()
|
||
{
|
||
curl --silent https://unshorten.me/s/"${1-}"
|
||
}
|
||
# }}}
|
||
|
||
# Get public IP address {{{
|
||
function ippub()
|
||
{
|
||
#curl ifconfig.me
|
||
#lynx --dump http://www.whatismyip.com/|grep Your|awk '{print $4}'
|
||
#wget http://checkip.dyndns.org/ -O - -o /dev/null | cut -d" " -f 6 | cut -d\< -f 1
|
||
dig +short myip.opendns.com @resolver1.opendns.com
|
||
}
|
||
# }}}
|
||
|
||
# Get all private IP addresses {{{
|
||
function ippriv()
|
||
{
|
||
for interface in $(find /sys/class/net/ ! -name lo -type l -printf "%f\n" | sort);
|
||
do
|
||
local IP_INTER=$(ip a s ${interface}|grep "inet "|awk '{print $2}')
|
||
printf '%b' "${WHITEB}${interface}${RESET}: ${IP_INTER}\n"
|
||
done
|
||
}
|
||
# }}}
|
||
|
||
# Get main private IP adress {{{
|
||
function ipmain()
|
||
{
|
||
hostname -i
|
||
}
|
||
# }}}
|
||
|
||
# Test if a network connection is available
|
||
function is_network()
|
||
{
|
||
for path_interface in $(find /sys/class/net/ ! -name lo -type l);
|
||
do
|
||
local IS_UP=$(grep 1 ${path_interface}/carrier)
|
||
if [ ${IS_UP} ]; then
|
||
return 0
|
||
fi
|
||
done
|
||
printf '%b' "${REDB}Not Online${RESET}\n"
|
||
return 1
|
||
}
|
||
|
||
#Renomme les fichiers en minuscule
|
||
function lowercase()
|
||
{
|
||
for file in *; do
|
||
local filename=${file##*/}
|
||
case "$filename" in
|
||
*/*) local dirname==${file%/*} ;;
|
||
*) local dirname=.;;
|
||
esac
|
||
local nf=$(printf $filename | tr A-Z a-z)
|
||
local newname="${dirname}/${nf}"
|
||
if [ "$nf" != "$filename" ]; then
|
||
mv "$file" "$newname"
|
||
printf 'lowercase: %s --> %s\n' ${file} ${newname}
|
||
else
|
||
printf 'lowercase %s not changed\n' ${file}
|
||
fi
|
||
done
|
||
}
|
||
|
||
##Capture d'écran
|
||
function printscreen()
|
||
{
|
||
scrot --select --exec 'gimp $f ; rm --recursive --force -- $f'
|
||
}
|
||
|
||
|
||
## Latex:
|
||
##Redéfinition de pdflatex:
|
||
# La commande pdflatex est exécutée deux fois pour permettre la construction de l'index
|
||
function pdflatex()
|
||
{
|
||
# On récupère le nom du fichier sans l'extension
|
||
local file_name="${1:r}"
|
||
# Le fichier avec l'extension pdf
|
||
local pdf="${file_name}.pdf"
|
||
# Dossier temporaire
|
||
local temp_dir="temp"
|
||
|
||
# On supprime le fichier pdf si il est présent
|
||
if [ -f "${pdf}" ]; then
|
||
rm --recursive --force -- "${pdf}"
|
||
fi
|
||
|
||
# Si le répertoire temporaire n'existe pas, on le crée
|
||
if [ ! -d "${temp_dir}" ]; then
|
||
mkdir "${temp_dir}"
|
||
fi
|
||
|
||
# On exécute la commande pour créer le pdf
|
||
/usr/bin/pdflatex -output-directory ${temp_dir} $1
|
||
/usr/bin/pdflatex -output-directory ${temp_dir} $1
|
||
|
||
# On place le fichier pdf qui est dans le répertoire temporaire dans le répertoire courant
|
||
mv --force -- "${temp_dir}"/*.pdf .
|
||
}
|
||
|
||
#Éteint un pc sous windows à distance
|
||
#Nécessite le paquet samba-common
|
||
# Arguments:
|
||
# ${1}: l'ip de la machine
|
||
# ${2}: le nom d'utilisateur
|
||
# ${3}: le mot de passe de l'utilisateur
|
||
function eteint()
|
||
{
|
||
net rpc shutdown -f -I $1 -U $2%$3 -t 10 -C "Arrêt en cours..."
|
||
}
|
||
|
||
# Calculatrice en ligne de commande
|
||
function calc()
|
||
{
|
||
echo "${1}" | bc -l
|
||
}
|
||
|
||
# Afficher le code retour de la commande précédente
|
||
function cmd_status {
|
||
local exit_code=$? # exit code of command
|
||
local count=$(jobs | wc --lines) # no. of background jobs
|
||
|
||
# Report no. of background jobs if >0
|
||
if [ $count -gt 0 ]; then
|
||
echo -n " %{$fg[cyan]%}⎇ %j "
|
||
fi
|
||
|
||
# Report exit code
|
||
if [ $exit_code -ne 0 ]; then
|
||
echo -n "%{$fg[yellow]%}%?%{$fg[red]%} ✖%{$reset_color%}"
|
||
else
|
||
echo -n "%{$fg[green]%}✔%{$reset_color%}"
|
||
fi
|
||
}
|
||
|
||
|
||
# Affiche un rappel des raccourcis pour se déplacer dans vim
|
||
function rappel_vim()
|
||
{
|
||
echo "\
|
||
##########################################
|
||
# Rappel basique pour VIM
|
||
##########################################
|
||
# Déplacements basiques :
|
||
H pour se déplacer vers la gauche
|
||
J pour se déplacer vers le bas
|
||
K pour se déplacer vers la droite
|
||
L pour se déplacer vers la droite
|
||
|
||
# Déplacements avancés sur une ligne :
|
||
e pour aller à la fin du mot suivant
|
||
w pour aller au début du mot suivant
|
||
b pour aller à la fin du mot précédent
|
||
0 pour aller en début de ligne
|
||
$ pour aller en fin de ligne
|
||
^ pour aller au premier caractère de la ligne qui n'est pas un espace ni une tabulation
|
||
f<c> pour aller jusqu'au caractère <c> vers l'avant
|
||
3f<c> pour aller jusqu'à la 3ème occurence du caractère <c> vers l'avant
|
||
F<c> pour aller jusqu'au caractère <c> vers l'arrière
|
||
nF<c> pour aller jusqu'à la nème occurence du caractère <c> vers l'arrière
|
||
t<c> pour aller jusqu'au caractère <c> vers l'avant en s'arrêtant avant
|
||
T<c> pour aller jusqu'au caractère <c> vers l'arrière en s'arrêtant avant
|
||
|
||
# Déplacement dans le document :
|
||
gg pour aller au début du document
|
||
G pour aller à la fin du document
|
||
nG pour aller à la ligne <n>
|
||
:<n> pour aller à la ligne <n>
|
||
% pour aller à la parenthèse (acollade, crochet) correspondant
|
||
|
||
# Copier/coller avancé
|
||
\"ayy Copier la ligne courante dans le buffer \"a\"
|
||
\"5byy Copier les 5 lignes sous le curseur dans le buffer \"b\"
|
||
<MODE_VISUEL>\"ey Copier les lignes sélectionnées dans le buffer \"e\"
|
||
|
||
# undo & redo
|
||
u pour annuler pour annuler la dernière modification
|
||
CTRL+R pour refaire la dernière modification
|
||
|
||
# Gestion du texte
|
||
~ pour inverser la casse du texte sélectionné
|
||
# Supprimer le texte du curseur à la fin de la ligne
|
||
<mode commande> d$
|
||
<mode insertion> CTRL-o D
|
||
# Supprimer le texte du curseur au début de la ligne
|
||
<mode commande> d^
|
||
" | $PAGER
|
||
}
|
||
|
||
# Affiche un rappel des raccourcis pour se déplacer dans vim
|
||
function rappel_vim_avance()
|
||
{
|
||
echo "\
|
||
##########################################
|
||
# Utilisation un peu plus avancée de VIM
|
||
##########################################
|
||
# nom fichier
|
||
# Avec par exemple un fichier qui s'appelle fichier.tex dans /home/limax/Documents/
|
||
|
||
# est le nom du fichier en cours
|
||
:!echo % (renvoie /Documents/fichier.tex )
|
||
:!echo %:r (renvoie /Documents/fichier )
|
||
:!echo %:e (renvoie tex )
|
||
:!echo %:t (renvoie fichier.tex )
|
||
:!echo %:p (renvoie /home/limax/Documents/fichier.tex )
|
||
:!echo %:t (renvoie fichier.tex )
|
||
:!echo %:h (renvoie Documents)
|
||
# Par exemple pour ouvrir le pdf avec lesspipe
|
||
:!lesspipe %:r.pdf
|
||
|
||
# Indentation
|
||
# Pour réindenter du texte:
|
||
mode visuel
|
||
- sélectionner toutes les lignes à indenter correctement
|
||
touche \"=\"
|
||
# Pour décaler plusieurs lignes de plusieurs tabulations:
|
||
mode visuel
|
||
- sélectionner toutes les lignes à décaler
|
||
:>>>
|
||
|
||
# Commande
|
||
# Pour exécuter une seule commande à partir du mode insertion
|
||
<mode insertion> CTRL-o suivi de la commande à exécuter
|
||
|
||
# Code touche
|
||
# Pour afficher le code clavier d'une touche spéciale en mode insertion:
|
||
<mode insertion> CTRL-V
|
||
# Pour afficher le code interne d'une touche spéciale:
|
||
<mode insertion> CTRL-K
|
||
# Pour obtenir le code ascii d'un caractère:
|
||
ga
|
||
|
||
# Plier/déplier
|
||
zm Plier tout le document sur un niveau de plus
|
||
zr Déplier tout le document sur un niveau de plus
|
||
zc Plier un bloc/fonction/class
|
||
zo Déplier un bloc/fonction/class
|
||
|
||
|
||
" | $PAGER
|
||
}
|
||
|
||
|
||
# Affiche un rappel pour l'édition de fichier Latex
|
||
function rappel_latex()
|
||
{
|
||
echo "\
|
||
-\\/- Permet d'afficher -- et non un tiret cadratin
|
||
Ligne vide Permet un retour à la ligne entre deux textes
|
||
\\ldots Affiche correctement \"...\"
|
||
|
||
|
||
# itemize
|
||
Mettre un \\vspace{0.5cm} après une liste?
|
||
Laisser une ligne vide après une commande root dans une liste?
|
||
|
||
# À faire
|
||
Ajouter un style pour les notes d'informations
|
||
Ajouter un style pour les notes importantes
|
||
|
||
|
||
" | $PAGER
|
||
}
|
||
|
||
## Vérifier les logins et logouts de tous les comptes incluant le mien.
|
||
watch=all
|
||
# Vérifie toutes les 30 secondes
|
||
logcheck=30
|
||
# Change le format de watch pour quelques chose avec plus d'informations
|
||
# %n = username, %M = hostname, %a = action, %l = tty, %T = time,
|
||
# %W = date
|
||
WATCHFMT="%n from %M has %a tty%l at %T %W"
|
||
|
||
|
||
# Crypte le fichier passer en paramètre en utilisant le certificat public
|
||
# de l'utilisateur.
|
||
# Arguments:
|
||
# ${1}: fichier à crypter
|
||
# ${2}:
|
||
function crypt()
|
||
{
|
||
openssl smime -encrypt -aes128 -in ${1} -out .${1}.ls ~/.openssl/mycert.crt
|
||
}
|
||
|
||
# Décrypte le fichier passer en paramètre en fonction de la clef ssl de
|
||
# l'utilisateur et trouve la ligne contenant le mot rechercher par l'user
|
||
# Arguments:
|
||
# ${1}: le fichier à décrypter
|
||
# ${2}: le paramètre rechercher dans le fichier
|
||
function getpdw()
|
||
{
|
||
openssl smime -decrypt -in ${1} -inkey ~/.openssl/mykey.key | grep ${2}
|
||
}
|
||
|
||
|
||
# Décrypte le fichier passer en paramètre en fonction de la clef ssl de
|
||
# l'utilisateur et le fichier de sorti est le second paramètre
|
||
# Arguments:
|
||
# ${1}: le fichier à décrypter
|
||
# ${2}: le fichier de sorti
|
||
function decrypt()
|
||
{
|
||
openssl smime -decrypt -in ${1} -out ${2} -inkey ~/.openssl/mykey.key
|
||
}
|
||
|
||
################################################
|
||
# 2. Prompt et définition des touches basiques #
|
||
################################################
|
||
|
||
# Prompt couleur (la couleur n'est pas la même pour le root et
|
||
# pour les simples utilisateurs)
|
||
# Définition des couleurs:
|
||
bleu_clair="[36;1m"
|
||
bleu_fonce="[34;1m"
|
||
rouge="[31m"
|
||
jaune="[33m"
|
||
blanc="[37m"
|
||
vert="[32m"
|
||
couleur_normale="[0m"
|
||
# Définition du texte du prompt
|
||
heure="%{$bleu_clair%}%T"
|
||
user="%{$bleu_fonce%}%n"
|
||
user_root="%{$rouge%}%n"
|
||
at="%{$jaune%}@"
|
||
host="%{$blanc%}%m"
|
||
repertoire_courant="%{$vert%}%c"
|
||
repertoire_absolu="%{$vert%}%d"
|
||
# Chemin du répertoire courant en relatif à ~
|
||
repertoire_relatif="%{$vert%}%~"
|
||
root="%{$jaune%}%#"
|
||
noroot="%{$jaune%}%%"
|
||
normal="%{$couleur_normale%}"
|
||
# Définition du prompt
|
||
if [ "`id -u`" -eq 0 ]; then ## Root
|
||
export PS1="$heure $user_root$at$host $repertoire_courant$root $normal"
|
||
# export PS1="%{$bleu_clair%T %{$rouge%n%{$jaune@%{$blanc%m %{$vert%c%{$jaune%#%{[0m%} "
|
||
else ## Simple utilisateur
|
||
export PS1="$heure $host $repertoire_courant$noroot $normal"
|
||
fi
|
||
|
||
# Prise en charge des touches [début], [fin] et autres
|
||
typeset -A key
|
||
|
||
key[Home]=${terminfo[khome]}
|
||
key[End]=${terminfo[kend]}
|
||
key[Insert]=${terminfo[kich1]}
|
||
key[Delete]=${terminfo[kdch1]}
|
||
key[Up]=${terminfo[kcuu1]}
|
||
key[Down]=${terminfo[kcud1]}
|
||
key[Left]=${terminfo[kcub1]}
|
||
key[Right]=${terminfo[kcuf1]}
|
||
key[PageUp]=${terminfo[kpp]}
|
||
key[PageDown]=${terminfo[knp]}
|
||
|
||
[[ -n "${key[Home]}" ]] && bindkey "${key[Home]}" beginning-of-line
|
||
[[ -n "${key[End]}" ]] && bindkey "${key[End]}" end-of-line
|
||
[[ -n "${key[Insert]}" ]] && bindkey "${key[Insert]}" overwrite-mode
|
||
[[ -n "${key[Delete]}" ]] && bindkey "${key[Delete]}" delete-char
|
||
[[ -n "${key[Up]}" ]] && bindkey "${key[Up]}" up-line-or-history
|
||
[[ -n "${key[Down]}" ]] && bindkey "${key[Down]}" down-line-or-history
|
||
[[ -n "${key[Left]}" ]] && bindkey "${key[Left]}" backward-char
|
||
[[ -n "${key[Right]}" ]] && bindkey "${key[Right]}" forward-char
|
||
[[ -n "${key[PageUp]}" ]] && bindkey "${key[PageUp]}" history-beginning-search-backward
|
||
[[ -n "${key[PageDown]}" ]] && bindkey "${key[PageDown]}" history-beginning-search-forward
|
||
|
||
# ctrl+← and ctrl+→ issue
|
||
bindkey "^[[1;5C" vi-forward-word-end
|
||
bindkey "^[[1;5D" backward-word
|
||
|
||
|
||
|
||
|
||
# Titre de la fenêtre d'un xterm
|
||
case $TERM in
|
||
xterm*)
|
||
precmd () {print -Pn "\e]0;%n@%m: %~\a"}
|
||
;;
|
||
esac
|
||
|
||
# Gestion de la couleur pour 'ls' (exportation de LS_COLORS)
|
||
# First, use vivid {{{
|
||
if [ $(command -v vivid) ]; then
|
||
export LS_COLORS="$(vivid generate dracula)"
|
||
# }}}
|
||
# Second, use dircolors {{{
|
||
elif [ -x /usr/bin/dircolors ]
|
||
then
|
||
if [ -r ~/.dir_colors ]
|
||
then
|
||
eval "`dircolors ~/.dir_colors`"
|
||
elif [ -r /etc/dir_colors ]
|
||
then
|
||
eval "`dircolors /etc/dir_colors`"
|
||
else
|
||
eval "`dircolors`"
|
||
fi
|
||
fi
|
||
# }}}
|
||
|
||
#######################################
|
||
# 3. Comportement ligne de commandes #
|
||
#######################################
|
||
# La ligne de commande dans zsh peut fonctionner suivant différents schémas (options).
|
||
# Les principaux que je vais utiliser sont fait pour la ligne de commande dans zhs se
|
||
# comporte à la vim. Il y a donc un mode commande/normal et un mode insertion.
|
||
|
||
# Afficher le mode courant dans le prompt de droite (normal|insertion)
|
||
function zle-line-init zle-keymap-select {
|
||
RPS1="$(cmd_status) ${${KEYMAP/vicmd/-CMD-}/(main|viins)/-INS-}"
|
||
RPS2=$RPS1
|
||
zle reset-prompt
|
||
}
|
||
|
||
# easy color names in this config
|
||
autoload -U colors && colors
|
||
|
||
# Chargement des keymaps
|
||
zle -N zle-line-init
|
||
zle -N zle-keymap-select
|
||
|
||
### Raccourcis communs à tous les modes
|
||
autoload -U edit-command-line
|
||
zle -N edit-command-line
|
||
bindkey '' edit-command-line # Ouvrir la commande actuelle dans l'éditeur
|
||
bindkey '' history-incremental-search-backward # Recherche incrémentale qui monte dans l'historique
|
||
#bindkey '' history-incremental-search-forward # Recherche incrémentale qui descend dans l'historique
|
||
|
||
### Raccourcis spécifiques au mode insertion
|
||
bindkey -M viins '' beginning-of-line # Début de ligne
|
||
bindkey -M viins '' vi-forward-blank-word-end # Fin du mot courant
|
||
#bindkey -M viins '' vi-forward-blank-word # Début du mot suivant
|
||
bindkey -M viins '' vi-backward-word # Début du mot précédent
|
||
bindkey -M viins '' vi-find-prev-char # Rechercher la précédente occurence d'une lettre
|
||
#bindkey -M viins ' ;' vi-repeat-find # Aller à la prochaine occurence de la lettre recherchée
|
||
|
||
### Raccourcis spécifiques au mode commande
|
||
# Le mode commande dispose déjà de la plupart d'un fonctionnement très semblable
|
||
# au mode normal de vim. Seul problème pour le moment, l'absence d'un mode visuel.
|
||
|
||
|
||
|
||
###########################################
|
||
# 4. Options de zsh (cf 'man zshoptions') #
|
||
###########################################
|
||
|
||
# Je ne veux JAMAIS de beeps
|
||
unsetopt beep
|
||
unsetopt hist_beep
|
||
unsetopt list_beep
|
||
|
||
# Redirection de la sortie:
|
||
# >| doit être utilisés pour pouvoir écraser un fichier déjà existant ;
|
||
# le fichier ne sera pas écrasé avec '>'
|
||
unsetopt clobber
|
||
|
||
# Ctrl+D est équivalent à 'logout'
|
||
unsetopt ignore_eof
|
||
|
||
# Affiche le code de sortie si différent de '0'
|
||
setopt print_exit_value
|
||
|
||
# Demande confirmation pour 'rm *'
|
||
unsetopt rm_star_silent
|
||
# Attend 10 secondes avant d'exécuter une commande rm qui contient un * (asterisk).
|
||
setopt rmstarwait
|
||
|
||
# Correction orthographique des commandes
|
||
# Désactivé car, contrairement à ce que dit le "man", il essaye de
|
||
# corriger les commandes avant de les hasher
|
||
setopt correct
|
||
# Si on utilise des jokers dans une liste d'arguments, retire les jokers
|
||
# qui ne correspondent à rien au lieu de donner une erreur
|
||
setopt nullglob
|
||
|
||
# Désactivé le raccourcis '='
|
||
# Par défaut, `ls -l =vim` indiquera l'emplacement de vim.
|
||
# =vim équivaut à `which vim`
|
||
#setopt noequals
|
||
|
||
## Activation des fonctions internes de ZSH:
|
||
# Liste des fonctions disponibles:
|
||
#zcalc : une calculatrice (plus besoin de bc ou autres expr)
|
||
#zargs : un super xargs
|
||
#zmv : une commande permettant de faire du renommage/déplaçage en masse de fichiers.
|
||
#zftp : un client ftp natif
|
||
autoload -U zfinit
|
||
zfinit
|
||
|
||
# Les jobs qui tournent en tâche de fond sont nicé à '0'
|
||
unsetopt bg_nice
|
||
# N'envoie pas de "HUP" aux jobs qui tourent quand le shell se ferme
|
||
unsetopt hup
|
||
|
||
# Lancer le manuel en se placant sur une commande et en faisant {ESC,ALT}+{H,h}
|
||
autoload -U run-help
|
||
|
||
## Gestion de la pile des dossiers:
|
||
# Taille maximale de la pile placé dans zshenv
|
||
# L'exécution de "cd" met le répertoire d'où l'on vient sur la pile
|
||
setopt auto_pushd
|
||
# Ignore les doublons dans la pile
|
||
setopt pushd_ignore_dups
|
||
# N'affiche pas la pile après un "pushd" ou "popd"
|
||
setopt pushd_silent
|
||
# Inverse l'action de cd +1 et cd +1
|
||
setopt pushdminus
|
||
# "pushd" sans argument = "pushd $HOME"
|
||
setopt pushd_to_home
|
||
## Pour bien utiliser la pile:
|
||
# `dirs` va afficher la pile
|
||
# `cd -NUMÉRO` ira dans le dossier correspondant au numéro du dossier dans la pile
|
||
|
||
## Dirstack
|
||
DIRSTACKSIZE=20
|
||
setopt autopushd pushdsilent pushdtohome
|
||
## Remove duplicate entries
|
||
setopt pushdignoredups
|
||
## This reverts the +/- operators.
|
||
setopt pushdminus
|
||
|
||
#DIRSTACKFILE="$HOME/.zsh/cache/dirs"
|
||
#if [[ -f $DIRSTACKFILE ]] && [[ $#dirstack -eq 0 ]]; then
|
||
#dirstack=( ${(f)"$(< $DIRSTACKFILE)"} )
|
||
#[[ -d $dirstack[1] ]] && cd $dirstack[1]
|
||
#fi
|
||
|
||
#chpwd() {
|
||
#print -l $PWD ${(u)dirstack} >> $DIRSTACKFILE
|
||
#}
|
||
|
||
|
||
|
||
###################################
|
||
###### Options de complétion ######
|
||
###################################
|
||
|
||
# Schémas de complétion
|
||
|
||
# - Schéma A :
|
||
# 1ère tabulation : complète jusqu'au bout de la partie commune
|
||
# 2ème tabulation : propose une liste de choix
|
||
# 3ème tabulation : complète avec le 1er item de la liste
|
||
# 4ème tabulation : complète avec le 2ème item de la liste, etc...
|
||
# -> c'est le schéma de complétion par défaut de zsh.
|
||
|
||
# Schéma B :
|
||
# 1ère tabulation : propose une liste de choix et complète avec le 1er item
|
||
# de la liste
|
||
# 2ème tabulation : complète avec le 2ème item de la liste, etc...
|
||
# Si vous voulez ce schéma, décommentez la ligne suivante :
|
||
#setopt menu_complete
|
||
|
||
# Schéma C :
|
||
# 1ère tabulation : complète jusqu'au bout de la partie commune et
|
||
# propose une liste de choix
|
||
# 2ème tabulation : complète avec le 1er item de la liste
|
||
# 3ème tabulation : complète avec le 2ème item de la liste, etc...
|
||
# Ce schéma est le meilleur à mon goût !
|
||
# Si vous voulez ce schéma, décommentez la ligne suivante :
|
||
unsetopt list_ambiguous
|
||
|
||
# Quand le dernier caractère d'une complétion est '/' et que l'on
|
||
# tape 'espace' après, le '/' est effacé
|
||
setopt auto_remove_slash
|
||
# Ne fait pas de complétion sur les fichiers et répertoires cachés
|
||
unsetopt glob_dots
|
||
|
||
# Traite les liens symboliques comme il faut
|
||
setopt chase_links
|
||
|
||
# Quand l'utilisateur commence sa commande par '!' pour faire de la
|
||
# complétion historique, il n'exécute pas la commande immédiatement
|
||
# mais il écrit la commande dans le prompt
|
||
setopt hist_verify
|
||
# Si la commande est invalide mais correspond au nom d'un sous-répertoire
|
||
# exécuter 'cd sous-répertoire'
|
||
setopt auto_cd
|
||
|
||
|
||
###############################################
|
||
# 5. Paramètres de l'historique des commandes #
|
||
###############################################
|
||
|
||
# Définition des variables
|
||
SAVEHIST=5000
|
||
HISTSIZE=5000
|
||
HISTFILE=$HOME/.zsh/history
|
||
#export TIMEFMT="%E"
|
||
|
||
export SAVEHIST HISTSIZE HISTFILE
|
||
|
||
# Toutes les sessions zsh partage le même historique
|
||
#setopt SHARE_HISTORY
|
||
|
||
# Ajoute l'historique à la fin de l'ancien fichier
|
||
#setopt append_history
|
||
|
||
# Chaque ligne est ajoutée dans l'historique à mesure qu'elle est tapée
|
||
setopt inc_append_history
|
||
|
||
# Ne stocke pas une ligne dans l'historique si elle est identique à la
|
||
# précédente
|
||
setopt hist_ignore_dups
|
||
|
||
# Supprime les répétitions dans le fichier d'historique, ne conservant
|
||
# que la dernière occurrence ajoutée
|
||
#setopt hist_ignore_all_dups
|
||
|
||
# Supprime les répétitions dans l'historique lorsqu'il est plein, mais
|
||
# pas avant
|
||
setopt hist_expire_dups_first
|
||
|
||
# N'enregistre pas plus d'une fois une même ligne, quelles que soient
|
||
# les options fixées pour la session courante
|
||
#setopt hist_save_no_dups
|
||
|
||
# La recherche dans l'historique avec l'éditeur de commandes de zsh ne
|
||
# montre pas une même ligne plus d'une fois, même si elle a été
|
||
# enregistrée plusieurs fois
|
||
setopt hist_find_no_dups
|
||
|
||
# Affichage de la date du début de la commande et sa durée (depuis epoch)
|
||
# Culture time: epoch: 1er janvier 1970
|
||
setopt extended_history
|
||
|
||
# Ne pas enregistrer les commandes précédées d'un espace:
|
||
setopt hist_ignore_space
|
||
|
||
###########################################
|
||
# 6. Complétion des options des commandes #
|
||
###########################################
|
||
|
||
zstyle ':completion:*' matcher-list '' 'm:{a-z}={A-Z}'
|
||
zstyle ':completion:*' max-errors 3 numeric
|
||
zstyle ':completion:*' use-compctl false
|
||
|
||
## Pour la liste des processus que l'on peut kill, avec un menu et couleur
|
||
zstyle ':completion:*:*:*:*:processes' menu yes select
|
||
#zstyle ':completion:*:*:*:*:processes' force-list always
|
||
zstyle ':completion:*:processes' command 'ps -fau$USER'
|
||
zstyle ':completion:*:*:kill:*:processes' list-colors "=(#b) #([0-9]#)*=36=31"
|
||
|
||
## Pour éviter de reproposer un argument déjà utiliser dans la commande lors de la complétion
|
||
zstyle ':completion:*:(rm|mv|cp|ls|scp):*' ignore-line yes
|
||
|
||
## cd ne sélectionnera pas le dossier courant lorsqu'il devra remonter d'un dossier
|
||
# cd ../<TAB> ne proposera pas le dossier courant par exemple.
|
||
zstyle ':completion:*:cd:*' ignore-parents parent pwd
|
||
|
||
## Pour la liste des fichiers qu'on peut ouvrir avec vim
|
||
zstyle ':completion:*:*:vim:*' menu yes select
|
||
## Mettre en cache les résultats de l'auto-complétion car certaines fonctions sont lentes (apt, dpkg, ...)
|
||
# Ne pas hésiter à faire un petit aptitude install <TAB> et de lister tous les résultats possibles une première fois, histoire d'avoir tous les paquets en cache (~600ko), ça vaut le coup!
|
||
zstyle ':completion:*' use-cache on
|
||
zstyle ':completion:*' cache-path ~/.zsh/cache
|
||
|
||
## Ajout des couleurs pour la complétion
|
||
zmodload -i zsh/complist
|
||
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
|
||
|
||
## Complétion de la commande cd avec les répertoires locaux puis ceux de la variable CDPATH
|
||
zstyle ':completion:*:*:cd:*' tag-order local-directories path-directories
|
||
|
||
## Complétion des commandes ssh avec le contenu du fichier ~/.ssh/config et le contenu de host
|
||
#local HOSTS
|
||
#[[ -f ~/.ssh/config ]] && HOSTS=(`sed --quiet \'s/^Host \(.*\)/\1/p\' ~/.ssh/config`)
|
||
#if [ -f ~/.ssh/config ]; then
|
||
#HOSTS=(`grep ^Host ~/.ssh/config | sed s/Host\ // | egrep -v ‘^\*$’`)
|
||
#fi
|
||
#zstyle ':completion:*:(ssh|scp|sftp|sshfs):*' hosts ${HOSTS}
|
||
zstyle ':completion:*:hosts' hosts off
|
||
|
||
# Complétions pour certains programmes en fonction des extensions
|
||
zstyle ':completion:*:*:vlc:*' file-patterns '*.(mkv|MKV|avi|AVI|flv|FLV|mp4|MP4|webm|WEBM|mov|MOV|flac|FLAC|mp3|MP3|ogg|OGG|ogv|OGV|wmv|WMV)\ *(-/):directories'
|
||
|
||
## Ajout de la complétion pour plusieurs fonctions:
|
||
autoload -U compinit
|
||
autoload -U zutil
|
||
autoload -U complist
|
||
# Activation
|
||
compinit
|
||
|
||
|
||
###########################################
|
||
# 7. Création des fichiers et répertoires #
|
||
###########################################
|
||
# Dossier .zsh dans le répertoire personnel
|
||
if [ ! -d ~/.zsh ]; then
|
||
mkdir ~/.zsh
|
||
fi
|
||
|
||
# Fichier contenant l'historique pour chaque utilisateur
|
||
if [ ! -f ~/.zsh/history ]; then
|
||
touch ~/.zsh/history
|
||
fi
|
||
|
||
# Dossier contenant le cache pour chaque utilisateur
|
||
if [ ! -d ~/.zsh/cache ]; then
|
||
mkdir ~/.zsh/cache
|
||
fi
|
||
|
||
|
||
###########################################
|
||
############## 8. Globbing ################
|
||
###########################################
|
||
|
||
# Activation du globbing étendu
|
||
setopt extendedglob
|
||
## '^' inverse la pattern qui suit.
|
||
# Exemple:
|
||
# `ls ^*.log` listera tous les fichiers exceptés *.log
|
||
|
||
|
||
###########################################
|
||
############### 9. Modules ################
|
||
###########################################
|
||
|
||
## IF fzf AVAILABLE
|
||
if [ -d ~/.fzf ]; then
|
||
|
||
## If local fzf bin is available use it in priority
|
||
if [[ ! "$PATH" == *"${HOME}"/.fzf/bin* ]]; then
|
||
export PATH="${HOME}/.fzf/bin:${PATH}"
|
||
fi
|
||
|
||
if [ -f ~/bin/fd ]; then
|
||
export FZF_DEFAULT_COMMAND='fd --type f'
|
||
fi
|
||
|
||
autoload is-at-least
|
||
if is-at-least 0.29.0 $(fzf --version); then
|
||
export FZF_DEFAULT_OPTS="--cycle --multi --select-1 --bind 'change:first,shift-tab:down,tab:up'"
|
||
else
|
||
## change:first is unknown in FZF before 0.29.0
|
||
export FZF_DEFAULT_OPTS="--cycle --multi --select-1 --bind 'tab:down,shift-tab:up'"
|
||
fi
|
||
|
||
# Auto-completion
|
||
# ---------------
|
||
[[ $- == *i* ]] && source "${HOME}/.fzf/shell/completion.zsh" 2> /dev/null
|
||
|
||
# Key bindings
|
||
# ------------
|
||
source "${HOME}/.fzf/shell/key-bindings.zsh"
|
||
|
||
# ff - cd to selected directory exclude hidden directories and their content {{{
|
||
# Search with find (fd|fdfind overkill the CPU for few benefits on small tree)
|
||
# Check for symlinked directories too
|
||
# Allow to give arguments to prefill fzf request
|
||
# Display a preview tree of the directory
|
||
# Move to the selected directory
|
||
ff() {
|
||
local dir
|
||
|
||
## Manage argument {{{
|
||
if [ "${#}" -eq "0" ]; then
|
||
## Default command without args
|
||
dir=$(find . -xtype d -not -path "*/.*" | fzf --prompt='cd> ' --height=50% --preview 'exa --tree --level 2 {} | head --lines=20' --no-multi) &&
|
||
else
|
||
## If at least one argument was given, add it to fzf query
|
||
dir=$(find . -xtype d -not -path "*/.*" | fzf --prompt='cd> ' --height=50% --preview 'exa --tree --level 2 {} | head --lines=20' --no-multi --query "${*} ") &&
|
||
fi
|
||
## }}}
|
||
|
||
cd -- "${dir}"
|
||
}
|
||
# }}}
|
||
# ffh - cd to selected directory (hidden only) {{{
|
||
# Search with find (fd|fdfind overkill the CPU for few benefits on small tree)
|
||
# Check for symlinked directories too
|
||
# Allow to give arguments to prefill fzf request
|
||
# Display a preview tree of the directory
|
||
# Move to the selected directory
|
||
ffh() {
|
||
local dir
|
||
|
||
## Manage argument {{{
|
||
if [ "${#}" -eq "0" ]; then
|
||
## Default command without args
|
||
dir=$(find . -xtype d -path "*/.*" | fzf --prompt='cd> ' --height=50% --preview 'exa --tree --level 2 {} | head --lines=20' --no-multi) &&
|
||
else
|
||
## If at least one argument was given, add it to fzf query
|
||
dir=$(find . -xtype d -path "*/.*" | fzf --prompt='cd> ' --height=50% --preview 'exa --tree --level 2 {} | head --lines=20' --no-multi --query "${*} ") &&
|
||
fi
|
||
## }}}
|
||
|
||
cd -- "${dir}"
|
||
}
|
||
# }}}
|
||
# ffa - cd to any directory from / {{{
|
||
# Search with fd (fdfind is perfect to search on /)
|
||
# Check for symlinked directories too
|
||
# Allow to give arguments to prefill fzf request
|
||
# Display a preview tree of the directory
|
||
# Move to the selected directory
|
||
ffa() {
|
||
local dir
|
||
|
||
## Manage argument {{{
|
||
if [ "${#}" -eq "0" ]; then
|
||
## Default command without args
|
||
dir=$(fd -uu --search-path / --type d --type symlink | fzf --prompt='cd> ' --height=50% --preview 'exa --tree --level 1 {} | head --lines=20' --no-multi) &&
|
||
else
|
||
## If at least one argument was given, add it to fzf query
|
||
dir=$(fd -uu --search-path / --type d --type symlink | fzf --prompt='cd> ' --height=50% --preview 'exa --tree --level 1 {} | head --lines=20' --no-multi --query "${*} ") &&
|
||
fi
|
||
## }}}
|
||
|
||
cd -- "${dir}"
|
||
}
|
||
# }}}
|
||
# ffu - cd to selected parent directory {{{
|
||
ffu() {
|
||
local declare dirs=()
|
||
local dir
|
||
|
||
## Function to list parents of the given directory {{{
|
||
get_parent_dirs() {
|
||
if [[ -d "${1}" ]]; then dirs+=("$1"); else return; fi
|
||
if [[ "${1}" == '/' ]]; then
|
||
for _dir in "${dirs[@]}"; do echo $_dir; done
|
||
else
|
||
get_parent_dirs $(dirname "${1}")
|
||
fi
|
||
}
|
||
## }}}
|
||
## Manage argument {{{
|
||
if [ "${#}" -eq "0" ]; then
|
||
## Default command without args
|
||
dir=$(get_parent_dirs $(realpath "${PWD}") | fzf --prompt='cd> ' --tac --height=50% --no-multi) &&
|
||
else
|
||
## If at least one argument was given, add it to fzf query
|
||
dir=$(get_parent_dirs $(realpath "${PWD}") | fzf --prompt='cd> ' --tac --height=50% --no-multi --query "${*} ") &&
|
||
fi
|
||
## }}}
|
||
|
||
cd -- "${dir}"
|
||
}
|
||
# }}}
|
||
# fff - cd to the directory of the selected file {{{
|
||
# Search with fd (after few tests, fdfind is fareway better than find… even on small tree)
|
||
# Check for symlinked files too
|
||
# Allow to give arguments to prefill fzf request
|
||
# Display a directory preview tree of the selected file with exa
|
||
# Move to the directory of the selected file
|
||
fff() {
|
||
local file
|
||
local dir
|
||
|
||
## Manage argument {{{
|
||
if [ "${#}" -eq "0" ]; then
|
||
## Default command without args
|
||
file=$(fd -uu --type file --type symlink | fzf --prompt='cd> ' --height=50% --preview 'exa --tree --level 2 $(dirname {}) | head --lines=20' --no-multi) &&
|
||
else
|
||
## If at least one argument was given, add it to fzf query
|
||
file=$(fd -uu --type file --type symlink | fzf --prompt='cd> ' --height=50% --preview 'exa --tree --level 2 $(dirname {}) | head --lines=20' --no-multi --query "${*} ") &&
|
||
fi
|
||
## }}}
|
||
|
||
dir=$(dirname "${file}")
|
||
cd -- "${dir}"
|
||
}
|
||
# }}}
|
||
# cf - fuzzy cd from anywhere {{{
|
||
# Search with fd (fdfind is perfect to search on /)
|
||
# Allow to give arguments to prefill fzf request
|
||
# Display a directory preview tree of the selected file with exa
|
||
# Move to the directory of the selected file
|
||
cf() {
|
||
local file
|
||
|
||
## Manage argument {{{
|
||
if [ "${#}" -eq "0" ]; then
|
||
## Default command without args
|
||
file=$(fd -uu --search-path / | fzf --prompt='cd> ' --height=50% --preview 'exa --tree --level 1 $(dirname {}) | head --lines=20' --no-multi) &&
|
||
else
|
||
## If at least one argument was given, add it to fzf query
|
||
file=$(fd -uu --search-path / | fzf --prompt='cd> ' --height=50% --preview 'exa --tree --level 1 $(dirname {}) | head --lines=20' --no-multi --query "${*} ") &&
|
||
fi
|
||
## }}}
|
||
|
||
if [[ -n "${file}" ]]
|
||
then
|
||
if [[ -d "${file}" ]]
|
||
then
|
||
### If it's a directory, cd
|
||
cd -- "${file}"
|
||
else
|
||
### If it's a file, cd to the directory
|
||
cd -- "${file:h}"
|
||
fi
|
||
fi
|
||
}
|
||
# }}}
|
||
|
||
# v - fuzzy open file with vi from current directory {{{
|
||
# Search with fd (fdfind is perfect to search more than ~200k files)
|
||
# Check for symlinked files too
|
||
# Allow to give arguments to prefill fzf request
|
||
# Display the 50 first lines of the selected file with bat (batcat)
|
||
# Move to the directory of the selected file
|
||
# Open the selected file with vi
|
||
v() {
|
||
local files
|
||
local dir
|
||
local file
|
||
|
||
## Manage argument {{{
|
||
if [ "${#}" -eq "0" ]; then
|
||
## Default command without args
|
||
files=$(fd -uu --type file --type symlink | fzf --prompt='vi> ' --preview 'bat --color=always --line-range 0:50 {}' --no-multi) &&
|
||
else
|
||
## If at least one argument was given, add it to fzf query
|
||
files=$(fd -uu --type file --type symlink | fzf --prompt='vi> ' --preview 'bat --color=always --line-range 0:50 {}' --no-multi --query "${*} ") &&
|
||
fi
|
||
## }}}
|
||
|
||
## Move to the directory and open the file {{{
|
||
if [[ -n "${files}" ]]
|
||
then
|
||
dir=$(dirname "${files}")
|
||
cd -- "${dir}"
|
||
file=$(basename "${files}")
|
||
vi -- "${file}"
|
||
fi
|
||
## }}}
|
||
}
|
||
# }}}
|
||
|
||
# pdf − fuzzy open PDF file with "${PDF_VIEWER}" from current directory {{{
|
||
# Search with fd (fdfind is better than find with a pattern)
|
||
# Allow to give arguments to prefill fzf request
|
||
# Display a preview of selected file with lesspipe
|
||
# Move to the directory of the selected file
|
||
# Open the selected file with "${PDF_VIEWER}"
|
||
pdf() {
|
||
local files
|
||
local dir
|
||
local file
|
||
|
||
## Manage argument {{{
|
||
if [ "${#}" -eq "0" ]; then
|
||
## Default command without args
|
||
files=$(fd --unrestricted --type file --type symlink "\.pdf$" | fzf --prompt='pdf> ' --preview 'lesspipe {} | less' --no-multi) &&
|
||
else
|
||
## If at least one argument was given, add it to fzf query
|
||
files=$(fd --unrestricted --type file --type symlink "\.pdf$" | fzf --prompt='pdf> ' --preview 'lesspipe {} | less' --no-multi --query "${*} ") &&
|
||
fi
|
||
## }}}
|
||
|
||
## Move to the directory and open the file {{{
|
||
if [[ -n $files ]]
|
||
then
|
||
dir=$(dirname "${files}")
|
||
cd -- "${dir}"
|
||
file=$(basename "${files}")
|
||
"${PDF_VIEWER}" -- "${file}"
|
||
fi
|
||
## }}}
|
||
}
|
||
# }}}
|
||
# pdfe − fuzzy open PDF file with evince from current directory {{{
|
||
# Search with fd (fdfind is better than find with a pattern)
|
||
# Allow to give arguments to prefill fzf request
|
||
# Display a preview of selected file with lesspipe
|
||
# Move to the directory of the selected file
|
||
# Open the selected file with evince (default rollback to "${PDF_VIEWER}")
|
||
pdfe() {
|
||
local files
|
||
local dir
|
||
local file
|
||
local evince_bin
|
||
|
||
## If evince is available {{{
|
||
if [ $(command -v evince) ]; then
|
||
evince_bin=$(command -v evince)
|
||
else
|
||
evince_bin="${PDF_VIEWER}"
|
||
fi
|
||
## }}}
|
||
## Manage argument {{{
|
||
if [ "${#}" -eq "0" ]; then
|
||
## Default command without args
|
||
files=$(fd --unrestricted --type file --type symlink "\.pdf$" | fzf --prompt='pdf> ' --preview 'lesspipe {} | less' --no-multi) &&
|
||
else
|
||
## If at least one argument was given, add it to fzf query
|
||
files=$(fd --unrestricted --type file --type symlink "\.pdf$" | fzf --prompt='pdf> ' --preview 'lesspipe {} | less' --no-multi --query "${*} ") &&
|
||
fi
|
||
## }}}
|
||
|
||
## Move to the directory and open the file {{{
|
||
if [[ -n $files ]]
|
||
then
|
||
dir=$(dirname "${files}")
|
||
cd "${dir}"
|
||
file=$(basename "${files}")
|
||
"${evince_bin}" -- "${file}"
|
||
fi
|
||
## }}}
|
||
}
|
||
# }}}
|
||
# pdfz - fuzzy open with zathura from current directory {{{
|
||
# Search with fd (fdfind is better than find with a pattern)
|
||
# Allow to give arguments to prefill fzf request
|
||
# Display a preview of selected file with lesspipe
|
||
# Move to the directory of the selected file
|
||
# Open the selected file with zathura (default rollback to "${PDF_VIEWER}")
|
||
pdfz() {
|
||
local files
|
||
local dir
|
||
local file
|
||
local zathura_bin
|
||
|
||
## If zathura is available {{{
|
||
if [ $(command -v zathura) ]; then
|
||
zathura_bin=$(command -v zathura)
|
||
else
|
||
zathura_bin="${PDF_VIEWER}"
|
||
fi
|
||
## }}}
|
||
## Manage argument {{{
|
||
if [ "${#}" -eq "0" ]; then
|
||
## Default command without args
|
||
files=$(fd --unrestricted --type file --type symlink "\.pdf$" | fzf --prompt='pdf> ' --preview 'lesspipe {} | less' --no-multi) &&
|
||
else
|
||
## If at least one argument was given, add it to fzf query
|
||
files=$(fd --unrestricted --type file --type symlink "\.pdf$" | fzf --prompt='pdf> ' --preview 'lesspipe {} | less' --no-multi --query "${*} ") &&
|
||
fi
|
||
## }}}
|
||
|
||
## Move to the directory and open the file {{{
|
||
if [[ -n $files ]]
|
||
then
|
||
dir=$(dirname "${files}")
|
||
cd "${dir}"
|
||
file=$(basename "${files}")
|
||
"${zathura_bin}" -- "${file}"
|
||
fi
|
||
## }}}
|
||
}
|
||
# }}}
|
||
|
||
# odt − fuzzy open text document file with LibreOffice from current directory {{{
|
||
# Search with fd (fdfind is better than find with a pattern)
|
||
# Search for odt|rtf|doc|docx files
|
||
# Allow to give arguments to prefill fzf request
|
||
# Move to the directory of the selected file
|
||
# Open the selected file with libreoffice --writer
|
||
odt() {
|
||
local files
|
||
|
||
## Manage argument {{{
|
||
if [ "${#}" -eq "0" ]; then
|
||
## Default command without args
|
||
files=$(fd --unrestricted --type file --type symlink "\.(odt|rtf|doc|docx)" | fzf --prompt='odt> ' --no-multi) &&
|
||
else
|
||
## If at least one argument was given, add it to fzf query
|
||
files=$(fd --unrestricted --type file --type symlink "\.(odt|rtf|doc|docx)" | fzf --prompt='odt> ' --no-multi --query "${*} ") &&
|
||
fi
|
||
## }}}
|
||
|
||
## Move to the directory and open the file {{{
|
||
if [[ -n $files ]]
|
||
then
|
||
dir=$(dirname "${files}")
|
||
cd -- "${dir}"
|
||
file=$(basename "${files}")
|
||
command libreoffice --writer "${file}" &
|
||
fi
|
||
## }}}
|
||
}
|
||
# }}}
|
||
# ods − fuzzy open calc document file with LibreOffice from current directory {{{
|
||
# Search with fd (fdfind is better than find with a pattern)
|
||
# Search for ods|xls|xlsx files
|
||
# Allow to give arguments to prefill fzf request
|
||
# Move to the directory of the selected file
|
||
# Open the selected file with libreoffice --calc
|
||
ods() {
|
||
local files
|
||
|
||
## Manage argument {{{
|
||
if [ "${#}" -eq "0" ]; then
|
||
## Default command without args
|
||
files=$(fd --unrestricted --type file --type symlink "\.(ods|xls|xlsx)" | fzf --prompt='ods> ' --no-multi) &&
|
||
else
|
||
## If at least one argument was given, add it to fzf query
|
||
files=$(fd --unrestricted --type file --type symlink "\.(ods|xls|xlsx)" | fzf --prompt='ods> ' --no-multi --query "${*} ") &&
|
||
fi
|
||
## }}}
|
||
|
||
## Move to the directory and open the file {{{
|
||
if [[ -n $files ]]
|
||
then
|
||
dir=$(dirname "${files}")
|
||
cd -- "${dir}"
|
||
file=$(basename "${files}")
|
||
command libreoffice --calc "${file}" &
|
||
fi
|
||
## }}}
|
||
}
|
||
# }}}
|
||
# odp − fuzzy open presentation document file with LibreOffice from current directory {{{
|
||
# Search with fd (fdfind is better than find with a pattern)
|
||
# Search for odp|ppt|pptx files
|
||
# Allow to give arguments to prefill fzf request
|
||
# Move to the directory of the selected file
|
||
# Open the selected file with libreoffice --impress
|
||
odp() {
|
||
local files
|
||
|
||
## Manage argument {{{
|
||
if [ "${#}" -eq "0" ]; then
|
||
## Default command without args
|
||
files=$(fd --unrestricted --type file --type symlink "\.(odp|ppt|pptx)" | fzf --prompt='odp> ' --no-multi) &&
|
||
else
|
||
## If at least one argument was given, add it to fzf query
|
||
files=$(fd --unrestricted --type file --type symlink "\.(odp|ppt|pptx)" | fzf --prompt='odp> ' --no-multi "${*} ") &&
|
||
fi
|
||
## }}}
|
||
|
||
## Move to the directory and open the file {{{
|
||
if [[ -n $files ]]
|
||
then
|
||
dir=$(dirname "${files}")
|
||
cd -- "${dir}"
|
||
file=$(basename "${files}")
|
||
command libreoffice --impress "${file}" &
|
||
fi
|
||
## }}}
|
||
}
|
||
# }}}
|
||
|
||
# fopen − fuzzy open file with xdg-open from current directory {{{
|
||
# Search with fd (fdfind is better than find with a pattern)
|
||
# Use first argument as fd pattern
|
||
# Other arguments will prefill fzf request
|
||
# Move to the directory of the selected file
|
||
# Open the selected file with xdg-open
|
||
fopen() {
|
||
local files
|
||
|
||
## Manage argument {{{
|
||
if [ "${#}" -le "1" ]; then
|
||
## Default command with one argument or default value
|
||
files=$(fd --unrestricted --type file --type symlink "${1:-.}" | fzf --prompt='open> ' --no-multi) &&
|
||
else
|
||
## If at least one argument was given, add it to fzf query
|
||
files=$(fd --unrestricted --type file --type symlink "${1:-.}" | fzf --prompt='open> ' --no-multi --query "${*} ") &&
|
||
fi
|
||
## }}}
|
||
|
||
## Move to the directory and open the file {{{
|
||
if [[ -n $files ]]
|
||
then
|
||
dir=$(dirname "${files}")
|
||
cd -- "${dir}"
|
||
file=$(basename "${files}")
|
||
command xdg-open "${file}" &
|
||
fi
|
||
## }}}
|
||
}
|
||
# }}}
|
||
|
||
# dexec − Docker exec in a running container {{{
|
||
# Display Docker running containers
|
||
# Allow to specify the shell (default to bash)
|
||
dexec() {
|
||
local images_name
|
||
local container_name
|
||
local container_id
|
||
|
||
images_name=$(docker container ls --format "table {{.Image}}\t {{.RunningFor}}\t {{.Ports}}\t {{.Names}}" | fzf --prompt='docker> ' --tac )
|
||
|
||
## Extract container_name from the selected line
|
||
container_name=$(printf '%b' "${images_name}" | awk '{ print $NF }')
|
||
## Get container_id from the selected container_name
|
||
container_id=$(docker container ls --quiet --filter=name="${container_name}")
|
||
|
||
printf "%b\n" "Try to enter to Docker container (named : ${container_name})"
|
||
docker exec --interactive --tty -- "${container_id:-/dev/null}" "${1:-bash}"
|
||
}
|
||
# }}}
|
||
|
||
# passf − Edit pass's passwords {{{
|
||
# Display existing files in ~/.password-store without .gpg extension
|
||
# https://www.passwordstore.org/
|
||
passf() {
|
||
local pass_files
|
||
|
||
pass_file=$(find ~/.password-store -type f -iname "*.gpg" -printf "%P\n" | sed 's/\(.*\)\.gpg$/\1/' | fzf --prompt='pass > ' )
|
||
|
||
pass edit "${pass_file:-/dev/null}"
|
||
}
|
||
# }}}
|
||
|
||
fi
|
||
## ENDIF fzf AVAILABLE
|
||
|
||
# }}}
|
||
# zsh-syntax-highlighting {{{
|
||
## Activate if plugin is available
|
||
[ -f ~/repos/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh ] && source ~/repos/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
|
||
|
||
## Additionnal highlighters
|
||
### The order is important. Put **regexp** before **main** to prioritize
|
||
### the double quotation marks
|
||
ZSH_HIGHLIGHT_HIGHLIGHTERS=(regexp main brackets pattern)
|
||
### Dangerous commands
|
||
ZSH_HIGHLIGHT_PATTERNS+=('rm -rf *' 'fg=white,bold,bg=red')
|
||
ZSH_HIGHLIGHT_REGEXP+=('\bsudo\b' 'fg=white,bold,bg=red')
|
||
### CLI
|
||
ZSH_HIGHLIGHT_REGEXP+=('\ \-[^- ]+' 'fg=227') # short args in yellow (-l)
|
||
ZSH_HIGHLIGHT_REGEXP+=('\ \--[^ ]+' 'fg=214') # long args in orange (--all)
|
||
### Taskwarrior
|
||
ZSH_HIGHLIGHT_REGEXP+=('\ \+[^ ]+' 'fg=226') # tags in yellow (+txt)
|
||
ZSH_HIGHLIGHT_REGEXP+=('[^ ]+\:' 'fg=135') # metadata in purple (project:)
|
||
ZSH_HIGHLIGHT_REGEXP+=('\ \_[^ ]+' 'fg=32') # subcommands in blue (_command)
|
||
# }}}
|