amfora: gemini browser

2023-05-26

Amfora is a rather pretty terminal client for the gemini web.

It handles certificates well although you do have to create them manually for now.

It is capable of managing atom/rss feed subscriptions and has a neat timeline view for posts on your subscribed feeds.

keyboard shortcut

| key seq.  | description                                                     |
| --------- | --------------------------------------------------------------- |
| ?         | opens up the keyboard shortcut help                             |
| q         | closes amfora                                                   |
| ctrl-b    | opens the bookmark list                                         |
| ctrl-d    | add / rename / delete bookmark for current page                 |
| ctrl-a    | opens the subscription list                                     |
| ctrl-x    | add or update a subscription                                    |
| ctrl-t    | opens a new tab                                                 |
| F1/F2     | go to next / previous tab                                       |
| ctrl-w    | close the current tab (will only work when on last tab)         |

basic navigation

| key seq.  | description                                                     |
| --------- | --------------------------------------------------------------- |
| hjkl      | navigate with vim keys                                          |
| 0-1       | open the link marked with the number                            |
| -n | opens the link with the number - necessary for links after 9    |
|    | allows to enter an URL                                          |
| b         | go to previous page in browser history                          |
| f         | go to next page in browser history                              |
| ctrl-r    | reload current page                                             |

customization

Amfora has a config.toml file in ~/.config/amfora which is very well documented. You can customize every keybinding etc. Which is useful since some of the default ones conflict with tmux.

Overall through I haven't felt the need to customize amfora much.

proxies

I recently learned that Adicus implemented stargate, a true HTTP to gemini proxy. It allows (some) HTML websites to be displayed in gemini browsers. Now it made sense for me to configure some proxies in amfora:

[proxies]
http = "stargate.gemi.dev:1994"
https = "stargate.gemi.dev:1994"

I don't believe stargate is public yet, but I'll try to set up a docker container for it once it is. Either way, credit where credit is due: Adicus did a fantastic job:

Adicus' announcement of stargate

themes

Okay, I caved. I tokyonight'ed amfora:

[theme]
bottombar_label = "#787c99"
bottombar_text = "#acb0d0"
bottombar_bg = "#43455b"

btn_text = "#32344a"

dl_choice_modal_bg = "#449dab"
dl_choice_modal_text = "#444b6a"
dl_modal_bg = "#449dab"
dl_modal_text = "#444b6a"
info_modal_bg = "#449dab"
info_modal_text = "#444b6a"
error_modal_bg = "#449dab"
error_modal_text = "#444b6a"
yesno_modal_bg = "#449dab"
yesno_modal_text = "#444b6a"
tofu_modal_bg = "#449dab"
tofu_modal_text = "#444b6a"
subscription_modal_bg = "#449dab"
subscription_modal_text = "#444b6a"
bkmk_modal_bg = "#449dab"
bkmk_modal_label = "#32344a"
bkmk_modal_text = "#444b6a"

input_modal_bg = "#449dab"
input_modal_text = "#444b6a"
input_modal_field_text = "#444b6a"


mutt: mail client

2023-05-26

Mutt is a mail client that claims to suck less than many others. I believe that to be true, simply because it can be configured till the cows come home to work precisely as you want it.

Of course, the downside is that personally, I found it pretty much unavoidable to configure it a lot until it becomes usable.

I cannot possibly include a full setup explanation here, but I'll try to cover the things I found necessary to make mutt superior to many other CLI mail clients for my own usecase.

As you might have guessed already, I want vim-keys for navigation. Also, I want the option to GPG-sign and -encrypt messages, work with different mail accounts and some of them being gmail, work with gmail labels efficiently.

config file structure

Mutt allows for a very flexible config file structure within ~/.config/mutt/ and I'm using that to keep track of things. Here is a rough outline:

~/.config/mutt/ 
 ↳ muttrc               the main config file, this is what mutt actually loads
 ↳ account-abc.rc       config file for account 'abc'
 ↳ account-abc.gpg      gpg-encrypted mail account password for 'abc'
 ↳ account-def.rc       config file for account 'def'
 ↳ account-def.gpg      gpg-encrypted mail account password for 'def'
 ↳ appearance.rc        global look and feel config
 ↳ colors-tokyonight    my theme, contains color declarations
 ↳ common.rc            global config options. to be fair this could be inside muttrc
 ↳ gpg.rc               GPG commands. GPG _behaviour_ is in the account.rcs
 ↳ keybinds.rc          keybind changes

