Compare commits

..

17 Commits

Author SHA1 Message Date
KK
6953e4f8a2 Store screenshots in Pictures 2026-07-02 22:44:01 +02:00
KK
12d9019278 PI_OFFLINE 2026-07-02 22:39:03 +02:00
KK
d5e87dba70 pi config for tmux 2026-06-28 23:16:28 +02:00
KK
a2cecfe691 Update 2026-06-27 14:27:02 +02:00
KK
ac1005b842 Show battery status in sway bar 2026-06-26 00:05:57 +02:00
KK
9fd1ba70a3 Update sublime stuff 2026-06-25 23:43:48 +02:00
KK
5d125be800 Update arch install 2026-06-25 08:48:57 +02:00
KK
d1a43f0ff9 Arch install script, forgot 2026-06-25 08:37:41 +02:00
KK
eea43ae978 Add json lib 2026-06-25 08:37:18 +02:00
KK
02cc4698dc Setup sublime 2026-06-25 08:37:05 +02:00
KK
fa6cf37c92 Small updates 2026-06-24 00:10:05 +02:00
KK
a7f6f8a3e0 add docs programs 2026-06-24 00:08:07 +02:00
KK
9577ad69c9 bash_profile 2026-06-22 22:24:43 +02:00
KK
35edc3cfe8 .profile to .bash_profile, cut some lines from .bashrc 2026-06-22 22:24:09 +02:00
KK
d274b952b1 generate auto install arch script and readme 2026-06-22 17:12:44 +02:00
KK
f8424776ae New arch setup 2026-06-22 16:34:30 +02:00
KK
4969692f93 New arch setup 2026-06-22 16:34:08 +02:00
29 changed files with 1610 additions and 476 deletions

View File

@@ -8,11 +8,13 @@
# for ssh logins, install and configure the libpam-umask package. # for ssh logins, install and configure the libpam-umask package.
#umask 022 #umask 022
export EDITOR=vim export EDITOR=kak
export VISUAL=vim export VISUAL=kak
export BROWSER=chromium export BROWSER=firefox
export TERMINAL=foot export TERMINAL=foot
export PI_OFFLINE=1
# if running bash # if running bash
if [ -n "$BASH_VERSION" ]; then if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists # include .bashrc if it exists
@@ -32,7 +34,6 @@ if [ -d "$HOME/.local/bin" ] ; then
fi fi
if [ -z "$WAYLAND_DISPLAY" ] && [ "$XDG_VTNR" = 1 ]; then if [ -z "$WAYLAND_DISPLAY" ] && [ "$XDG_VTNR" = 1 ]; then
export WLR_NO_HARDWARE_CURSORS=1 exec sway --unsupported-gpu > ~/.sway.log 2>&1
exec sway --unsupported-gpu
fi fi

81
.bashrc
View File

@@ -18,6 +18,7 @@ shopt -s histappend
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1) # for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=100000 HISTSIZE=100000
HISTFILESIZE=200000 HISTFILESIZE=200000
HISTTIMEFORMAT='%F %T '
# check the window size after each command and, if necessary, # check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS. # update the values of LINES and COLUMNS.
@@ -30,79 +31,12 @@ shopt -s globstar
# Type directory names directly, without 'cd' and still move there # Type directory names directly, without 'cd' and still move there
shopt -s autocd shopt -s autocd
# make less more friendly for non-text input files, see lesspipe(1) alias ls='ls -lahtr --color=auto'
#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" alias vi='kak'
alias df='/usr/bin/git --git-dir=$HOME/.dotfilesrepo/ --work-tree=$HOME'
# set variable identifying the chroot you work in (used in the prompt below) alias unpack='bsdtar -xf'
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then alias imv='imv-wayland'
debian_chroot=$(cat /etc/debian_chroot) alias sway='sway --unsupported-gpu'
fi
# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color|*-256color) color_prompt=yes;;
esac
# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes
if [ -n "$force_color_prompt" ]; then
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
# We have color support; assume it's compliant with Ecma-48
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
# a case would tend to support setf rather than setaf.)
color_prompt=yes
else
color_prompt=
fi
fi
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt
# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
;;
*)
;;
esac
# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto'
#alias dir='dir --color=auto'
#alias vdir='vdir --color=auto'
#alias grep='grep --color=auto'
#alias fgrep='fgrep --color=auto'
#alias egrep='egrep --color=auto'
fi
# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
# some more ls aliases
#alias ll='ls -l'
#alias la='ls -A'
#alias l='ls -CF'
# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
if [ -f ~/.config/bash_aliases ]; then
. ~/.config/bash_aliases
fi
# enable programmable completion features (you don't need to enable # enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile # this, if it's already enabled in /etc/bash.bashrc and /etc/profile
@@ -115,4 +49,3 @@ if ! shopt -oq posix; then
fi fi
fi fi
export PATH="$PATH:/home/kk/.local/share/pi-node/node-v22.22.3-linux-x64/bin"

