Compare commits

..

2 Commits
v3.8.0 ... v3

Author SHA1 Message Date
a200c1eb22 v3.9.1
=====================================================================

--- Changes ------------------------------

- Moved personal-environment specific scwrypts to wrynegade/dotwryn
2023-12-23 10:23:38 -07:00
f3e70c61cb v3.9.0
=====================================================================

--- Changes ------------------------------

- scwrypts runner has new arguments
  -q/--quiet   allows quiet-mode operation while still logging to logfiles
  -v/--verbose forces verbose mode
    --version  longform required (-v is now for "verbose" mode)

- scwrypts runner now auto-detects certain CLI usage, running in quiet,
  logged mode if pattern match successfully identifies a single scwrypt
  (or when using --name); use --verbose to override this behavior

- 'k exec' no longer requires double '--' if a '--' comes after
  - old : k exec -it my-pod-0 -- -- /bin/sh
  + new : k exec -it my-pod-0 -- /bin/sh
  + still works : k -- exec -it my-pod-0 -- /bin/sh

--- Bug Fixes ----------------------------

- fixed various plugins/kubectl auto-completion settings; arguments
  after '--' or profile number (e.g. 'k 1 get deployments') will now
  appropriately autocomplete in the indicated profile

- helm template functions now work on related .tpl files as well
  (renders from chart root)

- fixed some goofy UTF-8 icons in zsh/lib/utils/io

--- New Features -------------------------

- (experimental) scwrypts zsh plugin for interactive command selection
  (like CTRL+SPACE), but allows you to build command arguments,
  providing help dialogue for the selected command

--- New Scripts --------------------------

- zsh/misc/tally ) helps keep tally-counts of things; helpful when
                   running long scripts "what iteration am I on"
2023-12-11 18:19:37 -07:00
12 changed files with 287 additions and 350 deletions

View File

@ -2,30 +2,45 @@
command -v compdef >/dev/null 2>&1 || return 0
#####################################################################
_k() {
local C=$(k meta get context)
local NS=$(k meta get namespace)
for CLI in kubectl helm flux
do
eval "_${CLI[1]}() {
local SUBSESSION=0
echo \${words[2]} | grep -q '^[0-9]\\+$' && SUBSESSION=\${words[2]}
local KUBEWORDS=(kubectl)
[ $C ] && KUBEWORDS+=(--context $C)
[ $NS ] && KUBEWORDS+=(--namespace $NS)
local PASSTHROUGH_WORDS=($CLI)
[[ \$CURRENT -gt 2 ]] && echo \${words[2]} | grep -qv '^[0-9]\\+$' && {
local KUBECONTEXT=\$(k \$SUBSESSION meta get context)
local NAMESPACE=\$(k \$SUBSESSION meta get namespace)
words="$KUBEWORDS ${words[@]:1}"
_kubectl
}
[ \$KUBECONTEXT ] \
&& PASSTHROUGH_WORDS+=($([[ $CLI =~ ^helm$ ]] && echo '--kube-context' || echo '--context') \$KUBECONTEXT) \
;
[ \$NAMESPACE ] \
&& PASSTHROUGH_WORDS+=(--namespace \$NAMESPACE) \
;
}
compdef _k k
local DELIMIT_COUNT=0
local WORD
for WORD in \${words[@]:1}
do
case \$WORD in
[0-9]* ) continue ;;
-- )
echo \$words | grep -q 'exec' && ((DELIMIT_COUNT+=1))
[[ \$DELIMIT_COUNT -eq 0 ]] && ((DELIMIT_COUNT+=1)) && continue
;;
esac
PASSTHROUGH_WORDS+=(\"\$WORD\")
done
#####################################################################
_h() {
local C=$(k meta get context)
local NS=$(k meta get namespace)
echo \"\$words\" | grep -q '\\s\\+$' && PASSTHROUGH_WORDS+=(' ')
local KUBEWORDS=(kubectl)
[ $C ] && KUBEWORDS+=(--context $C)
[ $NS ] && KUBEWORDS+=(--namespace $NS)
words=\"\$PASSTHROUGH_WORDS\"
_$CLI
}
"
words="$KUBEWORDS ${words[@]:1}"
_helm
}
compdef _h h
compdef _${CLI[1]} ${CLI[1]}
done

View File