mutt itself will load the muttrc file. Its basic structure looks like this:

# this is the main script
#
# it loads all common .rc files,
# configures folder hooks and useful macros to switch accounts
# and then sources the default account

# general settings are included
source ~/.config/mutt/common.rc
source ~/.config/mutt/gpg.rc
source ~/.config/mutt/appearance.rc
source ~/.config/mutt/keybinds.rc

# configure folder hooks and macros for all accounts
folder-hook 'account-abc' 'source ~/.config/mutt/account-abc.rc'
folder-hook 'account-def' 'source ~/.config/mutt/account-def.rc'

# load default account
source '~/.config/mutt/account-abc.rc'

# account switching macros
macro index  'source ~/.config/mutt/account-abc.rc!'
macro index  'source ~/.config/mutt/account-def.rc!'

# styling
source ~/.config/mutt/colors-tokyonight

As you might have spotted, I can switch between accounts by pressing F2 / F3.

account config

There really isn't anything special here: The account-xyz.rc files source the GPG-encrypted passwords, set all parameters and folders for the mail account and configure the GPG setup. The GPG setup isn't centralized because I want only my main account to automatically sign my messages. All others are GPG capable but completely passive.

There is a separate section on GPG further down.

What the main account.rc file also does is activate the sidebar and configure the relevant GMail mailboxes to show up in the sidebar. More on that in the sidebar section.

GPG

The main gpg.rc file only configures the mutt command to call the right GPG commands in turn.

set crypt_use_gpgme=yes
set pgp_decode_command="gpg --status-fd=2 %?p?--passphrase-fd 0 --pinentry-mode=loopback? --no-verbose --quiet --batch --output - %f"
set pgp_verify_command="gpg --status-fd=2 --no-verbose --quiet --batch --output - --verify %s %f"
set pgp_decrypt_command="gpg --status-fd=2 %?p?--passphrase-fd 0 --pinentry-mode=loopback? --no-verbose --quiet --batch --output - %f"
set pgp_sign_command="gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0 --pinentry-mode=loopback? --armor --detach-sign --textmode %?a?-u %a? %f"
set pgp_clearsign_command="gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0 --pinentry-mode=loopback? --armor --textmode --clearsign %?a?-u %a? %f"
set pgp_encrypt_only_command="/usr/lib/mutt/pgpewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust -- -r %r -- %f"
set pgp_encrypt_sign_command="/usr/lib/mutt/pgpewrap gpg %?p?--passphrase-fd 0 --pinentry-mode=loopback? --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --always-trust -- -r %r -- %f"
set pgp_import_command="gpg --no-verbose --import %f"
set pgp_export_command="gpg --no-verbose --export --armor %r"
set pgp_verify_key_command="gpg --verbose --batch --fingerprint --check-sigs %r"
set pgp_list_pubring_command="gpg --no-verbose --batch --quiet --with-colons --with-fingerprint --list-keys %r"
set pgp_list_secring_command="gpg --no-verbose --batch --quiet --with-colons --with-fingerprint --list-secret-keys %r"
set pgp_good_sign="^\\[GNUPG:\\] Good signature from"
set pgp_check_gpg_decrypt_status_fd

This is a mixup of several sources, including an old mutt-gnupg-howto:

codesorcery.net mutt-gnupg-howto

How a mail account handles GPG is configured in the respective account.rc file.

For example the config below activates pgp for my respective key and will automatically sign all outgoing mails, including replies.

It will also automatically encrypt mails from people I have a key for.

set pgp_use_gpg_agent = yes
set crypt_autopgp = yes
set pgp_default_key="..."
# automatically sign all mails, even unsigned / unencrypted ones
set crypt_autosign = yes
# DO sign / encrypt replies to mails which are themselves signed / encrypted
set crypt_replysign = yes
set crypt_replyencrypt = yes
set crypt_replysignencrypted = yes
#-- automatically encrypts mails to recipients we have a key of
set crypt_opportunistic_encrypt = yes

For accounts that don't use GPG at all, I need to set crypt_autopgp = no to deactivate.

the sidebar

For the longest time I didn't know that the sidebar exists in mutt. I now use it to show the different mail folders and quickly navigate between them.

