This block of elisp loads an elisp file to set variables that can be
used in :tangle
arguments. It will be run automatically at document
load due to local variables set at the bottom of this file; the user
probabably needs to authorise this with ‘y’.
(setq system
(let ((hostname (system-name)))
(cond ((member hostname '("Angel" "Angel.lan" "Angel.local")) "Angel")
((member hostname '("ajj-mbp-1" "ajj-mbp-1.local"
"dock-ajj-mbp-1" "dock-ajj-mbp-1.esc.rl.ac.uk"))
"ajj-mbp-1")
;; To check the last part of hostname, we first pad to at least 16 char to avoid error on short names
((string= (substring (string-pad (system-name) 16) -16) "nubes.stfc.ac.uk") "SCD-cloud")
((string-match "host-[[:digit:]]+-[[:digit:]]+-[[:digit:]]+-[[:digit:]]+" (system-name)) "SCD-cloud")
('t hostname))
))
;; Centering, rows only supported for patched dmenu
(setq dmenu-patched-p
(cond ((member system '("Arctopus" "scpc041")) 't)
('t nil)))
(defmacro if-workstation (arg1 arg2)
`(if (member ,system '("Arctopus" "scpc041" "ajj-mbp-1" "SCLT452Mac"))
,arg1 ,arg2))
i3 configuration mostly lives in one file.
# Super key
set $mod Mod4
font pango:Inconsolata 8
# Start XDG autostart .desktop files using dex. See also
# https://wiki.archlinux.org/index.php/XDG_Autostart
exec --no-startup-id dex-autostart --autostart --environment i3
# Hide titlebars unless tabbing/stacking
for_window [class="^.*"] border none
# NetworkManager is the most popular way to manage wireless networks on Linux,
# and nm-applet is a desktop environment-independent system tray GUI for it.
exec --no-startup-id nm-applet
# Use Mouse+$mod to drag floating windows to their wanted position
floating_modifier $mod
# move tiling windows via drag & drop by left-clicking into the title bar,
# or left-clicking anywhere into the window while holding the floating modifier.
tiling_drag modifier titlebar
# start a terminal
bindsym $mod+Return exec alacritty msg create-window || alacritty
# kill focused window
bindsym $mod+Shift+q kill
# change focus
bindsym $mod+j focus left
bindsym $mod+k focus down
bindsym $mod+l focus up
bindsym $mod+semicolon focus right
# move focused window
bindsym $mod+Shift+j move left
bindsym $mod+Shift+k move down
bindsym $mod+Shift+l move up
bindsym $mod+Shift+semicolon move right
# split in horizontal orientation
bindsym $mod+h split h
# split in vertical orientation
bindsym $mod+v split v
# enter fullscreen mode for the focused container
bindsym $mod+f fullscreen toggle
# change container layout (stacked, tabbed, toggle split)
bindsym $mod+s layout stacking
bindsym $mod+w layout tabbed
bindsym $mod+e layout toggle split
# toggle tiling / floating
bindsym $mod+Shift+space floating toggle
# change focus between tiling / floating windows
bindsym $mod+space focus mode_toggle
# focus the parent container
bindsym $mod+a focus parent
# focus the child container
bindsym $mod+z focus child
# Define names for default workspaces for which we configure key bindings later on.
# We use variables to avoid repeating the names in multiple places.
set $ws1 "1"
set $ws2 "2"
set $ws3 "3"
set $ws4 "4"
set $ws5 "5"
set $ws6 "6"
set $ws7 "7"
set $ws8 "8"
set $ws9 "9"
set $ws10 "10"
# switch to workspace
bindsym $mod+1 workspace number $ws1
bindsym $mod+2 workspace number $ws2
bindsym $mod+3 workspace number $ws3
bindsym $mod+4 workspace number $ws4
bindsym $mod+5 workspace number $ws5
bindsym $mod+6 workspace number $ws6
bindsym $mod+7 workspace number $ws7
bindsym $mod+8 workspace number $ws8
bindsym $mod+9 workspace number $ws9
bindsym $mod+0 workspace number $ws10
# move focused container to workspace
bindsym $mod+Shift+1 move container to workspace number $ws1
bindsym $mod+Shift+2 move container to workspace number $ws2
bindsym $mod+Shift+3 move container to workspace number $ws3
bindsym $mod+Shift+4 move container to workspace number $ws4
bindsym $mod+Shift+5 move container to workspace number $ws5
bindsym $mod+Shift+6 move container to workspace number $ws6
bindsym $mod+Shift+7 move container to workspace number $ws7
bindsym $mod+Shift+8 move container to workspace number $ws8
bindsym $mod+Shift+9 move container to workspace number $ws9
bindsym $mod+Shift+0 move container to workspace number $ws10
# cycle workspaces
bindsym $mod+Tab workspace next
bindsym $mod+Shift+Tab workspace prev
# reload the configuration file
bindsym $mod+Shift+c reload
# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
bindsym $mod+Shift+r restart
# exit i3 (logs you out of your X session)
bindsym $mod+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -B 'Yes, exit i3' 'i3-msg exit'"
# resize window (you can also use the mouse for that)
mode "resize" {
# These bindings trigger as soon as you enter the resize mode
# Pressing left will shrink the window’s width.
# Pressing right will grow the window’s width.
# Pressing up will shrink the window’s height.
# Pressing down will grow the window’s height.
bindsym j resize shrink width 10 px or 10 ppt
bindsym k resize grow height 10 px or 10 ppt
bindsym l resize shrink height 10 px or 10 ppt
bindsym semicolon resize grow width 10 px or 10 ppt
# same bindings, but for the arrow keys
bindsym Left resize shrink width 10 px or 10 ppt
bindsym Down resize grow height 10 px or 10 ppt
bindsym Up resize shrink height 10 px or 10 ppt
bindsym Right resize grow width 10 px or 10 ppt
# back to normal: Enter or Escape or $mod+r
bindsym Return mode "default"
bindsym Escape mode "default"
bindsym $mod+r mode "default"
}
bindsym $mod+r mode "resize"
# Appearance tweaks
gaps inner 4
# gaps outer -4
# Start i3bar to display a workspace bar (plus the system information i3status
# finds out, if available)
# bar {
# status_command i3status
# }
On patched systems, use a modified dmenu_run
dmenu_path | dmenu -c -l 6 -g 3 "$@" | ${SHELL:-"/bin/sh"} &
Launch dmenu or i3-dmenu-desktop with shortcuts
(if dmenu-patched-p "-c -l 6 -g 3" "")
bindsym $mod+d exec --no-startup-id dmenu_run <<get_dmenu_args()>>
bindsym $mod+Shift+d exec --no-startup-id i3-dmenu-desktop --dmenu='dmenu -i <<get_dmenu_args()>>'
Use picom (may not be available on all systems)
- on scpc041 and Arctopus this is started by
/etc/xdg/autostart/picom.desktop
so redundant to also include in i3 config
# Enable compositing (i.e. for transparent terminals)
exec --no-startup-id picom --backend glx
Actual picom configuration lives in another file
corner-radius = 10;
rounded-corners-exclude = [
"window_type = 'dock'",
"window_type = 'desktop'"
];
backend = "glx";
inactive-dim = 0.2;
inactive-opacity = 0.9;
opacity-rule=["100:class_g = 'i3lock'"];
This is system-dependent, use xrandr commands to rotate and position monitors
# Sort out monitor positions
exec xrandr --output DVI-D-0 --rotate left --right-of HDMI-0 --pos 1980x0
exec xrandr --output HDMI-0 --pos 0x550
# They are in the wrong order so assign initial workspaces
workspace 1 output HDMI-0
workspace 2 output DVI-D-0
# Sort out monitor positions
exec xrandr --output DP-1 --rotate left --left-of DP-2 --pos 0x0
exec xrandr --output DP-2 --pos 1080x520
# They are in the wrong order so assign initial workspaces
workspace 1 output DP-2
workspace 2 output DP-1
(cond ((equal system "scpc041") "-i /usr/share/backgrounds/f34/default/f34-02-night.png")
((equal system "Arctopus") "-i /home/adam/Pictures/Wallpapers/lock-screen-big.png")
('t ""))
# xss-lock grabs a logind suspend inhibit lock and will use i3lock to lock the
# screen before suspend. Use loginctl lock-session to lock your screen.
exec --no-startup-id xss-lock --transfer-sleep-lock -- i3lock --nofork <<get_wallpaper_args()>>
We also create a shell script for screen lock, shutdown etc, borrowed from https://faq.i3wm.org/question/239/how-do-i-suspendlockscreen-and-logout.1.html
lock() {
i3lock <<get_wallpaper_args()>>
}
case "$1" in
lock)
lock
;;
logout)
i3-msg exit
;;
suspend)
systemctl suspend
;;
hibernate)
systemctl hibernate
;;
reboot)
systemctl reboot
;;
shutdown)
systemctl poweroff
;;
*)
echo "Usage: $0 {lock|logout|suspend|hibernate|reboot|shutdown}"
exit 2
esac
exit 0
But instead of using an i3 mode, try using dmenu
bindsym $mod+c exec echo -e "lock\nlogout\nsuspend\nhibernate\nreboot\nshutdown" | dmenu <<get_dmenu_args()>> "$@" | xargs ~/.local/bin/i3exit
# Fancy status bar
exec --no-startup-id $HOME/.config/polybar/launch.sh
# Wallpaper
exec --no-startup-id nitrogen --restore
Include polybar configuration with i3 configuration as I use them together. (To learn more about how to configure Polybar go to https://github.com/polybar/polybar. The wiki page is quite helpful.)
for m in $(xrandr --listactivemonitors | tail -n +2 | grep -o '[^ ]*$')
do
MONITOR=$m polybar --reload bottom &
done
else
polybar --reload bottom &
fi
(cond ((member system '("Arctopus" "scpc041"))
"[colors]
background = #2D3540
background-alt = #63738C
foreground = #C5C8C6
primary = #CFA43E
secondary = #8ABEB7
alert = #A54242
disabled = #707880"
)
('t ""))
<<get_polybar_colours()>>
[bar/bottom]
monitor = ${env:MONITOR:HDMI-0}
bottom = true
; override-redirect = true
override-redirect = false
width = 100%
height = 16pt
radius = 0
; dpi = 96
background = ${colors.background}
foreground = ${colors.foreground}
line-size = 3pt
border-size = 0pt
border-color = #00000000
padding-left = 0
padding-right = 1
module-margin = 1
separator = |
separator-foreground = ${colors.disabled}
font-0 = "Inconsolata:weight=black:pixelsize=10"
;font-0 = "VT323:pixelsize=14"
modules-left = i3
modules-right = filesystem pulseaudio memory cpu eth date
cursor-click = pointer
scroll-up = "#i3.prev"
scroll-down = "#i3.next"
enable-ipc = true
; tray-position = right
; wm-restack = generic
; wm-restack = bspwm
wm-restack = i3
; override-redirect = true
[module/xworkspaces]
type = internal/xworkspaces
label-active = %name%
label-active-background = ${colors.background-alt}
label-active-underline= ${colors.primary}
label-active-padding = 1
label-occupied = %name%
label-occupied-padding = 1
label-urgent = %name%
label-urgent-background = ${colors.alert}
label-urgent-padding = 1
label-empty = %name%
label-empty-foreground = ${colors.disabled}
label-empty-padding = 1
[module/xwindow]
type = internal/xwindow
label = %title:0:60:...%
[module/filesystem]
type = internal/fs
interval = 25
mount-0 = /
label-mounted = %{F#F0C674}%mountpoint%%{F-} %percentage_used%%
label-unmounted = %mountpoint% not mounted
label-unmounted-foreground = ${colors.disabled}
[module/pulseaudio]
type = internal/pulseaudio
format-volume-prefix = "VOL "
format-volume-prefix-foreground = ${colors.primary}
format-volume = <label-volume>
label-volume = %percentage%%
label-muted = muted
label-muted-foreground = ${colors.disabled}
click-right = pavucontrol
[module/i3]
type = internal/i3
pin-workspaces = true
show-urgent = true
strip-wsnumbers = true
index-sort = true
enable-click = false
enable-scroll = false
; ws-icon-[0-9]+ = <label>;<icon>
; NOTE: The <label> needs to match the name of the i3 workspace
; Neither <label> nor <icon> can contain a semicolon (;)
ws-icon-0 = 1;♚
ws-icon-1 = 2;♛
ws-icon-2 = 3;♜
ws-icon-3 = 4;♝
ws-icon-4 = 5;♞
ws-icon-default = ♟
; NOTE: You cannot skip icons, e.g. to get a ws-icon-6
; you must also define a ws-icon-5.
; NOTE: Icon will be available as the %icon% token inside label-*
; Available tags:
; <label-state> (default) - gets replaced with <label-(focused|unfocused|visible|urgent)>
; <label-mode> (default)
format = <label-state> <label-mode>
; Available tokens:
; %mode%
; Default: %mode%
label-mode = %mode%
label-mode-padding = 2
label-mode-background = #e60053
; Available tokens:
; %name%
; %icon%
; %index%
; %output%
; Default: %icon% %name%
label-focused = %index%
label-focused-foreground = ${colors.primary}
label-focused-background = ${colors.background}
label-focused-underline = ${colors.primary}
label-focused-padding = 2
; Available tokens:
; %name%
; %icon%
; %index%
; %output%
; Default: %icon% %name%
label-unfocused = %index%
label-unfocused-padding = 2
; Available tokens:
; %name%
; %icon%
; %index%
; %output%
; Default: %icon% %name%
label-visible = %index%
label-visible-underline = ${colors.foreground}
label-visible-padding = 2
; Available tokens:
; %name%
; %icon%
; %index%
; %output%
; Default: %icon% %name%
label-urgent = %index%
label-urgent-foreground = #000000
label-urgent-background = #bd2c40
label-urgent-padding = 4
; Separator in between workspaces
;label-separator = |
;label-separator-padding = 2
;label-separator-foreground = #ffb52a
[module/xkeyboard]
type = internal/xkeyboard
blacklist-0 = num lock
label-layout = %layout%
label-layout-foreground = ${colors.primary}
label-indicator-padding = 2
label-indicator-margin = 1
label-indicator-foreground = ${colors.background}
label-indicator-background = ${colors.secondary}
[module/memory]
type = internal/memory
interval = 2
format-prefix = "RAM "
format-prefix-foreground = ${colors.primary}
label = %percentage_used:2%%
[module/cpu]
type = internal/cpu
interval = 2
format-prefix = "CPU "
format-prefix-foreground = ${colors.primary}
label = %percentage:2%%
[network-base]
type = internal/network
interval = 5
format-connected = <label-connected>
format-disconnected = <label-disconnected>
label-disconnected = %{F#F0C674}%ifname%%{F#707880} disconnected
[module/wlan]
inherit = network-base
interface-type = wireless
label-connected = %{F#F0C674}%ifname%%{F-} %essid% %local_ip%
[module/eth]
inherit = network-base
interface-type = wired
label-connected = %{F#F0C674}%ifname%%{F-} %local_ip%
[module/date]
type = internal/date
interval = 1
date = %H:%M
date-alt = %Y-%m-%d %H:%M:%S
label = %date%
label-foreground = ${colors.primary}
[settings]
screenchange-reload = true
pseudo-transparency = true
; vim:ft=dosini
Configuration for Alacritty GPU-enhanced terminal emulator. I mostly use defaults for this, actually!
Alacritty has deprectated the yaml config I was using, and provided a migration tool. Still, I need to hack some of my literate emacs magic back in by hand…
Transparency is fun and lets us see our desktop background while working!
[window]
opacity = 0.9
Colour theme for Arctopus matching Hob wallpaper:
[colors.bright]
black = "0x63738c"
blue = "0x8cc7fe"
cyan = "0x34e2e2"
green = "0x94a7ae"
magenta = "0xad7fa8"
red = "0xef2929"
white = "0xeeeeec"
yellow = "0xe1c258"
[colors.normal]
black = "0x2d3540"
blue = "0x6c84a4"
cyan = "0x06989a"
green = "0x757f89"
magenta = "0x75507b"
red = "0xcc0000"
white = "0xd3d7cf"
yellow = "0xcfa43e"
[colors.primary]
background = "0x2d3c59"
foreground = "0xecf2f0"
Emacs can require a workaround to deal with glibc incompatibility; see corresponding section of Bash config for more info.
if status is-interactive
# Commands to run in interactive sessions can go here
if test -f "/usr/lib64/libc_malloc_debug.so.0"
set -x EDITOR="LD_PRELOAD=/usr/lib64/libc_malloc_debug.so.0 emacsclient -t"
else
set -x EDITOR "emacsclient -t"
end
set -x ALTERNATE_EDITOR ''
alias em $EDITOR
end
I might have installed some Chicken Scheme libraries, if so then export relevant variables.
set MY_CHICKEN_REPOSITORY $HOME/opt/eggs/lib/chicken/5
if test -d $MY_CHICKEN_REPOSITORY
set -x CHICKEN_INSTALL_REPOSITORY $MY_CHICKEN_REPOSITORY
set -x CHICKEN_REPOSITORY_PATH $MY_CHICKEN_REPOSITORY
end
Some systems don’t set ~/.local/bin
or /usr/bin
automatically. The
former seems a liability for non-interactive use, wheras the latter
should really always be available.
I also sometimes have a separate ~/bin
; wheras ~.local/bin
is for
things installed by condax or Pip, ~/bin
is mostly for things I
compiled locally.
if not contains /usr/bin $PATH
set -xp PATH /usr/bin
end
if status is-interactive
for BINDIR in $HOME/.local/bin $HOME/bin
if not contains $BINDIR $PATH
set -xp PATH $BINDIR
end
end
end
I’m currently having some trouble on Arctopus where /usr/bin always
ends up really early on the path; I think this is happening before
Fish is launched, but haven’t yet found where. Could be /etc/gdm
?
On a Mac we also want homebrew
if test -d /opt/homebrew
eval (/opt/homebrew/bin/brew shellenv)
end
I use Conda on most machines but it’s not always installed the same way. On Fedora workstations we use system installation. Otherwise, have a look to see if some kind of (micro)mamba is available and get the fish shell hook set up.
Note that with older versions of fish (3.1ish?) the micromamba shell init will fail, because it uses more recent features of string-split.
if test -d /home/adam/.conda/envs/science
# This is Arctopus, system Conda is in charge
eval conda "shell.fish" "hook" $argv | source
else if test -d "$MAMBA_ROOT_PREFIX" -a -f "$MAMBA_EXE"
# Mamba path already configured, this is probably a mambaorg/micromamba container
else if test -d "$HOME/mambaforge"
# Probably a macbook
set MAMBA_ROOT_PREFIX $HOME/mambaforge
set CONDA_EXE $HOME/mambaforge/bin/conda
else if test -d "$HOME/micromamba"
# Micromamba unpacked in home directory, probably a VM or server
set MAMBA_ROOT_PREFIX $HOME/micromamba
set MAMBA_EXE (which micromamba)
end
if test -d "$HOME/mambaforge"
# Probably a macbook
eval $CONDA_EXE "shell.fish" "hook" $argv | source
source $MAMBA_ROOT_PREFIX/etc/fish/conf.d/mamba.fish
else if test -f "$MAMBA_EXE"
$MAMBA_EXE shell hook --shell fish --root-prefix $MAMBA_ROOT_PREFIX | source
else if test -f "$CONDA_EXE"
eval $CONDA_EXE "shell.fish" "hook" $argv | source
source $MAMBA_ROOT_PREFIX/etc/fish/conf.d/mamba.fish
end
For convenience, the “n” function for use with nnn file manager is included in this repository. I didn’t write it so not much point having it in the literate file here. It is copied to . config/fish/functions
if which zoxide &> /dev/null
zoxide init fish | source
end
If environment modules are installed:
- initialise
- add user module path
- load any default modules from ~/.modules.
- ~/.modules is a non-standard config file that is not managed here. It should just contain a space-separated series of modules to load.
if test -f /usr/share/Modules/init/fish
source /usr/share/Modules/init/fish
set -xp MODULEPATH $HOME/.local/modulefiles
if test -f $HOME/.modules
module load (cat $HOME/.modules | string split -n " ")
end
end
Quarantined blocks: not exported. Move to another section if needed.
~/.local/bin is an important place used by, among other things, pip
install --user
. Adding to PATH doesn’t seem to be necessary for fish
on Arctopus, but I suspect it’s a complicated machine-specific thing
that might change as I start cleaning things up.
set -xp PATH $HOME/.local/bin
Some git aliases should go into ~/src/mantid/.git/config if it
exists. As well as the usual add-data
which is needed to upload test
data, we can add some aliases that make working from Fish a bit nicer.
(Basically, the mamba-installed GCC doesn’t configure the Fish
environment properly. The simplest workaround is to wrap our
build/test runs in a bash call.)
if test -f $HOME/src/mantid/.git/config
pushd $HOME/src/mantid
git config alias.build '!bash -cl \'$(basename $MAMBA_EXE) activate mantid-developer && cd ~/src/mantid && cmake --preset=linux && cd build && ninja\''
git config alias.build-tests '!bash -cl \'$(basename $MAMBA_EXE) activate mantid-developer && cd ~/src/mantid && cmake --preset=linux && cd build && ninja AllTests\''
git config alias.ctest '!bash -cl \'$(basename $MAMBA_EXE) activate mantid-developer && cd ~/src/mantid/build && ctest $*\' -'
git config alias.systemtest '!bash -cl \'$(basename $MAMBA_EXE) activate mantid-developer && cd ~/src/mantid/build && ./systemtest $*\' -'
popd
end
I still get a bit confused about bashrc vs bash_profile…
Some helpful stuff here https://unix.stackexchange.com/questions/170493/login-non-login-and-interactive-non-interactive-shells
- bash_profile is loaded for login shells
- i.e. a shell you would need to enter a username/password for
~/.bashrc
is loaded for non-login interactive shells- Easiest way to get one of these is open graphical terminal from desktop GUI
- Of course we also usually source
~/.bashrc
from~/.bash_profile
- Interactive shells have a prompt ($PS1) and source
/etc/profile
,~/.profile
- Non-interactive shells for scripts etc will generally also be non-login.
- source
/etc/bashrc
- also receives exported variables from the parent shell
- source
Yes, bash_profile is for login sessions and bashrc is for non-login
but “interactive” shells. It’s generally recommended that PATH stuff
happens in bash_profile and aliases/functions happen in bashrc. This
is due to the way they are inherited: we don’t want export
PATH=blah:$PATH
to be extended in every subshell, and
aliases/functions do not automatically get passed into subshells.
(Presumably this is why it is important to EXPORT any path manipulation; this allows it to get into any non-login subshells you launch.)
~/.profile
is run by non-bash login sessions. Usually this will be
the graphical interface.
On Arctopus we add ~/.local/bin to path at this point so that the custom build of dmenu is available to i3. This seems a slightly dangerous/sweeping way of doing that; maybe it would be better to limit the scope to a directory that only contains those programs.
We’ll put this under the “bash” folder which isn’t strictly correct
(it uses sh
) but makes sense when installing things.
# Put custom scripts on the path where i3 can see them
if [ -d "$HOME/.local/bin" ] ; then
PATH="$HOME/.local/bin:$PATH"
fi
Source system-wide profile if available. (Is this actually necessary? Maybe not.)
if [ -f /etc/bashrc ]; then
source /etc/bashrc
fi
Whether using lmod or the old tcl environment-modules, the standard location for init files is the same.
for MODULEINIT in /usr/share/Modules/init/bash /usr/local/opt/modules/init/bash
do
if [ -f ${MODULEINIT} ]; then
source ${MODULEINIT}
fi
done
Add a user directory for custom modulefiles:
export MODULEPATH=${HOME}/.local/modulefiles:${MODULEPATH}
Quarantined blocks: not exported. Move to another section if needed.
Not sure what program I have ~/.cabal/bin for. I know that’s for Haskell stuff but it doesn’t seem to be on Arctopus. Maybe just add for whatever machines use this?
export PATH=$HOME/.cabal/bin:$PATH
Intel MKL things: I don’t think I really use these any more but it was a nuisance to figure out the first time.
for INTEL_INIT in /opt/intel/mkl/bin/mklvars.sh /opt/intel/bin/ifortvars.sh
do
if [ -f ${INTEL_INIT} ]; then
source ${INTEL_INIT} intel64
fi
done
Most machines need ~/.local/bin adding, set it here and keep an eye out for where it might be redundant.
export PATH=$HOME/.local/bin:$PATH
I might have installed some Chicken Scheme libraries, if so then export relevant variables.
MY_CHICKEN_REPOSITORY=$HOME/opt/eggs/lib/chicken/5
if test -d $MY_CHICKEN_REPOSITORY
then
export CHICKEN_INSTALL_REPOSITORY=$MY_CHICKEN_REPOSITORY
export CHICKEN_REPOSITORY_PATH=$MY_CHICKEN_REPOSITORY
fi
The choice of editor is fairly clear at this point.
ALTERNATE_EDITOR=""
means emacsclient will start a new daemon if
none is available. This makes opening a new editor instantaneous
after the first one.
LD_PRELOAD is needed when using Emacs from conda-forge (built against old libc) on a recent Linux version (built against new libc). Apparently Emacs was pretty much the only program using this deprecated feature! See conda-forge/emacs-feedstock#63
if [[ -f "/usr/lib64/libc_malloc_debug.so.0" ]]; then
export EDITOR="LD_PRELOAD=/usr/lib64/libc_malloc_debug.so.0 emacsclient -t"
else
export EDITOR="emacsclient -t"
fi
export ALTERNATE_EDITOR=""
On Mac the conda setup gets put in .bash_profile as this is the only file people can assume will be run. For now put it here in a system-specific block; should generalise this at some point as we have done for fish.
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/Users/adam/mambaforge/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__conda_setup"
else
if [ -f "/Users/adam/mambaforge/etc/profile.d/conda.sh" ]; then
. "/Users/adam/mambaforge/etc/profile.d/conda.sh"
else
export PATH="/Users/adam/mambaforge/bin:$PATH"
fi
fi
unset __conda_setup
if [ -f "/Users/adam/mambaforge/etc/profile.d/mamba.sh" ]; then
. "/Users/adam/mambaforge/etc/profile.d/mamba.sh"
fi
# <<< conda initialize <<<
Source bashrc for the stuff that should be run for every bash shell
source $HOME/.bashrc
Source system-wide bashrc if available
if [ -f /etc/bashrc ]; then
source /etc/bashrc
fi
If there are some custom environment modules that should be loaded in
each shell session, they go in ~/.modules
. Not clear if this is
needed any more.
if [ -f $HOME/.modules ]; then
module load $(cat $HOME/.modules)
fi
Non-ancient versions of tmux set TERM to tmux-256color, but not many tools know how to work with that so use screen-256color instead.
if [ $TERM = tmux-256color ]; then
export TERM=screen-256color
fi
Compatibility fix for new versions of glibc with conda-forge emacs
export LD_PRELOAD=/usr/lib64/libc_malloc_debug.so.0
Check the window size after each command, updating LINES and COLUMNS
as necessary. This is only worth doing for interactive sessions so we
look for “i” in the $-
variable. (This is somewhat Bash specific.)
if [[ $- == *i* ]]; then
shopt -s checkwinsize
fi
Colour handling is a bit system/OS-specific.
On MacOS we pass -G
to ls; this does something totally different on
other versions of Bash…
alias ls='ls -G'
On most Linux-y systems we instead use
alias ls='ls --color=auto'
Some HPC admins gripe about this taxing the file system, so we might need to add an exception if I start using ARCHER again.
The colours are set in the LS_COLORS
variable; the dircolors
program can generate the appropriate content from a user config file,
conventionally ~/.dircolors
. I have never felt the need to tweak
this; I suppose it could be cute to one day add meaningful colours to DFT code
input files etc? For now lets not bother with that stuff.
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
I’m just using slurm at the moment, but we can check if it is available before setting alias.
if test $(command -v squeue)
then
alias myjob='squeue -u $USER'
fi
alias em=${EDITOR}
alias ll='ls -l'
alias la='ls -a'
For old times’ sake! I’ve been making these typos less frequently since moving to 40%-size keyboards.
alias celar='clear'
alias ks='ls'
Internet radio streaming with mplayer. Not useful for remote machines so only included for named ones.
alias soma-dronezone='mplayer -playlist http://somafm.com/dronezone130.pls < /dev/null >&0 2>&0 &'
alias soma-groovesalad='mplayer -playlist http://somafm.com/groovesalad130.pls < /dev/null >&0 2>&0 &'
alias soma-defcon='mplayer -playlist http://somafm.com/defcon130.pls < /dev/null >&0 2>&0 &'
alias soma-space='mplayer -playlist http://somafm.com/spacestation130.pls < /dev/null >&0 2>&0 &'
Set window title
set_title() { printf "\e]2;$*\a"; }
PDF manpages: first we need to find an appropriate PDF viewer
(if (equal system-type 'darwin) "open" "xdg-open")
PDF_VIEWER=<<get_pdf_viewer()>>
function pdfman() { man -t $1 | ps2pdf - /tmp/$1.pdf && ${PDF_VIEWER} /tmp/$1.pdf; }
nnn quitcd magic: Original source has useful comments. BSD 2-clause license, see header of the fish version.
n ()
{
# Block nesting of nnn in subshells
if [[ "${NNNLVL:-0}" -ge 1 ]]; then
echo "nnn is already running"
return
fi
export NNN_TMPFILE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.lastd"
\nnn "$@"
if [ -f "$NNN_TMPFILE" ]; then
. "$NNN_TMPFILE"
rm -f "$NNN_TMPFILE" > /dev/null
fi
}
Some machines have nicknames and signature colours; I haven’t been using this mechanism so much lately but it’s neat so I’ll keep the ARCHER example.
case $(hostname) in
eslogin0*)
NICKNAME="ARCHER/${USER}"
NICKCOLOUR="0;32m";;
*)
NICKNAME=$(hostname -s)
NICKCOLOUR="0m";;
esac
Get git branch (Thanks to this blog) and construct prompt.
function parse_git_branch {
ref=$(git symbolic-ref HEAD 2> /dev/null) || return
echo " ("${ref#refs/heads/}")"
}
RED="0;31m"
# (Simple prompt for dumb terminals: help emacs tramp mode)
case "$TERM" in
"dumb")
PS1="> "
;;
xterm*|rxvt*|eterm*|screen*|tmux*|alacritty)
PS1="\[\033[${NICKCOLOUR}\]${NICKNAME}\[\033[0m\]:\w\[\033[${RED}\]\$(parse_git_branch)\[\033[0m\]$ "
;;
*)
PS1="> "
;;
esac
Disable graphical password checks, as these are problematic when using a remote terminal.
unset SSH_ASKPASS
Bash completion doesn’t load automatically on a Mac if installed with Homebrew.
for COMPLETION in /usr/local/etc/profile.d/bash_completion.sh /opt/homebrew/etc/profile.d/bash_completion.sh ${HOME}/.local/completions/*
do
if [ -f ${COMPLETION} ]; then
source ${COMPLETION}
fi
done
I’m not using tmux so much on the desktop with i3 but it still has its uses especially on remote servers.
setw -g mode-keys emacs
set -g mouse on
I use `
as my leader key to avoid a chord and clashes with emacs
cursor movement. Actually, since moving to very small custom
keyboards this is less of an advantage: I use arrow keys in emacs
and the backtick requires a chord to access! Maybe if I start using
tmux heavily again I’ll switch back to C-b
but for now this is
what I’m comfortable with.
unbind-key C-b
set -g prefix '`'
bind-key '`' send-prefix
Add a shortcut for refreshing the config.
bind-key r source-file ~/.config/tmux/tmux.conf
When accessing a tmux session that was initiated in smaller window, try to resize it.
setw -g aggressive-resize on
Set up a nice simple blue colour scheme. This plays nicely with solarized, tango and my i3/alacrittys themes.
set -g status-style bg=blue,fg=white
set -g window-status-style bg=blue,fg=brightwhite
set -g pane-border-style fg=white
set -g pane-active-border-style fg=brightblue
set -g message-style bg=white,fg=blue
Make history longer so program output doesn’t clobber useful stuff.
set -g history-limit 100000
Add a few shortcuts for common new-pane needs.
# Create a new remote shell
bind-key S command-prompt -p "host" "split-window 'ssh %1'"
bind-key C-s command-prompt -p "host" "new-window -n %1 'ssh %1'"
# Get an editor
bind-key y new-window -n "emacs" "emacsclient -t"
# Get a file manager
bind-key N new-window -n "nnn" "nnn"
More intuitive splitting commands. I always forget which direction
%
is going to split…
bind-key | split-window -h
bind-key - split-window -v
Count from 1 so loading windows with 1, 2, 3… keys is easy.
set -g base-index 1
First we unbind some keys we’re going to need
unbind -T copy-mode 'C-w'
unbind -T copy-mode 'M-w'
unbind -T copy-mode Enter
Some of the clipboard configuration is different for Mac vs Linux. On Mac we need to install “reattach-to-user-namespace”
# http://iancmacdonald.com/macos/emacs/tmux/2017/01/15/macOS-tmux-emacs-copy-past.html
set-option -g default-command "reattach-to-user-namespace -l $SHELL"
bind-key -T copy-mode 'C-w' send-keys -X copy-pipe-and-cancel "reattach-to-user-namespace pbcopy"
bind-key -T copy-mode 'M-w' send-keys -X copy-pipe-and-cancel "reattach-to-user-namespace pbcopy"
bind-key -T copy-mode Enter send-keys -X copy-pipe-and-cancel "reattach-to-user-namespace pbcopy"
bind ] run "reattach-to-user-namespace pbpaste | tmux load-buffer - && tmux paste-buffer"
whereas on Linux we use xclip.
bind-key -T copy-mode 'C-w' send-keys -X copy-pipe-and-cancel "xclip -sel clip -i"
bind-key -T copy-mode 'M-w' send-keys -X copy-pipe-and-cancel "xclip -sel clip -i"
bind-key -T copy-mode Enter send-keys -X copy-pipe-and-cancel "xclip -sel clip -i"
Pretty barebones git config really
[user]
name = Adam J. Jackson
email = a.j.jackson@physics.org
[init]
defaultBranch = main
[rebase]
autosquash = true
git lol
is a classic, found passed around the internet[alias] lol = log --graph --decorate --pretty=oneline --abbrev-commit --all --color
- Here are some nice ones from https://www.reddit.com/r/commandline/comments/wf7oju:
pr = "!f() { git fetch --force origin pull/$1/head:pr-$1; }; f"
My ssh config draws significant inspiration from (outragously steals from) https://github.com/jarvist/jarvist-dotfiles.
Host *
Protocol 2
UseRoaming no
Other goodies improve performance and reduce drop-outs:
Compression yes
ServerAliveCountMax 5
# Allowed pings with no reply before hang up
ServerAliveInterval 30
# Needs to be <60s for some home routers
Actual account details are pulled from another file to be copied and pasted manually: ssh-accounts.txt.
(let ((filename "ssh-accounts.txt")
(get-text (lambda (filename)
(with-temp-buffer
(insert-file-contents filename)
(buffer-substring-no-properties
(point-min) (point-max))))))
(if (file-exists-p filename)
(funcall get-text filename)
(message (concat "# Could not find " filename)))
)
<<get_ssh_accounts()>>
NNN plugins are programs that live in ~/.config/nnn/plugins. By
default this directory is empty; the user copies/writes the plugins
they wish to use and sets an NNN_PLUG
environment variable that
assigns shortcuts. We can also include simple commands directly, such
as the git command to upload Mantid test data.
set -x NNN_PLUG 'u:!git add-test-data "$nnn"'
if test -f "$HOME/.config/nnn/plugins/nuke"
set -x NNN_OPENER "$HOME/.config/nnn/plugins/nuke"
set -x NNN_OPTS "c"
end
The default nuke
plugin doesn’t play nicely with EDITOR=emacsclient
-t
; it’s a sh
script and ends up keeping EDITOR in quotes when
calling it, so it looks for binary name includeing the ~ -t~ and fails.
The workaround is to change the editor calls from
"${EDITOR}" "${FPATH}"
to
sh -c "${EDITOR} ${FPATH}"
For now I’m not managing that in this file.
I’m not using mocp
much at the moment because of Linux Audio Hell
but may as well keep my config around.
The colour theme and keymap are stored in other files
Theme = my_theme
Keymap = my_keymap
Enable high quality audio when hardware allows.
ResampleMethod = SincMediumQuality
Allow24bitOutput = yes
Disabling TiMidity can prevent some buggy weirdness
TiMidity_Config = no
Audio backend options: these don’t seem to be playing well with whatever PulseAudio/Pipewire madness is going on these days :-(
# Sound driver - OSS, ALSA, JACK, SNDIO (on OpenBSD) or null (only for
# debugging). You can enter more than one driver as a colon-separated
# list. The first working driver will be used.
SoundDriver = JACK:ALSA:OSS
# Jack output settings.
#JackClientName = "moc"
#JackStartServer = no
JackOutLeft = "system:playback_1"
JackOutRight = "system:playback_2"
# OSS output settings.
#OSSDevice = /dev/dsp
#OSSMixerDevice = /dev/mixer
#OSSMixerChannel1 = pcm # 'pcm', 'master' or 'speaker'
#OSSMixerChannel2 = master # 'pcm', 'master' or 'speaker'
# ALSA output settings.
#ALSADevice = default
#ALSAMixer1 = PCM
#ALSAMixer2 = Master
Custom colour theme, nothing especially clever but looks nice on most of my machines.
background = default default
frame = blue default bold
window_title = blue default bold
directory = blue default bold
selected_directory = black yellow
playlist = blue default bold
selected_playlist = black yellow
file = blue default bold
selected_file = black yellow bold
marked_file = yellow default dim
marked_selected_file = black yellow
marked_selected_info = black yellow
info = blue default bold
marked_info = yellow default dim
selected_info = black yellow bold
status = blue default bold
title = blue default bold
state = blue default bold
current_time = yellow default bold
time_left = yellow default bold
total_time = yellow default bold
time_total_frames = blue default bold
sound_parameters = yellow default bold
legend = blue default bold
disabled = black default
enabled = blue default bold
empty_mixer_bar = blue default bold
filled_mixer_bar = black yellow
empty_time_bar = blue default bold
filled_time_bar = black yellow
entry = blue default bold
entry_title = blue default bold
error = red default bold
message = blue default bold
plist_time = blue default bold
MOCP keymap; mostly defaults but some emacs-y tweaks
# MOC control keys:
quit_client = q
quit = Q
# Menu and interface control keys:
go = ENTER ^m ^j
menu_down = DOWN ^n
menu_up = UP ^p
menu_page_down = PAGE_DOWN ^v
menu_page_up = PAGE_UP M-v
menu_first_item = HOME M-<
menu_last_item = END M->
search_menu = / ^s
toggle_read_tags = f
toggle_show_time = ^t
toggle_show_format = M-t
toggle_menu = TAB
toggle_layout = l
toggle_hidden_files = H
# next_search = ^g ^n
show_lyrics = L
theme_menu = T
help = h ?
refresh = ^r
reload = r g
# Audio playing and positioning keys:
seek_forward = RIGHT ^f
seek_backward = LEFT ^b
seek_forward_fast = ] ^e
seek_backward_fast = [ ^a
pause = SPACE
stop = s
next = n
previous = p
toggle_shuffle = S
toggle_repeat = R
toggle_auto_next = X
toggle_mixer = x
go_url = o
# Volume control keys:
volume_down_1 = <
volume_up_1 = >
volume_down_5 = ,
volume_up_5 = .
volume_10 = M-1
volume_20 = M-2
volume_30 = M-3
volume_40 = M-4
volume_50 = M-5
volume_60 = M-6
volume_70 = M-7
volume_80 = M-8
volume_90 = M-9
# Directory navigation keys: defaults are Shift-number
# (i.e., 'shift 1' -> '!' -> 'Fastdir1').
go_to_a_directory = i
go_to_music_directory = m
go_to_fast_dir1 = !
go_to_fast_dir2 = @
go_to_fast_dir3 = #
go_to_fast_dir4 = $
go_to_fast_dir5 = %
go_to_fast_dir6 = ^
go_to_fast_dir7 = &
go_to_fast_dir8 = *
go_to_fast_dir9 = (
go_to_fast_dir10 = )
go_to_playing_file = G
go_up = U
# Playlist specific keys:
add_file = a
add_directory = A
plist_add_stream = ^u
delete_from_playlist = d
playlist_full_paths = P
plist_move_up = u
plist_move_down = j
save_playlist = V
remove_dead_entries = Y
clear_playlist = C
# Queue manipulation keys:
enqueue_file = z
clear_queue = Z
# User interaction control:
history_up = UP M-p
history_down = DOWN M-n
delete_to_start = ^u ^a
delete_to_end = ^k
cancel = ESCAPE ^g
hide_message = M
# Softmixer specific keys:
toggle_softmixer = w
toggle_make_mono = J
# Equalizer specific keys:
toggle_equalizer = E
equalizer_refresh = e
equalizer_prev = K
equalizer_next = k
Chicken repository stuff was set up under Fish and Bash sections. Maybe that should live here somehow? Or we should do noweb things?
Configuration file for chicken that enables realine support so interpreter is not horribly painful to use:
(This is directly from the GPL-licensed project archive. Hopefully they are cool with that.)
(import (chicken load))
(load-verbose #f)
(let ()
(import (chicken format))
(import (chicken process-context))
(import (chicken process signal))
(unless (get-environment-variable "INSIDE_EMACS")
(import breadline)
(import breadline-scheme-completion)
(history-file (format "~a/.csi_history" (get-environment-variable "HOME")))
(stifle-history! 10000)
(completer-word-break-characters-set! "\"\'`;|(")
(completer-set! scheme-completer)
(basic-quote-characters-set! "\"|")
(variable-bind! "blink-matching-paren" "on")
(paren-blink-timeout-set! 200000)
(let ((handler (signal-handler signal/int)))
(set-signal-handler! signal/int
(lambda (s)
(cleanup-after-signal!)
(reset-after-signal!)
(handler s))))
(on-exit reset-terminal!)
(current-input-port (make-readline-port))))
I installed a few CPAN packages on scpc041 and it added this to my bashrc:
PATH="/home/adamjackson/perl5/bin${PATH:+:${PATH}}"; export PATH;
PERL5LIB="/home/adamjackson/perl5/lib/perl5${PERL5LIB:+:${PERL5LIB}}"; export PERL5LIB;
PERL_LOCAL_LIB_ROOT="/home/adamjackson/perl5${PERL_LOCAL_LIB_ROOT:+:${PERL_LOCAL_LIB_ROOT}}"; export PERL_LOCAL_LIB_ROOT;
PERL_MB_OPT="--install_base \"/home/adamjackson/perl5\""; export PERL_MB_OPT;
PERL_MM_OPT="INSTALL_BASE=/home/adamjackson/perl5"; export PERL_MM_OPT;
I was using Fish at the time, which made it especially unhelpful. Let’s just leave them here and see if it’s actually a problem; I really just needed that stuff to run a test suite.
Experimenting with better export:
Add the codeblock name if available and some ugly symbols if not
(setq org-babel-exp-code-template
(concat "\n=%name=:\n"
org-babel-exp-code-template)
)
Enable syntax highlighting
(require 'htmlize)
(setq org-src-fontify-natively t)