1073 lines
32 KiB
Bash
Executable File
1073 lines
32 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
NAME="kfg"
|
|
VERSION="0.15"
|
|
|
|
HOME_PATH="$HOME"
|
|
TMP_PATH="$HOME_PATH/.tmp/kfg_install"
|
|
CONFIG_PATH="$HOME_PATH/.config"
|
|
BINARY_PATH="/usr/bin"
|
|
RC_FILE=".zshrc"
|
|
|
|
ASK="\e[38;5;180m"
|
|
INFO="\e[38;5;39m"
|
|
ADD="\e[32m\e[1m"
|
|
ERROR="\033[0;31m"
|
|
DEBUG="\e[33m"
|
|
ENDCOLOR="\e[0m"
|
|
|
|
declare -A TOOLS || typeset -A TOOLS
|
|
|
|
TOOLS[all]="Install everything"
|
|
TOOLS[zsh]="Powerful Shell"
|
|
TOOLS[tmux]="Terminal Multiplexer - https://github.com/tmux/tmux"
|
|
TOOLS[unp]="Perl script to make file archive extraction easier"
|
|
TOOLS[bat]="cat replacement with syntax highlighting and git integration - https://github.com/sharkdp/bat"
|
|
TOOLS[lsd]="ls replacement with colors, icons, tree-view and more - https://github.com/lsd-rs/lsd"
|
|
TOOLS[omp]="Customisable shell prompt renderer - https://github.com/jandedobbeleer/oh-my-pos"
|
|
TOOLS[zoxide]="A smarter cd command. - https://github.com/ajeetdsouza/zoxide"
|
|
TOOLS[fzf]="A command-line fuzzy finder - https://github.com/junegunn/fzf"
|
|
TOOLS[fzf-tab]="Replace zsh's default completion selection menu with fzf - https://github.com/Aloxaf/fzf-tab"
|
|
TOOLS[zoom]="Conference platform Zoom - https://eu01web.zoom.us/"
|
|
TOOLS[nvim]="Neovim a modal terminal editor - https://github.com/neovim/neovim/"
|
|
TOOLS[nu]="Nushell - a new type of shell that works with data structures - https://github.com/nushell/nushell/"
|
|
|
|
function show_help_name {
|
|
echo "$NAME v$VERSION"
|
|
}
|
|
|
|
function show_help_cmd {
|
|
echo -e "cmd := {
|
|
${INFO}update${ENDCOLOR} \t\t Update $NAME,
|
|
${INFO}install${ENDCOLOR}\t\t Install configs :),
|
|
${INFO}version${ENDCOLOR}\t\t Print the version number
|
|
}\n"
|
|
}
|
|
|
|
function show_help_opt {
|
|
echo -en "opt := {
|
|
${INFO}-h${ENDCOLOR} | ${INFO}--help${ENDCOLOR} \t\t Show this help,
|
|
${INFO}-y${ENDCOLOR} | ${INFO}--yes${ENDCOLOR} \t\t Skip confirmation questions,
|
|
${INFO}-a${ENDCOLOR} | ${INFO}--arch STRING${ENDCOLOR} \t Set the architecture string to be used when downloading files from repositories. Most common are \"amd64\", \"arm64\", \"armhf\", etc,
|
|
${INFO}-d${ENDCOLOR} | ${INFO}--debug${ENDCOLOR}\t\t Print debug output,
|
|
}\n"
|
|
}
|
|
|
|
function show_help {
|
|
show_help_name
|
|
echo -e "Usage: ${INFO}${NAME}${ENDCOLOR} cmd [ opt ... ]\n"
|
|
show_help_cmd
|
|
show_help_opt
|
|
exit 2
|
|
}
|
|
|
|
function version {
|
|
echo "v$VERSION"
|
|
}
|
|
|
|
function log {
|
|
color "$1" "[$2]"
|
|
echo "$3"
|
|
}
|
|
|
|
function log_add {
|
|
log "$ADD" "+" "$1"
|
|
}
|
|
|
|
function log_info {
|
|
log "$INFO" "*" "$1"
|
|
}
|
|
|
|
function log_error {
|
|
log "$ERROR" "!" "$1" >&2
|
|
}
|
|
|
|
function err {
|
|
log_error "Error: $1"
|
|
exit 1
|
|
}
|
|
|
|
function log_debug {
|
|
if [ -z "$P_Debug" ]; then return 0; fi
|
|
log "$DEBUG" "~" "$1"
|
|
}
|
|
|
|
function ask {
|
|
color "$ASK" "[?]"
|
|
read -d '' -p "$1 [Y/n] " -N 1 -r
|
|
}
|
|
|
|
function color {
|
|
echo -en "$1$2$ENDCOLOR "
|
|
}
|
|
|
|
function user_confirm {
|
|
if [ -n "$P_Yes" ]; then return 0; fi
|
|
ask "$1"
|
|
while true; do
|
|
if [[ ! $REPLY =~ ^[$'\n']$ ]]; then echo -e -n "\n"; fi
|
|
case $REPLY in
|
|
[Yy$'\n']* ) return 0;;
|
|
[Nn]* ) return 1;;
|
|
* ) ask "Please enter";;
|
|
esac
|
|
done
|
|
}
|
|
|
|
function user_confirm_overwrite {
|
|
user_confirm "$1 already exists. Do you want to overwrite?"
|
|
return $?
|
|
}
|
|
|
|
function download_config {
|
|
if [ -z "$P_CONFIG" ]; then return 0; fi
|
|
mkdir -p "$CONFIG_PATH/$1/"
|
|
|
|
contains_path="${2%*/*}"
|
|
if [ -z "$contains_path" ]; then
|
|
mkdir -p "$CONFIG_PATH/$1/$contains_path/"
|
|
fi
|
|
|
|
FILE="$CONFIG_PATH/$1/$2"
|
|
if [ ! -e "$FILE" ] || user_confirm_overwrite "$FILE"; then
|
|
download "$3" "$FILE"
|
|
#wget -O "$FILE" "$3" > /dev/null 2>&1
|
|
log_add "Added $FILE"
|
|
fi
|
|
}
|
|
|
|
function install_rc_file {
|
|
local _file=$1
|
|
install_rc "[ -f "${_file}" ] && source "${_file}""
|
|
}
|
|
|
|
function install_rc_download {
|
|
local _folder _filename _file _remote_file
|
|
_folder=$1
|
|
_filename=$2
|
|
_remote_file=$3
|
|
# This is the config file
|
|
_file="$CONFIG_PATH/$_folder/$_filename"
|
|
|
|
if [ -z "$P_RC" ]; then return 0; fi
|
|
# Make sure the directory exists
|
|
mkdir -p "$CONFIG_PATH/$_folder/"
|
|
|
|
|
|
# Does the file already exist? or does the user want to overwrite it?
|
|
if [ ! -e "$_file" ] || user_confirm_overwrite "$_file"; then
|
|
# Download the file and save it
|
|
download "$_remote_file" "$_file"
|
|
log_add "Added $_file"
|
|
fi
|
|
|
|
install_rc_file "$_file"
|
|
}
|
|
|
|
function install_rc {
|
|
if [ -z "$P_RC" ]; then return 0; fi
|
|
# Add the file to the rc file as source $file
|
|
SOURCE_CMD="$1"
|
|
RC="$HOME_PATH/$RC_FILE"
|
|
if ! cat "$RC" | grep "$SOURCE_CMD" > /dev/null; then
|
|
echo "$SOURCE_CMD" >> "$RC"
|
|
log_add "Added \"$SOURCE_CMD\" to $RC"
|
|
else
|
|
log_debug "\"$SOURCE_CMD\" already in $RC"
|
|
fi
|
|
|
|
# Add the file to the rc file as source $file in root
|
|
RC_ROOT="/root/$RC_FILE"
|
|
if ! sudo cat "$RC_ROOT" | grep "$SOURCE_CMD" > /dev/null; then
|
|
echo "$SOURCE_CMD" | sudo tee -a "$RC_ROOT"
|
|
log_add "Added \"$SOURCE_CMD\" to $RC_ROOT"
|
|
else
|
|
log_debug "\"$SOURCE_CMD\" already in $RC_ROOT"
|
|
fi
|
|
}
|
|
|
|
function prepend_rc {
|
|
# Add the file to the rc file as source $file
|
|
SOURCE_CMD="$1"
|
|
RC="$HOME_PATH/$RC_FILE"
|
|
local out=`grep -Fox "${SOURCE_CMD}" "$RC"`
|
|
if [ -z "$out" ]; then
|
|
sed -i "1i${SOURCE_CMD//$'\n'/\\n}" "$RC"
|
|
log_add "Added \"$SOURCE_CMD\" to $RC"
|
|
else
|
|
log_debug "\"$SOURCE_CMD\" already in $RC"
|
|
fi
|
|
}
|
|
|
|
function download {
|
|
local _url=$1
|
|
local _path=$2
|
|
local _result
|
|
|
|
if check_cmd wget; then
|
|
_dld=wget
|
|
elif check_cmd curl; then
|
|
_dld=curl
|
|
else
|
|
need_cmd 'curl or wget'
|
|
fi
|
|
|
|
if [ -n "$_path" ]; then
|
|
|
|
mkdir -p "$(dirname "$_path")"
|
|
log_debug "Downloading $_url to $_path"
|
|
|
|
case "${_dld}" in
|
|
curl) _args="-sLo $_path" ;;
|
|
wget) _args="-qO $_path" ;;
|
|
esac
|
|
|
|
else
|
|
|
|
case "${_dld}" in
|
|
curl) _args="-sL" ;;
|
|
wget) _args="-qO-" ;;
|
|
esac
|
|
|
|
fi
|
|
|
|
case "${_dld}" in
|
|
curl) _result="$(curl $_args "${_url}" 2> /dev/null )" || _result="$(sudo curl $_args "${_url}" 2> /dev/null )" || (log_error "curl: failed to download ${_url}" && return 1) ;;
|
|
wget) _result="$(wget $_args "${_url}" 2> /dev/null )" || _result="$(sudo wget $_args "${_url}" 2> /dev/null )" || (log_error "wget: failed to download ${_url}" && return 1) ;;
|
|
*) err "unsupported downloader: ${_dld}" ;;
|
|
esac
|
|
|
|
RETVAL="${_result}"
|
|
return 0
|
|
}
|
|
|
|
function github_install {
|
|
ensure get_architecture
|
|
|
|
local _program=$1
|
|
local _arch="${RETVAL}"
|
|
local _url="https://api.github.com/repos/$2/releases/latest"
|
|
|
|
assert_nz "${_arch}" "arch"
|
|
|
|
need_cmd grep
|
|
|
|
download "${_url}"
|
|
local _releases=$RETVAL
|
|
|
|
(echo "${_releases}" | grep -q 'API rate limit exceeded') && (log_error "GitHub API rate limit exceeded. Please try again later." || return 1)
|
|
|
|
local _package_url _package_urls
|
|
_package_urls="$(echo "${_releases}" | grep "browser_download_url" | cut -d '"' -f 4)"
|
|
|
|
#log_debug "Packages: ${_package_urls}"
|
|
|
|
# Check for Rust package
|
|
local _rust_package_url _other_package_url
|
|
_rust_package_url="$(echo "$_package_urls" | grep "$_arch")"
|
|
_other_package_url="$(echo "$_package_urls" | grep "$ARCH" | grep -vE "$APP_FILTER")"
|
|
|
|
log_debug "Rust package: $_rust_package_url"
|
|
log_debug "Filter: $APP_FILTER"
|
|
log_debug "Other package: $_other_package_url"
|
|
|
|
if [ -n "$_other_package_url" ]; then
|
|
_package_url="${_other_package_url}"
|
|
elif [ -n "$_rust_package_url" ]; then
|
|
_package_url="${_rust_package_url}"
|
|
else
|
|
log_error "Can not find installable package for '$_program' for the detected architecture (${_arch})."
|
|
return 0
|
|
fi
|
|
|
|
log_debug "Selected package: ${_package_url}"
|
|
|
|
# Check the extension
|
|
local _ext
|
|
case "${_package_url}" in
|
|
*.tar.gz) _ext="tar.gz" ;;
|
|
*.deb) _ext="deb" ;;
|
|
*.zip) _ext="zip" ;;
|
|
*) _ext="" ;;
|
|
esac
|
|
|
|
local _package
|
|
if [ -z $_ext ]; then
|
|
_package="$TMP_PATH/$_program"
|
|
else
|
|
_package="$TMP_PATH/$_program.$_ext"
|
|
fi
|
|
|
|
download "$_package_url" "$_package"
|
|
|
|
# unpack
|
|
cd "${TMP_PATH}" || (log_error "Could not unpack ${_package}. The directory ${TMP_PATH} does not exist" && return 1)
|
|
case "${_package}" in
|
|
*.tar.gz)
|
|
need_cmd tar
|
|
log_info "Unpacking ${_package}"
|
|
tar -xf "${_package}"
|
|
;;
|
|
*.zip)
|
|
need_cmd unzip
|
|
log_info "Unpacking ${_package}"
|
|
unzip -oq "${_package}"
|
|
;;
|
|
*) ;; # ignore
|
|
esac
|
|
|
|
# install
|
|
local _binary
|
|
case "${_ext}" in
|
|
tar.gz)
|
|
_binary="$(tar --list -f "${_package}" | grep -E "^(.*/)?$_program$")"
|
|
log_debug "$_binary"
|
|
install_binary "$_program" "$TMP_PATH/$_binary"
|
|
return 0
|
|
;;
|
|
deb)
|
|
install_deb "${_program}" "${_package}"
|
|
return 0
|
|
;;
|
|
zip)
|
|
_binary="$(unzip -l "${_package}" | sed -E 's/ {1,}/ /g' | cut -d ' ' -f 5 | grep -E "^(.*/)?$_program$")"
|
|
log_debug "$_binary"
|
|
install_binary "$_program" "$TMP_PATH/$_binary"
|
|
return 0
|
|
;;
|
|
*)
|
|
_binary="${_program}"
|
|
log_debug "$_binary"
|
|
log_debug "Installing binary!"
|
|
install_binary "$_program" "$TMP_PATH/$_binary"
|
|
;;
|
|
esac
|
|
|
|
}
|
|
|
|
function github_download_config {
|
|
ensure get_architecture
|
|
local _program=$1
|
|
local _arch="${RETVAL}"
|
|
local _repo=$2
|
|
local _url="https://api.github.com/repos/$_repo/releases/latest"
|
|
local _file=$3
|
|
|
|
assert_nz "${_arch}" "arch"
|
|
|
|
need_cmd grep
|
|
|
|
download "${_url}"
|
|
local _releases=$RETVAL
|
|
|
|
(echo "${_releases}" | grep -q 'API rate limit exceeded') && (log_error "GitHub API rate limit exceeded. Please try again later." || return 1)
|
|
|
|
local _tag_name _remote_file _path
|
|
_tag_name="$(echo "${_releases}" | grep "tag_name" | cut -d '"' -f 4)"
|
|
_remote_file="https://raw.githubusercontent.com/$_repo/$_tag_name/$_file"
|
|
|
|
download_config "$_program" "$_file" "$_remote_file"
|
|
install_rc_file "$CONFIG_PATH/$_program/$_file"
|
|
}
|
|
|
|
function install_deb_check {
|
|
CHECK_CURRENT=$(dpkg -s "$1" 2>&1 | grep -E "Status|Version")
|
|
#INSTALLED_CURRENT=$(echo $CHECK_CURRENT | grep -oE "Status: .*" | cut -d ' ' -f 2)
|
|
VERSION_CURRENT=$(echo $CHECK_CURRENT | grep -oE "Version: .*" | cut -d ' ' -f 2)
|
|
CHECK_NEW=$(sudo dpkg -I $2 | grep -E "Status|Version")
|
|
#INSTALLED_NEW=$(echo $CHECK_NEW | grep -oE "Status: .*" | cut -d ' ' -f 2)
|
|
VERSION_NEW=$(echo $CHECK_NEW | grep -oE "Version: .*" | cut -d ' ' -f 2)
|
|
|
|
if [ ! -z "$CHECK_CURRENT" ]; then
|
|
if [[ "$VERSION_CURRENT" != "$VERSION_NEW" ]]; then
|
|
log_info "$1 ($VERSION_CURRENT) is installed."
|
|
else
|
|
log_info "$1 ($VERSION_CURRENT) is already installed. Skipping ..."
|
|
return 1
|
|
fi
|
|
if ! user_confirm "Do you want to install $1 ($VERSION_NEW)?"; then
|
|
return 1
|
|
fi
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
function install_deb {
|
|
local _file=$2
|
|
local _program=$1
|
|
#if [ -z "$P_DEB" ]; then return 0; fi
|
|
#log_info "Downloading $2 to $TMP_PATH ..."
|
|
#wget -O $TMP_PATH/$1.deb $2 > /dev/null 2>&1
|
|
|
|
if ! install_deb_check "$_program" "$_file"; then
|
|
return 1
|
|
fi
|
|
|
|
INSTALL=$(sudo dpkg -i "$_file")
|
|
log_debug "$INSTALL"
|
|
UNPACK=$(echo -n "$INSTALL" | grep -oE "Unpacking .*")
|
|
PROG=$(echo -n "$UNPACK" | cut -d '(' -f 1 | cut -d ' ' -f 2)
|
|
CURR_VERSION=$(echo -n "$UNPACK" | cut -d '(' -f 2 | cut -d ')' -f 1)
|
|
log_debug "Current Version: $CURR_VERSION"
|
|
PREV_VERSION=$(echo -n "$UNPACK" | cut -d '(' -f 3 | cut -d ')' -f 1)
|
|
log_debug "Previous Version: $PREV_VERSION"
|
|
color "$ADD" "[+]"
|
|
echo -n "Installed $PROG ($CURR_VERSION)"
|
|
if [ ! -z "${PREV_VERSION}" ] && [ "${PREV_VERSION}" != "${CURR_VERSION}" ]; then
|
|
echo " over ($PREV_VERSION)"
|
|
else
|
|
echo ""
|
|
fi
|
|
#rm $TMP_PATH/$1.deb
|
|
return 0
|
|
}
|
|
|
|
function init {
|
|
#if [ ! -z "$P_BINARY" ] || [ ! -z "$P_DEB" ]; then
|
|
# log_info "Found Architecture: $ARCH"
|
|
# if ! user_confirm "Is '$ARCH' the correct architecture to download programs?"; then
|
|
# log_info "Exiting ..."
|
|
# exit 0
|
|
# fi
|
|
#fi
|
|
if [ -n "$P_APT" ]; then
|
|
log_info "Running apt update ..."
|
|
sudo apt update > /dev/null 2>&1
|
|
fi
|
|
mkdir -p "$TMP_PATH/"
|
|
mkdir -p "$CONFIG_PATH/"
|
|
}
|
|
|
|
function cleanup {
|
|
sudo rm -R "$TMP_PATH"
|
|
#nop
|
|
}
|
|
|
|
function apt_install {
|
|
if [ -z "$P_APT" ]; then return 0; fi
|
|
RESULT=$(sudo apt install -y $1 2>&1 )
|
|
if echo "$1 is already the newest version" | grep "$RESULT" > /dev/null; then
|
|
log_info "$1 is already installed"
|
|
else
|
|
log_add "Installed $1"
|
|
fi
|
|
}
|
|
|
|
function github_latest {
|
|
VERSION=$(curl -I "https://github.com/$1/releases/latest/" 2> /dev/null | grep -iE "^Location:" | tr -s ' ' | cut -d '/' -f 8 2> /dev/null)
|
|
echo -n "${VERSION//[$'\t\r\n']}" 2> /dev/null
|
|
}
|
|
|
|
function git_clone {
|
|
CLONE=$(git clone "$1" "$2" 2>&1)
|
|
log_debug "${CLONE}"
|
|
if [[ $CLONE =~ "already exists" ]] || [[ $CLONE =~ "existiert bereits" ]]; then
|
|
log_debug "$1 already exists. Running 'git pull'."
|
|
git -C "$2" pull > /dev/null 2>&1
|
|
log_info "Updated $1 in $2"
|
|
else
|
|
log_add "Cloned $1 into $2"
|
|
fi
|
|
}
|
|
|
|
function install_binary {
|
|
local _app=$1
|
|
local _path=$2
|
|
if [ -z "$P_BINARY" ]; then return 0; fi
|
|
#log_info "Downloading $2 to $BINARY_PATH ..."
|
|
#sudo wget -O $BINARY_PATH/$1 $2 > /dev/null 2>&1
|
|
log_debug "$_path"
|
|
log_debug "$BINARY_PATH/$_app"
|
|
sudo cp "$_path" "$BINARY_PATH/$_app"
|
|
sudo chmod +x "$BINARY_PATH/$_app"
|
|
log_add "Installed $_app into $BINARY_PATH/$_app"
|
|
}
|
|
|
|
function set_shell {
|
|
if [ -z "$P_ZSH" ]; then return 0; fi
|
|
CURR_U=$(grep "^$USER" /etc/passwd | cut -d ':' -f 7 | cut -d '/' -f 4)
|
|
CURR_R=$(grep "^root" /etc/passwd | cut -d ':' -f 7 | cut -d '/' -f 4)
|
|
if [[ $1 != "$CURR_U" ]]; then
|
|
log_add "Setting default shell to $1"
|
|
sudo -u "$USER" chsh -s "$(which "$1")"
|
|
sudo chsh -s "$(which "$1")"
|
|
else
|
|
log_info "Shell already set to $1"
|
|
fi
|
|
}
|
|
|
|
# --------------------------------------------------------------------------------------------------
|
|
|
|
function update {
|
|
cd "$(dirname "$0")" || (log_error "Could not change directory to $(dirname "$0")." && exit 1)
|
|
download "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/kfg" "kfg"
|
|
exit 0
|
|
}
|
|
|
|
function show_help_install {
|
|
show_help_name
|
|
echo -e "Usage: ${INFO}${NAME}${ENDCOLOR} install <program> [ opt ]\n"
|
|
echo -e "program := {"
|
|
local _length _space
|
|
for key in "${!TOOLS[@]}"; do
|
|
_length="$(echo -n "$key" | wc -m)"
|
|
if [ "$_length" -gt 21 ]; then
|
|
_space=""
|
|
elif [ "$_length" -gt 13 ]; then
|
|
_space="\t"
|
|
elif [ "$_length" -gt 5 ]; then
|
|
_space="\t\t"
|
|
else
|
|
_space="\t\t\t"
|
|
fi
|
|
echo -e " ${INFO}${key}${ENDCOLOR}${_space} ${TOOLS[$key]}"
|
|
done
|
|
echo -e "}\n"
|
|
show_help_opt
|
|
exit 2
|
|
}
|
|
|
|
function p_all {
|
|
ALL=1
|
|
p_zsh
|
|
p_tmux
|
|
p_unp
|
|
p_bat
|
|
p_lsd
|
|
p_omp
|
|
p_zoxide
|
|
p_fzf
|
|
p_nvim
|
|
p_nu
|
|
}
|
|
|
|
function p_zsh {
|
|
# -----------------
|
|
# zsh
|
|
# -----------------
|
|
apt_install zsh
|
|
set_shell zsh
|
|
|
|
install_rc_download "sh" "_kfg.rc" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/sh/_kfg.rc"
|
|
install_rc_download "sh" "keybindings.rc" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/sh/keybindings.rc"
|
|
install_rc_download "sh" "util.rc" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/sh/util.rc"
|
|
|
|
download_config sh zsh-autosuggestions.zsh "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/sh/zsh-autosuggestions.zsh"
|
|
download_config sh zsh-syntax-highlighting.zsh "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/sh/zsh-syntax-highlighting.zsh"
|
|
download_config sh highlighters/brackets/brackets-highlighter.zsh "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/sh/highlighters/brackets/brackets-highlighter.zsh"
|
|
download_config sh highlighters/cursor/cursor-highlighter.zsh "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/sh/highlighters/cursor/cursor-highlighter.zsh"
|
|
download_config sh highlighters/line/line-highlighter.zsh "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/sh/highlighters/line/line-highlighter.zsh"
|
|
download_config sh highlighters/main/main-highlighter.zsh "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/sh/highlighters/main/main-highlighter.zsh"
|
|
download_config sh highlighters/pattern/pattern-highlighter.zsh "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/sh/highlighters/pattern/pattern-highlighter.zsh"
|
|
download_config sh highlighters/regexp/regexp-highlighter.zsh "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/sh/highlighters/regexp/regexp-highlighter.zsh"
|
|
download_config sh highlighters/root/root-highlighter.zsh "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/sh/highlighters/root/root-highlighter.zsh"
|
|
download_config sh .version "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/sh/.version"
|
|
download_config sh .revision-hash "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/sh/.revision-hash"
|
|
download_config sh zsh-ghostty-integration.zsh "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/sh/zsh-ghostty-integration.zsh"
|
|
install_rc_download sh zsh.rc 'https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/sh/zsh.rc'
|
|
prepend_rc $'# Ghostty Integration for OSC 133 marks\n[ -f $HOME/.config/sh/zsh-ghostty-integration.zsh ] && source $HOME/.config/sh/zsh-ghostty-integration.zsh\n'
|
|
}
|
|
|
|
|
|
function p_tmux {
|
|
# -----------------
|
|
# tmux
|
|
# -----------------
|
|
apt_install tmux
|
|
download_config tmux tmux.conf "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/tmux/tmux.conf"
|
|
download_config tmux tmux.theme "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/tmux/tmux.theme"
|
|
download_config tmux myip.sh "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/tmux/myip.sh"
|
|
sudo chmod +x "${CONFIG_PATH}/tmux/myip.sh"
|
|
install_rc_download "tmux" "tmux.rc" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/tmux/tmux.rc"
|
|
git_clone "https://github.com/tmux-plugins/tpm" "${CONFIG_PATH}/tmux/plugins/tpm"
|
|
}
|
|
|
|
function p_unp {
|
|
# -----------------
|
|
# unp
|
|
# -----------------
|
|
apt_install unp
|
|
# --- TODO --- : rc file
|
|
}
|
|
|
|
function p_bat {
|
|
# -----------------
|
|
# bat
|
|
# -----------------
|
|
github_install bat "sharkdp/bat"
|
|
#install_deb_github bat "sharkdp/bat" "bat_VERSION_ARCH.deb"
|
|
install_rc_download bat "bat.rc" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/bat/bat.rc"
|
|
}
|
|
|
|
function p_nu {
|
|
github_install nu 'nushell/nushell'
|
|
}
|
|
|
|
function p_lsd {
|
|
# -----------------
|
|
# Install lsd https://github.com/Peltoche/lsd
|
|
# -----------------
|
|
github_install "lsd" "lsd-rs/lsd"
|
|
#install_deb_github "lsd" "lsd-rs/lsd" "lsd_VERSION_ARCH.deb"
|
|
install_rc_download lsd "lsd.rc" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/lsd/lsd.rc"
|
|
download_config lsd "config.yaml" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/lsd/config.yaml"
|
|
download_config lsd "colors.yaml" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/lsd/colors.yaml"
|
|
}
|
|
|
|
function p_zoxide {
|
|
github_install "zoxide" "ajeetdsouza/zoxide"
|
|
install_rc_download zoxide "zoxide.rc" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/zoxide/zoxide.rc"
|
|
}
|
|
|
|
function p_omp {
|
|
# -----------------
|
|
# Install OhMyPosh
|
|
# -----------------
|
|
github_install "oh-my-posh" "JanDeDobbeleer/oh-my-posh"
|
|
download_config "omp" "omp.json" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/omp/omp.json"
|
|
install_rc_download "omp" "omp.rc" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/omp/omp.rc"
|
|
#install_binary_github "oh-my-posh" "JanDeDobbeleer/oh-my-posh" "posh-linux-ARCH"
|
|
}
|
|
|
|
function p_fzf {
|
|
# -----------------
|
|
# Install fzf
|
|
# -----------------
|
|
local _repo="junegunn/fzf"
|
|
github_install "fzf" "${_repo}"
|
|
|
|
# Install latest release version of fzf-tmux
|
|
local _latest_version _path_fzf_tmux
|
|
_latest_version="$( github_latest ${_repo})"
|
|
_path_fzf_tmux="$TMP_PATH/fzf-tmux"
|
|
download "https://raw.githubusercontent.com/${_repo}/${_latest_version}/bin/fzf-tmux" "${_path_fzf_tmux}"
|
|
install_binary "fzf-tmux" "${_path_fzf_tmux}"
|
|
|
|
# download autocomplete
|
|
|
|
|
|
# install fzf tab
|
|
if [ -n "$ALL" ] || user_confirm "Do you want to install fzf-tab as well?"; then
|
|
p_fzf_tab
|
|
fi
|
|
|
|
install_rc_download fzf "fzf.rc" "https://git.cbeck.tech/kamu/dotfiles/raw/branch/main/.config/fzf/fzf.rc"
|
|
github_download_config "fzf" "$_repo" "shell/completion.zsh"
|
|
github_download_config "fzf" "$_repo" "shell/key-bindings.zsh"
|
|
}
|
|
|
|
function p_fzf_tab {
|
|
# -----------------
|
|
# Install fzf-tab
|
|
# -----------------
|
|
git_clone "https://github.com/Aloxaf/fzf-tab" "${CONFIG_PATH}/fzf/tools/fzf-tab"
|
|
install_rc_file "${CONFIG_PATH}/fzf/tools/fzf-tab/fzf-tab.plugin.zsh"
|
|
}
|
|
|
|
function p_zoom {
|
|
# Install latest release version of zoom
|
|
local _path_zoom
|
|
_path_zoom="$TMP_PATH/zoom"
|
|
download "https://eu01web.zoom.us/client/latest/zoom_amd64.deb" "${_path_zoom}"
|
|
install_deb "zoom_amd64.deb" "${_path_zoom}"
|
|
}
|
|
|
|
function p_nvim {
|
|
# Build nvim from source
|
|
log_info "Installing dependencies for neovim"
|
|
# install requirements
|
|
apt_install ninja-build
|
|
apt_install gettext
|
|
apt_install cmake
|
|
apt_install unzip
|
|
apt_install curl
|
|
apt_install ripgrep
|
|
|
|
log_info "Cloning Repository"
|
|
# get repository
|
|
res=$(git_clone "https://github.com/neovim/neovim" "${TMP_PATH}/neovim" 2>&1)
|
|
res=$(git -C "${TMP_PATH}/neovim" checkout stable 2>&1)
|
|
|
|
# build neovim
|
|
log_info "Building neovim... (this can take a few minutes)"
|
|
res=$(make -C "${TMP_PATH}/neovim" CMAKE_BUILD_TYPE=Release 2>&1)
|
|
|
|
# Install neovim
|
|
log_info "Installing neovim..."
|
|
res=$(sudo make -C "${TMP_PATH}/neovim" install 2>&1)
|
|
log_add "Installed neovim [$(${TMP_PATH}/neovim/build/bin/nvim --version | head -n 1 | grep -oE "v(.*)$")]"
|
|
#cd "${TMP_PATH}/neovim/build" && cpack -G DEB && sudo dpkg -i nvim-linux64.deb
|
|
|
|
# Download config
|
|
log_info "Downloading neovim configuration..."
|
|
res=$(git -C "${TMP_PATH}" clone --filter=blob:none --no-checkout --depth 1 --sparse https://git.cbeck.tech/kamu/dotfiles.git "${TMP_PATH}/dotfiles" 2>&1)
|
|
res=$(git -C "${TMP_PATH}/dotfiles" sparse-checkout add ".config/nvim" 2>&1)
|
|
res=$(git -C "${TMP_PATH}/dotfiles" checkout 2>&1)
|
|
res=$(cp -r "${TMP_PATH}/dotfiles/.config/nvim/*" ${CONFIG_PATH}/nvim/ 2>&1)
|
|
log_add "Added neovim configuration."
|
|
|
|
}
|
|
|
|
function install {
|
|
if [ -z "$1" ]; then
|
|
show_help_install
|
|
fi
|
|
|
|
init
|
|
|
|
P_APT=1; P_DEB=1; P_CONFIG=1; P_RC=1; P_BINARY=1; P_ZSH=1
|
|
|
|
# -----------------
|
|
# General Config
|
|
# -----------------
|
|
install_rc "export KHOME=$HOME_PATH"
|
|
install_rc "export XDG_CONFIG_HOME=$CONFIG_PATH"
|
|
|
|
while :
|
|
do
|
|
case "$1" in
|
|
help) show_help_install ;;
|
|
"") break ;;
|
|
all) p_all; shift ;;
|
|
zsh) p_zsh; shift ;;
|
|
bat) p_bat; shift ;;
|
|
tmux) p_tmux; shift ;;
|
|
unp) p_unp; shift ;;
|
|
lsd) p_lsd; shift ;;
|
|
omp) p_omp; shift ;;
|
|
zoxide) p_zoxide; shift ;;
|
|
fzf) p_fzf; shift ;;
|
|
zoom) p_zoom; shift ;;
|
|
nvim) p_nvim; shift ;;
|
|
nu) p_nu; shift ;;
|
|
# If invalid options were passed, then getopt should have reported an error,
|
|
# which we checked as VALID_ARGUMENTS when getopt was called...
|
|
*) log_error "Unrecognised program: $1"; shift ;;
|
|
esac
|
|
done
|
|
|
|
cleanup
|
|
exit 0
|
|
}
|
|
|
|
function main {
|
|
if [ -z "$1" ]; then
|
|
show_help
|
|
fi
|
|
|
|
PARSED_ARGUMENTS=$(getopt -a -n install.sh -o hvdya: --long yes,help,debug,arch,verbose: -- "$@")
|
|
VALID_ARGUMENTS=$?
|
|
if [ "$VALID_ARGUMENTS" != "0" ]; then
|
|
show_help
|
|
fi
|
|
|
|
ARCH=$(/usr/bin/dpkg --print-architecture)
|
|
|
|
#echo "PARSED_ARGUMENTS is $PARSED_ARGUMENTS"
|
|
eval set -- "$PARSED_ARGUMENTS"
|
|
while :
|
|
do
|
|
case "$1" in
|
|
-h | --help) show_help ;;
|
|
-v | --verbose) P_Verbose=1 ; shift ;;
|
|
-d | --debug) P_Debug=1 ; shift ;;
|
|
-y | --yes) P_Yes=1 ; shift ;;
|
|
-a | --arch) ARCH="$2" ; shift 2 ;;
|
|
# -- means the end of the arguments; drop this, and break out of the while loop
|
|
--) shift; break ;;
|
|
# If invalid options were passed, then getopt should have reported an error,
|
|
# which we checked as VALID_ARGUMENTS when getopt was called...
|
|
*) log_error "Unexpected option: $1"
|
|
show_help ;;
|
|
esac
|
|
done
|
|
|
|
#echo "Parameters remaining are: $@"
|
|
case "$1" in
|
|
update) update ;;
|
|
version) version ;;
|
|
install) shift; install "$@";;
|
|
# -- means the end of the arguments; drop this, and break out of the while loop
|
|
--) shift; return ;;
|
|
# If invalid options were passed, then getopt should have reported an error,
|
|
# which we checked as VALID_ARGUMENTS when getopt was called...
|
|
*) log_error "Unexpected command: $1"; show_help ;;
|
|
esac
|
|
}
|
|
|
|
# The following is from (with modifications): https://github.com/rust-lang/rustup/blob/4c1289b2c3f3702783900934a38d7c5f912af787/rustup-init.sh
|
|
function get_architecture {
|
|
_ostype="$(uname -s)"
|
|
_cputype="$(uname -m)"
|
|
_clibtype="gnu"
|
|
|
|
APP_FILTER="arm64|freebsd|openbsd|amd64|aarch64|i686|x86_64|x86-64|x64|musl|gnu|windows|darwin|linux|android|exe|sig|sha256"
|
|
|
|
if [ "${_ostype}" = Linux ]; then
|
|
if [ "$(uname -o || true)" = Android ]; then
|
|
_ostype=Android
|
|
fi
|
|
|
|
if ldd --version 2>&1 | grep -q 'musl'; then
|
|
_clibtype="musl"
|
|
APP_FILTER="${APP_FILTER//musl|/}"
|
|
else
|
|
APP_FILTER="${APP_FILTER//gnu|/}"
|
|
fi
|
|
fi
|
|
|
|
if [ "${_ostype}" = Darwin ] && [ "${_cputype}" = i386 ]; then
|
|
# Darwin `uname -m` lies
|
|
if sysctl hw.optional.x86_64 | grep -q ': 1'; then
|
|
_cputype=x86_64
|
|
fi
|
|
fi
|
|
|
|
if [ "${_ostype}" = SunOS ]; then
|
|
# Both Solaris and illumos presently announce as "SunOS" in "uname -s"
|
|
# so use "uname -o" to disambiguate. We use the full path to the
|
|
# system uname in case the user has coreutils uname first in PATH,
|
|
# which has historically sometimes printed the wrong value here.
|
|
if [ "$(/usr/bin/uname -o || true)" = illumos ]; then
|
|
_ostype=illumos
|
|
fi
|
|
|
|
# illumos systems have multi-arch userlands, and "uname -m" reports the
|
|
# machine hardware name; e.g., "i86pc" on both 32- and 64-bit x86
|
|
# systems. Check for the native (widest) instruction set on the
|
|
# running kernel:
|
|
if [ "${_cputype}" = i86pc ]; then
|
|
_cputype="$(isainfo -n)"
|
|
fi
|
|
fi
|
|
|
|
case "${_ostype}" in
|
|
Android)
|
|
_ostype=linux-android
|
|
APP_FILTER="${APP_FILTER//android|/}"
|
|
;;
|
|
Linux)
|
|
check_proc
|
|
_ostype=unknown-linux-${_clibtype}
|
|
_bitness=$(get_bitness)
|
|
APP_FILTER="${APP_FILTER//linux|/}"
|
|
;;
|
|
FreeBSD)
|
|
_ostype=unknown-freebsd
|
|
APP_FILTER="${APP_FILTER//freebsd|/}"
|
|
;;
|
|
OpenBSD)
|
|
_ostype=unknown-freebsd
|
|
APP_FILTER="${APP_FILTER//openbsd|/}"
|
|
;;
|
|
NetBSD)
|
|
_ostype=unknown-netbsd
|
|
;;
|
|
DragonFly)
|
|
_ostype=unknown-dragonfly
|
|
;;
|
|
Darwin)
|
|
_ostype=apple-darwin
|
|
APP_FILTER="${APP_FILTER//darwin|/}"
|
|
;;
|
|
illumos)
|
|
_ostype=unknown-illumos
|
|
;;
|
|
MINGW* | MSYS* | CYGWIN* | Windows_NT)
|
|
_ostype=pc-windows-msvc
|
|
;;
|
|
*)
|
|
err "unrecognized OS type: ${_ostype}"
|
|
;;
|
|
esac
|
|
|
|
case "${_cputype}" in
|
|
i386 | i486 | i686 | i786 | x86)
|
|
_cputype=i686
|
|
APP_FILTER="${APP_FILTER//i686|/}"
|
|
;;
|
|
xscale | arm)
|
|
_cputype=arm
|
|
if [ "${_ostype}" = "linux-android" ]; then
|
|
_ostype=linux-androideabi
|
|
fi
|
|
;;
|
|
armv6l)
|
|
_cputype=arm
|
|
if [ "${_ostype}" = "linux-android" ]; then
|
|
_ostype=linux-androideabi
|
|
else
|
|
_ostype="${_ostype}eabihf"
|
|
fi
|
|
;;
|
|
armv7l | armv8l)
|
|
_cputype=armv7
|
|
if [ "${_ostype}" = "linux-android" ]; then
|
|
_ostype=linux-androideabi
|
|
else
|
|
_ostype="${_ostype}eabihf"
|
|
fi
|
|
;;
|
|
aarch64 | arm64)
|
|
_cputype=aarch64
|
|
APP_FILTER="${APP_FILTER//aarch64|/}"
|
|
APP_FILTER="${APP_FILTER//arm64|/}"
|
|
;;
|
|
x86_64 | x86-64 | x64 | amd64)
|
|
_cputype=x86_64
|
|
APP_FILTER="${APP_FILTER//amd64|/}"
|
|
APP_FILTER="${APP_FILTER//x86_64|/}"
|
|
APP_FILTER="${APP_FILTER//x86-64|/}"
|
|
APP_FILTER="${APP_FILTER//x64|/}"
|
|
;;
|
|
mips)
|
|
_cputype=$(get_endianness mips '' el)
|
|
;;
|
|
mips64)
|
|
if [ "${_bitness}" -eq 64 ]; then
|
|
# only n64 ABI is supported for now
|
|
_ostype="${_ostype}abi64"
|
|
_cputype=$(get_endianness mips64 '' el)
|
|
fi
|
|
;;
|
|
ppc)
|
|
_cputype=powerpc
|
|
;;
|
|
ppc64)
|
|
_cputype=powerpc64
|
|
;;
|
|
ppc64le)
|
|
_cputype=powerpc64le
|
|
;;
|
|
s390x)
|
|
_cputype=s390x
|
|
;;
|
|
riscv64)
|
|
_cputype=riscv64gc
|
|
;;
|
|
*)
|
|
err "unknown CPU type: ${_cputype}"
|
|
;;
|
|
esac
|
|
|
|
# Detect 64-bit linux with 32-bit userland
|
|
if [ "${_ostype}" = unknown-linux-musl ] && [ "${_bitness}" -eq 32 ]; then
|
|
case ${_cputype} in
|
|
x86_64)
|
|
# 32-bit executable for amd64 = x32
|
|
if is_host_amd64_elf; then {
|
|
echo "x32 userland is unsupported" 1>&2
|
|
exit 1
|
|
}; else
|
|
_cputype=i686
|
|
fi
|
|
;;
|
|
mips64)
|
|
_cputype=$(get_endianness mips '' el)
|
|
;;
|
|
powerpc64)
|
|
_cputype=powerpc
|
|
;;
|
|
aarch64)
|
|
_cputype=armv7
|
|
if [ "${_ostype}" = "linux-android" ]; then
|
|
_ostype=linux-androideabi
|
|
else
|
|
_ostype="${_ostype}eabihf"
|
|
fi
|
|
;;
|
|
riscv64gc)
|
|
err "riscv64 with 32-bit userland unsupported"
|
|
;;
|
|
*) ;;
|
|
esac
|
|
fi
|
|
|
|
# Detect armv7 but without the CPU features Rust needs in that build,
|
|
# and fall back to arm.
|
|
# See https://github.com/rust-lang/rustup.rs/issues/587.
|
|
if [ "${_ostype}" = "unknown-linux-musleabihf" ] && [ "${_cputype}" = armv7 ]; then
|
|
if ensure grep '^Features' /proc/cpuinfo | grep -q -v neon; then
|
|
# At least one processor does not have NEON.
|
|
_cputype=arm
|
|
fi
|
|
fi
|
|
|
|
_arch="${_cputype}-${_ostype}"
|
|
log_debug "Detected architecture: ${_arch}"
|
|
log_debug "APP_FILTER: $APP_FILTER"
|
|
RETVAL="${_arch}"
|
|
}
|
|
function get_bitness {
|
|
need_cmd head
|
|
# Architecture detection without dependencies beyond coreutils.
|
|
# ELF files start out "\x7fELF", and the following byte is
|
|
# 0x01 for 32-bit and
|
|
# 0x02 for 64-bit.
|
|
# The printf builtin on some shells like dash only supports octal
|
|
# escape sequences, so we use those.
|
|
local _current_exe_head
|
|
_current_exe_head=$(head -c 5 /proc/self/exe)
|
|
if [ "${_current_exe_head}" = "$(printf '\177ELF\001')" ]; then
|
|
echo 32
|
|
elif [ "${_current_exe_head}" = "$(printf '\177ELF\002')" ]; then
|
|
echo 64
|
|
else
|
|
err "unknown platform bitness"
|
|
fi
|
|
}
|
|
function get_endianness {
|
|
local cputype=$1
|
|
local suffix_eb=$2
|
|
local suffix_el=$3
|
|
|
|
# detect endianness without od/hexdump, like get_bitness() does.
|
|
need_cmd head
|
|
need_cmd tail
|
|
|
|
local _current_exe_endianness
|
|
_current_exe_endianness="$(head -c 6 /proc/self/exe | tail -c 1)"
|
|
if [ "${_current_exe_endianness}" = "$(printf '\001')" ]; then
|
|
echo "${cputype}${suffix_el}"
|
|
elif [ "${_current_exe_endianness}" = "$(printf '\002')" ]; then
|
|
echo "${cputype}${suffix_eb}"
|
|
else
|
|
err "unknown platform endianness"
|
|
fi
|
|
}
|
|
function is_host_amd64_elf() {
|
|
need_cmd head
|
|
need_cmd tail
|
|
# ELF e_machine detection without dependencies beyond coreutils.
|
|
# Two-byte field at offset 0x12 indicates the CPU,
|
|
# but we're interested in it being 0x3E to indicate amd64, or not that.
|
|
local _current_exe_machine
|
|
_current_exe_machine=$(head -c 19 /proc/self/exe | tail -c 1)
|
|
[ "${_current_exe_machine}" = "$(printf '\076')" ]
|
|
}
|
|
function check_proc() {
|
|
# Check for /proc by looking for the /proc/self/exe link.
|
|
# This is only run on Linux.
|
|
if ! test -L /proc/self/exe; then
|
|
err "unable to find /proc/self/exe. Is /proc mounted? Installation cannot proceed without /proc."
|
|
fi
|
|
}
|
|
function need_cmd() {
|
|
if ! check_cmd "$1"; then
|
|
err "need '$1' (command not found)"
|
|
fi
|
|
}
|
|
function check_cmd() {
|
|
command -v "$1" >/dev/null 2>&1
|
|
}
|
|
function ensure() {
|
|
if ! "$@"; then err "command failed: $*"; fi
|
|
}
|
|
function assert_nz() {
|
|
if [ -z "$1" ]; then err "found empty string: $2"; fi
|
|
}
|
|
|
|
{
|
|
main "$@" || exit 1
|
|
}
|