To activate the sidebar and display a bunch of existing mail folders:

set sidebar_visible = yes
mailboxes =INBOX =done =done/amazon =done/paypal =done/gemini =family 

To have the mailboxes appear exactly in the order I configure them, my common.rc sets the sorting:

set sidebar_sort_method = "unsorted"

To quickly navigate between sidebar folders I've chosen to use Ctrl plus j/k for vim-key like up and down, also Ctrl-l to go to the active mailbox. My keybinds.rc therefore contains:

bind index,pager  \Cj  sidebar-next
bind index,pager  \Ck  sidebar-prev
bind index,pager  \Cl  sidebar-open

For a bit of neatness my appearance.rc tweaks the vertical divider between sidebar and mail index / pager:

set sidebar_divider_char = "║"

To quickly send mails to a specific mailbox I have setup macros in keybinds.rc. For example:

bind index,pager \Ce noop
macro index,pager \Ce ":set confirmappend=no delete=yes\n=done\n:set confirmappend=yes delete=ask-yes\n"

This causes Ctrl-e to send the active mail (selected in the index or displayed in the pager) to be sent to my done folder.

Two gotchas here: Firstly: if the mailbox name contains a space I found mutt to behave randomly, mostly assigning other keyboard commands to the macro than what I configured. I couldn't find an escape sequence to mitigate this. Secondly: The built-in help sometimes didn't display that a keyboard shortcut was already used, so I find it wise to unbind the shortcut before assigning the macro.

keyboard shortcuts

I find that most default keybinds make a lot of sense. Nonetheless switching to vim-keys took some care, also the sidebar navigation above. There isn't much else to be honest.

# common keybinds

# by default IMAP mail fetching isn't bound, G is used for POP3
bind index G imap-fetch-mail

# scrolling in mail-view
## scroll with mouse-wheel
bind pager  previous-line
bind pager  next-line

## scroll with vim-keys
bind pager j next-line
bind pager k previous-line
bind pager h previous-entry
bind pager l next-entry
bind pager \Cf next-page
bind pager \Cb previous-page
bind pager \Cd half-down
bind pager \Cu half-up
bind pager b exit
bind index l display-message

# clear up some keybinds
bind pager i noop # seems bound to 'exit'
bind pager q noop # seems bound to 'exit'
bind pager x noop # seems bound to 'exit'

# move within sidebar
bind index,pager  \Cj  sidebar-next
bind index,pager  \Ck  sidebar-prev
bind index,pager  \Cl  sidebar-open

theming

I did only minor visual tweaking. One is to slightly change the colums in the index as well as introducing vertical dividers between the columns. The sidebar divider was already mentioned above. My appearance.rc file looks like this:

set date_format = "!%d %b %R"
set index_format = "%4C │ %Z │ (%?l?%4l&%4c?) │ %D │ %-30.30L │ %s"
set sidebar_divider_char = "║"

The other change was my theme. I like tokyonight although it is overdone. Also I couldn't actually find a tokyonight theme for mutt so I made my own. It isn't complete but it works for me:

# colors-tokyonight

# general ------------ foreground ---- background -----------------------------
color indicator        black           cyan
color status           brightblack     magenta
color error            red             black
# unchanged below
color markers          color210        default
color message          default         default
color normal           default         default
color prompt           default         default
color search           color84         default
color tilde            color231        default
color tree             color141        default

# message index ------ foreground ---- background -----------------------------
color index            brightgreen     default  ~N # new unread messages
color index            brightgreen     default  ~O # old unread messages
color index            default         default  ~R # read messages
color index            green           default  ~U # unread messages
color index            cyan            default  ~Q # messages which have been replied to
color index            red             default  ~D # deleted messages
# unchanged below
color index            color84         default  ~F # flagged messages
color index            color215        default  ~T # tagged messages
color index            color141        default  ~v # messages part of a collapsed thread

# message headers ---- foreground ---- background -----------------------------
color header           color231        default  ^Subject:.*
color header           color231        default  ^From:.*
color header           color231        default  ^To:.*
color header           color231        default  ^Date:.*
color hdrdefault       cyan            default

