Complete rewrite

This commit is contained in:
Kristofers Solo 2023-02-24 16:22:44 +02:00
parent 341d3a553c
commit 60de4b2394
5 changed files with 383 additions and 137 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
larbs.sh
karbs.old

331
karbs
View File

@ -1,66 +1,289 @@
#!/bin/sh
# Kristofers Auto Rice Boostrapping Script (KARBS)
# Kristofer's Auto Rice Bootstrapping Script (KARBS)
# by Kristofers Solo
# License: GNU GPLv3
echo "Choose display server (X11 / Wayland)[1/2]: "
read -r USER_INPUT
### OPTIONS AND VARIABLES ###
while getopts ":a:r:b:p:h" o; do case "${o}" in
h) printf "Optional arguments for custom use:\\n -r: Dotfiles repository (local file or url)\\n -p: Dependencies and programs csv (local file or url)\\n -a: AUR helper (must have pacman-like syntax)\\n -h: Show this message\\n" && exit 1 ;;
r) dotfilesrepo=${OPTARG} && git ls-remote "$dotfilesrepo" || exit 1 ;;
b) repobranch=${OPTARG} ;;
p) progsfile=${OPTARG} ;;
a) aurhelper=${OPTARG} ;;
*) printf "Invalid option: -%s\\n" "$OPTARG" && exit 1 ;;
esac done
# Get display server type from user
if [ "$USER_INPUT" = 1 ]; then
DISPLAY_SERVER="X11"
elif [ "$USER_INPUT" = 2 ]; then
DISPLAY_SERVER="wayland"
else
echo "Wrong input. Please try again."
exit
fi
[ -z "$dotfilesrepo" ] && dotfilesrepo="https://github.com/kristoferssolo/solorice.git"
# [ -z "$progsfile" ] && progsfile="https://raw.githubusercontent.com//LARBS/master/progs.csv"
[ -z "$progsfile" ] && progsfile="https://github.com/kristoferssolo/karbs/blob/main/pkg-files/X11-pkgs.csv"
[ -z "$aurhelper" ] && aurhelper="paru"
[ -z "$repobranch" ] && repobranch="master"
### FUNCTIONS ###
# Install paru
if pacman -Q paru; then
:
else
sudo pacman -S --noconfirm rust-src git wget fakeroot
git clone https://aur.archlinux.org/paru-bin
cd paru-bin || exit
makepkg -si
cd ..
rm -rf paru-bin
fi
installpkg() { pacman --noconfirm --needed -S "$1" >/dev/null 2>&1; }
FILE="pkg-files/$DISPLAY_SERVER-pkgs"
error() {
printf "%s\n" "$1" >&2
exit 1
}
if [ -f "$FILE" ]; then
paru -Syu --noconfirm --needed - < $FILE
else
curl -LO https://raw.githubusercontent.com/kristoferssolo/karbs/main/$FILE
paru -Syu --noconfirm --needed - < $DISPLAY_SERVER-pkgs
rm -f $DISPLAY_SERVER-pkgs
fi
welcomemsg() {
dialog --title "Welcome!" --msgbox "Welcome to Kristofer's Auto-Rice Bootstrapping Script!\\n\\nThis script will automatically install a fully-featured Linux desktop, which I use as my main machine.\\n\\n-Kristofers" 10 60
git clone https://github.com/kristoferssolo/solorice "$HOME/solorice"
cp -raf "$HOME"/solorice/{./config,./local,.zshenv} "$HOME"
git clone https://github.com/kristoferssolo/SoloVim "$HOME"/.config/nvim
rm -rf "$HOME"/solorice
mkdir -p "$HOME"/{Downloads,Documents,Videos,Music,Pictures/screenshots}
dialog --colors --title "Important Note!" --yes-label "All ready!" --no-label "Return..." --yesno "Be sure the computer you are using has current pacman updates and refreshed Arch keyrings.\\n\\nIf it does not, the installation of some programs might fail." 8 70
}
if [ $DISPLAY_SERVER = "wayland" ]; then
rm -rf "$HOME"/.config/{awesome,picom,sx,zsh/.zprofile-X11}
mv "$HOME"/.config/zsh/.zprofile-wayland "$HOME"/.config/zsh/.zprofile
chsh -s /bin/zsh
zsh
Hyprland
else
rm -rf "$HOME"/.config/{hypr,waybar,zsh/.zprofile-wayland}
mv "$HOME"/.config/zsh/.zprofile-X11 "$HOME"/.config/zsh/.zprofile
git clone https://github.com/streetturtle/awesome-wm-widgets "$HOME"/.config/awesome/awesome-wm-widgets
chsh -s /bin/zsh
zsh
echo -e "\n\n\033[1;31mFor weather widget to work, enter API-key from https://openweathermap.org, latitude and longitude in '~/.config/awesome/weather' file, each on seperate line.\033[0m"
echo "API-key"
echo "latitude"
echo "longitude"
echo -e "\nEverything else is ready to go. You can run 'sx' or reboot."
fi
getuserandpass() {
# Prompts user for new username an password.
name=$(dialog --inputbox "First, please enter a name for the user account." 10 60 3>&1 1>&2 2>&3 3>&1) || exit 1
while ! echo "$name" | grep -q "^[a-z_][a-z0-9_-]*$"; do
name=$(dialog --no-cancel --inputbox "Username not valid. Give a username beginning with a letter, with only lowercase letters, - or _." 10 60 3>&1 1>&2 2>&3 3>&1)
done
pass1=$(dialog --no-cancel --passwordbox "Enter a password for that user." 10 60 3>&1 1>&2 2>&3 3>&1)
pass2=$(dialog --no-cancel --passwordbox "Retype password." 10 60 3>&1 1>&2 2>&3 3>&1)
while ! [ "$pass1" = "$pass2" ]; do
unset pass2
pass1=$(dialog --no-cancel --passwordbox "Passwords do not match.\\n\\nEnter password again." 10 60 3>&1 1>&2 2>&3 3>&1)
pass2=$(dialog --no-cancel --passwordbox "Retype password." 10 60 3>&1 1>&2 2>&3 3>&1)
done
}
usercheck() {
! { id -u "$name" >/dev/null 2>&1; } ||
dialog --colors --title "WARNING!" --yes-label "CONTINUE" --no-label "No wait..." --yesno "The user \`$name\` already exists on this system. KARBS can install for a user already existing, but it will \\Zboverwrite\\Zn any conflicting settings/dotfiles on the user account.\\n\\nKARBS will \\Zbnot\\Zn overwrite your user files, documents, videos, etc., so don't worry about that, but only click <CONTINUE> if you don't mind your settings being overwritten.\\n\\nNote also that KARBS will change $name's password to the one you just gave." 14 70
}
preinstallmsg() {
dialog --title "Let's get this party started!" --yes-label "Let's go!" --no-label "No, nevermind!" --yesno "The rest of the installation will now be totally automated, so you can sit back and relax.\\n\\nIt will take some time, but when done, you can relax even more with your complete system.\\n\\nNow just press <Let's go!> and the system will begin installation!" 13 60 || {
clear
exit 1
}
}
adduserandpass() {
# Adds user `$name` with password $pass1.
dialog --infobox "Adding user \"$name\"..." 4 50
useradd -m -g wheel -s /bin/zsh "$name" >/dev/null 2>&1 ||
usermod -aG wheel "$name"
export repodir="/home/$name/.local/src"
mkdir -p "$repodir"
chown -R "$name":wheel "$(dirname "$repodir")"
echo "$name:$pass1" | chpasswd
unset pass1 pass2
}
refreshkeys() {
case "$(readlink -f /sbin/init)" in
*systemd*)
dialog --infobox "Refreshing Arch Keyring..." 4 40
grep -q "^\[multilib\]" /etc/pacman.conf ||
echo "[multilib]
Include = /etc/pacman.d/mirrorlist" >>/etc/pacman.conf
pacman --noconfirm -S archlinux-keyring >/dev/null 2>&1
;;
*)
dialog --infobox "Enabling Arch Repositories..." 4 40
pacman --noconfirm --needed -S artix-keyring artix-archlinux-support >/dev/null 2>&1
grep -q "^\[lib32\]" /etc/pacman.conf ||
echo "[lib32]
Include = /etc/pacman.d/mirrorlist" >>/etc/pacman.conf
grep -q "^\[universe\]" /etc/pacman.conf ||
echo "[universe]
Server = https://universe.artixlinux.org/\$arch" >>/etc/pacman.conf
for repo in extra community multilib; do
grep -q "^\[$repo\]" /etc/pacman.conf ||
echo "[$repo]
Include = /etc/pacman.d/mirrorlist-arch" >>/etc/pacman.conf
done
pacman -Sy >/dev/null 2>&1
pacman-key --populate archlinux >/dev/null 2>&1
;;
esac
}
newperms() { # Set special doas settings for install (or after).
echo "$" >>/etc/doas.conf
}
manualinstall() { # Installs $1 manually. Used only for AUR helper here.
# Should be run after repodir is created and var is set.
dialog --infobox "Installing \"$1\", an AUR helper..." 4 50
doas -u "$name" mkdir -p "$repodir/$1"
doas -u "$name" git clone --depth 1 "https://aur.archlinux.org/$1.git" "$repodir/$1" >/dev/null 2>&1 ||
{
cd "$repodir/$1" || return 1
doas -u "$name" git pull --force origin master
}
cd "$repodir/$1" || exit
doas -u "$name" -D "$repodir/$1" makepkg --noconfirm -si >/dev/null 2>&1 || return 1
}
maininstall() { # Installs all needed programs from main repo.
dialog --title "KARBS Installation" --infobox "Installing \`$1\` ($n of $total). $1 $2" 5 70
installpkg "$1"
}
gitmakeinstall() {
progname="$(basename "$1" .git)"
dir="$repodir/$progname"
dialog --title "KARBS Installation" --infobox "Installing \`$progname\` ($n of $total) via \`git\` and \`make\`. $(basename "$1") $2" 5 70
doas -u "$name" git clone --depth 1 "$1" "$dir" >/dev/null 2>&1 || {
cd "$dir" || return 1
doas -u "$name" git pull --force origin master
}
cd "$dir" || exit 1
make >/dev/null 2>&1
make install >/dev/null 2>&1
cd /tmp || return 1
}
aurinstall() {
dialog --title "KARBS Installation" --infobox "Installing \`$1\` ($n of $total) from the AUR. $1 $2" 5 70
echo "$aurinstalled" | grep -q "^$1$" && return 1
doas -u "$name" "$aurhelper" -S --noconfirm "$1" >/dev/null 2>&1
}
pipinstall() {
dialog --title "KARBS Installation" --infobox "Installing the Python package \`$1\` ($n of $total). $1 $2" 5 70
[ -x "$(command -v "pip")" ] || installpkg python-pip >/dev/null 2>&1
yes | pip install "$1"
}
installationloop() {
([ -f "$progsfile" ] && cp "$progsfile" /tmp/progs.csv) || curl -Ls "$progsfile" | sed '/^#/d' >/tmp/progs.csv
total=$(wc -l </tmp/progs.csv)
aurinstalled=$(pacman -Qqm)
while IFS=, read -r tag program comment; do
n=$((n + 1))
echo "$comment" | grep -q "^\".*\"$" && comment="$(echo "$comment" | sed -E "s/(^\"|\"$)//g")"
case "$tag" in
"A") aurinstall "$program" "$comment" ;;
"G") gitmakeinstall "$program" "$comment" ;;
"P") pipinstall "$program" "$comment" ;;
*) maininstall "$program" "$comment" ;;
esac
done </tmp/progs.csv
}
putgitrepo() { # Downloads a gitrepo $1 and places the files in $2 only overwriting conflicts
dialog --infobox "Downloading and installing config files..." 4 60
[ -z "$3" ] && branch="master" || branch="$repobranch"
dir=$(mktemp -d)
[ ! -d "$2" ] && mkdir -p "$2"
chown "$name":wheel "$dir" "$2"
doas -u "$name" git clone --recursive -b "$branch" --depth 1 --recurse-submodules "$1" "$dir" >/dev/null 2>&1
doas -u "$name" cp -rfT "$dir" "$2"
}
systembeepoff() {
dialog --infobox "Getting rid of that retarded error beep sound..." 10 50
rmmod pcspkr
echo "blacklist pcspkr" >/etc/modprobe.d/nobeep.conf
}
finalize() {
dialog --infobox "Preparing welcome message..." 4 50
dialog --title "All done!" --msgbox "Congrats! Provided there were no hidden errors, the script completed successfully and all the programs and configuration files should be in place.\\n\\nTo run the new graphical environment, log out and log back in as your new user, then run the command \"startx\" to start the graphical environment (it will start automatically in tty1).\\n\\n.t Luke" 12 80
}
### THE ACTUAL SCRIPT ###
### This is how everything happens in an intuitive format and order.
# Check if user is root on Arch distro. Install dialog.
pacman --noconfirm --needed -Sy dialog || error "Are you sure you're running this as the root user, are on an Arch-based distribution and have an internet connection?"
# Welcome user and pick dotfiles.
welcomemsg || error "User exited."
# Get and verify username and password.
getuserandpass || error "User exited."
# Give warning if user already exists.
usercheck || error "User exited."
# Last chance for user to back out before install.
preinstallmsg || error "User exited."
### The rest of the script requires no user input.
# Refresh Arch keyrings.
refreshkeys || error "Error automatically refreshing Arch keyring. Consider doing so manually."
for x in curl ca-certificates base-devel git ntp zsh; do
dialog --title "KARBS Installation" --infobox "Installing \`$x\` which is required to install and configure other programs." 5 70
installpkg "$x"
done
dialog --title "KARBS Installation" --infobox "Synchronizing system time to ensure successful and secure installation of software..." 4 70
ntpdate 0.us.pool.ntp.org >/dev/null 2>&1
adduserandpass || error "Error adding username and/or password."
# Allow user to run doas without password. Since AUR programs must be installed
# in a fakeroot environment, this is required for all builds with AUR.
newperms "permit nopass :wheel"
# Make pacman colorful, concurrent downloads and Pacman eye-candy.
grep -q "ILoveCandy" /etc/pacman.conf || sed -i "/#VerbosePkgLists/a ILoveCandy" /etc/pacman.conf
sed -Ei "s/^#(ParallelDownloads).*/\1 = 5/;/^#Color$/s/#//" /etc/pacman.conf
# Use all cores for compilation.
sed -i "s/-j2/-j$(nproc)/;/^#MAKEFLAGS/s/^#//" /etc/makepkg.conf
manualinstall "$aurhelper" || error "Failed to install AUR helper."
# The command that does all the installing. Reads the progs.csv file and
# installs each needed program the way required. Be sure to run this only after
# the user has been created and has privileges to run doas without a password
# and all build dependencies are installed.
installationloop
dialog --title "KARBS Installation" --infobox "Finally, installing \`libxft-bgra\` to enable color emoji in suckless software without crashes." 5 70
yes | doas -u "$name" "$aurhelper" -S libxft-bgra-git >/dev/null 2>&1
# Install the dotfiles in the user's home directory
putgitrepo "$dotfilesrepo" "/home/$name" "$repobranch"
rm -f "/home/$name/README.md" "/home/$name/LICENSE"
# make git ignore deleted LICENSE & README.md files
git update-index --assume-unchanged "/home/$name/README.md" "/home/$name/LICENSE"
# Most important command! Get rid of the beep!
systembeepoff
# Make zsh the default shell for the user.
chsh -s /bin/zsh "$name" >/dev/null 2>&1
doas -u "$name" mkdir -p "/home/$name/.cache/zsh/"
doas -u "$name" mkdir -p "/home/$name/.config/abook/"
doas -u "$name" mkdir -p "/home/$name/.config/mpd/playlists/"
# dbus UUID must be generated for Artix runit.
dbus-uuidgen >/var/lib/dbus/machine-id
# Use system notifications for Brave on Artix
echo "export \$(dbus-launch)" >/etc/profile.d/dbus.sh
# Tap to click
[ ! -f /etc/X11/xorg.conf.d/40-libinput.conf ] && printf 'Section "InputClass"
Identifier "libinput touchpad catchall"
MatchIsTouchpad "on"
MatchDevicePath "/dev/input/event*"
Driver "libinput"
# Enable left mouse button by tapping
Option "Tapping" "on"
EndSection' >/etc/X11/xorg.conf.d/40-libinput.conf
# Fix fluidsynth/pulseaudio issue.
grep -q "OTHER_OPTS='-a pulseaudio -m alsa_seq -r 48000'" /etc/conf.d/fluidsynth ||
echo "OTHER_OPTS='-a pulseaudio -m alsa_seq -r 48000'" >>/etc/conf.d/fluidsynth
# Last message! Install complete!
finalize
clear

