diff --git a/config.toml b/config.toml index 1de8dbe..3becb97 100644 --- a/config.toml +++ b/config.toml @@ -10,7 +10,7 @@ staticDir = ["static"] favicon = "favicon.ico" # path to a .ico to use as favicon # logo = "logo.svg" [params.footer] - text = "Pavel Korytov, 2021" + text = "Pavel Korytov, 2022" mainSections = ['posts'] [permalinks] diff --git a/content/configs/Console.md b/content/configs/Console.md deleted file mode 100644 index f1c3375..0000000 --- a/content/configs/Console.md +++ /dev/null @@ -1,1132 +0,0 @@ -+++ -title = "Console" -author = ["Pavel"] -draft = false -+++ - -\#+TOC headlines 6 - - -## `.profile` {#dot-profile} - - -### Environment {#environment} - -```sh -export QT_QPA_PLATFORMTHEME="qt5ct" -export QT_AUTO_SCREEN_SCALE_FACTOR=0 -``` - -Set ripgrep config path - -```sh -export RIPGREP_CONFIG_PATH=$HOME/.config/ripgrep/ripgreprc -``` - - -### My paths {#my-paths} - -My script folders - -```sh -if [ -d "$HOME/bin" ] ; then - export PATH="$HOME/bin:$PATH" - export PATH="$HOME/bin/scripts:$PATH" -fi -``` - - -### Guix settings {#guix-settings} - -Enable extra profiles - -```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 - export XDG_DATA_DIRS="$XDG_DATA_DIRS:$profile/share" - unset profile - done -fi -``` - -Set Jupyter config PATH. It defaults to readonly directory somewhere in Guix profile. - -```sh -export JUPYTER_CONFIG_DIR=$HOME/.config/jupyter -``` - -Set a folder for my packages. - -```sh -export GUIX_PACKAGE_PATH=~/guix-packages -``` - - -### Other package managers {#other-package-managers} - -Using other package managers with Guix requires some extra work. - -Cask - -```sh -if [ -d "$HOME/.cask" ]; then - export PATH="/home/pavel/.cask/bin:$PATH" -fi -``` - -Make flatpak apps visible to launchers: - -```sh -if [ -d "$HOME/.local/share/flatpak" ]; then - export XDG_DATA_DIRS="$XDG_DATA_DIRS:$HOME/.local/share/flatpak/exports/share" -fi -``` - -Enable Nix - -```sh -if [ -f /run/current-system/profile/etc/profile.d/nix.sh ]; then - . /run/current-system/profile/etc/profile.d/nix.sh -fi -``` - -Use Guix fontconfig. Necessary for nix apps - -```sh -if [ -d "$HOME/.guix-extra-profiles/desktop-misc" ]; then - export FONTCONFIG_PATH="$HOME/.guix-extra-profiles/desktop-misc/desktop-misc/etc/fonts" -fi -``` - -Make nix apps visible to launchers: - -```sh -if [ -d "$HOME/.nix-profile" ]; then - export XDG_DATA_DIRS="$XDG_DATA_DIRS:$HOME/.nix-profile/share/applications" -fi -``` - - -#### npm {#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: - -```conf -prefix=/home/pavel/.npm-packages -``` - -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: - -```sh -export NPM_CONFIG_USERCONFIG=$HOME/._npmrc -``` - -The variable is unset in a script in [Guix.org]({{< relref "Guix" >}}). - -Set PATH & MANPATH - -```sh -NPM_PACKAGES="${HOME}/.npm-packages" - -export PATH="$PATH:$NPM_PACKAGES/bin" -export MANPATH="${MANPATH-$(manpath)}:$NPM_PACKAGES/share/man" -``` - - -### XResources {#xresources} - -| Guix dependency | -|-----------------| -| xrdb | - -```sh -if [ -z "$IS_ANDROID" ]; then - xrdb ~/.Xresources -fi -``` - - -### OFF (OFF) Package manager paths {#off--package-manager-paths} - -Turned off for now, because probably it won't be necessary in Guix. - -LaTeX - -```sh -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 -``` - -Cargo (Rust) - -```sh -if [ -d "$HOME/.cargo" ] ; then - export PATH="$HOME/.cargo/bin:$PATH" -fi -``` - -RVM (Ruby) - -```sh -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 -``` - -Go - -```sh -if [ -d "$HOME/go" ] ; then - export PATH="$HOME/go/bin:$PATH" -fi -``` - -ghcup (Haskell) - -```sh -[ -f "/home/pavel/.ghcup/env" ] && source "/home/pavel/.ghcup/env" # ghcup-env -``` - -Perl - -```sh -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 -``` - - -## Bash {#bash} - - -### `.bash_profile` {#dot-bash-profile} - -```bash -[[ -f ~/.profile ]] && . ~/.profile - -[[ -f ~/.bashrc ]] && . ~/.bashrc -``` - - -### `.bashrc` {#dot-bashrc} - -My `.bashrc`, which has pieces from the default ones in Guix & Manjaro, as well some mine settings. - - -#### Startup & environment {#startup-and-environment} - -Export 'SHELL' to child processes. Programs such as 'screen' honor it and otherwise use /bin/sh. - -```bash -export SHELL -``` - -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. - -```bash -if [[ $- != *i* ]] -then - [[ -n "$SSH_CLIENT" && -f "/etc/bashrc" ]] && source /etc/profile - return -fi -``` - -Source the system-wide file - -```bash -if [[ -f "/etc/bashrc" ]]; then - source /etc/bashrc -fi -``` - -| Guix dependency | -|-----------------| -| xhost | - -Allow other users to access X server. Necessary for stuff like aw-watcher-window. - -```bash -xhost +local:root > /dev/null 2>&1 -``` - -Set manpager to bat - -```bash -export MANPAGER="sh -c 'sed -e s/.\\\\x08//g | bat -l man -p'" -``` - - -#### Launch fish {#launch-fish} - -Launch fish shell unless bash itself is launched from fish. - -```bash -use_fish=true - -if [[ $(ps --no-header --pid=$PPID --format=cmd) != "fish" && ${use_fish} && $(command -v fish) ]] -then - exec fish -fi -``` - -The rest of `.bashrc` is not executed if fish was launched. - - -#### Colors {#colors} - -Setting for colors, packed in the default `.bashrc` in Manjaro - -```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}$(/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 -``` - - -#### Settings {#settings} - -Some general bash settings. - -References: - -- [shopt list](https://www.gnu.org/software/bash/manual/html%5Fnode/The-Shopt-Builtin.html) - - - -```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) -``` - -History control - -```bash -shopt -s histappend -export HISTCONTROL=ignoredups:erasedups -HISTSIZE= -HISTFILESIZE= -``` - -Autocompletions - -```bash -[ -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 -``` - - -#### Aliases {#aliases} - -```bash -alias v="vim" -alias gg="lazygit" -alias ls="exa --icons" -alias ll="exa -lah --icons" -alias q="exit" -alias c="clear" -alias ci="init_conda" -alias ca="conda activate" -alias cii="export INIT_CONDA=true && init_conda" -``` - -```bash -if [[ ! -z "$SIMPLE" ]]; then - unalias ls - alias ll="ls -lah" -fi -``` - - -#### Anaconda {#anaconda} - -> managed by 'conda init' !!! - -Yeah, tell this to yourself - -```bash -init_conda () { - __conda_setup="$('/home/pavel/.guix-extra-profiles/dev/dev/bin/conda' 'shell.bash' 'hook' 2> /dev/null)" - if [ $? -eq 0 ]; then - eval "$__conda_setup" - else - if [ -f "/home/pavel/.guix-extra-profiles/dev/dev/etc/profile.d/conda.sh" ]; then - . "/home/pavel/.guix-extra-profiles/dev/dev/etc/profile.d/conda.sh" - else - # export PATH="/home/pavel/Programs/miniconda3/bin:$PATH" - echo "what" - fi - fi - unset __conda_setup -} - -if [[ ! -z "$INIT_CONDA" ]]; then - init_conda -fi -``` - - -#### Starship prompt {#starship-prompt} - -```bash -if [[ -z "$SIMPLE" ]]; then - eval "$(starship init bash)" -fi -``` - - -## Fish {#fish} - -| Guix dependency | Description | -|-----------------|------------------------------------------| -| fish | An alternative non POSIX-compliant shell | - -[Fish shell](https://fishshell.com/) is a non-POSIX-compliant shell, which offers some fancy UI & UX features. - -Launch starship - -```fish -starship init fish | source -``` - -Enable vi keybindings & aliases. The alias syntax is the same as in bash, so it's just a noweb reference to `.bashrc`. - -```fish -fish_vi_key_bindings - -<> -alias cad="conda activate (basename (pwd))" -``` - -| Guix dependency | -|-----------------| -| dt-colorscripts | - -Launch a random [DT's colorscript](https://gitlab.com/dwt1/shell-color-scripts) unless ran inside tmux or Emacs. - -```fish -if ! test -n "$TMUX"; and ! test -n "$IS_EMACS"; - colorscript random -end -``` - -Suppress fish greeting - -```fish -set fish_greeting -``` - - -### Anaconda {#anaconda} - -First, a function to initialize anaconda. - -```fish -function init_conda - eval /home/pavel/.guix-extra-profiles/dev/dev/bin/conda "shell.fish" "hook" $argv | source -end - -if test -n "$INIT_CONDA"; - init_conda -end -``` - -Then, check if launched from Emacs with environment activated. - -```fish -if test -n "$EMACS_CONDA_ENV"; - conda activate $EMACS_CONDA_ENV -end -``` - - -### Colors {#colors} - -Fish seems to have hardcoded colorcodes in some color settings. I set these to base16 colors so they would match Xresources. - -```fish -set fish_color_command cyan -set fish_color_comment green -set fish_color_end white -set fish_color_error red -set fish_color_escape yellow -set fish_color_operator yellow -set fish_color_param magenta -set fish_color_quote brwhite -set fish_color_redirection yellow -``` - - -### Keybindings {#keybindings} - -```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 -``` - - -### Functions {#functions} - -A small function to open the file with `$EDITOR`. - -```fish -function e - eval $EDITOR $argv -end -``` - - -## Nushell {#nushell} - -| Guix dependency | -|-----------------| -| nushell-bin | - -A structured shell. I don't use it as of now, but perhaps one day. - -Set starship prompt - -```toml -startup = [ - <>, - "mkdir ~/.cache/starship", - "starship init nu | save ~/.cache/starship/init.nu", - "source ~/.cache/starship/init.nu", -] -prompt = "starship_prompt" -``` - -Skip welcome message - -```toml -skip_welcome_message = true -``` - -Set table mode - -```toml -table_mode = "rounded" -``` - -Aliases - -```toml -"alias ll = ls -l", -"alias c = clear", -"alias q = exit" -``` - -Colors - -```toml -[color_config] -primitive_filesize="ub" -primitive_boolean="yu" -primitive_duration="g" -primitive_path="y" -primitive_date="r" -primitive_int="c" -primitive_decimal="c" -``` - - -## Starship prompt {#starship-prompt} - -| Guix dependency | Description | -|-----------------|---------------------| -| rust-starship | my prompt of choice | - -[Starship](https://starship.rs/) is a nice cross-shell prompt, written in Rust. - -References: - -- [Startship config guide](https://starship.rs/config/) - - - -```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 = " " -``` - - -## Tmux {#tmux} - -| Guix dependency | -|-----------------| -| tmux | -| python-tmuxp | - -[tmux](https://github.com/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 {#term-settings} - -I have no idea how and why these two work. - -```vim -set -g default-terminal "screen-256color" -set -ga terminal-overrides ",*256col*:Tc" -``` - -History limit. - -```vim -set -g history-limit 20000 -``` - - -### Keybindings {#keybindings} - -Enable vi keys and mouse. - -```vim -set-window-option -g mode-keys vi -set-option -g xterm-keys on -set-option -g mouse on -set -sg escape-time 10 -``` - -Change prefix from `C-b` to `C-a`. - -```vim -unbind C-b -set -g prefix C-a -bind C-a send-prefix -``` - -Vi-like keybindings to manage panes & windows. - -```vim -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 -``` - -Reload the config. - -```vim -bind r source-file ~/.tmux.conf -``` - - -### Copy to clipboard {#copy-to-clipboard} - -| Guix dependency | -|-----------------| -| xclip | - -Make tmux copying copy to clipboard as well - -```vim -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" -``` - - -### UI {#ui} - -I generated the following with [tmuxline.vim](https://github.com/edkolev/tmuxline.vim) plugin and palenight theme for [vim-airline](https://github.com/vim-airline/vim-airline) - -```vim -# This tmux statusbar config was created by tmuxline.vim -# on Wed, 22 Jan 2020 - -set -g status-justify "centre" -set -g status "on" -set -g status-left-style "none" -set -g message-command-style "fg=#bfc7d5,bg=#474b59" -set -g status-right-style "none" -set -g pane-active-border-style "fg=#939ede" -set -g status-style "none,bg=#333747" -set -g message-style "fg=#bfc7d5,bg=#474b59" -set -g pane-border-style "fg=#474b59" -set -g status-right-length "100" -set -g status-left-length "100" -setw -g window-status-activity-style "none,fg=#939ede,bg=#333747" -setw -g window-status-separator "" -setw -g window-status-style "none,fg=#bfc7d5,bg=#333747" -set -g status-left "#[fg=#292D3E,bg=#939ede] #S #[fg=#939ede,bg=#474b59,nobold,nounderscore,noitalics]#[fg=#bfc7d5,bg=#474b59] #W #[fg=#474b59,bg=#333747,nobold,nounderscore,noitalics]" -set -g status-right "#[fg=#333747,bg=#333747,nobold,nounderscore,noitalics]#[fg=#bfc7d5,bg=#333747] %-H:%M #[fg=#474b59,bg=#333747,nobold,nounderscore,noitalics]#[fg=#bfc7d5,bg=#474b59] %a, %b %d #[fg=#939ede,bg=#474b59,nobold,nounderscore,noitalics]#[fg=#292D3E,bg=#939ede] #H " -setw -g window-status-format "#[fg=#333747,bg=#333747,nobold,nounderscore,noitalics]#[default] #I #W #[align=left] #[fg=#333747,bg=#333747,nobold,nounderscore,noitalics]" -setw -g window-status-current-format "#[fg=#333747,bg=#474b59,nobold,nounderscore,noitalics]#[fg=#bfc7d5,bg=#474b59] #I #W #[fg=#474b59,bg=#333747,nobold,nounderscore,noitalics]" -``` - -Source the line config: - -```vim -source ~/.tmux.line.conf -``` - - -## Alacritty {#alacritty} - -| Guix dependency | -|-----------------| -| alacritty | - -[Alacritty](https://github.com/alacritty/alacritty) is a GPU-accelerated terminal emulator. I haven't found it to be an inch faster than st, but configuration the in yml format is way more convinient than patches. - -Once again, we have an application which doesn't support reading Xresources, so here goes noweb. - - -```bash -xrdb -query all | grep "$color:" | cut -f 2 -``` - -```emacs-lisp -(setq-local org-confirm-babel-evaluate nil) -``` - -References: - -- [default config](https://github.com/alacritty/alacritty/blob/master/alacritty.yml) - - - -```yaml -decorations: none - -font: - normal: - family: JetBrainsMono Nerd Font - style: Regular - - size: 10 - -env: - TERM: xterm-256color - -colors: - primary: - background: '<>' - foreground: '<>' - normal: - black: '<>' - red: '<>' - green: '<>' - yellow: '<>' - blue: '<>' - magenta: '<>' - cyan: '<>' - white: '<>' - bright: - Black: '<>' - Red: '<>' - Green: '<>' - Yellow: '<>' - Blue: '<>' - Magenta: '<>' - Cyan: '<>' - White: '<>' - -background_opacity: 0.80 - -window: - padding: - x: 0 - y: 0 - dynamic_padding: true - -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 } -``` - - -## Various console applications {#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 | -| unzip | | -| jmtpfs | A tool to mount MTP devices (e.g. Android) | -| tokei | Count lines of code | -| sshfs | Mount stuff over SSH | - - -### ripgrep config {#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. - -```text ---ignore-file=/home/pavel/.config/ripgrep/ripgrepignore -``` - -The corresponding ignore file: - -```text -*.ts.snap -``` - -By default ripgrep doesn't read any configs, so it is necessary to set the `RIPGREP_CONFIG_PATH` variable in the [.profile.](#environment) - - -## Misc scripts {#misc-scripts} - - -### `nt` - exec command with a finished notification {#nt-exec-command-with-a-finished-notification} - -Usage: - -```text -nt -``` - -```sh -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 -``` - - -### `autocommit` {#autocommit} - -A script to autocommit files 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: - -```text -autocommit [-F] -``` - -Environment: - -| Variable | Description | Default value | -|---------------|-----------------|---------------| -| `TIMEOUT_MIN` | Default timeout | 60 | - -Here's more or less what the script is doing: - -- If there is a merge conflict, notify -- If there are changed files in the last `TIMEOUT_MIN` minutes, commit -- Fetch -- If there are were changes in the last `TTMEOUT_MIN`, merge (usually the merge has to be fast-forward) -- If fetch was successful & merge was 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 - - - -```bash -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" - -if [[ $(git ls-files -u | wc -l) -gt 0 ]]; then - notify-send -u critical "Autocommit $(pwd)" "Merge conflict!" - exit -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-send "Autocommit $(pwd)" "$NOTIFICATION" -fi - -if [[ $(git ls-files -u | wc -l) -gt 0 ]]; then - notify-send -u critical "Autocommit $(pwd)" "Merge conflict!" -fi -``` - -`mcron` job: - -```scheme -(job "0 * * * *" "autocommit ~/Documents/org-mode") -(job "0,15,30,45 * * * *" "autocommit ~/.password-store") -``` - - -## Guix settings {#guix-settings} - - -```emacs-lisp -(my/format-guix-dependencies) -``` - -```scheme -(specifications->manifest - '( - <>)) -``` - - -## Android notes {#android-notes} - -SSH instructions: - -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 [DT's colorscripts](https://gitlab.com/dwt1/shell-color-scripts): {#installation-of-dt-s-colorscripts} - -```bash -git clone https://gitlab.com/dwt1/shell-color-scripts.git -cd shell-color-scripts -``` - -Apply a patch: - -```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)" -``` - -```bash -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 -``` \ No newline at end of file diff --git a/content/configs/Console.md~ b/content/configs/Console.md~ deleted file mode 100644 index f1c3375..0000000 --- a/content/configs/Console.md~ +++ /dev/null @@ -1,1132 +0,0 @@ -+++ -title = "Console" -author = ["Pavel"] -draft = false -+++ - -\#+TOC headlines 6 - - -## `.profile` {#dot-profile} - - -### Environment {#environment} - -```sh -export QT_QPA_PLATFORMTHEME="qt5ct" -export QT_AUTO_SCREEN_SCALE_FACTOR=0 -``` - -Set ripgrep config path - -```sh -export RIPGREP_CONFIG_PATH=$HOME/.config/ripgrep/ripgreprc -``` - - -### My paths {#my-paths} - -My script folders - -```sh -if [ -d "$HOME/bin" ] ; then - export PATH="$HOME/bin:$PATH" - export PATH="$HOME/bin/scripts:$PATH" -fi -``` - - -### Guix settings {#guix-settings} - -Enable extra profiles - -```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 - export XDG_DATA_DIRS="$XDG_DATA_DIRS:$profile/share" - unset profile - done -fi -``` - -Set Jupyter config PATH. It defaults to readonly directory somewhere in Guix profile. - -```sh -export JUPYTER_CONFIG_DIR=$HOME/.config/jupyter -``` - -Set a folder for my packages. - -```sh -export GUIX_PACKAGE_PATH=~/guix-packages -``` - - -### Other package managers {#other-package-managers} - -Using other package managers with Guix requires some extra work. - -Cask - -```sh -if [ -d "$HOME/.cask" ]; then - export PATH="/home/pavel/.cask/bin:$PATH" -fi -``` - -Make flatpak apps visible to launchers: - -```sh -if [ -d "$HOME/.local/share/flatpak" ]; then - export XDG_DATA_DIRS="$XDG_DATA_DIRS:$HOME/.local/share/flatpak/exports/share" -fi -``` - -Enable Nix - -```sh -if [ -f /run/current-system/profile/etc/profile.d/nix.sh ]; then - . /run/current-system/profile/etc/profile.d/nix.sh -fi -``` - -Use Guix fontconfig. Necessary for nix apps - -```sh -if [ -d "$HOME/.guix-extra-profiles/desktop-misc" ]; then - export FONTCONFIG_PATH="$HOME/.guix-extra-profiles/desktop-misc/desktop-misc/etc/fonts" -fi -``` - -Make nix apps visible to launchers: - -```sh -if [ -d "$HOME/.nix-profile" ]; then - export XDG_DATA_DIRS="$XDG_DATA_DIRS:$HOME/.nix-profile/share/applications" -fi -``` - - -#### npm {#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: - -```conf -prefix=/home/pavel/.npm-packages -``` - -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: - -```sh -export NPM_CONFIG_USERCONFIG=$HOME/._npmrc -``` - -The variable is unset in a script in [Guix.org]({{< relref "Guix" >}}). - -Set PATH & MANPATH - -```sh -NPM_PACKAGES="${HOME}/.npm-packages" - -export PATH="$PATH:$NPM_PACKAGES/bin" -export MANPATH="${MANPATH-$(manpath)}:$NPM_PACKAGES/share/man" -``` - - -### XResources {#xresources} - -| Guix dependency | -|-----------------| -| xrdb | - -```sh -if [ -z "$IS_ANDROID" ]; then - xrdb ~/.Xresources -fi -``` - - -### OFF (OFF) Package manager paths {#off--package-manager-paths} - -Turned off for now, because probably it won't be necessary in Guix. - -LaTeX - -```sh -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 -``` - -Cargo (Rust) - -```sh -if [ -d "$HOME/.cargo" ] ; then - export PATH="$HOME/.cargo/bin:$PATH" -fi -``` - -RVM (Ruby) - -```sh -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 -``` - -Go - -```sh -if [ -d "$HOME/go" ] ; then - export PATH="$HOME/go/bin:$PATH" -fi -``` - -ghcup (Haskell) - -```sh -[ -f "/home/pavel/.ghcup/env" ] && source "/home/pavel/.ghcup/env" # ghcup-env -``` - -Perl - -```sh -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 -``` - - -## Bash {#bash} - - -### `.bash_profile` {#dot-bash-profile} - -```bash -[[ -f ~/.profile ]] && . ~/.profile - -[[ -f ~/.bashrc ]] && . ~/.bashrc -``` - - -### `.bashrc` {#dot-bashrc} - -My `.bashrc`, which has pieces from the default ones in Guix & Manjaro, as well some mine settings. - - -#### Startup & environment {#startup-and-environment} - -Export 'SHELL' to child processes. Programs such as 'screen' honor it and otherwise use /bin/sh. - -```bash -export SHELL -``` - -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. - -```bash -if [[ $- != *i* ]] -then - [[ -n "$SSH_CLIENT" && -f "/etc/bashrc" ]] && source /etc/profile - return -fi -``` - -Source the system-wide file - -```bash -if [[ -f "/etc/bashrc" ]]; then - source /etc/bashrc -fi -``` - -| Guix dependency | -|-----------------| -| xhost | - -Allow other users to access X server. Necessary for stuff like aw-watcher-window. - -```bash -xhost +local:root > /dev/null 2>&1 -``` - -Set manpager to bat - -```bash -export MANPAGER="sh -c 'sed -e s/.\\\\x08//g | bat -l man -p'" -``` - - -#### Launch fish {#launch-fish} - -Launch fish shell unless bash itself is launched from fish. - -```bash -use_fish=true - -if [[ $(ps --no-header --pid=$PPID --format=cmd) != "fish" && ${use_fish} && $(command -v fish) ]] -then - exec fish -fi -``` - -The rest of `.bashrc` is not executed if fish was launched. - - -#### Colors {#colors} - -Setting for colors, packed in the default `.bashrc` in Manjaro - -```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}$(/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 -``` - - -#### Settings {#settings} - -Some general bash settings. - -References: - -- [shopt list](https://www.gnu.org/software/bash/manual/html%5Fnode/The-Shopt-Builtin.html) - - - -```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) -``` - -History control - -```bash -shopt -s histappend -export HISTCONTROL=ignoredups:erasedups -HISTSIZE= -HISTFILESIZE= -``` - -Autocompletions - -```bash -[ -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 -``` - - -#### Aliases {#aliases} - -```bash -alias v="vim" -alias gg="lazygit" -alias ls="exa --icons" -alias ll="exa -lah --icons" -alias q="exit" -alias c="clear" -alias ci="init_conda" -alias ca="conda activate" -alias cii="export INIT_CONDA=true && init_conda" -``` - -```bash -if [[ ! -z "$SIMPLE" ]]; then - unalias ls - alias ll="ls -lah" -fi -``` - - -#### Anaconda {#anaconda} - -> managed by 'conda init' !!! - -Yeah, tell this to yourself - -```bash -init_conda () { - __conda_setup="$('/home/pavel/.guix-extra-profiles/dev/dev/bin/conda' 'shell.bash' 'hook' 2> /dev/null)" - if [ $? -eq 0 ]; then - eval "$__conda_setup" - else - if [ -f "/home/pavel/.guix-extra-profiles/dev/dev/etc/profile.d/conda.sh" ]; then - . "/home/pavel/.guix-extra-profiles/dev/dev/etc/profile.d/conda.sh" - else - # export PATH="/home/pavel/Programs/miniconda3/bin:$PATH" - echo "what" - fi - fi - unset __conda_setup -} - -if [[ ! -z "$INIT_CONDA" ]]; then - init_conda -fi -``` - - -#### Starship prompt {#starship-prompt} - -```bash -if [[ -z "$SIMPLE" ]]; then - eval "$(starship init bash)" -fi -``` - - -## Fish {#fish} - -| Guix dependency | Description | -|-----------------|------------------------------------------| -| fish | An alternative non POSIX-compliant shell | - -[Fish shell](https://fishshell.com/) is a non-POSIX-compliant shell, which offers some fancy UI & UX features. - -Launch starship - -```fish -starship init fish | source -``` - -Enable vi keybindings & aliases. The alias syntax is the same as in bash, so it's just a noweb reference to `.bashrc`. - -```fish -fish_vi_key_bindings - -<> -alias cad="conda activate (basename (pwd))" -``` - -| Guix dependency | -|-----------------| -| dt-colorscripts | - -Launch a random [DT's colorscript](https://gitlab.com/dwt1/shell-color-scripts) unless ran inside tmux or Emacs. - -```fish -if ! test -n "$TMUX"; and ! test -n "$IS_EMACS"; - colorscript random -end -``` - -Suppress fish greeting - -```fish -set fish_greeting -``` - - -### Anaconda {#anaconda} - -First, a function to initialize anaconda. - -```fish -function init_conda - eval /home/pavel/.guix-extra-profiles/dev/dev/bin/conda "shell.fish" "hook" $argv | source -end - -if test -n "$INIT_CONDA"; - init_conda -end -``` - -Then, check if launched from Emacs with environment activated. - -```fish -if test -n "$EMACS_CONDA_ENV"; - conda activate $EMACS_CONDA_ENV -end -``` - - -### Colors {#colors} - -Fish seems to have hardcoded colorcodes in some color settings. I set these to base16 colors so they would match Xresources. - -```fish -set fish_color_command cyan -set fish_color_comment green -set fish_color_end white -set fish_color_error red -set fish_color_escape yellow -set fish_color_operator yellow -set fish_color_param magenta -set fish_color_quote brwhite -set fish_color_redirection yellow -``` - - -### Keybindings {#keybindings} - -```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 -``` - - -### Functions {#functions} - -A small function to open the file with `$EDITOR`. - -```fish -function e - eval $EDITOR $argv -end -``` - - -## Nushell {#nushell} - -| Guix dependency | -|-----------------| -| nushell-bin | - -A structured shell. I don't use it as of now, but perhaps one day. - -Set starship prompt - -```toml -startup = [ - <>, - "mkdir ~/.cache/starship", - "starship init nu | save ~/.cache/starship/init.nu", - "source ~/.cache/starship/init.nu", -] -prompt = "starship_prompt" -``` - -Skip welcome message - -```toml -skip_welcome_message = true -``` - -Set table mode - -```toml -table_mode = "rounded" -``` - -Aliases - -```toml -"alias ll = ls -l", -"alias c = clear", -"alias q = exit" -``` - -Colors - -```toml -[color_config] -primitive_filesize="ub" -primitive_boolean="yu" -primitive_duration="g" -primitive_path="y" -primitive_date="r" -primitive_int="c" -primitive_decimal="c" -``` - - -## Starship prompt {#starship-prompt} - -| Guix dependency | Description | -|-----------------|---------------------| -| rust-starship | my prompt of choice | - -[Starship](https://starship.rs/) is a nice cross-shell prompt, written in Rust. - -References: - -- [Startship config guide](https://starship.rs/config/) - - - -```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 = " " -``` - - -## Tmux {#tmux} - -| Guix dependency | -|-----------------| -| tmux | -| python-tmuxp | - -[tmux](https://github.com/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 {#term-settings} - -I have no idea how and why these two work. - -```vim -set -g default-terminal "screen-256color" -set -ga terminal-overrides ",*256col*:Tc" -``` - -History limit. - -```vim -set -g history-limit 20000 -``` - - -### Keybindings {#keybindings} - -Enable vi keys and mouse. - -```vim -set-window-option -g mode-keys vi -set-option -g xterm-keys on -set-option -g mouse on -set -sg escape-time 10 -``` - -Change prefix from `C-b` to `C-a`. - -```vim -unbind C-b -set -g prefix C-a -bind C-a send-prefix -``` - -Vi-like keybindings to manage panes & windows. - -```vim -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 -``` - -Reload the config. - -```vim -bind r source-file ~/.tmux.conf -``` - - -### Copy to clipboard {#copy-to-clipboard} - -| Guix dependency | -|-----------------| -| xclip | - -Make tmux copying copy to clipboard as well - -```vim -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" -``` - - -### UI {#ui} - -I generated the following with [tmuxline.vim](https://github.com/edkolev/tmuxline.vim) plugin and palenight theme for [vim-airline](https://github.com/vim-airline/vim-airline) - -```vim -# This tmux statusbar config was created by tmuxline.vim -# on Wed, 22 Jan 2020 - -set -g status-justify "centre" -set -g status "on" -set -g status-left-style "none" -set -g message-command-style "fg=#bfc7d5,bg=#474b59" -set -g status-right-style "none" -set -g pane-active-border-style "fg=#939ede" -set -g status-style "none,bg=#333747" -set -g message-style "fg=#bfc7d5,bg=#474b59" -set -g pane-border-style "fg=#474b59" -set -g status-right-length "100" -set -g status-left-length "100" -setw -g window-status-activity-style "none,fg=#939ede,bg=#333747" -setw -g window-status-separator "" -setw -g window-status-style "none,fg=#bfc7d5,bg=#333747" -set -g status-left "#[fg=#292D3E,bg=#939ede] #S #[fg=#939ede,bg=#474b59,nobold,nounderscore,noitalics]#[fg=#bfc7d5,bg=#474b59] #W #[fg=#474b59,bg=#333747,nobold,nounderscore,noitalics]" -set -g status-right "#[fg=#333747,bg=#333747,nobold,nounderscore,noitalics]#[fg=#bfc7d5,bg=#333747] %-H:%M #[fg=#474b59,bg=#333747,nobold,nounderscore,noitalics]#[fg=#bfc7d5,bg=#474b59] %a, %b %d #[fg=#939ede,bg=#474b59,nobold,nounderscore,noitalics]#[fg=#292D3E,bg=#939ede] #H " -setw -g window-status-format "#[fg=#333747,bg=#333747,nobold,nounderscore,noitalics]#[default] #I #W #[align=left] #[fg=#333747,bg=#333747,nobold,nounderscore,noitalics]" -setw -g window-status-current-format "#[fg=#333747,bg=#474b59,nobold,nounderscore,noitalics]#[fg=#bfc7d5,bg=#474b59] #I #W #[fg=#474b59,bg=#333747,nobold,nounderscore,noitalics]" -``` - -Source the line config: - -```vim -source ~/.tmux.line.conf -``` - - -## Alacritty {#alacritty} - -| Guix dependency | -|-----------------| -| alacritty | - -[Alacritty](https://github.com/alacritty/alacritty) is a GPU-accelerated terminal emulator. I haven't found it to be an inch faster than st, but configuration the in yml format is way more convinient than patches. - -Once again, we have an application which doesn't support reading Xresources, so here goes noweb. - - -```bash -xrdb -query all | grep "$color:" | cut -f 2 -``` - -```emacs-lisp -(setq-local org-confirm-babel-evaluate nil) -``` - -References: - -- [default config](https://github.com/alacritty/alacritty/blob/master/alacritty.yml) - - - -```yaml -decorations: none - -font: - normal: - family: JetBrainsMono Nerd Font - style: Regular - - size: 10 - -env: - TERM: xterm-256color - -colors: - primary: - background: '<>' - foreground: '<>' - normal: - black: '<>' - red: '<>' - green: '<>' - yellow: '<>' - blue: '<>' - magenta: '<>' - cyan: '<>' - white: '<>' - bright: - Black: '<>' - Red: '<>' - Green: '<>' - Yellow: '<>' - Blue: '<>' - Magenta: '<>' - Cyan: '<>' - White: '<>' - -background_opacity: 0.80 - -window: - padding: - x: 0 - y: 0 - dynamic_padding: true - -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 } -``` - - -## Various console applications {#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 | -| unzip | | -| jmtpfs | A tool to mount MTP devices (e.g. Android) | -| tokei | Count lines of code | -| sshfs | Mount stuff over SSH | - - -### ripgrep config {#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. - -```text ---ignore-file=/home/pavel/.config/ripgrep/ripgrepignore -``` - -The corresponding ignore file: - -```text -*.ts.snap -``` - -By default ripgrep doesn't read any configs, so it is necessary to set the `RIPGREP_CONFIG_PATH` variable in the [.profile.](#environment) - - -## Misc scripts {#misc-scripts} - - -### `nt` - exec command with a finished notification {#nt-exec-command-with-a-finished-notification} - -Usage: - -```text -nt -``` - -```sh -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 -``` - - -### `autocommit` {#autocommit} - -A script to autocommit files 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: - -```text -autocommit [-F] -``` - -Environment: - -| Variable | Description | Default value | -|---------------|-----------------|---------------| -| `TIMEOUT_MIN` | Default timeout | 60 | - -Here's more or less what the script is doing: - -- If there is a merge conflict, notify -- If there are changed files in the last `TIMEOUT_MIN` minutes, commit -- Fetch -- If there are were changes in the last `TTMEOUT_MIN`, merge (usually the merge has to be fast-forward) -- If fetch was successful & merge was 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 - - - -```bash -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" - -if [[ $(git ls-files -u | wc -l) -gt 0 ]]; then - notify-send -u critical "Autocommit $(pwd)" "Merge conflict!" - exit -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-send "Autocommit $(pwd)" "$NOTIFICATION" -fi - -if [[ $(git ls-files -u | wc -l) -gt 0 ]]; then - notify-send -u critical "Autocommit $(pwd)" "Merge conflict!" -fi -``` - -`mcron` job: - -```scheme -(job "0 * * * *" "autocommit ~/Documents/org-mode") -(job "0,15,30,45 * * * *" "autocommit ~/.password-store") -``` - - -## Guix settings {#guix-settings} - - -```emacs-lisp -(my/format-guix-dependencies) -``` - -```scheme -(specifications->manifest - '( - <>)) -``` - - -## Android notes {#android-notes} - -SSH instructions: - -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 [DT's colorscripts](https://gitlab.com/dwt1/shell-color-scripts): {#installation-of-dt-s-colorscripts} - -```bash -git clone https://gitlab.com/dwt1/shell-color-scripts.git -cd shell-color-scripts -``` - -Apply a patch: - -```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)" -``` - -```bash -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 -``` \ No newline at end of file diff --git a/content/configs/Desktop.md b/content/configs/Desktop.md deleted file mode 100644 index ce17c59..0000000 --- a/content/configs/Desktop.md +++ /dev/null @@ -1,3714 +0,0 @@ -+++ -title = "Desktop" -author = ["Pavel"] -draft = false -+++ - -My general desktop environment configuration. - -Parts prefixed with (OFF) are not used, but kept for historic purposes. For some reason GitHub's org renderer ignores TODO status, hence such a prefix. Round brackets instead of square ones to prevent GitHub's org renderer from screwing up. - -
-
- -
Table of Contents
- -- [Global customization](#global-customization) - - [Colors](#colors) - - [Xresources](#xresources) - - [Colors in Xresources](#colors-in-xresources) - - [Fonts](#fonts) - - [Themes](#themes) - - [Device-specific settings](#device-specific-settings) -- [EXWM](#exwm) - - [Xsession](#xsession) - - [Startup apps](#startup-apps) - - [Moving windows](#moving-windows) - - [Resizing windows](#resizing-windows) - - [App shortcuts](#app-shortcuts) - - [Move workspace to another monitor](#move-workspace-to-another-monitor) - - [Switch to the opposite monitor](#switch-to-the-opposite-monitor) - - [Switching buffers](#switching-buffers) - - [Add all EXWM buffers to current perspective](#add-all-exwm-buffers-to-current-perspective) - - [Revive perspectives](#revive-perspectives) - - [Locking up](#locking-up) - - [Keybindings](#keybindings) - - [Pinentry](#pinentry) - - [Modeline](#modeline) - - [EXWM config](#exwm-config) -- [i3wm](#i3wm) - - [General settings](#general-settings) - - [Managing windows](#managing-windows) - - [Workspaces](#workspaces) - - [Rules](#rules) - - [Scratchpad](#scratchpad) - - [Launch script](#launch-script) - - [i3 config](#i3-config) - - [Gaps & borders](#gaps-and-borders) - - [Keybindings](#keybindings) - - [Move & resize windows](#move-and-resize-windows) - - [OFF (OFF) Intergration with dmenu](#off--intergration-with-dmenu) - - [Integration with rofi](#integration-with-rofi) - - [Launching apps & misc keybindings](#launching-apps-and-misc-keybindings) - - [Apps](#apps) - - [Media controls & brightness](#media-controls-and-brightness) - - [Screenshots](#screenshots) - - [Colors](#colors) - - [OFF (OFF) i3blocks](#off--i3blocks) - - [Keyboard Layout](#keyboard-layout) - - [Autostart](#autostart) -- [Polybar](#polybar) - - [General settings](#general-settings) - - [Colors](#colors) - - [Glyphs](#glyphs) - - [Modules](#modules) - - [Global bar config](#global-bar-config) - - [Launch script](#launch-script) - - [Individual modules](#individual-modules) - - [pulseaudio](#pulseaudio) - - [mpd](#mpd) - - [cpu](#cpu) - - [ram-memory](#ram-memory) - - [swap-memory](#swap-memory) - - [network](#network) - - [ipstack-vpn](#ipstack-vpn) - - [openvpn](#openvpn) - - [xkeyboard](#xkeyboard) - - [battery](#battery) - - [weather](#weather) - - [sun](#sun) - - [aw-afk](#aw-afk) - - [date](#date) - - [pomm](#pomm) - - [SEP](#sep) - - [TSEP](#tsep) - - [i3](#i3) -- [Rofi](#rofi) - - [Theme](#theme) - - [Scripts](#scripts) - - [Buku bookmarks](#buku-bookmarks) - - [Man pages](#man-pages) - - [Emojis](#emojis) - - [pass](#pass) -- [Flameshot](#flameshot) -- [dunst](#dunst) -- [keynav](#keynav) - - [Config](#config) - - [Using with picom](#using-with-picom) -- [Picom](#picom) - - [Shadows](#shadows) - - [Fading](#fading) - - [Opacity](#opacity) - - [General settings](#general-settings) -- [Zathura](#zathura) -- [Various software](#various-software) - - [Browsers](#browsers) - - [Office & Multimedia](#office-and-multimedia) - - [LaTeX](#latex) - - [Dev](#dev) - - [Manifests](#manifests) - - [Flatpak](#flatpak) - - [Nix](#nix) -- [Services](#services) - - [Music](#music) - - [GNU Mcron](#gnu-mcron) - - [ActivityWatch](#activitywatch) - - [PulseEffects](#pulseeffects) - - [xsettingsd](#xsettingsd) - - [nm-applet](#nm-applet) - - [Discord rich presence](#discord-rich-presence) - - [Polkit Authentication agent](#polkit-authentication-agent) - - [Xmodmap](#xmodmap) - - [VPN](#vpn) - - [Davmail](#davmail) - - [Shepherd config](#shepherd-config) - - [Sync](#sync) -- [Guix settings](#guix-settings) - -
- - - -## Global customization {#global-customization} - - -### Colors {#colors} - -Most of the colors are from the Palenight theme. Colorcodes are taken from [this repo](https://github.com/JonathanSpeek/palenight-iterm2): - - - -| color | key | value | -|---------------|---------|---------| -| black | color0 | #292d3e | -| red | color1 | #f07178 | -| green | color2 | #c3e88d | -| yellow | color3 | #ffcb6b | -| blue | color4 | #82aaff | -| magenta | color5 | #c792ea | -| cyan | color6 | #89ddff | -| white | color7 | #d0d0d0 | -| light-black | color8 | #434758 | -| light-red | color9 | #ff8b92 | -| light-green | color10 | #ddffa7 | -| light-yellow | color11 | #ffe585 | -| light-blue | color12 | #9cc4ff | -| light-magenta | color13 | #e1acff | -| light-cyan | color14 | #a3f7ff | -| light-white | color15 | #ffffff | - -The table above is the only source of truth for colors in this config. - -The first way to get colors of it is to use the following noweb: - - -```emacs-lisp -(let ((color (seq-some (lambda (e) (and (string= name (car e)) (nth 2 e))) table))) - (if (> quote 0) - (concat "\"" color "\"") - color)) -``` - -Also, run the following to disable configuration for noweb evaluations: - -```emacs-lisp -(setq-local org-confirm-babel-evaluate nil) -``` - -Test: - -```emacs-lisp -<> -``` - - -### Xresources {#xresources} - - -#### Colors in Xresources {#colors-in-xresources} - -However, I'd rather use the `Xresources` file wherever possible. Here is the code to generate an Xresources file from this table: - - -```emacs-lisp -(apply - #'concat - (mapcar - (lambda (elem) - (concat "*" (nth 1 elem) ": " (nth 2 elem) "\n")) - (seq-filter - (lambda (elem) (nth 1 elem)) - table))) -``` - -```vim -<> - -*background: <> -*foreground: <> -``` - - -#### Fonts {#fonts} - -Also, Xresources are used to set `Xft` settings. Unfortunately, the DPI setting has to be unique for each machine, which means I cannot commit `Xresources` to the repo. - - -```emacs-lisp -(let ((hostname (system-name))) - (cond ((string-equal hostname "azure") 120) - ((string-equal hostname "eminence") 120) - ((string-equal hostname "indigo") 120) - (t 96))) -``` - -```vim -Xft.dpi: <> -``` - - -### Themes {#themes} - -A few programs I use to customize the apperance are listed below. - -| Guix dependency | Description | -|-----------------------|-------------------------| -| matcha-theme | My preferred GTK theme | -| papirus-icon-theme | My preferred Icon theme | -| gnome-themes-standard | | -| xsettingsd | X11 settings daemon | -| gnome-themes-extra | | - -[xsettingsd](https://github.com/derat/xsettingsd) is a lightweight daemon which configures X11 applications. It is launched with shepherd in the [Services](#services) section. - -```vim -Net/ThemeName "Matcha-dark-azul" -Net/IconThemeName "Papirus-Dark" -Gtk/DecorationLayout "menu:minimize,maximize,close" -Gtk/FontName "Sans 10" -Gtk/MonospaceFontName "JetBrainsMono Nerd Mono 12" -Gtk/CursorThemeName "Adwaita" -Xft/Antialias 1 -Xft/Hinting 0 -Xft/HintStyle "hintnone" -``` - - -### Device-specific settings {#device-specific-settings} - -| Guix dependency | Description | -|-----------------|--------------------------------------------| -| xrandr | X11 CLI to RandR | -| xgamma | A tool to alter monitor's gamma correction | -| xinput | Configure input devices | - -Set screen layout & other params depending on hostname - -```sh -hostname=$(hostname) -if [ "$hostname" = "indigo" ]; then - xrandr --output DisplayPort-0 --off --output HDMI-A-0 --mode 1920x1080 --pos 0x0 --rotate normal --output DVI-D-0 --mode 1920x1080 --pos 1920x0 --rotate normal -elif [ "$hostname" = "eminence" ]; then - xgamma -gamma 1.25 -fi -``` - - -## EXWM {#exwm} - -Settings for [Emacs X Window Manager](https://github.com/ch11ng/exwm), a tiling WM implemented in Emacs Lisp. - -References: - -- [EXWM Wiki](https://github.com/ch11ng/exwm/wiki) -- [Emacs From Scratch config](https://github.com/daviwil/emacs-from-scratch/blob/master/Desktop.org) - - -### Xsession {#xsession} - -First things first, Emacs has to be launched as a window manager. On a more conventional system I'd create a .desktop file in some system folder that can be seen by a login manager, but in the case of Guix it's a bit more complicated, because all such folders are not meant to be changed manually. - -However, GDM, the login manager that seems to be the default on Guix, launches `~/.xsession` on the startup if it's present, which is just fine for my purposes. - -```sh -# Source .profile -. ~/.profile - -# Disable access control for the current user -xhost +SI:localuser:$USER - -# Fix for Java applications -export _JAVA_AWT_WM_NONREPARENTING=1 - -# Apply XResourses -xrdb -merge ~/.Xresources - -# Turn off the system bell -xset -b - -# Use i3lock as a screen locker -xss-lock -- i3lock & - -# Some apps that have to be launched only once. -picom & -# nm-applet & -dunst & -copyq & - -# Run the Emacs startup script as a session. -# exec dbus-launch --exit-with-session ~/.emacs.d/run-exwm.sh -exec dbus-launch --exit-with-session emacs -mm --debug-init -l ~/.emacs.d/desktop.el -``` - - -### Startup apps {#startup-apps} - -Now that Emacs is launched, it is necessary to set up the EXWM-specific parts of config. - -I want to launch some apps from EXWM instead of the Xsession file for two purposes: - -- the app may need to have the entire desktop environment set up -- or it may need to be restarted if Emacs is killed. - -As of now, these are polybar, feh and, shepherd: - -```emacs-lisp -(defun my/exwm-run-polybar () - (call-process "~/bin/polybar.sh")) - -(defun my/exwm-set-wallpaper () - (call-process-shell-command "feh --bg-fill ~/Pictures/wallpaper.jpg")) - -(defun my/exwm-run-shepherd () - (when (string-empty-p (shell-command-to-string "pgrep -u pavel shepherd")) - (call-process "shepherd"))) -``` - - -### Moving windows {#moving-windows} - -My functions for managing windows. I initially wrote these to mimic the i3 behavior for my Emacs + i3 integration, but I want to try to keep them for the EXWM config as well to make the transition less painful. - -A predicate which checks whether there is space in the given direction: - -```emacs-lisp -(defun my/exwm-direction-exists-p (dir) - (cl-some (lambda (dir) - (let ((win (windmove-find-other-window dir))) - (and win (not (window-minibuffer-p win))))) - (pcase dir - ('width '(left right)) - ('height '(up down))))) -``` - -And a function to move windows with the following behavior: - -- if there is space in the required direction, move the Emacs window there; -- if there is no space in the required direction, but space in two orthogonal directions, move the Emacs window so that there is no more space in the orthogonal directions; - - - -```emacs-lisp -(defun my/exwm-move-window (dir) - (let ((other-window (windmove-find-other-window dir)) - (other-direction (my/exwm-direction-exists-p - (pcase dir - ('up 'width) - ('down 'width) - ('left 'height) - ('right 'height))))) - (cond - ((and other-window (not (window-minibuffer-p other-window))) - (window-swap-states (selected-window) other-window)) - (other-direction - (evil-move-window dir))))) -``` - - -### Resizing windows {#resizing-windows} - -Something like this also goes for resizing windows. I'm used to the i3 "mode" for this functionality, and this seems to be a sensible approach. - -```emacs-lisp -(setq my/exwm-resize-value 5) - -(defun my/exwm-resize-window (dir kind &optional value) - (unless value - (setq value my/exwm-resize-value)) - (pcase kind - ('shrink - (pcase dir - ('width - (evil-window-decrease-width value)) - ('height - (evil-window-decrease-height value)))) - ('grow - (pcase dir - ('width - (evil-window-increase-width value)) - ('height - (evil-window-increase-height value)))))) - -(defhydra my/exwm-resize-hydra (:color pink :hint nil :foreign-keys run) - " -^Resize^ -_l_: Increase width _h_: Decrease width _j_: Increase height _k_: Decrease height - -_=_: Balance " - ("h" (lambda () (interactive) (my/exwm-resize-window 'width 'shrink))) - ("j" (lambda () (interactive) (my/exwm-resize-window 'height 'grow))) - ("k" (lambda () (interactive) (my/exwm-resize-window 'height 'shrink))) - ("l" (lambda () (interactive) (my/exwm-resize-window 'width 'grow))) - ("=" balance-windows) - ("q" nil "quit" :color blue)) -``` - - -### App shortcuts {#app-shortcuts} - -Also, a transient for shortcuts for the most frequent apps. - -I wanted to make the interactive lambda a macro, but this doesn't seem to work the way I expect, so the code has a bit of duplication. - -```emacs-lisp -(use-package transient - :straight t) - -(defun my/run-in-background (command) - (let ((command-parts (split-string command "[ ]+"))) - (apply #'call-process `(,(car command-parts) nil 0 nil ,@(cdr command-parts))))) - -(transient-define-prefix my/exwm-apps () - ["Apps" - ("t" "Termnial (Alacritty)" (lambda () (interactive) (my/run-in-background "alacritty"))) - ("b" "Browser (Firefox)" (lambda () (interactive) (my/run-in-background "firefox"))) - ("v" "VK" (lambda () (interactive) (my/run-in-background "vk"))) - ("s" "Slack" (lambda () (interactive) (my/run-in-background "slack-wrapper"))) - ("d" "Discord" (lambda () (interactive) (my/run-in-background "flatpak run com.discordapp.Discord"))) - ("q" "Quit" transient-quit-one)]) -``` - - -### Move workspace to another monitor {#move-workspace-to-another-monitor} - -A function to move the current workspace to another monitor. - -```emacs-lisp -(defun my/exwm-workspace-switch-monitor () - (interactive) - (if (plist-get exwm-randr-workspace-monitor-plist exwm-workspace-current-index) - (setq exwm-randr-workspace-monitor-plist - (map-delete exwm-randr-workspace-monitor-plist exwm-workspace-current-index)) - (setq exwm-randr-workspace-monitor-plist - (plist-put exwm-randr-workspace-monitor-plist - exwm-workspace-current-index - my/exwm-another-monitor))) - (exwm-randr-refresh)) -``` - - -### Switch to the opposite monitor {#switch-to-the-opposite-monitor} - -Store the information about which workspace is available on which monitor. - -```emacs-lisp -(setq my/exwm-monitor-workspace '()) - -(defun my/exwm-get-current-monitor () - (if (plist-get exwm-randr-workspace-monitor-plist exwm-workspace-current-index) - 1 0)) - -(defun my/exwm-update-current-monitor () - (setf (alist-get (my/exwm-get-current-monitor) my/exwm-monitor-workspace) - exwm-workspace-current-index)) - -(add-hook 'exwm-workspace-switch-hook - #'my/exwm-update-current-monitor) -``` - -Switch to the opposite monitor. For now, this works only for two monitors because I don't have more. - -```emacs-lisp -(defun my/exwm-switch-to-other-monitor () - (interactive) - (let* ((current (my/exwm-get-current-monitor)) - (other (seq-some - (lambda (m) - (and (not (= (car m) current)) (cdr m))) - my/exwm-monitor-workspace)) - (focus-follows-mouse nil) - (mouse-autoselect-window nil)) - (exwm-workspace-switch other))) -``` - - -### Switching buffers {#switching-buffers} - -A single perspective usually has only a handful of EXWM buffers, so here is a function to cycle them. - -Those buffers that are visible in another window are highlighted blue and skipped. The current buffer is highlighted yellow. - -```emacs-lisp -(defun my/cycle-persp-exwm-buffers (dir) - (let* ((current (current-buffer)) - (ignore-rx (persp--make-ignore-buffer-rx)) - (visible-buffers '()) - (exwm-data - (cl-loop for buf in (persp-current-buffers) - for is-another = (and (get-buffer-window buf) (not (eq current buf))) - if (and (buffer-live-p buf) - (eq 'exwm-mode (buffer-local-value 'major-mode buf)) - (not (string-match-p ignore-rx (buffer-name buf)))) - collect buf into all-buffers - and if (not is-another) collect buf into cycle-buffers - finally (return (list all-buffers cycle-buffers)))) - (all-buffers (nth 0 exwm-data)) - (cycle-buffers (nth 1 exwm-data)) - (current-pos (or (cl-position current cycle-buffers) -1))) - (if (seq-empty-p cycle-buffers) - (message "No EXWM buffers to cycle!") - (let* ((next-pos (% (+ current-pos (length cycle-buffers) - (if (eq dir 'forward) 1 -1)) - (length cycle-buffers))) - (next-buffer (nth next-pos cycle-buffers))) - (switch-to-buffer next-buffer) - (message - "%s" - (mapconcat - (lambda (buf) - (let ((name (string-replace "EXWM :: " "" (buffer-name buf)))) - (cond - ((eq (current-buffer) buf) - (concat - "[" - (propertize name 'face `(foreground-color . ,(doom-color 'yellow))) - "]")) - ((not (member buf cycle-buffers)) - (concat - "[" - (propertize name 'face `(foreground-color . ,(doom-color 'blue))) - "]")) - (t (format " %s " name))))) - all-buffers - " ")))))) -``` - - -### Add all EXWM buffers to current perspective {#add-all-exwm-buffers-to-current-perspective} - -```emacs-lisp -(defun my/add-exwm-buffers-to-current-perspective () - (interactive) - (let ((ignore-rx (persp--make-ignore-buffer-rx))) - (cl-loop for buf in (buffer-list) - if (and (buffer-live-p buf) - (eq 'exwm-mode (buffer-local-value 'major-mode buf)) - (not (string-match-p ignore-rx (buffer-name buf)))) - do (persp-add-buffer (buffer-name buf))))) -``` - - -### Revive perspectives {#revive-perspectives} - -Occasionally the current perspective gets screwed up after a popup. This function attempts to fix it. - -```emacs-lisp -(defun my/exwm-revive-perspectives () - "Make perspectives in the current frame not killed." - (interactive) - (let ((to-switch nil)) - (maphash - (lambda (_ v) - (setf (persp-killed v) nil) - (unless to-switch - (setq to-switch v))) - (frame-parameter nil 'persp--hash)) - (when to-switch - (persp-switch (persp-name to-switch))))) -``` - - -### Locking up {#locking-up} - -Run i3lock. - -```emacs-lisp -(defun my/exwm-lock () - (interactive) - (my/run-in-background "i3lock -f -i /home/pavel/Pictures/lock-wallpaper.png")) -``` - - -### Keybindings {#keybindings} - -Setting keybindings for EXWM. This actually has to be in the `:config` block of the `use-package` form, that is it has to be run after EXWM is loaded, so I use noweb to put this block in the correct place. - -First, some prefixes for keybindings that are always passed to EXWM instead of the X application in `line-mode`: - -```emacs-lisp -(setq exwm-input-prefix-keys - `(?\C-x - ?\C-w - ?\M-x - ?\M-u)) -``` - -Also other local keybindings, that are also available only in `line-mode`: - -```emacs-lisp -(defmacro my/app-command (command) - `(lambda () (interactive) (my/run-in-background ,command))) - -(general-define-key - :keymaps '(exwm-mode-map) - "C-q" 'exwm-input-send-next-key - "" (my/app-command "flameshot gui") - "M-x" 'counsel-M-x - "M-SPC" (general-key "SPC")) -``` - -Simulation keys. - -```emacs-lisp -(setq exwm-input-simulation-keys `((,(kbd "M-w") . ,(kbd "C-w")) - (,(kbd "M-c") . ,(kbd "C-c")))) -``` - -And keybindings that are available in both `char-mode` and `line-mode`: - -```emacs-lisp -(setq exwm-input-global-keys - `( - ;; Reset to line-mode - (,(kbd "s-R") . exwm-reset) - - ;; Switch windows - (,(kbd "s-"). windmove-left) - (,(kbd "s-") . windmove-right) - (,(kbd "s-") . windmove-up) - (,(kbd "s-") . windmove-down) - - (,(kbd "s-h"). windmove-left) - (,(kbd "s-l") . windmove-right) - (,(kbd "s-k") . windmove-up) - (,(kbd "s-j") . windmove-down) - - ;; Moving windows - (,(kbd "s-H") . (lambda () (interactive) (my/exwm-move-window 'left))) - (,(kbd "s-L") . (lambda () (interactive) (my/exwm-move-window 'right))) - (,(kbd "s-K") . (lambda () (interactive) (my/exwm-move-window 'up))) - (,(kbd "s-J") . (lambda () (interactive) (my/exwm-move-window 'down))) - - ;; Fullscreen - (,(kbd "s-f") . exwm-layout-toggle-fullscreen) - - ;; Quit - (,(kbd "s-Q") . evil-quit) - - ;; Split windows - (,(kbd "s-s") . evil-window-vsplit) - (,(kbd "s-v") . evil-window-hsplit) - - ;; Switch perspectives - (,(kbd "s-,") . persp-prev) - (,(kbd "s-.") . persp-next) - - ;; Switch buffers - (,(kbd "s-e") . persp-ivy-switch-buffer) - - ;; Resize windows - (,(kbd "s-r") . my/exwm-resize-hydra/body) - - ;; Apps & stuff - (,(kbd "s-p") . ,(my/app-command "rofi -modi drun,run -show drun")) - (,(kbd "s-;") . my/exwm-apps) - (,(kbd "s--") . ,(my/app-command "rofi-pass")) - (,(kbd "s-=") . ,(my/app-command "rofimoji")) - - ;; Basic controls - (,(kbd "") . ,(my/app-command "ponymix increase 5 --max-volume 150")) - (,(kbd "") . ,(my/app-command "ponymix decrease 5 --max-volume 150")) - (,(kbd "") . ,(my/app-command "light -A 5")) - (,(kbd "") . ,(my/app-command "light -U 5")) - (,(kbd "") . ,(my/app-command "ponymix toggle")) - - (,(kbd "") . ,(my/app-command "mpc toggle")) - (,(kbd "") . ,(my/app-command "mpc pause")) - (,(kbd "") . ,(my/app-command "flameshot gui")) - - ;; Switch workspace - (,(kbd "s-q") . my/exwm-switch-to-other-monitor) - (,(kbd "s-w") . exwm-workspace-switch) - (,(kbd "s-W") . exwm-workspace-move-window) - (,(kbd "s-") . my/exwm-workspace-switch-monitor) - - ;; Cycle EXWM windows in the current perspective - (,(kbd "s-[") . (lambda () (interactive) (my/cycle-persp-exwm-buffers 'backward))) - (,(kbd "s-]") . (lambda () (interactive) (my/cycle-persp-exwm-buffers 'forward))) - (,(kbd "s-o") . ,(my/app-command "rofi -show window")) - - ;; 's-N': Switch to certain workspace with Super (Win) plus a number key (0 - 9) - ,@(mapcar (lambda (i) - `(,(kbd (format "s-%d" i)) . - (lambda () - (interactive) - (exwm-workspace-switch-create ,i)))) - (number-sequence 0 9)))) -``` - - -### Pinentry {#pinentry} - -The GUI pinentry doesn't work too well with EXWM because of issues with popup windows, so we will use the Emacs one. - -```emacs-lisp -(use-package pinentry - :straight t - :after (exwm) - :config - (setenv "GPG_AGENT_INFO" nil) ;; use emacs pinentry - (setq auth-source-debug t) - - (setq epg-gpg-program "gpg2") ;; not necessary - (require 'epa-file) - (epa-file-enable) - (setq epa-pinentry-mode 'loopback) - (setq epg-pinentry-mode 'loopback) - (pinentry-start) - (my/run-in-background "gpgconf --reload gpg-agent")) -``` - -```vim -default-cache-ttl 3600 -max-cache-ttl 3600 -allow-emacs-pinentry -allow-loopback-pinentry -``` - - -### Modeline {#modeline} - -Show current workspace in the modeline. - -```emacs-lisp -(defvar my/exwm-mode-line-info "") - -(add-to-list 'mode-line-misc-info - '(:eval my/exwm-mode-line-info)) - -(defun my/exwm-mode-line-info-update () - (setq my/exwm-mode-line-info - (concat - "[" - (propertize (funcall exwm-workspace-index-map exwm-workspace-current-index) - 'face - `(foreground-color . ,(doom-color 'yellow))) - "]")) - (setq my/exwm-mode-line-info-no-props (funcall exwm-workspace-index-map exwm-workspace-current-index)) - (force-mode-line-update)) - -(add-hook 'exwm-workspace-switch-hook #'my/exwm-mode-line-info-update) -``` - - -### EXWM config {#exwm-config} - -And the EXWM config itself. - -```emacs-lisp -(defun my/exwm-init () - (exwm-workspace-switch 1) - - (my/exwm-run-polybar) - (my/exwm-set-wallpaper) - (my/exwm-run-shepherd) - ;; (with-eval-after-load 'perspective - ;; (my/exwm-setup-perspectives)) - ) - -(defun my/exwm-update-class () - (exwm-workspace-rename-buffer (format "EXWM :: %s" exwm-class-name))) - -(use-package exwm - :straight t - :config - (setq exwm-workspace-number 5) - (add-hook 'exwm-init-hook #'my/exwm-init) - (add-hook 'exwm-update-class-hook #'my/exwm-update-class) - - (require 'exwm-randr) - (exwm-randr-enable) - (start-process-shell-command "xrandr" nil "~/bin/scripts/screen-layout") - (when (string= (system-name) "indigo") - (setq my/exwm-another-monitor "DVI-D-0") - (setq exwm-randr-workspace-monitor-plist `(2 ,my/exwm-another-monitor 3 ,my/exwm-another-monitor))) - - (setq exwm-workspace-warp-cursor t) - (setq mouse-autoselect-window t) - (setq focus-follows-mouse t) - - <> - <> - <> - - (set-frame-parameter (selected-frame) 'alpha '(90 . 90)) - (add-to-list 'default-frame-alist '(alpha . (90 . 90))) - - (exwm-enable)) -``` - - -## i3wm {#i3wm} - -| Guix dependency | Disabled | -|-----------------|----------| -| i3-gaps | | -| i3lock | true | - -`i3lock` is disabled because the global one has to be used. - -[i3wm](https://i3wm.org/) is a manual tiling window manager, which is currently my window manager of choice. I've tried several alternatives, including [xmonad](https://xmonad.org/) & [EXWM](https://github.com/ch11ng/exwm), but i3 seems to fit my workflow best. - -[i3-gaps](https://github.com/Airblader/i3) is an i3 fork with a few features like window gaps. I like to enable inner gaps when there is at least one container in a workspace. - -References: - -- [i3wm docs](https://i3wm.org/docs/) -- [i3-gaps wiki](https://github.com/Airblader/i3/wiki) - - -### General settings {#general-settings} - -```vim -set $mod Mod4 -font pango:monospace 10 - -# Use Mouse+$mod to drag floating windows to their wanted position -floating_modifier $mod - -# Move cursor between monitors -mouse_warping output - -# Apply XFCE Settings -# exec xfsettingsd -# exec xiccd - -# Set screen layout -exec ~/bin/scripts/screen-layout - -# Most needed keybindigs -# reload the configuration file -bindsym $mod+Shift+c reload - -# restart i3 inplace (preserves your layout/session, can be used to upgrade i3) -bindsym $mod+Shift+r restart - -# exit i3 (logs you out of your X session) -bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'" -``` - - -### Managing windows {#managing-windows} - -| Guix dependency | -|---------------------| -| rust-i3-switch-tabs | - -Some keybindings for managing windows. - -`emacs-i3-integration` is a script to pass some command to Emacs to get a consistent set of keybindings in both i3 and Emacs. Check out [the section in Emacs.org]({{< relref "Emacs" >}}) for details. - -Kill focused windows - -```vim -bindsym $mod+Shift+q exec emacs-i3-integration kill -``` - -Change focus - -```vim -bindsym $mod+h exec emacs-i3-integration focus left -bindsym $mod+j exec emacs-i3-integration focus down -bindsym $mod+k exec emacs-i3-integration focus up -bindsym $mod+l exec emacs-i3-integration focus right - -bindsym $mod+Left exec emacs-i3-integration focus left -bindsym $mod+Down exec emacs-i3-integration focus down -bindsym $mod+Up exec emacs-i3-integration focus up -bindsym $mod+Right exec emacs-i3-integration focus right -``` - -Move windows around - -```vim -bindsym $mod+Shift+h exec emacs-i3-integration move left -bindsym $mod+Shift+j exec emacs-i3-integration move down -bindsym $mod+Shift+k exec emacs-i3-integration move up -bindsym $mod+Shift+l exec emacs-i3-integration move right - -bindsym $mod+Shift+Left exec emacs-i3-integration move left -bindsym $mod+Shift+Down exec emacs-i3-integration move down -bindsym $mod+Shift+Up exec emacs-i3-integration move up -bindsym $mod+Shift+Right exec emacs-i3-integration move right -``` - -Split windows - -```vim -bindsym $mod+s exec emacs-i3-integration split h -bindsym $mod+v exec emacs-i3-integration split v -``` - -Switch tabs - -```vim -bindsym $mod+period exec i3-switch-tabs right -bindsym $mod+comma exec i3-switch-tabs left -``` - -Enter fullscreen mode - -```vim -# enter fullscreen mode for the focused container -bindsym $mod+f fullscreen toggle -bindsym $mod+c fullscreen toggle global -``` - -Changing layout - -```vim -bindsym $mod+w layout stacking -bindsym $mod+t layout tabbed -bindsym $mod+e exec emacs-i3-integration layout toggle split -``` - -Toggle tiling/floating, switch between tiled and floating windows - -```vim -bindsym $mod+Shift+f floating toggle -bindsym $mod+z focus mode_toggle -``` - -Switching outputs - -```vim -bindsym $mod+Tab move workspace to output right -bindsym $mod+q focus output right -``` - -Focus parent and child container - -```vim -bindsym $mod+a focus parent -bindsym $mod+Shift+A focus child -``` - -Toggle sticky - -```vim -bindsym $mod+i sticky toggle -``` - -Set windows as floating and sticky, move to the top right. - -```vim -bindsym $mod+x floating enable; sticky enable; move position 1220 0; resize set width 700 px -``` - - -### Workspaces {#workspaces} - -```vim -set $w1 "1 🚀" -set $w2 "2 🌍" -set $w3 "3 💬" -set $w4 "4 🛠️️" -set $w7 "7 🛰️" -set $w8 "8 📝" -set $w9 "9 🎵" -set $w10 "10 📦" - -bindsym $mod+1 workspace $w1 -bindsym $mod+2 workspace $w2 -bindsym $mod+3 workspace $w3 -bindsym $mod+4 workspace $w4 -bindsym $mod+5 workspace 5 -bindsym $mod+6 workspace 6 -bindsym $mod+7 workspace $w7 -bindsym $mod+8 workspace $w8 -bindsym $mod+9 workspace $w9 -bindsym $mod+0 workspace $w10 - -# move focused container to workspace -bindsym $mod+Shift+1 move container to workspace $w1 -bindsym $mod+Shift+2 move container to workspace $w2 -bindsym $mod+Shift+3 move container to workspace $w3 -bindsym $mod+Shift+4 move container to workspace $w4 -bindsym $mod+Shift+5 move container to workspace 5 -bindsym $mod+Shift+6 move container to workspace 6 -bindsym $mod+Shift+7 move container to workspace $w7 -bindsym $mod+Shift+8 move container to workspace $w8 -bindsym $mod+Shift+9 move container to workspace $w9 -bindsym $mod+Shift+0 move container to workspace $w10 -``` - - -### Rules {#rules} - -Rules to automatically assign applications to workspaces and do other stuff, like enable floating. - -Most apps can be distinguished by a WM class (you can get one with [xprop](https://www.x.org/releases/X11R7.5/doc/man/man1/xprop.1.html)), but in some cases it doesn't work, e.g. for terminal applications. In that case rules can be based on a window title, for instance. - -However, watch out for the following: rule such as `for_window [title="ncmpcpp.*"] move to workspace $w9` will move **any** window with a title starting with `ncmpcpp` to workspace `$w9`. For instance, it moves your browser when you google "ncmpcpp". - -```vim -assign [class="Emacs"] $w1 -assign [class="qutebrowser"] $w2 -assign [class="firefox"] $w2 -assign [class="VK"] $w3 -assign [class="Slack"] $w3 -assign [class="discord"] $w3 -assign [class="TelegramDesktop"] $w3 -assign [class="Postman"] $w4 -assign [class="Chromium-browse"] $w4 -assign [class="chromium"] $w4 -assign [class="google-chrome"] $w4 -assign [title="Vue Developer Tools"] $w4 -assign [class="Google Play Music Desktop Player"] $w9 -assign [class="jetbrains-datagrip"] $w4 -assign [class="zoom"] $w7 -assign [class="skype"] $w7 -assign [class="Mailspring"] $w8 -assign [class="Thunderbird"] $w8 -assign [class="Joplin"] $w8 -assign [class="keepassxc"] $w10 - -for_window [title="VirtScreen"] floating enable - -for_window [title="ncmpcpp.*"] move to workspace $w9 -for_window [title="newsboat.*"] move to workspace $w9 -for_window [title=".*run_wego"] move to workspace $w9 -for_window [class="cinnamon-settings*"] floating enable -for_window [title="Picture-in-Picture"] sticky enable -for_window [window_role="GtkFileChooserDialog"] resize set width 1000 px height 800 px -for_window [window_role="GtkFileChooserDialog"] move position center -``` - - -### Scratchpad {#scratchpad} - -Scratch terminal, inspired by [this Luke Smith's video](https://www.youtube.com/watch?v=q-l7DnDbiiU). - - -#### Launch script {#launch-script} - -First of all, we have to distinguish a scratchpad terminal from a normal one. To do that, one can create st with a required classname. - -Then, it would be cool not to duplicate scratchpads, so the following script first looks for a window with a created classname. If it exists, the script just toggles the scratchpad visibility. Otherwise, a new instance of a window is created. - -```bash -CLASSNAME="dropdown_tmux" -COMMAND="alacritty --class $CLASSNAME -e tmux new-session -s $CLASSNAME" -pid=$(xdotool search --classname "dropdown_tmux") -if [[ ! -z $pid ]]; then - i3-msg scratchpad show -else - setsid -f ${COMMAND} -fi -``` - - -#### i3 config {#i3-config} - -```vim -# Scratchpad -for_window [instance="dropdown_*"] floating enable -for_window [instance="dropdown_*"] move scratchpad -for_window [instance="dropdown_*"] sticky enable -for_window [instance="dropdown_*"] scratchpad show -for_window [instance="dropdown_*"] move position center - -bindsym $mod+u exec ~/bin/scripts/dropdown -``` - - -### Gaps & borders {#gaps-and-borders} - -The main reason to use i3-gaps - -```vim -# Borders -# for_window [class=".*"] border pixel 0 -default_border pixel 3 -hide_edge_borders both - -# Gaps -set $default_inner 10 -set $default_outer 0 - -gaps inner $default_inner -gaps outer $default_outer - -smart_gaps on -``` - - -#### Keybindings {#keybindings} - -```vim -mode "inner gaps" { - bindsym plus gaps inner current plus 5 - bindsym minus gaps inner current minus 5 - bindsym Shift+plus gaps inner all plus 5 - bindsym Shift+minus gaps inner all minus 5 - bindsym 0 gaps inner current set 0 - bindsym Shift+0 gaps inner all set 0 - - bindsym r gaps inner current set $default_inner - bindsym Shift+r gaps inner all set $default_inner - - bindsym Return mode "default" - bindsym Escape mode "default" -} - -mode "outer gaps" { - bindsym plus gaps outer current plus 5 - bindsym minus gaps outer current minus 5 - bindsym Shift+plus gaps outer all plus 5 - bindsym Shift+minus gaps outer all minus 5 - bindsym 0 gaps outer current set 0 - bindsym Shift+0 gaps outer all set 0 - - bindsym r gaps outer current set $default_outer - bindsym Shift+r gaps outer all set $default_outer - - bindsym Return mode "default" - bindsym Escape mode "default" -} - -bindsym $mod+g mode "inner gaps" -bindsym $mod+Shift+g mode "outer gaps" -``` - - -### Move & resize windows {#move-and-resize-windows} - -| Guix dependency | -|-----------------------------| -| python-i3-balance-workspace | - -A more or less standard set of keybindings to move & resize floating windows. Just be careful to always make a way to return from these new modes, otherwise you'd end up in a rather precarious situation. - -[i3-balance-workspace](https://github.com/atreyasha/i3-balance-workspace) is a small Python package to balance the i3 windows, but for the Emacs integration I also want this button to balance the Emacs windows, so here is a small script to do just that. - -```bash -if [[ $(xdotool getactivewindow getwindowname) =~ ^emacs(:.*)?@.* ]]; then - emacsclient -e "(balance-windows)" & -fi -i3_balance_workspace -``` - -```vim -mode "resize" { - - bindsym h exec emacs-i3-integration resize shrink width 10 px or 10 ppt - bindsym j exec emacs-i3-integration resize grow height 10 px or 10 ppt - bindsym k exec emacs-i3-integration resize shrink height 10 px or 10 ppt - bindsym l exec emacs-i3-integration resize grow width 10 px or 10 ppt - - bindsym Shift+h exec emacs-i3-integration resize shrink width 100 px or 100 ppt - bindsym Shift+j exec emacs-i3-integration resize grow height 100 px or 100 ppt - bindsym Shift+k exec emacs-i3-integration resize shrink height 100 px or 100 ppt - bindsym Shift+l exec emacs-i3-integration resize grow width 100 px or 100 ppt - - # same bindings, but for the arrow keys - bindsym Left exec emacs-i3-integration resize shrink width 10 px or 10 ppt - bindsym Down exec emacs-i3-integration resize grow height 10 px or 10 ppt - bindsym Up exec emacs-i3-integration resize shrink height 10 px or 10 ppt - bindsym Right exec emacs-i3-integration resize grow width 10 px or 10 ppt - - bindsym Shift+Left exec emacs-i3-integration resize shrink width 100 px or 100 ppt - bindsym Shift+Down exec emacs-i3-integration resize grow height 100 px or 100 ppt - bindsym Shift+Up exec emacs-i3-integration resize shrink height 100 px or 100 ppt - bindsym Shift+Right exec emacs-i3-integration resize grow width 100 px or 100 ppt - - bindsym equal exec i3-emacs-balance-windows - - # back to normal: Enter or Escape - bindsym Return mode "default" - bindsym Escape mode "default" -} - -bindsym $mod+r mode "resize" - -mode "move" { - bindsym $mod+Tab focus right - - bindsym Left move left - bindsym Down move down - bindsym Up move up - bindsym Right move right - - bindsym h move left - bindsym j move down - bindsym k move up - bindsym l move right - - # back to normal: Enter or Escape - bindsym Return mode "default" - bindsym Escape mode "default" -} - -bindsym $mod+m mode "move" focus floating -``` - - -### OFF (OFF) Intergration with dmenu {#off--intergration-with-dmenu} - -[dmenu](https://tools.suckless.org/dmenu/) is a dynamic menu program for X. I've opted out of using it in favour of rofi, but here is a relevant bit of config. - -Scripts are located in the `bin/scripts` folder. - -```vim -# dmenu -bindsym $mod+d exec i3-dmenu-desktop --dmenu="dmenu -l 10" -bindsym $mod+apostrophe mode "dmenu" - -mode "dmenu" { - bindsym d exec i3-dmenu-desktop --dmenu="dmenu -l 10"; mode default - bindsym p exec dmenu_run -l 10; mode default - bindsym m exec dmenu-man; mode default - bindsym b exec dmenu-buku; mode default - bindsym f exec dmenu-explore; mode default - bindsym t exec dmenu-tmuxp; mode default - bindsym Escape mode "default" -} - -bindsym $mod+b exec --no-startup-id dmenu-buku -``` - - -### Integration with rofi {#integration-with-rofi} - -Keybindings to launch [rofi](https://github.com/davatorium/rofi). For more detail, look the [Rofi](#rofi) section. - -```vim -bindsym $mod+d exec "rofi -modi 'drun,run' -show drun" -bindsym $mod+b exec --no-startup-id rofi-buku-mine -bindsym $mod+minus exec rofi-pass -bindsym $mod+equal exec rofimoji - -bindsym $mod+apostrophe mode "rofi" - -mode "rofi" { - bindsym d exec "rofi -modi 'drun,run' -show drun" - bindsym m exec rofi-man; mode default - bindsym b exec rofi-buku-mine; mode default - bindsym k exec rofi-pass; mode default - bindsym Escape mode "default" -} -``` - - -### Launching apps & misc keybindings {#launching-apps-and-misc-keybindings} - -I prefer to use a separate mode to launch most of my apps, with some exceptions. - - -#### Apps {#apps} - -```vim -# Launch apps -# start a terminal at workspace 1 -bindsym $mod+Return exec "i3-msg 'workspace 1 🚀; exec alacritty'" - -bindsym $mod+p exec "copyq menu" -bindsym $mod+Shift+x exec "i3lock -f -i /home/pavel/Pictures/lock-wallpaper.png" - -bindsym $mod+semicolon mode "apps" - -mode "apps" { - bindsym Escape mode "default" - bindsym b exec firefox; mode default - bindsym v exec vk; mode default - bindsym s exec slack-wrapper; mode default; - bindsym d exec "flatpak run com.discordapp.Discord"; mode default; - bindsym m exec "alacritty -e ncmpcpp"; mode default - bindsym c exec "copyq toggle"; mode default - bindsym k exec "keepassxc"; mode default - # bindsym e exec mailspring; mode default - bindsym a exec emacs; mode default - bindsym n exec "alacritty -e newsboat"; mode default - bindsym w exec "alacritty /home/pavel/bin/scripts/run_wego"; mode default - # bindsym a exec emacsclient -c; mode default - # bindsym Shift+a exec emacs; mode default -} -``` - - -#### Media controls & brightness {#media-controls-and-brightness} - -```vim -# Pulse Audio controls -bindsym XF86AudioRaiseVolume exec --no-startup-id "ponymix increase 5 --max-volume 150" -bindsym XF86AudioLowerVolume exec --no-startup-id "ponymix decrease 5 --max-volume 150" -bindsym XF86AudioMute exec --no-startup-id "ponymix toggle" - -exec --no-startup-id xmodmap -e 'keycode 135 = Super_R' && xset -r 135 -bindsym $mod+F2 exec --no-startup-id "ponymix increase 5" -bindsym $mod+F3 exec --no-startup-id "ponymix decrease 5" - -# Media player controls -bindsym XF86AudioPlay exec mpc toggle -bindsym XF86AudioPause exec mpc pause -bindsym XF86AudioNext exec mpc next -bindsym XF86AudioPrev exec mpc prev - -# Screen brightness -bindsym XF86MonBrightnessUp exec light -A 5 -bindsym XF86MonBrightnessDown exec light -U 5 -``` - - -#### Screenshots {#screenshots} - -```vim -# Screenshots -bindsym --release Print exec "flameshot gui" -bindsym --release Shift+Print exec "xfce4-screenshooter" -``` - - -### Colors {#colors} - -Application of the XResources theme to the WM. - -```vim -exec xrdb -merge $HOME/.Xresources - -# Colors -set_from_resource $bg-color background -set_from_resource $active-color color4 -set_from_resource $inactive-bg-color color8 -set_from_resource $text-color foreground -set_from_resource $inactive-text-color color7 -set_from_resource $urgent-bg-color color1 -set_from_resource $urgent-text-color color0 - -# window colors -# border background text indicator child border -client.focused $active-color $bg-color $text-color $bg-color $active-color -client.unfocused $bg-color $inactive-bg-color $inactive-text-color $bg-color $bg-color -client.focused_inactive $active-color $inactive-bg-color $inactive-text-color $bg-color $bg-color -client.urgent $urgent-bg-color $urgent-bg-color $urgent-text-color $bg-color $urgent-bg-color -``` - - -### OFF (OFF) i3blocks {#off--i3blocks} - -I've opted out of i3bar & [i3blocks](https://github.com/vivien/i3blocks) for [polybar](https://github.com/polybar/polybar) - -```vim -bar { - status_command i3blocks -c ~/.config/i3/i3blocks.conf - i3bar_command i3bar - font pango:monospace 12 - output HDMI-A-0 - tray_output none - colors { - background $bg-color - separator #757575 - # border background text - focused_workspace $bg-color $bg-color $text-color - inactive_workspace $inactive-bg-color $inactive-bg-color $inactive-text-color - urgent_workspace $urgent-bg-color $urgent-bg-color $urgent-text-color - } -} - -bar { - status_command i3blocks -c ~/.config/i3/i3blocks.conf - i3bar_command i3bar - font pango:monospace 10 - output DVI-D-0 - colors { - background $bg-color - separator #757575 - # border background text - focused_workspace $bg-color $bg-color $text-color - inactive_workspace $inactive-bg-color $inactive-bg-color $inactive-text-color - urgent_workspace $urgent-bg-color $urgent-bg-color $urgent-text-color - } -} -``` - - -### Keyboard Layout {#keyboard-layout} - -A script to set Russian-English keyboard layout: - -```bash -setxkbmap -layout us,ru -setxkbmap -model pc105 -option 'grp:win_space_toggle' -option 'grp:alt_shift_toggle' -``` - -A script to toggle the layout - -```bash -if setxkbmap -query | grep -q us,ru; then - setxkbmap -layout us - setxkbmap -option -else - setxkbmap -layout us,ru - setxkbmap -model pc105 -option 'grp:win_space_toggle' -option 'grp:alt_shift_toggle' -fi -``` - -And the relevant i3 settings: - -```vim -# Layout -exec_always --no-startup-id set_layout -bindsym $mod+slash exec toggle_layout -``` - - -### Autostart {#autostart} - -```vim -# Polybar -exec_always --no-startup-id "bash /home/pavel/bin/polybar.sh" - -# Wallpaper -exec_always "feh --bg-fill ~/Pictures/wallpaper.jpg" - -# Picom -exec picom - -# Keynav -exec keynav - -# Applets -exec --no-startup-id nm-applet -# exec --no-startup-id /usr/bin/blueman-applet - -exec shepherd -exec dunst -exec copyq -exec "xmodmap ~/.Xmodmap" -# exec "xrdb -merge ~/.Xresources" -# exec "bash ~/bin/autostart.sh" -``` - - -## Polybar {#polybar} - -| Category | Guix dependency | Description | -|-----------------|-----------------|-------------| -| desktop-polybar | polybar | statusbar | - -[Polybar](https://github.com/polybar/polybar) is a nice-looking, WM-agnostic statusbar program. - -I switched to polybar because I wanted to try out some WMs other than i3, but decided to stick with i3 for now. - -Don't forget to install the Google Noto Color Emoji font. Guix package with all Noto fonts is way too large. - -References: - -- [polybar docs](https://github.com/polybar/polybar/wiki) - - -### General settings {#general-settings} - - -#### Colors {#colors} - -First, let's use xrdb colors in polybar. To avoid code duplication, I generate them via noweb. - - -```emacs-lisp -(mapconcat - (lambda (elem) - (format "%s = ${xrdb:%s}" (nth 0 elem) (nth 1 elem))) - (seq-filter - (lambda (elem) (nth 1 elem)) - table) - "\n") -``` - -```ini -[colors] -<> - -background = ${xrdb:background} -; foreground = ${xrdb:foreground} -``` - - -#### Glyphs {#glyphs} - -Also, let's try to use some glyphs. The [polybar-themes](https://github.com/adi1090x/polybar-themes) repository can give some inspiration on what is possible, here I am replicating a powerline-ish look. - -Although polybar makes it a bit more awkward than it could've been. The approach is to put a glyph between two blocks like this: - -```text -block1  block2 -``` - -And set the colors like that: - -| | block1 | glyph | block 2 | -|------------|--------|-------|---------| -| foreground | F1 | B2 | F2 | -| background | B1 | B1 | B2 | - -So, let's define the glyph symbols: - -```ini -[glyph] -gleft =  -gright =  -``` - - -#### Modules {#modules} - -To make life a bit easier, I'll define a single source of truth for modules and their colors here. - -So, here is a table with all modules. - - - -| Index | Module | Color | Glyph | -|-------|-------------|---------------|-------| -| 1 | pulseaudio | light-magenta | + | -| 2 | mpd | magenta | + | -| 3 | cpu | cyan | + | -| 4 | ram-memory | light-green | + | -| 5 | swap-memory | green | + | -| 6 | network | light-red | + | -| 7 | openvpn | light-red | | -| 8 | xkeyboard | red | + | -| 9 | battery | green | + | -| 10 | weather | light-yellow | + | -| 12 | sun | yellow | + | -| 13 | aw-afk | light-blue | + | -| 14 | date | blue | + | - -Some functions to use colors in the individual modules: - - -```emacs-lisp -(format - "${colors.%s}" - (nth - 2 - (seq-find - (lambda (el) (string-equal (nth 1 el) module)) - table))) -``` - - -```emacs-lisp -"${colors.black}" -``` - -Also, I want to exclude some modules from certain monitors and machines. For now this concerns just the battery module, so I exclude it from the monitors of my desktop PC. In future I may need to rework this to include hostname, but as long as all my machines have separate monitor names, it works fine. - - - -| Monitor | Exclude | -|----------|---------| -| DVI-D-0 | battery | -| HDMI-A-0 | battery | - -Now, we need to generate a set of glyphs. The code below generates all the required glyhps so that every combination of neighoring colors in the bar had one. - - - -| Color 1 | Color 2 | -|------------|---------------| -| background | white | -| background | light-magenta | -| blue | background | - - -```emacs-lisp -(let* ((monitors - (thread-last - exclude-table - (seq-map (lambda (el) (nth 0 el))) - (seq-uniq))) - (exclude-combinations - (seq-map - (lambda (monitor) - (seq-map - (lambda (el) (nth 1 el)) - (seq-filter - (lambda (el) (and (string-equal (nth 0 el) monitor) - (nth 1 el))) - exclude-table))) - `(,@monitors ""))) - (module-glyph-combinations - (thread-last - exclude-combinations - (seq-map - (lambda (exclude) - (thread-last - table - (seq-filter - (lambda (elt) - (not (or - (member (nth 1 elt) exclude) - (not (string-equal (nth 3 elt) "+")))))) - ;; (seq-map (lambda (elt) (nth 1 elt))) - ))) - (seq-uniq))) - (color-changes nil)) - (dolist (e extra) - (add-to-list - 'color-changes - (concat (nth 0 e) "--" (nth 1 e)))) - (dolist (comb module-glyph-combinations) - (dotimes (i (1- (length comb))) - (add-to-list - 'color-changes - (concat (nth 2 (nth i comb)) - "--" - (nth 2 (nth (1+ i) comb)))))) - (mapconcat - (lambda (el) - (let ((colors (split-string el "--"))) - (format " -[module/glyph-%s--%s] -type = custom/text -content-background = ${colors.%s} -content-foreground = ${colors.%s} -content = ${glyph.gright} -content-font = 5" - (nth 0 colors) - (nth 1 colors) - (nth 0 colors) - (nth 1 colors)))) - color-changes - "\n")) -``` - -```ini -<> -``` - -And a set of modules interweaved with corresponding glyphs for each monitor: - - -```emacs-lisp -(let* ((exclude-modules - (thread-last - exclude-table - (seq-filter (lambda (el) (string-equal (nth 0 el) monitor))) - (seq-map (lambda (el) (nth 1 el))))) - (modules - (thread-last - table - (seq-filter (lambda (el) (not (member (nth 1 el) exclude-modules)))))) - (prev-color first-color) - (ret nil)) - (concat - (mapconcat - (lambda (el) - (apply - #'concat - (list - (when (string-equal (nth 3 el) "+") - (setq ret (format "glyph-%s--%s " prev-color (nth 2 el))) - (setq prev-color (nth 2 el)) - ret) - (nth 1 el)))) - modules - " ") - (unless (string-empty-p last-color) (format " glyph-%s--%s " prev-color last-color)))) -``` - - -#### Global bar config {#global-bar-config} - -Global bar configuration. - -Monitor config and base colors. - -```ini -[bar/mybar] -monitor = ${env:MONITOR:} -width = 100% -height = ${env:HEIGHT:27} -fixed-center = false -bottom=true - -background = ${colors.background} -foreground = ${colors.black} -``` - -Some geometry settings. These are set this way to make glyphs look the way they should - -```ini -; line-size = 3 -line-color = #f00 - -padding = 0 - -module-margin-left = 0 -module-margin-right = 0 -margin-bottom = 0 -margin-top = 0 - -; underline-size = 0 -border-size = 0 - -offset-x = 0 -offset-y = 0 -radius = 0.0 -``` - -Fonts - -```ini -; font-0 = ${env:FONT0:pango:monospace:size=10;1} -; font-1 = ${env:FONT1:NotoEmoji:scale=10:antialias=false;0} -; font-2 = ${env:FONT2:fontawesome:pixelsize=10;1} -; font-3 = ${env:FONT3:JetBrains Mono Nerd Font:monospace:size=10;1} - -font-0 = pango:monospace:size=13;2 -font-1 = NotoEmoji:scale=10:antialias=false;1 -font-2 = fontawesome:pixelsize=13;3 -font-3 = JetBrains Mono Nerd Font:monospace:size=13;4 -font-4 = JetBrains Mono Nerd Font:monospace:size=17;4 -``` - -Modules. Because I sometimes set up different blocks on different monitors, they are set via environment variables. - -```ini -; modules-left = i3 -; modules-center = test -modules-right = ${env:RIGHT_BLOCKS} - -tray-position = ${env:TRAY:right} -tray-padding = 0 -tray-maxsize = 16 -tray-background = ${colors.background} - -wm-restack = i3 -; override-redirect = true - -scroll-up = i3wm-wsnext -scroll-down = i3wm-wsprev - -; cursor-click = pointer -; cursor-scroll = ns-resize -``` - -Misc settings. - -```ini -[settings] -screenchange-reload = true -compositing-background = source -compositing-foreground = over -compositing-overline = over -compositing-underline = over -compositing-border = over - -[global/wm] -margin-top = 0 -margin-bottom = 0 -``` - - -#### Launch script {#launch-script} - -The script below allows me to: - -- have different blocks on my two different-sized monitors and my laptop; -- have different settings on my desktop PC and laptop; - - - -```bash -hostname=$(hostname) -# Settings varying on the hostname -export WLAN_INTERFACE=$(nmcli -f DEVICE con show | grep -Ev "(.*docker.*|DEVICE|br.*|tun.*|veth.*|--)" | xargs) -if [ "$hostname" = "azure" ]; then - TRAY_MONITOR="eDP-1" - # export WLAN_INTERFACE="wlp3s0" -elif [ "$hostname" = "eminence" ]; then - TRAY_MONITOR="eDP" - # export WLAN_INTERFACE="wlo1" -else - TRAY_MONITOR="HDMI-A-0" - # export WLAN_INTERFACE="wlp35s0f3u2" -fi - -# Setting varying on the monitor -declare -A FONT_SIZES=( - ["eDP"]="13" - ["eDP-1"]="13" - ["DVI-D-0"]="13" - ["HDMI-A-0"]="13" -) -declare -A EMOJI_SCALE=( - ["eDP"]="9" - ["eDP-1"]="9" - ["DVI-D-0"]="10" - ["HDMI-A-0"]="10" -) -declare -A BAR_HEIGHT=( - ["eDP"]="29" - ["eDP-1"]="29" - ["DVI-D-0"]="29" - ["HDMI-A-0"]="29" -) -declare -A BLOCKS=( - ["eDP"]="<>" - ["eDP-1"]="<>" - ["DVI-D-0"]="<>" - ["HDMI-A-0"]="<>" -) - -# Geolocation for some modules -export LOC="SPB" - -# export IPSTACK_API_KEY=$(pass show My_Online/APIs/ipstack | head -n 1) - -pkill polybar -for m in $(xrandr --query | grep " connected" | cut -d" " -f1); do - export MONITOR=$m - if [ "$MONITOR" = "$TRAY_MONITOR" ]; then - export TRAY="right" - else - export TRAY="none" - fi - SIZE=${FONT_SIZES[$MONITOR]} - SCALE=${EMOJI_SCALE[$MONITOR]} - if [[ -z "$SCALE" ]]; then - continue - fi - # export FONT0="pango:monospace:size=$SIZE;1" - # export FONT1="NotoEmoji:scale=$SCALE:antialias=false;1" - # export FONT2="fontawesome:pixelsize=$SIZE;1" - # export FONT3="JetBrains Mono Nerd Font:monospace:size=15;1" - export HEIGHT=${BAR_HEIGHT[$MONITOR]} - export RIGHT_BLOCKS=${BLOCKS[$MONITOR]} - polybar mybar & -done -``` - - -### Individual modules {#individual-modules} - -Some of the custom modules below use Org mode noweb to evaluate colors, because it's faster than querying `xrdb` at runtime. I wish I could reference polybar values there, but [it looks like this is impossible](https://github.com/polybar/polybar/issues/615). - -If you want to copy something, you can go to the [bin/polybar](bin/polybar/) folder. - - -#### pulseaudio {#pulseaudio} - -PulseAudio status - -```ini -[module/pulseaudio] -type = internal/pulseaudio -use-ui-max = true - -bar-volume-width = 7 -; bar-volume-foreground-0 = ${colors.white} -; bar-volume-foreground-1 = ${colors.yellow} -; bar-volume-foreground-2 = ${colors.yellow} -; bar-volume-foreground-3 = ${colors.blue} -; bar-volume-foreground-4 = ${colors.blue} -; bar-volume-foreground-5 = ${colors.green} -; bar-volume-foreground-6 = ${colors.green} -bar-volume-gradient = false -bar-volume-indicator = | -bar-volume-indicator-font = 2 -bar-volume-fill = ─ -bar-volume-fill-font = 2 -bar-volume-empty = ─ -bar-volume-empty-font = 2 -; bar-volume-empty-foreground = ${colors.light-white} - -format-volume = ♪ -label-volume = %percentage%% - -ramp-volume-0 = ▁ -ramp-volume-1 = ▂ -ramp-volume-2 = ▃ -ramp-volume-3 = ▄ -ramp-volume-4 = ▅ -ramp-volume-5 = ▆ -ramp-volume-6 = ▇ -ramp-volume-7 = █ - -format-muted = ♪ -label-muted = MUTE - -format-volume-background = <> -format-muted-background = <> - -; format-volume-underline = ${colors.white} -; format-muted-underline = ${colors.light-black} -``` - - -#### mpd {#mpd} - -[Music Player Daemon](https://www.musicpd.org/) status - -```ini -[module/mpd] -type = internal/mpd - -format-playing = -format-paused = -format-stopped = " " -label-song = [%album-artist%] %title% -label-time = %elapsed%/%total% - -label-song-maxlen = 30 -label-song-ellipsis = true - -; format-playing-underline = ${colors.yellow} -; format-paused-underline = ${colors.yellow} -; format-stopped-underline = ${colors.yellow} - -format-playing-background = <> -format-paused-background = <> -format-stopped-background = <> - -label-separator = 0 -separator-foreground = ${colors.red} - -icon-pause =  -icon-play =  -icon-stop =  -icon-prev = 1 -icon-next = 2 -``` - - -#### cpu {#cpu} - -CPU usage - -```ini -[module/cpu] -type = internal/cpu -format = "