@ -110,7 +110,11 @@ _SCWRYPTS_KUBECTL_DRIVER() {
shift 1
;;
-- ) shift 1; break ;;
-- )
echo $USER_ARGS | grep -q 'exec' && USER_ARGS+=(--)
shift 1
break
;;
* )
[ ! $CUSTOM_COMMAND ] && {

175
run
View File

@ -6,24 +6,35 @@ source "${0:a:h}/zsh/lib/import.driver.zsh" || exit 42
__RUN() {
local USAGE='
usage: scwrypts [OPTIONS ...] SCRIPT -- [SCRIPT OPTIONS ...]
usage: scwrypts [... options ...] [patterns] -- [...script options...]
OPTIONS
-g, --group <group-name> only use scripts from the indicated group
-t, --type <type-name> only use scripts of the indicated type
-m, --name <scwrypt-name> only run the script if there is an exact match
(requires type and group)
options:
selection
-m, --name <scwrypt-name> only run the script if there is an exact match
(requires type and group)
-g, --group <group-name> only use scripts from the indicated group
-t, --type <type-name> only use scripts of the indicated type
-y, --yes auto-accept all [yn] prompts through current scwrypt
-e, --env <env-name> set environment; overwrites SCWRYPTS_ENV
-n, --no-log skip logging and run in quiet mode
runtime
-y, --yes auto-accept all [yn] prompts through current scwrypt
-e, --env <env-name> set environment; overwrites SCWRYPTS_ENV
-q, --quiet run in quiet mode
-n, --no-log skip the log file and run in quiet mode
-v, --verbose override quiet mode settings and print all debug dialogue
--update update scwrypts library to latest version
--list-envs print out environment list and exit
alternate commands
-h, --help display this message and exit
-l, --list print out command list and exit
--list-envs print out environment list and exit
--update update scwrypts library to latest version
--version print out scwrypts version and exit
patterns:
- a list of glob patterns to loose-match a scwrypt by name
-v, --version print out scwrypts version and exit
-l, --list print out command list and exit
-h, --help display this message and exit
script options:
- everything after "--" is forwarded to the scwrypt you run
(usually "-- --help" will provide more information)
'
cd "$SCWRYPTS_ROOT"
@ -32,70 +43,29 @@ __RUN() {
local VARSPLIT SEARCH_GROUP SEARCH_TYPE SEARCH_NAME
local ALLOW_LOGFILE=1
local VERBOSE=1
[ $CI ] && [ ! $SCWRYPTS_CI_FORCE_NON_VERBOSE ] && VERBOSE=2
local ERROR=0
while [[ $# -gt 0 ]]
do
case $1 in
-t | --type )
[ ! $2 ] && ERROR "missing value for argument $1" && break
SEARCH_TYPE=$2
shift 2
;;
-g | --group )
[ ! $2 ] && ERROR "missing value for argument $1" && break
SEARCH_GROUP=$2
shift 2
;;
-m | --name )
[ ! $2 ] && ERROR "missing value for argument $1" && break
SEARCH_NAME=$2
shift 2
;;
-[a-z][a-z]* )
VARSPLIT=$(echo "$1 " | sed 's/^\(-.\)\(.*\) /\1 -\2/')
set -- $(echo " $VARSPLIT ") ${@:2}
;;
-h | --help )
USAGE
-h | --help ) USAGE; return 0 ;;
-l | --list ) SCWRYPTS__GET_AVAILABLE_SCWRYPTS; return 0 ;;
--list-envs ) SCWRYPTS__GET_ENV_NAMES; return 0 ;;
--version )
echo scwrypts $(git -C "$SCWRYPTS__ROOT__scwrypts" describe --tags)
return 0
;;
-n | --no-log )
[ ! $SUBSCWRYPT ] && SUBSCWRYPT=0
shift 1
;;
-y | --yes )
export __SCWRYPTS_YES=1
shift 1
;;
-e | --env )
[ ! $2 ] && ERROR "missing value for argument $1" && break
[ ! $SUBSCWRYPTS ] \
&& [ $ENV_NAME ] \
&& WARNING 'overwriting session environment' \
;
ENV_NAME="$2"
STATUS "using CLI environment '$ENV_NAME'"
shift 2
;;
-l | --list )
SCWRYPTS__GET_AVAILABLE_SCWRYPTS
return 0
;;
--list-envs )
SCWRYPTS__GET_ENV_NAMES
return 0
;;
-v | --version )
echo scwrypts $(cd "$SCWRYPTS__ROOT__scwrypts"; git describe --tags)
return 0
;;
--update )
cd "$SCWRYPTS__ROOT__scwrypts"
git fetch --quiet origin main
@ -118,24 +88,53 @@ __RUN() {
}
return 0
;;
-- )
shift 1
break # pass arguments after '--' to the scwrypt
;;
--* )
ERROR "unrecognized argument '$1'"
-m | --name )
[ ! $2 ] && ERROR "missing value for argument $1" && break
SEARCH_NAME=$2
shift 1
;;
* )
SEARCH_PATTERNS+=($1)
-g | --group )
[ ! $2 ] && ERROR "missing value for argument $1" && break
SEARCH_GROUP=$2
shift 1
;;
-t | --type )
[ ! $2 ] && ERROR "missing value for argument $1" && break
SEARCH_TYPE=$2
shift 1
;;
-y | --yes ) export __SCWRYPTS_YES=1 ;;
-q | --quiet ) VERBOSE=0 ;;
-n | --no-log ) VERBOSE=0 ; [ ! $SUBSCWRYPT ] && SUBSCWRYPT=0 ;;
-v | --verbose ) VERBOSE=2 ;;
-e | --env )
[ ! $2 ] && ERROR "missing value for argument $1" && break
[ ! $SUBSCWRYPTS ] \
&& [ $ENV_NAME ] \
&& WARNING 'overwriting session environment' \
;
ENV_NAME="$2"
STATUS "using CLI environment '$ENV_NAME'"
shift 1
;;
-- ) shift 1; break ;; # pass arguments after '--' to the scwrypt
--* ) ERROR "unrecognized argument '$1'" ;;
* ) SEARCH_PATTERNS+=($1) ;;
esac
shift 1
done
[ $SEARCH_NAME ] && {
[ ! $SEARCH_TYPE ] && ERROR '--name requires --type argument'
[ ! $SEARCH_GROUP ] && ERROR '--name requires --group argument'
[ $SEARCH_TYPE ] || ERROR '--name requires --type argument'
[ $SEARCH_GROUP ] || ERROR '--name requires --group argument'
}
CHECK_ERRORS
@ -209,9 +208,12 @@ __RUN() {
local TYPE="$SEARCH_TYPE"
local GROUP="$SEARCH_GROUP"
[[ $(echo $SCWRYPTS_AVAILABLE | wc -l) -eq 2 ]] \
&& SCWRYPT_SELECTION=$(echo $SCWRYPTS_AVAILABLE | tail -n1) \
|| SCWRYPT_SELECTION=$(echo $SCWRYPTS_AVAILABLE | FZF "select a script to run" --header-lines 1)
[[ $(echo $SCWRYPTS_AVAILABLE | wc -l) -eq 2 ]] && {
SCWRYPT_SELECTION=$(echo $SCWRYPTS_AVAILABLE | tail -n1)
[[ $VERBOSE -eq 2 ]] || VERBOSE=0
} || {
SCWRYPT_SELECTION=$(echo $SCWRYPTS_AVAILABLE | FZF "select a script to run" --header-lines 1)
}
[ $SCWRYPT_SELECTION ] || exit 2
SCWRYPTS__SEPARATE_SCWRYPT_SELECTION $SCWRYPT_SELECTION
@ -254,7 +256,8 @@ __RUN() {
##########################################
[ ! $SUBSCWRYPT ] \
: \
&& [ ! $SUBSCWRYPT ] \
&& [[ $ENV_NAME =~ prod ]] \
&& { __VALIDATE_UPSTREAM_TIMELINE || ABORT; }
@ -268,6 +271,7 @@ __RUN() {
local LOGFILE=$(__GET_LOGFILE)
local HEADER=$(
[[ $VERBOSE -gt 0 ]] || return 0
[ $SUBSCWRYPT ] && return 0
echo '====================================================================='
echo "script : $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME"
@ -289,14 +293,14 @@ __RUN() {
{
[ $HEADER ] && echo $HEADER
echo '\033[1;33m--- BEGIN OUTPUT -------------------------\033[0m'
[[ $VERBOSE -gt 0 ]] && echo '\033[1;33m--- BEGIN OUTPUT -------------------------\033[0m'
(eval "$RUN_STRING $(printf "%q " "$@")")
EXIT_CODE=$?
echo '\033[1;33m--- END OUTPUT ---------------------------\033[0m'
[[ $VERBOSE -gt 0 ]] && echo '\033[1;33m--- END OUTPUT ---------------------------\033[0m'
[[ $EXIT_CODE -eq 0 ]] && EXIT_COLOR='32m' || EXIT_COLOR='31m'
echo "terminated with\\033[1;$EXIT_COLOR code $EXIT_CODE\\033[0m"
[[ $VERBOSE -gt 0 ]] && echo "terminated with\\033[1;$EXIT_COLOR code $EXIT_CODE\\033[0m"
} 2>&1 | tee --append "$LOGFILE"
exit $(\
@ -338,10 +342,9 @@ __VALIDATE_UPSTREAM_TIMELINE() {
}
__GET_LOGFILE() {
[ $SUBSCWRYPT ] \
|| [[ $SCWRYPT_NAME =~ scwrypts/logs ]] \
|| [[ $SCWRYPT_NAME =~ interactive ]] \
&& return 0
[ $SUBSCWRYPT ] && return 0
[[ $SCWRYPT_NAME =~ scwrypts/logs ]] && return 0
[[ $SCWRYPT_NAME =~ interactive ]] && return 0
echo "$SCWRYPTS_LOG_PATH/$(echo $GROUP/$TYPE/$NAME | sed 's/^\.\///; s/\//\%/g').log"
}

View File

@ -6,7 +6,7 @@ SCWRYPTS__ZSH_PLUGIN() {
local NAME
local TYPE
local GROUP
zle clear-command-line
LBUFFER= RBUFFER=
[ ! $SCWRYPT_SELECTION ] && { zle accept-line; return 0; }
SCWRYPTS__SEPARATE_SCWRYPT_SELECTION $SCWRYPT_SELECTION
@ -14,13 +14,40 @@ SCWRYPTS__ZSH_PLUGIN() {
which scwrypts >/dev/null 2>&1\
&& RBUFFER="scwrypts" || RBUFFER="$SCWRYPTS_ROOT/scwrypts"
RBUFFER+=" --name $NAME --group $GROUP --type $TYPE"
RBUFFER+=" --name $NAME --group $GROUP --type $TYPE --verbose"
zle accept-line
}
zle -N scwrypts SCWRYPTS__ZSH_PLUGIN
bindkey $SCWRYPTS_SHORTCUT scwrypts
#####################################################################
SCWRYPTS__ZSH_BUILDER_PLUGIN() {
local SCWRYPT_SELECTION=$(SCWRYPTS__GET_AVAILABLE_SCWRYPTS | FZF 'select a script' --header-lines 1)
local NAME
local TYPE
local GROUP
LBUFFER= RBUFFER=
[ ! $SCWRYPT_SELECTION ] && { zle accept-line; return 0; }
SCWRYPTS__SEPARATE_SCWRYPT_SELECTION $SCWRYPT_SELECTION
scwrypts --name $NAME --group $GROUP --type $TYPE -- --help >&2 || {
zle accept-line
return 0
}
echo
zle reset-prompt
which scwrypts >/dev/null 2>&1\
&& LBUFFER="scwrypts" || LBUFFER="$SCWRYPTS_ROOT/scwrypts"
LBUFFER+=" --name $NAME --group $GROUP --type $TYPE -- "
}
zle -N scwrypts-builder SCWRYPTS__ZSH_BUILDER_PLUGIN
bindkey $SCWRYPTS_BUILDER_SHORTCUT scwrypts-builder
#####################################################################
SCWRYPTS__ZSH_PLUGIN_ENV() {
local RESET='reset'

Binary file not shown.

View File

@ -4,6 +4,7 @@ DEPENDENCIES+=(helm kubeval)
REQUIRED_ENV+=()
use helm/validate
use scwrypts
#####################################################################

View File

@ -38,6 +38,8 @@ HELM__VALIDATE() {
HELM_ARGS+=(--values $TEMPLATE_FILENAME)
USE_CHART_ROOT=1
}
[[ $TEMPLATE_FILENAME =~ .tpl$ ]] \
&& USE_CHART_ROOT=1
[[ $(dirname $TEMPLATE_FILENAME) =~ ^$CHART_ROOT$ ]] \
&& USE_CHART_ROOT=1

View File

@ -0,0 +1,106 @@
#####################################################################
DEPENDENCIES+=()
REQUIRED_ENV+=()
#####################################################################
TALLY_USE_REDIS=false # maybe someday
TALLY_PATH="$SCWRYPTS_DATA_PATH/tally"
#####################################################################
TALLY() {
local USAGE="
usage: [...options...]
options:
-c, --increment-count increment the tally by this much (default 1)
-n, --tally-name name of tally system (default 'default')
-g, --get only output the current value
-s, --set set the tally to a specific value
-r, --reset set the tally back to zero
--raw only output the tally value
-h, --help print this dialogue and exit
Simple tally mark system; keep track of a count.
"
local INCREMENT_COUNT=1
local TALLY_NAME=default
local RAW=false
local SET_VALUE=
while [[ $# -gt 0 ]]
do
case $1 in
-c | --increment-count ) INCREMENT_COUNT=$2; shift 1 ;;
-n | --tally-name ) TALLY_NAME=$2; shift 1 ;;
-g | --get ) INCREMENT_COUNT=0 ;;
-s | --set ) SET_VALUE=$2; shift 1 ;;
-r | --reset ) SET_VALUE=0 ;;
--raw ) RAW=true ;;
-h | --help ) USAGE; return 0 ;;
* ) ERROR "unknown argument '$1'" ;;
esac
shift 1
done
[ $TALLY_NAME ] && echo "$TALLY_NAME" | grep -qv '/' \
|| ERROR "invalid tally name '$TALLY_NAME'"
local TALLY_FILENAME="$TALLY_PATH/$TALLY_NAME.txt"
CHECK_ERRORS --no-fail || return 1
##########################################
local NEW_VALUE CURRENT_VALUE=0
[ $SET_VALUE ] && NEW_VALUE=$SET_VALUE || {
[ -f "$TALLY_FILENAME" ] && {
CURRENT_VALUE=$(cat "$TALLY_FILENAME" | tail -n1 | grep '^[0-9]\+')
}
[ $CURRENT_VALUE ] || {
ERROR "malformed tally file '$TALLY_FILENAME'; aborting"
return 1
}
NEW_VALUE=$(($CURRENT_VALUE + $INCREMENT_COUNT))
}
##########################################
local TALLY_DIR="$(dirname "$TALLY_FILENAME")"
[ -d "$TALLY_DIR" ] || mkdir -p "$TALLY_DIR"
[ -d "$TALLY_DIR" ] || {
ERROR "unable to write to '$TALLY_DIR'; aborting"
return 1
}
echo "# autogenerated tally file; avoid direct modification\n$NEW_VALUE" > "$TALLY_FILENAME" || {
ERROR "failed to write to '$TALLY_FILENAME': aborting"
return 1
}
##########################################
case $RAW in
true ) printf "$NEW_VALUE" ;;
false )
case $TALLY_NAME in
default ) INFO "current tally : $NEW_VALUE" ;;
* ) INFO "$TALLY_NAME : $NEW_VALUE" ;;
esac
esac
}