View File

@ -1,83 +0,0 @@
alacritty
arc-solid-gtk-theme
awesome
bat
btop
catdoc
chafa
docx2txt
dracula-gtk-theme
dracula-icons-git
epub-thumbnailer-git
exa
fakeroot
fastfetch
feh
ffmpegthumbnailer
flameshot
git
gnumeric
imagemagick
lazygit
lf
librewolf-bin
linux-headers
make
man-db
mpv
ncdu
neovim
network-manager-applet
networkmanager
nextcloud
nextcloud-client
nodejs
nsxiv
ntfs-3g
numlockx
pandoc-bin
papirus-icon-theme
picom
pipewire
pipewire-jack
pipewire-pulse
pipewire-v4l2
pkgconf
playerctl
polkit-gnome
poppler
pulsemixer
redshift
reflector
ripgrep
skim
spacefm
sshfs
starship
sx
tealdeer
transmission-cli
ueberzug
unicode-emoji
unimatrix-git
unrar
unzip
v4l2loopback-dkms
v4l2loopback-utils
wget
wireplumber
xclip
xorg-xinit
xorg-xinput
xorg-xwininfo
youtube-dl
zathura
zathura-cb
zathura-djvu
zathura-pdf-mupdf
zathura-ps
zip
zsh
zsh-autosuggestions
zsh-fast-syntax-highlighting
zsh-history-substring-search