View File

@@ -1,5 +0,0 @@
alias ls='ls -lahtr'
alias vi='kak'
alias df='/usr/bin/git --git-dir=$HOME/.dotfilesrepo/ --work-tree=$HOME'
alias unpack='dtrx'
alias imv='imv-wayland'

View File

@@ -1,5 +1,5 @@
[main] [main]
font=JetBrains Mono:size=14 font=JetBrains Mono:size=10
[bell] [bell]
urgent=no urgent=no

View File

@@ -16,8 +16,35 @@ map global user / ': comment-line<ret>'
# insert four spaces instead of a tab character while in insert mode. # insert four spaces instead of a tab character while in insert mode.
map global insert <tab> '<space><space><space><space>' map global insert <tab> '<space><space><space><space>'
hook global RegisterModified '"' %{ nop %sh{ hook global InsertChar j %{ try %{
printf %s "$kak_main_reg_dquote" | wl-copy > /dev/null 2>&1 & exec -draft hH <a-k>jj<ret> d
exec -with-hooks <esc>
}}
evaluate-commands %sh{
if [ -n "${WAYLAND_DISPLAY:-}" ] && command -v wl-copy >/dev/null 2>&1 && command -v wl-paste >/dev/null 2>&1; then
printf %s "
hook global RegisterModified '\"' %{ nop %reg{dquote} %sh{
printf %s \"\$kak_main_reg_dquote\" | wl-copy > /dev/null 2>&1 &
}} }}
define-command -hidden paste-system-after %{
evaluate-commands -save-regs '\"' %{
set-register dquote %sh{ wl-paste --no-newline 2>/dev/null }
execute-keys p
}
}
define-command -hidden paste-system-before %{
evaluate-commands -save-regs '\"' %{
set-register dquote %sh{ wl-paste --no-newline 2>/dev/null }
execute-keys P
}
}
map global normal p ': paste-system-after<ret>'
map global normal P ': paste-system-before<ret>'
"
fi
}
add-highlighter global/ number-lines add-highlighter global/ number-lines

View File

@@ -1,5 +1,5 @@
{ {
"theme": "Merge Dark.sublime-theme", /*"theme": "Merge Dark.sublime-theme",*/
"side_bar_layout": "tabs", "side_bar_layout": "tabs",
"diff_algorithm": "match_git", "diff_algorithm": "match_git",
"visible_carriage_returns_at_eol": true, "visible_carriage_returns_at_eol": true,

View File

@@ -0,0 +1,28 @@
[
{ "keys": ["ctrl+q"], "command": "goto_definition" },
{ "keys": ["alt+q"], "command": "jump_back" },
{ "keys": ["ctrl+e"], "command": "next_result" },
{ "keys": ["alt+e"], "command": "prev_result" },
{ "keys": ["ctrl+up"], "command": "move", "args": {"by": "stops", "empty_line": true, "forward": false} },
{ "keys": ["ctrl+down"], "command": "move", "args": {"by": "stops", "empty_line": true, "forward": true} },
{ "keys": ["ctrl+shift+up"], "command": "move", "args": {"by": "stops", "empty_line": true, "forward": false, "extend": true} },
{ "keys": ["ctrl+shift+down"], "command": "move", "args": {"by": "stops", "empty_line": true, "forward": true, "extend": true} },
{ "keys": ["alt+up"], "command": "swap_line_up" },
{ "keys": ["alt+down"], "command": "swap_line_down" },
{ "keys": ["alt+left"], "command": "jump_back" },
{ "keys": ["alt+right"], "command": "jump_forward" },
{ "keys": ["alt+shift+up"], "command": "select_lines", "args": {"forward": false} },
{ "keys": ["alt+shift+down"], "command": "select_lines", "args": {"forward": true} },
{ "keys": ["ctrl+alt+down"], "command": "duplicate_line" },
{ "keys": ["ctrl+alt+up"], "command": "duplicate_line" },
{ "keys": ["ctrl+shift+l"], "command": "split_selection_into_lines" },
{ "keys": ["ctrl+r"], "command": "goto_symbol_in_project" },
{ "keys": ["ctrl+m"], "command": "toggle_record_macro" },
{ "keys": ["alt+m"], "command": "run_macro" },
]

View File

@@ -0,0 +1,13 @@
{
"bootstrapped": true,
"in_process_packages":
[
],
"installed_packages":
[
"A File Icon",
"ayu",
"gruvbox",
"Package Control",
],
}

View File

@@ -19,7 +19,7 @@
], ],
"index_files": true, "index_files": true,
// "color_scheme": "gruvbox (Light) (Soft).sublime-color-scheme", // "color_scheme": "gruvbox (Light) (Soft).sublime-color-scheme",
"font_size": 11, "font_size": 10,
"font_face": "Cascadia Code", "font_face": "Cascadia Code",
"theme": "Adaptive.sublime-theme", "theme": "Adaptive.sublime-theme",
"folder_exclude_patterns": ["external", ".svn", ".git", ".hg", "CVS", ".Trash", ".Trash-*"], "folder_exclude_patterns": ["external", ".svn", ".git", ".hg", "CVS", ".Trash", ".Trash-*"],
@@ -31,5 +31,8 @@
// "line_numbers": false, // "line_numbers": false,
// "gutter": false, // "gutter": false,
// "margin": 0, // "margin": 0,
"color_scheme": "gruvbox (Dark) (Hard).sublime-color-scheme", // "color_scheme": "gruvbox (Dark) (Hard).sublime-color-scheme",
"color_scheme": "auto",
"dark_color_scheme": "Mariana.sublime-color-scheme",
"light_color_scheme": "Breakers.sublime-color-scheme",
} }

