Skip to content

Instantly share code, notes, and snippets.

@kyle0r
Last active May 9, 2025 23:57
Show Gist options
  • Save kyle0r/74cd5a6046747867e521efc01997a53d to your computer and use it in GitHub Desktop.
Save kyle0r/74cd5a6046747867e521efc01997a53d to your computer and use it in GitHub Desktop.

Revisions

  1. kyle0r revised this gist May 9, 2025. 1 changed file with 6 additions and 0 deletions.
    6 changes: 6 additions & 0 deletions A containerised Linux desktop env setup.md
    Original file line number Diff line number Diff line change
    @@ -115,13 +115,19 @@ EOF
    # once complete, reboot the CT for good measure
    reboot
    ```

    ---

    Now it is time to set up the demo user.
    If you need inspiration for a password, you can try this snippet which will run as the `nobody` user as a best practice:
    ```
    cat <<'EOF' | sudo -u nobody bash
    test -e /usr/share/dict/words && echo "$(whoami) generated password: $(shuf -n 4 <(awk 'length($0) > 4 && length($0) < 9 && ! /'"'"'/' /usr/share/dict/words) | tr '\n' ' ' | tr '[:upper:]' '[:lower:]')" || echo 'Aborted. Dictionary not found.'
    EOF
    ```
    This generation approach follows the logic of https://xkcd.com/936/. Jeff Preshing published an online generator [here](https://preshing.com/20110811/xkcd-password-generator/).

    ---

    **From the hypervisor terminal:**, enter the CT and setup the demo user:
    ```
  2. kyle0r revised this gist May 9, 2025. 1 changed file with 8 additions and 2 deletions.
    10 changes: 8 additions & 2 deletions A containerised Linux desktop env setup.md
    Original file line number Diff line number Diff line change
    @@ -3,23 +3,29 @@ This gist is currently a Work In Progress.

    These steps were practised and performed on a Debian Bookworm container and Proxmox 8.x Hypervisor (Debian). Instructions may vary for other releases/distros. Please DYOR and observe that YMMV. Comments, ideas and critique very welcome.

    There will be a screencast performing a speed run of the topics.
    Speed run screencast: https://youtu.be/SFWV8blEdZQ

    This gist is effectively a tech demo. I hope you enjoy and take away something useful.

    The objective with most of the topics is to show ways / introduce tooling to boost productivity and the quality of our daily lives working in tech.

    # TODO
    <details>
    <summary><strong>Click here</strong> to toggle the TODO section</summary>


    * Talk about / introduce https://github.com/kyle0r/bash-shortcuts-cheat-sheet, probably fits in the xterm/tmux sections.
    ---
    Does xrdp support USB key pass-through/auth?
    * Does xrdp support USB key pass-through/auth?
    ```
    xrdp-chansrv[430]: [INFO ] Detected remote smartcard 'SCARD'
    ```
    ---
    * Add a TOC
    * Investigate if [this](https://unix.stackexchange.com/a/600787/19406) answer can help to optmise the xterm config duplication

    </details>

    # Creating a Proxmox CT
    Depends on the `jq` command. Perform the following **from the hypervisor terminal:**
    ```
  3. kyle0r revised this gist May 9, 2025. 1 changed file with 25 additions and 0 deletions.
    25 changes: 25 additions & 0 deletions A containerised Linux desktop env setup.md
    Original file line number Diff line number Diff line change
    @@ -801,6 +801,31 @@ Versatile and comprehensive XPath 1.0 package for processing HTML and XML with x

    </details>

    # Visual Studio Code

    If you like [VS Code](https://code.visualstudio.com/), then here some shell snippets to get you started.

    ## Per user install

    ```
    curl --connect-timeout 5 -sSL 'https://code.visualstudio.com/sha/download?build=stable&os=linux-x64' | bsdtar -xf - -C ~/.local && ln -s ~/.local/VSCode-linux-x64/bin/code ~/.local/bin
    ```

    ## System wide install

    ```
    curl --connect-timeout 5 -sSL 'https://code.visualstudio.com/sha/download?build=stable&os=linux-deb-x64' > ~/Downloads/vscode_amd64.deb
    sudo apt update && sudo apt install -y --fix-broken ~/Downloads/vscode_amd64.deb
    ```

    ## Plugins

    ### Nord

    Of corse there is a Nord plugin for VS Code :)

    # Beyond Compare
    A similar story to text editors... I've used a number of text/file comparison and merge tools over the years. Beyond Compare is hands down the best I've tried to date and I've purchased a number of licences over the years both personally and in the enterprise, to support its great team and further development.

  4. kyle0r revised this gist May 5, 2025. 1 changed file with 16 additions and 6 deletions.
    22 changes: 16 additions & 6 deletions A containerised Linux desktop env setup.md
    Original file line number Diff line number Diff line change
    @@ -18,6 +18,7 @@ xrdp-chansrv[430]: [INFO ] Detected remote smartcard 'SCARD'
    ```
    ---
    * Add a TOC
    * Investigate if [this](https://unix.stackexchange.com/a/600787/19406) answer can help to optmise the xterm config duplication

    # Creating a Proxmox CT
    Depends on the `jq` command. Perform the following **from the hypervisor terminal:**
    @@ -153,7 +154,7 @@ UXTerm*faceSize: 14
    SH
    EOF
    # function to remove CR from the clipboard
    # function to remove CR (windows line endings) from the clipboard
    cat <<'EOF' | sudo -u "$demouser" sh
    cat <<'SH' >> ~/.bash_aliases
    clipclean() { xclip -o -selection clipboard | tr -d '\r' | xclip -i -selection clipboard; }
    @@ -175,7 +176,7 @@ dhcp_ip=<dhcp_ip>
    ssh_key=~/.ssh/<key>; ssh-copy-id -i "$ssh_key" "$demouser"@"$dhcp_ip"
    # test ssh connectivity
    ssh "$demouser"@"$dhcp_ip" 'date;hostname;uptime;w'
    ssh "$demouser"@"$dhcp_ip" 'date;hostname;tty;w'
    ```

    # CT GUI Login
    @@ -375,7 +376,7 @@ The [tpm project](https://github.com/tmux-plugins/tpm) is a simple way to manage
    ```
    git clone --depth=1 https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
    tmux new-session '~/.tmux/plugins/tpm/scripts/install_plugins.sh'
    tmux new-session '~/.tmux/plugins/tpm/scripts/install_plugins.sh; printf "%s" "Press ENTER to continue..."; read -r _;'
    ```
    Now you can launch `tmux` :)

    @@ -408,6 +409,8 @@ else
    echo 'There was a problem determining xpanes_latest_version'
    fi
    ```
    💡 You'll want to logout / exit any terminal sessions to pick up changes.

    ### Updating `xpanes`
    Just run the snippet again in the future.

    @@ -457,17 +460,19 @@ endif
    EOF
    ```

    Then run `vim -c 'PlugUpdate'` which will install the plugin(s) and then quit vim to finalise the install.
    Then run the following, which will install the plugin(s) and then quit vim to finalise the install.

    `vim -c PlugInstall -c 'echo "Press ENTER to continue..."' -c 'call input("")' -c qa`

    Now try to edit a file, for example `vim ~/.vimrc` to see that the nord plugin/colorscheme is active.

    ## Updating vim plugins
    `vim -c 'PlugUpdate'` to update plugins and `vim -c 'PlugUpgrade'` to upgrade `vim-plug` itself.
    `vim -c PlugUpdate` to update plugins and `vim -c PlugUpgrade` to upgrade `vim-plug` itself.

    # `fzf`
    `fzf` describes itself as "a general-purpose command-line fuzzy finder" and improves the quality of life on the terminal, enhancing things like searching shell history, changing dirs and finding files.

    This approach installs `fzf on a per user basis rather than system wide.
    This approach installs `fzf` on a per user basis rather than system wide.

    To install the latest version from GitHub inspired from the official docs [here](https://github.com/junegunn/fzf?tab=readme-ov-file#using-git):

    @@ -641,6 +646,10 @@ After install, you can launch the latest ungoogled-chromium-portablelinux by inv

    You will might see a `gnome-keyring` prompt. I have no experience with this, so DYOR. [Here is the man page for `gnome-keyring`](https://manpages.debian.org/stable/gnome-keyring/gnome-keyring.1.en.html). I'm assuming it wants to use the keyring to read and write website secrets like usernames and passwords for saved sites, that sort of thing. Similar to the keychain in OS X. You'll probably need to take some steps to initialise the user keyring if you want to take advantage of its features.

    <details>

    <summary><strong>Click here</strong> to see details on installing Google Chrome</summary>

    ### Portable Google Chrome?
    When researching, I found the "Google-Chrome-Portable-maker-for-linux" project [here](https://github.com/shivamgly/Google-Chrome-Portable-maker-for-linux). Which is discussed [here](https://askubuntu.com/a/1051236). It looks quite interesting. Keep in mind this relates to the Google Chrome browser distribution and is not ungoogled.

    @@ -661,6 +670,7 @@ sudo apt install --dry-run --fix-broken ~/Downloads/"$chrome_dl_filename"
    # install Chrome system wide
    sudo apt install -y --fix-broken ~/Downloads/"$chrome_dl_filename"
    ```
    </details>

    # Sublime Text
    [Sublime Text](https://www.sublimetext.com/) as its name suggests is extremely good. Back in ~2008 creator Jon Skinner had some really novel ideas on improving UI/UX and Sublime introduced and made the Command Palette popular which other apps have since implemented their own flavours of. I remember trying the early versions and being blown away by it.
  5. kyle0r revised this gist May 5, 2025. 1 changed file with 178 additions and 168 deletions.
    346 changes: 178 additions & 168 deletions A containerised Linux desktop env setup.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,3 @@

    # A containerised Linux desktop env setup
    This gist is currently a Work In Progress.

    @@ -165,18 +164,18 @@ exit # logout from the CT termminal
    ```

    # CT `ssh` login
    Simple steps to test ssh and setup pub key auth for op-demo user
    Simple steps to test ssh connectivity and optionally setup pub key auth for the demo user
    ```
    # setup auth, replace <dhcp_ip> and <key> with your values
    dhcp_ip=<dhcp_ip>; ssh_key=~/.ssh/<key>
    demouser=op-demo
    # OPTIONAL: if needed, set up public key auth
    ssh-copy-id -i "$ssh_key" op-demo@"$dhcp_ip"
    # replace <dhcp_ip> with the one noted during CT creation
    dhcp_ip=<dhcp_ip>
    # connect
    ssh op-demo@"$dhcp_ip"
    # OPTIONAL: set up public key auth - replace <key> accordingly
    ssh_key=~/.ssh/<key>; ssh-copy-id -i "$ssh_key" "$demouser"@"$dhcp_ip"
    hostname
    # test ssh connectivity
    ssh "$demouser"@"$dhcp_ip" 'date;hostname;uptime;w'
    ```

    # CT GUI Login
    @@ -346,49 +345,198 @@ EOF
    ```
    💡 You'll want to logout / exit any terminal sessions to pick up changes.

    # Browser
    ## Librewolf
    **A Firefox fork...** To quote [Librewolf's](https://librewolf.net/) website: "A custom version of Firefox, focused on privacy, security and freedom."
    # tmux
    I'm assuming `tmux` is installed system wide per the prerequisites section.
    Installing `tmux` on a per user basis inside `~/.local` is possible but outside the scope of this gist.

    ## `~/.tmux.conf`
    This gist contains a copy of my `tmux` config which may include some features you'll like including:
    * tmux-plugins/tpm - tmux plugin manager
    * tmux-plugins/tmux-sensible - sensible settings for tmux
    * arcticicestudio/nord-tmux - theme
    * Use the mouse to select panes and drag-resize panes
    * <kbd>ALT</kbd>+<kbd>PGUP</kbd> / <kbd>PGDN</kbd> to change between windows
    * <kbd>ALT</kbd>+<kbd>←</kbd> / <kbd>↑</kbd> / <kbd>→</kbd> / <kbd>↓</kbd> to change between panes
    * <kbd>prefix</kbd> <kbd>|</kbd> to split a pane vertically (pipe)
    * <kbd>prefix</kbd> <kbd>-</kbd> to split a pane horizontally (minus/hyphen/dash)
    * <kbd>prefix</kbd> <kbd><</kbd> move window left
    * <kbd>prefix</kbd> <kbd>></kbd> move window right
    * <kbd>prefix</kbd> <kbd>s</kbd> toggle pane synchronisation - typing into all panes at the same time
    * <kbd>prefix</kbd> <kbd>R</kbd> reload tmux config

    You can download the latest version of the [`.tmux.conf`](#file-tmux-conf) as follows:
    ```
    echo -n 'installing ~/.tmux.conf ... '; curl --connect-timeout 5 -sSL https://gist.github.com/kyle0r/74cd5a6046747867e521efc01997a53d/raw/.tmux.conf > ~/.tmux.conf && echo OK || echo FAILURE
    ```

    ## The `tmux` Plugin Manager aka tpm
    The [tpm project](https://github.com/tmux-plugins/tpm) is a simple way to manage `tmux` plugins.

    ```
    git clone --depth=1 https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
    tmux new-session '~/.tmux/plugins/tpm/scripts/install_plugins.sh'
    ```
    Now you can launch `tmux` :)

    Here is an example of how the tmux config looks like from a cygwin mintty:

    ![image](https://gist.github.com/user-attachments/assets/34a311c0-18d3-4171-8fee-10d8607f97b4)

    ### Updating plugins
    Launch `tmux` and invoke the `prefix` + <kbd>U</kbd> kbd shortcut.

    ## `xpanes`
    [`xpanes`](https://github.com/greymd/tmux-xpanes/) describes itself as "The ultimate terminal divider powered by [`tmux`](https://github.com/tmux/tmux/wiki)"

    ![enter image description here](https://raw.githubusercontent.com/wiki/greymd/tmux-xpanes/img/movie_v4.gif)

    This shell snippet will install the latest version of `xpanes` into the local bin:
    ```
    if xpanes_latest_version=$(curl --connect-timeout 5 -sSL https://api.github.com/repos/greymd/tmux-xpanes/releases/latest|grep '"tag_name":'|grep -Eo 'v[0-9\.]+'); then
    echo "xpanes latest version detected as: $xpanes_latest_version"
    echo -n 'Downloading and installing xpanes. Please wait... '
    if curl --create-dirs --connect-timeout 5 -sSL "https://raw.githubusercontent.com/greymd/tmux-xpanes/$xpanes_latest_version/bin/xpanes" -o ~/.local/bin/xpanes; then
    echo OK
    chmod +x ~/.local/bin/xpanes
    else
    echo FAILURE
    fi
    else
    echo 'There was a problem determining xpanes_latest_version'
    fi
    ```
    ### Updating `xpanes`
    Just run the snippet again in the future.

    ### `xpanes` Demo
    TODO

    # nord theme for `vim`
    We need a `vim` plugin manager for this, lets go with [`vim-plug`](https://github.com/junegunn/vim-plug). Here is a shell snippet to install `vim-plug`:
    ```
    if latest_version=$(curl --connect-timeout 5 -sSL https://api.github.com/repos/junegunn/vim-plug/releases/latest|grep '"tag_name":'|cut -d'"' -f4); then
    echo "vim-plug latest version detected as: $latest_version"
    echo -n 'Downloading and installing vim-plug. Please wait... '
    if curl --create-dirs --connect-timeout 5 -sSL "https://raw.githubusercontent.com/junegunn/vim-plug/$latest_version/plug.vim" -o ~/.vim/autoload/plug.vim; then
    echo OK
    else
    echo FAILURE
    fi
    else
    echo 'There was a problem determining xpanes_latest_version'
    fi
    ```
    A relevant `vim` config with some defaults:
    ```
    cat <<EOF >> ~/.vimrc
    " disable bracketed-paste - which prevents pasting commands into vim
    " https://en.wikipedia.org/wiki/Bracketed-paste
    " https://vimhelp.org/term.txt.html#xterm-bracketed-paste
    set t_BE=
    syntax on
    " enables support for 24-bit RGB color in terminal emulators that support it
    set termguicolors
    call plug#begin()
    " INFO: nord-vim plugin modifies formatoptions and removes t option
    " which prevents autowrapping to textwidth on paste
    Plug 'arcticicestudio/nord-vim'
    call plug#end()
    " conditional color scheme loading
    if filereadable(expand("~/.vim/plugged/nord-vim/colors/nord.vim"))
    colorscheme nord
    endif
    EOF
    ```

    Then run `vim -c 'PlugUpdate'` which will install the plugin(s) and then quit vim to finalise the install.

    I've taken Librewolf for a spin and it looks good. After a quick look at the out of the box settings, they were refreshingly privacy focused. It was a nice touch to see that Librewolf comes bundled with [uBlock Origin](https://addons.mozilla.org/firefox/addon/ublock-origin).
    Now try to edit a file, for example `vim ~/.vimrc` to see that the nord plugin/colorscheme is active.

    I'm going to trail this as my main desktop browser and drop-in replacement for Firefox. It will be interesting to see if Firefox profiles can be used in / migrated to Librewolf.
    ## Updating vim plugins
    `vim -c 'PlugUpdate'` to update plugins and `vim -c 'PlugUpgrade'` to upgrade `vim-plug` itself.

    # `fzf`
    `fzf` describes itself as "a general-purpose command-line fuzzy finder" and improves the quality of life on the terminal, enhancing things like searching shell history, changing dirs and finding files.

    This approach installs `fzf on a per user basis rather than system wide.

    To install the latest version from GitHub inspired from the official docs [here](https://github.com/junegunn/fzf?tab=readme-ov-file#using-git):

    ```
    git clone --depth=1 https://github.com/junegunn/fzf.git ~/.fzf
    # run the installer and follow the prompts
    ~/.fzf/install
    ```
    💡 You'll want to logout / exit any terminal sessions to pick up the change.

    Check out this screencast by [@samoshkin](https://github.com/samoshkin) which explores `fzf` features.

    ## Updating `fzf`
    ```
    ( cd ~/.fzf && git pull && ~/.fzf/install )
    ```

    ## Example `fzf` usage
    TODO

    # Browsers
    ## LibreWolf
    **A Firefox fork...** To quote [LibreWolf's](https://librewolf.net/) website: "A custom version of Firefox, focused on privacy, security and freedom."

    I've taken LibreWolf for a spin and it looks good. After a quick look at the out of the box settings, they were refreshingly privacy focused. It was a nice touch to see that LibreWolf comes bundled with [uBlock Origin](https://addons.mozilla.org/firefox/addon/ublock-origin).

    I'm going to trail this as my main desktop browser and drop-in replacement for Firefox. It will be interesting to see if Firefox profiles can be used in / migrated to LibreWolf.

    ### Per user install

    TODO explain the snippet:
    GPT-4o mini said
    > In summary, this script automates the process of downloading the latest LibreWolf browser release for Linux, unpacking it, and setting up a convenient symlink for easy access. It includes error handling to ensure that the user is informed if something goes wrong during the URL retrieval process.
    > In summary, this shell snippet automates the process of downloading the latest LibreWolf browser release for Linux, unpacking it, and setting up a convenient symlink for easy access. It includes error handling to ensure that the user is informed if something goes wrong during the URL retrieval process.
    ```
    if librewolf_url=$(curl --connect-timeout 5 -sSL "https://gitlab.com/api/v4/projects/librewolf-community%2Fbrowser%2Fbsys6/releases" | jq -r 'sort_by(.tag_name) | last | .assets.links[] | select(.name | test("linux-x86_64.*\\.tar\\.xz$")) | .url'); then
    mkdir -p ~/.local/bin
    echo -n 'unpacking Librewolf to ~/.local/librewolf. Please wait... '
    echo -n 'unpacking LibreWolf to ~/.local/librewolf. Please wait... '
    # cruftless download and unpack
    curl --connect-timeout 5 -sSL "$librewolf_url" | bsdtar -xf - -C ~/.local && echo OK || echo FAILURE
    # local bin symlink for Librewolf
    # local bin symlink for LibreWolf
    ln -fs ~/.local/librewolf/librewolf ~/.local/bin
    else
    echo 'There was an error determining the librewolf_url'
    fi
    ```
    💡 You'll want to logout / exit any terminal sessions to pick up changes.

    ### System wide install
    Taken from https://librewolf.net/installation/debian/
    ```
    # install external repo support
    sudo apt update && sudo apt install extrepo -y
    # enable Librewolf repo
    # enable LibreWolf repo
    sudo extrepo enable librewolf
    # system wide install of Librewolf
    # system wide install of LibreWolf
    sudo apt update && sudo apt install librewolf -y
    ```

    ## Firefox

    Mozilla structures its Firefox release process into multiple platforms, editions, and channels.
    For this demo, we are interested in the desktop platform and the various editions and channels.

    ### Per user install
    The following shell snippet will install the latest Firefox edition of your choice, for the current user. AFAIK this approach bypasses the download token that Mozilla implemented in 2020. See the privacy concerns section below.
    ```
    @@ -407,16 +555,20 @@ ff_os=linux64
    # pick an edition
    ff_edition=firefox-latest-ssl
    ff_edition=firefox-beta-latest-ssl
    ff_edition=firefox-devedition-latest-ssl
    ```
    ...
    ```
    # All-in-one as an example
    ff_locale=en-GB;ff_os=linux64;ff_edition=firefox-devedition-latest-ssl
    # As of 2025-April
    # This works as of 2025-May
    # determine the ftp edition path
    ff_ftp_edition_path=firefox
    [[ $ff_edition =~ devedition ]] && ff_ftp_edition_path=devedition
    # use the http location header to determine the latest release
    if ff_ftp_release_url=$(echo -n 'https://ftp.mozilla.org/pub/firefox/releases/'; curl --connect-timeout 5 --head -sS "https://download.mozilla.org/?product=${ff_edition}&os=${ff_os}&lang=${ff_locale}"| grep ^Location | cut -d'/' -f7- | tr -d '\r'); then
    if ff_ftp_release_url=$(echo -n "https://ftp.mozilla.org/pub/$ff_ftp_edition_path/releases/"; curl --connect-timeout 5 --head -sS "https://download.mozilla.org/?product=${ff_edition}&os=${ff_os}&lang=${ff_locale}"| grep ^Location | cut -d'/' -f7- | tr -d '\r'); then
    mkdir -p ~/.local/bin
    @@ -437,10 +589,13 @@ Read more about Mozilla's download token which is used by Firefox's telemetry fe
    You can browse the different editions/locales via an existing browser: https://www.mozilla.org/firefox/all/ but be warned, downloading from the website directly will include a download token as mentioned above.

    ### System wide install
    TODO
    TODO [[ref](https://support.mozilla.org/en-US/kb/install-firefox-linux#w_install-firefox-deb-package-for-debian-based-distributions)]

    ## Extensions for Firefox based browsers
    Firefox no longer supports sideloading/preloading extensions, so I'm not aware of a way to install extensions automatically without providing a preconfigured Firefox profile which I would not consider a best practice.
    Firefox no longer supports sideloading/preloading extensions, so I'm not aware of a way to install extensions automatically without distributing either:
    * A preconfigured Firefox profile which I would not consider a best practice.
    OR
    * A custom packaged Firefox like LibreWolf

    The next best thing is just to click the direct install links from your preferred/throwaway Firefox profile:

    @@ -507,150 +662,6 @@ sudo apt install --dry-run --fix-broken ~/Downloads/"$chrome_dl_filename"
    sudo apt install -y --fix-broken ~/Downloads/"$chrome_dl_filename"
    ```

    # tmux
    I'm assuming `tmux` is installed system wide per the prerequisites section.
    Installing `tmux` on a per user basis inside `~/.local` is possible but outside the scope of this gist.

    ## `~/.tmux.conf`
    This gist contains a copy of my `tmux` config which may include some features you'll like including:
    * tmux-plugins/tpm - tmux plugin manager
    * tmux-plugins/tmux-sensible - sensible settings for tmux
    * arcticicestudio/nord-tmux - theme
    * Use the mouse to select panes and drag-resize panes
    * <kbd>ALT</kbd>+<kbd>PGUP</kbd> / <kbd>PGDN</kbd> to change between windows
    * <kbd>ALT</kbd>+<kbd>←</kbd> / <kbd>↑</kbd> / <kbd>→</kbd> / <kbd>↓</kbd> to change between panes
    * <kbd>prefix</kbd> <kbd>|</kbd> to split a pane vertically (pipe)
    * <kbd>prefix</kbd> <kbd>-</kbd> to split a pane horizontally (minus/hyphen/dash)
    * <kbd>prefix</kbd> <kbd><</kbd> move window left
    * <kbd>prefix</kbd> <kbd>></kbd> move window right
    * <kbd>prefix</kbd> <kbd>s</kbd> toggle pane synchronisation - typing into all panes at the same time
    * <kbd>prefix</kbd> <kbd>R</kbd> reload tmux config

    You can download the latest version of the [`.tmux.conf`](#file-tmux-conf) as follows:
    ```
    echo -n 'installing ~/.tmux.conf ... '; curl --connect-timeout 5 -sSL https://gist.github.com/kyle0r/74cd5a6046747867e521efc01997a53d/raw/.tmux.conf > ~/.tmux.conf && echo OK || echo FAILURE
    ```

    ## The `tmux` Plugin Manager aka tpm
    The [tpm project](https://github.com/tmux-plugins/tpm) is a simple way to manage `tmux` plugins.

    ```
    git clone --depth=1 https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
    tmux new-session '~/.tmux/plugins/tpm/scripts/install_plugins.sh'
    ```
    Now you can launch `tmux` :)

    Here is an example of how the tmux config looks like from a cygwin mintty:

    ![image](https://gist.github.com/user-attachments/assets/34a311c0-18d3-4171-8fee-10d8607f97b4)

    ### Updating plugins
    Launch `tmux` and invoke the `prefix` + <kbd>U</kbd> kbd shortcut.

    ## `xpanes`
    [`xpanes`](https://github.com/greymd/tmux-xpanes/) describes itself as "The ultimate terminal divider powered by [`tmux`](https://github.com/tmux/tmux/wiki)"

    ![enter image description here](https://raw.githubusercontent.com/wiki/greymd/tmux-xpanes/img/movie_v4.gif)

    This shell snippet will install the latest version of `xpanes` into the local bin:
    ```
    if xpanes_latest_version=$(curl --connect-timeout 5 -sSL https://api.github.com/repos/greymd/tmux-xpanes/releases/latest|grep '"tag_name":'|grep -Eo 'v[0-9\.]+'); then
    echo "xpanes latest version detected as: $xpanes_latest_version"
    echo -n 'Downloading and installing xpanes. Please wait... '
    if curl --create-dirs --connect-timeout 5 -sSL "https://raw.githubusercontent.com/greymd/tmux-xpanes/$xpanes_latest_version/bin/xpanes" -o ~/.local/bin/xpanes; then
    echo OK
    chmod +x ~/.local/bin/xpanes
    else
    echo FAILURE
    fi
    else
    echo 'There was a problem determining xpanes_latest_version'
    fi
    ```
    ### Updating `xpanes`
    Just run the snippet again in the future.

    ### `xpanes` Demo
    TODO

    # nord theme for `vim`
    We need a `vim` plugin manager for this, lets go with [`vim-plug`](https://github.com/junegunn/vim-plug). Here is a shell snippet to install `vim-plug`:
    ```
    if latest_version=$(curl --connect-timeout 5 -sSL https://api.github.com/repos/junegunn/vim-plug/releases/latest|grep '"tag_name":'|cut -d'"' -f4); then
    echo "vim-plug latest version detected as: $latest_version"
    echo -n 'Downloading and installing vim-plug. Please wait... '
    if curl --create-dirs --connect-timeout 5 -sSL "https://raw.githubusercontent.com/junegunn/vim-plug/$latest_version/plug.vim" -o ~/.vim/autoload/plug.vim; then
    echo OK
    else
    echo FAILURE
    fi
    else
    echo 'There was a problem determining xpanes_latest_version'
    fi
    ```
    A relevant `vim` config with some defaults:
    ```
    cat <<EOF >> ~/.vimrc
    " disable bracketed-paste - which prevents pasting commands into vim
    " https://en.wikipedia.org/wiki/Bracketed-paste
    " https://vimhelp.org/term.txt.html#xterm-bracketed-paste
    set t_BE=
    syntax on
    " enables support for 24-bit RGB color in terminal emulators that support it
    set termguicolors
    call plug#begin()
    " INFO: nord-vim plugin modifies formatoptions and removes t option
    " which prevents autowrapping to textwidth on paste
    Plug 'arcticicestudio/nord-vim'
    call plug#end()
    " conditional color scheme loading
    if filereadable(expand("~/.vim/plugged/nord-vim/colors/nord.vim"))
    colorscheme nord
    endif
    EOF
    ```

    Then run `vim -c 'PlugUpdate'` which will install the plugin(s) and then quit vim to finalise the install.

    Now try to edit a file, for example `vim ~/.vimrc` to see that the nord plugin/colorscheme is active.

    ## Updating vim plugins
    `vim -c 'PlugUpdate'` to update plugins and `vim -c 'PlugUpgrade'` to upgrade `vim-plug` itself.

    # `fzf`
    `fzf` describes itself as "a general-purpose command-line fuzzy finder" and improves the quality of life on the terminal, enhancing things like searching shell history, changing dirs and finding files.

    This approach installs `fzf on a per user basis rather than system wide.

    To install the latest version from GitHub inspired from the official docs [here](https://github.com/junegunn/fzf?tab=readme-ov-file#using-git):

    ```
    git clone --depth=1 https://github.com/junegunn/fzf.git ~/.fzf
    # run the installer and follow the prompts
    ~/.fzf/install
    ```
    💡 You'll want to logout / exit any terminal sessions to pick up the change.

    Check out this screencast by [@samoshkin](https://github.com/samoshkin) which explores `fzf` features.

    ## Updating `fzf`
    ```
    ( cd ~/.fzf && git pull && ~/.fzf/install )
    ```

    ## Example `fzf` usage
    TODO

    # Sublime Text
    [Sublime Text](https://www.sublimetext.com/) as its name suggests is extremely good. Back in ~2008 creator Jon Skinner had some really novel ideas on improving UI/UX and Sublime introduced and made the Command Palette popular which other apps have since implemented their own flavours of. I remember trying the early versions and being blown away by it.

    @@ -804,4 +815,3 @@ sudo apt update && sudo apt install -y --fix-broken ~/Downloads/bcompare-5.0.7.3
    ```



  6. kyle0r revised this gist May 4, 2025. 3 changed files with 46 additions and 5 deletions.
    24 changes: 21 additions & 3 deletions A containerised Linux desktop env setup.md
    Original file line number Diff line number Diff line change
    @@ -91,7 +91,7 @@ apt install -y mawk aptitude molly-guard needrestart bash-completion sudo curl v
    # 💡👇 The following will install lots of deps required for the desktop env
    # It will also prompt you to setup the keyboard
    apt install -y xrdp mate-desktop-environment
    apt install -y xrdp mate-desktop-environment xclip
    # choose an editor
    update-alternatives --config editor
    @@ -146,8 +146,18 @@ cp -a ~root/.ssh $(eval echo ~"$demouser")/.ssh && chown -R "$demouser": "$_"
    cat <<'EOF' | sudo -u "$demouser" sh
    cat <<'SH' >> ~/.Xresources
    XTerm*selectToClipboard: true
    UXTerm*selectToClipboard: true
    XTerm*faceName: monospace
    UXTerm*faceName: monospace
    XTerm*faceSize: 14
    UXTerm*faceSize: 14
    SH
    EOF
    # function to remove CR from the clipboard
    cat <<'EOF' | sudo -u "$demouser" sh
    cat <<'SH' >> ~/.bash_aliases
    clipclean() { xclip -o -selection clipboard | tr -d '\r' | xclip -i -selection clipboard; }
    SH
    EOF
    @@ -282,6 +292,8 @@ I suggest to create a launcher which invokes `xterm -ls` which will launch `xter

    One reason this is important, is that the profile contains the setup for things like the users `~/.local/bin`

    💡 **`xterm` vs. `uxterm`** for improved unicode support, you may wish to use `uxterm` rather than `xterm`.

    💡 **Cosmetic paste issue** It looks like there is a **cosmetic** paste bug in `xterm`. If the paste is larger/more than the visible terminal rows, then the terminal doesn't scroll to accommodate the paste, so it looks like the paste has become malformed. From testing, the paste is fine and it is just a cosmetic issue. I was not able to tune this out via `xterm` config options. If you know how to fix it please leave a comment.

    ## `xterm` Nord theme
    @@ -305,21 +317,27 @@ The following snippet will setup some sensible defaults for `xterm` and merge t
    cat <<'EOF' > ~/.Xresources && xrdb -merge ~/.Xresources || echo 'FAILURE'
    ! font cfg
    XTerm*faceName: SourceCodePro-Medium
    UXTerm*faceName: SourceCodePro-Medium
    XTerm*faceSize: 14
    UXTerm*faceSize: 14
    ! color support
    XTerm*termName: xterm-256color
    UXTerm*termName: xterm-256color
    XTerm*colorMode: true
    UXTerm*colorMode: true
    ! selections in the terminal are automatically copied to the clipboard
    XTerm*selectToClipboard: true
    UXTerm*selectToClipboard: true
    ! the Meta key (e.g. Alt key) sends an escape sequence e.g. ALT+B and ALT+F
    ! For example:
    ! ALT+B moves the cursor backwards by one word
    ! ALT+F moves the cursor forwards by one word
    ! ref: https://github.com/kyle0r/bash-shortcuts-cheat-sheet
    XTerm*metaSendsEscape: true
    UXTerm*metaSendsEscape: true
    ! testing suggests pwd is ~
    #include ".config/xterm/themes/nord"
    @@ -510,7 +528,7 @@ This gist contains a copy of my `tmux` config which may include some features yo

    You can download the latest version of the [`.tmux.conf`](#file-tmux-conf) as follows:
    ```
    echo 'installing ~/.tmux.conf ... '; curl --connect-timeout 5 -sSL https://gist.github.com/kyle0r/74cd5a6046747867e521efc01997a53d/raw/.tmux.conf > ~/.tmux.conf && echo OK || echo FAILURE
    echo -n 'installing ~/.tmux.conf ... '; curl --connect-timeout 5 -sSL https://gist.github.com/kyle0r/74cd5a6046747867e521efc01997a53d/raw/.tmux.conf > ~/.tmux.conf && echo OK || echo FAILURE
    ```

    ## The `tmux` Plugin Manager aka tpm
    @@ -667,7 +685,7 @@ Here is an example shell snippet from the time of writing:
    curl --connect-timeout 5 -sSL 'https://download.sublimetext.com/sublime_text_build_4192_x64.tar.xz' |
    bsdtar -xf - -C ~/.local && ln -s ~/.local/sublime_text/sublime_text ~/.local/bin/subl
    ```
    If successful, you should now be able to invoke `sublime_text` in the terminal.
    If successful, you should now be able to invoke `subl` in the terminal.

    ## System wide install
    Tweaked from https://www.sublimetext.com/docs/linux_repositories.html#apt
    2 changes: 1 addition & 1 deletion .gitattributes
    Original file line number Diff line number Diff line change
    @@ -1 +1 @@
    * text eol=lf
    * text=auto
    25 changes: 24 additions & 1 deletion xterm-nord-theme
    Original file line number Diff line number Diff line change
    @@ -24,6 +24,12 @@ XTerm*cursorColor: nord4
    XTerm*fading: 35
    XTerm*fadeColor: nord3

    UXTerm*foreground: nord4
    UXTerm*background: nord0
    UXTerm*cursorColor: nord4
    UXTerm*fading: 35
    UXTerm*fadeColor: nord3

    XTerm*color0: nord1
    XTerm*color1: nord11
    XTerm*color2: nord14
    @@ -39,4 +45,21 @@ XTerm*color11: nord13
    XTerm*color12: nord9
    XTerm*color13: nord15
    XTerm*color14: nord7
    XTerm*color15: nord6
    XTerm*color15: nord6

    UXTerm*color0: nord1
    UXTerm*color1: nord11
    UXTerm*color2: nord14
    UXTerm*color3: nord13
    UXTerm*color4: nord9
    UXTerm*color5: nord15
    UXTerm*color6: nord8
    UXTerm*color7: nord5
    UXTerm*color8: nord3
    UXTerm*color9: nord11
    UXTerm*color10: nord14
    UXTerm*color11: nord13
    UXTerm*color12: nord9
    UXTerm*color13: nord15
    UXTerm*color14: nord7
    UXTerm*color15: nord6
  7. kyle0r revised this gist May 4, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion .gitattributes
    Original file line number Diff line number Diff line change
    @@ -1 +1 @@
    * text=auto
    * text eol=lf
  8. kyle0r revised this gist May 4, 2025. 1 changed file with 33 additions and 16 deletions.
    49 changes: 33 additions & 16 deletions A containerised Linux desktop env setup.md
    Original file line number Diff line number Diff line change
    @@ -37,7 +37,7 @@ hypervisor_storage=sas-zfs-nocrypt
    # procure CT template
    sudo pveam download "$template_storage" debian-12-standard_12.7-1_amd64.tar.zst
    # determine the proxmox host - this assumes the first / a signular host setup
    # determine the proxmox host - this assumes the first / a singular host setup
    h=$(pvesh ls --output-format=json nodes | jq -r '.[0].name')
    # determine the next free vmid
    next_vmid=$(( $(cat <(sudo pvesh get /nodes/"$h"/lxc --output-format=json | jq -r '.[].vmid') <(sudo pvesh get /nodes/"$h"/qemu --output-format=json | jq -r '.[].vmid') | sort | tail -n1) + 1 ))
    @@ -62,14 +62,17 @@ sudo pct create "$next_vmid" "$template_storage":vztmpl/debian-12-standard_12.7-
    # make a note of the dhcp ip
    sudo pct exec "$next_vmid" -- hostname -I
    ```

    Now to run commands on the CT, **from the hypervisor terminal:**
    ```
    # note that: sudo pct enter "$next_vmid # does not provide login shell
    # enter the CT with root login shell
    sudo pct exec "$next_vmid" -- /bin/bash -l
    # Sanity check that you entered the CT and are not on the hypervisor
    hostname -f
    hostname
    # Select the locales to generate for the CT and set a system-wide default if desired.
    dpkg-reconfigure locales
    @@ -80,13 +83,15 @@ net.ipv6.conf.all.disable_ipv6 = 1
    net.ipv6.conf.default.disable_ipv6 = 1
    EOF
    # upgrade the CT
    # update and upgrade the CT packages
    apt update && apt full-upgrade -y
    # install aptitude which offers enhanced options and conflict resolution
    apt install -y aptitude
    # 👇 The following will install lots of deps required for the desktop env
    # 💡 It will also prompt you to setup the keyboard
    aptitude install -y awk molly-guard needrestart xrdp mate-desktop-environment bash-completion sudo curl vim
    # some misc sensible/required packages
    apt install -y mawk aptitude molly-guard needrestart bash-completion sudo curl vim
    # 💡👇 The following will install lots of deps required for the desktop env
    # It will also prompt you to setup the keyboard
    apt install -y xrdp mate-desktop-environment
    # choose an editor
    update-alternatives --config editor
    @@ -118,7 +123,7 @@ EOF
    sudo pct exec "$next_vmid" -- /bin/bash -l
    # Sanity check that you entered the CT and are not on the hypervisor
    hostname -f
    hostname
    # check you are happy with the keyboard and locale config, adjust as required
    localectl status; echo "value of /etc/default/locale: $(</etc/default/locale)"
    @@ -131,12 +136,19 @@ passwd "$demouser"
    # if you'd like to give the demo user sudo rights
    usermod --append --groups sudo "$demouser"
    # you may wish to modify the suoders config to set NOPASSWD for the sudo group
    # OPTIONAL: you may wish to modify the suoders config to set NOPASSWD for the sudo group
    visudo
    # enable copy/paste for xterm required for future steps
    # OPTIONAL: copy the ssh config to the demo user
    cp -a ~root/.ssh $(eval echo ~"$demouser")/.ssh && chown -R "$demouser": "$_"
    # enable copy/paste in xterm required for future steps, and a legible font size
    cat <<'EOF' | sudo -u "$demouser" sh
    echo 'XTerm*selectToClipboard: true' >> ~/.Xresources
    cat <<'SH' >> ~/.Xresources
    XTerm*selectToClipboard: true
    XTerm*faceName: monospace
    XTerm*faceSize: 14
    SH
    EOF
    exit # logout from the CT termminal
    @@ -147,11 +159,14 @@ Simple steps to test ssh and setup pub key auth for op-demo user
    ```
    # setup auth, replace <dhcp_ip> and <key> with your values
    dhcp_ip=<dhcp_ip>; ssh_key=~/.ssh/<key>
    # OPTIONAL: if needed, set up public key auth
    ssh-copy-id -i "$ssh_key" op-demo@"$dhcp_ip"
    # connect
    ssh op-demo@"$dhcp_ip"
    hostname -f
    hostname
    ```

    # CT GUI Login
    @@ -175,7 +190,7 @@ OK, now its time to setup the demo user and install the following prerequisites:

    **From the CT terminal:**
    ```
    sudo aptitude install -y tmux git libarchive-tools jq
    sudo apt install -y tmux git libarchive-tools jq
    ```
    ## Keyboard map
    ### Per user
    @@ -206,6 +221,8 @@ Generating locales and optionally setting the system default locale is easy via
    Adding locales can be automated by manipulating `/etc/locale.gen` and invoking `locale-gen` and `update-locale` but I'm leaving it out of scope for this gist. Ask a GenAI or perform a web search if you are interested in further details. DYOR - YMMV!

    ### Per user
    Check the current users locale settings by invoking the `locale` command.

    If a user doesn't specify their own locale in their shell profile or rc files, the system default `/etc/default/locale` will be used. If the system default is not set, there will be a fall back to an unspecified default, typically the `C` locale.

    In case you want to perform this for a specific user (or don't have sudo rights) then use the `locale -a` to list which locales are available and then set one by invoking `LC_ALL=<locale>` where `<locale>` is your preferred locale. For example `LC_ALL=en_GB.UTF-8`.
    @@ -272,7 +289,7 @@ Nord is a beautiful color palette for text editors and terminals (any many other

    You can download the latest version of the [xterm nord theme](#file-xterm-nord-theme) as follows:
    ```
    curl --connect-timeout 5 --create-dirs -sSL https://gist.github.com/kyle0r/74cd5a6046747867e521efc01997a53d/raw/xterm-nord-theme -o ~/.config/xterm/themes/nord
    echo -n 'xterm-nord-theme install... '; curl --connect-timeout 5 --create-dirs -sSL https://gist.github.com/kyle0r/74cd5a6046747867e521efc01997a53d/raw/xterm-nord-theme -o ~/.config/xterm/themes/nord && echo OK || echo FAILURE
    ```
    I sourced this file from the [nordtheme/xresources](https://github.com/nordtheme/xresources) git repo and made simple adjustments to make it work on the version of `xterm` in the CT.

    @@ -493,7 +510,7 @@ This gist contains a copy of my `tmux` config which may include some features yo

    You can download the latest version of the [`.tmux.conf`](#file-tmux-conf) as follows:
    ```
    curl --connect-timeout 5 -sSL https://gist.github.com/kyle0r/74cd5a6046747867e521efc01997a53d/raw/.tmux.conf > ~/.tmux.conf
    echo 'installing ~/.tmux.conf ... '; curl --connect-timeout 5 -sSL https://gist.github.com/kyle0r/74cd5a6046747867e521efc01997a53d/raw/.tmux.conf > ~/.tmux.conf && echo OK || echo FAILURE
    ```

    ## The `tmux` Plugin Manager aka tpm
  9. kyle0r revised this gist May 1, 2025. 3 changed files with 66 additions and 56 deletions.
    79 changes: 23 additions & 56 deletions A containerised Linux desktop env setup.md
    Original file line number Diff line number Diff line change
    @@ -2,12 +2,12 @@
    # A containerised Linux desktop env setup
    This gist is currently a Work In Progress.

    These steps were practised and performed on a Debian Bookworm container and Proxmox 8.x Hypervisor. Instructions may vary for other releases/distros. Please DYOR and observe that YMMV. Comments, ideas and critique very welcome.

    This post is effectively a tech demo. I hope you enjoy and take away something useful.
    These steps were practised and performed on a Debian Bookworm container and Proxmox 8.x Hypervisor (Debian). Instructions may vary for other releases/distros. Please DYOR and observe that YMMV. Comments, ideas and critique very welcome.

    There will be a screencast performing a speed run of the topics.

    This gist is effectively a tech demo. I hope you enjoy and take away something useful.

    The objective with most of the topics is to show ways / introduce tooling to boost productivity and the quality of our daily lives working in tech.

    # TODO
    @@ -19,7 +19,6 @@ xrdp-chansrv[430]: [INFO ] Detected remote smartcard 'SCARD'
    ```
    ---
    * Add a TOC
    * Add ~/.config/xterm/themes/nord as a file, and add curl call

    # Creating a Proxmox CT
    Depends on the `jq` command. Perform the following **from the hypervisor terminal:**
    @@ -268,60 +267,22 @@ One reason this is important, is that the profile contains the setup for things

    💡 **Cosmetic paste issue** It looks like there is a **cosmetic** paste bug in `xterm`. If the paste is larger/more than the visible terminal rows, then the terminal doesn't scroll to accommodate the paste, so it looks like the paste has become malformed. From testing, the paste is fine and it is just a cosmetic issue. I was not able to tune this out via `xterm` config options. If you know how to fix it please leave a comment.

    ## Nord theme
    ```
    mkdir -p ~/.config/xterm/themes
    cat <<'EOF' > ~/.config/xterm/themes/nord
    ! Copyright (c) 2016-present Sven Greb <[email protected]>
    ! This source code is licensed under the MIT license found in the license file.
    #define nord0 #2E3440
    #define nord1 #3B4252
    #define nord2 #434C5E
    #define nord3 #4C566A
    #define nord4 #D8DEE9
    #define nord5 #E5E9F0
    #define nord6 #ECEFF4
    #define nord7 #8FBCBB
    #define nord8 #88C0D0
    #define nord9 #81A1C1
    #define nord10 #5E81AC
    #define nord11 #BF616A
    #define nord12 #D08770
    #define nord13 #EBCB8B
    #define nord14 #A3BE8C
    #define nord15 #B48EAD
    XTerm*foreground: nord4
    XTerm*background: nord0
    XTerm*cursorColor: nord4
    XTerm*fading: 35
    XTerm*fadeColor: nord3
    XTerm*color0: nord1
    XTerm*color1: nord11
    XTerm*color2: nord14
    XTerm*color3: nord13
    XTerm*color4: nord9
    XTerm*color5: nord15
    XTerm*color6: nord8
    XTerm*color7: nord5
    XTerm*color8: nord3
    XTerm*color9: nord11
    XTerm*color10: nord14
    XTerm*color11: nord13
    XTerm*color12: nord9
    XTerm*color13: nord15
    XTerm*color14: nord7
    XTerm*color15: nord6
    EOF
    ## `xterm` Nord theme
    Nord is a beautiful color palette for text editors and terminals (any many other ports). Check out the details on [nordtheme.com](https://www.nordtheme.com).

    You can download the latest version of the [xterm nord theme](#file-xterm-nord-theme) as follows:
    ```
    curl --connect-timeout 5 --create-dirs -sSL https://gist.github.com/kyle0r/74cd5a6046747867e521efc01997a53d/raw/xterm-nord-theme -o ~/.config/xterm/themes/nord
    ```
    I sourced this file from the [nordtheme/xresources](https://github.com/nordtheme/xresources) git repo and made simple adjustments to make it work on the version of `xterm` in the CT.

    ## `xterm` config

    The following snippet will setup some reasonable defaults for `xterm` and merge the changes into the X resource database.
    The following snippet will setup some sensible defaults for `xterm` and merge the changes into the X resource database. The config will:

    * Activate the SourceCodePro font
    * Activate the Nord theme published above
    * Set some sensible defaults

    ```
    cat <<'EOF' > ~/.Xresources && xrdb -merge ~/.Xresources || echo 'FAILURE'
    @@ -343,7 +304,7 @@ XTerm*selectToClipboard: true
    ! ref: https://github.com/kyle0r/bash-shortcuts-cheat-sheet
    XTerm*metaSendsEscape: true
    ! testing suggestions pwd is ~
    ! testing suggests pwd is ~
    #include ".config/xterm/themes/nord"
    EOF
    @@ -530,7 +491,7 @@ This gist contains a copy of my `tmux` config which may include some features yo
    * <kbd>prefix</kbd> <kbd>s</kbd> toggle pane synchronisation - typing into all panes at the same time
    * <kbd>prefix</kbd> <kbd>R</kbd> reload tmux config

    You can download the version of the [`.tmux.conf`](#file-tmux-conf) as follows:
    You can download the latest version of the [`.tmux.conf`](#file-tmux-conf) as follows:
    ```
    curl --connect-timeout 5 -sSL https://gist.github.com/kyle0r/74cd5a6046747867e521efc01997a53d/raw/.tmux.conf > ~/.tmux.conf
    ```
    @@ -719,7 +680,10 @@ Manually:
    ```
    3) Start Sublime and either inspect the console log or look for **Package** entries in the Command Palette

    Here is a collection of some of the packages which I find extremely useful / productive:
    <details>

    <summary><strong>Click here</strong> to see a selection of packages which I find extremely useful / productive:</summary>

    ### CodeFormatter
    by Avtandil Kikabidze aka LONGMAN https://packagecontrol.io/packages/CodeFormatter
    Formats (beautifies) source code and supports various languages including PHP, JavaScript, JSON, HTML, Python ...
    @@ -779,6 +743,8 @@ Versatile and comprehensive XPath 1.0 package for processing HTML and XML with x

    ![enter image description here](https://cloud.githubusercontent.com/assets/11882719/12841929/245cdbd4-cbf8-11e5-8da0-26119e5213ab.gif)

    </details>

    # Beyond Compare
    A similar story to text editors... I've used a number of text/file comparison and merge tools over the years. Beyond Compare is hands down the best I've tried to date and I've purchased a number of licences over the years both personally and in the enterprise, to support its great team and further development.

    @@ -803,3 +769,4 @@ sudo apt update && sudo apt install -y --fix-broken ~/Downloads/bcompare-5.0.7.3
    ```



    1 change: 1 addition & 0 deletions .gitattributes
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    * text=auto
    42 changes: 42 additions & 0 deletions xterm-nord-theme
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,42 @@
    ! Copyright (c) 2016-present Sven Greb <[email protected]>
    ! This source code is licensed under the MIT license found in the license file.

    #define nord0 #2E3440
    #define nord1 #3B4252
    #define nord2 #434C5E
    #define nord3 #4C566A
    #define nord4 #D8DEE9
    #define nord5 #E5E9F0
    #define nord6 #ECEFF4
    #define nord7 #8FBCBB
    #define nord8 #88C0D0
    #define nord9 #81A1C1
    #define nord10 #5E81AC
    #define nord11 #BF616A
    #define nord12 #D08770
    #define nord13 #EBCB8B
    #define nord14 #A3BE8C
    #define nord15 #B48EAD

    XTerm*foreground: nord4
    XTerm*background: nord0
    XTerm*cursorColor: nord4
    XTerm*fading: 35
    XTerm*fadeColor: nord3

    XTerm*color0: nord1
    XTerm*color1: nord11
    XTerm*color2: nord14
    XTerm*color3: nord13
    XTerm*color4: nord9
    XTerm*color5: nord15
    XTerm*color6: nord8
    XTerm*color7: nord5
    XTerm*color8: nord3
    XTerm*color9: nord11
    XTerm*color10: nord14
    XTerm*color11: nord13
    XTerm*color12: nord9
    XTerm*color13: nord15
    XTerm*color14: nord7
    XTerm*color15: nord6
  10. kyle0r revised this gist May 1, 2025. 1 changed file with 25 additions and 20 deletions.
    45 changes: 25 additions & 20 deletions A containerised Linux desktop env setup.md
    Original file line number Diff line number Diff line change
    @@ -18,7 +18,8 @@ Does xrdp support USB key pass-through/auth?
    xrdp-chansrv[430]: [INFO ] Detected remote smartcard 'SCARD'
    ```
    ---
    * Standardise the `--connect-timeout` for `curl` invocations.
    * Add a TOC
    * Add ~/.config/xterm/themes/nord as a file, and add curl call

    # Creating a Proxmox CT
    Depends on the `jq` command. Perform the following **from the hypervisor terminal:**
    @@ -71,7 +72,7 @@ sudo pct exec "$next_vmid" -- /bin/bash -l
    # Sanity check that you entered the CT and are not on the hypervisor
    hostname -f
    # Pick locales to generate for the CT and if desired set a system-wide default
    # Select the locales to generate for the CT and set a system-wide default if desired.
    dpkg-reconfigure locales
    # OPTIONAL: disable IPv6 to simplify the localnet IP stack
    @@ -80,16 +81,18 @@ net.ipv6.conf.all.disable_ipv6 = 1
    net.ipv6.conf.default.disable_ipv6 = 1
    EOF
    # upgrade the CT
    apt update && apt full-upgrade -y
    apt install -y aptitude # offers enhanced options and conflict resolution
    # install aptitude which offers enhanced options and conflict resolution
    apt install -y aptitude
    # 👇 The following will install lots of deps required for the desktop env
    # It will also prompt you to setup the keyboard
    # 💡 It will also prompt you to setup the keyboard
    aptitude install -y awk molly-guard needrestart xrdp mate-desktop-environment bash-completion sudo curl vim
    # choose an editor
    update-alternatives --config editor
    # Fix a bug with xrdp where the service user cannot read the private key causing TLS is be disabled.
    # Fix a bug with xrdp where the service user cannot read the private key causing TLS to be disabled.
    # journal: Cannot accept TLS connections because certificate or private key file is not readable
    mkdir -p /etc/systemd/system/xrdp-sesman.service.d
    cat <<EOF > /etc/systemd/system/xrdp-sesman.service.d/99-ssl-key-fix.conf
    @@ -141,9 +144,10 @@ exit # logout from the CT termminal
    ```

    # CT `ssh` login
    Simple steps to test ssh and setup pub key auth for op-demo user
    ```
    # setup auth
    dhcp_ip=192.168.169.38; ssh_key=~/.ssh/id_ed25519
    # setup auth, replace <dhcp_ip> and <key> with your values
    dhcp_ip=<dhcp_ip>; ssh_key=~/.ssh/<key>
    ssh-copy-id -i "$ssh_key" op-demo@"$dhcp_ip"
    # connect
    ssh op-demo@"$dhcp_ip"
    @@ -360,13 +364,13 @@ TODO explain the snippet:
    GPT-4o mini said
    > In summary, this script automates the process of downloading the latest LibreWolf browser release for Linux, unpacking it, and setting up a convenient symlink for easy access. It includes error handling to ensure that the user is informed if something goes wrong during the URL retrieval process.
    ```
    if librewolf_url=$(curl -sSL "https://gitlab.com/api/v4/projects/librewolf-community%2Fbrowser%2Fbsys6/releases" | jq -r 'sort_by(.tag_name) | last | .assets.links[] | select(.name | test("linux-x86_64.*\\.tar\\.xz$")) | .url'); then
    if librewolf_url=$(curl --connect-timeout 5 -sSL "https://gitlab.com/api/v4/projects/librewolf-community%2Fbrowser%2Fbsys6/releases" | jq -r 'sort_by(.tag_name) | last | .assets.links[] | select(.name | test("linux-x86_64.*\\.tar\\.xz$")) | .url'); then
    mkdir -p ~/.local/bin
    echo -n 'unpacking Librewolf to ~/.local/librewolf. Please wait... '
    # cruftless download and unpack
    curl -sSL "$librewolf_url" | bsdtar -xf - -C ~/.local && echo OK || echo FAILURE
    curl --connect-timeout 5 -sSL "$librewolf_url" | bsdtar -xf - -C ~/.local && echo OK || echo FAILURE
    # local bin symlink for Librewolf
    ln -fs ~/.local/librewolf/librewolf ~/.local/bin
    @@ -416,20 +420,21 @@ ff_locale=en-GB;ff_os=linux64;ff_edition=firefox-devedition-latest-ssl
    # As of 2025-April
    # use the http location header to determine the latest release
    if ff_ftp_release_url=$(echo -n 'https://ftp.mozilla.org/pub/firefox/releases/'; curl --head -sS "https://download.mozilla.org/?product=${ff_edition}&os=${ff_os}&lang=${ff_locale}"| grep ^Location | cut -d'/' -f7- | tr -d '\r'); then
    if ff_ftp_release_url=$(echo -n 'https://ftp.mozilla.org/pub/firefox/releases/'; curl --connect-timeout 5 --head -sS "https://download.mozilla.org/?product=${ff_edition}&os=${ff_os}&lang=${ff_locale}"| grep ^Location | cut -d'/' -f7- | tr -d '\r'); then
    mkdir -p ~/.local/bin
    echo 'unpacking Firefox to ~/.local/firefox. Please wait...'
    # cruftless download and unpack
    curl -sSL "$ff_ftp_release_url" | bsdtar -xf - -C ~/.local && echo OK || echo FAILURE
    curl --connect-timeout 5 -sSL "$ff_ftp_release_url" | bsdtar -xf - -C ~/.local && echo OK || echo FAILURE
    # local bin symlink for Firefox
    ln -fs ~/.local/firefox/firefox ~/.local/bin
    else
    echo 'There was an error determining the ff_ftp_release_url'
    fi
    ```

    ### Firefox privacy concerns
    Read more about Mozilla's download token which is used by Firefox's telemetry feature: [[ref](https://redd.it/vitjny)] [[ref](https://bugzilla.mozilla.org/show_bug.cgi?id=1677497)] [[ref](https://www.privacyguides.org/en/desktop-browsers/#firefox)]. AFAIK downloads from the Firefox releases repo, originally their ftp, now hosted on a CDN, does NOT contain a download token.

    @@ -497,7 +502,7 @@ For this you can research projects like [OpenSnitch](https://github.com/evilsock
    ```
    # download latest Chrome
    chrome_dl_filename=google-chrome-stable_current_"$(dpkg --print-architecture)".deb
    curl -sSL https://dl.google.com/linux/direct/$chrome_dl_filename > ~/Downloads/"$chrome_dl_filename"
    curl --connect-timeout 5 -sSL https://dl.google.com/linux/direct/$chrome_dl_filename > ~/Downloads/"$chrome_dl_filename"
    # dry-run the install to check if you are happy with the install plan
    sudo apt install --dry-run --fix-broken ~/Downloads/"$chrome_dl_filename"
    @@ -681,15 +686,15 @@ As of 2025-April direct downloads are available via https://www.sublimetext.com/

    Here is an example shell snippet from the time of writing:
    ```
    curl -sSL 'https://download.sublimetext.com/sublime_text_build_4192_x64.tar.xz' |
    curl --connect-timeout 5 -sSL 'https://download.sublimetext.com/sublime_text_build_4192_x64.tar.xz' |
    bsdtar -xf - -C ~/.local && ln -s ~/.local/sublime_text/sublime_text ~/.local/bin/subl
    ```
    If successful, you should now be able to invoke `sublime_text` in the terminal.

    ## System wide install
    Tweaked from https://www.sublimetext.com/docs/linux_repositories.html#apt
    ```
    curl -sSL https://download.sublimetext.com/sublimehq-pub.gpg | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/sublimehq-archive.gpg > /dev/null
    curl --connect-timeout 5 -sSL https://download.sublimetext.com/sublimehq-pub.gpg | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/sublimehq-archive.gpg > /dev/null
    echo "deb https://download.sublimetext.com/ apt/stable/" | sudo tee /etc/apt/sources.list.d/sublime-text.list
    @@ -710,12 +715,12 @@ Manually:
    1) Exit Sublime
    2) Install via `curl`
    ```
    curl -sSL 'https://packagecontrol.io/Package%20Control.sublime-package' > "~/.config/sublime-text/Installed Packages/Package Control.sublime-package"
    curl --connect-timeout 5 -sSL 'https://packagecontrol.io/Package%20Control.sublime-package' > "~/.config/sublime-text/Installed Packages/Package Control.sublime-package"
    ```
    3) Start Sublime and either inspect the console log or look for **Package** entries in the Command Palette

    Here is a collection of some of the packages which I find extremely useful / productive:
    ### Code​Formatter
    ### CodeFormatter
    by Avtandil Kikabidze aka LONGMAN https://packagecontrol.io/packages/CodeFormatter
    Formats (beautifies) source code and supports various languages including PHP, JavaScript, JSON, HTML, Python ...

    @@ -735,21 +740,21 @@ I use this ALOT. Amazing package!

    ![enter image description here](https://github.com/davidpeckham/sublime-filterlines/raw/master/filter_lines_demo.gif)

    ### Filter​Pipes
    ### FilterPipes
    by tylerl https://packagecontrol.io/packages/FilterPipes
    A very useful package and similar to `:%!<command>` in `vim` filtering/piping the buffer/file through a command and replacing the buffer with the output.

    ![enter image description here](https://raw.githubusercontent.com/tylerl/FilterPipes/media/fp_sort.gif)

    ### Neo​Vintageous
    ### NeoVintageous
    by NeoVintageous https://packagecontrol.io/packages/NeoVintageous
    A powerful `vim` emulator for Sublime Text. Designed to be fast, reliable, and with zero configuration required.

    ### Rsync SSH
    by davidolrik https://packagecontrol.io/packages/Rsync%20SSH
    This package lets you keep a remote in sync with rsync, and syncs the current file on save. I don't use it that often but its been a productivity booster in the past.

    ### Select​Until
    ### SelectUntil
    by xavi- https://packagecontrol.io/packages/SelectUntil
    A real productivity booster when handling text data files.
    > This package allows you to **extend one ore more selections until the next instance of a search term,** making it super easy to select or edit multiple pieces of text that are similar but not quite the same.
    @@ -791,7 +796,7 @@ install prefix? [/home/op-demo] /home/op-demo/.local
    https://www.scootersoftware.com/kb/linux_install#debian
    ```
    # procure the .deb
    ( cd ~/Downloads; curl -sSLO 'https://www.scootersoftware.com/files/bcompare-5.0.7.30840_amd64.deb' )
    ( cd ~/Downloads; curl --connect-timeout 5 -sSLO 'https://www.scootersoftware.com/files/bcompare-5.0.7.30840_amd64.deb' )
    # install
    sudo apt update && sudo apt install -y --fix-broken ~/Downloads/bcompare-5.0.7.30840_amd64.deb
  11. kyle0r revised this gist Apr 30, 2025. 1 changed file with 6 additions and 6 deletions.
    12 changes: 6 additions & 6 deletions A containerised Linux desktop env setup.md
    Original file line number Diff line number Diff line change
    @@ -239,7 +239,7 @@ if download_url=$(curl --connect-timeout 5 -sSL https://api.github.com/repos/ado
    echo 'FAILURE'
    fi
    else
    echo 'Error determining font download_url'
    echo 'Error determining font download_url'
    fi
    ```
    More powerline fonts are available here: https://github.com/powerline/fonts
    @@ -362,7 +362,7 @@ GPT-4o mini said
    ```
    if librewolf_url=$(curl -sSL "https://gitlab.com/api/v4/projects/librewolf-community%2Fbrowser%2Fbsys6/releases" | jq -r 'sort_by(.tag_name) | last | .assets.links[] | select(.name | test("linux-x86_64.*\\.tar\\.xz$")) | .url'); then
    mkdir -p ~/.local/bin
    mkdir -p ~/.local/bin
    echo -n 'unpacking Librewolf to ~/.local/librewolf. Please wait... '
    # cruftless download and unpack
    @@ -427,7 +427,7 @@ if ff_ftp_release_url=$(echo -n 'https://ftp.mozilla.org/pub/firefox/releases/';
    # local bin symlink for Firefox
    ln -fs ~/.local/firefox/firefox ~/.local/bin
    else
    echo 'There was an error determining the ff_ftp_release_url'
    echo 'There was an error determining the ff_ftp_release_url'
    fi
    ```
    ### Firefox privacy concerns
    @@ -478,7 +478,7 @@ if download_url=$(curl --connect-timeout 5 -sSL https://api.github.com/repos/ung
    echo FAILURE
    fi
    else
    echo 'Error determining font download_url'
    echo 'Error determining font download_url'
    fi
    ```
    After install, you can launch the latest ungoogled-chromium-portablelinux by invoking `chromium` on the terminal.
    @@ -525,7 +525,7 @@ This gist contains a copy of my `tmux` config which may include some features yo
    * <kbd>prefix</kbd> <kbd>s</kbd> toggle pane synchronisation - typing into all panes at the same time
    * <kbd>prefix</kbd> <kbd>R</kbd> reload tmux config

    You can download the version of the `.tmux.conf` as follows:
    You can download the version of the [`.tmux.conf`](#file-tmux-conf) as follows:
    ```
    curl --connect-timeout 5 -sSL https://gist.github.com/kyle0r/74cd5a6046747867e521efc01997a53d/raw/.tmux.conf > ~/.tmux.conf
    ```
    @@ -556,7 +556,7 @@ This shell snippet will install the latest version of `xpanes` into the local bi
    ```
    if xpanes_latest_version=$(curl --connect-timeout 5 -sSL https://api.github.com/repos/greymd/tmux-xpanes/releases/latest|grep '"tag_name":'|grep -Eo 'v[0-9\.]+'); then
    echo "xpanes latest version detected as: $xpanes_latest_version"
    echo "xpanes latest version detected as: $xpanes_latest_version"
    echo -n 'Downloading and installing xpanes. Please wait... '
    if curl --create-dirs --connect-timeout 5 -sSL "https://raw.githubusercontent.com/greymd/tmux-xpanes/$xpanes_latest_version/bin/xpanes" -o ~/.local/bin/xpanes; then
  12. kyle0r renamed this gist Apr 30, 2025. 1 changed file with 0 additions and 0 deletions.
  13. kyle0r revised this gist Apr 30, 2025. No changes.
  14. kyle0r revised this gist Apr 30, 2025. 2 changed files with 101 additions and 30 deletions.
    84 changes: 84 additions & 0 deletions .tmux.conf
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,84 @@
    # Split panes using | and -
    bind | split-window -h
    bind - split-window -v
    unbind '"'
    unbind %

    # Reduce escape-time to 100 milliseconds
    set -sg escape-time 100

    # Reload config file (change file location to your the tmux.conf you want to use)
    bind R source-file ~/.tmux.conf \; display-message 'Configuration reloaded'

    # Fix HOME and END keys inside tmux
    # cite: https://stackoverflow.com/a/55616731
    bind-key -n Home send Escape "OH"
    bind-key -n End send Escape "OF"

    # Switch panes using Alt+arrow without prefix
    bind -n M-Left select-pane -L
    bind -n M-Right select-pane -R
    bind -n M-Up select-pane -U
    bind -n M-Down select-pane -D

    # Alt+PageUp/Down = Switch window
    bind -n M-PageUp previous-window
    bind -n M-PageDown next-window

    # prefix + < or > to move a window left or right
    #+ pressing < or > can be repeated to move a window multiple times
    #+ focus is kept on the moved window
    bind-key -r < swap-window -t - \; select-window -t -
    bind-key -r > swap-window -t + \; select-window -t +

    # Switch between current and previous (last) window à la screen
    bind-key C-b last-window

    set -g mouse on

    # Don't rename windows automatically
    set-option -g allow-rename off

    set -g history-limit 10000

    # Solves issues inside vim with the HOME and END keys
    set -g default-terminal "xterm-256color"

    # True color support
    set-option -sa terminal-overrides ",xterm*:Tc"

    # S = Synchronise panes (type into all panes at once)
    unbind s
    bind s \
    setw synchronize-panes \; \
    display "Sync #{?synchronize-panes,ON,OFF}"

    # Alt key binding to toggle sync panes.
    #+ CTRL+S - without the need for activation key first.
    #+ Downside to this is it overrides the bash CTRL+S used for "suspending" output.
    #+ I prefer the previous key binding.
    #bind -n C-S setw synchronize-panes

    # This cfg adds a visual indicator to the status-right area when sync panes is active
    set-option -g status-right "#{?pane_synchronized, #[bg=red]SYNC ON#[default],} "

    # Set to 0 if you wish nord theme to stop clobbering the status content
    set -g @nord_tmux_show_status_content "1"

    # List of plugins
    set -g @plugin 'tmux-plugins/tpm'
    set -g @plugin 'tmux-plugins/tmux-sensible'
    set -g @plugin "arcticicestudio/nord-tmux"

    # Other examples:
    # set -g @plugin 'github_username/plugin_name'
    # set -g @plugin '[email protected]/user/plugin'
    # set -g @plugin '[email protected]/user/plugin'

    # Disable the usage of patched „powerline“ styled font characters,
    #+ using normal Unicode characters instead that should be compatible
    #+ with all terminals and fonts
    #set -g @nord_tmux_no_patched_font "1"

    # Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
    run '~/.tmux/plugins/tpm/tpm'
    47 changes: 17 additions & 30 deletions A containerised Linux desktop env setup.md
    Original file line number Diff line number Diff line change
    @@ -19,8 +19,6 @@ xrdp-chansrv[430]: [INFO ] Detected remote smartcard 'SCARD'
    ```
    ---
    * Standardise the `--connect-timeout` for `curl` invocations.
    * Add the `.tmux.conf` as a dedicated file in the gist and replace the base64 block with a `curl` from the gist file.
    URL template: `https://gist.github.com/kyle0r/<gist_id>/raw/<filename>`

    # Creating a Proxmox CT
    Depends on the `jq` command. Perform the following **from the hypervisor terminal:**
    @@ -513,36 +511,23 @@ I'm assuming `tmux` is installed system wide per the prerequisites section.
    Installing `tmux` on a per user basis inside `~/.local` is possible but outside the scope of this gist.

    ## `~/.tmux.conf`
    Here is is a copy of my `tmux` config which may include some features you'll like including:
    * Use the mouse to drag-resize panes
    This gist contains a copy of my `tmux` config which may include some features you'll like including:
    * tmux-plugins/tpm - tmux plugin manager
    * tmux-plugins/tmux-sensible - sensible settings for tmux
    * arcticicestudio/nord-tmux - theme
    * Use the mouse to select panes and drag-resize panes
    * <kbd>ALT</kbd>+<kbd>PGUP</kbd> / <kbd>PGDN</kbd> to change between windows
    * <kbd>ALT</kbd>+<kbd>←</kbd> / <kbd>↑</kbd> / <kbd>→</kbd> / <kbd>↓</kbd> to change between panes
    * <kbd>CTRL</kbd>+<kbd>B</kbd> <kbd>|</kbd> (pipe) to split a pane vertically
    * <kbd>CTRL</kbd>+<kbd>B</kbd> <kbd>-</kbd> (minus/hyphen/dash) to split a pane horizontally
    ```
    cat <<EOF | base64 -d | gunzip > ~/.tmux.conf
    H4sIAAAAAAACA4VV+2/bNhD+3X/FQcbgdAnjZkMyIFu3DnkgBZJ4yAPY0BYGLZ0kIhIpkJQdb+3+
    9t2RkivngRkBQvFeHz9+dxyDayrloZEaHbRO6QK+gNQZiNFC0b8v0UGs6MOsQJRxWzzZXo5aHQyT
    ZNIvvxuNHHoQrgB0qWxQeFUjvB2NxmCxMjKD1OhcFZCrCmEnLaUuMH5UJpVeGQ3ewNq0FnyJ4Ov2
    cZ9DeAtWUns2tw7fRFAWHLmmKEKKf6f7mwAumatHeMC1o2XpfeOOp1PnZfpglmjzyqzIsZ7K6eHh
    0cHRTz8ehJSCAkBouDAE3CHVOAsngWR2kWx5nJFt2+E84apupXxabvH7e+WFtJZoI1tpWmLfIqHr
    mNVwJS4x95SuwtQLDgVxObDeqKJ8Yr4ZmO+bbdv9wHZqVnrbesooGdIfssD7Zho83sFtxB3vd5Ag
    ejHipTKtEy86hBwaH3t9jAZUWfiFSJHNRjq+k1pv/vWpeZcRelMUdKkL9CtEDWlrLdL9s1Ir6fwQ
    aEh0IhbBsEEQpFhATaARjOacmdETT1LUkm43+jmQrTc1aS+VVbXmKGGaoEQKpi2zEl2AyfNN1lI5
    b+xaVKqmZjp4Sz8q0BkzzGVLBHu0tdKygsSllg4hfjg8Sk1lbMI6MdWSFKKca+kfCwOWqoaL2dVZ
    OOTZ9Smrd/RqzkdeDlIyZ7ZFCJ/g2qYx1m+dx0nowwU3gVUZlU72Qqbvj+/SkOSWxbDWaWmNVkRd
    VPKOX5PIlab+I1K6TemJ2JS6sRsALsrCwacR0I9qr8D1qf5GEaM+/dzZM0UzRa4h4XIw/ue3Z757
    s+u92fn51wCMRcuUABfhviIsnUo4MGLaH4134eTu5nL3lmZW3288TDRiBjlRI1OvlnHYcLZcWedD
    GKvYESchMd0w8B8dcUMVp1lIV/YFSFkxZeJa12BAlQAVbNqY8UPodIzTrG+h4RnIq++kE3H7CmPh
    ahlPmpMks4yIJ624llTAWWhwEoSAmZjw0lOX2jAxpEUJq5La5xtBfKjAAD7R+lZkQrfB7vMBmGwP
    xh8XxTuL2efbv65PYHY9/tjp8vPeV4jjD8OMfguqG9qK6NLGZrxLPdNAWpnFAm24wA1gfhg89Xcv
    9/ccMudxPnelWc2j17zzguQgFLukLqS2hKZqC6XdJjh+w4TjRWec+qae/I8Hf9BMd2pR4TPfRFqi
    LVUpOt9mykwZouCYgGVGh7GAj7JuKnTHHRXDWgWJsV3MSTSW58k07s95PXnZ/X0MCQ8Vh3Uhr3kv
    lF+06QP65wEU8UErr2RFFwl3V/d/dqRBLTUNcAs7D4hNlFml6J2QsWtI+yRW42lGMtObB/bNyLZU
    tntzpwOSI9FjMgtXIs2K5JnTkOdpv9jvqXwuAW3mjaTXCbN5brrrf6kAAa7RfbuYsOry/gdppTS+
    +QgAAA==
    EOF
    * <kbd>prefix</kbd> <kbd>|</kbd> to split a pane vertically (pipe)
    * <kbd>prefix</kbd> <kbd>-</kbd> to split a pane horizontally (minus/hyphen/dash)
    * <kbd>prefix</kbd> <kbd><</kbd> move window left
    * <kbd>prefix</kbd> <kbd>></kbd> move window right
    * <kbd>prefix</kbd> <kbd>s</kbd> toggle pane synchronisation - typing into all panes at the same time
    * <kbd>prefix</kbd> <kbd>R</kbd> reload tmux config

    You can download the version of the `.tmux.conf` as follows:
    ```
    curl --connect-timeout 5 -sSL https://gist.github.com/kyle0r/74cd5a6046747867e521efc01997a53d/raw/.tmux.conf > ~/.tmux.conf
    ```

    ## The `tmux` Plugin Manager aka tpm
    @@ -810,4 +795,6 @@ https://www.scootersoftware.com/kb/linux_install#debian
    # install
    sudo apt update && sudo apt install -y --fix-broken ~/Downloads/bcompare-5.0.7.30840_amd64.deb
    ```
    ```


  15. kyle0r revised this gist Apr 29, 2025. 1 changed file with 92 additions and 51 deletions.
    143 changes: 92 additions & 51 deletions A containerised Linux desktop env setup.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,4 @@

    # A containerised Linux desktop env setup
    This gist is currently a Work In Progress.

    @@ -10,29 +11,24 @@ There will be a screencast performing a speed run of the topics.
    The objective with most of the topics is to show ways / introduce tooling to boost productivity and the quality of our daily lives working in tech.

    # TODO
    Investigate these issues in the demo CT
    * Talk about / introduce https://github.com/kyle0r/bash-shortcuts-cheat-sheet, probably fits in the xterm/tmux sections.
    ---
    Does xrdp support USB key pass-through/auth?
    ```
    Apr 25 15:56:07 debian-de-demo xrdp[1286]: [WARN ] Cannot accept TLS connections because certificate or private key file is not readable. certificate file: [/etc/xrdp/cert.pem], private key file: [/etc/xrdp/key.pem]
    Apr 25 15:56:07 debian-de-demo xrdp[1286]: [INFO ] Non-TLS connection established from ::ffff:192.168.169.50 port 58668: with security level : high
    --
    Apr 25 15:56:07 debian-de-demo xrdp[1286]: [WARN ] xrdp_caps_process_codecs: unknown codec id 5
    Apr 25 15:56:07 debian-de-demo xrdp[1286]: [INFO ] Loading keymap file /etc/xrdp/km-00000809.ini
    Apr 25 15:56:07 debian-de-demo xrdp[1286]: [WARN ] local keymap file for 0x00000809 found and doesn't match built in keymap, using local keymap file
    --
    Apr 25 15:58:03 debian-de-demo xrdp-sesman[209]: [ERROR] sesman_data_in: scp_process_msg failed
    Apr 25 15:58:03 debian-de-demo xrdp-sesman[209]: [ERROR] sesman_main_loop: trans_check_wait_objs failed, removing trans
    xrdp-chansrv[430]: [INFO ] Detected remote smartcard 'SCARD'
    ```
    ---
    * Talk about / introduce https://github.com/kyle0r/bash-shortcuts-cheat-sheet, probably fits in the xterm/tmux sections.
    * Standardise the `--connect-timeout` for `curl` invocations.
    * Add the `.tmux.conf` as a dedicated file in the gist and replace the base64 block with a `curl` from the gist file.
    URL template: `https://gist.github.com/kyle0r/<gist_id>/raw/<filename>`

    # Creating a Proxmox CT
    Depends on the `jq` command. Perform the following **from the hypervisor terminal:**
    ```
    sudo apt install jq
    # list available storage
    pvesh get storage
    sudo pvesh get storage
    # pick the relevant storage for CT templates
    template_storage=local
    @@ -69,25 +65,41 @@ sudo pct create "$next_vmid" "$template_storage":vztmpl/debian-12-standard_12.7-
    # make a note of the dhcp ip
    sudo pct exec "$next_vmid" -- hostname -I
    sudo pct enter "$next_vmid" # does not provide login shell
    # note that: sudo pct enter "$next_vmid # does not provide login shell
    # enter the CT with root login shell
    sudo pct exec "$next_vmid" -- /bin/bash -l
    # Sanity check that you entered the CT and are not on the hypervisor
    hostname -f
    # Pick locales to generate for the CT and if desired set a system-wide default
    dpkg-reconfigure locales
    # OPTIONAL: disable IPv6 to simplify the localnet IP stack
    cat <<EOF > /etc/sysctl.d/disable_ipv6.conf
    net.ipv6.conf.all.disable_ipv6 = 1
    net.ipv6.conf.default.disable_ipv6 = 1
    EOF
    apt update && apt full-upgrade
    apt install aptitude # offers enhanced options and conflict resolution
    # 👇 This will install a lot of packages to setup the desktop env
    # This will also prompt you to setup the keyboard
    aptitude install awk molly-guard needrestart xrdp mate-desktop-environment bash-completion sudo curl vim
    apt update && apt full-upgrade -y
    apt install -y aptitude # offers enhanced options and conflict resolution
    # 👇 The following will install lots of deps required for the desktop env
    # It will also prompt you to setup the keyboard
    aptitude install -y awk molly-guard needrestart xrdp mate-desktop-environment bash-completion sudo curl vim
    # choose an editor
    update-alternatives --config editor
    # Fix a bug with xrdp where the service user cannot read the private key causing TLS is be disabled.
    # journal: Cannot accept TLS connections because certificate or private key file is not readable
    mkdir -p /etc/systemd/system/xrdp-sesman.service.d
    cat <<EOF > /etc/systemd/system/xrdp-sesman.service.d/99-ssl-key-fix.conf
    [Service]
    ExecStartPre=/usr/bin/find /etc/xrdp/key.pem -type l -and -delete
    ExecStartPre=/usr/bin/cp /etc/ssl/private/ssl-cert-snakeoil.key /etc/xrdp/key.pem
    ExecStartPre=/usr/bin/chown xrdp:root /etc/xrdp/key.pem
    EOF
    # once complete, reboot the CT for good measure
    reboot
    @@ -108,16 +120,22 @@ sudo pct exec "$next_vmid" -- /bin/bash -l
    # Sanity check that you entered the CT and are not on the hypervisor
    hostname -f
    # check you are happy with the keyboard and locale config, adjust as required
    localectl status; echo "value of /etc/default/locale: $(</etc/default/locale)"
    # create a throwaway user for demo purposes
    demouser=op-demo
    sudo adduser --disabled-password --gecos '' "$demouser"
    adduser --disabled-password --gecos '' "$demouser"
    # set a password so you can login via xrdp
    sudo passwd "$demouser"
    passwd "$demouser"
    # if you'd like to give the demo user sudo rights
    sudo usermod --append --groups sudo "$demouser"
    usermod --append --groups sudo "$demouser"
    # you may wish to modify the suoders config to set NOPASSWD for the sudo group
    visudo
    # enable copy/paste for xterm required for future steps
    cat <<'EOF' | sudo -u op-demo sh
    cat <<'EOF' | sudo -u "$demouser" sh
    echo 'XTerm*selectToClipboard: true' >> ~/.Xresources
    EOF
    @@ -156,38 +174,45 @@ OK, now its time to setup the demo user and install the following prerequisites:

    **From the CT terminal:**
    ```
    sudo aptitude install tmux git libarchive-tools jq
    sudo aptitude install -y tmux git libarchive-tools jq
    ```
    ## Keyboard map
    ### Per user
    For a host that has a desktop env installed you can *typically* check the current keyboard map via `setxkbmap -query` and set the map via `setxkbmap gb` for English GB or `no` for Norwegian and `us` for United States and so on.

    You can also invoke `localectl status` to see locale and keymap info.

    To persist this change for a specific user, add the `setxkbmap` to `~/.bashrc` or the relevant rc file for the shell you are using.

    If you prefer a GUI to manage this aspect, on MATE destop env you can change keyboard settings via
    System → Control Center → Hardware → Keyboard → Layouts Tab.

    ### System wide
    To change the **system default** on Debian invoke: `sudo dpkg-reconfigure keyboard-configuration` and follow the menu steps. [[docs](https://www.debian.org/doc/manuals/debian-reference/ch08.en.html#_the_keyboard_input)]

    If the `kbd` package is not installed, for example on a minimally installed host, The `kdb` package may be required for correct functioning of keyboard management.
    If the `kbd` package is not installed, for example on a minimally installed host, the `kdb` package may be required keyboard management to work properly.

    ### Notes
    I noted when testing different keyboard settings/commands that one needs to keep in mind if one is sitting on a physical `tty` or a pseudo `pty` terminal. AFAIK `loadkeys` and `dumpkeys` are designed to work on physical TTYs and may have issues with TTYs.

    If you prefer a GUI to manage this aspect, on MATE destop env you can change keyboard settings via
    System → Control Center → Hardware → Keyboard → Layouts Tab.

    ## Locales
    ### System wide
    I recommend you install and set a default UTF-8 locale specific to your territory. On Debian this is simple via `sudo dpkg-reconfigure locales`.
    Generating locales and optionally setting the system default locale is easy via `sudo dpkg-reconfigure locales`. Users will inherit `/etc/default/locale` if its set. This was already suggested to be performed during the CT setup steps.

    💡 Note that this demo CT is not intended to be a multilingual host, so setting the default locale should not be an issue. For multi-user, multi-language hosts, it is usually best practice not to set a default locale.

    ### Manual locale configuration
    Adding locales can be automated by manipulating `/etc/locale.gen` and invoking `locale-gen` and `update-locale` but I'm leaving it out of scope for this gist. Ask a GenAI or perform a web search if you are interested in further details. DYOR - YMMV!

    ### Per user
    If a user doesn't specify their own locale in their shell profile or rc files, the system default `/etc/default/locale` will be used. If the system default is not set, there will be a fall back to an unspecified default, typically the `C` locale.

    In case you want to perform this for a specific user (or don't have sudo rights) then use the `locale -a` to list which locales are available and then set one by invoking `LC_ALL=<locale>` where `<locale>` is your preferred locale. For example `LC_ALL=en_GB.UTF-8`.

    Add the relevant `LC_ALL` to your `~/.bashrc` or relevant shell rc file to set the locale for *interactive* sessions and set it in your `~/.profile` to set the locale for any *login* sessions. For consistency you may wish to set it in both files.

    💡 You'll want to logout of any desktop env / exit any terminal sessions to pick up the change.

    ### Manual locale configuration
    Adding locales can be automated by manipulating `/etc/locale.gen` and invoking `locale-gen` and `update-locale` but I'm leaving it out of scope for this gist. Ask a GenAI for a solution if you are interested. DYOR - YMMV!

    ### Missing language / regional settings in MATE Control Center
    I noted on a minimal MATE desktop env that created from a `debian-12-standard_12.2-1_amd64` template that **the language / regional options were missing from the Control Center.** There is some ambiguity on if and how one makes those options appear. It would be worth investigating the `ibus` setup and/or `i18n` settings on MATE desktop.

    @@ -199,6 +224,7 @@ AFAIK, Kim Silkebækken introduced the concept of *powerlines* when he started h

    For this demo I've chosen [SourceCodePro](https://github.com/adobe-fonts/source-code-pro/releases/latest) which is open font created by Adobe.

    ### Per user
    The following snippet will download and extract the latest OTF version of SourceCodePro to the `~/.fonts` dir.
    The snippet utilises the GitHub API and `jq` to determine the latest version and then runs an download | extract pipeline and does not create any temporary cruft.
    ```
    @@ -207,19 +233,22 @@ if download_url=$(curl --connect-timeout 5 -sSL https://api.github.com/repos/ado
    mkdir -p ~/.fonts
    echo -n 'Downloading font. Please wait... '
    if curl --connect-timeout 5 -sSL "$download_url" |bsdtar -xf - --strip-components=1 -C ~/.fonts; then
    echo 'font installed OK'
    echo 'Font installed OK'
    # install new fonts
    fc-cache -fv
    echo -n 'Updaing font cache. Please wait... '
    fc-cache -fv 1>/dev/null 2>&1 && echo OK || echo FAILURE
    else
    echo 'FAILURE'
    fi
    else
    echo 'Error determining font download_url'
    fi
    ```

    More powerline fonts are available here: https://github.com/powerline/fonts

    ### System wide
    TODO

    # `xterm`
    I chose to demo `xterm` because its a straightforward and ubiquitous. I tested with `xterm -version` 379.

    @@ -229,15 +258,19 @@ Keep in mind the difference between login and non-login shell sessions

    The pre-installed MATE desktop `xterm` launcher does not not invoke a login shell. Run `shopt login_shell` to see what I mean.

    I suggest to create a launcher which invokes `xterm -ls` which will launch `xterm` as a login shell and will execute the system and user profile. **TODO screenshot.**
    I suggest to create a launcher which invokes `xterm -ls` which will launch `xterm` as a login shell and will execute the system and user profile.

    **TODO screenshot.**

    One reason this is important, is that the profile contains the setup for things like the users `~/.local/bin`

    💡 **Cosmetic paste issue** It looks like there is a **cosmetic** paste bug in `xterm`. If the paste is larger/more than the visible terminal rows, then the terminal doesn't scroll to accommodate the paste, so it looks like the paste has become malformed. From testing, the paste is fine and it is just a cosmetic issue. I was not able to tune this out via `xterm` config options. If you know how to fix it please leave a comment.

    ## Nord theme
    ```
    mkdir -p ~/.config/themes
    mkdir -p ~/.config/xterm/themes
    cat <<'EOF' > ~/.config/themes/xterm-nord
    cat <<'EOF' > ~/.config/xterm/themes/nord
    ! Copyright (c) 2016-present Sven Greb <[email protected]>
    ! This source code is licensed under the MIT license found in the license file.
    @@ -309,10 +342,11 @@ XTerm*selectToClipboard: true
    XTerm*metaSendsEscape: true
    ! testing suggestions pwd is ~
    #include ".config/themes/xterm-nord"
    #include ".config/xterm/themes/nord"
    EOF
    ```
    💡 You'll want to logout / exit any terminal sessions to pick up changes.

    # Browser
    ## Librewolf
    @@ -325,6 +359,8 @@ I'm going to trail this as my main desktop browser and drop-in replacement for F
    ### Per user install

    TODO explain the snippet:
    GPT-4o mini said
    > In summary, this script automates the process of downloading the latest LibreWolf browser release for Linux, unpacking it, and setting up a convenient symlink for easy access. It includes error handling to ensure that the user is informed if something goes wrong during the URL retrieval process.
    ```
    if librewolf_url=$(curl -sSL "https://gitlab.com/api/v4/projects/librewolf-community%2Fbrowser%2Fbsys6/releases" | jq -r 'sort_by(.tag_name) | last | .assets.links[] | select(.name | test("linux-x86_64.*\\.tar\\.xz$")) | .url'); then
    @@ -340,7 +376,6 @@ else
    echo 'There was an error determining the librewolf_url'
    fi
    ```
    💡 You'll want to logout / exit any terminal sessions to pick up changes.

    ### System wide install
    Taken from https://librewolf.net/installation/debian/
    @@ -375,7 +410,9 @@ ff_os=linux64
    # pick an edition
    ff_edition=firefox-latest-ssl
    ff_edition=firefox-devedition-latest-ssl
    ```
    ...
    ```
    # All-in-one as an example
    ff_locale=en-GB;ff_os=linux64;ff_edition=firefox-devedition-latest-ssl
    @@ -448,7 +485,7 @@ fi
    ```
    After install, you can launch the latest ungoogled-chromium-portablelinux by invoking `chromium` on the terminal.

    You will probably see a `gnome-keyring` prompt. I have no experience with this, so DYOR. [Here is the man page for `gnome-keyring`](https://manpages.debian.org/stable/gnome-keyring/gnome-keyring.1.en.html). I'm assuming it wants to use the keyring to read and write website secrets like usernames and passwords for saved sites, that sort of thing. Similar to the keychain in OS X. You'll probably need to take some steps to initialise the user keyring if you want to take advantage of its features.
    You will might see a `gnome-keyring` prompt. I have no experience with this, so DYOR. [Here is the man page for `gnome-keyring`](https://manpages.debian.org/stable/gnome-keyring/gnome-keyring.1.en.html). I'm assuming it wants to use the keyring to read and write website secrets like usernames and passwords for saved sites, that sort of thing. Similar to the keychain in OS X. You'll probably need to take some steps to initialise the user keyring if you want to take advantage of its features.

    ### Portable Google Chrome?
    When researching, I found the "Google-Chrome-Portable-maker-for-linux" project [here](https://github.com/shivamgly/Google-Chrome-Portable-maker-for-linux). Which is discussed [here](https://askubuntu.com/a/1051236). It looks quite interesting. Keep in mind this relates to the Google Chrome browser distribution and is not ungoogled.
    @@ -468,7 +505,7 @@ curl -sSL https://dl.google.com/linux/direct/$chrome_dl_filename > ~/Downloads/"
    sudo apt install --dry-run --fix-broken ~/Downloads/"$chrome_dl_filename"
    # install Chrome system wide
    sudo apt install --fix-broken ~/Downloads/"$chrome_dl_filename"
    sudo apt install -y --fix-broken ~/Downloads/"$chrome_dl_filename"
    ```

    # tmux
    @@ -518,7 +555,7 @@ tmux new-session '~/.tmux/plugins/tpm/scripts/install_plugins.sh'
    ```
    Now you can launch `tmux` :)

    Here is what it looks like from a cygwin mintty:
    Here is an example of how the tmux config looks like from a cygwin mintty:

    ![image](https://gist.github.com/user-attachments/assets/34a311c0-18d3-4171-8fee-10d8607f97b4)

    @@ -550,6 +587,9 @@ fi
    ### Updating `xpanes`
    Just run the snippet again in the future.

    ### `xpanes` Demo
    TODO

    # nord theme for `vim`
    We need a `vim` plugin manager for this, lets go with [`vim-plug`](https://github.com/junegunn/vim-plug). Here is a shell snippet to install `vim-plug`:
    ```
    @@ -617,11 +657,14 @@ git clone --depth=1 https://github.com/junegunn/fzf.git ~/.fzf

    Check out this screencast by [@samoshkin](https://github.com/samoshkin) which explores `fzf` features.

    ## Updating fzf
    ## Updating `fzf`
    ```
    ( cd ~/.fzf && git pull && ~/.fzf/install )
    ```

    ## Example `fzf` usage
    TODO

    # Sublime Text
    [Sublime Text](https://www.sublimetext.com/) as its name suggests is extremely good. Back in ~2008 creator Jon Skinner had some really novel ideas on improving UI/UX and Sublime introduced and made the Command Palette popular which other apps have since implemented their own flavours of. I remember trying the early versions and being blown away by it.

    @@ -653,7 +696,8 @@ As of 2025-April direct downloads are available via https://www.sublimetext.com/

    Here is an example shell snippet from the time of writing:
    ```
    curl -sSL 'https://download.sublimetext.com/sublime_text_build_4192_x64.tar.xz' | bsdtar -xf - -C ~/.local && ln -s ~/.local/sublime_text/sublime_text ~/.local/bin
    curl -sSL 'https://download.sublimetext.com/sublime_text_build_4192_x64.tar.xz' |
    bsdtar -xf - -C ~/.local && ln -s ~/.local/sublime_text/sublime_text ~/.local/bin/subl
    ```
    If successful, you should now be able to invoke `sublime_text` in the terminal.

    @@ -765,8 +809,5 @@ https://www.scootersoftware.com/kb/linux_install#debian
    ( cd ~/Downloads; curl -sSLO 'https://www.scootersoftware.com/files/bcompare-5.0.7.30840_amd64.deb' )
    # install
    sudo apt update
    sudo apt install --fix-broken ~/Downloads/bcompare-5.0.7.30840_amd64.deb
    ```


    sudo apt update && sudo apt install -y --fix-broken ~/Downloads/bcompare-5.0.7.30840_amd64.deb
    ```
  16. kyle0r revised this gist Apr 26, 2025. 1 changed file with 11 additions and 3 deletions.
    14 changes: 11 additions & 3 deletions A containerised Linux desktop env setup.md
    Original file line number Diff line number Diff line change
    @@ -31,8 +31,17 @@ Depends on the `jq` command. Perform the following **from the hypervisor termina
    ```
    sudo apt install jq
    # list available storage
    pvesh get storage
    # pick the relevant storage for CT templates
    template_storage=local
    # pick relevant storage for the CT rootfs
    hypervisor_storage=sas-zfs-nocrypt
    # procure CT template
    sudo pveam download <storage> debian-12-standard_12.7-1_amd64.tar.zst
    sudo pveam download "$template_storage" debian-12-standard_12.7-1_amd64.tar.zst
    # determine the proxmox host - this assumes the first / a signular host setup
    h=$(pvesh ls --output-format=json nodes | jq -r '.[0].name')
    @@ -41,11 +50,10 @@ next_vmid=$(( $(cat <(sudo pvesh get /nodes/"$h"/lxc --output-format=json | jq -
    echo "The next available vmid on host: $h, is: $next_vmid"
    ct_new_hostname=debian-de-demo
    hypervisor_storage=sas-zfs-nocrypt
    pub_key=~kyle/.ssh/tmp.pub
    # create the CT
    sudo pct create "$next_vmid" local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst \
    sudo pct create "$next_vmid" "$template_storage":vztmpl/debian-12-standard_12.7-1_amd64.tar.zst \
    --ostype debian \
    --hostname "$ct_new_hostname" \
    --memory 8192 \
  17. kyle0r revised this gist Apr 26, 2025. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions A containerised Linux desktop env setup.md
    Original file line number Diff line number Diff line change
    @@ -469,6 +469,7 @@ Installing `tmux` on a per user basis inside `~/.local` is possible but outside

    ## `~/.tmux.conf`
    Here is is a copy of my `tmux` config which may include some features you'll like including:
    * Use the mouse to drag-resize panes
    * <kbd>ALT</kbd>+<kbd>PGUP</kbd> / <kbd>PGDN</kbd> to change between windows
    * <kbd>ALT</kbd>+<kbd>←</kbd> / <kbd>↑</kbd> / <kbd>→</kbd> / <kbd>↓</kbd> to change between panes
    * <kbd>CTRL</kbd>+<kbd>B</kbd> <kbd>|</kbd> (pipe) to split a pane vertically
    @@ -509,6 +510,10 @@ tmux new-session '~/.tmux/plugins/tpm/scripts/install_plugins.sh'
    ```
    Now you can launch `tmux` :)

    Here is what it looks like from a cygwin mintty:

    ![image](https://gist.github.com/user-attachments/assets/34a311c0-18d3-4171-8fee-10d8607f97b4)

    ### Updating plugins
    Launch `tmux` and invoke the `prefix` + <kbd>U</kbd> kbd shortcut.

  18. kyle0r revised this gist Apr 26, 2025. 2 changed files with 759 additions and 1 deletion.
    759 changes: 759 additions & 0 deletions A containerised Linux desktop env setup.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,759 @@
    # A containerised Linux desktop env setup
    This gist is currently a Work In Progress.

    These steps were practised and performed on a Debian Bookworm container and Proxmox 8.x Hypervisor. Instructions may vary for other releases/distros. Please DYOR and observe that YMMV. Comments, ideas and critique very welcome.

    This post is effectively a tech demo. I hope you enjoy and take away something useful.

    There will be a screencast performing a speed run of the topics.

    The objective with most of the topics is to show ways / introduce tooling to boost productivity and the quality of our daily lives working in tech.

    # TODO
    Investigate these issues in the demo CT
    ```
    Apr 25 15:56:07 debian-de-demo xrdp[1286]: [WARN ] Cannot accept TLS connections because certificate or private key file is not readable. certificate file: [/etc/xrdp/cert.pem], private key file: [/etc/xrdp/key.pem]
    Apr 25 15:56:07 debian-de-demo xrdp[1286]: [INFO ] Non-TLS connection established from ::ffff:192.168.169.50 port 58668: with security level : high
    --
    Apr 25 15:56:07 debian-de-demo xrdp[1286]: [WARN ] xrdp_caps_process_codecs: unknown codec id 5
    Apr 25 15:56:07 debian-de-demo xrdp[1286]: [INFO ] Loading keymap file /etc/xrdp/km-00000809.ini
    Apr 25 15:56:07 debian-de-demo xrdp[1286]: [WARN ] local keymap file for 0x00000809 found and doesn't match built in keymap, using local keymap file
    --
    Apr 25 15:58:03 debian-de-demo xrdp-sesman[209]: [ERROR] sesman_data_in: scp_process_msg failed
    Apr 25 15:58:03 debian-de-demo xrdp-sesman[209]: [ERROR] sesman_main_loop: trans_check_wait_objs failed, removing trans
    ```
    ---
    * Talk about / introduce https://github.com/kyle0r/bash-shortcuts-cheat-sheet, probably fits in the xterm/tmux sections.

    # Creating a Proxmox CT
    Depends on the `jq` command. Perform the following **from the hypervisor terminal:**
    ```
    sudo apt install jq
    # procure CT template
    sudo pveam download <storage> debian-12-standard_12.7-1_amd64.tar.zst
    # determine the proxmox host - this assumes the first / a signular host setup
    h=$(pvesh ls --output-format=json nodes | jq -r '.[0].name')
    # determine the next free vmid
    next_vmid=$(( $(cat <(sudo pvesh get /nodes/"$h"/lxc --output-format=json | jq -r '.[].vmid') <(sudo pvesh get /nodes/"$h"/qemu --output-format=json | jq -r '.[].vmid') | sort | tail -n1) + 1 ))
    echo "The next available vmid on host: $h, is: $next_vmid"
    ct_new_hostname=debian-de-demo
    hypervisor_storage=sas-zfs-nocrypt
    pub_key=~kyle/.ssh/tmp.pub
    # create the CT
    sudo pct create "$next_vmid" local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst \
    --ostype debian \
    --hostname "$ct_new_hostname" \
    --memory 8192 \
    --cores 4 \
    --storage "$hypervisor_storage" \
    --rootfs "$hypervisor_storage":20,mountoptions=noatime \
    --net0 name=eth0,type=veth,bridge=vmbr0,ip=dhcp,firewall=0 \
    --unprivileged 1 \
    --features nesting=1 \
    --ssh-public-keys "$pub_key" \
    --start 1
    # make a note of the dhcp ip
    sudo pct exec "$next_vmid" -- hostname -I
    sudo pct enter "$next_vmid" # does not provide login shell
    # enter the CT with root login shell
    sudo pct exec "$next_vmid" -- /bin/bash -l
    # Sanity check that you entered the CT and are not on the hypervisor
    hostname -f
    # OPTIONAL: disable IPv6 to simplify the localnet IP stack
    cat <<EOF > /etc/sysctl.d/disable_ipv6.conf
    net.ipv6.conf.all.disable_ipv6 = 1
    net.ipv6.conf.default.disable_ipv6 = 1
    EOF
    apt update && apt full-upgrade
    apt install aptitude # offers enhanced options and conflict resolution
    # 👇 This will install a lot of packages to setup the desktop env
    # This will also prompt you to setup the keyboard
    aptitude install awk molly-guard needrestart xrdp mate-desktop-environment bash-completion sudo curl vim
    # once complete, reboot the CT for good measure
    reboot
    ```
    Now it is time to set up the demo user.
    If you need inspiration for a password, you can try this snippet which will run as the `nobody` user as a best practice:
    ```
    cat <<'EOF' | sudo -u nobody bash
    test -e /usr/share/dict/words && echo "$(whoami) generated password: $(shuf -n 4 <(awk 'length($0) > 4 && length($0) < 9 && ! /'"'"'/' /usr/share/dict/words) | tr '\n' ' ' | tr '[:upper:]' '[:lower:]')" || echo 'Aborted. Dictionary not found.'
    EOF
    ```

    **From the hypervisor terminal:**, enter the CT and setup the demo user:
    ```
    # enter the CT with root login shell
    sudo pct exec "$next_vmid" -- /bin/bash -l
    # Sanity check that you entered the CT and are not on the hypervisor
    hostname -f
    # create a throwaway user for demo purposes
    demouser=op-demo
    sudo adduser --disabled-password --gecos '' "$demouser"
    # set a password so you can login via xrdp
    sudo passwd "$demouser"
    # if you'd like to give the demo user sudo rights
    sudo usermod --append --groups sudo "$demouser"
    # enable copy/paste for xterm required for future steps
    cat <<'EOF' | sudo -u op-demo sh
    echo 'XTerm*selectToClipboard: true' >> ~/.Xresources
    EOF
    exit # logout from the CT termminal
    ```

    # CT `ssh` login
    ```
    # setup auth
    dhcp_ip=192.168.169.38; ssh_key=~/.ssh/id_ed25519
    ssh-copy-id -i "$ssh_key" op-demo@"$dhcp_ip"
    # connect
    ssh op-demo@"$dhcp_ip"
    hostname -f
    ```

    # CT GUI Login
    ## Windows
    Open the run dialogue: <kbd>WIN</kbd>+<kbd>r</kbd> and run: `mstsc /v:<dhcp_ip> /w:1920 /h:1080`

    TODO `cmdkey` entry?

    ## Linux
    I'm not personally familiar with connecting to RDP servers from a Linux desktop env but I understand that Debian 12 Bookworm has at least two packages available `aptitude search freerdp rdesktop`. It should be *fairly* self explanatory to then launch those clients and connect to the new CT.

    # Prerequisites
    OK, now its time to setup the demo user and install the following prerequisites:

    * [`tmux`](https://github.com/tmux/tmux/wiki) is a terminal multiplexer
    * [`git`](https://git-scm.com/) mange source control and clone repos
    * [`bsdtar`](https://manpages.debian.org/stable/libarchive-tools/bsdtar.1.en.html) can handle zip extraction from a pipe`*`
    * [`jq`](https://jqlang.org/) is a cli tool for parsing and manipulating JSON data.

    `*` `bsdtar` can handle extracting zip and other formats in a pipeline - check the [`man bsdtar`](https://manpages.debian.org/stable/libarchive-tools/bsdtar.1.en.html) page. It is part of the `libarchive-tools` package in Debian.

    **From the CT terminal:**
    ```
    sudo aptitude install tmux git libarchive-tools jq
    ```
    ## Keyboard map
    For a host that has a desktop env installed you can *typically* check the current keyboard map via `setxkbmap -query` and set the map via `setxkbmap gb` for English GB or `no` for Norwegian and `us` for United States and so on.

    You can also invoke `localectl status` to see locale and keymap info.

    To persist this change for a specific user, add the `setxkbmap` to `~/.bashrc` or the relevant rc file for the shell you are using.

    To change the **system default** on Debian invoke: `sudo dpkg-reconfigure keyboard-configuration` and follow the menu steps. [[docs](https://www.debian.org/doc/manuals/debian-reference/ch08.en.html#_the_keyboard_input)]

    If the `kbd` package is not installed, for example on a minimally installed host, The `kdb` package may be required for correct functioning of keyboard management.

    I noted when testing different keyboard settings/commands that one needs to keep in mind if one is sitting on a physical `tty` or a pseudo `pty` terminal. AFAIK `loadkeys` and `dumpkeys` are designed to work on physical TTYs and may have issues with TTYs.

    If you prefer a GUI to manage this aspect, on MATE destop env you can change keyboard settings via
    System → Control Center → Hardware → Keyboard → Layouts Tab.

    ## Locales
    ### System wide
    I recommend you install and set a default UTF-8 locale specific to your territory. On Debian this is simple via `sudo dpkg-reconfigure locales`.

    ### Per user
    In case you want to perform this for a specific user (or don't have sudo rights) then use the `locale -a` to list which locales are available and then set one by invoking `LC_ALL=<locale>` where `<locale>` is your preferred locale. For example `LC_ALL=en_GB.UTF-8`.

    Add the relevant `LC_ALL` to your `~/.bashrc` or relevant shell rc file to set the locale for *interactive* sessions and set it in your `~/.profile` to set the locale for any *login* sessions. For consistency you may wish to set it in both files.

    💡 You'll want to logout of any desktop env / exit any terminal sessions to pick up the change.

    ### Manual locale configuration
    Adding locales can be automated by manipulating `/etc/locale.gen` and invoking `locale-gen` and `update-locale` but I'm leaving it out of scope for this gist. Ask a GenAI for a solution if you are interested. DYOR - YMMV!

    ### Missing language / regional settings in MATE Control Center
    I noted on a minimal MATE desktop env that created from a `debian-12-standard_12.2-1_amd64` template that **the language / regional options were missing from the Control Center.** There is some ambiguity on if and how one makes those options appear. It would be worth investigating the `ibus` setup and/or `i18n` settings on MATE desktop.

    ## Fonts
    To get the best look and feel you'll want a font that supports **powerline**. What is that? Here is what GPT-4o mini says:
    > Powerline fonts are a type of font specifically designed for use in terminal applications, particularly for enhancing the appearance of status lines and prompts in command-line interfaces. They are often used in conjunction with terminal emulators and text editors to provide a visually appealing and informative display of information.
    AFAIK, Kim Silkebækken introduced the concept of *powerlines* when he started his vim project. The repo is here: https://github.com/powerline/powerline.

    For this demo I've chosen [SourceCodePro](https://github.com/adobe-fonts/source-code-pro/releases/latest) which is open font created by Adobe.

    The following snippet will download and extract the latest OTF version of SourceCodePro to the `~/.fonts` dir.
    The snippet utilises the GitHub API and `jq` to determine the latest version and then runs an download | extract pipeline and does not create any temporary cruft.
    ```
    if download_url=$(curl --connect-timeout 5 -sSL https://api.github.com/repos/adobe-fonts/source-code-pro/releases/latest | jq -r '.assets[] | select(.name | contains("OTF")) | .browser_download_url'); then
    mkdir -p ~/.fonts
    echo -n 'Downloading font. Please wait... '
    if curl --connect-timeout 5 -sSL "$download_url" |bsdtar -xf - --strip-components=1 -C ~/.fonts; then
    echo 'font installed OK'
    # install new fonts
    fc-cache -fv
    else
    echo 'FAILURE'
    fi
    else
    echo 'Error determining font download_url'
    fi
    ```

    More powerline fonts are available here: https://github.com/powerline/fonts

    # `xterm`
    I chose to demo `xterm` because its a straightforward and ubiquitous. I tested with `xterm -version` 379.

    Keep in mind the difference between login and non-login shell sessions
    * login: executes the system and current user profile
    * non-login: skips the profile

    The pre-installed MATE desktop `xterm` launcher does not not invoke a login shell. Run `shopt login_shell` to see what I mean.

    I suggest to create a launcher which invokes `xterm -ls` which will launch `xterm` as a login shell and will execute the system and user profile. **TODO screenshot.**

    One reason this is important, is that the profile contains the setup for things like the users `~/.local/bin`

    ## Nord theme
    ```
    mkdir -p ~/.config/themes
    cat <<'EOF' > ~/.config/themes/xterm-nord
    ! Copyright (c) 2016-present Sven Greb <[email protected]>
    ! This source code is licensed under the MIT license found in the license file.
    #define nord0 #2E3440
    #define nord1 #3B4252
    #define nord2 #434C5E
    #define nord3 #4C566A
    #define nord4 #D8DEE9
    #define nord5 #E5E9F0
    #define nord6 #ECEFF4
    #define nord7 #8FBCBB
    #define nord8 #88C0D0
    #define nord9 #81A1C1
    #define nord10 #5E81AC
    #define nord11 #BF616A
    #define nord12 #D08770
    #define nord13 #EBCB8B
    #define nord14 #A3BE8C
    #define nord15 #B48EAD
    XTerm*foreground: nord4
    XTerm*background: nord0
    XTerm*cursorColor: nord4
    XTerm*fading: 35
    XTerm*fadeColor: nord3
    XTerm*color0: nord1
    XTerm*color1: nord11
    XTerm*color2: nord14
    XTerm*color3: nord13
    XTerm*color4: nord9
    XTerm*color5: nord15
    XTerm*color6: nord8
    XTerm*color7: nord5
    XTerm*color8: nord3
    XTerm*color9: nord11
    XTerm*color10: nord14
    XTerm*color11: nord13
    XTerm*color12: nord9
    XTerm*color13: nord15
    XTerm*color14: nord7
    XTerm*color15: nord6
    EOF
    ```

    ## `xterm` config

    The following snippet will setup some reasonable defaults for `xterm` and merge the changes into the X resource database.

    ```
    cat <<'EOF' > ~/.Xresources && xrdb -merge ~/.Xresources || echo 'FAILURE'
    ! font cfg
    XTerm*faceName: SourceCodePro-Medium
    XTerm*faceSize: 14
    ! color support
    XTerm*termName: xterm-256color
    XTerm*colorMode: true
    ! selections in the terminal are automatically copied to the clipboard
    XTerm*selectToClipboard: true
    ! the Meta key (e.g. Alt key) sends an escape sequence e.g. ALT+B and ALT+F
    ! For example:
    ! ALT+B moves the cursor backwards by one word
    ! ALT+F moves the cursor forwards by one word
    ! ref: https://github.com/kyle0r/bash-shortcuts-cheat-sheet
    XTerm*metaSendsEscape: true
    ! testing suggestions pwd is ~
    #include ".config/themes/xterm-nord"
    EOF
    ```

    # Browser
    ## Librewolf
    **A Firefox fork...** To quote [Librewolf's](https://librewolf.net/) website: "A custom version of Firefox, focused on privacy, security and freedom."

    I've taken Librewolf for a spin and it looks good. After a quick look at the out of the box settings, they were refreshingly privacy focused. It was a nice touch to see that Librewolf comes bundled with [uBlock Origin](https://addons.mozilla.org/firefox/addon/ublock-origin).

    I'm going to trail this as my main desktop browser and drop-in replacement for Firefox. It will be interesting to see if Firefox profiles can be used in / migrated to Librewolf.

    ### Per user install

    TODO explain the snippet:
    ```
    if librewolf_url=$(curl -sSL "https://gitlab.com/api/v4/projects/librewolf-community%2Fbrowser%2Fbsys6/releases" | jq -r 'sort_by(.tag_name) | last | .assets.links[] | select(.name | test("linux-x86_64.*\\.tar\\.xz$")) | .url'); then
    mkdir -p ~/.local/bin
    echo -n 'unpacking Librewolf to ~/.local/librewolf. Please wait... '
    # cruftless download and unpack
    curl -sSL "$librewolf_url" | bsdtar -xf - -C ~/.local && echo OK || echo FAILURE
    # local bin symlink for Librewolf
    ln -fs ~/.local/librewolf/librewolf ~/.local/bin
    else
    echo 'There was an error determining the librewolf_url'
    fi
    ```
    💡 You'll want to logout / exit any terminal sessions to pick up changes.

    ### System wide install
    Taken from https://librewolf.net/installation/debian/
    ```
    # install external repo support
    sudo apt update && sudo apt install extrepo -y
    # enable Librewolf repo
    sudo extrepo enable librewolf
    # system wide install of Librewolf
    sudo apt update && sudo apt install librewolf -y
    ```

    ## Firefox
    ### Per user install
    The following shell snippet will install the latest Firefox edition of your choice, for the current user. AFAIK this approach bypasses the download token that Mozilla implemented in 2020. See the privacy concerns section below.
    ```
    # ref: https://ftp.mozilla.org/pub/firefox/releases/latest/README.txt
    # pick a locale
    ff_locale=nb-NO # Norwegian
    ff_locale=en-US # US English
    ff_locale=en-GB # British English
    # pick a platform
    ff_os=win64
    ff_os=osx
    ff_os=linux
    ff_os=linux64
    # pick an edition
    ff_edition=firefox-latest-ssl
    ff_edition=firefox-devedition-latest-ssl
    # All-in-one as an example
    ff_locale=en-GB;ff_os=linux64;ff_edition=firefox-devedition-latest-ssl
    # As of 2025-April
    # use the http location header to determine the latest release
    if ff_ftp_release_url=$(echo -n 'https://ftp.mozilla.org/pub/firefox/releases/'; curl --head -sS "https://download.mozilla.org/?product=${ff_edition}&os=${ff_os}&lang=${ff_locale}"| grep ^Location | cut -d'/' -f7- | tr -d '\r'); then
    mkdir -p ~/.local/bin
    echo 'unpacking Firefox to ~/.local/firefox. Please wait...'
    # cruftless download and unpack
    curl -sSL "$ff_ftp_release_url" | bsdtar -xf - -C ~/.local && echo OK || echo FAILURE
    # local bin symlink for Firefox
    ln -fs ~/.local/firefox/firefox ~/.local/bin
    else
    echo 'There was an error determining the ff_ftp_release_url'
    fi
    ```
    ### Firefox privacy concerns
    Read more about Mozilla's download token which is used by Firefox's telemetry feature: [[ref](https://redd.it/vitjny)] [[ref](https://bugzilla.mozilla.org/show_bug.cgi?id=1677497)] [[ref](https://www.privacyguides.org/en/desktop-browsers/#firefox)]. AFAIK downloads from the Firefox releases repo, originally their ftp, now hosted on a CDN, does NOT contain a download token.

    You can browse the different editions/locales via an existing browser: https://www.mozilla.org/firefox/all/ but be warned, downloading from the website directly will include a download token as mentioned above.

    ### System wide install
    TODO

    ## Extensions for Firefox based browsers
    Firefox no longer supports sideloading/preloading extensions, so I'm not aware of a way to install extensions automatically without providing a preconfigured Firefox profile which I would not consider a best practice.

    The next best thing is just to click the direct install links from your preferred/throwaway Firefox profile:

    * [Quick Tabs Ported](https://github.com/babyman/quick-tabs-chrome-extension/issues/189#issuecomment-2563974135) by [kyle0r](https://github.com/kyle0r) - [direct install link](https://sh4re.eu/misc/quick_tabs_ported-1.0.6.2.xpi) (1.0.6.2)
    ☝️ Based on the original Chrome extension by [babyman](https://github.com/babyman/quick-tabs-chrome-extension) which was [originally ported](https://addons.mozilla.org/firefox/addon/quick-tabs-ported/) to Firefox by [Kevin Jones](https://addons.mozilla.org/firefox/user/6034453/).

    * [uBlock Origin](https://addons.mozilla.org/firefox/addon/ublock-origin) by [Raymond Hill](https://addons.mozilla.org/firefox/user/11423598/) - [direct install link](https://addons.mozilla.org/firefox/downloads/file/4458450/ublock_origin-1.63.2.xpi) (1.63.2)
    I suggest to enable "Block Outsider Intrusion into LAN" under Filter Lists -> Privacy

    * [Port Authority](https://addons.mozilla.org/firefox/addon/port-authority/) by [Hacks and Hops](https://addons.mozilla.org/firefox/user/17239316/) - [direct install link](https://addons.mozilla.org/firefox/downloads/file/4445872/port_authority-2.0.0.xpi) (2.0.0)
    Alternative to "Block Outsider Intrusion into LAN" feature of uBlock Origin that can also provide notifications of intrusion attempts.

    ### Dictionaries
    1. Set your language in `about:preferences`
    2. Install a dictionary: https://addons.mozilla.org/firefox/language-tools/

    ## Google Chrome
    I cannot endorse installing Google Chrome on your system, which is effectively mass surveillance software. In addition to the privacy and surveillance issues with Google products, the 2024 drama surrounding the migration of extension manifest v2 to v3 highlights Google's disdain for ad blocking and privacy. It is a real shame Chrome has achieved an effective monopoly. [[ref](https://web.archive.org/web/20240805181924/https://arstechnica.com/gadgets/2024/08/chromes-manifest-v3-and-its-changes-for-ad-blocking-are-coming-real-soon/)] [[ref](https://web.archive.org/web/20250110084005/https://github.com/uBlockOrigin/uBlock-issues/wiki/About-Google-Chrome's-%22This-extension-may-soon-no-longer-be-supported%22)] [[ref](https://web.archive.org/web/20250224154540/https://www.theregister.com/2025/02/24/google_v2_eol_v3_rollout/)].

    In the past, many people, especially early Google adopters/advocates were duped by Google's "Don't be evil" corporate code of conduct, myself included, which was officially abandoned in 2018... one can interpolate that evil/unethical things were happening at Google before then. On a related note, one interesting data point would be to map whether Google was working on military contracts before 2018, and how this may have expanded in recent years, especially with the rise of AI [[search](https://duckduckgo.com/?q=google%20military%20contracts&t=ffab&df=m&ia=news&iar=news)].

    I would urge you to look for privacy-respecting ethically sound alternatives. Browsers based on Firefox that support the WebExtensions API manifest V2, such as uBlock Origin, are a good place to start researching.

    ### Alternatives
    You could research the [ungoogled-chromium-portablelinux](https://github.com/ungoogled-software/ungoogled-chromium-portablelinux/releases) project which provides a portable ungoogled Chromium install. Here is a quick snippet if you'd like to take it for a test drive.
    ```
    if download_url=$(curl --connect-timeout 5 -sSL https://api.github.com/repos/ungoogled-software/ungoogled-chromium-portablelinux/releases/latest | jq -r '.assets[] | select(.name | test("linux\\.tar\\.xz$")) | .browser_download_url'); then
    mkdir -p ~/.local
    echo -n 'Downloading archive. Please wait... '
    if curl --connect-timeout 5 -sSL "$download_url" |bsdtar -xf - -C ~/.local; then
    echo 'installed OK'
    # create symlink to the latest ungoogled-chromium
    ln -fs "$(find ~/.local -name 'ungoogled-chromium*' | sort -h | tail -n1)"/chrome ~/.local/bin/chromium
    else
    echo FAILURE
    fi
    else
    echo 'Error determining font download_url'
    fi
    ```
    After install, you can launch the latest ungoogled-chromium-portablelinux by invoking `chromium` on the terminal.

    You will probably see a `gnome-keyring` prompt. I have no experience with this, so DYOR. [Here is the man page for `gnome-keyring`](https://manpages.debian.org/stable/gnome-keyring/gnome-keyring.1.en.html). I'm assuming it wants to use the keyring to read and write website secrets like usernames and passwords for saved sites, that sort of thing. Similar to the keychain in OS X. You'll probably need to take some steps to initialise the user keyring if you want to take advantage of its features.

    ### Portable Google Chrome?
    When researching, I found the "Google-Chrome-Portable-maker-for-linux" project [here](https://github.com/shivamgly/Google-Chrome-Portable-maker-for-linux). Which is discussed [here](https://askubuntu.com/a/1051236). It looks quite interesting. Keep in mind this relates to the Google Chrome browser distribution and is not ungoogled.

    ### Installing Google Chrome system wide
    Given Chrome's market share, it's understandable if you still have a Chrome use case, for example if you need to install Chrome to migrate away from it... or if Google surveillance don't bother you, or if you require it for projects and won't be using it for personal accounts and real data... I've included a quick start shell snippet below.

    🔐 **I would strongly recommend to block outbound connections from Chrome by default** and to selectively open up access for the specific use cases / hosts that you may have. This will mitigate some of the surveillance issues.

    For this you can research projects like [OpenSnitch](https://github.com/evilsocket/opensnitch) or [Firejail](https://firejail.wordpress.com/).
    ```
    # download latest Chrome
    chrome_dl_filename=google-chrome-stable_current_"$(dpkg --print-architecture)".deb
    curl -sSL https://dl.google.com/linux/direct/$chrome_dl_filename > ~/Downloads/"$chrome_dl_filename"
    # dry-run the install to check if you are happy with the install plan
    sudo apt install --dry-run --fix-broken ~/Downloads/"$chrome_dl_filename"
    # install Chrome system wide
    sudo apt install --fix-broken ~/Downloads/"$chrome_dl_filename"
    ```

    # tmux
    I'm assuming `tmux` is installed system wide per the prerequisites section.
    Installing `tmux` on a per user basis inside `~/.local` is possible but outside the scope of this gist.

    ## `~/.tmux.conf`
    Here is is a copy of my `tmux` config which may include some features you'll like including:
    * <kbd>ALT</kbd>+<kbd>PGUP</kbd> / <kbd>PGDN</kbd> to change between windows
    * <kbd>ALT</kbd>+<kbd>←</kbd> / <kbd>↑</kbd> / <kbd>→</kbd> / <kbd>↓</kbd> to change between panes
    * <kbd>CTRL</kbd>+<kbd>B</kbd> <kbd>|</kbd> (pipe) to split a pane vertically
    * <kbd>CTRL</kbd>+<kbd>B</kbd> <kbd>-</kbd> (minus/hyphen/dash) to split a pane horizontally
    ```
    cat <<EOF | base64 -d | gunzip > ~/.tmux.conf
    H4sIAAAAAAACA4VV+2/bNhD+3X/FQcbgdAnjZkMyIFu3DnkgBZJ4yAPY0BYGLZ0kIhIpkJQdb+3+
    9t2RkivngRkBQvFeHz9+dxyDayrloZEaHbRO6QK+gNQZiNFC0b8v0UGs6MOsQJRxWzzZXo5aHQyT
    ZNIvvxuNHHoQrgB0qWxQeFUjvB2NxmCxMjKD1OhcFZCrCmEnLaUuMH5UJpVeGQ3ewNq0FnyJ4Ov2
    cZ9DeAtWUns2tw7fRFAWHLmmKEKKf6f7mwAumatHeMC1o2XpfeOOp1PnZfpglmjzyqzIsZ7K6eHh
    0cHRTz8ehJSCAkBouDAE3CHVOAsngWR2kWx5nJFt2+E84apupXxabvH7e+WFtJZoI1tpWmLfIqHr
    mNVwJS4x95SuwtQLDgVxObDeqKJ8Yr4ZmO+bbdv9wHZqVnrbesooGdIfssD7Zho83sFtxB3vd5Ag
    ejHipTKtEy86hBwaH3t9jAZUWfiFSJHNRjq+k1pv/vWpeZcRelMUdKkL9CtEDWlrLdL9s1Ir6fwQ
    aEh0IhbBsEEQpFhATaARjOacmdETT1LUkm43+jmQrTc1aS+VVbXmKGGaoEQKpi2zEl2AyfNN1lI5
    b+xaVKqmZjp4Sz8q0BkzzGVLBHu0tdKygsSllg4hfjg8Sk1lbMI6MdWSFKKca+kfCwOWqoaL2dVZ
    OOTZ9Smrd/RqzkdeDlIyZ7ZFCJ/g2qYx1m+dx0nowwU3gVUZlU72Qqbvj+/SkOSWxbDWaWmNVkRd
    VPKOX5PIlab+I1K6TemJ2JS6sRsALsrCwacR0I9qr8D1qf5GEaM+/dzZM0UzRa4h4XIw/ue3Z757
    s+u92fn51wCMRcuUABfhviIsnUo4MGLaH4134eTu5nL3lmZW3288TDRiBjlRI1OvlnHYcLZcWedD
    GKvYESchMd0w8B8dcUMVp1lIV/YFSFkxZeJa12BAlQAVbNqY8UPodIzTrG+h4RnIq++kE3H7CmPh
    ahlPmpMks4yIJ624llTAWWhwEoSAmZjw0lOX2jAxpEUJq5La5xtBfKjAAD7R+lZkQrfB7vMBmGwP
    xh8XxTuL2efbv65PYHY9/tjp8vPeV4jjD8OMfguqG9qK6NLGZrxLPdNAWpnFAm24wA1gfhg89Xcv
    9/ccMudxPnelWc2j17zzguQgFLukLqS2hKZqC6XdJjh+w4TjRWec+qae/I8Hf9BMd2pR4TPfRFqi
    LVUpOt9mykwZouCYgGVGh7GAj7JuKnTHHRXDWgWJsV3MSTSW58k07s95PXnZ/X0MCQ8Vh3Uhr3kv
    lF+06QP65wEU8UErr2RFFwl3V/d/dqRBLTUNcAs7D4hNlFml6J2QsWtI+yRW42lGMtObB/bNyLZU
    tntzpwOSI9FjMgtXIs2K5JnTkOdpv9jvqXwuAW3mjaTXCbN5brrrf6kAAa7RfbuYsOry/gdppTS+
    +QgAAA==
    EOF
    ```

    ## The `tmux` Plugin Manager aka tpm
    The [tpm project](https://github.com/tmux-plugins/tpm) is a simple way to manage `tmux` plugins.

    ```
    git clone --depth=1 https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
    tmux new-session '~/.tmux/plugins/tpm/scripts/install_plugins.sh'
    ```
    Now you can launch `tmux` :)

    ### Updating plugins
    Launch `tmux` and invoke the `prefix` + <kbd>U</kbd> kbd shortcut.

    ## `xpanes`
    [`xpanes`](https://github.com/greymd/tmux-xpanes/) describes itself as "The ultimate terminal divider powered by [`tmux`](https://github.com/tmux/tmux/wiki)"

    ![enter image description here](https://raw.githubusercontent.com/wiki/greymd/tmux-xpanes/img/movie_v4.gif)

    This shell snippet will install the latest version of `xpanes` into the local bin:
    ```
    if xpanes_latest_version=$(curl --connect-timeout 5 -sSL https://api.github.com/repos/greymd/tmux-xpanes/releases/latest|grep '"tag_name":'|grep -Eo 'v[0-9\.]+'); then
    echo "xpanes latest version detected as: $xpanes_latest_version"
    echo -n 'Downloading and installing xpanes. Please wait... '
    if curl --create-dirs --connect-timeout 5 -sSL "https://raw.githubusercontent.com/greymd/tmux-xpanes/$xpanes_latest_version/bin/xpanes" -o ~/.local/bin/xpanes; then
    echo OK
    chmod +x ~/.local/bin/xpanes
    else
    echo FAILURE
    fi
    else
    echo 'There was a problem determining xpanes_latest_version'
    fi
    ```
    ### Updating `xpanes`
    Just run the snippet again in the future.

    # nord theme for `vim`
    We need a `vim` plugin manager for this, lets go with [`vim-plug`](https://github.com/junegunn/vim-plug). Here is a shell snippet to install `vim-plug`:
    ```
    if latest_version=$(curl --connect-timeout 5 -sSL https://api.github.com/repos/junegunn/vim-plug/releases/latest|grep '"tag_name":'|cut -d'"' -f4); then
    echo "vim-plug latest version detected as: $latest_version"
    echo -n 'Downloading and installing vim-plug. Please wait... '
    if curl --create-dirs --connect-timeout 5 -sSL "https://raw.githubusercontent.com/junegunn/vim-plug/$latest_version/plug.vim" -o ~/.vim/autoload/plug.vim; then
    echo OK
    else
    echo FAILURE
    fi
    else
    echo 'There was a problem determining xpanes_latest_version'
    fi
    ```
    A relevant `vim` config with some defaults:
    ```
    cat <<EOF >> ~/.vimrc
    " disable bracketed-paste - which prevents pasting commands into vim
    " https://en.wikipedia.org/wiki/Bracketed-paste
    " https://vimhelp.org/term.txt.html#xterm-bracketed-paste
    set t_BE=
    syntax on
    " enables support for 24-bit RGB color in terminal emulators that support it
    set termguicolors
    call plug#begin()
    " INFO: nord-vim plugin modifies formatoptions and removes t option
    " which prevents autowrapping to textwidth on paste
    Plug 'arcticicestudio/nord-vim'
    call plug#end()
    " conditional color scheme loading
    if filereadable(expand("~/.vim/plugged/nord-vim/colors/nord.vim"))
    colorscheme nord
    endif
    EOF
    ```

    Then run `vim -c 'PlugUpdate'` which will install the plugin(s) and then quit vim to finalise the install.

    Now try to edit a file, for example `vim ~/.vimrc` to see that the nord plugin/colorscheme is active.

    ## Updating vim plugins
    `vim -c 'PlugUpdate'` to update plugins and `vim -c 'PlugUpgrade'` to upgrade `vim-plug` itself.

    # `fzf`
    `fzf` describes itself as "a general-purpose command-line fuzzy finder" and improves the quality of life on the terminal, enhancing things like searching shell history, changing dirs and finding files.

    This approach installs `fzf on a per user basis rather than system wide.

    To install the latest version from GitHub inspired from the official docs [here](https://github.com/junegunn/fzf?tab=readme-ov-file#using-git):

    ```
    git clone --depth=1 https://github.com/junegunn/fzf.git ~/.fzf
    # run the installer and follow the prompts
    ~/.fzf/install
    ```
    💡 You'll want to logout / exit any terminal sessions to pick up the change.

    Check out this screencast by [@samoshkin](https://github.com/samoshkin) which explores `fzf` features.

    ## Updating fzf
    ```
    ( cd ~/.fzf && git pull && ~/.fzf/install )
    ```

    # Sublime Text
    [Sublime Text](https://www.sublimetext.com/) as its name suggests is extremely good. Back in ~2008 creator Jon Skinner had some really novel ideas on improving UI/UX and Sublime introduced and made the Command Palette popular which other apps have since implemented their own flavours of. I remember trying the early versions and being blown away by it.

    Another prominent name associated to Sublime Text is Will Bond who is the author/hoster of the Sublime Text package repo hosted at https://packagecontrol.io/. Will was one of the primary engineers for the v3 and v4 releases of Sublime Text and has been instrumental figure in the Sublime package/extensibility community.

    A key UX paradigm of Sublime is **palettes,** which take keystrokes from the user and fuzzy match against commands and files facilitating mouseless navigation:
    1. The **Command Palette:** <kbd>ctrl</kbd>+<kbd>shift</kbd>+<kbd>p</kbd> on Win/Linux, and <kbd>cmd</kbd>+<kbd>shift</kbd>+<kbd>p</kbd> on OS X.
    ![enter image description here](https://live.staticflickr.com/7159/6771113149_a59eb88a8a.jpg)

    1. **Goto Anything** is also implemented in a Palette: <kbd>ctrl</kbd>+<kbd>p</kbd> on Win/Linux, and <kbd>cmd</kbd>+<kbd>p</kbd> on OS X.
    ![Goto Anything Palette](https://docs.sublimetext.io/assets/goto.Cks-Bajm.png)

    Sublime is highly customisable through its preferences system and extensible through its package/plugin system. Packages are authored in Python. Sublime has a console and `vim` emulation... If you've never tried it I highly recommend taking it for a test drive.

    Although Sublime has always worked in evaluation mode without restrictions, I can really recommend the software and would encourage you to buy a licence if you can afford it and feel the same way as so many users. Its worth reading the [sales FAQ](https://www.sublimehq.com/sales_faq) if you are considering buying a license, which as of writing provides 3 years of updates.

    **A little history on my text editor usage**
    I was born at the beginning of the 80's... so I've used a few text editors over the years. [`vim`](https://en.wikipedia.org/wiki/Vim_%28text_editor%29) has a special place in my heart and its my goto on the Terminal. On Windows I've used [Notepad++](https://notepad-plus-plus.org/) on and off, and heavily used [TextMate](https://macromates.com/) on OS X for about a decade when I was daily driving Apple hardware.

    That being said, I've been using [Sublime Text](https://www.sublimetext.com) for a long time and procured it for a number of teams in the enterprise. Its very hard to beat - in the last decade its my preferred editor. It works flawlessly on Windows, Linux and OS X.

    I've only found one issue with Sublime Text where I needed to fallback to `vim` which I posted about [here](https://github.com/sublimehq/sublime_text/issues/182#issuecomment-2781765812). Its related to how Sublime Text handles files with mixed line endings.

    ## Docs
    An officially endorsed community driven set of Docs exists for Sublime Text: https://docs.sublimetext.io/ which to be honest, makes the [official docs](https://www.sublimetext.com/docs/) look... a bit shit.

    ## Per user basis install
    As of 2025-April direct downloads are available via https://www.sublimetext.com/download_thanks. Click the "direct download" text/link to expand the options. You can see the downloads are hosted on https://download.sublimetext.com and have sigs and keys available for file verification.

    Here is an example shell snippet from the time of writing:
    ```
    curl -sSL 'https://download.sublimetext.com/sublime_text_build_4192_x64.tar.xz' | bsdtar -xf - -C ~/.local && ln -s ~/.local/sublime_text/sublime_text ~/.local/bin
    ```
    If successful, you should now be able to invoke `sublime_text` in the terminal.

    ## System wide install
    Tweaked from https://www.sublimetext.com/docs/linux_repositories.html#apt
    ```
    curl -sSL https://download.sublimetext.com/sublimehq-pub.gpg | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/sublimehq-archive.gpg > /dev/null
    echo "deb https://download.sublimetext.com/ apt/stable/" | sudo tee /etc/apt/sources.list.d/sublime-text.list
    sudo apt update
    sudo aptitude install sublime-text
    ```
    ## Plugins aka Packages
    Head over to https://packagecontrol.io/ and knock yourself out. The repo hosts ~2,500 packages.

    Kudos to Will for hosting the repo! ❤️

    ### Installing Package Control
    Open the Command Palette and start to type: Install Package Control, press <kbd>enter</kbd>
    OR
    In the GUI menu bar: Tools → Install Package Control...
    OR
    Manually:
    1) Exit Sublime
    2) Install via `curl`
    ```
    curl -sSL 'https://packagecontrol.io/Package%20Control.sublime-package' > "~/.config/sublime-text/Installed Packages/Package Control.sublime-package"
    ```
    3) Start Sublime and either inspect the console log or look for **Package** entries in the Command Palette

    Here is a collection of some of the packages which I find extremely useful / productive:
    ### Code​Formatter
    by Avtandil Kikabidze aka LONGMAN https://packagecontrol.io/packages/CodeFormatter
    Formats (beautifies) source code and supports various languages including PHP, JavaScript, JSON, HTML, Python ...

    ### AsciiConverter
    by bg-k https://packagecontrol.io/packages/AsciiConverter

    ![enter image description here](https://camo.githubusercontent.com/acf0209aba356001cb782dd14cc18e157b43581065a1093c3d464b796b07abc4/687474703a2f2f62672d6b2e6769746875622e696f2f4173636969436f6e766572746572506c7567696e2f64656d6f2e676966)

    ### Column Select
    by ehuss https://packagecontrol.io/packages/Column%20Select

    ![enter image description here](https://github.com/ehuss/Sublime-Column-Select/raw/master/demo1.gif)

    ### Filter Lines
    by davidpeckham https://packagecontrol.io/packages/Filter%20Lines
    I use this ALOT. Amazing package!

    ![enter image description here](https://github.com/davidpeckham/sublime-filterlines/raw/master/filter_lines_demo.gif)

    ### Filter​Pipes
    by tylerl https://packagecontrol.io/packages/FilterPipes
    A very useful package and similar to `:%!<command>` in `vim` filtering/piping the buffer/file through a command and replacing the buffer with the output.

    ![enter image description here](https://raw.githubusercontent.com/tylerl/FilterPipes/media/fp_sort.gif)

    ### Neo​Vintageous
    by NeoVintageous https://packagecontrol.io/packages/NeoVintageous
    A powerful `vim` emulator for Sublime Text. Designed to be fast, reliable, and with zero configuration required.

    ### Rsync SSH
    by davidolrik https://packagecontrol.io/packages/Rsync%20SSH
    This package lets you keep a remote in sync with rsync, and syncs the current file on save. I don't use it that often but its been a productivity booster in the past.

    ### Select​Until
    by xavi- https://packagecontrol.io/packages/SelectUntil
    A real productivity booster when handling text data files.
    > This package allows you to **extend one ore more selections until the next instance of a search term,** making it super easy to select or edit multiple pieces of text that are similar but not quite the same.
    ### Show Character Code
    by borislubimov https://packagecontrol.io/packages/Show%20Character%20Code
    Very useful package to display detailed character information in the status bar

    ![enter image description here](https://camo.githubusercontent.com/4c627e9c58322baa4dd7e136cb03f95a80652ca8088bee3c44f1465d495ab7c0/687474703a2f2f692e696d6775722e636f6d2f434a6a30426e632e676966)

    ### Trimmer
    by jonlabelle https://packagecontrol.io/packages/Trimmer
    ![enter image description here](https://raw.githubusercontent.com/jonlabelle/Trimmer/master/screenshots/command_palette.png)

    ### URLEncode
    by btoews https://packagecontrol.io/packages/URLEncode
    Encodes and decodes URLs.

    ### xpath
    by rosshadden https://packagecontrol.io/packages/xpath
    Versatile and comprehensive XPath 1.0 package for processing HTML and XML with xpath. Extensive demo gifs have been published on the GitHub repo: https://github.com/rosshadden/sublime-xpath. Includes a markup linter/formatter.

    ![enter image description here](https://cloud.githubusercontent.com/assets/11882719/12841929/245cdbd4-cbf8-11e5-8da0-26119e5213ab.gif)

    # Beyond Compare
    A similar story to text editors... I've used a number of text/file comparison and merge tools over the years. Beyond Compare is hands down the best I've tried to date and I've purchased a number of licences over the years both personally and in the enterprise, to support its great team and further development.

    ## Per user basis install
    https://www.scootersoftware.com/kb/linux_install#targz
    TODO resolve the following deps:
    ```
    op-demo@debian-de-demo:~$ ~/Downloads/bcompare-5.0.7.30840/install.sh
    install prefix? [/home/op-demo] /home/op-demo/.local
    /home/op-demo/Downloads/bcompare-5.0.7.30840/install.sh: line 172: ldconfig: command not found
    ```

    ## System wide install
    https://www.scootersoftware.com/kb/linux_install#debian
    ```
    # procure the .deb
    ( cd ~/Downloads; curl -sSLO 'https://www.scootersoftware.com/files/bcompare-5.0.7.30840_amd64.deb' )
    # install
    sudo apt update
    sudo apt install --fix-broken ~/Downloads/bcompare-5.0.7.30840_amd64.deb
    ```


    1 change: 0 additions & 1 deletion tmux and xpanes setup.md
    Original file line number Diff line number Diff line change
    @@ -1 +0,0 @@
    .
  19. kyle0r created this gist Apr 22, 2025.
    1 change: 1 addition & 0 deletions tmux and xpanes setup.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    .