Files
dotfiles/kfg
2025-01-10 12:49:39 +01:00

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
}