From 22dd6f8112e9e1179391690c17cf417f146c3f66 Mon Sep 17 00:00:00 2001 From: yage Date: Mon, 22 Aug 2022 16:04:03 -0600 Subject: [PATCH] v2.6.0 ===================================================================== --- New Scripts -------------------------- - i3 window manager scrypts (see --help for more info) - zsh/i3/create-local-font-override - zsh/i3/launch-or-show --- New Features ------------------------- Now support `__select` syntax in environment files! (see zsh/scwrypts/README.md for more detail) --- Changes ------------------------------ - moved some rogue configuration files under the scwrypts config - ~/.vim/bundle/build.zsh >> ~/.config/scwrypts/vundle.zsh - ~/.config/scwrypts/config.dotfile.zsh >> ~/.config/scwrypts/dotfiles.zsh - __FZF, __FZF_TAIL, and __FZF_HEAD now create prompt+response logs --- Bug Fixes ---------------------------- - zsh/config/symlinks - don't fail when trying to symlink a directory - no longer fails when trying to replace a broken symlink - scwrypts now detects environments which are symlinked - USAGE syntax now correctly shows the position of the '--' argument delimiter support __select in env files; ignore __lower_case suffix in env files; put blank line before comments in env files added i3 scripts --- .env.template | 4 + .env.template.descriptions | 5 ++ zsh/common.zsh | 2 +- zsh/config/common.zsh | 5 +- zsh/config/symlinks | 10 +-- zsh/i3/common.zsh | 14 ++++ zsh/i3/create-local-font-override | 105 +++++++++++++++++++++++++ zsh/i3/launch-or-show | 113 +++++++++++++++++++++++++++ zsh/scwrypts/README.md | 20 +++++ zsh/scwrypts/environment/synchronize | 19 ++--- zsh/utils/environment.zsh | 6 ++ zsh/utils/io.zsh | 7 +- zsh/vim/vundle/common.zsh | 2 +- 13 files changed, 292 insertions(+), 20 deletions(-) create mode 100644 zsh/i3/common.zsh create mode 100755 zsh/i3/create-local-font-override create mode 100755 zsh/i3/launch-or-show diff --git a/.env.template b/.env.template index 67cdaff..33bc474 100644 --- a/.env.template +++ b/.env.template @@ -5,6 +5,10 @@ export AWS_REGION= export AWS__EFS__LOCAL_MOUNT_POINT= export AWS__S3__MEDIA_BUCKET= export AWS__S3__MEDIA_TARGETS= +export I3__BORDER_PIXEL_SIZE= +export I3__DMENU_FONT_SIZE= +export I3__GLOBAL_FONT_SIZE= +export I3__MODEL_CONFIG= export REDIS_AUTH= export REDIS_HOST= export REDIS_PORT= diff --git a/.env.template.descriptions b/.env.template.descriptions index 857de6f..705671b 100644 --- a/.env.template.descriptions +++ b/.env.template.descriptions @@ -7,6 +7,11 @@ AWS__EFS__LOCAL_MOUNT_POINT | fully-qualified path to mount the EFS drive AWS__S3__MEDIA_BUCKET | s3 bucket name and filesystem targets for media backups AWS__S3__MEDIA_TARGETS | +I3__BORDER_PIXEL_SIZE | custom i3 configuration settings +I3__DMENU_FONT_SIZE | +I3__GLOBAL_FONT_SIZE | +I3__MODEL_CONFIG | + REDIS_AUTH | redis connection credentials REDIS_HOST | REDIS_PORT | diff --git a/zsh/common.zsh b/zsh/common.zsh index a126dd6..6c1f5f9 100644 --- a/zsh/common.zsh +++ b/zsh/common.zsh @@ -6,7 +6,7 @@ source ${0:a:h}/utils/utils.module.zsh \ ##################################################################### -__GET_ENV_FILES() { find $SCWRYPTS_CONFIG_PATH/env -maxdepth 1 -type f | sort -r } +__GET_ENV_FILES() { ls $SCWRYPTS_CONFIG_PATH/env | sort -r } [ ! "$(__GET_ENV_FILES)" ] && { cp $__ENV_TEMPLATE "$SCWRYPTS_CONFIG_PATH/env/dev" cp $__ENV_TEMPLATE "$SCWRYPTS_CONFIG_PATH/env/local" diff --git a/zsh/config/common.zsh b/zsh/config/common.zsh index 62cd08f..171efe3 100644 --- a/zsh/config/common.zsh +++ b/zsh/config/common.zsh @@ -6,8 +6,9 @@ source ${0:a:h}/../common.zsh SAFE_SYMLINKS=1 -# in case config.dotfile.zsh is sourced... allow user to provide initial config ;) +# in case dotfiles.zsh is sourced... allow user to provide initial config ;) [ ! $CONFIG__USER_SETTINGS ] \ - && CONFIG__USER_SETTINGS="$SCWRYPTS_CONFIG_PATH/config.dotfile.zsh" + && CONFIG__USER_SETTINGS="$SCWRYPTS_CONFIG_PATH/dotfiles.zsh" + [ ! -f "$CONFIG__USER_SETTINGS" ] && cp "$DEFAULT_CONFIG" "$CONFIG__USER_SETTINGS" source $CONFIG__USER_SETTINGS diff --git a/zsh/config/symlinks b/zsh/config/symlinks index f1dc0e6..66be218 100755 --- a/zsh/config/symlinks +++ b/zsh/config/symlinks @@ -15,16 +15,16 @@ SETUP_SYMLINK() { [ ! $2 ] && __FAIL 1 'must provide SOURCE_CONFIG and TARGET_CONFIG' local SOURCE_CONFIG="$1" - [ ! -f "$SOURCE_CONFIG" ] && __FAIL 2 "no such file '$SOURCE_CONFIG'" + [ ! -f "$SOURCE_CONFIG" ] && [ ! -d "$SOURCE_CONFIG" ] && __FAIL 2 "no such file or directory '$SOURCE_CONFIG'" local TARGET_CONFIG="$HOME/.config/$2" [ ! -d $(dirname "$TARGET_CONFIG") ] && mkdir -p $(dirname "$TARGET_CONFIG") - [ -f "$TARGET_CONFIG" ] && { - [[ $SAFE_SYMLINKS -eq 1 ]] && mv "$TARGET_CONFIG" "$TARGET_CONFIG.bak" - [[ $SAFE_SYMLINKS -eq 0 ]] && rm "$TARGET_CONFIG" - } + [[ $SAFE_SYMLINKS -eq 1 ]] \ + && mv "$TARGET_CONFIG" "$TARGET_CONFIG.bak" >/dev/null 2>&1 + + rm "$TARGET_CONFIG" >/dev/null 2>&1 ln -s "$SOURCE_CONFIG" "$TARGET_CONFIG" \ && __SUCCESS "successfully linked '$(basename $(dirname $TARGET_CONFIG))/$(basename $TARGET_CONFIG)'" \ diff --git a/zsh/i3/common.zsh b/zsh/i3/common.zsh new file mode 100644 index 0000000..dd798e5 --- /dev/null +++ b/zsh/i3/common.zsh @@ -0,0 +1,14 @@ +_DEPENDENCIES+=( + i3 + i3-msg +) +_REQUIRED_ENV+=() +source ${0:a:h}/../common.zsh +##################################################################### + +[ ! $DISPLAY ] && export DISPLAY=:0 + +_NOTIFY() { + __CHECK_DEPENDENCY notify-send || return 0 + notify-send "SCWRYPTS $SCWRYPT_NAME" $@ +} diff --git a/zsh/i3/create-local-font-override b/zsh/i3/create-local-font-override new file mode 100755 index 0000000..9f9f2dc --- /dev/null +++ b/zsh/i3/create-local-font-override @@ -0,0 +1,105 @@ +#!/bin/zsh +_DEPENDENCIES+=( + diff +) +_REQUIRED_ENV+=( + I3__MODEL_CONFIG +) +source ${0:a:h}/common.zsh + +__CHECK_ENV_VAR I3__GLOBAL_FONT_SIZE --optional +__CHECK_ENV_VAR I3__DMENU_FONT_SIZE --optional +__CHECK_ENV_VAR I3__BORDER_PIXEL_SIZE --optional +##################################################################### + +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__DMENU_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 $@ diff --git a/zsh/i3/launch-or-show b/zsh/i3/launch-or-show new file mode 100755 index 0000000..1c4d4b5 --- /dev/null +++ b/zsh/i3/launch-or-show @@ -0,0 +1,113 @@ +#!/bin/zsh +_DEPENDENCIES+=( + xdotool + xrandr + i3-msg +) +_REQUIRED_ENV+=() +source ${0:a:h}/common.zsh +##################################################################### + +LAUNCH_OR_SHOW() { + local USAGE=" + usage: [client-class] [...options...] + + options + -c, --client if different from the executable name, xprop CLIENT_CLASS + + -s, --scale (default: 0.8 or 0.5 if screen width >3000px) + -x, --x-offset (default: 0.0) + -y, --y-offset (default: 0.0) + + -a, --always-launch invoke executable even if client-class exists + -n, --no-resize don't resize the window (ignores -sxy flags) + + -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. + + Depending on state, performs one of three useful functions + 1) starts application + 2) adds application window to the scratchpad + 3) pulls applciation from scratchpad to foreground on active screen + " + 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 + + 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 ;; + + -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" + } + } + + __ERROR_CHECK + + 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" + + __STATUS 'pulling window from scratchpad to foreground' + i3-msg "[class=$CLIENT_CLASS] scratchpad show" + + __STATUS 'moving window to center of current screen' + i3-msg "[class=$CLIENT_CLASS] move position center" +} + +##################################################################### +LAUNCH_OR_SHOW $@ diff --git a/zsh/scwrypts/README.md b/zsh/scwrypts/README.md index 0879d88..f15c513 100644 --- a/zsh/scwrypts/README.md +++ b/zsh/scwrypts/README.md @@ -31,6 +31,26 @@ Inherited values are denoted by `# inherited from ` in the environm Nested children will inherit values from all parents. +### Special Environment Variable Syntax + +All environment variables which end in `__[a-z_]+` are ignored by the template file. +These environment variables *will propagate to children*, but will not be removed nor staged into the `.env.template`. + +#### `__select` Environment Variables +Omit any variable, but provide a comma-separated list with the `__select` suffix, and the user will be prompted to select a value from the provided options. + +In the following configuration, the user will be prompted to select an `AWS_REGION` once at the beginning of scwrypt execution: + +```zsh +export AWS_REGION= +export AWS_REGION__select=us-east-1,us-east-2,us-west-1,us-west-2 +``` + +Setting the `AWS_REGION` variable will cause scwrypts to ignore the `__select` syntax. + +CI will fail on select, because CI fails on any FZF prompt. + + ## Logs Quickly view or clear Scwrypts logs. diff --git a/zsh/scwrypts/environment/synchronize b/zsh/scwrypts/environment/synchronize index 52c3e12..65442ee 100755 --- a/zsh/scwrypts/environment/synchronize +++ b/zsh/scwrypts/environment/synchronize @@ -17,10 +17,12 @@ _SYNCHRONIZE() { [ ! $SLIENT ] && { __yN 'change the template before sync?' && __EDIT $__ENV_TEMPLATE - _SORT_ENV "$__ENV_TEMPLATE" - git add $__ENV_TEMPLATE >/dev/null 2>&1 } + _SORT_ENV "$__ENV_TEMPLATE" + sed -i '/__[a-z_]\+=$/d' "$__ENV_TEMPLATE" + git add $__ENV_TEMPLATE >/dev/null 2>&1 + ENVIRONMENTS=$(__GET_ENV_NAMES | sort -r) _CLEAR_INHERITED_VARIABLES @@ -68,6 +70,8 @@ _REMOVE_OLD_VARIABLES() { while read line do ENV_VAR=$(echo "$line" | sed 's/=.*/=/') + echo $ENV_VAR | grep -q '__[a-z_]\+=' && continue + grep -q "$ENV_VAR" "$__ENV_TEMPLATE" || { sed -i "\\%$ENV_VAR%d" "$ENV_FILE" echo "$ENV_VAR" | grep -qv '^#' \ @@ -139,14 +143,11 @@ _ADD_DESCRIPTIONS() { done done < <(sed -n '/^[^ ]\+ \+| /p' "$__ENV_TEMPLATE.descriptions") - while read ENV_VAR + for ENV_NAME in $(echo $ENVIRONMENTS) do - for ENV_NAME in $(echo $ENVIRONMENTS) - do - sed -i "/^export $ENV_VAR=/a \ " "$(__GET_ENV_FILE $ENV_NAME)" - sed -i "s/^ $//" "$(__GET_ENV_FILE $ENV_NAME)" - done - done < <(grep -B1 '^$' "$__ENV_TEMPLATE.descriptions" | grep '|' | awk '{print $1;}') + sed -i "/^# /i \ " "$(__GET_ENV_FILE $ENV_NAME)" + sed -i "s/^ $//" "$(__GET_ENV_FILE $ENV_NAME)" + done } ##################################################################### diff --git a/zsh/utils/environment.zsh b/zsh/utils/environment.zsh index 8a7b0e5..bef83b2 100644 --- a/zsh/utils/environment.zsh +++ b/zsh/utils/environment.zsh @@ -14,6 +14,12 @@ __CHECK_ENV_VAR() { local VALUE=$(eval echo '$'$NAME) [ $VALUE ] && return 0 + local SELECTION_VALUES=$(eval echo '$'$NAME'__select' | sed 's/,/\n/g') + [ $SELECTION_VALUES ] && { + local SELECTION=$(echo $SELECTION_VALUES | __FZF "select a value for '$NAME'") + [ $SELECTION ] && export VALUE=$SELECTION + } + [ $VALUE ] && return 0 [ $__SCWRYPT ] && { # scwrypts exclusive (missing vars staged in env.template) diff --git a/zsh/utils/io.zsh b/zsh/utils/io.zsh index f398b32..15589d0 100644 --- a/zsh/utils/io.zsh +++ b/zsh/utils/io.zsh @@ -37,7 +37,7 @@ __USAGE() { local USAGE_LINE=$(\ echo $USAGE \ | grep -i '^ *usage *:' \ - | sed "s;^[^:]*:;& scwrypts -- $SCWRYPT_NAME;" \ + | sed "s;^[^:]*:;& scwrypts $SCWRYPT_NAME --;" \ | sed 's/ \{2,\}/ /g; s/scwrypts -- scwrypts/scwrypts/' \ ) local THE_REST=$(echo $USAGE | grep -vi '^ *usage *:' | sed 'N;/^\n$/D;P;D;') @@ -85,7 +85,10 @@ __FZF() { exit 1 } - fzf -i --height=30% --layout=reverse --prompt "$1 : " ${@:2} + local SELECTION=$(fzf -i --height=30% --layout=reverse --prompt "$1 : " ${@:2}) + __PROMPT "$1" + echo $SELECTION >&2 + echo $SELECTION } __FZF_HEAD() { __FZF $@ --print-query | sed '/^$/d' | head -n1; } # prefer user input over selected __FZF_TAIL() { __FZF $@ --print-query | sed '/^$/d' | tail -n1; } # prefer selected over user input diff --git a/zsh/vim/vundle/common.zsh b/zsh/vim/vundle/common.zsh index 0521595..faf4eb9 100644 --- a/zsh/vim/vundle/common.zsh +++ b/zsh/vim/vundle/common.zsh @@ -4,7 +4,7 @@ source ${0:a:h}/../common.zsh ##################################################################### VUNDLE_PLUGIN_DIR="$HOME/.vim/bundle" -VUNDLE_BUILD_DEFINITIONS="$VUNDLE_PLUGIN_DIR/build.zsh" +VUNDLE_BUILD_DEFINITIONS="$SCWRYPTS_CONFIG_PATH/vundle.zsh" [ ! -f $VUNDLE_BUILD_DEFINITIONS ] && { {