105
pkg-files/X11-pkgs.csv Normal file
View File

@ -0,0 +1,105 @@
#TAG,NAME IN REPO (or git url),PURPOSE (should be a verb phrase to sound right while installing),
,alacritty,"is a cross-platform, GPU-accelerated terminal emulator."
,arandr,"provides a simple visual front end for XRandR 1.2."
,arc-solid-gtk-theme,"is a flat theme for GTK."
,atool,"is a script for managing file archives of various types."
,autopep8,"is a tool that automatically formats Python code to conform to the PEP 8 style guide."
,awesome,"is highly configurable framework window manager."
,bat,"is cat clone with syntax highlighting and git integration."
,btop,"is monitor of system resources, bpytop ported to C++."
,catdoc,"is a convertor for Microsoft Word, Excel, PowerPoint and RTF Files to text."
,chafa,"is image-to-text converter supporting a wide range of symbols and palettes, transparency, animations, etc."
,dmenu,"is generic menu for X"
,docx2txt,"recovers text from DOCX files, with good formatting."
,dosfstools,"is DOS filesystem utilities."
,dunst,"is customizable and lightweight notification-daemon."
,exa,"is ls replacement."
,exfat-utils,"are utilities for exFAT file system."
,fakeroot,"is a tool for simulating superuser privileges."
,ffmpeg,"is complete solution to record, convert and stream audio and video."
,ffmpegthumbnailer,"is lightweight video thumbnailer that can be used by file managers."
,flake8,"is the modular source code checker: pep8, pyflakes and co."
,flameshot,"is powerful yet simple to use screenshot software."
,git,"is the fast distributed version control system."
,glow,"is command-line markdown renderer."
,gnome-epub-thumbnailer,"is thumbnailer for EPub and MOBI books."
,gnumeric,"is a GNOME Spreadsheet Program."
,gzip,"is GNU compression utility."
,imagemagick,"in an image viewing/manipulation program."
,lazygit,"is simple terminal UI for git commands."
,libnotify,"is a library for sending desktop notifications."
,linux-headers,"are Headers and scripts for building modules for the Linux kernel"
,luacheck,"is a tool for linting and static analysis of Lua code."
,luarocks,"is deployment and management system for Lua modules."
,make,"are GNU make utility to maintain groups of programs."
,man-db,"is a utility for reading man pages."
,mediainfo,"supplies technical and tag information about a video or audio file (CLI interface)."
,moreutils,"is a growing collection of the unix tools that nobody thought to write thirty years ago."
,mpv,"is a free, open source, and cross-platform media player."
,ncdu,"is disk usage analyzer with an ncurses interface."
,neovim,"is a fork of Vim aiming to improve user experience, plugins, and GUIs."
,network-manager-applet,"is applet for managing network connections."
,nextcloud-client,"is Nextcloud desktop client."
,nodejs,"is evented I/O for V8 javascript."
,nsxiv,"is Neo (or New or Not) Simple (or Small or Suckless) X Image Viewer."
,ntfs-3g,"is NTFS filesystem driver and utilities."
,odt2txt,"extracts the text out of OpenDocument Texts."
,papirus-icon-theme,"is Papirus icon theme."
,picom,"is X compositor that may fix tearing issues."
,pipewire,"is low-latency audio/video router and processor."
,pipewire-jack,"is low-latency audio/video router and processor - JACK support."
,pipewire-pulse,"is low-latency audio/video router and processor - PulseAudio replacement."
,pipewire-v4l2,"is low-latency audio/video router and processor - V4L2 interceptor."
,pkgconf,"is package compiler and linker metadata toolkit"
,playerctl,"is mpris media player controller and lib for spotify, vlc, audacious, bmp, xmms2, and others."
,polkit-gnome,"is legacy polkit authentication agent for GNOME."
,poppler,"is PDF rendering library based on xpdf 3.0."
,pulsemixer,"is CLI and curses mixer for pulseaudio."
,python-pip,"is the PyPA recommended tool for installing Python packages."
,redshift,"adjusts the color temperature of your screen according to your surroundings."
,reflector,"is a Python 3 module and script to retrieve and filter the latest Pacman mirror list."
,ripgrep,"is a search tool that combines the usability of ag with the raw speed of grep."
,skim,"is a Fuzzy Finder in Rust."
,slock,"is a simple screen locker for X."
,starship,"is a cross-shell prompt for astronauts."
,stig,"is TUI and CLI client for the Transmission daemon."
,tealdeer,"is a fast tldr client in Rust."
,transmission-cli,"is fast, easy, and free BitTorrent client (CLI tools, daemon and web client)."
,ttf-linux-libertine,"are Serif (Libertine) and Sans Serif (Biolinum) OpenType fonts with large Unicode coverage."
,ueberzug,"is a command line util which allows to display images in combination with X11."
,unicode-emoji,"is unicode Emoji Data Files."
,unrar,"is the RAR uncompression program."
,unzip,"for extracting and viewing files in .zip archives."
,v4l2loopback-utils,"is v4l2-loopback device utilities only."
,wget,"is network utility to retrieve files from the Web."
,wireplumber,"is session / policy manager implementation for PipeWire."
,xclip,"is command line interface to the X11 clipboard."
,xorg-xinit,"is X.Org initialisation program."
,xorg-xprop,"is property displayer for X."
,xorg-xwininfo,"is command-line utility to print information about windows on an X server."
,xwallpaper,"is wallpaper setting utility for X."
,yt-dlp,"is a youtube-dl fork with additional features and fixes."
,zathura,"is a minimalistic document viewer."
,zathura-cb,"adds comic book support to zathura."
,zathura-djvu,"adds DjVu support for Zathura."
,zathura-pdf-mupdf,"is PDF support for Zathura (MuPDF backend) (Supports PDF, ePub, and OpenXPS)."
,zathura-ps,"Adds ps support to zathura by using the libspectre library."
,zip,"is compressor/archiver for creating and modifying zipfiles."
,zsh,"is a very advanced and programmable command interpreter (shell) for UNIX."
,zsh-autosuggestions,"is Fish-like autosuggestions for zsh."
,zsh-history-substring-search,"is a ZSH port of Fish history search (up arrow)."
A,beautysh,"is a Bash beautifier for the masses."
A,doasedit-alternative,"Enables doers to edit non-user-editable files with an unprivileged editor."
A,dracula-gtk-theme,"is dark theme for GTK."
A,dracula-icons-git,"is Dark Icons Theme for Linux Desktops."
A,fastfetch-git,"like neofetch, but much faster because written in C."
A,htop-vim,"is interactive process viewer with a Vim keybindings patch."
A,lf,"is a terminal file manager inspired by ranger."
A,librewolf-bin,"is community-maintained fork of Firefox, focused on privacy, security and freedom.."
A,sc-im,"is a spreadsheet program based on SC."
A,spacefm,"is multi-panel tabbed file manager."
A,unimatrix-git,"is Python script to simulate the display from "The Matrix" in terminal. Uses half-width katakana unicode characters by default, but can use custom character sets."
A,v4l2loopback-dkms,"is v4l2-loopback device module sources."
A,zsh-autoswitch-virtualenv-git,"is ZSH plugin that switches python virtualenvs automatically as you move between directories."
A,zsh-fast-syntax-highlighting,"is optimized and extended zsh-syntax-highlighting."
G,https://github.com/kristoferssolo/SoloVim.git,"are my neovim configuration files."
Can't render this file because it has a wrong number of fields in line 2.