# message body ------- foreground ---- background -----------------------------
color quoted           blue            default
color quoted1          brightblue      default
color quoted2          cyan            default
color quoted3          brightcyan      default
color quoted4          green           default
color body             color231        default  [\-\.+_a-zA-Z0-9]+@[\-\.a-zA-Z0-9]+               # email addresses
color body             color228        default  (https?|ftp|gemini)://[\-\.,/%~_:?&=\#a-zA-Z0-9]+        # URLs
color body             brightyellow    default  " [:;][-o][)/(|D]" # emoticons with nose
color body             brightyellow    default  " [:;][/)(|D]"     # emoticons without nose
color body             brightyellow    default  (o.O|O.o)         # emoticon: confused look
color body             color231        default  (^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$) # *bold* text
color body             color231        default  (^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)     # _underlined_ text
color body             color231        default  (^|[[:space:]])/[^/]+/([[:space:][:punct:]]|$)     # /italic/ text
# unchanged below
color attachment       color228        default
color signature        color212        default

conclusion and links

I know this has been a long cheat sheet. It certainly took me quite a while to piece it all together. I am very certain that a lot of mutt goodness still evades me but with the setup above mutt has replaced my gmail webclient and Thunderbird. It is perfectly usable. Anything from here on out is optimization.

There are a lot of helpful links for mutt without I wouldn't have been able to get here. Also the man page is fantastic.

Some of the most important web resources:

an old mutt & gnupg howto. It is a very good source to understand GPG.

the official mutt manual

The mutt command reference. Anything that can be set in the .rc files.

Sadly, getting mail encryption going isn't trivial, even today. I recommend these two sources to get started:

email self-defense

generating secure and easy-to-remember passphrases with diceware


ncmpcpp: music player

2023-03-10

ncmpcpp takes the cake for having the most unintuitive name of the lot. So much that I have created a shell alias for it. That aside, it is a pretty fantastic client for mpd to play / stream music.

notes

It is important to understand that ncmpcpp isn't actually playing any music, it is simply a client for mpd. Mpd is what plays the music. This has implications:

The whole thing can look pretty neat in my opinion:

Here's a screenshot

screen and slave screen

Personally I don't use that feature (yet?) since it messes with my head regarding keyboad navigation, I prefer to launch several instances. But that's just me.

keyboard shortcuts

general navigation

| keybind | description                                            |
| ------- | ------------------------------------------------------ |
| 1       | opens the current playlist                             |
| 2       | opens the media folder browser                         |
| 3       | opens the search options                               |
| 4       | opens the media library                                |
| 5       | playlist editor (create/edit playlists)                |
| 6       | tag editor                                             |
| 7       | output options                                         |
| 8       | music visualizer                                       |
|   | move to main screen (when slave screen is present)     |
|  | move to slave screen (when present)                    |

playback options

| keybind | description                                            |
| --------| ------------------------------------------------------ |
|  | add the current selection to playlist                  |
|  | add current selection to playlist and start playing    |
| p       | toggle play/pause                                      |
| s       | stop playback                                          |
| <       | jump to previous song                                  |
| >       | jump to next song                                      |
| z       | toggle random mode                                     |
| r       | toggle repeat mode                                     |

playlist

| keybind | description                                            |
| --------| ------------------------------------------------------ |
| x       | remove highlighted song from playlist                  |
| A       | add file path or URL to playlist                       |

Note that ncmpcpp can play streaming radios if the URL of the stream is

copied into the playlist, try with https://liveradio.swr.de/sw331ch/swr3/play.aac

tweaks and config changes

By default ncmpcpp doesn't use vim keys for navigation. They can however easily be added by tweaking the ~/.config/ncmpcpp/bindings file:

def_key "j"
    scroll_down
def_key "k"
    scroll_up

def_key "ctrl-u"
    page_up
def_key "ctrl-d"
    page_down
def_key "u"
    page_up
def_key "d"
    page_down
def_key "h"
    previous_column
def_key "l"
    next_column
def_key "J"
    move_sort_order_down
def_key "K"
    move_sort_order_up
def_key "h"
  jump_to_parent_directory
def_key "l"
  enter_directory
def_key "l"
  run_action
def_key "l"
  play_item

plugins, addons, dependencies

Remember that ncmpcpp is only a client for mpd, it needs a few other programs installed to work, and work well


ranger: file manager

2023-03-10

Ranger is a file browser for the commandline. This page contains my personal tweaks, config changes and commonly used keyboard shortcuts.

keyboard shortcuts

