diff --git a/install.sh b/install.sh
index 4f3742e..4fdd3fd 100755
--- a/install.sh
+++ b/install.sh
@@ -1,172 +1,362 @@
-#!/bin/sh
+#!/bin/bash
 
-_usage() {
-  printf "%s" \
-    "Usage: sh ${0##*/} [ options ]
-    -h | --help          => Show this help.
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+ORANGE='\033[0;33m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
 
-    -i | --install       => Install the config.
+REPO="https://github.com/siduck76/NvChad.git"
+BACKUP_PATH="/tmp/nvchad/"
+TMP_NVCHAD="/tmp/nvchad_updates/"
 
-    -u | --update        => Update the existing config without removing existing stuff.
+skip=0
+nvchad_path="$HOME/.config/nvim/"
+do_startup="true"
+dependencies=(
+    "git"
+)
+preserved_files=(
+    "lua/mappings.lua"
+    "lua/user_config.lua"
+)
 
-    -b | --backup 'path' => Custom config backup path.
-
-    -nb | --no-backup    => Don't take existing config backup. Use with caution.
-"
-  exit 0
+# https://stackoverflow.com/questions/5947742/how-to-change-the-output-color-of-echo-in-linux
+prompt() {
+    case ${1} in
+    "-s" | "--success")
+        printf "${GREEN}%s${NC}\n" "${2}"
+        ;;
+    "-e" | "--error")
+        printf "${RED}%s${NC}\n" "${2}"
+        ;;
+    "-w" | "--warning")
+        printf "${ORANGE}%s${NC}\n" "${2}"
+        ;;
+    "-i" | "--info")
+        printf "${BLUE}%s${NC}\n" "${2}"
+        ;;
+    *)
+        printf "${GREEN}%s${NC}\n" "${2}"
+        ;;
+    esac
 }
 
