Des menus dans votre terminal - retour accueil
git clone git://bebou.netlib.re/zenu
Log | Files | Refs |
commit fb3c849fc5468e838ccdd42e5898dd8aa7db21b5 Auterice: Marc Chantreux <mc@unistra.fr> Date: Fri, 3 Mar 2023 13:09:30 +0100 first contact Diffstat:
A | .gitignore | | | 1 | + |
A | bin/build | | | 40 | ++++++++++++++++++++++++++++++++++++++++ |
A | makefile | | | 14 | ++++++++++++++ |
A | menus/mail | | | 15 | +++++++++++++++ |
A | menus/main | | | 10 | ++++++++++ |
A | menus/mru | | | 5 | +++++ |
A | menus/network | | | 27 | +++++++++++++++++++++++++++ |
A | rc | | | 32 | ++++++++++++++++++++++++++++++++ |
A | zenu.zsh | | | 59 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
9 files changed, 203 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore @@ -0,0 +1 @@ +menus/*.* diff --git a/bin/build b/bin/build @@ -0,0 +1,40 @@ +#!/bin/sh -ue + +usage() <<-% cat + usage: + * build a face (the file that becomes part of a menu) + $0 face file + $0 -f file + * build a script (the function to handle pressed keys) + $0 script file + $0 -f file +% + +cmd="${1?command to run. -h for details}" +: "${2?file to parse. -h for details}" +shift + +case "$cmd" +in (-h|help|--help) usage +;; (face | -f) sed -rn '/^##/q;s/_(.)/\x1b[7m\1\x1b[m/;s/^/ /p' "$@" +;; (script | -s) <<-% cat + $( sed -rn '/^## *pre */,/^##/p' "$@" ) + # zenu.show + read -sk1 zenu_key + case "\$zenu_key" + in (\$'\n') zenu-- + $( sed -rn '/^## *react */,/^##/p' "$@" ) + esac + % +;; (emph| -e) + sed -rn '/^##/q;s/(.*)_((.).*)/\3 \1\2 /;p' "$@" | tee -a LOG | awk ' + {line[i++]=$0} + (l=length)>m {m=l} + END { for (i=0; i<until ; ++i) printf "%-*s\n", m, line[i] } + ' until=$(cat menus/until.txt) +;; (*) + >& echo "$cmd isn't a valid command" + false +esac + + diff --git a/makefile b/makefile @@ -0,0 +1,14 @@ +root = menus +menus != find ${root} -type f -not -name '*.*' +face = ${menus:%=%.face} +script = ${menus:%=%.script} +emph = ${menus:%=%.emph} +until = ${root}/until.txt + +all: ${until} ${script} ${emph} + +%.face : % ; bin/build -f $< > $@ +%.script : % ${until} ; bin/build -s $< > $@ +%.emph : % ${until} ; bin/build -e $< > $@ +${until} : ${face} ; wc $? | awk 'n>m{m=n}{n=$$1}END{print m}' > $@ +clean:; rm -rf ${root}/*.* diff --git a/menus/mail b/menus/mail @@ -0,0 +1,15 @@ +_read main box +_sync from partage +read _old stuff +_compose +_index +## react +;; (r) mutt +;; (o) mutt -f ~/Maildir/Trash +;; (s) mbsync -ac ~/Maildir/rc +;; (c) echo not yet +;; (i) set mu index + if [ "$TMUX" ] + then tmux split -dl3 $@ + else $@ + fi diff --git a/menus/main b/menus/main @@ -0,0 +1,10 @@ +_mail +_recent (MRU) +_jobs +_notes +net_work +## react +;; (m) zenu+ mail +;; (r) zenu+ mru +;; (w) zenu+ network +;; (n) vim ~p/start +'cd %:h' +'setf roguemode' diff --git a/menus/mru b/menus/mru @@ -0,0 +1,5 @@ +_directories +_files +## react +;; (d) c +;; (f) e diff --git a/menus/network b/menus/network @@ -0,0 +1,27 @@ +_chose interface +_up +_down +_get ip addr +get up (u_+g) +## pre +local save=$zenu_store/network_interface +local state=$zenu_store/network_state +local nif= +touch $save +read nif < $save +echo +ip -br a | sed -r " + s/ /! / # separator for pick + s/^/ / # margin +"| tee $state | +sed "/${nif:-é}!/s/.*/\x1b[7m&\x1b[m/;s/!/ /" +## react +;; (c) + zenu.up $(( $(< $state wc -l) + 1 )) + < $state IFS='!' pick -Xd > $save + read nif < $save +;; (u) doas ip li set $nif up +;; (d) doas ip li set $nif down +;; (g) doas /sbin/dhclient $nif +;; (+) doas ip li set $nif up + doas /sbin/dhclient $nif diff --git a/rc b/rc @@ -0,0 +1,32 @@ +autoload -Uz add-zsh-hook +last_cmd=: +preexec () last_cmd="$*" +. ~/.zsh/zenu/zenu.zsh +_precmd_run_menu() { + [ "$last_cmd" ] || zenu.loop in ~/.zsh/zenu/menus/ + last_cmd= +} +PSGIT= +_precmd_udate_git_status() { + PSGIT=$( { + 2>/dev/null git branch --show-current && { + git status -s|wc -l + } + } | tr '\n' ' ' ) +} +add-zsh-hook -Uz precmd _precmd_udate_git_status +add-zsh-hook -Uz precmd _precmd_run_menu +chpwd() { + pwd >> ~/.was-here +} +PS1=$'%{\e]0;%n@%m:%~ $PSGIT\a%}$( + i=0; for it { echo -n "〔$[++i] $it〕"} +)${*/?*/\n} ▶ ' +bindkey -v +bindkey -s "((" "()\ei" +bindkey -s "{{" "{}\ei" +bindkey -s "[[" "[]\ei" +bindkey -s "''" "'\ei'" +bindkey -s '""' '"\ei"' +stty -ixo{n,ff} +export EDITOR=vim diff --git a/zenu.zsh b/zenu.zsh @@ -0,0 +1,59 @@ +: ${zenu_store:=$( mktemp -d )} +trap "rm -rf $zenu_store" EXIT + +zenu.up() { + repeat ${1:-1} printf "[2K\e[A" + printf "\e[2K" +} + +zenu.emph() { + sed -r ' + /^'"$zenu_key"'(.*)$/ { + s//\x1b[7m\1\x1b[m/ + n + } + s/^.// + ' $zenu_base/$zenu_stack[-1].emph > $zenu_store/$#zenu_stack +} + +zenu+() { + zenu.emph + zenu_stack+=$1 +} + +zenu--() { + (( $#zenu_stack )) && zenu_stack[-1]=() +} + +zenu.update() { + set $zenu_base/$zenu_stack + cat $1.face + . $1.script +} + +zenu.loop() { + local -a zenu_stack + zenu_stack=( main ) + local zenu_base= zenu_key= + while (( $# )) { + case "$1" + in (from) zenu_stack=($2) ; shift 2 + ;; (in) zenu_base=$2 ; shift 2 + ;; (*) >&2 echo "not a valid key $1"; return 1 + esac + } + while {true} { + clear + case $#zenu_stack + in (0) return + ;; (1) zenu.update + ;; (*) + set $zenu_base/$zenu_stack[-1] + paste $zenu_store/{1..$[$#zenu_stack-1]} $1.face | sed 's/\t/│/g' + . $1.script + # echo paste $zenu_store/{1..$[$#zenu_stack-1]} $zenu_base/$zenu_stack[-1].face + # exit + esac + } +} +