View File

@ -43,11 +43,11 @@ SUCCESS() { PREFIX="SUCCESS ✔" COLOR=$__GREEN PRINT "$@"; }
WARNING() { PREFIX="WARNING " COLOR=$__ORANGE PRINT "$@"; }
STATUS() { PREFIX="STATUS " COLOR=$__BLUE PRINT "$@"; }
REMINDER() { PREFIX="REMINDER " COLOR=$__PURPLE PRINT "$@"; }
INFO() { PREFIX="INFO " COLOR=$__WHITE PRINT "$@"; }
INFO() { PREFIX="INFO " COLOR=$__WHITE PRINT "$@"; }
PROMPT() {
PREFIX="PROMPT " COLOR=$__CYAN PRINT "$@"
PREFIX="USER " COLOR=$__CYAN PRINT '' --no-line-end
PREFIX="USER " COLOR=$__CYAN PRINT '' --no-line-end
}
FAIL() { ERROR "${@:2}"; exit $1; }

17
zsh/misc/tally Executable file
View File

@ -0,0 +1,17 @@
#!/bin/zsh
#####################################################################
DEPENDENCIES+=()
REQUIRED_ENV+=()
use misc/tally
CHECK_ENVIRONMENT
#####################################################################
MAIN() {
unset USAGE
TALLY $@
}
#####################################################################
MAIN $@

