Installation Manjaro (KDE)
Everything from pacman and AUR
sudo pacman -Syu --needed base-devel yay git git-lfs libsecret github-cli cmake curl openssh python-pip python-pandas python-numpy python-pipx python-tldextract uv texlive-basic texlive-binextra texlive-fontutils texlive-xetex texlive-latexextra texlive-pictures texlive-bibtexextra texlive-fontsextra texlive-fontsrecommended texlive-mathscience biber keepassxc htop vlc tmux openconnect networkmanager-openconnect unison signal-desktop tailscale webapp-manager virtualbox linux71-virtualbox-host-modules virtualbox-guest-iso plasma-nm ksnip
yay -S --needed ttf-ms-fonts spotify synology-drive microsoft-edge-stable-bin visual-studio-code-bin juliaup quarto-cli-bin zoom nordvpn-bin zotero-bin
sudo systemctl enable --now sshd tailscaled nordvpnd
sudo systemctl restart NetworkManager
sudo usermod -aG vboxusers $USER
sudo groupadd nordvpn
sudo usermod -aG nordvpn $USERThen reboot.
Notes:
linux71-virtualbox-host-moduleshas to match the installed kernel, check withmhwd-kernel -li(e.g.linux71->linux71-virtualbox-host-modules).- yay asks to import the Spotify PGP key, accept it.
spotify-launcherfrom pacman fails to download Spotify (“Exceeded number of retries for download”), so usespotifyfrom the AUR instead.- The texlive packages above include all LaTeX packages needed, so no
tlmgrsetup is needed. pympressis not available in pacman or the AUR.- Stata is a tarball, see below.
- Services are not started on install (unlike Ubuntu), so the
systemctl enable --nowline is needed:tailscale upandnordvpn loginfail without their daemons running.sshdis only needed to ssh into this machine.
Synology Drive client
- Do not sync hidden folders (.folder) and do not sync the following files (add as exception):
- Manifest.toml
- in settings,
Global Settings -> Notificationsuntick notifications - NAS quickconnect:
rpgnasasdfjh
Keepass
- Enable integration of browser in settings off keepass
- Add database in browser integration (in extension settings)
Launchers for different online apps
Use “Web Apps” (webapp-manager). Choose edge and separate profile for each app. Use the following urls:
- Outlook: outlook.office.com
- Email personal: outlook.live.com
- WhatsApp: web.whatsapp.com
- Remarkable: https://app.remarkable.com/folder/home
- ToDoist: https://app.todoist.com/app/upcoming
Programming
Git:
- Note: libsecret is required for persistent github credentials (I think..)
git config --global user.name "rgreminger" git config --global user.email "rafael.greminger@outlook.com" gh auth login # this logs into github gh auth setup-git # needed to store credentials (I think..)Tailscale:
sudo tailscale upto log inClaude
curl -fsSL https://claude.ai/install.sh | bashVscode:
- Remote SSH extension: Ctrl+P
ext install ms-vscode-remote.remote-ssh
- Remote SSH extension: Ctrl+P
Julia: installed through
juliaup, the firstjuliacall installs the latest releaseStata:
- download
- Install
sudo mkdir /usr/local/stata
sudo cp /home/rafael/Downloads/StataNow19Linux64.tar.gz /usr/local/stata/stata.tar.gz
cd /usr/local/stata/
sudo tar -xvf stata.tar.gz
sudo ./install
sudo ./stinit- Right-click on desktop “create launcher” -> prompts whether to also create start menu entry. Command is
/usr/local/stata/xstata-mp - Add binaries to path. Edit
~/.profilewith this:
echo 'export PATH=$PATH:/usr/local/stata' >> ~/.profileUCL VPN
Use openconnect to connect to UCL VPN. In system settings, go to Wi-Fi & Networking, then use + to add a new “Cisco AnyConnect Compatible VPN (openconnect)” connection with these settings (don’t miss bottom change on Token mode!):

