#+TITLE: Console
#+TODO: TODO(t) CHECK(s) | OFF(o)
#+PROPERTY: header-args :mkdirp yes
#+PROPERTY: header-args:conf-space   :comments link
#+PROPERTY: header-args:conf-toml    :comments link
#+PROPERTY: header-args:sh           :tangle-mode (identity #o755) :comments link :shebang "#!/usr/bin/env sh"
#+PROPERTY: header-args:bash         :tangle-mode (identity #o755) :comments link :shebang "#!/usr/bin/env bash"
#+OPTIONS: broken-links:auto h:6 toc:nil

#+begin_quote
No matter from which side you approach penguins, more always come from behind
#+end_quote
- A friend of mine


* Colors
Noweb function to get colors.

#+NAME: get-color
#+begin_src emacs-lisp :var name="black" quote=0 :tangle no
(let ((color (or (my/color-value name))))
  (if (> quote 0)
      (concat "\"" color "\"")
    color))
#+end_src

#+NAME: get-fg-for-color
#+begin_src emacs-lisp :var name="black" quote=0 :tangle no
(let ((val (if (ct-light-p (my/color-value name))
               (my/color-value 'black)
             (my/color-value 'white))))
  (if (eq quote 1)
      (concat "\"" val "\"")
    val))
#+end_src

#+begin_src emacs-lisp :tangle no
(setq-local org-confirm-babel-evaluate nil)
#+end_src

* =.profile=
:PROPERTIES:
:header-args+: :tangle ./.profile
:header-args:sh: :shebang "" :comments link
:END:
** Environment
#+begin_src sh
export QT_QPA_PLATFORMTHEME="qt5ct"
export QT_AUTO_SCREEN_SCALE_FACTOR=0
#+end_src

Set ripgrep config path
#+begin_src sh
export RIPGREP_CONFIG_PATH=$HOME/.config/ripgrep/ripgreprc
#+end_src

hledger path
#+begin_src sh
export LEDGER_FILE="$HOME/30-39 Life/32 org-mode/ledger/ledger.journal"
#+end_src

Checking if running inside termux
#+begin_src sh
if command -v termux-setup-storage > /dev/null; then
    export IS_ANDROID=true
    [[ -f ~/.android_profile ]] && . ~/.android_profile
fi
#+end_src

Timezone
#+begin_src sh
# TZ='Asia/Karachi'; export TZ
#+end_src
** My paths
My script folders
#+begin_src sh
if [ -d "$HOME/bin" ] ; then
    export PATH="$HOME/bin:$PATH"
    export PATH="$HOME/bin/scripts:$PATH"
fi

if [ -d "$HOME/.local/bin" ] ; then
    export PATH="$HOME/.local/bin:$PATH"
fi
#+end_src

** Guix settings
Enable extra profiles

#+begin_src sh
if [ -z "$IS_ANDROID" ]; then
    GUIX_EXTRA_PROFILES=$HOME/.guix-extra-profiles
    for i in $GUIX_EXTRA_PROFILES/*; do
        profile=$i/$(basename "$i")
        if [ -f "$profile"/etc/profile ]; then
            GUIX_PROFILE="$profile"
            . "$GUIX_PROFILE"/etc/profile
        fi
        if [ -d "$profile"/share/man ]; then
            export MANPATH="${MANPATH:-$(manpath)}:$profile/share/man"
        fi
        export XDG_DATA_DIRS="$XDG_DATA_DIRS:$profile/share"
        unset profile
    done
fi
#+end_src

Set Jupyter config PATH. It defaults to readonly directory somewhere in Guix profile.
#+begin_src sh
export JUPYTER_CONFIG_DIR=$HOME/.config/jupyter
#+end_src

Set a folder for my packages.
#+begin_src sh
export GUIX_PACKAGE_PATH=~/guix-packages
#+end_src

Locale settings
#+begin_src sh
export GUIX_LOCPATH=$HOME/.guix-extra-profiles/console/console/lib/locale
#+end_src

Somehow LibreOffice doesn't work without the following:
#+begin_src sh
export GIO_EXTRA_MODULES=""
#+end_src
** Other package managers
Using other package managers with Guix requires some extra work.

Cask
#+begin_src sh
if [ -d "$HOME/.cask" ]; then
    export PATH="/home/pavel/.cask/bin:$PATH"
fi
#+end_src

Make flatpak apps visible to launchers:
#+begin_src sh
if [ -d "$HOME/.local/share/flatpak" ]; then
    export XDG_DATA_DIRS="$XDG_DATA_DIRS:$HOME/.local/share/flatpak/exports/share"
fi
#+end_src

Enable Nix
#+begin_src sh
if [ -f /run/current-system/profile/etc/profile.d/nix.sh ]; then
  . /run/current-system/profile/etc/profile.d/nix.sh
fi
#+end_src

Use Guix fontconfig. Necessary for nix apps
#+begin_src sh
if [ -d "$HOME/.guix-extra-profiles/desktop-misc" ]; then
    export FONTCONFIG_PATH="$HOME/.guix-extra-profiles/desktop-misc/desktop-misc/etc/fonts"
fi
#+end_src

Make nix apps visible to launchers:
#+begin_src sh
if [ -d "$HOME/.nix-profile" ]; then
    export XDG_DATA_DIRS="$XDG_DATA_DIRS:$HOME/.nix-profile/share/applications"
fi
#+end_src

*** npm
npm is especially cumbersome, for instance because by default it tries to install packages to =/gnu/store/=.

In principle, one can set a prefix like this:
#+begin_src conf :tangle ~/._npmrc
prefix=/home/pavel/.npm-packages
#+end_src

But I also want to use node from conda occasionally, where prefix is already set correctly. So instead of tangling the above to the =~/.npmrc= directly, I set an environment variable in the profile:

#+begin_src sh
export NPM_CONFIG_USERCONFIG=$HOME/._npmrc
#+end_src

The variable is unset in a script in [[file:Guix.org::*micromamba][Guix.org]].

Set PATH & MANPATH
#+begin_src sh
NPM_PACKAGES="${HOME}/.npm-packages"

export PATH="$PATH:$NPM_PACKAGES/bin"
export MANPATH="${MANPATH:-$(manpath)}:$NPM_PACKAGES/share/man"
#+end_src
** XResources
| Guix dependency |
|-----------------|
| xrdb            |

#+begin_src sh
if [ -z "$IS_ANDROID" ]; then
    xrdb ~/.Xresources
fi
#+end_src
** OFF (OFF) Package manager paths
Turned off for now, because probably it won't be necessary in Guix.

LaTeX
#+begin_src sh :tangle no
if [ -d "/usr/local/texlive/2020" ]; then
    export MANPATH="/usr/local/texlive/2020/texmf-dist/doc/man:$MANPATH"
    export INFOPATH="/usr/local/texlive/2020/texmf-dist/doc/info:$INFOPATH"
    export PATH="/usr/local/texlive/2020/bin/x86_64-linux:$PATH"
fi
#+end_src

Cargo (Rust)
#+begin_src sh :tangle no
if [ -d "$HOME/.cargo" ] ; then
    export PATH="$HOME/.cargo/bin:$PATH"
fi
#+end_src

RVM (Ruby)
#+begin_src sh :tangle no
if [ -d "$HOME/.rvm" ] ; then
    export PATH="$PATH:$HOME/.rvm/bin"
fi
# if [ -d "$HOME/.gem" ]; then
#     export PATH="$HOME/.gem/ruby/2.7.0/bin:$PATH"
# fi
#+end_src

Go
#+begin_src sh :tangle no
if [ -d "$HOME/go" ] ; then
    export PATH="$HOME/go/bin:$PATH"
fi
#+end_src

ghcup (Haskell)
#+begin_src sh :tangle no
[ -f "/home/pavel/.ghcup/env" ] && source "/home/pavel/.ghcup/env" # ghcup-env
#+end_src

Perl
#+begin_src sh :tangle no
if [ -d "$HOME/perl5" ] ; then
    PATH="/home/pavel/perl5/bin${PATH:+:${PATH}}"
    PERL5LIB="/home/pavel/perl5/lib/perl5${PERL5LIB:+:${PERL5LIB}}"; export PERL5LIB;
    PERL_LOCAL_LIB_ROOT="/home/pavel/perl5${PERL_LOCAL_LIB_ROOT:+:${PERL_LOCAL_LIB_ROOT}}"; export PERL_LOCAL_LIB_ROOT;
    PERL_MB_OPT="--install_base \"/home/pavel/perl5\""; export PERL_MB_OPT;
    PERL_MM_OPT="INSTALL_BASE=/home/pavel/perl5"; export PERL_MM_OPT;
fi
#+end_src
* Bash
:PROPERTIES:
:header-args:bash: :shebang "" :comments link
:END:
** =.bash_profile=
#+begin_src bash :tangle ./.bash_profile
[[ -f ~/.profile ]] && . ~/.profile

[[ -f ~/.bashrc ]] && . ~/.bashrc
#+end_src
** =.bashrc=
:PROPERTIES:
:header-args+: :tangle ./.bashrc
:END:

My =.bashrc=, which has pieces from the default one in Guix & Manjaro, as well some mine settings.

*** Startup & environment
Export 'SHELL' to child processes.  Programs such as 'screen' honor it and otherwise use /bin/sh.
#+begin_src bash
export SHELL
#+end_src

We are being invoked from a non-interactive shell.  If this is an SSH session (as in "ssh host command"), source /etc/profile, so we get PATH and other essential variables.
#+begin_src bash
if [[ $- != *i* ]]
then
    [[ -n "$SSH_CLIENT" && -f "/etc/bashrc" ]] && source /etc/profile
    return
fi
#+end_src

If =termux-setup-storage= is available, then we're running inside termux. It is necessary to source =~/.profile= manually.
#+begin_src bash
if command -v termux-setup-storage > /dev/null; then
    if [[ -z "$IS_ANDROID" ]]; then
        source ~/.profile
    fi
fi
#+end_src

Source the system-wide file
#+begin_src bash
if [[ -f "/etc/bashrc" ]]; then
    source /etc/bashrc
fi
#+end_src

| Guix dependency |
|-----------------|
| xhost           |

Allow other users to access X server. Necessary for stuff like aw-watcher-window.
#+begin_src bash
xhost +local:root > /dev/null 2>&1
#+end_src

Set manpager to bat
#+begin_src bash
export MANPAGER="sh -c 'sed -e s/.\\\\x08//g | bat -l man -p'"
#+end_src

[[https://codeberg.org/akib/emacs-eat][eat]] integration
#+begin_src bash
[ -n "$EAT_SHELL_INTEGRATION_DIR" ] && source "$EAT_SHELL_INTEGRATION_DIR/bash"
#+end_src
*** Launch fish
Launch fish shell unless bash itself is launched from fish.
#+begin_src bash
use_fish=true

if [[ $(ps --no-header --pid=$PPID --format=cmd) != "fish" && ${use_fish} && $(command -v fish) ]]
then
    exec fish
fi
#+end_src
The rest of =.bashrc= is not executed if fish was launched.
*** Colors
Setting for colors, packed in the default =.bashrc= in Manjaro
#+begin_src bash
use_color=true

# Set colorful PS1 only on colorful terminals.
# dircolors --print-database uses its own built-in database
# instead of using /etc/DIR_COLORS.  Try to use the external file
# first to take advantage of user additions.  Use internal bash
# globbing instead of external grep binary.
safe_term=${TERM//[^[:alnum:]]/?}   # sanitize TERM
match_lhs=""
[[ -f ~/.dir_colors   ]] && match_lhs="${match_lhs}$(<~/.dir_colors)"
[[ -f /etc/DIR_COLORS ]] && match_lhs="${match_lhs}$(</etc/DIR_COLORS)"
[[ -z ${match_lhs}    ]] \
    && type -P dircolors >/dev/null \
    && match_lhs=$(dircolors --print-database)
[[ $'\n'${match_lhs} == *$'\n'"TERM "${safe_term}* ]] && use_color=true

if ${use_color} ; then
    # Enable colors for ls, etc.  Prefer ~/.dir_colors #64489
    if type -P dircolors >/dev/null ; then
        if [[ -f ~/.dir_colors ]] ; then
            eval $(dircolors -b ~/.dir_colors)
        elif [[ -f /etc/DIR_COLORS ]] ; then
            eval $(dircolors -b /etc/DIR_COLORS)
        fi
    fi

    if [[ ${EUID} == 0 ]] ; then
        PS1='\[\033[01;31m\][\h\[\033[01;36m\] \W\[\033[01;31m\]]\$\[\033[00m\] '
    else
        PS1='\[\033[01;32m\][\u@\h\[\033[01;37m\] \W\[\033[01;32m\]]\$\[\033[00m\] '
    fi

    alias ls='ls --color=auto'
    alias grep='grep --colour=auto'
    alias egrep='egrep --colour=auto'
    alias fgrep='fgrep --colour=auto'
else
    if [[ ${EUID} == 0 ]] ; then
        # show root@ when we don't have colors
        PS1='\u@\h \W \$ '
    else
        PS1='\u@\h \w \$ '
    fi
fi

unset use_color safe_term match_lhs sh
#+end_src
*** Settings
Some general bash settings.

References:
- [[https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html][shopt list]]
#+begin_src bash
complete -cf sudo           # Sudo autocompletion

shopt -s checkwinsize       # Check windows size after each command
shopt -s expand_aliases     # Aliases
shopt -s autocd             # Cd to directory just by typing its name (without cd)
#+end_src

History control
#+begin_src bash
shopt -s histappend
export HISTCONTROL=ignoredups:erasedups
HISTSIZE=
HISTFILESIZE=
#+end_src

Autocompletions
#+begin_src bash :tangle no
[ -r /usr/share/bash-completion/bash_completion ] && . /usr/share/bash-completion/bash_completion
if [ -d "/usr/share/fzf" ]; then
    source /usr/share/fzf/completion.bash
    source /usr/share/fzf/key-bindings.bash
fi
#+end_src
*** Aliases
#+begin_src bash :noweb yes :noweb-ref shell-aliases
alias v="vim"
if command -v exa > /dev/null; then
    alias ls="exa --icons"
    alias ll="exa -lah --icons"
else
    alias ll='ls -lah'
fi
alias q="exit"
alias c="clear"
alias ci="init_mamba"
alias ca="micromamba activate"
alias cii="export INIT_MAMBA=true && init_mamba"
#+end_src

#+begin_src bash
if [[ ! -z "$SIMPLE" ]]; then
    unalias ls
    alias ll="ls -lah"
fi
#+end_src
*** Micromamba
I've moved from conda to [[https://github.com/mamba-org/mamba][micromamba]] because it's faster.

#+begin_quote
managed by 'mamba init' !!!
#+end_quote
Yeah, tell this to yourself

#+begin_src bash
init_mamba () {
    export MAMBA_EXE="/home/pavel/.guix-extra-profiles/dev/dev/bin/micromamba";
    export MAMBA_ROOT_PREFIX="/home/pavel/micromamba";
    __mamba_setup="$("$MAMBA_EXE" shell hook --shell bash --prefix "$MAMBA_ROOT_PREFIX" 2> /dev/null)"
    if [ $? -eq 0 ]; then
        eval "$__mamba_setup"
    else
        if [ -f "/home/pavel/micromamba/etc/profile.d/micromamba.sh" ]; then
            . "/home/pavel/micromamba/etc/profile.d/micromamba.sh"
        else
            export  PATH="/home/pavel/micromamba/bin:$PATH"  # extra space after export prevents interference from conda init
        fi
    fi
    unset __mamba_setup
}

if [[ ! -z "$INIT_MAMBA" ]]; then
    init_mamba
fi
#+end_src

*** Starship
#+begin_src bash
if [[ -z "$SIMPLE" && "$TERM" != "dumb" ]]; then
    eval "$(starship init bash)"
fi
#+end_src
*** Yandex Cloud
#+begin_src bash
init_yc () {
    # The next line updates PATH for Yandex Cloud CLI.
    if [ -f '/home/pavel/yandex-cloud/path.bash.inc' ]; then source '/home/pavel/yandex-cloud/path.bash.inc'; fi

    # The next line enables shell command completion for yc.
    if [ -f '/home/pavel/yandex-cloud/completion.bash.inc' ]; then source '/home/pavel/yandex-cloud/completion.bash.inc'; fi
}
#+end_src
* Fish
:PROPERTIES:
:header-args+: :tangle ./.config/fish/config.fish :comments link
:END:

| Guix dependency | Description                              |
|-----------------+------------------------------------------|
| fish            | An alternative non POSIX-compliant shell |

[[https://fishshell.com/][Fish shell]] is a non-POSIX-compliant shell, which offers some fancy UI & UX features.

Launch starship
#+begin_src fish
if [ "$TERM" != "dumb" ]; and type -q starship;
    starship init fish | source
else
    function fish_prompt -d "Write out the prompt"
        printf '%s@%s %s%s%s > ' $USER $hostname \
            (set_color $fish_color_cwd) (basename (pwd)) (set_color normal)
    end
end
#+end_src

Enable vi keybindings & aliases. The alias syntax is the same as in bash, so it's just a noweb reference to =.bashrc=.
#+begin_src fish :noweb yes
fish_vi_key_bindings

alias q="exit"
alias c="clear"
if type -q exa
    alias ls="exa --icons"
    alias ll="exa -lah --icons"
else
    alias ll="ls -h"
end
#+end_src


| Guix dependency |
|-----------------|
| dt-colorscripts |

Launch a random [[https://gitlab.com/dwt1/shell-color-scripts][DT's colorscript]] unless ran inside tmux or Emacs.
#+begin_src fish
if ! test -n "$TMUX"; and ! test -n "$IS_EMACS"; and type -q colorscript
    colorscript random
end
#+end_src

Suppress fish greeting
#+begin_src fish
set fish_greeting
#+end_src
** Micromamba
First, a function to initialize micromamba.
#+begin_src fish
function init_mamba
    set -gx MAMBA_EXE "/home/pavel/.guix-extra-profiles/dev/dev/bin/micromamba"
    set -gx MAMBA_ROOT_PREFIX "/home/pavel/micromamba"
    $MAMBA_EXE shell hook --shell fish --prefix $MAMBA_ROOT_PREFIX | source
end

if test -n "$INIT_MAMBA";
    init_mamba
end

alias ca="micromamba activate"
alias ci="init_mamba"
alias cii="export INIT_MAMBA=true && init_mamba"
#+end_src

Then, check if launched from Emacs with environment activated.
#+begin_src fish
# if test -n "$EMACS_CONDA_ENV";
    # conda activate $EMACS_CONDA_ENV
# end
#+end_src
** Colors
Fish seems to have hardcoded colorcodes in some color settings. I set these to base16 colors, so they would match Xresources.

#+begin_src fish
set fish_color_command cyan
set fish_color_comment green
set fish_color_end black
set fish_color_error red
set fish_color_escape yellow
set fish_color_operator yellow
set fish_color_param magenta
set fish_color_quote green
set fish_color_redirection yellow
#+end_src
** Keybindings
#+begin_src fish
bind -M insert \el forward-char
bind -M insert \eh backward-char
bind -M insert \ew forward-word
bind -M insert \eb backward-word
#+end_src
** Functions
A small function to open the file with =$EDITOR=.

#+begin_src fish
function e
    eval $EDITOR $argv
end
#+end_src
** direnv
#+begin_src fish
direnv hook fish | source
#+end_src
* Nushell
:PROPERTIES:
:header-args+: :tangle ./.config/nu/config.toml :comments link
:END:
 | Guix dependency |
 |-----------------|
 | nushell-bin     |

A structured shell. I don't use it as of now, but perhaps one day.

* Starship prompt
| Guix dependency | Description         |
|-----------------+---------------------|
| starship-bin    | my prompt of choice |

[[https://starship.rs/][Starship]] is a nice cross-shell prompt, written in Rust.

References:
- [[https://starship.rs/config/][Startship config guide]]

#+begin_src conf-toml :tangle ./.config/starship.toml
[character]
success_symbol = "[➤ ](bold green)"
error_symbol = "[ ](bold red)"
vicmd_symbol = "[ᐊ ](bold green)"

[aws]
symbol = " "

# [battery]
# full_symbol = ""
# charging_symbol = ""
# discharging_symbol = ""

[conda]
symbol = " "

[cmd_duration]
min_time = 500
format = " [$duration]($style) "

[docker_context]
symbol = " "

[elixir]
symbol = " "

[elm]
symbol = " "

[git_branch]
symbol = " "
truncation_length = 20

[golang]
symbol = " "

# [haskell]
# symbol = " "

[hg_branch]
symbol = " "

[java]
symbol = " "

[julia]
symbol = " "

[memory_usage]
symbol = " "

[nim]
symbol = " "

[nix_shell]
symbol = " "

[nodejs]
symbol = " "

[package]
symbol = " "
disabled = true

[php]
symbol = " "

[python]
symbol = " "

[ruby]
symbol = " "

[rust]
symbol = " "
#+end_src
* Tmux
:PROPERTIES:
:header-args+: :tangle ./.tmux.conf
:END:
| Guix dependency |
|-----------------|
| tmux            |
| python-tmuxp    |

[[https://github.com/tmux/tmux][tmux]] is my terminal multiplexer of choice.

It provides pretty sane defaults, so the config is not too large. I rebind the prefix to =C-a= though.
** Term settings
I have no idea how and why these statements work.
#+begin_src conf-space
set -g default-terminal "screen-256color"
set -ga terminal-overrides ",*256col*:Tc"
#+end_src

History limit.
#+begin_src conf-space
set -g history-limit 20000
#+end_src
** Keybindings
Enable vi keys and mouse.
#+begin_src conf-space
set-window-option -g mode-keys vi
set-option -g xterm-keys on
set-option -g mouse on
set -sg escape-time 10
#+end_src

Change prefix from =C-b= to =C-a=.
#+begin_src conf-space
unbind C-b
set -g prefix C-a
bind C-a send-prefix
#+end_src

Vi-like keybindings to manage panes & windows.
#+begin_src conf-space
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R

bind s split-window
bind v split-window -h

bind-key n new-window
bind-key t next-window
bind-key T previous-window
#+end_src

Reload the config.
#+begin_src conf-space
bind r source-file ~/.tmux.conf
#+end_src
** Copy to clipboard
| Guix dependency |
|-----------------|
| xclip           |

Make tmux copy to clipboard as well
#+begin_src conf-space
bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "xclip -selection clipboard -i"
bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xclip -selection clipboard -i"
#+end_src
** UI
On [2020-01-22 Wed], I had generated the first version of this following with [[https://github.com/edkolev/tmuxline.vim][tmuxline.vim]] plugin and palenight theme for [[https://github.com/vim-airline/vim-airline][vim-airline]].

Then I adapted it to use the current Emacs theme.

#+begin_src conf-space :tangle ./.tmux.line.conf :noweb yes
set -g status-justify "centre"
set -g status "on"
set -g status-left-style "none"
set -g message-command-style "fg=<<get-color(name="fg")>>,bg=<<get-color(name="bg-other")>>"
set -g status-right-style "none"
set -g pane-active-border-style "fg=<<get-color(name="blue")>>"
set -g status-style "none,bg=<<get-color(name="bg-other")>>"
set -g message-style "fg=<<get-color(name="fg")>>,bg=<<get-color(name="bg-other")>>"
set -g pane-border-style "fg=<<get-color(name="blue")>>"
set -g status-right-length "100"
set -g status-left-length "100"
setw -g window-status-activity-style "none,fg=<<get-color(name="blue")>>,bg=<<get-color(name="bg-other")>>"
setw -g window-status-separator ""
setw -g window-status-style "none,fg=<<get-color(name="fg")>>,bg=<<get-color(name="bg-other")>>"
set -g status-left "#[fg=<<get-fg-for-color(name="blue")>>,bg=<<get-color(name="blue")>>] #S #[fg=<<get-color(name="blue")>>,bg=<<get-color(name="light-blue")>>,nobold,nounderscore,noitalics]#[fg=<<get-fg-for-color(name="light-blue")>>,bg=<<get-color(name="light-blue")>>] #W #[fg=<<get-color(name="light-blue")>>,bg=<<get-color(name="bg-other")>>,nobold,nounderscore,noitalics]"
set -g status-right "%-H:%M #[bg=<<get-color(name="bg-other")>>,fg=<<get-color(name="light-blue")>>,nobold,nounderscore,noitalics]#[fg=<<get-fg-for-color(name="light-blue")>>,bg=<<get-color(name="light-blue")>>] %a, %b %d #[bg=<<get-color(name="light-blue")>>,fg=<<get-color(name="blue")>>,nobold,nounderscore,noitalics]#[fg=<<get-fg-for-color(name="blue")>>,bg=<<get-color(name="blue")>>] #H "
setw -g window-status-format "#[fg=<<get-color(name="bg-other")>>,bg=<<get-color(name="light-blue")>>,nobold,nounderscore,noitalics]#[fg=<<get-fg-for-color(name="light-blue")>>,bg=<<get-color(name="light-blue")>>] #I #W #[align=left] #[fg=<<get-color(name="light-blue")>>,bg=<<get-color(name="bg-other")>>,nobold,nounderscore,noitalics]"
setw -g window-status-current-format "#[fg=<<get-color(name="bg-other")>>,bg=<<get-color(name="blue")>>,nobold,nounderscore,noitalics]#[fg=<<get-fg-for-color(name="blue")>>,bg=<<get-color(name="blue")>>] #I #W #[fg=<<get-color(name="blue")>>,bg=<<get-color(name="bg-other")>>,nobold,nounderscore,noitalics]"
#+end_src

Source the line config:
#+begin_src conf-space
source ~/.tmux.line.conf
#+end_src
* Alacritty
:PROPERTIES:
:header-args+: :tangle ./.config/alacritty/alacritty.yml :comments link
:END:

| Guix dependency |
|-----------------|
| alacritty       |

[[https://github.com/alacritty/alacritty][Alacritty]] is a GPU-accelerated terminal emulator. I haven't found it to be an inch faster than st, but =yml= configuration is way more convenient than patches.

References:
- [[https://github.com/alacritty/alacritty/blob/master/alacritty.yml][default config]]

#+begin_src yaml :noweb yes
decorations: none

font:
  normal:
    family: JetBrainsMono Nerd Font
    style: Regular

  size: 10

env:
  TERM: xterm-256color

colors:
  primary:
    background: '<<get-color(name="bg")>>'
    foreground: '<<get-color(name="fg")>>'
  normal:
    black: '<<get-color(name="black")>>'
    red: '<<get-color(name="red")>>'
    green: '<<get-color(name="green")>>'
    yellow: '<<get-color(name="yellow")>>'
    blue: '<<get-color(name="blue")>>'
    magenta: '<<get-color(name="magenta")>>'
    cyan: '<<get-color(name="cyan")>>'
    white: '<<get-color(name="white")>>'
  bright:
    Black: '<<get-color(name="light-black")>>'
    Red: '<<get-color(name="light-red")>>'
    Green: '<<get-color(name="light-green")>>'
    Yellow: '<<get-color(name="light-yellow")>>'
    Blue: '<<get-color(name="light-blue")>>'
    Magenta: '<<get-color(name="light-magenta")>>'
    Cyan: '<<get-color(name="light-cyan")>>'
    White: '<<get-color(name="light-white")>>'

window:
  padding:
    x: 0
    y: 0
  dynamic_padding: true
  opacity: 1

key_bindings:
  - { key: Paste,                                       action: Paste          }
  - { key: Copy,                                        action: Copy           }
  - { key: L,         mods: Control,                    action: ClearLogNotice }
  - { key: L,         mods: Control, mode: ~Vi|~Search, chars: "\x0c"          }
  - { key: PageUp,    mods: Shift,   mode: ~Alt,        action: ScrollPageUp,  }
  - { key: PageDown,  mods: Shift,   mode: ~Alt,        action: ScrollPageDown }
  - { key: Home,      mods: Shift,   mode: ~Alt,        action: ScrollToTop,   }
  - { key: End,       mods: Shift,   mode: ~Alt,        action: ScrollToBottom }

  #  Turn off vi mode
  - { key: Space,  mods: Shift|Control, mode: ~Search,    action: ReceiveChar             }

  # (Windows, Linux, and BSD only)
  - { key: V,              mods: Control|Shift, mode: ~Vi,        action: Paste            }
  - { key: C,              mods: Control|Shift,                   action: Copy             }
  - { key: F,              mods: Control|Shift, mode: ~Search,    action: ReceiveChar    }
  - { key: B,              mods: Control|Shift, mode: ~Search,    action: ReceiveChar   }
  - { key: Insert,         mods: Shift,                           action: PasteSelection   }
  - { key: Key0,           mods: Control,                         action: ResetFontSize    }
  - { key: Equals,         mods: Control,                         action: IncreaseFontSize }
  - { key: Plus,           mods: Control,                         action: IncreaseFontSize }
  - { key: NumpadAdd,      mods: Control,                         action: IncreaseFontSize }
  - { key: Minus,          mods: Control,                         action: DecreaseFontSize }
  - { key: NumpadSubtract, mods: Control,                         action: DecreaseFontSize }
#+end_src
* Bottom
| Guix dependency       | Description                                 |
|-----------------------+---------------------------------------------|
| bottom-bin            | resource monitor                            |

[[https://github.com/ClementTsang/bottom][bottom]] is a TUI system monitor.

See the [[https://github.com/ClementTsang/bottom/blob/master/sample_configs/default_config.toml][default config]] for the avaliable options.

#+NAME: bottom-theme
#+begin_src elisp
(if (my/light-p) "default-light" "default")
#+end_src

#+begin_src toml :tangle ~/.config/bottom/bottom.toml :noweb yes
[flags]
hide_table_gap = true  # Remove space in tables
color = "<<bottom-theme()>>"
process_command = true

[processes]
columns = ["PID", "State", "Name", "CPU%", "Mem%", "R/s", "W/s", "User"]
#+end_src

* Various console applications
| Guix dependency | Description                                 |
|-----------------+---------------------------------------------|
| ncurses         | Provides stuff like ~clear~                 |
| exa             | ~ls~ replacement, written in Rust           |
| bat             | ~cat~ clone with syntax highlighting        |
| htop            | Interactive process viewer                  |
| nethogs         | A tool to group processed by used bandwidth |
| osync           | rsync wrapper                               |
| neofetch        | Fetch system info                           |
| fzf             | fuzzy finder                                |
| p7zip           | archiver                                    |
| password-store  | CLI password manager                        |
| zip             |                                             |
| unzip           |                                             |
| jmtpfs          | A tool to mount MTP devices (e.g. Android)  |
| tokei           | Count lines of code                         |
| sshfs           | Mount stuff over SSH                        |
| lftp            | File transfer                               |
| git-lfs         |                                             |
| glibc-locales   |                                             |
| direnv          |                                             |
| jless-bin       | JSON viewer                                 |
| megacmd         | mega.nz client                              |
| ncdu            | disk usage analyzer                         |
| openssl         |                                             |

** ripgrep config
Occasionally I can't exclude certain files from ripgrep via the VCS settings, so here is a simple config to ignore certain files globally.
#+begin_src text :tangle ~/.config/ripgrep/ripgreprc
--ignore-file=/home/pavel/.config/ripgrep/ripgrepignore
#+end_src

The ignore file:
#+begin_src text :tangle ~/.config/ripgrep/ripgrepignore
*.ts.snap
#+end_src

By default, ripgrep doesn't read any configs, so it is necessary to set the =RIPGREP_CONFIG_PATH= variable in the [[*Environment][.profile.]]
* Misc scripts
** =nt= - exec command with a finished notification
Usage:

#+begin_example
nt <command>
#+end_example

#+begin_src sh :tangle ~/bin/scripts/nt
command="$@"
if [ ! -z "$command" ]; then
    start_time="$(date -u +%s)"
    $command
    end_time="$(date -u +%s)"
    elapsed="$(($end_time-$start_time))"
    notify-send "Terminal" "Command\n$command\nexecuted in $elapsed seconds"
else
    notify-send "Terminal" "Command execution complete"
fi
#+end_src
** =autocommit=
A script to perform automatic commits in a repository. I use it to sync my org directory and password store. I guess it's not how git is intended to be used, but it works for me.

Usage:
#+begin_example
autocommit <repository> [-F]
#+end_example

Environment:
| Variable      | Description     | Default value |
|---------------+-----------------+---------------|
| =TIMEOUT_MIN= | Default timeout | 60            |

Here's roughly what the script is doing:
- If there is a merge conflict, notify
- If there were changed files in the last =TIMEOUT_MIN= minutes, commit
- Fetch
- If there were changes in the last =TTMEOUT_MIN=, merge (usually the merge is just fast-forward)
- If the fetch was successful & the merge was either successful or delayed because of changes in the last =TIMEOUT_MIN=, push
- Send a notification about the events above
- Send a separate notification if there is a merge conflict

#+begin_src bash :tangle ~/bin/scripts/autocommit
TIMEOUT_MIN=${TIMEOUT_MIN:-60}

export DISPLAY=:0
cd "$1"

TIMESTAMP=$(date +%s)
LAST_COMMIT_TIMESTAMP=$(git log -1 --format="%at" | xargs -I{} date -d @{} +%s)
RECENTLY_CHANGED_NUM=$(find . -not -path '*/\.*' -mmin -$TIMEOUT_MIN | wc -l)
CHANGED_NUM=$(git status --porcelain | wc -l)
COMMITED="No"
PUSHED="No"
FETCHED="No"
MERGED="No"

notify () {
    if command -v notify-send; then
        notify-send -u ${LEVEL:-normal} "$1" "$2"
    else
        echo "$1" "$2"
    fi
}

if [[ $(git ls-files -u | wc -l) -gt 0 ]]; then
    LEVEL=critical notify "Autocommit $(pwd)" "Merge conflict!"
fi

if [[ ($RECENTLY_CHANGED_NUM -eq 0 || $2 = "-F") && $CHANGED_NUM -gt 0 ]]; then
    read -r -d '' MESSAGE << EOM
Autocommit $(date -Iminutes)

Hostname: $(hostname)
EOM
    git add -A
    git commit -m "$MESSAGE"
    COMMITED="Yes"
fi

NEED_TO_PUSH=$(git log origin/master..HEAD | wc -l)

git fetch && FETCHED="Yes" || FETCHED="No"
if [[ $RECENTLY_CHANGED_NUM -gt 0 && $2 != '-F' ]]; then
    MERGED="Waiting"
fi

if [[ ($RECENTLY_CHANGED_NUM -eq 0 || $2 = "-F") && $FETCHED = "Yes" ]]; then
    MERGE_OUT=$(git merge origin/master) && MERGED="Yes" || MERGED="No"
fi

if [[ $NEED_TO_PUSH -gt 0 && ($MERGED = "Yes" || $MERGED = "Waiting") ]]; then
    git push origin && PUSHED="Yes" || PUSHED="No"
fi

if [[ $PUSHED = "Yes" || $COMMITED = "Yes" || ($MERGED = "Yes" &&  $MERGE_OUT != "Already up to date.")]]; then
    read -r -d '' NOTIFICATION << EOM
Commited: $COMMITED
Fetched: $FETCHED
Merged: $MERGED
Pushed: $PUSHED
EOM
    notify "Autocommit $(pwd)" "$NOTIFICATION"
fi

if [[ $(git ls-files -u | wc -l) -gt 0 ]]; then
    LEVEL=critical notify "Autocommit $(pwd)" "Merge conflict!"
fi
#+end_src

=mcron= job:
#+begin_src scheme :tangle ~/.config/cron/autocommit.guile
(job "0 * * * *" "autocommit ~/Documents/org-mode")
(job "0,15,30,45 * * * *" "autocommit ~/.password-store")
#+end_src
* Guix settings
#+NAME: packages
#+begin_src emacs-lisp :tangle no :eval never-export
(my/format-guix-dependencies)
#+end_src

#+begin_src scheme :tangle .config/guix/manifests/console.scm :noweb yes
(specifications->manifest
 '(
   <<packages()>>))
#+end_src
* Android notes
SSH instructions: https://wiki.termux.com/wiki/Remote_Access

Don't forget to install the following termux packages:
| Termux package |
|----------------|
| vim            |
| tmux           |
| starship       |
| fish           |
| exa            |
| bat            |
| git            |

Also:
- cleanup =$PREFIX/etc/motd= to remove hello message.
- copy the required font at =$HOME/.termux/font.ttf= and run =termux-reload-settings=.

** Installation of [[https://gitlab.com/dwt1/shell-color-scripts][DT's colorscripts]]:
#+begin_src bash :tangle no :eval no
git clone https://gitlab.com/dwt1/shell-color-scripts.git
cd shell-color-scripts
#+end_src

Apply a patch:
#+begin_src diff
--- a/colorscript.sh
+++ b/colorscript.sh
@@ -2,7 +2,7 @@

 # Simple CLI for shell-color-scripts

-DIR_COLORSCRIPTS="/opt/shell-color-scripts/colorscripts"
+DIR_COLORSCRIPTS="$PREFIX/opt/shell-color-scripts/colorscripts"
 LS_CMD="$(command -v ls)"
 fmt_help="  %-20s\t%-54s\n"
 list_colorscripts="$($LS_CMD "${DIR_COLORSCRIPTS}" | cut -d ' ' -f 1 | nl)"
#+end_src

#+begin_src bash :tangle no :eval no
sudo mkdir -p $PREFIX/opt/shell-color-scripts/colorscripts || return 1
sudo cp -rf colorscripts/* $PREFIX/opt/shell-color-scripts/colorscripts
sudo cp colorscript.sh $PREFIX/bin/colorscript
#+end_src
