Compare commits
21 Commits
466220c7aa
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b712c714cf | ||
|
|
bc287e40e0 | ||
|
|
ab04d5ae63 | ||
|
|
116b66db4b | ||
|
|
7bfb9a2d7d | ||
|
|
6559d05e06 | ||
|
|
8d1fb991fa | ||
|
|
89e9f63019 | ||
|
|
a00ad450bf | ||
|
|
5ea5794ce6 | ||
|
|
ebcff99d2d | ||
|
|
c6bd25182a | ||
|
|
b9b2d652f7 | ||
|
|
4b2b24e052 | ||
|
|
5534eee012 | ||
|
|
0159412aa6 | ||
|
|
5b5e28221e | ||
|
|
e4851ca9a8 | ||
|
|
c4a251ce09 | ||
|
|
a67e7b0aa1 | ||
|
|
bd9506a9be |
11
.bashrc
11
.bashrc
@@ -16,8 +16,8 @@ HISTCONTROL=ignoreboth
|
|||||||
shopt -s histappend
|
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=1000
|
HISTSIZE=100000
|
||||||
HISTFILESIZE=2000
|
HISTFILESIZE=200000
|
||||||
|
|
||||||
# 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.
|
||||||
@@ -25,7 +25,10 @@ shopt -s checkwinsize
|
|||||||
|
|
||||||
# If set, the pattern "**" used in a pathname expansion context will
|
# If set, the pattern "**" used in a pathname expansion context will
|
||||||
# match all files and zero or more directories and subdirectories.
|
# match all files and zero or more directories and subdirectories.
|
||||||
#shopt -s globstar
|
shopt -s globstar
|
||||||
|
|
||||||
|
# Type directory names directly, without 'cd' and still move there
|
||||||
|
shopt -s autocd
|
||||||
|
|
||||||
# make less more friendly for non-text input files, see lesspipe(1)
|
# make less more friendly for non-text input files, see lesspipe(1)
|
||||||
#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
|
#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
|
||||||
@@ -111,3 +114,5 @@ if ! shopt -oq posix; then
|
|||||||
. /etc/bash_completion
|
. /etc/bash_completion
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
export PATH="$PATH:/home/kk/.local/share/pi-node/node-v22.22.3-linux-x64/bin"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
alias ls='ls -lahtr'
|
alias ls='ls -lahtr'
|
||||||
alias vi='vim'
|
alias vi='kak'
|
||||||
alias df='/usr/bin/git --git-dir=$HOME/.dotfilesrepo/ --work-tree=$HOME'
|
alias df='/usr/bin/git --git-dir=$HOME/.dotfilesrepo/ --work-tree=$HOME'
|
||||||
|
alias unpack='dtrx'
|
||||||
|
|||||||
32
.config/git/config
Normal file
32
.config/git/config
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
[user]
|
||||||
|
name = KK
|
||||||
|
email = git.exclaim518@passmail.net
|
||||||
|
[core]
|
||||||
|
editor = kak
|
||||||
|
excludesFile = ~/.config/git/ignore
|
||||||
|
[commit]
|
||||||
|
verbose = true
|
||||||
|
[push]
|
||||||
|
autoSetupRemote = true
|
||||||
|
[diff]
|
||||||
|
colorMoved = default
|
||||||
|
algorithm = histogram
|
||||||
|
[merge]
|
||||||
|
conflictStyle = zdiff3
|
||||||
|
[color]
|
||||||
|
ui = auto
|
||||||
|
[branch]
|
||||||
|
sort = -committerdate
|
||||||
|
[tag]
|
||||||
|
sort = version:refname
|
||||||
|
[alias]
|
||||||
|
s = status --short --branch
|
||||||
|
st = status
|
||||||
|
co = checkout
|
||||||
|
br = branch
|
||||||
|
ci = commit
|
||||||
|
lg = log --graph --pretty=format:'%C(auto)%h%Creset %Cgreen%cr%Creset %C(bold blue)%an%Creset %s%C(auto)%d%Creset' --all
|
||||||
|
branches = for-each-ref --sort=-committerdate refs/heads/ --format='%(committerdate:relative) %(refname:short)'
|
||||||
|
filelog = log --follow --graph --decorate --date=relative --pretty=format:'%C(auto)%h%Creset %Cgreen%cr%Creset %C(bold blue)%an%Creset %s'
|
||||||
|
|
||||||
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
# TODO:
|
|
||||||
# - [ ] Mount /krk-pc on startup
|
|
||||||
# - [ ] Add server SSH keys and PC ssh keys
|
|
||||||
# - [ ] Mount /proton on startup
|
|
||||||
# - [x] Hibernate if not using PC for 10 minutes
|
|
||||||
#
|
|
||||||
# - [ ] Combine apps + bin + bookmarks
|
|
||||||
# - [x] everything relevant wmenu browser (programs and scripts without arguments, bookmarks, files)
|
|
||||||
# - [x] plocate + wmenu > xdg-open
|
|
||||||
# - [x] applications + bin folder
|
|
||||||
# - [x] bookmarks
|
|
||||||
#
|
|
||||||
# - [x] fzf starship zoxide eza bat (only fzf seems descent)
|
|
||||||
#
|
|
||||||
# Solutions in search for problems:
|
|
||||||
# - [ ] tmux automation
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
# Setup sudo for user
|
|
||||||
su root
|
|
||||||
export PATH="$PATH:/usr/sbin"
|
|
||||||
apt install sudo
|
|
||||||
usermod -aG sudo kk
|
|
||||||
exit # exit root
|
|
||||||
exit # exit user to reload config
|
|
||||||
|
|
||||||
# Basic utilities
|
|
||||||
sudo apt install clang cmake build-essential make tcc vim ripgrep curl git man-db plocate tmux zip unzip fzf
|
|
||||||
sudo updatedb
|
|
||||||
|
|
||||||
# Standard enviroment setup
|
|
||||||
sudo apt install xdg-desktop-portal-wlr xdg-desktop-portal-gtk xdg-user-dirs
|
|
||||||
|
|
||||||
# DE setup
|
|
||||||
sudo apt install sway swayidle swaybg swaylock foot wmenu brightnessctl
|
|
||||||
|
|
||||||
# Clipboard and history
|
|
||||||
sudo apt install wl-clipboard cliphist
|
|
||||||
|
|
||||||
# Issue fix
|
|
||||||
# there were issues because user was not in render group (error messages on start of sway)
|
|
||||||
sudo usermod -aG render kk
|
|
||||||
|
|
||||||
# Setup audio
|
|
||||||
sudo apt install pipewire pipewire-pulse wireplumber pavucontrol
|
|
||||||
|
|
||||||
sudo apt install sshfs
|
|
||||||
|
|
||||||
# Setup internet
|
|
||||||
# sudo apt install w3m surfraw
|
|
||||||
sudo apt install chromium
|
|
||||||
|
|
||||||
20
.config/kak/kakrc
Normal file
20
.config/kak/kakrc
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
colorscheme gruvbox-dark
|
||||||
|
|
||||||
|
# Use 4 spaces for indentation.
|
||||||
|
# indentwidth controls Kakoune's indentation commands; tabstop controls display width.
|
||||||
|
set-option global tabstop 4
|
||||||
|
set-option global indentwidth 4
|
||||||
|
set-option global makecmd 'bash build.sh'
|
||||||
|
|
||||||
|
map global user n :make-next-error<ret>
|
||||||
|
map global user p :make-previous-error<ret>
|
||||||
|
|
||||||
|
# Kakoune does not have a Vim-style 'expandtab' option. Make a literal Tab key
|
||||||
|
# insert four spaces instead of a tab character while in insert mode.
|
||||||
|
map global insert <tab> '<space><space><space><space>'
|
||||||
|
|
||||||
|
hook global RegisterModified '"' %{ nop %sh{
|
||||||
|
printf %s "$kak_main_reg_dquote" | wl-copy > /dev/null 2>&1 &
|
||||||
|
}}
|
||||||
|
|
||||||
|
add-highlighter global/ number-lines
|
||||||
@@ -42,18 +42,8 @@ include /etc/sway/config-vars.d/*
|
|||||||
#
|
#
|
||||||
# You can get the names of your outputs by running: swaymsg -t get_outputs
|
# You can get the names of your outputs by running: swaymsg -t get_outputs
|
||||||
|
|
||||||
### Idle configuration
|
# Suspend the machine after 600 seconds
|
||||||
#
|
exec swayidle -w timeout 600 'systemctl suspend'
|
||||||
# Example configuration:
|
|
||||||
#
|
|
||||||
exec swayidle -w \
|
|
||||||
timeout 300 'swaymsg "output * power off"' resume 'swaymsg "output * power on"' \
|
|
||||||
timeout 600 'systemctl hibernate' \
|
|
||||||
before-sleep 'swaylock -f -c 000000'
|
|
||||||
#
|
|
||||||
# This will lock your screen after 300 seconds of inactivity, then turn off
|
|
||||||
# your displays after another 300 seconds, and turn your screens back on when
|
|
||||||
# resumed. It will also lock your screen before your computer goes to sleep.
|
|
||||||
|
|
||||||
### Input configuration
|
### Input configuration
|
||||||
#
|
#
|
||||||
@@ -70,6 +60,8 @@ exec swayidle -w \
|
|||||||
# Read `man 5 sway-input` for more information about this section.
|
# Read `man 5 sway-input` for more information about this section.
|
||||||
|
|
||||||
input * {
|
input * {
|
||||||
|
xkb_layout pl
|
||||||
|
xkb_options caps:none
|
||||||
repeat_rate 80
|
repeat_rate 80
|
||||||
repeat_delay 300
|
repeat_delay 300
|
||||||
}
|
}
|
||||||
@@ -86,14 +78,13 @@ input "1267:12734:ELAN06FA:00_04F3:31BE_Touchpad" {
|
|||||||
scroll_factor 0.8
|
scroll_factor 0.8
|
||||||
}
|
}
|
||||||
|
|
||||||
# Clipboard history
|
|
||||||
exec wl-paste --type text --watch cliphist store
|
|
||||||
exec wl-paste --type image --watch cliphist store
|
|
||||||
|
|
||||||
### Key bindings
|
### Key bindings
|
||||||
#
|
#
|
||||||
# Basics:
|
# Basics:
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
# Start a terminal
|
# Start a terminal
|
||||||
bindsym $mod+Return exec $term
|
bindsym $mod+Return exec $term
|
||||||
|
|
||||||
@@ -203,6 +194,9 @@ exec wl-paste --type image --watch cliphist store
|
|||||||
# Show the next scratchpad window or hide the focused scratchpad window.
|
# Show the next scratchpad window or hide the focused scratchpad window.
|
||||||
# If there are multiple scratchpad windows, this command cycles through them.
|
# If there are multiple scratchpad windows, this command cycles through them.
|
||||||
bindsym $mod+minus scratchpad show
|
bindsym $mod+minus scratchpad show
|
||||||
|
|
||||||
|
# Dedicated scratchpad terminal for voice queries to pi.
|
||||||
|
for_window [app_id="pi-voice"] border pixel 2, move scratchpad
|
||||||
#
|
#
|
||||||
# Resizing containers:
|
# Resizing containers:
|
||||||
#
|
#
|
||||||
@@ -217,7 +211,7 @@ mode "resize" {
|
|||||||
bindsym $right resize grow width 10px
|
bindsym $right resize grow width 10px
|
||||||
|
|
||||||
# Ditto, with arrow keys
|
# Ditto, with arrow keys
|
||||||
bindsym Left kesize shrink width 10px
|
bindsym Left resize shrink width 10px
|
||||||
bindsym Down resize grow height 10px
|
bindsym Down resize grow height 10px
|
||||||
bindsym Up resize shrink height 10px
|
bindsym Up resize shrink height 10px
|
||||||
bindsym Right resize grow width 10px
|
bindsym Right resize grow width 10px
|
||||||
@@ -225,7 +219,9 @@ mode "resize" {
|
|||||||
# Return to default mode
|
# Return to default mode
|
||||||
bindsym Return mode "default"
|
bindsym Return mode "default"
|
||||||
bindsym Escape mode "default"
|
bindsym Escape mode "default"
|
||||||
|
bindsym $mod+r mode "default"
|
||||||
}
|
}
|
||||||
|
|
||||||
bindsym $mod+r mode "resize"
|
bindsym $mod+r mode "resize"
|
||||||
#
|
#
|
||||||
# Utilities:
|
# Utilities:
|
||||||
@@ -239,7 +235,19 @@ 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 grim
|
bindsym Print exec sh -c 'mkdir -p ~/screenshots; f=~/screenshots/$(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"'
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
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"'
|
||||||
|
|
||||||
|
# Voice query to pi in a dedicated tmux session/scratchpad terminal.
|
||||||
|
# Hold $mod+Shift+x, speak, release; transcription is submitted to pi.
|
||||||
|
bindsym $mod+Shift+x exec ~/bin/pi-voice-query start
|
||||||
|
bindsym --release $mod+Shift+x exec ~/bin/pi-voice-query stop
|
||||||
|
|
||||||
|
|
||||||
# Pick an entry from clipboard history and copy it back to the clipboard
|
# Pick an entry from clipboard history and copy it back to the clipboard
|
||||||
bindsym $mod+c exec sh -c 'cliphist list | wmenu -l 10 | cliphist decode | wl-copy'
|
bindsym $mod+c exec sh -c 'cliphist list | wmenu -l 10 | cliphist decode | wl-copy'
|
||||||
|
|||||||
@@ -7,14 +7,21 @@ print_status() {
|
|||||||
|
|
||||||
brightness=$(brightnessctl -m 2>/dev/null | awk -F, '{print $4}')
|
brightness=$(brightnessctl -m 2>/dev/null | awk -F, '{print $4}')
|
||||||
|
|
||||||
printf 'VOL %s | BRI %s | %s\n' "${volume:-n/a}" "${brightness:-n/a}" "$(date +'%Y-%m-%d %H:%M:%S')"
|
voxtype_state=$(voxtype status 2>/dev/null)
|
||||||
|
case "$voxtype_state" in
|
||||||
|
recording) voxtype=' | VOX REC' ;;
|
||||||
|
transcribing) voxtype=' | VOX ...' ;;
|
||||||
|
*) voxtype='' ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
printf 'VOL %s | BRI %s%s | %s\n' "${volume:-n/a}" "${brightness:-n/a}" "$voxtype" "$(date +'%Y-%m-%d %H:%M:%S')"
|
||||||
}
|
}
|
||||||
|
|
||||||
trap print_status USR1
|
trap print_status USR1
|
||||||
|
|
||||||
print_status
|
print_status
|
||||||
while :; do
|
while :; do
|
||||||
sleep 60 &
|
sleep 1 &
|
||||||
wait $!
|
wait $!
|
||||||
print_status
|
print_status
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -4,6 +4,13 @@
|
|||||||
set -g extended-keys on
|
set -g extended-keys on
|
||||||
set -g extended-keys-format csi-u
|
set -g extended-keys-format csi-u
|
||||||
|
|
||||||
|
# Index windows/tabs and panes from 1 instead of 0.
|
||||||
|
set -g base-index 1
|
||||||
|
setw -g pane-base-index 1
|
||||||
|
|
||||||
|
# Automatically close gaps in window/tab numbers after a window is closed.
|
||||||
|
set -g renumber-windows on
|
||||||
|
|
||||||
# Use 256-colour tmux terminfo and advertise truecolour support to apps.
|
# Use 256-colour tmux terminfo and advertise truecolour support to apps.
|
||||||
set -g default-terminal "tmux-256color"
|
set -g default-terminal "tmux-256color"
|
||||||
set -as terminal-features ",*:RGB"
|
set -as terminal-features ",*:RGB"
|
||||||
@@ -20,12 +27,6 @@ bind-key j select-pane -D
|
|||||||
bind-key k select-pane -U
|
bind-key k select-pane -U
|
||||||
bind-key l select-pane -R
|
bind-key l select-pane -R
|
||||||
|
|
||||||
# Optional no-prefix pane navigation with Alt+hjkl
|
|
||||||
bind-key -n M-h select-pane -L
|
|
||||||
bind-key -n M-j select-pane -D
|
|
||||||
bind-key -n M-k select-pane -U
|
|
||||||
bind-key -n M-l select-pane -R
|
|
||||||
|
|
||||||
# Mouse support: scroll with the wheel, resize/select panes, and make mouse
|
# Mouse support: scroll with the wheel, resize/select panes, and make mouse
|
||||||
# selections pane-aware instead of selecting across the whole terminal window.
|
# selections pane-aware instead of selecting across the whole terminal window.
|
||||||
set-option -g mouse on
|
set-option -g mouse on
|
||||||
|
|||||||
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.config/librewolf/
|
||||||
|
.config/pulse/
|
||||||
|
bin/pi
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
6
.profile
6
.profile
@@ -30,3 +30,9 @@ fi
|
|||||||
if [ -d "$HOME/.local/bin" ] ; then
|
if [ -d "$HOME/.local/bin" ] ; then
|
||||||
PATH="$HOME/.local/bin:$PATH"
|
PATH="$HOME/.local/bin:$PATH"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -z "$WAYLAND_DISPLAY" ] && [ "$XDG_VTNR" = 1 ]; then
|
||||||
|
export WLR_NO_HARDWARE_CURSORS=1
|
||||||
|
exec sway --unsupported-gpu
|
||||||
|
fi
|
||||||
|
|
||||||
|
|||||||
348
README.md
Normal file
348
README.md
Normal file
@@ -0,0 +1,348 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
### 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 \
|
||||||
|
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.
|
||||||
|
- 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
|
||||||
|
```
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
import os, subprocess, json
|
import os, subprocess, json, sqlite3, shutil, tempfile
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
def readfile(path):
|
def readfile(path):
|
||||||
fd = open(path, "r")
|
fd = open(path, "r")
|
||||||
@@ -8,6 +8,9 @@ def readfile(path):
|
|||||||
fd.close()
|
fd.close()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
#
|
||||||
|
# GTK apps
|
||||||
|
#
|
||||||
vals = {}
|
vals = {}
|
||||||
home = os.environ["HOME"]
|
home = os.environ["HOME"]
|
||||||
appsdir=["/usr/share/applications", f"{home}/.local/share/applications"]
|
appsdir=["/usr/share/applications", f"{home}/.local/share/applications"]
|
||||||
@@ -34,7 +37,7 @@ for appdir in appsdir:
|
|||||||
_exec = line[5:]
|
_exec = line[5:]
|
||||||
elif line.startswith("Type="):
|
elif line.startswith("Type="):
|
||||||
_type = line[5:]
|
_type = line[5:]
|
||||||
elif line.startswith("Name="):
|
elif line.startswith("Name=") and _name is None:
|
||||||
_name = line[5:]
|
_name = line[5:]
|
||||||
elif line.startswith("NoDisplay="):
|
elif line.startswith("NoDisplay="):
|
||||||
_nodisplay = line[10:]
|
_nodisplay = line[10:]
|
||||||
@@ -49,9 +52,11 @@ for appdir in appsdir:
|
|||||||
if _nodisplay == "true" or _hidden == "true":
|
if _nodisplay == "true" or _hidden == "true":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
vals[_name] = {"kind": "app", "exec": _exec, "path": path}
|
vals[_name] = {"kind": "app", "exec": _exec, "path": path, "name": appfile[:-8]}
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bin
|
||||||
|
#
|
||||||
bindir = f"{home}/bin"
|
bindir = f"{home}/bin"
|
||||||
for file in os.listdir(bindir):
|
for file in os.listdir(bindir):
|
||||||
path = f"{bindir}/{file}"
|
path = f"{bindir}/{file}"
|
||||||
@@ -61,6 +66,9 @@ for file in os.listdir(bindir):
|
|||||||
continue
|
continue
|
||||||
vals[file] = {"kind": "bin", "path": path}
|
vals[file] = {"kind": "bin", "path": path}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Chromium bookmarks
|
||||||
|
#
|
||||||
def walk_bookmarks(node, folder=""):
|
def walk_bookmarks(node, folder=""):
|
||||||
if isinstance(node, dict):
|
if isinstance(node, dict):
|
||||||
if node.get("type") == "url" and node.get("url"):
|
if node.get("type") == "url" and node.get("url"):
|
||||||
@@ -82,6 +90,74 @@ if os.path.isfile(bookmarkfile):
|
|||||||
for root in roots.values():
|
for root in roots.values():
|
||||||
walk_bookmarks(root)
|
walk_bookmarks(root)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Firefox bookmarks
|
||||||
|
#
|
||||||
|
SEARCH_DIRS = [
|
||||||
|
Path.home() / ".config" / "librewolf",
|
||||||
|
]
|
||||||
|
|
||||||
|
def find_places_databases():
|
||||||
|
seen = set()
|
||||||
|
for base in SEARCH_DIRS:
|
||||||
|
if not base.exists():
|
||||||
|
continue
|
||||||
|
for db in base.glob("**/places.sqlite"):
|
||||||
|
resolved = db.resolve()
|
||||||
|
if resolved not in seen:
|
||||||
|
seen.add(resolved)
|
||||||
|
yield db
|
||||||
|
|
||||||
|
def read_firefox_bookmarks(db_path):
|
||||||
|
# Copy the DB first so this also works while Firefox/LibreWolf is running.
|
||||||
|
with tempfile.TemporaryDirectory() as tmp:
|
||||||
|
tmp_db = Path(tmp) / "places.sqlite"
|
||||||
|
shutil.copy2(db_path, tmp_db)
|
||||||
|
|
||||||
|
for suffix in ("-wal", "-shm"):
|
||||||
|
sidecar = Path(str(db_path) + suffix)
|
||||||
|
if sidecar.exists():
|
||||||
|
shutil.copy2(sidecar, Path(str(tmp_db) + suffix))
|
||||||
|
|
||||||
|
con = sqlite3.connect(f"file:{tmp_db}?mode=ro", uri=True)
|
||||||
|
cur = con.cursor()
|
||||||
|
query = """
|
||||||
|
WITH RECURSIVE folders(id, path) AS (
|
||||||
|
SELECT id, COALESCE(title, '')
|
||||||
|
FROM moz_bookmarks
|
||||||
|
WHERE parent = 0
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT b.id,
|
||||||
|
CASE
|
||||||
|
WHEN folders.path = '' THEN COALESCE(b.title, '')
|
||||||
|
WHEN COALESCE(b.title, '') = '' THEN folders.path
|
||||||
|
ELSE folders.path || '/' || b.title
|
||||||
|
END
|
||||||
|
FROM moz_bookmarks b
|
||||||
|
JOIN folders ON b.parent = folders.id
|
||||||
|
WHERE b.type = 2
|
||||||
|
)
|
||||||
|
SELECT COALESCE(folders.path, ''), COALESCE(b.title, ''), p.url
|
||||||
|
FROM moz_bookmarks b
|
||||||
|
JOIN moz_places p ON b.fk = p.id
|
||||||
|
LEFT JOIN folders ON b.parent = folders.id
|
||||||
|
WHERE b.type = 1
|
||||||
|
AND p.url IS NOT NULL
|
||||||
|
ORDER BY b.dateAdded
|
||||||
|
"""
|
||||||
|
|
||||||
|
for folder, title, url in cur.execute(query):
|
||||||
|
name = title or url
|
||||||
|
label = f"{folder}/{name}" if folder else name
|
||||||
|
vals[label] = {"kind": "url", "url": url}
|
||||||
|
|
||||||
|
con.close()
|
||||||
|
|
||||||
|
for it in find_places_databases():
|
||||||
|
read_firefox_bookmarks(it)
|
||||||
|
|
||||||
entries = []
|
entries = []
|
||||||
for it in vals.items():
|
for it in vals.items():
|
||||||
entries.append(it[0])
|
entries.append(it[0])
|
||||||
@@ -92,12 +168,15 @@ if result.returncode != 0:
|
|||||||
exit(result.returncode)
|
exit(result.returncode)
|
||||||
|
|
||||||
choice = result.stdout.strip()
|
choice = result.stdout.strip()
|
||||||
val = vals[choice]
|
if choice[0] == '@':
|
||||||
|
choice = choice[1:]
|
||||||
|
val = vals.get(choice)
|
||||||
|
if val is not None:
|
||||||
if val["kind"] == "bin":
|
if val["kind"] == "bin":
|
||||||
subprocess.run([val["path"]])
|
subprocess.run([val["path"]])
|
||||||
elif val["kind"] == "app":
|
elif val["kind"] == "app":
|
||||||
subprocess.run(["gtk-launch", choice])
|
subprocess.run(["gtk-launch", val["name"]])
|
||||||
elif val["kind"] == "url":
|
elif val["kind"] == "url":
|
||||||
subprocess.run(["xdg-open", val["url"]])
|
subprocess.run(["xdg-open", val["url"]])
|
||||||
|
else:
|
||||||
|
subprocess.run(["xdg-open", "https://www.google.com/search?q=" + choice])
|
||||||
|
|||||||
95
bin/pi-voice-query
Executable file
95
bin/pi-voice-query
Executable file
@@ -0,0 +1,95 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
SESSION="pi-voice"
|
||||||
|
APP_ID="pi-voice"
|
||||||
|
TITLE="Pi Voice"
|
||||||
|
OUT="${XDG_RUNTIME_DIR:-/tmp}/pi-voice-query.txt"
|
||||||
|
STATUS_SCRIPT="$HOME/.config/sway/status.sh"
|
||||||
|
|
||||||
|
refresh_bar() {
|
||||||
|
pkill -USR1 -f "$STATUS_SCRIPT" 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
position_pi_window() {
|
||||||
|
# Size scratchpad window to 60% of the focused output using absolute pixels.
|
||||||
|
# Doing this here is more reliable than a for_window percentage resize.
|
||||||
|
set -- $(swaymsg -t get_outputs 2>/dev/null | python3 -c '
|
||||||
|
import json, sys
|
||||||
|
outs = json.load(sys.stdin)
|
||||||
|
out = next((o for o in outs if o.get("focused")), None) or next((o for o in outs if o.get("active")), None)
|
||||||
|
rect = (out or {}).get("rect", {})
|
||||||
|
w = int(rect.get("width", 1200) * 0.6)
|
||||||
|
h = int(rect.get("height", 800) * 0.6)
|
||||||
|
print(w, h)
|
||||||
|
')
|
||||||
|
w=${1:-1200}
|
||||||
|
h=${2:-800}
|
||||||
|
swaymsg '[app_id="'"$APP_ID"'"] border pixel 2, resize set width '"$w"' px height '"$h"' px, move position center' >/dev/null 2>&1 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_pi_terminal() {
|
||||||
|
if ! tmux has-session -t "$SESSION" 2>/dev/null; then
|
||||||
|
tmux new-session -d -s "$SESSION" 'pi'
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v swaymsg >/dev/null 2>&1; then
|
||||||
|
if ! swaymsg -t get_tree 2>/dev/null | grep -q '"app_id": "'"$APP_ID"'"'; then
|
||||||
|
foot --app-id="$APP_ID" --title="$TITLE" \
|
||||||
|
--override=main.resize-by-cells=no \
|
||||||
|
--override=colors.alpha=1.0 \
|
||||||
|
--override=main.pad=0x0 \
|
||||||
|
tmux attach-session -t "$SESSION" >/dev/null 2>&1 &
|
||||||
|
# Give the window a moment to appear before trying to show/focus it.
|
||||||
|
sleep 0.5
|
||||||
|
fi
|
||||||
|
swaymsg '[app_id="'"$APP_ID"'"] scratchpad show, focus' >/dev/null 2>&1 || true
|
||||||
|
position_pi_window
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
send_to_pi() {
|
||||||
|
text=$1
|
||||||
|
[ -n "$text" ] || exit 0
|
||||||
|
|
||||||
|
ensure_pi_terminal
|
||||||
|
|
||||||
|
# Paste literally, then press Enter to submit to pi.
|
||||||
|
printf '%s' "$text" | tmux load-buffer -
|
||||||
|
tmux paste-buffer -t "$SESSION"
|
||||||
|
tmux send-keys -t "$SESSION" Enter
|
||||||
|
}
|
||||||
|
|
||||||
|
case "${1:-}" in
|
||||||
|
start)
|
||||||
|
ensure_pi_terminal
|
||||||
|
: > "$OUT"
|
||||||
|
voxtype record start --file="$OUT"
|
||||||
|
refresh_bar
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
voxtype record stop
|
||||||
|
refresh_bar
|
||||||
|
|
||||||
|
# Wait for transcription to land in OUT. Stop early once voxtype is idle
|
||||||
|
# and the file has text, otherwise allow slower large-model runs.
|
||||||
|
i=0
|
||||||
|
while [ "$i" -lt 180 ]; do
|
||||||
|
if [ -s "$OUT" ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
state=$(voxtype status 2>/dev/null || true)
|
||||||
|
[ "$state" = idle ] && [ "$i" -gt 2 ] && break
|
||||||
|
sleep 0.5
|
||||||
|
i=$((i + 1))
|
||||||
|
done
|
||||||
|
refresh_bar
|
||||||
|
|
||||||
|
text=$(cat "$OUT" 2>/dev/null || true)
|
||||||
|
send_to_pi "$text"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "usage: $0 start|stop" >&2
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
19
setup.sh
Normal file
19
setup.sh
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
SRC=$HOME/.dotfilesrepo
|
||||||
|
rm $HOME/.bashrc
|
||||||
|
rm $HOME/.profile
|
||||||
|
ln -sf $SRC/.bashrc $HOME/.bashrc
|
||||||
|
ln -sf $SRC/.vimrc $HOME/.vimrc
|
||||||
|
ln -sf $SRC/.profile $HOME/.profile
|
||||||
|
ln -sf $SRC/.config $HOME/.config
|
||||||
|
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
|
||||||
Reference in New Issue
Block a user