-_check_install_dependencies() {
-  _error_dependencies() {
-    printf "%s\n" "Error: Install ${1} before proceeding."
-    exit 1
-  }
-  command -v git 1>/dev/null || _error_dependencies git
-  _SED="$(command -v sed)" || _error_dependencies sed
-  return 0
+_usage() {
+    printf "%s" \
+        "Usage: ./${0##*/} [ options ]
+    -h, --help          -> Show this help.
+    -i, --install       -> Install the config.
+    -r, --remove        -> Remove the config.
+    -u, --update        -> Update the existing config without removing existing stuff.
+    -s, --skip-startup  -> Skip starting up nvim after installing the config.
+    -c, --clean-backups -> Remove backups (if any) from your system.
+    -p=*, --path=*      -> Path to NvChad. Relevant for installing and updating.
+"
+}
+
+_remove() {
+	
+	read -p "Are you sure you want to uninstall NvChad? This will 'flush' dirs such as $HOME/.config/nvim/. (y/n): " u_reply
+
+	if [[ "${u_reply}" == "y" ]]; then
+		printf "  + %s\n" "$(prompt -w "Removing config        ->	($HOME/.config/nvim/)")"
+		rm -rf "$HOME/.config/nvim/"
+
+		printf "  + %s\n" "$(prompt -w "Removing miscellaneous ->	($HOME/.local/share/nvim/)")"
+		rm -rf "$HOME/.local/share/nvim/"
+
+		printf "  + %s\n" "$(prompt -w "Removing cache         ->	($HOME/.cache/nvim/)")"
+		rm -rf "$HOME/.cache/nvim/"
+	elif [[ "${u_reply}" == "n" ]]; then
+		prompt -i "Ok, enjoy NvChad :)"
+	else
+		prompt -e "Error: you must type either 'n' for no or 'y' for yes."
+	fi
+
+}
+
+_check_dependencies() {
+    local err
+
+    for i in "${dependencies[@]}"; do
+
+        if ! command -v "${i}" &>/dev/null; then
+            prompt -e "Error: You need to install the dependency '${i}'"
+            err="true"
+        fi
+    done
+
+    if [[ "${err}" == "true" ]]; then
+        exit 1
+    fi
+}
+
+_fetch() {
+    printf "  + %s\n" "$(prompt -i "Cleaning workspace")"
+    rm -rf ${nvchad_path}
+    printf "  + %s\n" "$(prompt -i "Fetching repo")"
+    git clone -n ${REPO} --depth 1 "${nvchad_path}"
+    cd "${nvchad_path}" || return
+
+    printf "  + %s\n" "$(prompt -i "Checking out core")"
+    git checkout HEAD lua/
+    printf "  + %s\n" "$(prompt -i "Checking out init file")"
+    git checkout HEAD init.lua
+}
+
+_check_prev_conf() {
+    if [[ -d "${nvchad_path}" ]]; then
+        mkdir -p "${BACKUP_PATH}"
+        amount_files=$(ls "${BACKUP_PATH}" | wc -l)
+        printf "  + %s\n" "$(prompt -i "Previous config found, backing it up (/tmp/nvchad/backup_${amount_files})")"
+        cp -r "${nvchad_path}" "${BACKUP_PATH}backup_${amount_files}"
+    fi
 }
 
 _check_nvim_version() {
-  version_string="$(nvim --version | grep -Eo 'NVIM.*v[0-9.]+' -m 1 | grep -Eo '[0-9.]+')" || return 1
-  printf "%s\n" "${version_string}" | while IFS=. read -r num1 num2 num3; do
-    { [ "${num1}" -ge 0 ] && [ "${num2}" -ge 5 ] && [ "${num3}" -ge 0 ]; } || return 1
-  done
+    version_string="$(nvim --version | grep -Eo 'NVIM.*v[0-9.]+' -m 1 | grep -Eo '[0-9.]+')" || return 1
+    printf "%s\n" "${version_string}" | while IFS=. read -r num1 num2 num3; do
+        { [ "${num1}" -ge 0 ] && [ "${num2}" -ge 5 ] && [ "${num3}" -ge 0 ]; } || return 1
+    done
 }
 
-_copy_config() {
-  printf "%s\n" "Linking config"
-  printf "%s\n" "Old nvim config will be changed to nvim.bak if exists! :0"
+_startup() {
 
-  # copying config
-  if [ -d "${_CONFIG_PATH}" ]; then
-    printf "%s\n" "Nvim Directory exists"
-    if [ "${_NO_BACKUP}" = "true" ]; then
-      printf "%s\n" "Skipping backup as --no-backup flag was passed.."
-      [ "${_UPDATE}" = "false" ] && rm -rf "${_CONFIG_PATH}"
+    printf "  + %s\n" "$(prompt -i "Checking nvim version")"
+    if _NVIM="$(command -v nvim)"; then
+        if _check_nvim_version; then
+            printf "  + %s\n" "$(prompt -i "NeoVim will open now")"
+            sleep 1
+            "${_NVIM}" +'autocmd User PackerComplete ++once lua print "Waiting for PackerCompile.." vim.cmd "PackerCompile"' \
+                +'autocmd User PackerCompileDone ++once quitall' \
+                +'lua print "Wait for PackerUpdate and PackerCompile to complete.." require "pluginList" vim.cmd "PackerUpdate"'
+            "${_NVIM}"
+        else
+            prompt -e "Error: Neovim is installed, but version is lower than 0.5.x, install Neovim >= 5.x and then run nvim & do :PackerSync"
+        fi
     else
-      printf "%s\n" "Taking backup of existing config.."
-      mv "${_CONFIG_PATH}" "${_BACKUP_PATH}" || {
-        printf "\n%s\n" "Error: Cannot move ${_CONFIG_PATH} to ${_BACKUP_PATH}"
-        printf "\n%s\n" "Take backup manually or use -b/--backup to provide non-empty path or use -nb/--no-backup to skip backup."
-        exit 1
-      }
+        prompt -e "Error: Neovim is not installed, install Neovim >= 5.x and then run neovim & do :PackerSync"
     fi
-  else
-    printf "%s\n" "Nvim config doesn't exist, creating it now"
-  fi
-
-  mkdir -p "${_CONFIG_PATH}" || {
-    printf "%s\n" "Error: Cannot create folder ${_CONFIG_PATH}"
-    exit 1
-  }
-
-  { cp -r init.lua lua "${_CONFIG_PATH}"/; } || {
-    printf "Error: Couldn't copy nvim config\n"
-    exit 1
-  }
-  return 0
 }
 
-_setup_terminal_shell() {
-  _mappings_file="${_CONFIG_PATH}/lua/mappings.lua"
-  # only ask for shellname if running in terminal
-  if [ -t 1 ]; then
-    if chsh -l 2>/dev/null 1>&2; then
-      printf "\nAvailable Shells:\n"
-      chsh -l | nl
-      printf "\n%s\n" "Which shell do you want to use? (Eg. 2)"
-      printf "\t%s\n" "[ Enter nothing for current shell ( $_CURRENT_SHELL ) ]"
-      read -r shellnum
-      [ "${shellnum}" -gt 0 ] 2>/dev/null && _SHELLPATH="$(chsh -l | sed -n "$shellnum p")"
-    fi
-  fi
+_install() {
+    prompt -w "-> Checking dependencies..."
+    _check_dependencies
+    prompt -w "-> Checking for previous confs..."
+    _check_prev_conf
+    prompt -w "-> Cloning..."
+    _fetch
 
-  # don't try to do any changes user wants their default shell in nvim
-  if [ -n "$_SHELLPATH" ]; then
-    # Reference: https://stackoverflow.com/a/4247319
-    # \( & \) will use regex brackets (for later reference with \1)
-    # ( & ) will match text brackets
-    if "${_SED}" --posix -i'.bak' -e "s=^\(map(.* \+*terminal\) \(.*)\)=\1$_SHELLPATH \2=g" "${_mappings_file}"; then
-      printf "%s\n" "=> Neovim shell changed to $_SHELLPATH successfully!"
-    else
-      printf "%s\n" "Cannot edit with sed, edit ${_mappings_file} manually to replace bash with $_SHELLPATH."
+    if [[ "$do_startup" == "true" ]]; then
+        prompt -w "-> Loading nvim..."
+        _startup
     fi
-    rm -f "${_mappings_file}".bak # delete backup file created by sed
-  fi
-  printf "%s\n" "=> Neovim shell will be ${_SHELLPATH:-${_CURRENT_SHELL}}"
-  return 0
 }
-_setup_arguments() {
-  # default variables to be used
-  _CONFIG_PATH="${XDG_CONFIG_HOME:-${HOME}/.config}/nvim"
-  _UPDATE=""
-  _BACKUP_PATH="${_CONFIG_PATH}.bak"
-  _NO_BACKUP="false"
-  _CURRENT_SHELL="${SHELL##*/}"
 
-  _check_longoptions() {
-    [ -z "${2}" ] &&
-      printf '%s: %s: option requires an argument\nTry '"%s -h/--help"' for more information.\n' "${0##*/}" "${1}" "${0##*/}" &&
-      exit 1
-    return 0
-  }
-
-  while [ $# -gt 0 ]; do
-    case "${1}" in
-    -h | --help) _usage ;;
-    -i | --install) _UPDATE="false" ;;
-    -u | --update) _UPDATE="true" ;;
-    -b | --backup)
-      _check_longoptions "${1}" "${2}"
-      _BACKUP_PATH="${2}" && shift
-      ;;
-    -nb | --nobackup) _NO_BACKUP="true" ;;
-    esac
-    shift
-  done
-
-  [ -z "${_UPDATE}" ] && {
-    printf "%s\n" "Error: Either -i/--install or -u/--update flag must be used."
-    printf "%s\n" "See -h/--help for more info."
-    exit 1
-  }
-
-  printf "%s\n" \
-    "CONFIG PATH: ${_CONFIG_PATH}
-$(if [ "${_NO_BACKUP}" = "true" ]; then
-      printf "SKIPPING CONFIG BACKUP !\n"
+_clean_backups() {
+    prompt -w "-> Looking for backups..."
+    if [[ -d "${BACKUP_PATH}" ]]; then
+        if [[ -z "$(ls -A ${BACKUP_PATH})" ]]; then
+            printf "  + %s\n" "$(prompt -w "No backups were found")"
+        else
+            printf "  + %s\n" "$(prompt -i "Backups were found, removing them...")"
+            rm -rf "${BACKUP_PATH}"
+        fi
     else
-      printf "%s\n" "CONFIG BACKUP PATH: ${_BACKUP_PATH}"
-    fi)
-CURRENT SHELL: ${_CURRENT_SHELL}
-"
+        printf "  + %s\n" "$(prompt -w "No backups were found")"
+    fi
+}
 