use nvim keys

| key seq.  | description                                                     |
| --------- | --------------------------------------------------------------- |
| h         | up one level                                                    |
| k         | down one level                                                  |
| j         | down one item in list                                           |
| k         | up one item in list                                             |
| Ctrl-D    | scroll down one half screen                                     |
| Ctrl-U    | scroll up one half screen                                       |
| gh        | quick jump to home dir                                          |

copy path and information

| key seq.  | description                                                     |
| --------- | --------------------------------------------------------------- |
| yd        | yank directory information (excludes filename)                  |
| yp        | yank absolute path information (includes filename)              |
| yn        | yank name (this is _only_ the file/dir name, no path            |
| y.        | yank name without extension                                     |

operations

| key seq.  | description                                                     |
| --------- | --------------------------------------------------------------- |
| :touch n  | create new file `n`                                             |
| :mkdir n  | create new diectory `n`                                         |
| a         | rename append (cursor at end of current name, before extension) |
| A         | rename append (cursor at end of extension)                      |
| I         | rename insert (cursor at beginning of name)                     |
| Space     | mark file                                                       |
| v         | mark all files in current list                                  |
| V         | mark in visual mode (can do this multiple times for segments)   |
| uV        | unmark in visual mode                                           |
| t         | toggle tag                                                      |
| yy        | copy marked (if any), current otherwise                         |
| dd        | cut marked (if any), current otherwise                          |
| dD        | delete marked (if any), current otherwise                       |
| pp        | paste (will dynamically rename doubles)                         |
| po        | paste overwrite                                                 |
| pl        | paste absolute symlink to yy-copied file                        |
| pL        | paste relative symlink to yy-copied file                        |

tweaks and config changes

Generally the rc.conf is extensive and superbly documented. Tweaking ranger is really easy.

Do have a look at the official documentation however, some aspects of the program are configured in other files.

Ranger has multiple options to integrate file previews into the TUI. What you can use depends on what other programs you have installed and which terminal you use. Do have a look.

theming

By default ranger will use the terminal theme, which is good enough for me. The rc.conf however does have some default colorschemes.

plugins & addons

I find the devicons plugin tremendously useful. If you're using a Nerdfont in your terminal — and you really should! — it adds file and folder icons and similar things to the interface. I find that this makes it much easier to find the right things.

=> https://github.com/alexanderjeurissen/ranger_devicons

To get the most out of ranger, I find that a bunch of additional software was required to make use of some of the built-in addons:


various short shell commands

2023-12-14

This one contains a list of one-liners or short shell scripts to get stuff done.

conversions

convert video to gif

This one works in several steps: first analyze the video and generate an image that acts as color palette, then create the gif using the video and palette as inputs:

    # create palette
    ffmpeg -i video.mp4 -filter_complex "[0:v] palettegen" palette.png
    # converting to gif
    ffmpeg -i video.mp4 -i palette.png -filter_complex "[0:v][1:v] paletteuse" video.gif

convert images to a standard size with ImageMagick

    magick mogrify -path output/folder/ -resize 1000x1000^ -gravity center -monitor *.jpg

convert WAV to Ogg Vorbis

    #!/usr/bin/env bash

    if [ $# -ne 1 ]; then
      echo "converts an audio file to Ogg vorbis"
      echo "Usage $0 path/to/audiofile.wav"
      exit 1
    fi

    filepath=$1
    dirname=$(dirname "$filepath")
    filename=$(basename "$filepath")
    extension="${filename##*.}"
    basename="${filename%.*}"

    targetpath="$dirname/$basename.ogg"

    ffmpeg -i $filepath -c:a libvorbis $targetpath

convert numbers to different bases

this converts from base 10 to base 16

   echo "obase=16;" 73 | bc

This converts from base 16 to binary (base 2)

    echo "ibase=16;obase=2;" F | bc

All wrapped up in a script

    #!/usr/bin/env bash

    if [ $# -ne 2 ]; then
      basename=$(basename $0)
      echo "Converts a decimal number into another base"
      echo "Usage: $basename target_base decimal_number"
      echo
      echo "Examples:"
      echo "  $basename 2 30     converts decimal 30 to binary 11110"
      echo "  $basename 16 73    converts decimal 73 to hexadecimal 4B"
      exit 1
    fi

    decimalNum=$2
    obase=$1
    prefix=""

    # convert bases
    if   [[ $obase == "h" || $obase == "hex" ]]; then obase=16
    elif [[ $obase == "o" || $obase == "oct" ]]; then obase=8
    elif [[ $obase == "b" || $obase == "bin" ]]; then obase=2
    fi

    # helpful prefixes
    if   [ $obase -eq 16 ]; then prefix="0x"
    fi

    targetNum=$(echo "obase=$obase;$decimalNum" | bc)
    echo "$decimalNum in base $obase is $prefix$targetNum"

monitoring

Raspberry Pi 4 system health

    #!/usr/bin/env zsh

    sep='\033[0;34m//\033[0m'
    mem=`free --mega | awk 'NR==2 {printf "%.1f/%.1f GB\n", $3/1024, $2/1024}'`
    tmp=`head -1 /sys/class/thermal/thermal_zone0/temp | awk '{printf "%.1f°C\n", $0/1000}'`
    dsk=`df -h / | awk 'NR==2 {print "hdd: "$3" ("$5") of "$2}'`

    echo "$mem $sep $tmp $sep $dsk"

recording

record video and audio (Wayland WM)

I need the --geometry parameter to record only one monitor in my dual monitor setup.

    #!/usr/bin/env bash

    if [ $# -ne 1 ]; then
      basename=$(basename $0)
      echo "records the left screen as 720p video with audio"
      echo "Usage: $basename path/to/output.mkv"
      exit 1
    fi

    outputFile=$1
    audioDevice="alsa_output.usb-Logitech_Logitech_USB_Headset_000000000000-00.analog-stereo.monitor"

    wf-recorder -g "0,0 1920x1080" -R 44100 -F "scale=-1:720" -a=$audioDevice -f "$outputFile"

web-related

download a single webpage as markdown

Instead of commonmark_x you can experiment with commonmark, markdown_strict or simply markdown

    #!/usr/bin/env zsh
    # Uses pandoc to download a file and convert it to a markdown file

    binPandoc=$(which pandoc)

    if [ $# -ne 2 ]; then
      echo "Usage: "
      echo "$0 URL filename"
      exit 1
    fi

    $binPandoc --from=html --to=commonmark_x --standalone --embed-resources=false --output=$2 $1

download all pages in a website directory, but nothing above it

This will convert relative links so they still work after downloading.

    wget --convert-links --page-requisites --recursive --no-parent "https://example.com/path/to/download"

...in a script that's a little flexible

    #!/usr/bin/env zsh

    # uses wget to download a website and all links / images / ... 
    # to use locally. inline links are converted

    binWget=$(which wget)

    if [[ $# -eq 0 || $# -gt 2 ]]; then
      echo "Usage:"
      echo "$0 [-d|--directory] URL"
      echo
      echo "-d\t--directory\twill recursively download the given directory, but nothing above it"
      exit 1;
    fi

    if [[ $1 == "-d" || $1 == "--directory" ]]; then
      dirOnly=1
      url=$2
    else
      dirOnly=0
      url=$1
    fi

    if [[ $dirOnly -eq 1 ]]; then
      $binWget --convert-links --page-requisites --recursive --no-parent "$url"
    else
      $binWget --convert-links --page-requisites "$url"
    fi

make a gemini certificate

    #!/usr/bin/env zsh

    basedir="/home/dominique/Documents/synced/personal/gemini/identities/"

    if [ $# -ne 2 ]; then
      echo "Usage $0 label hostname"
      exit 1
    else
      label=$1 
      hostname=$2
    fi

    openssl req -new -subj "/CN=$label" -x509 -newkey ec \
            -pkeyopt ec_paramgen_curve:prime256v1 -days 7300 -nodes \
            -out $basedir$hostname.crt \
            -keyout $basedir$hostname.key


tmux: terminal multiplexer

2023-05-01

Tmux is a terminal multiplexer that is allows to split a terminal window into multiple panes and add multiple virtual windows within a single tmux session.

On top of that tmux allows you to detach from a session and reconnect later. Sessions are preserved until the system reboots. Multiple sessions can be managed and switched between.

Panes live inside a single window. Windows live inside a single session.

The session preservation feature makes tmux extremely useful when connecting to remote computers: Combinations of windows and panes — for example for different users on that computer — can be created and arranged once, then detached and attached to as needed. All over one single SSH connection.

Long-running processes are safe from disconnects since tmux keeps them running even if your SSH connection drops.

The panes feature isn't very useful for me since I'm using a tiling window manager to begin with. Having multiple virtual windows per session saves on screenspace though. But the killer feature for me comes with the plugins ‘continuum’ and ‘resurrect’: If configured just right, they will …well… resurrect all applications that were running in the windows and panes, even across system reboots.

On my desktop I use this to preserve pane tilings and launch apps that I'll inevitably use anyway, like my mail client, gemini space reader, matrix client, ncmpcpp music client… it is so convenient.

On my selfhosted server I use it to have ready-made login shells for common users.

In the command list below, those command marked with a * are customized.

links and resources

tmux Getting Started wiki page

awesome tmux - list of howtos, plugins, themes

TPM, the tmux plugin manager

console commands

| command                            | description                          |
| ---------------------------------- | -------------------------------------|
| tmux                               | start a new unnamed session          |
| tmux new -s docker                 | start a new session named docker     |
| tmux ls                            | lists available sessions             |
| tmux attach -t [name]              | re-attach to existing session [name] |
| tmux rename-session -t [old] [new] | renames a session                    |
| tmux kill-session -t [name]        | kills a session and everything in it |

keyboard shortcuts

| keybind              | description                                        |
| -------------------- | -------------------------------------------------- |
|  ?           | show keybinds                                      |
|  :           | open the command prompt                            |

handling panes

| keybind                | description                                      |
| ---------------------- | ------------------------------------------------ |
|  b           * | create a new pane to the right of current        |
|  v           * | create a new pane below the current              |
|  hljk        * | navigate between panes                           |
|  Ctrl-[CURSOR] | resize pane                                      |
|  x             | close current pane                               |
|  z             | zoom / unzoom current pane                       |
| exit                   | exit current pane / window when last pane        |

handling windows

| keybind              | description                                        |
| -------------------- | -------------------------------------------------- |
|  c           | create a new window                                |
|  [n]         | switch to window [n] inside current session        |
|  ,           | rename current window                              |
|  &           | close current window                               |
|  w           | list windows                                       |
|  p           | move to previous window                            |
|  n           | move to next window                                |
|  a         * | toggle to last active window                       |
|  .           | move a window (use numeric indexes or cursor keys) |

handling sessions from within a session

| keybind              | description                                        |
| -------------------- | -------------------------------------------------- |
|  s           | switch to a different session from a list          |
|  d           | detach from current session                        |
|  $           | rename session                                     |
|  (           | move to previous session                           |
|  )           | move to next session                               |

plugins

Tmux has strong plugin support. It all starts with the tmux plugin manager:

TPM, the tmux plugin manager

To add new plugins, add them to your tmux.conf file and press Ctrl-b I to load new plugins.

tweaks and config changes

Tmux reads config options from ~/.tmux.conf or my personal preference ~/.config/tmux/tmux.conf but only when the server is started, not when a new session is created or attached to. My config file looks like this:

#---- remap prefix key to Ctrl-a --------------------------
unbind C-b
set-option -g prefix C-a 
bind-key C-a send-prefix

#---- enable mouse control --------------------------------
set -g mouse on 

#---- start window numbering from 1, not 0 ----------------
set -g base-index 1

#---- set 256 color space ---------------------------------
set-option -g default-terminal "xterm-256color"
set-option -ga terminal-overrides ',xterm-256color:Tc'

#---- keybinds --------------------------------------------
# pane creation same as SwayWM
bind-key    -T prefix   v     split-window
bind-key    -T prefix   b     split-window -h
# pane navigation same as vim
bind-key    -T prefix   h     select-pane -L
bind-key    -T prefix   l     select-pane -R
bind-key    -T prefix   j     select-pane -D
bind-key    -T prefix   k     select-pane -U
# left-/right-shift windows in a session by one
bind-key    -r         "<"    swap-window -d -t -1
bind-key    -r         ">"    swap-window -d -t +1

#---- resurrection ----------------------------------------
set -g @continuum-restore on
set -g @resurrect-capture-pane-contents "on"
# declare additional applications as safe for resurrection
set -g @resurrect-processes "amfora ncmpcpp w3m"

#---- theme and styling -----------------------------------
# using nova theme customization to make it look like tokyo night
#    since the tokyo night theme isn't working for me
set -g @plugin "o0th/tmux-nova"

set -g @nova-nerdfonts true
set -g @nova-nerdfonts-left 
set -g @nova-nerdfonts-right 

set -g @nova-pane-active-border-style "#7da6ff"
set -g @nova-pane-border-style "#444b6a"
set -g @nova-status-style-bg "#32344a"
set -g @nova-status-style-fg "#787c99"
set -g @nova-status-style-active-bg "#449dab"
set -g @nova-status-style-active-fg "#32344a"
set -g @nova-status-style-double-bg "#acb0d0"

set -g @nova-pane "#I#{?pane_in_mode,  #{pane_mode},}  #W"

set -g @nova-segment-mode "#S #{?client_prefix,Ω,ω}"
set -g @nova-segment-mode-colors "#ad8ee6 #32344a"

set -g @nova-segment-whoami "#(whoami)@#h"
set -g @nova-segment-whoami-colors "#ad8ee6 #32344a"

set -g @nova-rows 0
set -g @nova-segments-0-left "mode"
set -g @nova-segments-0-right "whoami"

# list of plugins
set -g @plugin "tmux-plugins/tpm"
set -g @plugin "tmux-plugins/tmux-sensible"
set -g @plugin "tmux-plugins/tmux-resurrect"
set -g @plugin "tmux-plugins/tmux-continuum"

#---- initialize TMUX plugin manager ----------------------
#     (keep this line at the very bottom of tmux.conf)
run "~/.config/tmux/plugins/tpm/tpm"


w3m: internet browser

2024-11-22

w3m is my commandline internet browser of choice

keyboard shortcuts

| keybind              | description                                        |
| -------------------- | -------------------------------------------------- |
|                 | jump to next link                                  |
|  -       | jump to previous link                              |
|  - h          | help                                               |
|  - u          | enter new URL                                      |
|  - b          | go one page back in current buffer                 |
|  - t          | open current buffer in new tab                     |
|  - t           | open link under cursor in new tab                  |
| {                    | go one tab left                                    |
| }                    | go one tab right                                   |
|  - q           | close current tab                                  |


weechat

2024-11-22

weechat is an IRC client. IRC stands for Internet Relay Chat.

copy and paste

This is a weird one. Copy & paste with the mouse works only if WeeChat mouse functionality is disabled.

So do Alt-m to disable the mouse, then select something in WeeChat with the mouse.

To paste, simply middle-click as per usual in the terminal.

Once done, do Alt-m again to re-enable the mouse.

Middle-clicking to paste also works with copied content from another terminal, as long as the mouse is disabled.

keyboard shortcuts

| keybind              | description                                        |
| -------------------- | -------------------------------------------------- |
| Alt-a                | switch to next buffer with activity                |
| Alt-up               | goes up in the buffer list on the left             |
| Alt-down             | goes down in the buffer list on the left           |
| Alt-Enter            | edit value, i.e. in the /set irc.server conf list  |
| Alt-m                | toggle mouse functionality off/on                  |

configuring SASL for WeeChat

Here’s a simple guide for password-based authentication, based on the WeeChat quick-start guide.

If you haven’t already set up your connection to Libera.Chat, use this command:

/server add libera irc.libera.chat/6697 -tls

If you have already set up a connection to Libera.Chat, or if that command fails with a message like irc: server "libera" already exists, can't add it!, then use these commands to ensure

that SSL/TLS is enabled for your connection:

/set irc.server.libera.addresses "irc.libera.chat/6697"

/set irc.server.libera.tls on

Now, configure SASL:

/set irc.server.libera.sasl_mechanism plain

/set irc.server.libera.sasl_username

/set irc.server.libera.sasl_password

/save

It is recommended to store the password as secured data (skip setting passphrase if already set):

/secure passphrase

/secure set libera_password

/set irc.server.libera.sasl_password "${sec.data.libera_password}"

/save

For more complete instructions, including non-password-based mechanisms, see the official WeeChat documentation.


Proxy Information
Original URL
gemini://laniakea.rodoste.de/md/tui.md
Status Code
Success (20)
Meta
text/plain; charset=utf-8
Capsule Response Time
268.669939 milliseconds
Gemini-to-HTML Time
4.079385 milliseconds

This content has been proxied by September (ba2dc).