NordVPN
nordvpn login
nordvpn connectZotero
- Zotero installation instructions (Linux) (Zotero itself is installed above as
zotero-bin, skip the apt part) - ZotMoov, Better BibTeX and their settings can be installed with a script instead of the manual steps (Zotero must be closed):
~/SynologyDrive/Notes/admin-computer-it/zotero-setup.sh- The script downloads the latest XPIs into the Zotero profile and appends zotero-prefs.js to the profile’s
prefs.js. To refreshzotero-prefs.jsafter changing settings, re-export the matchinguser_preflines from~/.zotero/zotero/*.default/prefs.js. - The file renaming format is not in
prefs.jsbut synced with the Zotero account, so it comes back after logging into sync. Better BibTeX auto-exports are not covered, set them up again.
Printer UCL
See instructions here.
Virtual windows machine
- VirtualBox and the guest additions ISO are installed above (reboot after the install).
- Get ISO: https://www.microsoft.com/en-gb/software-download/windows11
- Install Windows 11 in virtualbox. Use the following settings:
- Unattended guest install: yes
- Memory: 8GB
- Storage: 60GB dynamically allocated
- Install virtual guest additions: point to
/usr/lib/virtualbox/additions/VBoxGuestAdditions.iso
- Start VM and set:
- Devices -> shared clipboard -> bidirectional
- Input -> keyboard -> In general settings, set folder /home/rafael/windows, then update host key to right alt
- Set up shared folder to access files from host machine:
- In virtualbox, go to settings -> shared folders -> add new shared folder. Choose folder path and folder name. Tick “Auto-mount” and “Make Permanent”
- In Windows, go to “This PC” and you should see the shared folder under “Network locations”. If not, you may need to map the network drive manually using the folder name you set in virtualbox.
- Install Microsoft Office: download from https://www.microsoft.com/en-us/microsoft-365/download-office
- Debloat windows install. Open terminal and run
& ([scriptblock]::Create((irm "https://debloat.raphi.re/"))). This opens a window can specify which apps to remove. Most can be removed.
Tweaks for KDE Plasma
Paste this block into a terminal (inside a Plasma session). It:
- sets the built-in profile as default in Konsole (instead of Manjaro’s
Breathprofile) - sets
zshas default terminal profile in VS Code (addsterminal.integrated.defaultProfile.linuxto itssettings.json) - adds
Ctrl+Alt+Arrowto switch desktop andCtrl+Shift+Alt+Arrowto move the window to another desktop. The defaultMeta+Ctrl(+Shift)+Arrowshortcuts are kept. Applies immediately, no logout needed. - makes
Meta+Upmaximize the window, and pressing it again on a maximized window tiles it to the top half (pressing again maximizes again). This is a small KWin script in~/.local/share/kwin/scripts/maxtiletop; the built-inMeta+Up(Quick Tile Top) shortcut is removed. - adds the German (Switzerland) keyboard layout (after English (US)) and makes
Meta+Spaceswitch between layouts (Meta+Alt+Kis kept). The shortcut applies immediately, the layouts only after logging out and back in.
kwriteconfig6 --file konsolerc --group "Desktop Entry" --key DefaultProfile ""
f=~/.config/Code/User/settings.json
mkdir -p ~/.config/Code/User
[ -s "$f" ] || echo '{}' > "$f"
if grep -q '"terminal.integrated.defaultProfile.linux"' "$f"; then
sed -i 's/"terminal.integrated.defaultProfile.linux": *"[^"]*"/"terminal.integrated.defaultProfile.linux": "zsh"/' "$f"
else
sed -i '0,/{/s//{\n "terminal.integrated.defaultProfile.linux": "zsh",/' "$f"
fi
kwinkey() { gdbus call --session --dest org.kde.kglobalaccel --object-path /kglobalaccel --method org.kde.KGlobalAccel.setForeignShortcut "['kwin','$1','KWin','$1']" "$2" > /dev/null; }
deskkeys() { kwinkey "Switch One Desktop $1" "[$((0x14000000|$2)), $((0x0C000000|$2))]"; kwinkey "Window One Desktop $1" "[$((0x16000000|$2)), $((0x0E000000|$2))]"; }
deskkeys "to the Left" 0x01000012
deskkeys "Up" 0x01000013
deskkeys "to the Right" 0x01000014
deskkeys "Down" 0x01000015
d=~/.local/share/kwin/scripts/maxtiletop
mkdir -p $d/contents/code
cat > $d/metadata.json <<'EOF'
{
"KPlugin": {
"Id": "maxtiletop",
"Name": "Maximize or tile top",
"Description": "Meta+Up maximizes the window, or tiles it to the top half if it is already maximized",
"Version": "1.0",
"License": "MIT"
},
"X-Plasma-API": "javascript",
"KPackageStructure": "KWin/Script"
}
EOF
cat > $d/contents/code/main.js <<'EOF'
registerShortcut("MaximizeOrTileTop", "Maximize window, or tile to top half if maximized", "Meta+Up", function () {
const w = workspace.activeWindow;
if (w && w.normalWindow) {
if (w.maximizeMode == 3) {
workspace.slotWindowQuickTileTop();
} else {
w.setMaximize(true, true);
}
}
});
EOF
kwinkey "Window Quick Tile Top" "@ai []"
kwriteconfig6 --file kwinrc --group Plugins --key maxtiletopEnabled true
qdbus6 org.kde.KWin /KWin reconfigure
kwriteconfig6 --file kxkbrc --group Layout --key Use true
kwriteconfig6 --file kxkbrc --group Layout --key LayoutList us,ch
kwriteconfig6 --file kxkbrc --group Layout --key VariantList ,
gdbus call --session --dest org.kde.kglobalaccel --object-path /kglobalaccel --method org.kde.KGlobalAccel.setForeignShortcut "['KDE Keyboard Layout Switcher','Switch to Next Keyboard Layout','Keyboard Layout Switcher','Switch to Next Keyboard Layout']" "[$((0x10000020)), $((0x1800004B))]" > /dev/nullNotes:
- Konsole windows that are already open keep their profile; new ones use the built-in profile.
- The numbers in
deskkeysare Qt key codes:0x0C000000= Ctrl+Alt,0x0E000000= Ctrl+Shift+Alt,0x14000000= Meta+Ctrl,0x16000000= Meta+Ctrl+Shift;0x01000012-0x01000015= Left, Up, Right, Down. - The KWin script can be switched off in System Settings -> Window Management -> KWin Scripts (“Maximize or tile top”).
0x10000020= Meta+Space,0x1800004B= Meta+Alt+K.- Keyboard layouts can be checked in System Settings -> Keyboard -> Layouts.
- Check the shortcuts in System Settings -> Keyboard -> Shortcuts -> KWin.
Command line scripts
Installs small scripts to ~/.local/bin so they can be run from any terminal. To add another script, copy a mkscript block. Run the whole block again after changes; it overwrites the existing scripts. Don’t put # comments in the block: interactive zsh doesn’t accept them when pasted (zsh: bad pattern: #).
Scripts:
gpull: stash all local changes (including untracked files), then pullginit: in a folder named like an existing GitHub repo ofrgreminger, initialize git, addhttps://github.com/rgreminger/<folder name>.gitasorigin, and point the local branch at its default branch (trackingorigin). Missing hidden files and files in hidden folders (e.g..gitignore,data/.gitkeep,.github/workflows/...) are restored from GitHub, since Synology doesn’t sync them. Files already in the folder are not touched; where they differ from GitHub they show up as changes. Then either rungpullto get the GitHub versions (local differences end up ingit stash), or commit and push to keep the local versions
mkdir -p ~/.local/bin
grep -qs 'HOME/.local/bin' ~/.zshrc || echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
mkscript() { cat > ~/.local/bin/"$1"; chmod +x ~/.local/bin/"$1"; }
mkscript gpull <<'EOF'
#!/usr/bin/env bash
git add -A; git stash; git pull
EOF
mkscript ginit <<'EOF'
#!/usr/bin/env bash
set -e
url="https://github.com/rgreminger/$(basename "$PWD").git"
branch=$(git ls-remote --symref "$url" HEAD | sed -n 's|^ref: refs/heads/\(.*\)\tHEAD$|\1|p')
[ -n "$branch" ] || { echo "Cannot access $url"; exit 1; }
git init -b "$branch"
git remote add origin "$url"
git fetch origin
git reset "origin/$branch"
git branch -u "origin/$branch"
git ls-files -z --deleted | grep -z '\(^\|/\)\.' | xargs -0 -r git checkout --
git status --short
EOF
source ~/.zshrcThen open a new terminal (or source ~/.zshrc) and run e.g. gpull inside a git repo.