View File

@ -1,102 +0,0 @@
#!/bin/zsh
DEPENDENCIES+=(
diff
)
REQUIRED_ENV+=(
I3__MODEL_CONFIG
)
CHECK_ENVIRONMENT
#####################################################################
REGEX_FONT='^\(font [^0-9]*\)\(.*\)'
REGEX_DMENU="^\\(.*dmenu_run .*-fn '[^0-9]*\\)\\([0-9]*\\)'"
REGEX_BORDER='^\(for_window.*border pixel \)\(.*\)'
INSTALL() {
local USAGE="
usage: [...options...]
options
-f, --force force replacement of existing i3config
-n, --no-link if output config and template are the same, don't create link
-h, --help print this message and exit
environment
I3__MODEL_CONFIG fully-qualified path to sourced i3config
I3__GLOBAL_FONT_SIZE global font size
I3__DMENU_FONT_SIZE (optional) font size for 'dmenu' command
I3__BORDER_PIXEL_SIZE (optional) pixel-width of window borders
I3 provides no way to include dynamic variables in your config.
The main difference I want between my i3 configurations is font-size
to match the current monitor. Since i3-msg provides no way to change
font size, I run this command to update those variables on a local
copy of my sourced config
"
local FORCE=0
local AUTOLINK=1
while [[ $# -gt 0 ]]
do
case $1 in
-f | --force ) FORCE=1 ;;
-n | --no-link ) AUTOLINK=0 ;;
-h | --help ) USAGE; exit 0 ;;
esac
shift 1
done
STATUS 'reading local i3config'
[[ ^$I3__MODEL_CONFIG$ =~ ^$HOME/.config/i3/config$ ]] && {
STATUS "model configuration is default configuration"
I3__MODEL_CONFIG="$I3__MODEL_CONFIG.template"
[ ! -f "$I3__MODEL_CONFIG" ] && {
STATUS "creating template"
cp "$HOME/.config/i3/config" "$I3__MODEL_CONFIG.template"
}
STATUS "referring to '$I3__MODEL_CONFIG'"
}
local CONFIG=$(cat "$I3__MODEL_CONFIG")
[ ! $CONFIG ] && FAIL 1 "failed to read config at '$I3__MODEL_CONFIG'"
local CONFIG_FILE="$HOME/.config/i3/config"
[ ! -d $(dirname "$CONFIG_FILE") ] && mkdir -p "$(dirname "$CONFIG_FILE")"
[ -f "$CONFIG_FILE" ] && mv "$CONFIG_FILE" "$CONFIG_FILE.bak"
[ $I3__GLOBAL_FONT_SIZE ] && {
STATUS "setting global font size to '$I3__GLOBAL_FONT_SIZE'"
CONFIG=$(echo $CONFIG | sed "s/$REGEX_FONT/\\1$I3__GLOBAL_FONT_SIZE/")
}
[ $I3__DMENU_FONT_SIZE ] && {
STATUS "setting dmenu font size to '$I3__DMENU_FONT_SIZE'"
CONFIG=$(echo $CONFIG | sed "s/$REGEX_DMENU/\\1$I3__DMENU_FONT_SIZE'/")
}
[ $I3__BORDER_PIXEL_SIZE ] && {
STATUS "setting border pixel size to '$I3__BORDER_PIXEL_SIZE'"
CONFIG=$(echo $CONFIG | sed "s/$REGEX_BORDER/\\1$I3__BORDER_PIXEL_SIZE/")
}
echo $CONFIG > "$CONFIG_FILE"
[ -f "$CONFIG_FILE.bak" ] \
&& diff "$CONFIG_FILE" "$CONFIG_FILE.bak" -q >/dev/null \
&& mv "$CONFIG_FILE.bak" "$CONFIG_FILE" \
&& INFO "no changes were made" \
;
[[ $AUTOLINK -eq 1 ]] \
&& diff "$CONFIG_FILE" "$I3__MODEL_CONFIG" -q >/dev/null \
&& rm "$CONFIG_FILE" \
&& ln -s "$I3__MODEL_CONFIG" "$CONFIG_FILE" \
&& INFO "output is the same as model, i3config has been linked to model" \
;
[[ $FORCE -eq 1 ]] && rm "$CONFIG.bak" >/dev/null 2>&1
return 0
}
#####################################################################
INSTALL $@