-  return 0
+_update() {
+
+    prompt -w "-> Checking if conf is eligible for being updated..."
+
+    if [[ -z "$(ls -A ${nvchad_path})" ]]; then
+        printf "  + %s\n" "$(prompt -e "Error: there is nothing to update")"
+    else
+        printf "  + %s\n" "$(prompt -i "Updating config")"
+        mkdir -p ${TMP_NVCHAD}
+        for to_preservef in "${!preserved_files[@]}"; do
+            file="${nvchad_path}${preserved_files[to_preservef]}"
+            printf "    + %s\n" "$(prompt -i "saving file: ${preserved_files[to_preservef]}")"
+            if [[ -e "${file}" ]]; then
+                mv "${file}" "${TMP_NVCHAD}"
+            fi
+        done
+
+        do_startup="false"
+        _install
+
+        for to_preservef in "${!preserved_files[@]}"; do
+            destination_file="${nvchad_path}${preserved_files[to_preservef]}"
+            file_name=$(basename "${preserved_files[to_preservef]}")
+            location_path=$(dirname "${destination_file}")
+            stored_file="${TMP_NVCHAD}${file_name}"
+            printf "    + %s\n" "$(prompt -i "restoring file: ${preserved_files[to_preservef]}")"
+
+            if [[ -e "${stored_file}" ]]; then
+                rm -rf "${destination_file}"
+                mkdir -p "${location_path}"
+                mv "${stored_file}" "${destination_file}"
+            fi
+        done
+        rm -rf "${TMP_NVCHAD}"
+    fi
+}
+
+_skip_ahead() {
+    amount=$1
+    skip=$((skip + amount))
+}
+
+_reorder_array() {
+    local arr=("$@")
+
+    for i in "${!arr[@]}"; do
+        new_array+=("${arr[i]}")
+    done
+    arr=("${new_array[@]}")
+    unset new_array
+
+    echo "${arr[@]}"
+}
+
+_parse_args() {
+    local func_args=$1
+    local argv=("$@")
+
+    unset 'argv[0]' # becuase arg1 is $func_arg
+    for i in "${!argv[@]}"; do new_array+=("${argv[i]}"); done
+    argv=("${new_array[@]}")
+    unset new_array
+
+    local argc=${#argv[@]}
+
+    _skip_ahead() {
+        amount=$1
+        skip=$((skip + amount))
+    }
+
+    _clean_arg() {
+        arg=$1
+        if [[ "$arg" == "--"* ]]; then
+            echo "${arg:2}"
+        elif [[ "$arg" == "-"* ]]; then
+            echo "${arg:1}"
+        fi
+    }
+
+    for j in "${!argv[@]}"; do
+        if [[ ${skip} -gt 0 ]]; then
+            left=$((argc - j))
+            while [[ ${skip} > ${left} ]]; do ((skip--)); done
+            skip=$((skip - 1))
+            continue
+        fi
+
+        case ${argv[j]} in
+        --*) # End of all options.
+            case ${argv[j]} in
+            --) # End of all options.
+                break
+                ;;
+            *)
+                # eval "${func_args}" "$(_clean_arg "${argv[j]}")" "$j"
+                eval "${func_args}" "${argv[j]}" "$j"
+                ;;
+            esac
+            ;;
+        -*)
+            if [[ ${#argv[j]} -le 2 ]]; then
+                eval "${func_args}" "${argv[j]}" "$j"
+            else
+                tangled_args=$(_clean_arg "${argv[j]}")
+                for ((k = 0; k < ${#tangled_args}; k++)); do
+                    eval "${func_args}" "-${tangled_args:$k:1}" "$j"
+                done
+            fi
+            ;;
+        *)
+            eval "${func_args}" "${argv[j]}" "$j"
+            ;;
+        esac
+    done
 }
 
 main() {
-  [ $# = 0 ] && _usage
+    local argvs=("$@")
+    local argc=${#argvs[@]}
+    local counter=0
 
-  _check_install_dependencies
+    _set_params() {
+        argc=${#argvs[@]}
+        counter=0
+    }
 
-  _setup_arguments "${@}"
-  _copy_config
-  [ "${_UPDATE}" = "false" ] && _setup_terminal_shell
+    _free_arg() {
+        local index=$1
+        unset 'argvs[index-counter]'
+        argvs=($(_reorder_array "${argvs[@]}"))
+        ((counter++))
+    }
 
-  # install all plugins + compile them
-  if _NVIM="$(command -v nvim)"; then
-    if _check_nvim_version; then
-      printf "\n%s\n" "=> Neovim will now open." && sleep 1
-      "${_NVIM}" +'autocmd User PackerComplete ++once lua print "Waiting for PackerCompile.." vim.cmd "PackerCompile"' \
-        +'autocmd User PackerCompileDone ++once quitall' \
-        +'lua print "Wait for PackerUpdate and PackerCompile to complete.." require "pluginList" vim.cmd "PackerUpdate"'
-      "${_NVIM}"
-    else
-      printf "Error: Neovim is installed, but version is lower than 0.5.x, install Neovim >= 5.x and then run nvim & do :PackerSync\n."
-    fi
-  else
-    printf "Error: Neovim is not installed, install Neovim >= 5.x and then run neovim & do :PackerSync.\n"
-  fi
+    assert_aditional_args() {
+        var=$1   # flag
+        index=$2 # flag's index
+        case ${var} in
+        -p=* | --path=*)
+            nvchad_path="${var#*=}"
+            _free_arg "${index}"
+            ;;
+        -s | --skip-startup)
+            do_startup="false"
+            _free_arg "${index}"
+            ;;
+        esac
+    }
+
+    assert_args() {
+        var=$1   # flag
+        index=$2 # flag's index
+        case ${var} in
+        -h | --help)
+            _usage
+            ;;
+        -i | --install)
+            prompt -i "Installing NvChad..."
+            _install
+            ;;
+        -r | --remove)
+            prompt -i "Removing NvChad..."
+            _remove
+            ;;
+        -u | --update)
+            prompt -i "Updating NvChad..."
+            _update
+            ;;
+        -c | --clean-backups)
+            prompt -i "Cleaning NvChad backups..."
+            _clean_backups
+            ;;
+        *)
+            prompt -w "Warning: --unknown command '${var}'"
+            ;;
+        esac
+    }
+
+    _set_params
+    _parse_args "assert_aditional_args" "${argvs[@]}"
+    _set_params
+    _parse_args "assert_args" "${argvs[@]}"
 }
 
-main "${@}"
+init() {
+    if [ $# -eq 0 ]; then
+        prompt -e "ERROR: This script needs at least one argument"
+    else
+        main "${@}"
+    fi
+}
+
+init "${@}"