View File

@@ -1,5 +1,5 @@
{ {
"shell_cmd": "build.bat", "shell_cmd": "bash build.sh",
"file_regex": "^(.*)\\((\\d+),?(\\d+)?\\)\\s?:\\s([^\n]+)", // msvc "file_regex": "^(.*)\\((\\d+),?(\\d+)?\\)\\s?:\\s([^\n]+)", // msvc
// "file_regex": "^(.*):(\\d+):(\\d+):", // clang // "file_regex": "^(.*):(\\d+):(\\d+):", // clang
"working_dir": "$folder", "working_dir": "$folder",

View File

@@ -83,8 +83,6 @@ input "1267:12734:ELAN06FA:00_04F3:31BE_Touchpad" {
# #
# Basics: # Basics:
# #
# Start a terminal # Start a terminal
bindsym $mod+Return exec $term bindsym $mod+Return exec $term
@@ -93,6 +91,7 @@ input "1267:12734:ELAN06FA:00_04F3:31BE_Touchpad" {
# Start your launcher # Start your launcher
bindsym $mod+p exec $menu bindsym $mod+p exec $menu
bindsym $mod+d exec /home/kk/bin/docs-list.c
# Drag floating windows by holding down $mod and left mouse button. # Drag floating windows by holding down $mod and left mouse button.
# Resize them with right mouse button + $mod. # Resize them with right mouse button + $mod.
@@ -233,13 +232,13 @@ bindsym $mod+r mode "resize"
bindsym --locked XF86MonBrightnessDown exec brightnessctl set 5%-; pkill -USR1 -f "$HOME/.config/sway/status.sh" bindsym --locked XF86MonBrightnessDown exec brightnessctl set 5%-; pkill -USR1 -f "$HOME/.config/sway/status.sh"
bindsym --locked XF86MonBrightnessUp exec brightnessctl set 5%+; pkill -USR1 -f "$HOME/.config/sway/status.sh" bindsym --locked XF86MonBrightnessUp exec brightnessctl set 5%+; pkill -USR1 -f "$HOME/.config/sway/status.sh"
# Special key to take a screenshot with grim # Special key to take a screenshot with grim
bindsym Print exec sh -c 'mkdir -p ~/screenshots; f=~/screenshots/$(date +%F-%H%M%S).png; grim "$f"; wl-copy < "$f"' bindsym Print exec sh -c 'mkdir -p ~/screenshots; f=~/Pictures/$(date +%F-%H%M%S).png; grim "$f"; wl-copy < "$f"'
bindsym Shift+Print exec sh -c 'mkdir -p ~/screenshots; f=~/screenshots/$(date +%F-%H%M%S).png; grim -g "$(slurp)" "$f"; wl-copy < "$f"' bindsym Shift+Print exec sh -c 'mkdir -p ~/screenshots; f=~/Pictures/$(date +%F-%H%M%S).png; grim -g "$(slurp)" "$f"; wl-copy < "$f"'
# Push-to-talk: hold Caps Lock to record, release to transcribe. # Push-to-talk: hold Caps Lock to record, release to transcribe.
# xkb_options caps:none above disables the normal Caps Lock toggle, so bind by keycode. # xkb_options caps:none above disables the normal Caps Lock toggle, so bind by keycode.
bindcode 66 exec sh -c 'voxtype record start; pkill -USR1 -f "$HOME/.config/sway/status.sh"' # bindcode 66 exec sh -c 'voxtype record start; pkill -USR1 -f "$HOME/.config/sway/status.sh"'
bindcode --release 66 exec sh -c 'voxtype record stop; pkill -USR1 -f "$HOME/.config/sway/status.sh"' # bindcode --release 66 exec sh -c 'voxtype record stop; pkill -USR1 -f "$HOME/.config/sway/status.sh"'
# #
# Status Bar: # Status Bar:
@@ -247,7 +246,7 @@ bindsym $mod+r mode "resize"
# Read `man j sway-bar` for more information about this section. # Read `man j sway-bar` for more information about this section.
bar { bar {
position top position top
font pango:JetBrains Mono $fontsize font pango:Fira Code $fontsize
# Show volume, brightness, and date/time. # Show volume, brightness, and date/time.
status_command ~/.config/sway/status.sh status_command ~/.config/sway/status.sh

View File

@@ -1,4 +1,4 @@
#!/bin/sh #!/bin/bash
print_status() { print_status() {
volume_info=$(wpctl get-volume @DEFAULT_AUDIO_SINK@ 2>/dev/null) volume_info=$(wpctl get-volume @DEFAULT_AUDIO_SINK@ 2>/dev/null)
@@ -7,21 +7,28 @@ print_status() {
brightness=$(brightnessctl -m 2>/dev/null | awk -F, '{print $4}') brightness=$(brightnessctl -m 2>/dev/null | awk -F, '{print $4}')
voxtype_state=$(voxtype status 2>/dev/null) battery_device=$(upower -e 2>/dev/null | grep -m 1 battery)
case "$voxtype_state" in if [ -n "$battery_device" ]; then
recording) voxtype=' | VOX REC' ;; battery=$(upower -i "$battery_device" 2>/dev/null | awk '
transcribing) voxtype=' | VOX ...' ;; /state/ { state=$2 }
*) voxtype='' ;; /percentage/ { percentage=$2 }
esac END {
if (percentage != "") {
printf "%s", percentage
if (state != "") printf " %s", state
}
}
')
fi
printf 'VOL %s | BRI %s%s | %s\n' "${volume:-n/a}" "${brightness:-n/a}" "$voxtype" "$(date +'%Y-%m-%d %H:%M:%S')" printf 'VOL %s | BRI %s | BAT %s | %s\n' "${volume:-n/a}" "${brightness:-n/a}" "${battery:-n/a}" "$(date +'%Y-%m-%d %H:%M:%S')"
} }
trap print_status USR1 trap print_status USR1
print_status print_status
while :; do while :; do
sleep 1 & sleep 60 &
wait $! wait $!
print_status print_status
done done

View File

@@ -4,6 +4,9 @@
set -g extended-keys on set -g extended-keys on
set -g extended-keys-format csi-u set -g extended-keys-format csi-u
# To fix ctrl-b + direction (hjkl) switching pane multiple times after hitting the direction again
set-option -g repeat-time 150
# Index windows/tabs and panes from 1 instead of 0. # Index windows/tabs and panes from 1 instead of 0.
set -g base-index 1 set -g base-index 1
setw -g pane-base-index 1 setw -g pane-base-index 1
@@ -15,12 +18,21 @@ set -g renumber-windows on
set -g default-terminal "tmux-256color" set -g default-terminal "tmux-256color"
set -as terminal-features ",*:RGB" set -as terminal-features ",*:RGB"
# Allow terminal escape passthrough for apps such as opencode that use OSC 52
# clipboard sequences from inside tmux.
set -g allow-passthrough on
# Keep a large scrollback history. # Keep a large scrollback history.
set -g history-limit 1000000 set -g history-limit 1000000
# Reload config with prefix + r. # Reload config with prefix + r.
bind-key r source-file ~/.config/tmux/tmux.conf \; display-message "tmux config reloaded" bind-key r source-file ~/.config/tmux/tmux.conf \; display-message "tmux config reloaded"
# Open new panes/windows in the currently focused pane's directory.
bind-key % split-window -h -c "#{pane_current_path}"
bind-key '"' split-window -v -c "#{pane_current_path}"
bind-key c new-window -c "#{pane_current_path}"
# Pane navigation with Vim-style keys # Pane navigation with Vim-style keys
bind-key h select-pane -L bind-key h select-pane -L
bind-key j select-pane -D bind-key j select-pane -D

355
README.md
View File

@@ -1,355 +0,0 @@
# System install guide
Install guide with DIY spirit, key is to reproduce my system setup while making sure understanding is there and all.
- Commands are written for user `kk` unless stated otherwise.
## Current TODOs
- [ ] systemd-boot
- [ ] systemd-network + iwd
### System / mounts
- [x] Add server SSH keys and PC SSH keys
- [ ] Mount the mobile phone
- Make sure nobody else can log in when I connect to random Wi-Fi.
- [ ] Mount `/proton` on startup
- [x] Mount `/lenovo-laptop`
- [x] Mount server at `/server-vps`
### Desktop / UX
- [x] Hibernate if not using the PC for 10 minutes
- [ ] Start Sway in a tmux session for debugging
- [ ] Kakoune setup
- [x] Firefox bookmarks
- [ ] Ideas for Chinese learning integration
### Launcher / search
- [x] Combine apps, scripts, bookmarks, and files
- [x] Use `.desktop` file name instead of the `Name` parameter
- [x] Everything relevant in `wmenu` browser
- [x] `plocate + wmenu > xdg-open`
- [x] Applications + `bin` folder
- [x] Bookmarks
### Ideas looking for problems
- [ ] tmux automation
---
## Bootstrap sudo and git
```sh
su root
export PATH="$PATH:/usr/sbin"
apt install sudo git
usermod -aG sudo kk
```
Then exit both root and the user session, and log in again so the `sudo` group change applies.
Verify:
```sh
groups # should see "sudo"
sudo whoami # you should see "root"
```
Expected output from `sudo whoami`:
```text
root
```
---
## Install basic utilities
**Automate later.**
```sh
sudo apt update
sudo apt install -y \
clang \
cmake \
build-essential \
make \
tcc \
vim \
ripgrep \
curl \
git \
man-db \
plocate \
tmux \
fzf \
dtrx \
gdb
sudo updatedb # plocate update the database so you can query files on PC nicely
```
- fzf - fuzzy search on command line, good for making command line tools
- ripgrep - better grep, nicer syntax and faster: rg "query"
- dtrx - nice archive unpacking wrapper that makes it less confusing, just dtrx thing.zip or whatever other tar and it should work nicely
Mostly development tools are downloaded here, stuff like tmux, vim and the compiler toolchain needed for development, compiling etc.
---
## Speed up GRUB boot
**Automate later.** Edit `/etc/default/grub`:
```sh
sudo vi /etc/default/grub
```
Set:
```ini
GRUB_TIMEOUT=0
GRUB_TIMEOUT_STYLE=hidden
```
Apply changes:
```sh
sudo update-grub
```
---
## Enable Debian non-free repositories
**Automate later.** Needed for NVIDIA and firmware packages.
Edit `/etc/apt/sources.list` and add:
```text
contrib non-free non-free-firmware
```
Then update apt:
```sh
sudo apt update
```
---
## Install drivers and firmware
**Machine-specific / automate carefully.**
```sh
sudo apt install -y \
nvidia-driver \
firmware-misc-nonfree \
linux-headers-amd64
```
TODO:
- Set NVIDIA modeset to `1`.
- Update initramfs.
- Reboot.
---
## Desktop environment: Sway
**Automate later.**
```sh
sudo apt install -y \
sway \
swayidle \
swaybg \
swaylock \
foot \
wmenu \
brightnessctl \
xwayland \
wl-clipboard \
xdg-desktop-portal-wlr \
xdg-desktop-portal-gtk \
xdg-user-dirs \
fonts-jetbrains-mono \
fonts-noto-cjk \
fonts-noto-cjk-extra \
pipewire \
pipewire-pulse \
pipewire-alsa \
wireplumber \
pavucontrol \
grim \
imv \
mpv \
ffmpeg libavcodec-extra
```
Package notes:
- sway, terminal, menu, addons:
- `sway` - the Wayland window manager / desktop environment of choice. This is the main thing that replaces a traditional desktop like GNOME or KDE.
- `swayidle` - idle manager for Sway. Used for things like locking the screen, turning off the display, suspending, or hibernating after a timeout.
- `swaybg` - simple wallpaper/background setter for Sway.
- `swaylock` - screen locker for Sway/Wayland. Used when locking the session manually or from `swayidle`.
- `foot` - terminal emulator for Wayland. This is the main terminal.
- `wmenu` - small menu/launcher for Wayland. Useful for app launching and custom scripts like bookmarks/search/file opening.
- `grim` - screenshot tool for Wayland. Usually used together with selection/clipboard scripts later.
- `brightnessctl` - command line tool for changing screen brightness, usually bound to laptop brightness keys.
- `xwayland` - compatibility layer that allows older X11 applications to run inside the Wayland/Sway session.
- `wl-clipboard` - Wayland clipboard tools, mainly `wl-copy` and `wl-paste`. Needed by scripts and editor integrations.
- `fonts-jetbrains-mono` - nice monospace font for terminal/editor use.
- `imv` - image viewer
- `mpv` - multimedia viewer (watching videos)
- xdg, a standard required by some apps (shared enviroment variables and such):
- `xdg-desktop-portal-wlr` - desktop portal backend for wlroots compositors like Sway. Needed for screen sharing, screenshots, file pickers, and other app integrations.
- `xdg-desktop-portal-gtk` - GTK portal backend/fallback. Helps with file picker dialogs and desktop integration for some applications.
- `xdg-user-dirs` - creates standard user folders like `~/Downloads`, `~/Documents`, `~/Pictures`, etc.
- fix unicode characters (like Chinese) not showing up properly in firefox:
- `fonts-noto-cjk` - fonts needed for displaying Chinese, Japanese, Korean, etc. characters in Firefox, Chromium, terminal apps, and other programs.
- `fonts-noto-cjk-extra` - additional CJK font coverage/styles.
- audio:
- `pipewire` - the main modern Linux audio/media server. Handles audio routing and is also useful for screen sharing/media integration on Wayland.
- `pipewire-pulse` - PulseAudio compatibility layer for PipeWire. Makes applications that expect PulseAudio work through PipeWire instead.
- `pipewire-alsa` - ALSA compatibility layer for PipeWire. Helps applications that use ALSA directly play/record audio through PipeWire.
- `wireplumber` - PipeWire session/policy manager. It decides how audio devices and streams should be connected automatically.
- `pavucontrol` - graphical volume mixer. Useful for choosing input/output devices, changing app volumes, and debugging audio problems.
- codecs (to fix videos not playing in browser):
- ffmpeg libavcodec-extra
### Fix Sway permission issues
If Sway reports render/video permission errors, add the user to the relevant groups:
```sh
sudo usermod -aG video,render kk
```
Log out and back in afterwards.
---
## SSH keys
**Manual.** Generate a key if the machine does not already have one:
```sh
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N ""
```
Now exchange the keys with relevant machines so as to make communication easier. This prepares the ground for mounting these machines as easy to access drives.
---
## SSHFS drives
**Partly manual.** Install SSHFS:
```sh
sudo apt install -y sshfs
```
Create mount points as needed:
```sh
sudo mkdir -p /server-vps /lenovo-laptop /proton
```
Example `/etc/fstab` entry for the VPS:
```fstab
root@157.90.144.237:/ /server-vps fuse.sshfs noauto,x-systemd.automount,_netdev,x-systemd.idle-timeout=2min,x-systemd.mount-timeout=10s,reconnect,ServerAliveInterval=15,ServerAliveCountMax=3,IdentityFile=/home/kk/.ssh/id_ed25519,UserKnownHostsFile=/home/kk/.ssh/known_hosts,StrictHostKeyChecking=accept-new,allow_other,default_permissions 0 0
```
Test after editing `/etc/fstab`:
```sh
sudo systemctl daemon-reload
ls /server-vps
```
---
## Browser / internet tools
**Automate later.**
```sh
sudo apt install -y chromium
```
Optional text/web search tools:
```sh
sudo apt install -y w3m surfraw
```
---
## Extras
### Clipboard history
```sh
sudo apt install -y cliphist
```
---
## Voice typing: Voxtype
**Manual / automate carefully.**
Install Voxtype:
```sh
curl -LO https://github.com/peteonrails/voxtype/releases/download/v0.6.0/voxtype_0.6.0-1_amd64.deb
sudo dpkg -i voxtype_0.6.0-1_amd64.deb
rm voxtype_0.6.0-1_amd64.deb
```
Install runtime dependencies:
```sh
sudo apt install -y \
wtype \
wl-clipboard \
libnotify-bin \
playerctl
```
Allow input access:
```sh
sudo usermod -aG input "$USER"
```
Log out and back in afterwards.
### Optional GPU support
```sh
read -r -p "Enable GPU support? [y/N] " answer
case "$answer" in
[yY]|[yY][eE][sS])
sudo voxtype setup gpu --enable
;;
esac
```
### Voxtype setup
```sh
voxtype setup
voxtype setup systemd
voxtype setup model
```

170
arch-install.sh Executable file
View File

@@ -0,0 +1,170 @@
#!/bin/bash
set -euo pipefail
username=kk
core_packages=(
tmux
kakoune
man-db
man-pages
clang
make
cmake
tcc
ripgrep
curl
plocate
fzf
gdb
which
tree
)
network_packages=(
openssh
sshfs
)
desktop_packages=(
sway
swayidle
swaybg
swaylock
foot
wmenu
polkit # this is needed to fix swayidle not being to suspend because it doesn't have the authority, systemd-logind asks it for policy
xorg-xwayland
wl-clipboard
xdg-desktop-portal-wlr
xdg-desktop-portal-gtk
xdg-user-dirs
xdg-utils
grim # For screenshotting the desktop
upower # For querying battery charge
)
media_packages=(
pipewire
pipewire-pulse
pipewire-alsa
pipewire-jack
pipewire-libcamera
libcamera
pavucontrol
wireplumber
bluez
bluez-utils # bluetooth
rtkit # There was a pipewire error so I decided to add this, "changes scheduling policy of user threads to realtime"
ffmpeg
imv
mpv
)
font_packages=(
ttf-fira-code
ttf-jetbrains-mono
noto-fonts
noto-fonts-cjk
noto-fonts-emoji
noto-fonts-extra
ttf-liberation
ttf-dejavu
ttf-roboto
fontconfig
)
app_packages=(
firefox
)
machine_packages=(
nvidia-open
)
if [[ ${EUID} -ne 0 ]]; then
printf 'Run this script as root inside arch-chroot.\n' >&2
exit 1
fi
ln -sf /usr/share/zoneinfo/Europe/Warsaw /etc/localtime
hwclock --systohc
sed -i 's/^#\(en_US.UTF-8 UTF-8\)/\1/' /etc/locale.gen
sed -i 's/^#\(pl_PL.UTF-8 UTF-8\)/\1/' /etc/locale.gen
locale-gen
cat >/etc/locale.conf <<'EOF'
LANG=en_US.UTF-8
EOF
cat >/etc/vconsole.conf <<'EOF'
KEYMAP=pl2
EOF
bootctl install
cat >/boot/loader/loader.conf <<'EOF'
default arch.conf
timeout 0
console-mode max
editor no
EOF
root_uuid=$(findmnt -no UUID /)
if [[ -z ${root_uuid} ]]; then
printf 'Could not detect root filesystem UUID. Check findmnt/blkid manually.\n' >&2
exit 1
fi
cat >/boot/loader/entries/arch.conf <<EOF
title Arch Linux
linux /vmlinuz-linux
initrd /amd-ucode.img
initrd /initramfs-linux.img
options root=UUID=${root_uuid} rw
EOF
bootctl status
systemctl enable systemd-networkd.service
systemctl enable systemd-resolved.service
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
install -d /etc/systemd/network
ln -sf /usr/lib/systemd/network/89-ethernet.network.example /etc/systemd/network/89-ethernet.network
if ! id -u "${username}" >/dev/null 2>&1; then
useradd -m -s /bin/bash -G wheel,video,render "${username}"
fi
install -m 0750 -d /etc/sudoers.d
cat >/etc/sudoers.d/00-wheel <<'EOF'
%wheel ALL=(ALL:ALL) ALL
EOF
chmod 0440 /etc/sudoers.d/00-wheel
visudo -cf /etc/sudoers.d/00-wheel
passwd "${username}"
curl -O https://download.sublimetext.com/sublimehq-pub.gpg && pacman-key --add sublimehq-pub.gpg && pacman-key --lsign-key 8A8F901A && rm sublimehq-pub.gpg
echo -e "\n[sublime-text]\nServer = https://download.sublimetext.com/arch/stable/x86_64" | sudo tee -a /etc/pacman.conf
pacman -Syu --needed \
"${core_packages[@]}" \
"${network_packages[@]}" \
"${desktop_packages[@]}" \
"${media_packages[@]}" \
"${font_packages[@]}" \
"${app_packages[@]}" \
"${machine_packages[@]}" \
sublime-merge sublime-text
updatedb
systemctl enable sshd.service
systemctl enable rtkit-daemon.service
systemctl enable --now bluetooth.service
printf '\nChroot setup complete. Exit, unmount /mnt, reboot, then log in as %s.\n' "${username}"
printf 'After first login, run: xdg-user-dirs-update\n'
printf 'After first login, run: systemctl --user enable --now pipewire pipewire-pulse wireplumber\n'
printf 'Generate SSH key after first login with: ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519\n'

165
bin/docs-list.c Executable file
View File

@@ -0,0 +1,165 @@
#!/usr/bin/tcc -run
#include <ctype.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
void print_man_dir(FILE *menu, const char *dir) {
DIR *d = opendir(dir);
if (!d) {
return;
}
struct dirent *ent;
while ((ent = readdir(d))) {
if (ent->d_name[0] == '.') {
continue;
}
char file[512];
snprintf(file, sizeof(file), "%s", ent->d_name);
const char *suffixes[] = {".gz", ".bz2", ".xz", ".lzma", ".zst"};
for (size_t i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); i++) {
size_t flen = strlen(file);
size_t slen = strlen(suffixes[i]);
if (flen > slen && strcmp(file + flen - slen, suffixes[i]) == 0) {
file[flen - slen] = '\0';
break;
}
}
char *dot = strrchr(file, '.');
if (!dot || dot == file || !dot[1]) {
continue;
}
*dot++ = '\0';
fprintf(menu, "%s (%s)\tman\n", file, dot);
}
closedir(d);
}
void print_man_pages(FILE *menu, const char *root) {
DIR *d = opendir(root);
if (!d) {
return;
}
struct dirent *ent;
char path[4096];
while ((ent = readdir(d))) {
if (strncmp(ent->d_name, "man", 3) != 0) {
continue;
}
snprintf(path, sizeof(path), "%s/%s", root, ent->d_name);
print_man_dir(menu, path);
}
closedir(d);
}
int main(void) {
char path[] = "/tmp/docs-list.XXXXXX";
int fd = mkstemp(path);
if (fd < 0) {
perror("mkstemp");
return 1;
}
FILE *menu = fdopen(fd, "w");
if (!menu) {
perror("fdopen");
unlink(path);
return 1;
}
char line[8192];
FILE *manpath = popen("manpath 2>/dev/null", "r");
if (manpath && fgets(line, sizeof(line), manpath)) {
line[strcspn(line, "\n")] = '\0';
for (char *dir = strtok(line, ":"); dir; dir = strtok(NULL, ":")) {
print_man_pages(menu, dir);
}
}
if (manpath) {
pclose(manpath);
}
FILE *pydoc = popen("python -c 'import pkgutil; [print(m) for m in sorted({m.name for m in pkgutil.iter_modules()})]'", "r");
if (pydoc) {
while (fgets(line, sizeof(line), pydoc)) {
line[strcspn(line, "\n")] = '\0';
fprintf(menu, "%s\tpydoc\n", line);
}
pclose(pydoc);
}
fclose(menu);
char command[1024];
snprintf(command, sizeof(command), "wmenu -i -l 20 < '%s'", path);
FILE *wmenu = popen(command, "r");
if (!wmenu) {
perror("wmenu");
unlink(path);
return 1;
}
if (!fgets(line, sizeof(line), wmenu)) {
pclose(wmenu);
unlink(path);
return 0;
}
int status = pclose(wmenu);
unlink(path);
if (status != 0) {
return WIFEXITED(status) ? WEXITSTATUS(status) : 1;
}
line[strcspn(line, "\n")] = '\0';
char *kind = strrchr(line, '\t');
if (!kind) {
return 0;
}
*kind++ = '\0';
if (strcmp(kind, "man") == 0) {
char *s = line;
char name[256] = {0};
char section[64] = {0};
size_t i = 0;
while (*s && !isspace((unsigned char)*s) && *s != '(' && i < sizeof(name) - 1) {
name[i++] = *s++;
}
char *open = strchr(s, '(');
char *close = open ? strchr(open + 1, ')') : NULL;
if (open && close && close > open + 1) {
size_t len = close - open - 1;
if (len >= sizeof(section)) {
len = sizeof(section) - 1;
}
memcpy(section, open + 1, len);
}
if (name[0] && section[0]) {
execlp("foot", "foot", "-e", "man", section, name, NULL);
} else if (name[0]) {
execlp("foot", "foot", "-e", "man", name, NULL);
}
} else if (strcmp(kind, "pydoc") == 0 && line[0]) {
execlp("foot", "foot", "-e", "python", "-m", "pydoc", line, NULL);
}
perror("foot");
return 1;
}

1125
bin/json.c Executable file

File diff suppressed because it is too large Load Diff

2
bin/man-list Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
man -k . | wmenu -i -l 20 | awk '{print $1}' | xargs -r man

9
bin/pydoc-list Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/sh
module="$(
python - <<'PY' | wmenu -i -l 20
import pkgutil
for m in sorted({m.name for m in pkgutil.iter_modules()}):
print(m)
PY
)"
[ -n "$module" ] && foot -e python -m pydoc "$module"

7
bin/tmux3 Executable file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
tmux split-window -h \; \
split-window -h \; \
select-layout even-horizontal \; \
resize-pane -t 1 -R "${1:-5}"

View File

@@ -1,19 +1,12 @@
SRC=$HOME/.dotfilesrepo SRC=$HOME/dotfiles
rm $HOME/.bashrc [ -e $HOME/.bashrc ] && echo "I won't install ~/.bashrc because there is already a file like that; skipping setup for this file."
rm $HOME/.profile [ -e $HOME/.vimrc ] && echo "I won't install ~/.vimrc because there is already a file like that; skipping setup for this file."
[ -e $HOME/.bash_profile ] && echo "I won't install ~/.bash_profile because there is already a file like that; skipping setup for this file."
[ -d $HOME/.config ] && echo "I won't install ~/.config because there is already a directory like that; skipping setup for this directory."
[ -d $HOME/bin ] && echo "I won't install ~/bin because there is already a directory like that; skipping setup for this directory."
ln -sf $SRC/.bashrc $HOME/.bashrc ln -sf $SRC/.bashrc $HOME/.bashrc
ln -sf $SRC/.vimrc $HOME/.vimrc ln -sf $SRC/.vimrc $HOME/.vimrc
ln -sf $SRC/.profile $HOME/.profile ln -sf $SRC/.bash_profile $HOME/.bash_profile
ln -sf $SRC/.config $HOME/.config ln -sf $SRC/.config $HOME/.config
ln -sf $SRC/bin $HOME/bin ln -sf $SRC/bin $HOME/bin
# Install kakoune
wget https://github.com/mawww/kakoune/releases/download/v2026.05.21/kakoune-v2026.05.21-linux.tar.bz2
unpack kakoune-v2026.05.21-linux.tar.bz2
cd kakoune-v2026.05.21-linux
sudo cp -r bin/* /usr/local/bin/
sudo cp -r libexec/* /usr/local/libexec/
sudo cp -r share/* /usr/local/share/
cd ..
rm kakoune-v2026.05.21-linux -rf
rm kakoune-v2026.05.21-linux.tar.bz2