View File

@ -1,136 +0,0 @@
#!/bin/zsh
DEPENDENCIES+=(
i3-msg
xdotool
xrandr
)
REQUIRED_ENV+=()
use system/desktop/notify
CHECK_ENVIRONMENT
#####################################################################
LAUNCH_OR_SHOW() {
INFO $@
local USAGE="
usage: <path-executable> [client-class] [...options...]
options
-c, --client <string> if different from the executable name, xprop CLIENT_CLASS
-s, --scale <value> (default: 0.8 or 0.5 if screen width >3000px)
-x, --x-offset <value> (default: 0.0)
-y, --y-offset <value> (default: 0.0)
-a, --always-launch invoke executable even if client-class exists
-n, --no-resize don't resize the window (ignores -sxy flags)
-l, --no-center leave the window wherever it was last positioned
--has-statusbar-icon (default: false) use if program has a statusbar icon
-h, --help print this message and exit
Makes it easy to bind appications to key shortcuts without having to
spin up redundant instances or cycle through the scratchpad queue.
Performs a variety of tasks based on states:
1) starts and application
2) adds all instances of the specified application to the scratchpad
3) (toggle) hides all visible instances
4) (toggle) shows all scratchpad-hidden instances
"
local APPLICATION CLIENT_CLASS
local XFFSET=0.0
local YFFSET=0.0
local SCALE=0.8
[[ $(xrandr | grep primary | awk '{print $4;}' | sed 's/x.*//') -gt 3000 ]] \
&& SCALE=0.5
local ALWAYS_LAUNCH=0
local RESIZE=1
local MOVE=1
local MIN_ACTIVE=1
while [[ $# -gt 0 ]]
do
case $1 in
-c | --client ) CLIENT_CLASS="$2"; shift 1 ;;
-x | --x-offset ) XFFSET=$2; shift 1 ;;
-y | --y-offset ) YFFSET=$2; shift 1 ;;
-s | --scale ) SCALE=$2; shift 1 ;;
-a | --always-launch ) ALWAYS_LAUNCH=1 ;;
-n | --no-resize ) RESIZE=0 ;;
-l | --no-center ) MOVE=0 ;;
--has-statusbar-icon ) MIN_ACTIVE=2 ;;
-h | --help ) USAGE; exit 0 ;;
* )
[ ! $APPLICATION ] && APPLICATION="$1" \
|| ERROR "extra positional argument '$1'"
esac
shift 1
done
[ ! $APPLICATION ] && ERROR 'path-executable required'
[ ! $CLIENT_CLASS ] && CLIENT_CLASS=$APPLICATION
[ $APPLICATION ] && {
__CHECK_DEPENDENCY $APPLICATION || {
ERROR "$APPLICATION is not installed"
NOTIFY "ERROR: $APPLICATION not found"
}
}
CHECK_ERRORS
xrandr | grep primary | awk '{print $4;}' | grep -q '^[0-9]\+$' || {
xrandr --output $(xrandr | grep ' connected' | awk '{print $1;}' | head -n1) --primary
}
local CURRENTLY_ACTIVE=$(xdotool search --onlyvisible --classname $CLIENT_CLASS 2>/dev/null | wc -l)
local LAUNCH_APP=$ALWAYS_LAUNCH
STATUS "looking for window process ids"
xdotool search --class $CLIENT_CLASS || LAUNCH_APP=1
[[ $LAUNCH_APP -eq 1 ]] && {
STATUS 'launching application'
i3-msg "exec --no-startup-id $APPLICATION;"
sleep .5
}
STATUS 'getting target window size'
WINDOW_SIZE=$(\
xrandr \
| grep 'connected primary' \
| sed 's/.*connected primary \([^x]*\)x\([^+]*\).*/\1 \2/' \
| awk -v f=$SCALE -v x=$XFFSET -v y=$YFFSET \
'{print int($1*f+x)," ",int($2*f+y);}'\
)
INFO "window size: $WINDOW_SIZE"
STATUS 'moving window to scratchpad'
i3-msg "[class=$CLIENT_CLASS] move scratchpad"
[[ $RESIZE -eq 1 ]] \
&& STATUS 'resizing window' \
&& i3-msg "[class=$CLIENT_CLASS] resize set $WINDOW_SIZE"
[[ $CURRENTLY_ACTIVE -lt $MIN_ACTIVE ]] && {
STATUS 'pulling window from scratchpad to foreground'
i3-msg "[class=$CLIENT_CLASS] scratchpad show"
}
STATUS 'moving window to center of current screen'
[[ $MOVE -eq 1 ]] && i3-msg "[class=$CLIENT_CLASS] move position center"
return 0
}
#####################################################################
LAUNCH_OR_SHOW $@