# -*- org-confirm-babel-evaluate: nil -*-
#+TITLE: Install a Phundrak-flavored Arch Linux
#+INCLUDE: headers.org
#+OPTIONS: auto-id:t
#+HTML_HEAD_EXTRA: <meta name="description" content="Phundrak-flavored Arch Linux" />
#+HTML_HEAD_EXTRA: <meta property="og:title" content="Phundrak-flavored Arch Linux" />
#+HTML_HEAD_EXTRA: <meta property="og:description" content="How to install a Phundrak-flavored Arch Linux" />
#+PROPERTY: header-args :exports code

* Table of Contents                                        :TOC_4_gh:noexport:
  :PROPERTIES:
  :CUSTOM_ID: h-400070eb-725f-4416-a4c6-da3053df750b
  :END:

- [[#introduction][Introduction]]
- [[#install-arch-linux][Install Arch Linux]]
  - [[#get-the-latest-live-system-with-fast-mirrors][Get the latest live system with fast mirrors]]
  - [[#install-the-system][Install the system]]
- [[#install-basic-packages][Install basic packages]]
- [[#execute-bootstrap][Execute bootstrap]]
  - [[#decrypt-private-yadm-files][Decrypt private yadm files]]
  - [[#get-a-correct-keyboard-layout][Get a correct keyboard layout]]
  - [[#set-our-locale][Set our locale]]
  - [[#create-some-folders][Create some folders]]
  - [[#set-users-shell-to-fish][Set user’s shell to fish]]
  - [[#install-yay-if-it-isnt-already-installed][Install =yay= if it isn’t already installed]]
  - [[#install-basic-packages-1][Install basic packages]]
  - [[#tangle-configuration-files-from-org-files][Tangle configuration files from Org files]]
  - [[#setting-up-emacs-installing-spacemacs][Setting up Emacs: Installing Spacemacs]]
  - [[#set-up-dotfiles][Set up dotfiles]]
    - [[#update-our-dotfiles-remotes][Update our dotfiles’ remotes]]
    - [[#get-envtpl][Get =envtpl=]]
    - [[#update-our-submodules][Update our submodules]]
    - [[#generate-our-alt-files][Generate our alt files]]
  - [[#installing-tryones-compton-fork][Installing Tryone’s Compton fork]]
  - [[#enable-some-of-our-services][Enable some of our services]]
    - [[#docker][Docker]]
    - [[#emacs][Emacs]]
    - [[#ssh-server][SSH server]]
    - [[#ly][Ly]]
    - [[#acpilight][Acpilight]]
    - [[#nordvpn][NordVPN]]
  - [[#symlink-some-system-config-files][Symlink some system config files]]
  - [[#install-packages-from-git][Install packages from git]]
    - [[#polybar-battery][Polybar Battery]]
    - [[#revealjs][Reveal.JS]]
  - [[#install-rust][Install Rust]]
    - [[#install-the-toolchains][Install the toolchains]]
    - [[#install-some-utilities][Install some utilities]]
  - [[#install-some-python-packages][Install some python packages]]
  - [[#install-go-packages][Install go packages]]
  - [[#set-up-chicken-scheme-interpretercompiler][Set up Chicken (Scheme interpreter/compiler)]]
  - [[#clean-the-pacman-and-yay-cache][Clean the =pacman= and =yay= cache]]
  - [[#export-configuration-file-from-org-files][Export configuration file from org files]]
  - [[#set-up-our-fish-shell][Set up our fish shell]]
    - [[#install-fisher][Install =fisher=]]
    - [[#install-our-extensions][Install our extensions]]

* Introduction
  :PROPERTIES:
  :CUSTOM_ID: h-12a4ef6d-13b6-4d1f-9e0f-a060b63b12d4
  :END:
  Here will be  presented what I do to  get my system up and running  on a fresh
  Arch Linux install.  These installation instructions were written  in order to
  get an Arch  Linux distribution up and running with  the same configuration as
  my main computer’s and my travelling laptop’s configuration.

* Install Arch Linux
  :PROPERTIES:
  :CUSTOM_ID: h-cfe21de6-15fa-477a-a5ff-6cd81dfead19
  :END:
  I usually install Arch  from the [[https://www.archlinux.org/download/][vanilla ISO]], however I  began using [[https://github.com/MatMoul/archfi][archfi]] to
  install easily  the distro (I’ve done  it so many  times, I know how  it works
  now). Usually,  my distros will be  installed on at least  two partitions, one
  dedicated to =/home=, the other to the root partition =/=.

  If the computer supports EFI bootloaders, the EFI partition will be mounted on
  =/boot=.  I generally  use rEFInd  as my  boot manager,  but if  you are  more
  comfortable with another one, just install what you want. Be aware that if you
  format your =/boot= partition, you will  delete all boot managers that already
  exist;  so, if  you are  dual-booting, *DO  NOT FORMAT  IT*. Yes,  I made  the
  mistake of wiping the Windows boot manager.

  The swap partition is always at least 4GB  large, and I should have a total of
  12GB of combined RAM  and swap. This means on my main computer  I have 16GB of
  RAM and 4GB of swap, but on my thinkpad I have 4GB of RAM and 8GB of swap.

** Get the latest live system with fast mirrors
   :PROPERTIES:
   :CUSTOM_ID: h-da7951ee-e39a-4a59-a05d-7b7fffdc7825
   :END:
   When you boot into the live ISO, execute the following command:
   #+BEGIN_SRC sh
     pacman -Sy reflector
     reflector -c France -c Germany -l 200 -p http -p https --sort rate \
               --save /etc/pacman.d/mirrorlist --verbose
   #+END_SRC
   This will update the  packages from your live ISO, and you  will get the best
   mirrors for your installation. Of course, change the countries accordingly to
   your location.

** Install the system
   :PROPERTIES:
   :CUSTOM_ID: h-9f9e1fe5-4726-486b-9875-5fcfd91d0bb0
   :END:
   Then you can use a custom script to  ease your installation of Arch if you do
   not wish to do it manually. Personally, I’ve done it several times already, I
   know  how the  distro works,  I just  want to  be able  to install  my distro
   quickly now.
   #+BEGIN_SRC sh
     wget archfi.sf.net/archfi
     # Or from matmoul.github.io/archfi if SourceForge is down
     sh archfi
   #+END_SRC
   Then, follow the instructions and install Arch Linux. Take the opportunity to
   install as many packages as you need,  mainly =yay= which I use as my package
   manager  (it   is  just  a  wrapper   for  =pacman=)  and  AUR   helper,  and
   =pacman-contrib= which will help us installing some packages later.

   Once your system is installed, reboot and remove your installation media from
   your computer.

* Install basic packages
  :PROPERTIES:
  :CUSTOM_ID: h-d2485595-3014-4151-a76c-63bc353359a8
  :END:
  We will need some basic packages in order to run the bootstrap file. So, let’s
  install =fish= (our shell running the script) and =git=.
  #+BEGIN_SRC sh
    sudo pacman -Sy fish git yadm
  #+END_SRC

* Execute bootstrap
  :PROPERTIES:
  :CUSTOM_ID: h-c13d132f-9e69-4bb0-838b-29c7c5611f11
  :HEADER-ARGS: :tangle ~/.config/yadm/bootstrap
  :END:
  =yadm= comes with  a very handy feature: its bootstrap  script. We can execute
  it by running the following command:
  #+BEGIN_SRC fish :tangle no
    yadm bootstrap
  #+END_SRC

  Notice these two header files, we can see  this is a fish script, hence why we
  need fish (which is my daily shell anyway).
  #+BEGIN_SRC fish
    #!/usr/bin/fish
    # -*- mode: fish -*-
  #+END_SRC
  Let’s take a look at what it does.

** Decrypt private yadm files
   :PROPERTIES:
   :CUSTOM_ID: h-2ce7e756-3dab-4c12-a3b3-d1b6f8d4805d
   :END:
   Some  private  files are  stored  encrypted  in  the  repository of  my  yadm
   dotfiles. I will need them later on during the bootstrap execution.
   #+BEGIN_SRC fish
   yadm decrypt
   #+END_SRC

** Get a correct keyboard layout
   :PROPERTIES:
   :CUSTOM_ID: h-89fb8f3a-6ec4-4701-a5d9-3e593c47ece9
   :END:
   I use  mainly the [[https://bepo.fr/wiki/Accueil][bépo]]  layout, a French  keyboard layout inspired  by Dvorak
   layouts,  however I  sometimes need  to switch  back to  the standard  French
   AZERTY or the American  QWERTY layout, so I make it so  the Menu key switches
   for me my layout between these three.  This makes it so my xorg configuration
   of my keyboard looks like this:
   #+BEGIN_SRC fish
     set keyboardconf \
     'Section "InputClass"
             Identifier "system-keyboard"
             MatchIsKeyboard "on"
             Option "XkbLayout" "fr,fr,us"
             Option "XkbModel" "pc104"
             Option "XkbVariant" "bepo,,"
             Option "XkbOptions" "grp:menu_toggle"
     EndSection'
   #+END_SRC
   So, let’s set it as our keyboard configuration.
   #+BEGIN_SRC fish
     printf "\n# Set keyboard layout #########################################################\n\n"
     echo $keyboardconf | sudo tee /etc/X11/xorg.conf.d/00-keyboard.conf
   #+END_SRC

** Set our locale
   :PROPERTIES:
   :CUSTOM_ID: h-48678405-93ae-41b6-b44b-285ab0da4e92
   :END:
   I use two main  locales, the French and US UTF-8 locales, and  I like to keep
   the Japanese locale activated just in case.
   #+BEGIN_SRC fish
     set mylocales "en_US.UTF-8 UTF-8" "fr_FR.UTF-8 UTF-8" "ja_JP.UTF-8 UTF-8"
   #+END_SRC
   Let’s enable these.
   #+BEGIN_SRC fish
     printf "\n# Set our locale ##############################################################\n\n"
     for item in $mylocales
         if test (grep -e "#$item" /etc/locale.gen)
             sudo sed -i "/$item/s/^#//g" /etc/locale.gen
         end
     end
   #+END_SRC

   This is my configuration I usually use when it comes to my locale.
   #+BEGIN_SRC fish
     set localeconf "LANG=en_US.UTF-8
     LC_COLLATE=C
     LC_NAME=fr_FR.UTF-8
     LC_NUMERIC=fr_FR.UTF-8
     LC_IDENTIFICATION=fr_FR.UTF-8
     LC_TELEPHONE=fr_FR.UTF-8
     LC_MONETARY=fr_FR.UTF-8
     LC_PAPER=fr_FR.UTF-8
     LC_ADDRESS=fr_FR.UTF-8
     LC_TIME=fr_FR.UTF-8
     LC_MEASUREMENT=fr_FR.UTF-8"
   #+END_SRC
   Let’s set it as our system’s locale.
   #+BEGIN_SRC fish
     echo $localeconf | sudo tee /etc/locale.conf
   #+END_SRC
   Now we can generate our locale!
   #+BEGIN_SRC fish
     printf "\n# Generate locale #############################################################\n\n"
     sudo locale-gen
   #+END_SRC

** Create some folders
   :PROPERTIES:
   :CUSTOM_ID: h-85ce90ff-56dc-469b-bf08-480ecf27acc4
   :END:
   Let’s create  some folders  we might  need for  mounting our  drives, Android
   devices and CDs.
   #+BEGIN_SRC fish
     printf "\n# Create directories for mounting #############################################\n\n"
     sudo mkdir -p /mnt/{USB,CD,Android}
     sudo chown $USER:(id -g $USER) /mnt/{USB,CD,Android}
   #+END_SRC

   We also need the following folder for our nano backups.
   #+BEGIN_SRC fish
     mkdir -p $HOME/.cache/nano/backups
   #+END_SRC

** Set user’s shell to fish
   :PROPERTIES:
   :CUSTOM_ID: h-c1a78394-c156-4a03-ae82-e5e9d4090dab
   :END:
   First of all, the bootstrap shell will set the user’s shell to fish.
   #+BEGIN_SRC fish
     printf "\n# Set fish as the default shell ###############################################\n\n"
     chsh -s /usr/bin/fish
   #+END_SRC

** Install =yay= if it isn’t already installed
   :PROPERTIES:
   :CUSTOM_ID: h-fef57cea-cf1d-4900-9d90-ec6353ea9661
   :END:
   Now we’ll need to be sure =yay=,  our AUR helper, is installed on our system.
   If it is, we  don’t need to to anything. However, if  it isn’t, we’ll install
   it manually.
   #+BEGIN_SRC fish
     if ! test (which yay)
         printf "\n# Installing yay ##############################################################\n\n"
         cd
         mkdir -p fromGIT
         cd fromGIT
         git clone https://aur.archlinux.org/yay.git
         cd yay
         makepkg -si --noconfirm
     else
         printf "\n# yay already installed #######################################################\n\n"
     end
   #+END_SRC

** Install basic packages
   :PROPERTIES:
   :CUSTOM_ID: h-887ec6d4-535d-4363-a0a7-884717b87a47
   :END:
   Let’s set in a custom varible what packages we’ll be needing.
   #+BEGIN_SRC fish
     set PACKAGES \
     acpilight adobe-source-han-sans-jp-fonts asar ascii aspell-en aspell-fr assimp \
     awesome-terminal-fonts base-devel bat biber bleachbit bluez-firmware \
     bluez-utils bookworm boost bzip2 ccls chicken chromium clisp compton cppcheck \
     cppreference cppreference-devhelp cpupower cronie cryptsetup device-mapper \
     diffutils discord-canary discount ditaa dmenu dmenu-lpass docker \
     docker-compose dockerfile-language-server-bin doxygen dunst dwarffortress \
     emacs exfat-utils farbfeld feh ffmpegthumbnailer findutils firefox \
     flake8 font-mathematica fontforge freeglut fzf gcc-libs gdb gimp glibc \
     gnome-disk-utility gnome-epub-thumbnailer gnu-free-fonts gnuplot go-tools \
     golangci-lint-bin graphviz htop i3-gaps-rounded i3lock-blur i3status igdm-bin \
     inetutils j4-dmenu-desktop javascript-typescript-langserver js-beautify \
     jfsutils jmtpfs lastpass-cli less linux-headers lldb logrotate lvm2 ly-git \
     meson minted mpc mpd mpd-rich-presence-discord-git mpv mupdf-tools nano ncdu \
     ncmpcpp nemo-fileroller nemo-preview neofetch neovim netctl networkmanager \
     networkmanager-openvpn nm-connection-editor nnn nodejs-vmd nomacs nordvpn-bin \
     noto-fonts-emoji npm ntfs-3g numlockx openssh otf-fandol otf-ipafont p7zip \
     pacman-contrib pandoc-bin pavucontrol pciutils pcurses pdfpc polybar prettier \
     pulseaudio-bluetooth python-autoflake python-envtpl-git python-epc \
     python-importmagic python-language-server python-nose python-pip python-ptvsd \
     python-pytest python-pywal qt5-imageformats qemu r raw-thumbnailer redshift \
     reflector rofi rofi-wifi-menu-git rsync rtv rustup s-nail samba scrot sent \
     shadow siji-git simplescreenrecorder speedcrunch sshfs st-luke-git swi-prolog \
     texlive-bin texlive-langchinese texlive-langcyrillic texlive-langgreek \
     texlive-langjapanese texlive-langkorean texlive-latexextra \
     texlive-localmanager-git texlive-most tmux tree ttf-arphic-uming ttf-baekmuk \
     ttf-bitstream-vera ttf-dejavu ttf-google-fonts-opinionated-git ttf-hanazono \
     ttf-joypixels ttf-koruri ttf-liberation ttf-material-design-icons-git \
     ttf-monapo ttf-mplus ttf-ms-fonts ttf-sazanami ttf-symbola ttf-tibetan-machine \
     ttf-twemoji-color ttf-unifont ttf-vlgothic typescript \
     typescript-language-server-bin unicode unicode-emoji unrar usbutils valgrind \
     vscode-css-languageserver-bin vscode-html-languageserver-bin w3m wget \
     x11-ssh-askpass xclip xdg-user-dirs-gtk xfsprogs xorg-apps xorg-drivers \
     xorg-server xorg-xinit xss-lock xvkbd yaml-language-server-bin yapf
   #+END_SRC
   These are the  minimum I would have  in my own installation. You  can edit it
   however you want. Let’s install those.
   #+BEGIN_SRC fish
     printf "\n# Installing needed packages ##################################################\n\n"
     sudo pacman -Syu
     yay -S --needed $PACKAGES
   #+END_SRC

** Tangle configuration files from Org files
   :PROPERTIES:
   :CUSTOM_ID: h-2e4fe0f5-a507-44c5-b69f-1935868b909d
   :END:
   The next step is  to tangle all the Org files. Here is the list of files that
   are to be tangled:
   #+NAME: tangled-files
   | filename      |
   |---------------|
   | bin.org       |
   | fish.org      |
   | i3.org        |
   | index.org     |
   | nano.org      |
   | polybar.org   |
   | spacemacs.org |
   | tmux.org      |

   #+NAME: generate-tangle
   #+BEGIN_SRC python :exports none :var files=tangled-files[,0] :cache yes
     result = ''
     commandPrintf = 'printf "\\n\\n==== Tangling {0}\\n\\n"\n'
     commandEmacs = 'emacs -q --batch --eval "(require \'ob-tangle)" --eval "(org-babel-tangle-file \\"~/org/config/{0}\\")"\n'
     for file in files:
         result += commandPrintf.format(file) + commandEmacs.format(file)
     return result
   #+END_SRC

   #+RESULTS[9de2e89515335bfbcc2c0974c81bf8b7d3b4c182]: generate-tangle
   #+begin_example
   printf "\n\n==== Tangling bin.org\n\n"
   emacs -q --batch --eval "(require 'ob-tangle)" --eval "(org-babel-tangle-file \"bin.org\")"
   printf "\n\n==== Tangling fish.org\n\n"
   emacs -q --batch --eval "(require 'ob-tangle)" --eval "(org-babel-tangle-file \"fish.org\")"
   printf "\n\n==== Tangling i3.org\n\n"
   emacs -q --batch --eval "(require 'ob-tangle)" --eval "(org-babel-tangle-file \"i3.org\")"
   printf "\n\n==== Tangling index.org\n\n"
   emacs -q --batch --eval "(require 'ob-tangle)" --eval "(org-babel-tangle-file \"index.org\")"
   printf "\n\n==== Tangling nano.org\n\n"
   emacs -q --batch --eval "(require 'ob-tangle)" --eval "(org-babel-tangle-file \"nano.org\")"
   printf "\n\n==== Tangling polybar.org\n\n"
   emacs -q --batch --eval "(require 'ob-tangle)" --eval "(org-babel-tangle-file \"polybar.org\")"
   printf "\n\n==== Tangling spacemacs.org\n\n"
   emacs -q --batch --eval "(require 'ob-tangle)" --eval "(org-babel-tangle-file \"spacemacs.org\")"
   printf "\n\n==== Tangling tmux.org\n\n"
   emacs -q --batch --eval "(require 'ob-tangle)" --eval "(org-babel-tangle-file \"tmux.org\")"
   #+end_example

   #+BEGIN_SRC fish :noweb yes
     printf "\n# Tangling org files ##########################################################\n\n"
     <<generate-tangle()>>
   #+END_SRC

   Let’s also make  sure the exported files that are  supposed to be executables
   are indeed executables.
   #+BEGIN_SRC fish
     find ~/.local/bin -type f -exec chmod +x {} +
   #+END_SRC

** Setting up Emacs: Installing Spacemacs
   :PROPERTIES:
   :CUSTOM_ID: h-bd5a92c4-1a4f-49ea-a447-050a4ff0301c
   :END:
   Now,  the first  thing we  want to  do with  Emacs is  install its  Spacemacs
   distribution. We’ll clone its =develop=  branch into =~/.emacs.d=. We need to
   do this  prior to our dotfiles’  cloning because of some  submodules that are
   cloned  within  our  =~/.emacs.d=  directory,  and git  won’t  let  us  clone
   Spacemacs in  an already existing  and non-empty  directory. To make  sure it
   isn’t one, let’s delete any potentially existing =~/.emacs.d= directory:
   #+BEGIN_SRC fish
     printf "\n# Installing Spacemacs ########################################################\n\n"
     rm -rf ~/.emacs.d
   #+END_SRC
   Now we can clone Spacemacs:
   #+BEGIN_SRC fish
     git clone --single-branch --branch develop https://github.com/syl20bnr/spacemacs ~/.emacs.d
   #+END_SRC
   And we can  restore what might have been deleted  in our =~/.emacs.d/private=
   directory:
   #+BEGIN_SRC fish
     yadm checkout -- ~/.emacs.d/private/
   #+END_SRC

** Set up dotfiles
   :PROPERTIES:
   :CUSTOM_ID: h-cf2c3a24-b08e-4b07-9d51-31f6df781e62
   :END:
*** Update our dotfiles’ remotes
    :PROPERTIES:
    :CUSTOM_ID: h-18967335-2637-44d6-b407-bb1d2d2718b9
    :END:
    This line in the bootstrap script will  test if the current user is using my
    username. If yes, it’s probably me.
    #+BEGIN_SRC fish
      if ! test (echo "phundrak" | sed -e "s/^.*$USER//I")
    #+END_SRC
    If it is  me installing and using  these dotfiles, I want the  remotes of my
    dotfiles to be set to ssh remotes using my ssh keys.
    #+BEGIN_SRC fish
      printf "\n# Update yadm’s remotes #######################################################\n\n"
      yadm remote set-url origin git@labs.phundrak.com:phundrak/dotfiles.git
      yadm remote add github git@github.com:phundrak/dotfiles.git
    #+END_SRC
    I will also want to decrypt my encrypted files, such as said ssh keys.
    #+BEGIN_SRC fish
      printf "\n# Decrypt encrypted dotfiles ##################################################\n\n"
      yadm decrypt
    #+END_SRC
    Finally, let’s close this =if= statement.
    #+BEGIN_SRC fish
      end
    #+END_SRC

*** Get =envtpl=
    :PROPERTIES:
    :CUSTOM_ID: h-39034878-7864-4a1c-855d-d9882795aac0
    :END:
    Before  we set  our  dotfiles  up, let’s  make  sure  =envtpl= is  correctly
    installed. This package will be needed for generating our alt dotfiles.
    #+BEGIN_SRC fish
      printf '\n# Install envtpl ##############################################################\n\n'
      yay -Syu python-envtpl-git
    #+END_SRC

*** Update our submodules
    :PROPERTIES:
    :CUSTOM_ID: h-ae2f8ccb-a8f3-4699-832c-52cbc8b6d081
    :END:
    Now we  can download  the various  dependencies of our  dotfiles. To  do so,
    let’s run the following command:
    #+BEGIN_SRC fish
      printf "\n# Getting yadm susbmodules ####################################################\n\n"
      yadm submodule update --init --recursive
    #+END_SRC

*** Generate our alt files
    :PROPERTIES:
    :CUSTOM_ID: h-f924c003-a15c-4132-891f-36cd3948a7c1
    :END:
    Now this should  be the last manipulation on our  dotfiles: let’s create our
    alternate files:
    #+BEGIN_SRC fish
      printf "\n# Generating alt files ########################################################\n\n"
      yadm alt
    #+END_SRC

** Installing Tryone’s Compton fork
   :PROPERTIES:
   :CUSTOM_ID: h-aecf9f01-268c-40cd-8fc3-622c6ce822e4
   :END:
   For some reason, I  found installing directly this fork does  not work, and I
   need  to  install  it  after   I  installed  the  regular  compton  packages.
   =compton-tryone-git= will replace =compton= which will be removed.
   #+BEGIN_SRC fish
     printf "\n# Installing tryone’s compton fork ############################################\n\n"
     yay -S compton-tryone-git
   #+END_SRC

** Enable some of our services
   :PROPERTIES:
   :CUSTOM_ID: h-1044da09-e992-4dcb-90ff-513725e1d450
   :END:
   We have  installed some packages  which require  some services to  run. Let’s
   enable them.

*** Docker
    :PROPERTIES:
    :CUSTOM_ID: h-429cb31a-fccb-420f-a5aa-21054c45fb38
    :END:
    First, let’s activate Docker.
    #+BEGIN_SRC fish
      printf "\n# Enabling and starting Docker ################################################\n\n"
      sudo systemctl enable --now docker
    #+END_SRC

    Now, if we wish  it, we can be added to the =docker=  group so we won’t have
    to type =sudo= each time we call Docker or Docker Compose.
    #+BEGIN_SRC fish
      read --prompt "echo 'Do you wish to be added to the `docker` group? (Y/n): ' " -l adddockergroup
      if test $adddockergroup = 'y' || test $adddockergroup = "Y" || test $adddockergroup = ''
          sudo usermod -aG docker $USER
      end
    #+END_SRC

*** Emacs
    :PROPERTIES:
    :CUSTOM_ID: h-7131fa13-3c6e-4cfc-b8e8-c880de9d380f
    :END:
    Emacs will run as a user service,  which means it won’t be launched until we
    log in.
    #+BEGIN_SRC fish
      printf "\n# Enabling Emacs as user service ##############################################\n\n"
      systemctl --user enable --now emacs
    #+END_SRC

*** SSH server
    :PROPERTIES:
    :CUSTOM_ID: h-1f355779-f1dc-4c0f-9cf1-14724ce05f4d
    :END:
    Maybe we want to activate an SSH server on our machine. If so, we can enable
    it. Let’s ask the question.
    #+BEGIN_SRC fish
      read --prompt "echo 'Do you want to activate the ssh server? (Y/n): ' " -l sshdserver
      if test $sshdserver = 'y' || test $sshdserver = "Y" || test $sshdserver = ''
          printf "\n# Enabling ssh server #########################################################\n\n"
          sudo systemctl enable --now sshd
      end
    #+END_SRC

*** Ly
    :PROPERTIES:
    :CUSTOM_ID: h-2785fc5b-cd35-4c99-9f47-3dcbf1a7a870
    :END:
    Ly is a display manager based on ncurses  which I find nice enough for me to
    use (I  generally don’t like using  display managers). Let’s enable  it, and
    let’s disable tty2 while we’re at it (Ly uses it to run X).
    #+BEGIN_SRC fish
      sudo systemctl enable --now ly
      sudo systemctl disable getty@tty2
    #+END_SRC

*** Acpilight
    :PROPERTIES:
    :CUSTOM_ID: h-5423e2a7-d2ce-4bc3-9d5d-85677c18181e
    :END:
    =acpilight= is our  utility managing the brightness of our  screen. There is
    actually no service to  enable here, but we must ensure the  user is part of
    the =video=  group so  we can  modify the brightness  of our  screen without
    using =sudo=.
    #+BEGIN_SRC fish
      sudo usermod -aG video $USER
    #+END_SRC

*** NordVPN
    :PROPERTIES:
    :CUSTOM_ID: h-49c24a3e-a496-4200-bf64-96e945c203a0
    :END:
    Thanks  to the  AUR  package ~nordvpn-bin~,  I no  longer  have to  manually
    maintain my  VPN connections manually  with OpenVPN. However, it  requires a
    service that we should activate:
    #+BEGIN_SRC fish
    sudo systemctl enable --now nordvpnd
    #+END_SRC

** Symlink some system config files
   :PROPERTIES:
   :CUSTOM_ID: h-b14d7d03-da49-4a7b-ba05-1c0848bd8e44
   :END:
   We have some files in [[file:ect/][etc/]] that are to be symlinked to =/etc=.
   #+BEGIN_SRC fish
     for f in (find ~/.etc -type f)
         set dest (echo $f | sed -n 's/^.*etc\(.*\)$/\/etc\1/p')
         sudo ln -s $f $dest
     end
   #+END_SRC

   We may also want  to symlink our [[file:.nanorc][nanorc]] to the =/root=  directory for when we
   use =nano= as =sudo=.
   #+BEGIN_SRC fish
     read --prompt "echo 'Symlink .nanorc to root’s .nanorc? (Y/n): ' " -l nanoroot
     if test $nanoroot = 'y' || test $nanoroot = "Y" || test $nanoroot = ''
         printf "\n# Symlinking .nanorc to root’s .nanorc ########################################\n\n"
         sudo ln -s $HOME/.nanorc /root/.nanorc
     end
   #+END_SRC

** Install packages from git
   :PROPERTIES:
   :CUSTOM_ID: h-e79da7b2-9286-4b66-812e-453e3b2505c7
   :END:
   Now, let’s install some packages from git directly.

*** Polybar Battery
    :PROPERTIES:
    :CUSTOM_ID: h-f228ec52-a7d0-4c16-adfa-75c544fcfa93
    :END:
    Now let’s install =polybar-battery=. This is a binary that I’ll use in my [[file:.config/i3/config][i3
    config]] to  indicate my battery  level. It also  sends a notification  on low
    battery and on charging completed.
    #+BEGIN_SRC fish
      printf "\n# Install polybar-battery #####################################################\n\n"
      cd ~/fromGIT
      git clone https://github.com/drdeimos/polybar_another_battery.git
      cd polybar_another_battery
      go get -u github.com/distatus/battery/cmd/battery
      make build
    #+END_SRC

    Now, we  have our binary,  let’s symlink it  in our local  binary directory,
    =~/.local/bin=.
    #+BEGIN_SRC fish
      ln -s polybar-ab ~/.local/bin/polybar-ab
    #+END_SRC

*** Reveal.JS
    :PROPERTIES:
    :CUSTOM_ID: h-68d1cdb4-1447-420f-ab0c-53ef905e757b
    :END:
    I sometimes use  Reveal.JS to make presentations, and I  set its location in
    my [[file:.spacemacs][dotspacemacs]] file to be in =~/fromGIT=, so let’s clone it there.
    #+BEGIN_SRC fish
      printf "\n# Install Reveal.JS ###########################################################\n\n"
      cd ~/fromGIT
      git clone https://github.com/hakimel/reveal.js.git
    #+END_SRC

** Install Rust
   :PROPERTIES:
   :CUSTOM_ID: h-57e8af4c-93f2-4145-9c39-a5f8d1c9f012
   :END:
*** Install the toolchains
    :PROPERTIES:
    :CUSTOM_ID: h-05ee25dc-3885-46ca-afaf-35bfb2e385d4
    :END:
    When using rust, I bounce between two toolchains, the =stable= toolchain and
    the =nightly=  toolchain. To  install them,  I will  use =rustup=  which has
    already been installed.
    #+BEGIN_SRC fish
      printf "\n# Install the rust toolchains, nightly is the default one #####################\n\n"
      rustup default nightly
    #+END_SRC
    This will both download the nightly toolchain and set it as the default one.
    Yup, I like to live dangerously.  Now to install the stable toolchain, let’s
    run this:
    #+BEGIN_SRC fish
      rustup toolchain install stable
    #+END_SRC

*** Install some utilities
    :PROPERTIES:
    :CUSTOM_ID: h-f94f2e18-623f-4aa5-be99-6a7df6a9cbcd
    :END:
    We’ll need some utilities when  developing Rust from Emacs, namely =rustfmt=
    and =racer=. Let’s install them with =cargo=.
    #+BEGIN_SRC fish
      printf "\n# Add rust utilities ##########################################################\n\n"
      cargo install rustfmt racer
    #+END_SRC

    We will also need some components for development purposes:
    #+BEGIN_SRC fish
      rustup component add src
      rustup component add rls
    #+END_SRC

** Install some python packages
   :PROPERTIES:
   :CUSTOM_ID: h-8155ae1a-0be1-489f-be13-9222f7686fb2
   :END:
   Some  packages will  be needed  from  pip in  order  to get  our Emacs  setup
   correctly working. Let’s install them locally for our user:
   #+BEGIN_SRC fish
     printf "\n# Installing Python packages ##################################################\n\n"
     pip install --user pyls-isort pyls-mypy
   #+END_SRC

** Install go packages
   :PROPERTIES:
   :CUSTOM_ID: h-8c6e2311-eb84-4bf4-8e0b-948f89bc9664
   :END:
   For go development from Emacs, the  Spacemacs go and lsp layers requires some
   packages to be installed.
   #+BEGIN_SRC fish
     printf "\n# Installing Go packages ######################################################\n\n"
     go get -v golang.org/x/tools/gopls@latest
     go get -u -v golang.org/x/tools/cmd/godoc
     go get -u -v golang.org/x/tools/cmd/goimports
     go get -u -v golang.org/x/tools/cmd/gorename
     go get -u -v golang.org/x/tools/cmd/guru
     go get -u -v github.com/cweill/gotests/...
     go get -u -v github.com/davidrjenni/reftools/cmd/fillstruct
     go get -u -v github.com/fatih/gomodifytags
     go get -u -v github.com/godoctor/godoctor
     go get -u -v github.com/golangci/golangci-lint/cmd/golangci-lint
     go get -u -v github.com/haya14busa/gopkgs/cmd/gopkgs
     go get -u -v github.com/josharian/impl
     go get -u -v github.com/mdempsky/gocode
     go get -u -v github.com/rogpeppe/godef
     go get -u -v github.com/zmb3/gogetdoc
     go get -u -v golang.org/x/tools/gopls
   #+END_SRC

** Set up Chicken (Scheme interpreter/compiler)
   :PROPERTIES:
   :CUSTOM_ID: h-10ffb0c0-8028-4e9c-842e-9e7d2c165c5b
   :END:
   Chicken needs to be  set up before being used. First, we  need to install its
   documentation.
   #+BEGIN_SRC fish
     printf "\n# Setting up Chicken ##########################################################\n\n"
     chicken-install -s apropos chicken-doc
   #+END_SRC

   Then, we’ll complete the documentation like so:
   #+BEGIN_SRC fish
     cd (chicken-csi -b -e "(import (chicken platform))" -p "(chicken-home)")
     curl https://3e8.org/pub/chicken-doc/chicken-doc-repo.tgz | sudo tar zx
   #+END_SRC

** Clean the =pacman= and =yay= cache
   :PROPERTIES:
   :CUSTOM_ID: h-fa5307ec-065b-4d06-9d47-05ccde0da8ac
   :END:
   Finally, we are almost done! Let’s clean the cache of =pacman= and =yay=.
   #+BEGIN_SRC fish
     printf "\n# Clean the pacman and yay cache ##############################################\n\n"
     yay -Sc --noconfirm
   #+END_SRC

** Export configuration file from org files
   :PROPERTIES:
   :CUSTOM_ID: h-a4fb171a-3121-46f2-8c3c-2e65500ebdbe
   :END:
   As I strive to write most of my configuration file as literary programming
   files through org-mode, they are not versioned nor downloaded by git when
   cloning my dotfiles. This is why

** Set up our fish shell
   :PROPERTIES:
   :CUSTOM_ID: h-f6f4df67-b0de-40bf-95fb-888d42169088
   :END:
   The last thing we want to do is to set up our fish shell with some extensions
   in order to improve the user experience.

*** Install =fisher=
    :PROPERTIES:
    :CUSTOM_ID: h-d6490ddc-c909-4713-b36a-19c25a79c7ac
    :END:
    We will be using =fisher= as  our extensions manager for Fish. Let’s install
    it.
    #+BEGIN_SRC fish
      printf "\n# Installing fisher ###########################################################\n\n"
      curl https://git.io/fisher --create-dirs -sLo ~/.config/fish/functions/fisher.fish
    #+END_SRC

*** Install our extensions
    :PROPERTIES:
    :CUSTOM_ID: h-3d540273-bdfb-4c63-a05f-2374a010dc29
    :END:
    I generally use the following extensions in my Fish shell.
    #+NAME: fish-extensions
    #+CAPTION: Fish extensions managed by Fisher
    | Package name                | Description                                                      |
    |-----------------------------+------------------------------------------------------------------|
    | oh-my-fish/theme-bobthefish | Robust, git-aware, powerline prompt                              |
    | jorgebucaran/fish-bax       | Run bash scripts, replaying environment changes in fish          |
    | franciscolourenco/done      | Automatically receive notifications when a long process finishes |
    | jethrokuan/fzf              | Improved key bindings for [[https://github.com/junegunn/fzf][junegunn/fzf]]                           |
    | jethrokuan/z                | Pure-fish [[https://github.com/rupa/z][rupa/z]]-like directory jumping                          |
    | jorgebucaran/fish-getopts   | CLI options parser; alternative to the [[https://fishshell.com/docs/current/commands.html#argparse][argparse]] fish builtin     |
    | laughedelic/pisces          | Autoclose parentheses, braces, quotes and other paired symbols   |
    | tuvistavie/fish-ssh-agent   | Utility functions to start your ssh agent                        |
    | acomagu/fish-async-prompt   | Make your prompt asynchronous to increase it reactivity          |

    #+NAME: fish-ext-py
    #+BEGIN_SRC python :exports none :tangle no :var extensions=fish-extensions :cache yes
      results = ''
      for extension in extensions:
          results += "fisher add {0}\n".format(extension[0])
      return results
    #+END_SRC

    #+RESULTS[e82c7269c09b1d43a1a335a13c422b22b59079b1]: fish-ext-py
    : fisher add oh-my-fish/theme-bobthefish
    : fisher add jorgebucaran/fish-bax
    : fisher add franciscolourenco/done
    : fisher add jethrokuan/fzf
    : fisher add jethrokuan/z
    : fisher add jorgebucaran/fish-getopts
    : fisher add laughedelic/pisces
    : fisher add tuvistavie/fish-ssh-agent
    : fisher add acomagu/fish-async-prompt

    #+BEGIN_SRC fish :noweb yes
      printf "\n# Installing Fisher Extensions ################################################\n\n"
      <<fish-ext-py()>>
    #+END_SRC
