feat/devflow
This commit is contained in:
parent
78ea031fd6
commit
60834ccae1
@ -1,99 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
#
|
|
||||||
# This file echoes a bunch of 24-bit color codes
|
|
||||||
# to the terminal to demonstrate its functionality.
|
|
||||||
# The foreground escape sequence is ^[38;2;<r>;<g>;<b>m
|
|
||||||
# The background escape sequence is ^[48;2;<r>;<g>;<b>m
|
|
||||||
# <r> <g> <b> range from 0 to 255 inclusive.
|
|
||||||
# The escape sequence ^[0m returns output to default
|
|
||||||
|
|
||||||
setBackgroundColor()
|
|
||||||
{
|
|
||||||
echo -en "\x1b[48;2;$1;$2;$3""m"
|
|
||||||
}
|
|
||||||
|
|
||||||
resetOutput()
|
|
||||||
{
|
|
||||||
echo -en "\x1b[0m\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Gives a color $1/255 % along HSV
|
|
||||||
# Who knows what happens when $1 is outside 0-255
|
|
||||||
# Echoes "$red $green $blue" where
|
|
||||||
# $red $green and $blue are integers
|
|
||||||
# ranging between 0 and 255 inclusive
|
|
||||||
rainbowColor()
|
|
||||||
{
|
|
||||||
let h=$1/43
|
|
||||||
let f=$1-43*$h
|
|
||||||
let t=$f*255/43
|
|
||||||
let q=255-t
|
|
||||||
|
|
||||||
if [ $h -eq 0 ]
|
|
||||||
then
|
|
||||||
echo "255 $t 0"
|
|
||||||
elif [ $h -eq 1 ]
|
|
||||||
then
|
|
||||||
echo "$q 255 0"
|
|
||||||
elif [ $h -eq 2 ]
|
|
||||||
then
|
|
||||||
echo "0 255 $t"
|
|
||||||
elif [ $h -eq 3 ]
|
|
||||||
then
|
|
||||||
echo "0 $q 255"
|
|
||||||
elif [ $h -eq 4 ]
|
|
||||||
then
|
|
||||||
echo "$t 0 255"
|
|
||||||
elif [ $h -eq 5 ]
|
|
||||||
then
|
|
||||||
echo "255 0 $q"
|
|
||||||
else
|
|
||||||
# execution should never reach here
|
|
||||||
echo "0 0 0"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
for i in `seq 0 127`; do
|
|
||||||
setBackgroundColor $i 0 0
|
|
||||||
echo -en " "
|
|
||||||
done
|
|
||||||
resetOutput
|
|
||||||
for i in `seq 255 128`; do
|
|
||||||
setBackgroundColor $i 0 0
|
|
||||||
echo -en " "
|
|
||||||
done
|
|
||||||
resetOutput
|
|
||||||
|
|
||||||
for i in `seq 0 127`; do
|
|
||||||
setBackgroundColor 0 $i 0
|
|
||||||
echo -n " "
|
|
||||||
done
|
|
||||||
resetOutput
|
|
||||||
for i in `seq 255 128`; do
|
|
||||||
setBackgroundColor 0 $i 0
|
|
||||||
echo -n " "
|
|
||||||
done
|
|
||||||
resetOutput
|
|
||||||
|
|
||||||
for i in `seq 0 127`; do
|
|
||||||
setBackgroundColor 0 0 $i
|
|
||||||
echo -n " "
|
|
||||||
done
|
|
||||||
resetOutput
|
|
||||||
for i in `seq 255 128`; do
|
|
||||||
setBackgroundColor 0 0 $i
|
|
||||||
echo -n " "
|
|
||||||
done
|
|
||||||
resetOutput
|
|
||||||
|
|
||||||
for i in `seq 0 127`; do
|
|
||||||
setBackgroundColor `rainbowColor $i`
|
|
||||||
echo -n " "
|
|
||||||
done
|
|
||||||
resetOutput
|
|
||||||
for i in `seq 255 128`; do
|
|
||||||
setBackgroundColor `rainbowColor $i`
|
|
||||||
echo -n " "
|
|
||||||
done
|
|
||||||
resetOutput
|
|
||||||
|
|
||||||
@ -1,97 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Test black and white
|
|
||||||
echo "=== Black and White ==="
|
|
||||||
printf "Normal text\n"
|
|
||||||
printf "\e[1mBold text\e[0m\n"
|
|
||||||
printf "\e[7mReverse text\e[0m\n\n"
|
|
||||||
|
|
||||||
# Test 4-bit ANSI (16 colors)
|
|
||||||
echo "=== 4-bit ANSI Colors (16 colors) ==="
|
|
||||||
echo "Foreground colors:"
|
|
||||||
for i in {30..37}; do
|
|
||||||
printf "\e[${i}m\\e[${i}m\e[0m "
|
|
||||||
done
|
|
||||||
echo -e "\n"
|
|
||||||
|
|
||||||
echo "Background colors:"
|
|
||||||
for i in {40..47}; do
|
|
||||||
printf "\e[${i}m\\e[${i}m\e[0m "
|
|
||||||
done
|
|
||||||
echo -e "\n"
|
|
||||||
|
|
||||||
echo "Bright foreground colors:"
|
|
||||||
for i in {90..97}; do
|
|
||||||
printf "\e[${i}m\\e[${i}m\e[0m "
|
|
||||||
done
|
|
||||||
echo -e "\n"
|
|
||||||
|
|
||||||
echo "Bright background colors:"
|
|
||||||
for i in {100..107}; do
|
|
||||||
printf "\e[${i}m\\e[${i}m\e[0m "
|
|
||||||
done
|
|
||||||
echo -e "\n\n"
|
|
||||||
|
|
||||||
# Test 8-bit ANSI (256 colors)
|
|
||||||
echo "=== 8-bit ANSI Colors (256 colors) ==="
|
|
||||||
echo "16 System Colors:"
|
|
||||||
for i in {0..15}; do
|
|
||||||
printf "\e[48;5;${i}m \e[0m"
|
|
||||||
if [ $((($i + 1) % 8)) == 0 ]; then
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo
|
|
||||||
|
|
||||||
echo "216 RGB Colors:"
|
|
||||||
for i in {16..231}; do
|
|
||||||
printf "\e[48;5;${i}m \e[0m"
|
|
||||||
if [ $((($i - 15) % 36)) == 0 ]; then
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo
|
|
||||||
|
|
||||||
echo "24 Grayscale Colors:"
|
|
||||||
for i in {232..255}; do
|
|
||||||
printf "\e[48;5;${i}m \e[0m"
|
|
||||||
if [ $((($i - 231) % 12)) == 0 ]; then
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo -e "\n"
|
|
||||||
|
|
||||||
# Test 24-bit true color
|
|
||||||
echo "=== 24-bit True Color (16.7 million colors) ==="
|
|
||||||
echo "RGB Color Gradient:"
|
|
||||||
awk 'BEGIN{
|
|
||||||
s="/\\";
|
|
||||||
for (colnum = 0; colnum<77; colnum++) {
|
|
||||||
r = 255-(colnum*255/76);
|
|
||||||
g = (colnum*510/76);
|
|
||||||
b = (colnum*255/76);
|
|
||||||
if (g>255) g = 510-g;
|
|
||||||
printf "\033[48;2;%d;%d;%dm", r,g,b;
|
|
||||||
printf "\033[38;2;%d;%d;%dm", 255-r,255-g,255-b;
|
|
||||||
printf "%s\033[0m", substr(s,colnum%2+1,1);
|
|
||||||
}
|
|
||||||
printf "\n";
|
|
||||||
}'
|
|
||||||
|
|
||||||
echo "RGB Color Bars:"
|
|
||||||
for r in 0 127 255; do
|
|
||||||
for g in 0 127 255; do
|
|
||||||
for b in 0 127 255; do
|
|
||||||
printf "\e[48;2;${r};${g};${b}m \e[0m"
|
|
||||||
done
|
|
||||||
printf " "
|
|
||||||
done
|
|
||||||
echo
|
|
||||||
done
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Print terminal information
|
|
||||||
echo "=== Terminal Information ==="
|
|
||||||
echo "TERM: $TERM"
|
|
||||||
echo "COLORTERM: $COLORTERM"
|
|
||||||
echo "Reported colors (tput colors): $(tput colors)"
|
|
||||||
@ -1,42 +1,84 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
source './parse_image_ref.sh'
|
set -e
|
||||||
|
|
||||||
REGISTRY="registry.tomastm.com"
|
source "/home/tomas/.local/bin/barg"
|
||||||
REGISTRY_ABBR="tm0"
|
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
SPEC=(
|
||||||
|
"command;flow;DevFlow CLI - Manage instances and development containers"
|
||||||
|
"note;Use 'flow <command> --help' for command-specific options"
|
||||||
|
|
||||||
|
"command;enter;Connect to a development instance via SSH"
|
||||||
|
"note;Target format: [user@]namespace@platform (e.g., 'personal@orb' or 'root@personal@orb')"
|
||||||
|
"argument;user,u;type:option;help:SSH user (overrides user in target)"
|
||||||
|
"argument;namespace,n;type:option;help:Instance namespace (overrides namespace in target)"
|
||||||
|
"argument;platform,p;type:option;help:Platform name (overrides platform in target)"
|
||||||
|
"argument;session,s;type:option;default:default;help:Development session name (default: 'default')"
|
||||||
|
"argument;no-tmux;type:flag;dest:no_tmux;default:false;help:Skip tmux attachment on connection"
|
||||||
|
"argument;dry-run,d;type:flag;dest:dry_run;default:false;help:Show SSH command without executing"
|
||||||
|
"argument;target,t;required;help:Target instance in format [user@]namespace@platform"
|
||||||
|
"argument;ssh-args;type:rest;dest:ssh_args;help:Additional SSH arguments (after --)"
|
||||||
|
"end"
|
||||||
|
|
||||||
|
"command;create;Create and start a new development container"
|
||||||
|
"argument;image,i;required;type:option;help:Container image to use (with optional tag)"
|
||||||
|
"argument;project,p;type:option;help:Path to local project directory"
|
||||||
|
"argument;name;required;help:Container name"
|
||||||
|
"end"
|
||||||
|
|
||||||
|
"command;exec;Execute a command or open a shell in a container"
|
||||||
|
"argument;name;required;help:Container name"
|
||||||
|
"argument;cmd;type:rest;help:Command to execute inside container (after --)"
|
||||||
|
"end"
|
||||||
|
|
||||||
|
"command;connect;Attach or switch to the container’s tmux session"
|
||||||
|
"note;When already inside tmux, switches to the target session instead of reattaching."
|
||||||
|
"note;New tmux panes or windows in the session automatically start inside the container."
|
||||||
|
"argument;from,f;type:option;dest:name;help:Optional source container name"
|
||||||
|
"argument;name;required;help:Target container name"
|
||||||
|
"end"
|
||||||
|
|
||||||
|
"command;list;Display all development containers and their status"
|
||||||
|
"end"
|
||||||
|
|
||||||
|
"command;stop;Stop or kill a running development container"
|
||||||
|
"argument;from;type:option;dest:name;help:Optional source container name"
|
||||||
|
"argument;kill;type:flag;help:Use kill instead of graceful stop"
|
||||||
|
"argument;name;required;help:Target container name"
|
||||||
|
"end"
|
||||||
|
|
||||||
|
"command;remove,rm;Remove a development container"
|
||||||
|
"argument;from;type:option;dest:name;help:Optional source container name"
|
||||||
|
"argument;force,f;type:flag;help:Force removal of container"
|
||||||
|
"argument;name;required;help:Target container name"
|
||||||
|
"end"
|
||||||
|
|
||||||
|
"command;respawn;Restart all tmux panes for a development session"
|
||||||
|
"argument;from;type:option;dest:name;help:Optional source container name"
|
||||||
|
"argument;name;required;help:Session or container name"
|
||||||
|
"end"
|
||||||
|
|
||||||
|
"command;test;Verify that the dev script is functioning"
|
||||||
|
"argument;from;type:option;dest:name;help:Optional source container name"
|
||||||
|
"argument;name;help:Target container name"
|
||||||
|
"end"
|
||||||
|
|
||||||
|
"end"
|
||||||
|
)
|
||||||
|
|
||||||
|
DEFAULT_REGISTRY="registry.tomastm.com"
|
||||||
|
DEFAULT_TAG="latest"
|
||||||
PROJECT_DIR="$HOME/projects"
|
PROJECT_DIR="$HOME/projects"
|
||||||
PROJECT_ABBR="p"
|
PROJECT_ABBR="p"
|
||||||
|
|
||||||
usage() {
|
|
||||||
cat <<'EOF'
|
|
||||||
Usage: dev <command> [options] <name>
|
|
||||||
|
|
||||||
Commands:
|
|
||||||
create -i, --image <image> -p, --project <path> <name>
|
|
||||||
exec <name> [-- <cmd>...]
|
|
||||||
connect <name>
|
|
||||||
list
|
|
||||||
info <name>
|
|
||||||
stop [--kill] <name>
|
|
||||||
rm [--force|-f] <name>
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
- 'exec' treats the LAST argument as <name>; everything before it is the command to run.
|
|
||||||
- If already inside tmux, 'connect' switches to the session; otherwise it attaches.
|
|
||||||
- New tmux panes/windows created in a session always run inside the container.
|
|
||||||
- within tmux that need <name>: info, stop, rm, restore, connect
|
|
||||||
EOF
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
fail() {
|
fail() {
|
||||||
printf 'Error: %s\n' "$*" >&2
|
printf 'Error: %b\n' "$*" >&2
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve_path() {
|
resolve_path() {
|
||||||
local path="$1"
|
local path="${1:-$(dirname "${BASH_SOURCE[0]}")}"
|
||||||
if command -v realpath >/dev/null 2>&1; then
|
if command -v realpath >/dev/null 2>&1; then
|
||||||
realpath "$path"
|
realpath "$path"
|
||||||
else
|
else
|
||||||
@ -44,14 +86,53 @@ resolve_path() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
docker_container_exists() {
|
# shellcheck disable=SC2178,SC2128
|
||||||
local name="$1"
|
parse_image_ref() {
|
||||||
docker container ls -a --format '{{.Names}}' | grep -Fqx "$name"
|
local input="$1"
|
||||||
|
|
||||||
|
local image_ref registry repo tag label
|
||||||
|
|
||||||
|
if [[ $input == */* ]]; then
|
||||||
|
local prefix="${input%%/*}"
|
||||||
|
if [[ "$prefix" == "docker" ]]; then
|
||||||
|
input="docker.io/library/${input#*/}"
|
||||||
|
elif [[ "$prefix" == "tm0" ]]; then
|
||||||
|
input="${DEFAULT_REGISTRY}/${input#*/}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
registry="${input%%/*}"
|
||||||
|
input=${input#*/}
|
||||||
|
else
|
||||||
|
registry="$DEFAULT_REGISTRY"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${input##*/}" == *:* ]]; then
|
||||||
|
tag="${input##*:}"
|
||||||
|
input="${input%:*}"
|
||||||
|
else
|
||||||
|
tag="$DEFAULT_TAG"
|
||||||
|
fi
|
||||||
|
|
||||||
|
repo="${registry}/${input}"
|
||||||
|
repo="${repo#*/}"
|
||||||
|
image_ref="${registry}/${repo}:${tag}"
|
||||||
|
|
||||||
|
label="${registry%.*}"
|
||||||
|
label="${label##*.}/${repo##*/}"
|
||||||
|
|
||||||
|
echo "$image_ref $repo $tag $label"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154,SC2155
|
||||||
|
docker_container_exists() {
|
||||||
|
local cname="$(get_cname)"
|
||||||
|
docker container ls -a --format '{{.Names}}' | grep -Fqx "$cname"
|
||||||
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154,SC2155
|
||||||
docker_container_running() {
|
docker_container_running() {
|
||||||
local name="$1"
|
local cname="$(get_cname)"
|
||||||
docker container ls --format '{{.Names}}' | grep -Fqx "$name"
|
docker container ls --format '{{.Names}}' | grep -Fqx "$cname"
|
||||||
}
|
}
|
||||||
|
|
||||||
docker_image_present() {
|
docker_image_present() {
|
||||||
@ -59,39 +140,98 @@ docker_image_present() {
|
|||||||
docker image inspect "$ref" >/dev/null 2>&1
|
docker image inspect "$ref" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154,SC2155
|
||||||
|
get_cname() {
|
||||||
|
printf "%s" "dev-${name_arg#dev-}"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd() {
|
||||||
|
barg_usage
|
||||||
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154,SC2155
|
||||||
|
cmd_enter() {
|
||||||
|
# VARS: user_arg, namespace_arg, platform_arg, target_arg, session_arg, no_tmux_arg, dry_run_arg, ssh_args_arg
|
||||||
|
|
||||||
|
# Do not run inside instance
|
||||||
|
if [[ -n "$DF_NAMESPACE" && -n "$DF_PLATFORM" ]]; then
|
||||||
|
fail "It is not recommended to run this command inside an instance.\nCurrently inside: $(tput bold)${DF_NAMESPACE}@${DF_PLATFORM}$(tput sgr0)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local -A CONFIG_HOST=(
|
||||||
|
[orb.host]="<namespace>@orb"
|
||||||
|
[utm.host]="<namespace>@utm.local"
|
||||||
|
[core.host]="<namespace>@core.lan"
|
||||||
|
)
|
||||||
|
|
||||||
|
local df_platform=""
|
||||||
|
local df_namespace=""
|
||||||
|
local df_user=""
|
||||||
|
|
||||||
|
# Parse target: get user, namespace, platform
|
||||||
|
if [[ "$target_arg" == "*@*" ]]; then
|
||||||
|
df_platform="${target_arg##*@}"
|
||||||
|
target_arg="${target_arg%@*}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$target_arg" == "*@*" ]]; then
|
||||||
|
df_namespace="${target_arg##*@}"
|
||||||
|
df_user="${target_arg%@*}"
|
||||||
|
else
|
||||||
|
df_namespace="${target_arg}"
|
||||||
|
df_user="${USER}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$platform_arg" ]]; then
|
||||||
|
df_platform="$platform_arg"
|
||||||
|
fi
|
||||||
|
if [[ -n "$namespace_arg" ]]; then
|
||||||
|
df_namespace="$namespace_arg"
|
||||||
|
fi
|
||||||
|
if [[ -n "$user_arg" ]]; then
|
||||||
|
df_user="$user_arg"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Resolve host, identity (maybe check what would the host be in order to use .ssh/config)
|
||||||
|
local host_config="${CONFIG_HOST[${df_platform}.host]}"
|
||||||
|
local ssh_host="${host_config//<namespace>/$df_namespace}"
|
||||||
|
if [[ -z "$ssh_host" ]]; then
|
||||||
|
fail "Invalid platform: ${df_platform}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build ssh cmd: ssh + identity + tmux + envs
|
||||||
|
local ssh_cmd=(ssh -tt "${df_user}@${ssh_host}")
|
||||||
|
|
||||||
|
if [[ "$no_tmux_arg" == "false" ]]; then
|
||||||
|
# TODO: instead of tmux,maybe use "flow" in order to attach to dev container too
|
||||||
|
ssh_cmd+=("tmux" "new-session" "-As" "$session_arg"
|
||||||
|
"-e" "DF_NAMESPACE=$df_namespace"
|
||||||
|
"-e" "DF_PLATFORM=$df_platform")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run or dryrun?
|
||||||
|
if [[ "$dry_run_arg" == "true" ]]; then
|
||||||
|
echo "Dry run command:"
|
||||||
|
printf '%q ' "${ssh_cmd[@]}"
|
||||||
|
echo
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "${ssh_cmd[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154,SC2155
|
||||||
cmd_create() {
|
cmd_create() {
|
||||||
local image_arg="" project_arg=""
|
# VARS: name_arg, image_arg, project_arg
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
# Check if container name already exists
|
||||||
case "$1" in
|
local cname="$(get_cname)"
|
||||||
-i | --image)
|
|
||||||
[[ $# -ge 2 ]] || fail "Missing value for $1"
|
|
||||||
image_arg="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
-p | --project)
|
|
||||||
[[ $# -ge 2 ]] || fail "Missing value for $1"
|
|
||||||
project_arg="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
-*) usage ;;
|
|
||||||
*) break ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
# Check args
|
|
||||||
local name_arg="${1:-}"
|
|
||||||
if [[ -z "$name_arg" || -z "$image_arg" || -z "$project_arg" ]]; then
|
|
||||||
fail "Missing arguments"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check container name
|
|
||||||
local cname="dev-$name_arg"
|
|
||||||
if docker_container_exists "$cname"; then
|
if docker_container_exists "$cname"; then
|
||||||
fail "Container already exists: "$cname" (from name "$name_arg")"
|
printf -v msg 'Container already exists: "%s" (from name "%s")' "$cname" "$name_arg"
|
||||||
|
fail "$msg"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check project path
|
# Check if project path is valid
|
||||||
local project_path
|
local project_path
|
||||||
project_path="$(resolve_path "$project_arg")"
|
project_path="$(resolve_path "$project_arg")"
|
||||||
if [[ ! -d "$project_path" ]]; then
|
if [[ ! -d "$project_path" ]]; then
|
||||||
@ -99,9 +239,10 @@ cmd_create() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Check image
|
# Check image
|
||||||
IFS=' ' read -r image_ref image_repo image_tag image_label <<<"$(parse_image_ref "$image_arg")"
|
IFS=' ' read -r image_ref _ _ _ <<<"$(parse_image_ref "$image_arg")"
|
||||||
if ! docker_image_present "$image_ref"; then
|
if ! docker_image_present "$image_ref"; then
|
||||||
fail $'Image not found locally.\nTry:\n\t- docker pull '"$image_ref"
|
printf -v msg 'Image not found locally.\nTry:\n\t- docker pull %s' "$image_ref"
|
||||||
|
fail "$msg"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Run (= create and start container)
|
# Run (= create and start container)
|
||||||
@ -109,6 +250,9 @@ cmd_create() {
|
|||||||
docker run -d
|
docker run -d
|
||||||
--name "$cname"
|
--name "$cname"
|
||||||
--label dev=true
|
--label dev=true
|
||||||
|
--label "dev.name=$name_arg"
|
||||||
|
--label "dev.project_path=$project_path"
|
||||||
|
--label "dev.image_ref=$image_ref"
|
||||||
--network host
|
--network host
|
||||||
--init # run tini as PID 1 to handle signals & reap zombies for cleaner container shutdown
|
--init # run tini as PID 1 to handle signals & reap zombies for cleaner container shutdown
|
||||||
-v "$project_path:/workspace"
|
-v "$project_path:/workspace"
|
||||||
@ -125,58 +269,14 @@ cmd_create() {
|
|||||||
cmd+=("$image_ref" sleep infinity)
|
cmd+=("$image_ref" sleep infinity)
|
||||||
"${cmd[@]}"
|
"${cmd[@]}"
|
||||||
|
|
||||||
echo "$cname"
|
printf "Created and started container: %s" "$cname"
|
||||||
}
|
|
||||||
|
|
||||||
cmd_exec() {
|
|
||||||
# usage: exec <name> [-- <cmd>...]
|
|
||||||
|
|
||||||
local name="$1"
|
|
||||||
[[ -n "$name" ]] || fail "Missing project name"
|
|
||||||
shift
|
|
||||||
|
|
||||||
local cname="dev-$name"
|
|
||||||
if ! docker_container_running "$cname"; then
|
|
||||||
fail "Container $cname not running"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$1" == "--" ]]; then
|
|
||||||
shift
|
|
||||||
local args=("$@")
|
|
||||||
if [[ -t 1 ]]; then
|
|
||||||
docker exec -it "$cname" "${args[@]}"
|
|
||||||
else
|
|
||||||
docker exec "$cname" "${args[@]}"
|
|
||||||
fi
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# No command provided -> open a shell
|
|
||||||
docker exec -it "$cname" zsh -l ||
|
|
||||||
docker exec -it "$cname" bash -l ||
|
|
||||||
docker exec -it "$cname" sh
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154,SC2155
|
||||||
cmd_connect() {
|
cmd_connect() {
|
||||||
# usage: connect [--from] <name>
|
# VARS: name_arg
|
||||||
|
|
||||||
local from_name=""
|
local cname="$(get_cname)"
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case "$1" in
|
|
||||||
-f | --from)
|
|
||||||
[[ $# -ge 2 ]] || fail "Missing value for $1"
|
|
||||||
from_name="$2"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
-*) usage ;;
|
|
||||||
*) break ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
local name="${1:from_name}"
|
|
||||||
[[ -n "$name" ]] || fail "Missing project name"
|
|
||||||
|
|
||||||
local cname="dev-$name"
|
|
||||||
if ! docker_container_exists "$cname"; then
|
if ! docker_container_exists "$cname"; then
|
||||||
fail "Container does not exist: ${cname}. Run: dev create ..."
|
fail "Container does not exist: ${cname}. Run: dev create ..."
|
||||||
fi
|
fi
|
||||||
@ -187,41 +287,79 @@ cmd_connect() {
|
|||||||
|
|
||||||
if ! command -v tmux >/dev/null 2>&1; then
|
if ! command -v tmux >/dev/null 2>&1; then
|
||||||
echo "tmux not found; falling back to direct exec"
|
echo "tmux not found; falling back to direct exec"
|
||||||
exec "$0" exec "$name"
|
exec "$0" exec "$cname"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local image_ref
|
local image_ref
|
||||||
image_ref="$(docker container inspect "$cname" --format '{{ .Config.Image }}')"
|
image_ref="$(docker container inspect "$cname" --format '{{ .Config.Image }}')"
|
||||||
IFS=' ' read -r _image_ref image_repo image_tag image_label <<<"$(parse_image_ref "$image_ref")"
|
IFS=' ' read -r _image_ref _ _ image_label <<<"$(parse_image_ref "$image_ref")"
|
||||||
|
|
||||||
local tname="dev:$name"
|
if ! tmux has-session -t "$cname" 2>/dev/null; then
|
||||||
if ! tmux has-session -t "$tname" 2>/dev/null; then
|
tmux new-session -ds "$cname" \
|
||||||
tmux new-session -ds "$tname" -e "DEV_IMAGE=$image_label" "$0 exec \"$name\""
|
-e "DF_IMAGE=$image_label" \
|
||||||
tmux set-option -t "$tname" default-command "$0 exec \"$name\""
|
-e "DF_NAMESPACE=$DF_NAMESPACE" \
|
||||||
|
-e "DF_PLATFORM=$DF_PLATFORM" \
|
||||||
|
"$0 exec \"$name_arg\""
|
||||||
|
tmux set-option -t "$cname" default-command "$0 exec \"$name_arg\""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n "${TMUX-}" ]]; then
|
if [[ -n "${TMUX-}" ]]; then
|
||||||
tmux switch-client -t "$tname"
|
tmux switch-client -t "$cname"
|
||||||
else
|
else
|
||||||
tmux attach -t "$tname"
|
tmux attach -t "$cname"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154,SC2155
|
||||||
|
cmd_exec() {
|
||||||
|
# VARS: name_arg, cmd_arg
|
||||||
|
|
||||||
|
local cname="$(get_cname)"
|
||||||
|
if ! docker_container_running "$cname"; then
|
||||||
|
fail "Container $cname not running"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$cmd_arg" ]]; then
|
||||||
|
if [[ -t 0 ]]; then
|
||||||
|
docker exec -it "$cname" "${cmd_arg}"
|
||||||
|
else
|
||||||
|
docker exec "$cname" "${cmd_arg}"
|
||||||
|
fi
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# No command provided -> open a shell
|
||||||
|
docker exec --detach-keys "ctrl-q,ctrl-p" -it "$cname" zsh -l ||
|
||||||
|
docker exec --detach-keys "ctrl-q,ctrl-p" -it "$cname" bash -l ||
|
||||||
|
docker exec --detach-keys "ctrl-q,ctrl-p" -it "$cname" sh
|
||||||
|
}
|
||||||
|
|
||||||
shorten_project_path() {
|
shorten_project_path() {
|
||||||
local project="$1"
|
local project=$1
|
||||||
|
local home=${HOME%/}
|
||||||
|
local projdir=${PROJECT_DIR%/}
|
||||||
|
|
||||||
# Case 1: path is under PROJECT_DIR
|
# Case 1: under PROJECT_DIR
|
||||||
if [[ "$project" == "$PROJECT_DIR"* ]]; then
|
if [[ -n ${projdir} && $project == "$projdir"/* ]]; then
|
||||||
project="~/$PROJECT_ABBR${project#$PROJECT_DIR}"
|
# shellcheck disable=SC2088
|
||||||
# Case 2: path is under HOME (but not PROJECT_DIR)
|
project="~/$PROJECT_ABBR${project#"$projdir"}"
|
||||||
elif [[ "$project" == "$HOME"* ]]; then
|
|
||||||
project="~${project#$HOME}"
|
# Case 2: equals HOME
|
||||||
|
elif [[ $project == "$home" ]]; then
|
||||||
|
project="~"
|
||||||
|
|
||||||
|
# Case 3: under HOME (but not PROJECT_DIR)
|
||||||
|
elif [[ $project == "$home"/* ]]; then
|
||||||
|
project="~${project#"$home"}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "$project"
|
printf '%s\n' "$project"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154,SC2155
|
||||||
cmd_list() {
|
cmd_list() {
|
||||||
|
# VARS:
|
||||||
|
|
||||||
{
|
{
|
||||||
echo "NAME|IMAGE|PROJECT|STATUS"
|
echo "NAME|IMAGE|PROJECT|STATUS"
|
||||||
docker ps -a --filter "label=dev=true" \
|
docker ps -a --filter "label=dev=true" \
|
||||||
@ -237,65 +375,65 @@ cmd_list() {
|
|||||||
done | column -t -s '|'
|
done | column -t -s '|'
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_stop() {
|
tmux_fallback_to_default_if_in_session() {
|
||||||
local kill_flag=0
|
# If inside tmux and current session matches the given one,
|
||||||
while [[ $# -gt 0 ]]; do
|
# switch to or create 'default' before proceeding.
|
||||||
case "$1" in
|
local target_session="$1"
|
||||||
--kill)
|
|
||||||
kill_flag=1
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-*) usage ;;
|
|
||||||
*) break ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
local name="${1:-}"
|
|
||||||
[[ -n "$name" ]] || fail "Missing project name"
|
|
||||||
local cname="dev-$name"
|
|
||||||
|
|
||||||
|
[[ -z "${TMUX-}" ]] && return 0 # not in tmux, nothing to do
|
||||||
|
|
||||||
|
local current_session
|
||||||
|
current_session="$(tmux display-message -p '#S')"
|
||||||
|
|
||||||
|
if [[ "$current_session" == "$target_session" ]]; then
|
||||||
|
if ! tmux has-session -t default 2>/dev/null; then
|
||||||
|
tmux new-session -ds default
|
||||||
|
fi
|
||||||
|
tmux switch-client -t default
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154,SC2155
|
||||||
|
cmd_stop() {
|
||||||
|
# VARS: kill_arg name_arg
|
||||||
|
local cname
|
||||||
|
cname="$(get_cname)"
|
||||||
docker_container_exists "$cname" || fail "Container $cname does not exist"
|
docker_container_exists "$cname" || fail "Container $cname does not exist"
|
||||||
|
|
||||||
if ((kill_flag)); then
|
if [[ "$kill_arg" == "true" ]]; then
|
||||||
echo "Killing container $cname..."
|
echo "Killing container $cname..."
|
||||||
docker kill "$cname"
|
docker kill "$cname"
|
||||||
else
|
else
|
||||||
echo "Stopping container $cname..."
|
echo "Stopping container $cname..."
|
||||||
docker stop "$cname"
|
docker stop "$cname"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
tmux_fallback_to_default_if_in_session "$cname"
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_rm() {
|
# shellcheck disable=SC2154,SC2155
|
||||||
local force_flag=0
|
cmd_remove() {
|
||||||
while [[ $# -gt 0 ]]; do
|
# VARS: force_arg name_arg
|
||||||
case "$1" in
|
local cname
|
||||||
--force | -f)
|
cname="$(get_cname)"
|
||||||
force_flag=1
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-*) usage ;;
|
|
||||||
*) break ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
local name="${1:-}"
|
|
||||||
[[ -n "$name" ]] || fail "Missing project name"
|
|
||||||
local cname="dev-$name"
|
|
||||||
|
|
||||||
docker_container_exists "$cname" || fail "Container $cname does not exist"
|
docker_container_exists "$cname" || fail "Container $cname does not exist"
|
||||||
|
|
||||||
if ((force_flag)); then
|
if [[ "$force_arg" == "true" ]]; then
|
||||||
echo "Removing container $cname (force)..."
|
echo "Removing container $cname (force)..."
|
||||||
docker rm -f "$cname"
|
docker rm -f "$cname"
|
||||||
else
|
else
|
||||||
echo "Removing container $cname..."
|
echo "Removing container $cname..."
|
||||||
docker rm "$cname"
|
docker rm "$cname"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
tmux_fallback_to_default_if_in_session "$cname"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154,SC2155
|
||||||
cmd_respawn() {
|
cmd_respawn() {
|
||||||
local name="${1:-}"
|
# VARS: name_arg
|
||||||
[[ -n "$name" ]] || fail "Missing project name"
|
local cname
|
||||||
local cname="dev-$name"
|
cname="$(get_cname)"
|
||||||
|
|
||||||
panes=$(tmux list-panes -t "$cname" -s -F "#{session_name}:#{window_index}.#{pane_index}")
|
panes=$(tmux list-panes -t "$cname" -s -F "#{session_name}:#{window_index}.#{pane_index}")
|
||||||
|
|
||||||
for pane in $panes; do
|
for pane in $panes; do
|
||||||
@ -304,24 +442,15 @@ cmd_respawn() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154,SC2155
|
||||||
cmd_test() {
|
cmd_test() {
|
||||||
|
# VARS: name_arg
|
||||||
|
|
||||||
echo "Script dev is working fine!"
|
echo "Script dev is working fine!"
|
||||||
|
if [[ -n "$name_arg" ]]; then
|
||||||
|
get_cname
|
||||||
|
fi
|
||||||
|
echo
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
barg_run SPEC[@] "$@"
|
||||||
local cmd="${1:-}"
|
|
||||||
shift || true
|
|
||||||
case "$cmd" in
|
|
||||||
create) cmd_create "$@" ;;
|
|
||||||
connect) cmd_connect "$@" ;;
|
|
||||||
exec) cmd_exec "$@" ;;
|
|
||||||
list) cmd_list ;;
|
|
||||||
stop) cmd_stop "$@" ;;
|
|
||||||
rm) cmd_rm "$@" ;;
|
|
||||||
respawn) cmd_respawn "$@" ;;
|
|
||||||
test) cmd_test "$@" ;;
|
|
||||||
*) usage ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
||||||
|
|||||||
@ -1,34 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
REGISTRY="registry.tomastm.com"
|
|
||||||
DEFAULT_IMAGE="base-debian"
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
echo "Usage: $0 -i <image>"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse arguments
|
|
||||||
while getopts ":i:" opt; do
|
|
||||||
case ${opt} in
|
|
||||||
i )
|
|
||||||
IMAGE="${OPTARG}"
|
|
||||||
;;
|
|
||||||
\? )
|
|
||||||
usage
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
IMAGE="${IMAGE:-$DEFAULT_IMAGE}"
|
|
||||||
FULL_IMAGE_NAME="${REGISTRY}/${IMAGE}"
|
|
||||||
|
|
||||||
docker run --rm -it \
|
|
||||||
--network host \
|
|
||||||
-v "$HOME/.ssh:/home/dev/.ssh" \
|
|
||||||
-v "$PWD:/workspace" \
|
|
||||||
--init \
|
|
||||||
--entrypoint /bin/zsh \
|
|
||||||
"$FULL_IMAGE_NAME"
|
|
||||||
12
config/shared/bin/dev-tmux-wrapper.sh
Executable file
12
config/shared/bin/dev-tmux-wrapper.sh
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
/home/tomas/bin/dev "$@" 2>&1
|
||||||
|
exit_code=$?
|
||||||
|
|
||||||
|
if [ $exit_code -ne 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "Command: $*"
|
||||||
|
echo "Failed: exit $exit_code"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $exit_code
|
||||||
@ -1,7 +0,0 @@
|
|||||||
# tempfile=$(mktemp) \
|
|
||||||
# && curl -o $tempfile https://raw.githubusercontent.com/wezterm/wezterm/master/termwiz/data/wezterm.terminfo \
|
|
||||||
# && tic -x -o ~/.terminfo $tempfile \
|
|
||||||
# && rm $tempfile
|
|
||||||
|
|
||||||
printf "\x1b[58:2::255:0:0m\x1b[4:1msingle\x1b[4:2mdouble\x1b[4:3mcurly\x1b[4:4mdotted\x1b[4:5mdashed\x1b[0m\n"
|
|
||||||
|
|
||||||
@ -1,117 +1,48 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
#
|
|
||||||
# This file echoes a bunch of 24-bit color codes
|
|
||||||
# to the terminal to demonstrate its functionality.
|
|
||||||
# The foreground escape sequence is ^[38;2;<r>;<g>;<b>m
|
|
||||||
# The background escape sequence is ^[48;2;<r>;<g>;<b>m
|
|
||||||
# <r> <g> <b> range from 0 to 255 inclusive.
|
|
||||||
# The escape sequence ^[0m returns output to default
|
|
||||||
|
|
||||||
setBackgroundColor()
|
echo
|
||||||
{
|
|
||||||
echo -en "\x1b[48;2;$1;$2;$3""m"
|
|
||||||
}
|
|
||||||
|
|
||||||
resetOutput()
|
|
||||||
{
|
|
||||||
echo -en "\x1b[0m\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Gives a color $1/255 % along HSV
|
|
||||||
# Who knows what happens when $1 is outside 0-255
|
|
||||||
# Echoes "$red $green $blue" where
|
|
||||||
# $red $green and $blue are integers
|
|
||||||
# ranging between 0 and 255 inclusive
|
|
||||||
rainbowColor()
|
|
||||||
{
|
|
||||||
let h=$1/43
|
|
||||||
let f=$1-43*$h
|
|
||||||
let t=$f*255/43
|
|
||||||
let q=255-t
|
|
||||||
|
|
||||||
if [ $h -eq 0 ]
|
|
||||||
then
|
|
||||||
echo "255 $t 0"
|
|
||||||
elif [ $h -eq 1 ]
|
|
||||||
then
|
|
||||||
echo "$q 255 0"
|
|
||||||
elif [ $h -eq 2 ]
|
|
||||||
then
|
|
||||||
echo "0 255 $t"
|
|
||||||
elif [ $h -eq 3 ]
|
|
||||||
then
|
|
||||||
echo "0 $q 255"
|
|
||||||
elif [ $h -eq 4 ]
|
|
||||||
then
|
|
||||||
echo "$t 0 255"
|
|
||||||
elif [ $h -eq 5 ]
|
|
||||||
then
|
|
||||||
echo "255 0 $q"
|
|
||||||
else
|
|
||||||
# execution should never reach here
|
|
||||||
echo "0 0 0"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
for i in `seq 0 127`; do
|
|
||||||
setBackgroundColor $i 0 0
|
|
||||||
echo -en " "
|
|
||||||
done
|
|
||||||
resetOutput
|
|
||||||
for i in `seq 255 128`; do
|
|
||||||
setBackgroundColor $i 0 0
|
|
||||||
echo -en " "
|
|
||||||
done
|
|
||||||
resetOutput
|
|
||||||
|
|
||||||
for i in `seq 0 127`; do
|
|
||||||
setBackgroundColor 0 $i 0
|
|
||||||
echo -n " "
|
|
||||||
done
|
|
||||||
resetOutput
|
|
||||||
for i in `seq 255 128`; do
|
|
||||||
setBackgroundColor 0 $i 0
|
|
||||||
echo -n " "
|
|
||||||
done
|
|
||||||
resetOutput
|
|
||||||
|
|
||||||
for i in `seq 0 127`; do
|
|
||||||
setBackgroundColor 0 0 $i
|
|
||||||
echo -n " "
|
|
||||||
done
|
|
||||||
resetOutput
|
|
||||||
for i in `seq 255 128`; do
|
|
||||||
setBackgroundColor 0 0 $i
|
|
||||||
echo -n " "
|
|
||||||
done
|
|
||||||
resetOutput
|
|
||||||
|
|
||||||
for i in `seq 0 127`; do
|
|
||||||
setBackgroundColor `rainbowColor $i`
|
|
||||||
echo -n " "
|
|
||||||
done
|
|
||||||
resetOutput
|
|
||||||
for i in `seq 255 128`; do
|
|
||||||
setBackgroundColor `rainbowColor $i`
|
|
||||||
echo -n " "
|
|
||||||
done
|
|
||||||
resetOutput
|
|
||||||
|
|
||||||
echo -e "Another test:"
|
|
||||||
awk 'BEGIN{
|
awk 'BEGIN{
|
||||||
s="/\\/\\/\\/\\/";
|
s="/\\/\\/\\/\\/\\"; s=s s s s s s s s;
|
||||||
for (colnum = 0; colnum<77; colnum++) {
|
for (colnum = 0; colnum<77; colnum++) {
|
||||||
r = 255-(colnum*255/76);
|
r = 255-(colnum*255/76);
|
||||||
g = (colnum*510/76);
|
g = (colnum*510/76);
|
||||||
b = (colnum*255/76);
|
b = (colnum*255/76);
|
||||||
if (g>255) g = 510-g;
|
if (g>255) g = 510-g;
|
||||||
printf "\033[48;2;%d;%d;%dm", r,g,b;
|
printf "\033[48;2;%d;%d;%dm", r,g,b;
|
||||||
printf "%s\033[0m", substr(s,(colnum%4)+1,1);
|
printf "\033[38;2;%d;%d;%dm", 255-r,255-g,255-b;
|
||||||
|
printf "%s\033[0m", substr(s,colnum+1,1);
|
||||||
}
|
}
|
||||||
printf "\n";
|
printf "\n";
|
||||||
}'
|
}'
|
||||||
|
|
||||||
echo -e "\nTerm: $(echo "$TERM")"
|
# --- Environment diagnostics -------------------------------------------------
|
||||||
echo "$(tmux info | grep -e RGB -e Tc)"
|
echo
|
||||||
echo -e "\nTmux server options:\n$(tmux show-options -s | grep terminal)"
|
echo "──────────────────────────────"
|
||||||
echo ""
|
echo " Environment and Tmux Details "
|
||||||
|
echo "──────────────────────────────"
|
||||||
|
echo "TERM: ${TERM}"
|
||||||
|
echo "COLORTERM: ${COLORTERM:-undefined}"
|
||||||
|
echo
|
||||||
|
|
||||||
|
if command -v tmux >/dev/null && tmux info &>/dev/null; then
|
||||||
|
echo "Tmux RGB/Tc capabilities:"
|
||||||
|
tmux info | grep -E "RGB|Tc" || echo "(none found)"
|
||||||
|
echo
|
||||||
|
echo "Tmux server terminal options:"
|
||||||
|
tmux show-options -s | grep terminal || echo "(none found)"
|
||||||
|
else
|
||||||
|
echo "Tmux not running or unavailable."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Underline capability test -----------------------------------------------
|
||||||
|
echo
|
||||||
|
echo "Underline styles test:"
|
||||||
|
printf '\x1b[58:2::255:0:0m' # red underline color
|
||||||
|
printf '\x1b[4:1msingle ' # single underline
|
||||||
|
printf '\x1b[4:2mdouble ' # double underline
|
||||||
|
printf '\x1b[4:3mcurly ' # curly underline
|
||||||
|
printf '\x1b[4:4mdotted ' # dotted underline
|
||||||
|
printf '\x1b[4:5mdashed ' # dashed underline
|
||||||
|
printf '\x1b[0m\n'
|
||||||
|
|
||||||
|
echo
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
Subproject commit 173ff5e47a9b780a25e021efb451a6a3c8669cea
|
Subproject commit 8687a1cf31bb6b28d3c234ffb308c25f14c02f52
|
||||||
@ -20,14 +20,16 @@ set -g mouse on
|
|||||||
set -g set-titles on
|
set -g set-titles on
|
||||||
set -g set-titles-string "#S"
|
set -g set-titles-string "#S"
|
||||||
|
|
||||||
|
# set -g remain-on-exit on
|
||||||
|
|
||||||
set -gw pane-base-index 1 # pane index
|
set -gw pane-base-index 1 # pane index
|
||||||
|
|
||||||
##### Appearance #####
|
##### Appearance #####
|
||||||
set -g status-style fg=black,bg=default
|
set -g status-style fg=black,bg=default
|
||||||
set -g window-status-current-style fg=blue,bold
|
set -g window-status-current-style fg=blue,bold
|
||||||
set -g message-style fg=blue,bg=default
|
set -g message-style fg=blue,bg=default
|
||||||
set -g status-left "#[fg=blue,bold][#S] "
|
set -g status-left "#[fg=blue,bold][#{s/^dev-//:#{session_name}}] "
|
||||||
set -g status-right "host:#H | machine:#{?TARGET_MACHINE,#{TARGET_MACHINE},local}"
|
set -g status-right " #{?DF_IMAGE,#{DF_IMAGE} | ,}#{?DF_NAMESPACE,#{DF_NAMESPACE},#H}@#{?DF_PLATFORM,#{DF_PLATFORM},local}"
|
||||||
set -g status-left-length 50
|
set -g status-left-length 50
|
||||||
set -g status-right-length 50
|
set -g status-right-length 50
|
||||||
set -g pane-active-border-style fg=blue
|
set -g pane-active-border-style fg=blue
|
||||||
@ -58,3 +60,9 @@ bind c confirm-before -p "kill-pane \#P? (y/n)" kill-pane
|
|||||||
##### Misc #####
|
##### Misc #####
|
||||||
bind r source-file ~/.tmux.conf \; display "Reloaded!"
|
bind r source-file ~/.tmux.conf \; display "Reloaded!"
|
||||||
|
|
||||||
|
unbind d
|
||||||
|
bind e detach
|
||||||
|
|
||||||
|
bind d command-prompt -I "dev " 'run-shell "/home/tomas/bin/dev-tmux-wrapper.sh %1 --from #{session_name}"'
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user