Compare commits

..
34 Commits
Author SHA1 Message Date
jasonhilder c43ff55d32 Emacs clean up. 2026-10-27 07:59:41 +02:00
jasonhilder 62e4feba61 Custom theme 2026-10-26 09:34:18 +02:00
jasonhilder d2e47dec2a Emacs omg. 2026-10-26 08:26:57 +02:00
jasonhilder d2de783f3b Updated ignore files. 2026-10-26 08:26:45 +02:00
jasonhilder 1c4f950e3f Emacs config wip, split to better fit modules. 2026-10-26 08:06:00 +02:00
jasonhilder 2e6bbc77fd Cleanups. 2026-10-26 08:05:45 +02:00
jasonhilder 60c8d863d3 Cleaned up gitignore. 2026-10-26 08:05:31 +02:00
jasonhilder 30c87a36af Steam install script. 2026-10-26 08:05:19 +02:00
jasonhilder 5ddfe643c3 Updated dired to hide hidden files and toggle them. 2026-10-21 08:04:00 +02:00
jasonhilder ce6b1aa6f0 Focus script acts as light weight window manager with x11. 2026-10-16 06:34:33 +02:00
jasonhilder 8313889ac4 Big emacs cleanup, nearly there. 2026-10-16 06:34:16 +02:00
jasonhilder 9b63be7856 Updates for the xfce4 emacs setup. 2026-10-15 07:48:37 +02:00
jasonhilder 625713cbb4 Small cleanup for trimmed configs. 2026-10-14 07:45:32 +02:00
jasonhilder 20f501c2b1 Cleanup of old configs. 2026-10-14 07:44:59 +02:00
jasonhilder 8fa53a582c Added the old emacs config. 2026-10-14 07:44:06 +02:00
jasonhilder ed196212ed Clean up of old configs. 2026-10-14 07:42:20 +02:00
jasonhilder 7d9fc403b0 Simple vis plugin add. 2026-10-09 07:07:53 +02:00
jasonhilder dc575dc2fd added some helpers for niri. 2026-10-09 07:07:42 +02:00
jasonhilder 438f67e4cc Update config/vis/lexers/odin.lua 2026-10-07 06:42:48 +00:00
jasonhilder 6617102c5b Update config/vis/visrc.lua 2026-10-07 06:42:19 +00:00
jasonhilder ee1bb98515 Nearly there!! 2026-10-07 08:21:36 +02:00
jasonhilder aeb9df3e0e Vis Editor updates. 2026-10-06 09:14:01 +02:00
jasonhilder bc408c412b Updated proj file. 2026-10-06 05:40:51 +02:00
jasonhilder 4264a4c05c Swapped vim for vis + yazi 2026-10-06 05:40:37 +02:00
jasonhilder ac8adf9554 Cleanup. 2026-10-06 05:40:09 +02:00
jasonhilder f3f3d6a94a Odin ols env var for builtin defs. 2026-09-23 12:50:30 +02:00
jasonhilder d4cb9100c0 Installs converted for void. 2026-09-23 12:50:06 +02:00
jasonhilder 9ce77ad817 Rework for void + dms. 2026-09-23 12:49:55 +02:00
jasonhilder 2a6b552725 Kanata config rename for system service. 2026-09-23 12:49:44 +02:00
jasonhilder 10db5ade01 Initial niri config. 2026-09-23 12:49:32 +02:00
jasonhilder 83409564ef Updates to fish config. 2026-09-14 08:29:27 +02:00
jasonhilder 3a111d6017 Major cleanup for pop os minimal config. 2026-09-09 05:48:19 +02:00
jasonhilder 1e2dd2f5fb Vim setup 2026-08-18 05:52:38 +02:00
jasonhilder 398722e3a4 Removed evi for vanilla vim. 2026-08-18 05:50:54 +02:00
28 changed files with 1628 additions and 780 deletions
+16 -2
View File
@@ -1,7 +1,21 @@
# emacs
config/emacs/.ignore
config/emacs/var/
config/emacs/elfeed/
config/emacs/eshell/
config/emacs/auto-save-list/
# fish
config/fish/conf.d config/fish/conf.d
config/fish/functions config/fish/functions
config/fish/fish_variables config/fish/fish_variables
config/fish/generated_completions/
# vim/nvim
config/vim/autoload/
config/vim/pack/
config/vim/.netrwhist
config/nvim/nvim-pack-lock.json config/nvim/nvim-pack-lock.json
config/awesome/bling # other
scripts/bin/Obsidian
scripts/bin/ols scripts/bin/ols
scripts/bin/deno
scripts/bin/yt-dlp
scripts/bin/tiled
-120
View File
@@ -1,120 +0,0 @@
#!/usr/bin/env bash
set -e
if [ "$EUID" -eq 0 ]; then
echo "Please run this script as your normal user, not with sudo."
exit 1
fi
echo "==> Updating system..."
sudo xbps-install -Syu
echo "==> Installing KDE and desktop essentials..."
sudo xbps-install -y \
kde-plasma \
kde-baseapps \
NetworkManager \
sddm \
xorg-minimal \
xorg-server-xwayland \
mesa-dri \
qt6-wayland \
kwayland \
elogind \
pipewire \
alsa-pipewire \
libspa-bluetooth \
bluez \
xdg-desktop-portal \
xdg-desktop-portal-kde \
git \
curl \
neovim
echo "==> Disabling conflicting DHCP service..."
if [ -e /var/service/dhcpcd ]; then
sudo sv down dhcpcd || true
sudo rm -f /var/service/dhcpcd
fi
echo "==> Enabling system services..."
enable_service() {
service="$1"
if [ ! -e "/var/service/$service" ]; then
sudo ln -s "/etc/sv/$service" "/var/service/$service"
fi
}
enable_service dbus
enable_service NetworkManager
enable_service sddm
enable_service bluetoothd
echo "==> Adding user to required groups..."
sudo usermod -aG network,audio,video,bluetooth "$USER"
echo "==> Configuring ALSA for PipeWire..."
sudo mkdir -p /etc/alsa/conf.d
sudo ln -sf \
/usr/share/alsa/alsa.conf.d/50-pipewire.conf \
/etc/alsa/conf.d/50-pipewire.conf
sudo ln -sf \
/usr/share/alsa/alsa.conf.d/99-pipewire-default.conf \
/etc/alsa/conf.d/99-pipewire-default.conf
echo "==> Configuring PipeWire PulseAudio compatibility..."
sudo mkdir -p /etc/pipewire/pipewire.conf.d
sudo ln -sf \
/usr/share/examples/pipewire/20-pipewire-pulse.conf \
/etc/pipewire/pipewire.conf.d/20-pipewire-pulse.conf
echo "==> Enabling PipeWire desktop autostart..."
mkdir -p "$HOME/.config/autostart"
ln -sf \
/usr/share/applications/pipewire.desktop \
"$HOME/.config/autostart/pipewire.desktop"
echo "==> Reconfiguring packages..."
sudo xbps-reconfigure -fa
echo
echo "========================================"
echo " Void KDE bootstrap complete"
echo "========================================"
echo
echo "Installed:"
echo " KDE Plasma"
echo " SDDM"
echo " Plasma Wayland"
echo " NetworkManager"
echo " PipeWire + WirePlumber"
echo " Bluetooth"
echo " XWayland"
echo " Neovim"
echo
echo "Enabled services:"
sudo sv status dbus NetworkManager bluetoothd sddm
echo
echo "NOTE: elogind is installed but intentionally"
echo "not enabled as a runit service."
echo
echo "Reboot, then select 'Plasma (Wayland)' in SDDM."
echo
echo " sudo reboot"
echo
-184
View File
@@ -1,184 +0,0 @@
# ==============================================================================
# ENVIRONMENT VARIABLES
# ==============================================================================
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_DATA_HOME="$HOME/.local/share"
export XDG_CACHE_HOME="$HOME/.cache"
export XDG_STATE_HOME="$HOME/.local/state"
export GOOGLE_API_KEY="no"
export GOOGLE_DEFAULT_CLIENT_ID="no"
export GOOGLE_DEFAULT_CLIENT_SECRET="no"
# Core settings
export EDITOR="evi"
export VISUAL="evi"
export MANPAGER="evi +Man!"
export BROWSER="firefox"
export COLORTERM="truecolor"
# Development
export DEBUG=1
export GOPATH="$HOME/.go"
export GOCACHE="$HOME/.go/cache"
export GOROOT=/usr/local/go
export PATH="/usr/local/go/bin:$GOPATH/bin:$PATH"
# Direnv
eval "$(direnv hook bash)"
# ==============================================================================
# FZF configuration
# ==============================================================================
export FZF_DEFAULT_OPTS="
--height 40%
--layout=reverse
--border
--ansi
--preview-window=down:30%
--bind 'ctrl-d:preview-page-down,ctrl-u:preview-page-up'
--color=fg:#ffffff,header:#f38ba8,info:#cba6ac,pointer:#f5e0dc
--color=marker:#f5e0dc,fg+:#cdd6f4,prompt:#cba6ac,hl+:#f38ba8"
export FZF_DEFAULT_COMMAND='fdfind --exclude={.git,.cache,.xmake,.zig-cache,build,tmp,node_modules,elpa} --type f -H'
# ==============================================================================
# PATH CONFIGURATION
# ==============================================================================
# bash has no fish_add_path (which dedupes + checks existence), so roll a
# small helper that does the same thing.
add_to_path() {
if [ -d "$1" ] && [[ ":$PATH:" != *":$1:"* ]]; then
PATH="$1:$PATH"
fi
}
add_to_path /var/lib/flatpak/exports/bin
add_to_path /usr/local/bin
add_to_path /usr/local/go/bin
add_to_path "$GOPATH/bin"
add_to_path "$HOME/bin"
add_to_path "$HOME/.local/bin"
add_to_path "$HOME/.local/share/flatpak/exports/bin"
add_to_path "$HOME/.npm-global/bin"
add_to_path "$HOME/.odin/"
export PATH
# ==============================================================================
# AUTO COMPLETE
# ==============================================================================
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
fi
# ==============================================================================
# ALIASES
# ==============================================================================
# Void linux helpers
# System update (sync + update all packages)
alias void-update='sudo xbps-install -Su'
# Remove orphaned dependencies + clean cache
alias void-clean='sudo xbps-remove -Oo'
# List explicitly installed (manual) packages
alias void-installed='xbps-query -m'
# List all installed packages
alias void-installedall='xbps-query -l'
# Show which package owns a file
alias void-owns='xbps-query -o'
# Remove a package and its unused deps in one go (usage: purge <pkgname>)
alias void-purge='sudo xbps-remove -R'
# Install a package (usage: install <pkgname>)
alias void-install='sudo xbps-install'
# Remove a package (usage: remove <pkgname>)
alias void-remove='sudo xbps-remove'
# Search for a package
alias void-search='xbps-query -Rs'
# Show info about a package
alias void-query='xbps-query -R'
# List commands
alias ls='ls -lh --color=auto --group-directories-first'
alias ll='ls -lAh --color=auto --group-directories-first'
alias la='ls -la --color=auto --group-directories-first'
alias l='ls -CF --color=auto'
alias tree='tree --dirsfirst -C'
# Safety aliases
alias rm='rm -I --preserve-root'
alias mv='mv -i'
alias cp='cp -i'
alias ln='ln -i'
# System information
alias df='df -h'
alias du='du -h'
alias free='free -h'
alias bat='bat --theme="ansi" --paging=never'
# Application shortcuts
alias :q='exit'
alias files='thunar .'
alias fetch='pfetch'
# Custom shortcuts
alias v='evi'
alias vi='evi'
alias reload='source ~/.bashrc'
alias dots='cd ~/.dotfiles && evi'
alias doti='bash ~/.dotfiles/install.sh -i'
alias dotl='bash ~/.dotfiles/install.sh -l'
alias myip='curl ipinfo.io/ip; echo ""'
alias query='xbps-query -Rs'
alias commits='git log origin/main..HEAD --oneline'
## Basic project picker using fzf
pp() {
local project
project=$(
find ~/Projects -mindepth 1 -maxdepth 1 -type d |
awk -F/ '{print $NF "\t" $0}' |
fzf --with-nth=1
)
[ -z "$project" ] && return
project=$(echo "$project" | cut -f2)
cd "$project" && clear
}
# ==============================================================================
# PROMPT
# ==============================================================================
# bash has no built-in __fish_git_prompt_* equivalent, so we write a small
# git-branch function and build PS1 by hand.
parse_git_branch() {
git branch 2>/dev/null | sed -n '/\* /s///p'
}
git_prompt_info() {
local branch
branch=$(parse_git_branch)
[ -z "$branch" ] && return
local esc=$'\033'
local status marker
status=$(git status --porcelain 2>/dev/null)
if [ -n "$status" ]; then
if echo "$status" | grep -q '^[MADRC]'; then
marker=" ${esc}[33m●${esc}[0m " # staged - yellow ●
elif echo "$status" | grep -q '^??'; then
marker="" # untracked - no char
else
marker=" ${esc}[31m+${esc}[0m " # dirty - red +
fi
else
marker=" ${esc}[1;32m${esc}[0m " # clean - green
fi
echo " ${esc}[1;35m(${branch})${esc}[0m${marker}"
}
PS1='\[\033[32m\]\u\[\033[0m\]@\[\033[34m\]\h\[\033[0m\]:\[\033[36m\]\w\[\033[0m\]$(git_prompt_info)\$ '
+36
View File
@@ -0,0 +1,36 @@
;;; early-init.el --- Pre-init: GC ceiling and frame chrome -*- lexical-binding: t; -*-
;;; Commentary:
;; Runs before package.el initialises and first frame is drawn, the only place these take effect:
;; 1. Raising the GC ceiling, so the whole startup (package load + init.el)
;; runs without garbage-collection pauses.
;; 2. Removing the menu/tool/scroll bars via `default-frame-alist', so they
;; are never drawn — toggling the minor modes in init.el instead draws
;; them and then removes them, a visible flicker on launch.
;;
;; Nothing here may depend on a package: none are loaded yet.
;;; Code:
(startup-redirect-eln-cache (expand-file-name "var/eln-cache/" user-emacs-directory))
(setq package-user-dir (expand-file-name "var/elpa/" user-emacs-directory))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Garbage Collection
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Hold GC off for the whole startup; init.el lowers it back on
;; `emacs-startup-hook' (see the Commentary above).
(setq gc-cons-threshold most-positive-fixnum)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Frame Chrome (no flicker)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Disable the bars before the first frame exists.
(push '(menu-bar-lines . 0) default-frame-alist)
(push '(tool-bar-lines . 0) default-frame-alist)
(push '(vertical-scroll-bars) default-frame-alist)
;; Don't resize the frame when the UI/fonts change during startup.
(setq frame-inhibit-implied-resize t)
;;; early-init.el ends here
+235
View File
@@ -0,0 +1,235 @@
;;; init.el --- Minimal Emacs: built-ins + evil + consult -*- lexical-binding: t; -*-
;; Learning: F1 k KEY, F1 f FUNCTION, F1 v VARIABLE, F1 m (modes), F1 b (bindings).
;; C-h works too, except in normal/motion state where it moves to the window on the left.
;;; Code:
;;;; 1. Emac setup, gc, files, packages
(add-hook 'emacs-startup-hook
(lambda () (setq gc-cons-threshold (* 16 1024 1024))))
(dolist (bin (list (expand-file-name "~/.local/bin")
(expand-file-name "~/.go/bin")))
(add-to-list 'exec-path bin)
(setenv "PATH" (concat bin path-separator (getenv "PATH"))))
;; Add the themes directory to the load path
(add-to-list 'custom-theme-load-path (expand-file-name "themes" user-emacs-directory))
;; all the emacs runtime files live in var/.
;; early-init.el redirects eln-cache and elpa.
(defvar my/var (locate-user-emacs-file "var/"))
(make-directory (concat my/var "transient/") t)
(setq savehist-file (concat my/var "history")
save-place-file (concat my/var "places.eld")
recentf-save-file (concat my/var "recentf.eld")
project-list-file (concat my/var "projects.eld")
transient-history-file (concat my/var "transient/history.el")
transient-levels-file (concat my/var "transient/levels.el")
transient-values-file (concat my/var "transient/values.el"))
;; Custom output goes to its own file, not here.
(setq custom-file (expand-file-name "var/custom.el" user-emacs-directory))
(load custom-file 'noerror 'nomessage)
;; No session manager save: stops the empty session.* files.
(add-hook 'emacs-save-session-functions #'always)
;; Package GNU, NonGNU are built in melpa additional lowest priority.
(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(setq package-archive-priorities '(("gnu" . 3) ("nongnu" . 2) ("melpa" . 1)))
(package-initialize)
(require 'use-package)
(setq use-package-always-ensure t)
;;;; 2. Ui settings, theme setup and fonts
(add-to-list 'default-frame-alist '(fullscreen . maximized))
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(blink-cursor-mode -1)
(setq inhibit-startup-screen t
ring-bell-function #'ignore
use-short-answers t
scroll-conservatively 101
scroll-margin 20)
(setq-default indent-tabs-mode nil tab-width 4)
(global-hl-line-mode 1)
(global-display-line-numbers-mode 1)
(pixel-scroll-precision-mode 1)
(column-number-mode 1)
(electric-pair-mode 1)
(which-key-mode 1)
;; Load the compline theme
(load-theme 'minimal t)
;; set mode line at the top of each window
(setq-default header-line-format mode-line-format mode-line-format nil)
(set-face-attribute 'default nil :family "JetBrainsMono Nerd Font" :height 120)
(setq-default line-spacing '(4 . 4))
;; Command launcher.
(keymap-global-set "C-S-p" #'execute-extended-command)
;; Escape behaves like C-g
(keymap-global-set "<escape>" #'keyboard-quit)
(keymap-set minibuffer-local-map "<escape>" #'abort-minibuffers)
;;;; 3. Files
(setq make-backup-files nil
auto-save-default nil
auto-save-list-file-prefix nil
create-lockfiles nil
confirm-kill-processes nil
vc-follow-symlinks t)
(save-place-mode 1)
(savehist-mode 1)
(recentf-mode 1)
(global-auto-revert-mode 1)
;;;; 4. Completion
;; C-n/C-p navigates up and down, section 5 stops evil from overrriding
(use-package vertico
:init
(vertico-mode 1)
:custom
(vertico-count 15))
(setq completion-styles '(basic partial-completion flex)
completion-ignore-case t
read-buffer-completion-ignore-case t
read-file-name-completion-ignore-case t
completions-format 'one-column
isearch-lazy-count t
xref-search-program 'ripgrep)
(use-package vertico-posframe
:after vertico
:custom
(vertico-posframe-poshandler #'posframe-poshandler-frame-center)
:config
(vertico-posframe-mode 1))
;;;; 5. Evil
(defvar evil-mode-buffers nil)
(defun my/insert-tab ()
"Insert a literal tab character."
(interactive)
(insert "\t"))
(use-package evil
:init
(setq evil-want-C-u-scroll t
evil-undo-system 'undo-redo
evil-want-keybinding nil)
:config
(evil-mode 1)
(evil-define-key 'insert 'global
(kbd "TAB") #'my/insert-tab
(kbd "C-SPC") #'completion-at-point)
;; C-p and C-f are assigned to Consult below, C-m to ibuffer.
(evil-define-key '(normal motion) 'global
(kbd "C-e") #'dired-jump))
(use-package evil-collection
:after evil
:custom
;; Don't add its global [b ]b [e ]e ... bindings.
(evil-collection-want-unimpaired-p nil)
:config
(evil-collection-init '(info ibuffer)))
;; Minibuffer. Vertico
(with-eval-after-load 'vertico
(evil-define-key '(insert normal) vertico-map
(kbd "C-n") #'vertico-next
(kbd "C-p") #'vertico-previous
(kbd "TAB") #'vertico-insert
(kbd "<tab>") #'vertico-insert))
(evil-define-key '(insert normal) minibuffer-local-map
(kbd "<escape>") #'abort-minibuffers)
;; Result buffers: hjkl motions and RET to jump to a result.
(dolist (m '(occur-mode grep-mode xref--xref-buffer-mode))
(evil-set-initial-state m 'motion))
(with-eval-after-load 'compile
(evil-define-key 'motion compilation-mode-map
(kbd "RET") #'compile-goto-error))
(with-eval-after-load 'grep
(evil-define-key 'motion grep-mode-map
(kbd "RET") #'compile-goto-error))
(with-eval-after-load 'replace
(evil-define-key 'motion occur-mode-map
(kbd "RET") #'occur-mode-goto-occurrence))
(with-eval-after-load 'xref
(evil-define-key 'motion xref--xref-buffer-mode-map
(kbd "RET") #'xref-goto-xref))
;;;; 6. Consult
;; Requires the external `fd` and `rg` executables. Both honour .ignore files,
;; so keep excludes (node_modules, elpa, ...) in ~/.ignore or per-project .ignore.
;; Searches start at the project root when there is one, else the current directory.
(use-package consult
:config
;; Don't re-run the preview on every keystroke while typing a search.
(consult-customize consult-ripgrep
:preview-key '(:debounce 0.4 any)))
;; Bind immediately, without waiting for consult to load.
;; C-m opens the full ibuffer list (evil-collection provides its navigation).
(evil-define-key '(normal motion) 'global
(kbd "C-p") #'consult-fd
(kbd "C-f") #'consult-ripgrep
(kbd "C-m") #'ibuffer)
;;;; 7. Dired
(setq dired-dwim-target t
dired-kill-when-opening-new-dired-buffer t
dired-listing-switches "-agho --group-directories-first"
dired-recursive-copies 'always
delete-by-moving-to-trash t)
(with-eval-after-load 'dired
(require 'dired-x)
(setq dired-omit-files "\\`\\.")
(add-hook 'dired-mode-hook #'dired-omit-mode)
(evil-set-initial-state 'dired-mode 'motion)
(evil-define-key 'motion dired-mode-map
"h" #'dired-up-directory
"l" #'dired-find-file
"." #'dired-omit-mode
(kbd "RET") #'dired-find-file))
;;;; Core config ends here.
;;;; -----------------------------------------------------------------
;;;; 8. Modules - additional functionality outside of the core init.el
;; Setup for orgmode
(load (locate-user-emacs-file "modules/org.el") nil 'nomessage)
;; Magit and the :git command live in modules/git.el.
(load (locate-user-emacs-file "modules/git.el") nil 'nomessage)
;; Setup for personal build commands and system.
(load (locate-user-emacs-file "modules/build.el") nil 'nomessage)
;; Setup for dev languages, modes, lsp and lsp keybinds.
(load (locate-user-emacs-file "modules/dev.el") nil 'nomessage)
;;; init.el ends here
+47
View File
@@ -0,0 +1,47 @@
;;; build.el --- Project build, set up for Evil -*- lexical-binding: t; -*-
;;; Commentary:
;; Loaded from init.el after Evil.
;;
;; :build Run ./build.sh from the nearest ancestor dir containing it.
;; :build ARGS Run ./build.sh ARGS, e.g. :build release -v
;;
;; If no build.sh is found (or it isn't executable), report it and do nothing.
;;
;; The compilation buffer opens at the bottom (45% height, full width) and
;; takes focus when the build starts. ANSI colours are rendered.
;; Kill a running build with M-x kill-compilation.
;;; Code:
(setq compilation-read-command nil ; run without prompting
compilation-ask-about-save nil
compilation-scroll-output t)
(add-hook 'compilation-filter-hook #'ansi-color-compilation-filter)
;; Compilation buffer at the bottom, full frame width.
(add-to-list 'display-buffer-alist
'((derived-mode . compilation-mode)
(display-buffer-reuse-window display-buffer-at-bottom)
(window-height . 0.45)))
;; Focus the compilation window when a build starts.
(add-hook 'compilation-start-hook
(lambda (proc)
(when-let* ((win (get-buffer-window (process-buffer proc))))
(select-window win))))
;; :build runs ./build.sh; :build ARGS appends ARGS.
(evil-define-command my/ex-build (args)
"Run `./build.sh ARGS' from the nearest directory containing build.sh."
(interactive "<a>")
(let ((root (locate-dominating-file default-directory "build.sh")))
(unless root
(user-error "No build.sh found"))
(let ((default-directory root))
(unless (file-executable-p "build.sh")
(user-error "build.sh is not executable"))
(compile (string-trim (concat "./build.sh " args)))))) ; nil args -> ""
(evil-ex-define-cmd "build" #'my/ex-build)
;;; build.el ends here
+99
View File
@@ -0,0 +1,99 @@
;;; development.el --- Languages, Eglot and code navigation -*- lexical-binding: t; -*-
;;; Commentary:
;; Loaded from init.el. Requires Evil.
;;
;; Languages:
;; Markdown markdown-mode.
;; PHP php-mode, PSR-2 style, 4 spaces.
;; Odin odin-mode from git (needs Emacs 30+ for :vc), Eglot + OLS.
;; Go go-mode, Eglot + gopls; organize imports and format on save.
;;
;; Normal/motion state:
;; gd definitions gD references K eldoc
;; C-t jump back ESC closes any open eldoc window.
;;; Code:
;;;; Markdown
(use-package markdown-mode)
;;;; PHP
(use-package php-mode
:mode "\\.php\\'"
:hook
(php-mode . (lambda ()
(setq-local indent-tabs-mode nil)
(setq-local tab-width 4)
(setq-local c-basic-offset 4)))
:custom
(php-mode-coding-style 'psr2))
;;;; Odin
(use-package odin-mode
:vc (:url "https://github.com/mattt-b/odin-mode"
:rev :newest)
:mode "\\.odin\\'"
:hook (odin-mode . eglot-ensure))
;;;; Go
;; Emacs started from the desktop doesn't inherit fish env.
(dolist (d '("/usr/local/go/bin" "/home/jason/.go/bin"))
(add-to-list 'exec-path d)
(setenv "PATH" (concat d ":" (getenv "PATH"))))
(setenv "GOPATH" "/home/jason/.go")
(setenv "GOCACHE" "/home/jason/.go/cache")
(defun my/go-before-save ()
"Organize imports and format the buffer through Eglot."
(when (eglot-managed-p)
(eglot-code-actions nil nil "source.organizeImports" t)
(eglot-format-buffer)))
(use-package go-mode
:mode "\\.go\\'"
:hook ((go-mode . eglot-ensure)
(go-mode . (lambda ()
(setq-local tab-width 4)
(add-hook 'before-save-hook #'my/go-before-save nil t)))))
;;;; Eglot
(use-package eglot
:ensure nil
:config
(setq eglot-autoshutdown t)
(add-to-list 'eglot-ignored-server-capabilities :signatureHelpProvider)
;; Explicit OLS configuration.
(add-to-list
'eglot-server-programs
'(odin-mode
. ("/home/jason/.local/bin/ols"
:initializationOptions
(:odin_command "/home/jason/.odin/odin"
:enable_document_symbols t
:enable_format t
:collections
[(:name "core"
:path "/home/jason/.odin/core")
(:name "vendor"
:path "/home/jason/.odin/vendor")])))))
;; OLS built-in definitions.
(setenv "OLS_BUILTIN_FOLDER" "/home/jason/ThirdParty/ols/builtin")
;;;; Code navigation
;; Vim-style code navigation.
(evil-define-key '(normal motion) 'global
"gd" #'xref-find-definitions
"gD" #'xref-find-references
"K" #'eldoc
(kbd "C-t") #'xref-go-back)
;; ESC closes any open eldoc window.
(defun my/eldoc-close (&rest _)
"Quit every window showing an *eldoc* buffer."
(dolist (w (window-list))
(when (string-prefix-p "*eldoc" (buffer-name (window-buffer w)))
(quit-window nil w))))
(advice-add 'evil-force-normal-state :after #'my/eldoc-close)
;;; development.el ends here
+58
View File
@@ -0,0 +1,58 @@
;;; git.el --- Magit, set up for Evil -*- lexical-binding: t; -*-
;;; Commentary:
;; Loaded from init.el, which must set `evil-want-keybinding' to nil before
;; Evil loads (Evil Collection needs it).
;;
;; :git Magit status for the current repo, full frame.
;; q puts your previous window layout back.
;; :git ARGS Run `git ARGS' from the repo root, e.g. :git log --oneline
;;
;; In Magit (Evil Collection layout):
;; j/k move, TAB folds, s stage, u unstage, x discard, c c commit,
;; p push, F pull, l log, d diff, b branch, z stash, gr refresh, q quit,
;; ? lists every command.
;; Commit message: opens in insert state; ZZ or C-c C-c commits,
;; ZQ or C-c C-k cancels.
;; Ctrl+hjkl, C-f and C-b keep their global meaning in Magit buffers.
;;; Code:
(use-package magit
:defer t
:custom
;; Status takes the whole frame; q restores the previous window layout.
(magit-display-buffer-function #'magit-display-buffer-fullframe-status-v1)
(magit-bury-buffer-function #'magit-restore-window-configuration))
;; Vim-style keys for Magit, its section folding, and the commit message buffer.
;; (magit magit-submodule) is the form Evil Collection's own default list uses.
(with-eval-after-load 'evil-collection
;; Evil Collection puts section jumps on C-j/C-k and page scrolling on C-f/C-b.
;; Unbind them so your window and Consult keys show through. Sibling sections
;; are still on ] and [, and scrolling on C-d/C-u.
(add-hook 'evil-collection-setup-hook
(lambda (mode &rest _)
(when (eq mode 'magit)
(evil-define-key 'normal magit-mode-map
(kbd "C-j") nil
(kbd "C-k") nil
(kbd "C-f") nil
(kbd "C-b") nil))))
(evil-collection-init '((magit magit-submodule) magit-section with-editor)))
;; Commit messages start in insert state. Added after git-commit loads so its
;; default hook functions are kept.
(with-eval-after-load 'git-commit
(add-hook 'git-commit-setup-hook #'evil-insert-state))
;; :git opens Magit; :git ARGS runs a git command.
(evil-define-command my/git (args)
"Open Magit status, or run `git ARGS' from the repository root."
(interactive "<a>")
(if (and args (string-match-p "[^[:space:]]" args))
(magit-git-command-topdir (concat "git " args))
(magit-status)))
(evil-ex-define-cmd "git" #'my/git)
;;; git.el ends here
+58
View File
@@ -0,0 +1,58 @@
;;; org.el --- Org appearance -*- lexical-binding: t; -*-
;;; Code:
;; Styled stars, bullets, tags, tables and blocks.
(use-package org-modern
:hook (org-mode . org-modern-mode))
(setq org-directory "~/Projects/notebook")
(setq org-startup-indented t ; visual indent per level, no real spaces
org-hide-emphasis-markers t ; *bold* shows bold, markers hidden
org-pretty-entities t ; \rarr, \alpha etc. as symbols
org-ellipsis " ▾" ; folded-heading marker
org-startup-folded 'show2levels ; open with headings only
org-fontify-whole-heading-line t
org-fontify-done-headline t
org-fontify-quote-and-verse-blocks t
org-src-fontify-natively t ; highlight src blocks with their own mode
org-src-tab-acts-natively t
org-edit-src-content-indentation 0
org-return-follows-link t)
;; org-modern's recommended settings.
(setq org-auto-align-tags nil
org-tags-column 0
org-catch-invisible-edits 'show-and-error
org-special-ctrl-a/e t
org-insert-heading-respect-content t)
(add-hook 'org-mode-hook #'visual-line-mode) ; wrap at window edge
(add-hook 'org-mode-hook (lambda () (display-line-numbers-mode -1))) ; prose reads better without
;; doom-themes' own Org fontification fixes (blocks, headings).
(doom-themes-org-config)
;; Heading sizes; 'user survives theme reloads, same as in init.el.
(doom-themes-set-faces 'user
'(org-document-title :height 1.3 :weight 'bold)
'(org-level-1 :height 1.2 :weight 'bold)
'(org-level-2 :height 1.15 :weight 'bold)
'(org-level-3 :height 1.1 :weight 'bold)
'(org-level-4 :height 1.0 :weight 'bold))
(defun my/notes-index ()
"Open the notes index."
(interactive)
(find-file (expand-file-name "index.org" org-directory)))
(keymap-global-set "C-c n" #'my/notes-index)
;; Evil's TAB (= C-i, jump-forward) shadows Org's. Rebind for Org buffers only.
(with-eval-after-load 'org
(evil-define-key 'normal org-mode-map
(kbd "TAB") #'org-cycle ; fold/unfold the heading at point
(kbd "<tab>") #'org-cycle ; GUI emits <tab>, so bind both
(kbd "RET") #'org-open-at-point
(kbd "<backtab>") #'org-shifttab)) ; S-TAB: cycle all headings
;;; org.el ends here
+360
View File
@@ -0,0 +1,360 @@
;;; minimal-theme.el --- Minimal high-functionality Ujelly port -*- lexical-binding: t; -*-
;;
;; Built on the compline-theme face structure, updated with the color palette
;; from Ujelly (color-theme-ujelly by marktran).
;;
;;; Code:
(deftheme minimal
"Created 2026-10-26.")
(custom-theme-set-faces
'minimal
;;;; Core
'(default ((t (:inherit nil :extend nil :stipple nil :background "#151515" :foreground "#e8e8d3" :inverse-video nil :box nil :strike-through nil :overline nil :underline nil :slant normal :weight regular :height 143 :width normal))))
'(cursor ((t (:background "#8fbfdc"))))
'(fixed-pitch ((t (:height 140))))
'(variable-pitch ((t (:height 140))))
'(escape-glyph ((t (:foreground "#8fbfdc"))))
'(homoglyph ((t (:foreground "#8fbfdc"))))
'(minibuffer-prompt ((t (:foreground "#8fbfdc"))))
'(highlight ((t (:foreground "#e8e8d3" :background "#303030" :weight bold))))
'(hl-line ((t (:extend t :background "#1b1b1b"))))
'(region ((t (:extend t :background "#404040"))))
'(shadow ((t (:foreground "#7f7f7f"))))
'(secondary-selection ((t (:extend t :background "#404040"))))
'(trailing-whitespace ((t (:background "#cf6a4c"))))
'(vertical-border ((t (:foreground "#262626"))))
'(error ((t (:foreground "#cf6a4c"))))
'(warning ((t (:foreground "#fad07a"))))
'(success ((t (:foreground "#99ad6a"))))
;;;; Line numbers
'(line-number ((t (:foreground "#404040"))))
'(line-number-current-line ((t (:foreground "#e8e8d3"))))
;;;; Font lock
'(font-lock-bracket-face ((t (:inherit (font-lock-punctuation-face)))))
'(font-lock-builtin-face ((t (:foreground "#8fbfdc"))))
'(font-lock-comment-delimiter-face ((default (:inherit (font-lock-comment-face)))))
'(font-lock-comment-face ((t (:foreground "#767676"))))
'(font-lock-constant-face ((t (:foreground "#c6b5ed"))))
'(font-lock-delimiter-face ((t (:inherit (font-lock-punctuation-face)))))
'(font-lock-doc-face ((t (:foreground "#767676" :inherit (font-lock-comment-face)))))
'(font-lock-doc-markup-face ((t (:inherit (font-lock-constant-face)))))
'(font-lock-escape-face ((t (:inherit (font-lock-regexp-grouping-backslash)))))
'(font-lock-function-call-face ((t (:slant italic :foreground "#8fbfdc" :inherit (font-lock-function-name-face)))))
'(font-lock-function-name-face ((t (:foreground "#8fbfdc"))))
'(font-lock-keyword-face ((t (:foreground "#fad07a"))))
'(font-lock-negation-char-face ((t (:foreground "#cf6a4c" :inherit (bold)))))
'(font-lock-number-face ((t (:foreground "#cf6a4c"))))
'(font-lock-misc-punctuation-face ((t (:inherit (font-lock-punctuation-face)))))
'(font-lock-operator-face ((t (:foreground "#a0a8b0"))))
'(font-lock-preprocessor-face ((t (:foreground "#fad07a" :inherit (bold)))))
'(font-lock-property-name-face ((t (:weight bold :foreground "#8fbfdc"))))
'(font-lock-property-use-face ((t (:weight regular :inherit (font-lock-property-name-face)))))
'(font-lock-punctuation-face ((t (:foreground "#a0a8b0"))))
'(font-lock-regexp-grouping-backslash ((t (:foreground "#fad07a" :inherit (bold)))))
'(font-lock-regexp-grouping-construct ((t (:foreground "#fad07a" :inherit (bold)))))
'(font-lock-string-face ((t (:foreground "#99ad6a"))))
'(font-lock-type-face ((t (:foreground "#ffb17a"))))
'(font-lock-variable-name-face ((t (:foreground "#e8e8d3"))))
'(font-lock-variable-use-face ((t (:foreground "#e8e8d3" :inherit (font-lock-variable-name-face)))))
'(font-lock-warning-face ((t (:inherit (warning)))))
;;;; Links, buttons, tooltips
'(button ((t (:inherit (link)))))
'(link ((t (:weight bold :underline (:color foreground-color :style line :position nil) :foreground "#8fbfdc"))))
'(link-visited ((t (:inherit link :foreground "#c6b5ed"))))
'(fringe ((t (:foreground "#404040" :inherit (default)))))
'(tooltip ((t (:foreground "#e8e8d3" :background "#1b1b1b"))))
;;;; Mode line
'(header-line ((t (:inherit (mode-line)))))
'(mode-line ((t (:background "#1c1c1c" :foreground unspecified))))
'(mode-line-buffer-id ((t (:weight bold))))
'(mode-line-emphasis ((t (:foreground "#fad07a"))))
'(mode-line-highlight ((t (:inherit (highlight)))))
'(mode-line-inactive ((t (:foreground "#767676" :background "#121212"))))
;;;; Tab bar
'(tab-bar ((t (:inherit default :background "#151515" :foreground "#767676"))))
'(tab-bar-tab ((t (:inherit tab-bar :background "#262626" :foreground "#e8e8d3" :weight bold :box nil))))
'(tab-bar-tab-inactive ((t (:inherit tab-bar :background "#151515" :foreground "#999999" :weight normal :box nil))))
;;;; Search & Completions
'(isearch ((t (:weight bold :inherit (lazy-highlight)))))
'(isearch-fail ((t (:weight bold :foreground "#151515" :background "#cf6a4c"))))
'(lazy-highlight ((t (:weight bold :foreground "#e8e8d3" :background "#303030"))))
'(match ((t (:weight bold :foreground "#99ad6a" :background "#151515"))))
'(next-error ((t (:inherit (region)))))
'(query-replace ((t (:inherit (isearch)))))
;;;; VC gutter: added = green, deleted = red, modified = sand/yellow
'(diff-hl-insert ((t (:foreground "#99ad6a" :background "#99ad6a"))))
'(diff-hl-delete ((t (:foreground "#cf6a4c" :background "#cf6a4c"))))
'(diff-hl-change ((t (:foreground "#fad07a" :background "#fad07a"))))
'(git-gutter:added ((t (:foreground "#99ad6a" :background "#99ad6a"))))
'(git-gutter:deleted ((t (:foreground "#cf6a4c" :background "#cf6a4c"))))
'(git-gutter:modified ((t (:foreground "#fad07a" :background "#fad07a"))))
'(git-gutter-fr:added ((t (:foreground "#99ad6a"))))
'(git-gutter-fr:deleted ((t (:foreground "#cf6a4c"))))
'(git-gutter-fr:modified ((t (:foreground "#fad07a"))))
;;;; gnus: group buffer
'(gnus-group-news-1 ((t (:foreground "#e8e8d3" :weight bold))))
'(gnus-group-news-1-empty ((t (:foreground "#e8e8d3" :weight normal))))
'(gnus-group-news-2 ((t (:foreground "#8fbfdc" :weight bold))))
'(gnus-group-news-2-empty ((t (:foreground "#8fbfdc" :weight normal))))
'(gnus-group-news-3 ((t (:foreground "#fad07a" :weight bold))))
'(gnus-group-news-3-empty ((t (:foreground "#fad07a" :weight normal))))
'(gnus-group-news-low ((t (:foreground "#767676" :weight bold))))
'(gnus-group-news-low-empty ((t (:foreground "#404040" :weight normal))))
'(gnus-group-mail-1 ((t (:foreground "#99ad6a" :weight bold))))
'(gnus-group-mail-1-empty ((t (:foreground "#99ad6a" :weight normal))))
'(gnus-group-mail-2 ((t (:foreground "#c6b5ed" :weight bold))))
'(gnus-group-mail-2-empty ((t (:foreground "#c6b5ed" :weight normal))))
'(gnus-group-mail-3 ((t (:foreground "#ffb17a" :weight bold))))
'(gnus-group-mail-3-empty ((t (:foreground "#ffb17a" :weight normal))))
'(gnus-group-mail-low ((t (:foreground "#767676" :weight bold))))
'(gnus-group-mail-low-empty ((t (:foreground "#404040" :weight normal))))
;;;; gnus: summary buffer
'(gnus-summary-normal-unread ((t (:foreground "#e8e8d3" :weight bold))))
'(gnus-summary-normal-read ((t (:foreground "#767676" :weight normal))))
'(gnus-summary-normal-ticked ((t (:foreground "#cf6a4c" :weight bold))))
'(gnus-summary-normal-ancient ((t (:foreground "#404040" :weight normal))))
'(gnus-summary-normal-undownloaded ((t (:foreground "#8fbfdc" :slant italic))))
'(gnus-summary-high-unread ((t (:foreground "#fad07a" :weight bold))))
'(gnus-summary-high-read ((t (:foreground "#99ad6a" :weight normal))))
'(gnus-summary-high-ticked ((t (:foreground "#cf6a4c" :weight bold))))
'(gnus-summary-high-ancient ((t (:foreground "#767676" :weight normal))))
'(gnus-summary-low-unread ((t (:foreground "#8fbfdc" :slant italic :weight bold))))
'(gnus-summary-low-read ((t (:foreground "#404040" :slant italic :weight normal))))
'(gnus-summary-low-ticked ((t (:foreground "#cf6a4c" :slant italic))))
'(gnus-summary-low-ancient ((t (:foreground "#404040" :slant italic))))
'(gnus-summary-selected ((t (:background "#404040" :foreground "#e8e8d3" :weight bold))))
'(gnus-summary-cancelled ((t (:foreground "#cf6a4c" :strike-through t))))
;;;; gnus: article headers, citations, misc
'(gnus-header-name ((t (:foreground "#8fbfdc" :weight bold))))
'(gnus-header-content ((t (:foreground "#fad07a" :slant italic))))
'(gnus-header-from ((t (:foreground "#e8e8d3" :weight bold))))
'(gnus-header-subject ((t (:foreground "#ffb17a"))))
'(gnus-header-newsgroups ((t (:foreground "#fad07a" :slant italic))))
'(gnus-cite-1 ((t (:foreground "#8fbfdc"))))
'(gnus-cite-2 ((t (:foreground "#99ad6a"))))
'(gnus-cite-3 ((t (:foreground "#fad07a"))))
'(gnus-cite-4 ((t (:foreground "#cf6a4c"))))
'(gnus-cite-5 ((t (:foreground "#c6b5ed"))))
'(gnus-cite-6 ((t (:foreground "#ffb17a"))))
'(gnus-cite-7 ((t (:foreground "#8fbfdc"))))
'(gnus-cite-8 ((t (:foreground "#99ad6a"))))
'(gnus-cite-9 ((t (:foreground "#fad07a"))))
'(gnus-cite-10 ((t (:foreground "#767676"))))
'(gnus-cite-11 ((t (:foreground "#404040"))))
'(gnus-signature ((t (:foreground "#767676" :slant italic))))
'(gnus-button ((t (:inherit link))))
'(gnus-splash ((t (:foreground "#767676"))))
'(gnus-emphasis-bold ((t (:weight bold))))
'(gnus-emphasis-italic ((t (:slant italic))))
'(gnus-emphasis-underline ((t (:underline t))))
'(gnus-emphasis-bold-italic ((t (:weight bold :slant italic))))
'(gnus-server-opened ((t (:foreground "#99ad6a" :weight bold))))
'(gnus-server-closed ((t (:foreground "#767676" :slant italic))))
'(gnus-server-denied ((t (:foreground "#cf6a4c" :weight bold))))
'(gnus-server-offline ((t (:foreground "#fad07a" :weight bold))))
'(gnus-server-agent ((t (:foreground "#8fbfdc" :weight bold))))
;;;; message (gnus composition buffers)
'(message-header-name ((t (:foreground "#8fbfdc" :weight bold))))
'(message-header-to ((t (:foreground "#e8e8d3" :weight bold))))
'(message-header-cc ((t (:foreground "#ffb17a"))))
'(message-header-subject ((t (:foreground "#e8e8d3" :weight bold))))
'(message-header-newsgroups ((t (:foreground "#fad07a" :slant italic))))
'(message-header-other ((t (:foreground "#fad07a"))))
'(message-header-xheader ((t (:foreground "#767676"))))
'(message-separator ((t (:foreground "#404040"))))
'(message-mml ((t (:foreground "#99ad6a"))))
'(message-cited-text-1 ((t (:foreground "#8fbfdc"))))
'(message-cited-text-2 ((t (:foreground "#99ad6a"))))
'(message-cited-text-3 ((t (:foreground "#fad07a"))))
'(message-cited-text-4 ((t (:foreground "#cf6a4c"))))
;;;; magit: sections
'(magit-section-heading ((t (:foreground "#fad07a" :weight bold :extend t))))
'(magit-section-secondary-heading ((t (:foreground "#c6b5ed" :weight bold :extend t))))
'(magit-section-heading-selection ((t (:foreground "#99ad6a" :weight bold :extend t))))
'(magit-section-highlight ((t (:background "#1b1b1b" :extend t))))
'(magit-section-child-count ((t (:foreground "#767676"))))
;;;; magit: refs, hashes, log
'(magit-branch-local ((t (:foreground "#8fbfdc"))))
'(magit-branch-remote ((t (:foreground "#99ad6a"))))
'(magit-branch-current ((t (:foreground "#8fbfdc" :weight bold :box (:line-width -1 :color "#767676")))))
'(magit-branch-remote-head ((t (:foreground "#99ad6a" :weight bold :box (:line-width -1 :color "#767676")))))
'(magit-branch-upstream ((t (:slant italic))))
'(magit-tag ((t (:foreground "#fad07a"))))
'(magit-hash ((t (:foreground "#767676"))))
'(magit-dimmed ((t (:foreground "#404040"))))
'(magit-filename ((t (:foreground "#e8e8d3"))))
'(magit-refname ((t (:foreground "#767676"))))
'(magit-refname-stash ((t (:foreground "#767676"))))
'(magit-refname-wip ((t (:foreground "#767676"))))
'(magit-log-author ((t (:foreground "#fad07a"))))
'(magit-log-date ((t (:foreground "#767676"))))
'(magit-log-graph ((t (:foreground "#404040"))))
'(magit-keyword ((t (:foreground "#fad07a"))))
'(magit-keyword-squash ((t (:foreground "#fad07a"))))
'(magit-cherry-equivalent ((t (:foreground "#e8e8d3"))))
'(magit-cherry-unmatched ((t (:foreground "#8fbfdc"))))
;;;; magit: diffs
'(magit-diff-file-heading ((t (:foreground "#e8e8d3" :weight bold :extend t))))
'(magit-diff-file-heading-highlight ((t (:inherit magit-diff-file-heading :background "#1b1b1b"))))
'(magit-diff-file-heading-selection ((t (:inherit magit-diff-file-heading :foreground "#fad07a" :background "#404040"))))
'(magit-diff-hunk-heading ((t (:foreground "#c6b5ed" :background "#222222" :extend t))))
'(magit-diff-hunk-heading-highlight ((t (:foreground "#e8e8d3" :background "#404040" :extend t))))
'(magit-diff-hunk-heading-selection ((t (:foreground "#fad07a" :background "#404040" :extend t))))
'(magit-diff-lines-heading ((t (:foreground "#151515" :background "#fad07a" :extend t))))
'(magit-diff-context ((t (:foreground "#767676" :extend t))))
'(magit-diff-context-highlight ((t (:foreground "#c6b5ed" :background "#1b1b1b" :extend t))))
'(magit-diff-added ((t (:foreground "#99ad6a" :background "#1a261a" :extend t))))
'(magit-diff-added-highlight ((t (:foreground "#99ad6a" :background "#223322" :extend t))))
'(magit-diff-removed ((t (:foreground "#cf6a4c" :background "#261a1a" :extend t))))
'(magit-diff-removed-highlight ((t (:foreground "#cf6a4c" :background "#332222" :extend t))))
'(magit-diffstat-added ((t (:foreground "#99ad6a"))))
'(magit-diffstat-removed ((t (:foreground "#cf6a4c"))))
'(magit-diff-whitespace-warning ((t (:background "#cf6a4c"))))
;;;; magit: process, signatures, sequences, blame, header line
'(magit-process-ok ((t (:foreground "#99ad6a" :weight bold))))
'(magit-process-ng ((t (:foreground "#cf6a4c" :weight bold))))
'(magit-mode-line-process ((t (:foreground "#fad07a"))))
'(magit-mode-line-process-error ((t (:foreground "#cf6a4c"))))
'(magit-signature-good ((t (:foreground "#99ad6a"))))
'(magit-signature-bad ((t (:foreground "#cf6a4c" :weight bold))))
'(magit-signature-untrusted ((t (:foreground "#8fbfdc"))))
'(magit-signature-expired ((t (:foreground "#fad07a"))))
'(magit-signature-expired-key ((t (:foreground "#fad07a"))))
'(magit-signature-revoked ((t (:foreground "#cf6a4c"))))
'(magit-signature-error ((t (:foreground "#cf6a4c"))))
'(magit-sequence-head ((t (:foreground "#8fbfdc"))))
'(magit-sequence-stop ((t (:foreground "#99ad6a"))))
'(magit-sequence-part ((t (:foreground "#fad07a"))))
'(magit-sequence-done ((t (:foreground "#767676"))))
'(magit-sequence-onto ((t (:foreground "#767676"))))
'(magit-bisect-good ((t (:foreground "#99ad6a"))))
'(magit-bisect-skip ((t (:foreground "#fad07a"))))
'(magit-bisect-bad ((t (:foreground "#cf6a4c"))))
'(magit-blame-heading ((t (:foreground "#c6b5ed" :background "#222222" :extend t))))
'(magit-header-line ((t (:foreground "#fad07a" :weight bold))))
'(magit-header-line-key ((t (:foreground "#fad07a"))))
'(magit-header-line-log-select ((t (:foreground "#e8e8d3" :weight bold))))
;;;; transient (magit popups)
'(transient-heading ((t (:foreground "#fad07a" :weight bold))))
'(transient-key ((t (:foreground "#fad07a" :weight bold))))
'(transient-key-exit ((t (:foreground "#cf6a4c" :weight bold))))
'(transient-key-return ((t (:foreground "#fad07a" :weight bold))))
'(transient-key-stay ((t (:foreground "#99ad6a" :weight bold))))
'(transient-argument ((t (:foreground "#99ad6a" :weight bold))))
'(transient-value ((t (:foreground "#99ad6a"))))
'(transient-inactive-argument ((t (:foreground "#767676"))))
'(transient-inactive-value ((t (:foreground "#767676"))))
'(transient-unreachable ((t (:foreground "#404040"))))
'(transient-unreachable-key ((t (:foreground "#404040"))))
'(transient-disabled-suffix ((t (:foreground "#151515" :background "#cf6a4c" :weight bold))))
'(transient-enabled-suffix ((t (:foreground "#151515" :background "#99ad6a" :weight bold))))
'(transient-delimiter ((t (:foreground "#767676"))))
'(transient-separator ((t (:background "#1c1c1c"))))
'(transient-active-infix ((t (:foreground "#e8e8d3" :background "#404040"))))
'(transient-mismatched-key ((t (:underline t))))
'(transient-nonstandard-key ((t (:underline t))))
;;;; git-commit (magit commit message buffer)
'(git-commit-summary ((t (:foreground "#e8e8d3" :weight bold))))
'(git-commit-overlong-summary ((t (:foreground "#cf6a4c" :weight bold))))
'(git-commit-nonempty-second-line ((t (:foreground "#cf6a4c"))))
'(git-commit-keyword ((t (:foreground "#8fbfdc"))))
'(git-commit-comment-heading ((t (:foreground "#fad07a" :weight bold))))
'(git-commit-comment-branch-local ((t (:foreground "#8fbfdc"))))
'(git-commit-comment-branch-remote ((t (:foreground "#99ad6a"))))
'(git-commit-comment-detached ((t (:foreground "#fad07a"))))
'(git-commit-comment-file ((t (:foreground "#fad07a"))))
'(git-commit-comment-action ((t (:foreground "#99ad6a"))))
;;;; erc: buffer text
'(erc-default-face ((t (:foreground "#e8e8d3"))))
'(erc-input-face ((t (:foreground "#99ad6a"))))
'(erc-my-nick-face ((t (:foreground "#99ad6a" :weight bold))))
'(erc-my-nick-prefix-face ((t (:foreground "#99ad6a" :weight bold))))
'(erc-nick-default-face ((t (:foreground "#e8e8d3" :weight bold))))
'(erc-nick-prefix-face ((t (:foreground "#fad07a"))))
'(erc-notice-face ((t (:foreground "#767676" :weight normal))))
'(erc-information ((t (:foreground "#c6b5ed"))))
'(erc-timestamp-face ((t (:foreground "#404040" :weight normal))))
'(erc-action-face ((t (:foreground "#ffb17a" :weight bold))))
'(erc-prompt-face ((t (:foreground "#fad07a" :weight bold))))
'(erc-command-indicator-face ((t (:foreground "#c6b5ed" :weight bold))))
'(erc-error-face ((t (:foreground "#cf6a4c"))))
'(erc-button ((t (:inherit link :foreground "#e8e8d3"))))
'(erc-button-nick-default-face ((t (:foreground "#e8e8d3" :weight bold))))
'(erc-bold-face ((t (:weight bold))))
'(erc-italic-face ((t (:slant italic))))
'(erc-underline-face ((t (:underline t))))
'(erc-inverse-face ((t (:foreground "#151515" :background "#e8e8d3"))))
'(erc-keep-place-indicator-line ((t (:underline (:color "#404040" :style line)))))
'(erc-keep-place-indicator-arrow ((t (:foreground "#cf6a4c"))))
'(erc-header-line ((t (:foreground "#c6b5ed" :background "#1c1c1c"))))
'(erc-header-line-disconnected ((t (:foreground "#cf6a4c" :background "#1c1c1c"))))
;;;; erc: highlighting rules
'(erc-current-nick-face ((t (:foreground "#fad07a" :weight bold))))
'(erc-keyword-face ((t (:foreground "#fad07a" :weight bold))))
'(erc-nick-msg-face ((t (:foreground "#fad07a" :weight bold))))
'(erc-direct-msg-face ((t (:foreground "#cf6a4c"))))
'(erc-pal-face ((t (:foreground "#99ad6a" :weight bold))))
'(erc-fool-face ((t (:foreground "#404040"))))
'(erc-dangerous-host-face ((t (:foreground "#cf6a4c"))))
;;;; css-mode / scss-mode
'(css-proprietary-property ((t (:foreground "#fad07a"))))
'(css-property ((t (:foreground "#e8e8d3"))))
'(css-selector ((t (:foreground "#cf6a4c"))))
;;;; markdown-mode
'(markdown-markup-face ((t (:foreground "#404040"))))
'(markdown-header-face ((t (:inherit bold :foreground "#cf6a4c"))))
'(markdown-code-face ((t (:background "#1c1c1c"))))
;;;; outline
'(outline-1 ((t (:foreground "#e8e8d3" :weight ultra-bold))))
'(outline-2 ((t (:foreground "#8fbfdc"))))
'(outline-3 ((t (:foreground "#99ad6a"))))
'(outline-4 ((t (:foreground "#c6b5ed"))))
'(outline-5 ((t (:foreground "#ffb17a"))))
'(outline-6 ((t (:foreground "#fad07a"))))
'(outline-7 ((t (:foreground "#cf6a4c"))))
'(outline-8 ((t (:foreground "#e8e8d3"))))
;;;; org
'(org-block ((t (:background "#1b1b1b"))))
'(org-block-begin-line ((t (:foreground "#404040" :slant italic :background "#121212"))))
'(org-ellipsis ((t (:underline nil :background "#151515" :foreground "#cf6a4c"))))
'(org-quote ((t (:background "#1c1c1c"))))
'(org-hide ((t (:foreground "#151515"))))
;;;; solaire-mode
'(solaire-mode-line-face ((t (:inherit mode-line :background "#1c1c1c"))))
'(solaire-mode-line-inactive-face ((t (:inherit mode-line-inactive :background "#1c1c1c")))))
;;;###autoload
(when load-file-name
(add-to-list 'custom-theme-load-path
(file-name-as-directory (file-name-directory load-file-name))))
(provide-theme 'minimal)
;;; minimal-theme.el ends here
-12
View File
@@ -1,12 +0,0 @@
let g:netrw_dirhistmax =10
let g:netrw_dirhistcnt =1
let g:netrw_dirhist_1='/home/jason/Projects/dotfiles'
let g:netrw_dirhist_0='/home/jason/Projects/GraveKeeper/src'
let g:netrw_dirhist_9='/home/jason/Projects/GraveKeeper'
let g:netrw_dirhist_8='/home/jason/.config/kitty/kitty.conf'
let g:netrw_dirhist_7='/home/jason/.evi'
let g:netrw_dirhist_6='/home/jason/Projects/GraveKeeper'
let g:netrw_dirhist_5='/home/jason/.evi'
let g:netrw_dirhist_4='/home/jason/.evi/pack'
let g:netrw_dirhist_3='/home/jason/.evi'
let g:netrw_dirhist_2='/home/jason/.evi/autoload'
-202
View File
@@ -1,202 +0,0 @@
" ============================================================================
" EVi Configuration
" ============================================================================
" General
" ----------------------------------------------------------------------------
set nocompatible
set encoding=utf-8
set hidden
set history=1000
set clipboard=unnamedplus
set splitright
set splitbelow
" ----------------------------------------------------------------------------
" UI
" ----------------------------------------------------------------------------
set number
set relativenumber
set wildmenu
set showcmd
colorscheme jellybeans
" ----------------------------------------------------------------------------
" Transparent UI
" ----------------------------------------------------------------------------
augroup VimTransparent
autocmd!
autocmd ColorScheme * highlight Normal ctermbg=NONE guibg=NONE
\ | highlight NonText ctermbg=NONE guibg=NONE
\ | highlight LineNr ctermbg=NONE guibg=NONE
\ | highlight SignColumn ctermbg=NONE guibg=NONE
\ | highlight EndOfBuffer ctermbg=NONE guibg=NONE
augroup END
" ----------------------------------------------------------------------------
" Status Line
" ----------------------------------------------------------------------------
set laststatus=2
highlight EviStatus cterm=NONE ctermfg=White ctermbg=236
set statusline=%#EviStatus#%f\ %m%r\ %=%{&filetype}\ \ %l:%c\ %p%%
" ----------------------------------------------------------------------------
" Editing
" ----------------------------------------------------------------------------
set tabstop=4
set shiftwidth=4
set expandtab
set smartindent
set nowrap
set incsearch
set hlsearch
set ignorecase
set smartcase
set completeopt=menu,menuone,noselect
" ----------------------------------------------------------------------------
" File Types
" ----------------------------------------------------------------------------
syntax on
filetype plugin indent on
" ----------------------------------------------------------------------------
" fzf
" ----------------------------------------------------------------------------
if executable('rg')
let $FZF_DEFAULT_COMMAND =
\ 'rg --files --hidden --follow --glob "!.git/*"'
endif
nnoremap <C-p> :Files<CR>
nnoremap <C-o> :Buffers<CR>
nnoremap <C-s> :Rg<CR>
nnoremap <C-b> :Build<CR>
" ----------------------------------------------------------------------------
" Search
" ----------------------------------------------------------------------------
nnoremap <Esc><Esc> :nohlsearch<CR>
nnoremap n nzzzv
nnoremap N Nzzzv
" ----------------------------------------------------------------------------
" Window Navigation
" ----------------------------------------------------------------------------
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l
nnoremap <C-x> <C-w>q
" ----------------------------------------------------------------------------
" LSP - OLS
" ----------------------------------------------------------------------------
packadd lsp
call LspOptionsSet(#{
\ autoComplete: v:false,
\ autoHighlight: v:false,
\ autoHighlightDiags: v:true,
\ autoPopulateDiags: v:true,
\ semanticHighlight: v:false,
\ showSignature: v:false,
\ completionInPreview: v:false,
\ condensedCompletionMenu: v:true,
\ })
if executable('ols')
call LspAddServer([#{
\ name: 'ols',
\ filetype: ['odin'],
\ path: 'ols',
\ args: ['--stdio'],
\ features: #{
\ diagnostic: v:false,
\ completion: v:true,
\ hover: v:true,
\ signatureHelp: v:false,
\ documentHighlight: v:true,
\ semanticHighlight: v:true,
\ },
\ }])
endif
command! Action LspCodeAction
command! Rename LspRename
autocmd FileType odin setlocal omnifunc=LspOmniFunc
inoremap <C-@> <C-X><C-O>
nnoremap K :LspHover<CR>
" ----------------------------------------------------------------------------
" Go to Definition
" ----------------------------------------------------------------------------
function! GotoDefinitionSplit() abort
vsplit
LspGotoDefinition
endfunction
nnoremap gd :call GotoDefinitionSplit()<CR>
" ----------------------------------------------------------------------------
" Diagnostics
" ----------------------------------------------------------------------------
function! ToggleDiagnostics() abort
for l:win in getwininfo()
if get(l:win, 'quickfix', 0)
execute l:win.winnr .. 'close'
return
endif
endfor
LspDiag show
endfunction
command! Diagnostics call ToggleDiagnostics()
nnoremap <C-i> :Diagnostics<CR>
" ----------------------------------------------------------------------------
" Netrw / File Tree
" ----------------------------------------------------------------------------
let g:netrw_banner = 0
let g:netrw_liststyle = 3
let g:netrw_browse_split = 0
let g:netrw_altv = 1
let g:netrw_winsize = 33
let g:netrw_keepdir = 0
nnoremap <C-e> :Lexplore<CR>
" ----------------------------------------------------------------------------
" Build System
" ----------------------------------------------------------------------------
function! Build(...) abort
" Already in the build terminal → close it.
if get(b:, 'build_terminal', 0) && &buftype ==# 'terminal'
close
echo ''
return
endif
if !filereadable('build.sh')
echohl WarningMsg
echo 'No build.sh found in current directory.'
echohl None
return
endif
wall
let l:command = './build.sh'
if a:0 > 0
let l:command .= ' ' .. join(a:000, ' ')
endif
botright vsplit
execute 'vertical resize ' .. float2nr(&columns * 0.37)
execute 'terminal ++curwin ' .. l:command
let b:build_terminal = 1
tnoremap <buffer> <CR> <Nop>
endfunction
command! -nargs=* Build call Build(<f-args>)
Submodule config/evi/pack/downloads/opt/lsp deleted from 6ab67121fa
Submodule config/evi/pack/plugins/start/fzf deleted from ca4c1b80e3
Submodule config/evi/pack/plugins/start/fzf.vim deleted from d2a59a992a
Submodule config/evi/pack/plugins/start/jellybeans deleted from ef83bf4dc8
Submodule config/evi/pack/plugins/start/vim-polyglot deleted from f061eddb7c
+139
View File
@@ -0,0 +1,139 @@
# ==============================================================================
# ENVIRONMENT VARIABLES
# ==============================================================================
set -g fish_greeting
set -gx XDG_CONFIG_HOME "$HOME/.config"
set -gx XDG_DATA_HOME "$HOME/.local/share"
set -gx XDG_CACHE_HOME "$HOME/.cache"
set -gx XDG_STATE_HOME "$HOME/.local/state"
set -gx GOOGLE_API_KEY "no"
set -gx GOOGLE_DEFAULT_CLIENT_ID "no"
set -gx GOOGLE_DEFAULT_CLIENT_SECRET "no"
# Core settings
set -gx EDITOR "vi"
set -gx VISUAL "vi"
set -gx MANPAGER "vi +Man!"
set -gx BROWSER "firefox"
set -gx COLORTERM "truecolor"
# Development
set -gx DEBUG 1
set -gx GOPATH "$HOME/.go"
set -gx GOCACHE "$HOME/.go/cache"
set -gx OLS_BUILTIN_FOLDER "/home/jason/ThirdParty/ols/builtin"
# Direnv
direnv hook fish | source
# ==============================================================================
# FZF configuration
# ==============================================================================
set -gx FZF_DEFAULT_OPTS "
--height 40%
--layout=reverse
--border
--ansi
--preview-window=down:30%
--bind 'ctrl-d:preview-page-down,ctrl-u:preview-page-up'
--color=fg:#ffffff,header:#f38ba8,info:#cba6ac,pointer:#f5e0dc
--color=marker:#f5e0dc,fg+:#cdd6f4,prompt:#cba6ac,hl+:#f38ba8"
set -gx FZF_DEFAULT_COMMAND "fd --exclude={.git,.cache,.xmake,.zig-cache,build,tmp,node_modules,elpa} --type f -H"
# ==============================================================================
# PATH CONFIGURATION
# ==============================================================================
# fish_add_path dedupes + checks existence natively, no helper needed
fish_add_path /var/lib/flatpak/exports/bin
fish_add_path /usr/local/bin
fish_add_path /usr/local/go/bin
fish_add_path $GOPATH/bin
fish_add_path $HOME/bin
fish_add_path $HOME/.local/bin
fish_add_path $HOME/.local/share/flatpak/exports/bin
fish_add_path $HOME/.npm-global/bin
fish_add_path $HOME/.odin/
# ==============================================================================
# ALIASES
# ==============================================================================
# List commands
alias ls 'ls -lh --color=auto --group-directories-first'
alias ll 'ls -lAh --color=auto --group-directories-first'
alias la 'ls -la --color=auto --group-directories-first'
alias l 'ls -CF --color=auto'
alias tree 'tree --dirsfirst -C'
# Safety aliases
alias rm 'rm -I --preserve-root'
alias mv 'mv -i'
alias cp 'cp -i'
alias ln 'ln -i'
# System information
alias df 'df -h'
alias du 'du -h'
alias free 'free -h'
alias bat 'bat --theme="ansi" --paging=never'
# Application shortcuts
alias :q 'exit'
alias files 'thunar .'
alias fetch 'pfetch'
# Map 'php' directly to FrankenPHP's bundled PHP CLI runtime
alias php="frankenphp php-cli"
# Optional: A shorthand to spin up your local dev server instantly using your Caddyfile
alias phpserve="frankenphp php-server --config Caddyfile"
# Custom shortcuts
alias reload 'source ~/.config/fish/config.fish'
alias dots 'cd ~/.dotfiles && vi'
alias doti 'bash ~/.dotfiles/install.sh -i'
alias dotl 'bash ~/.dotfiles/install.sh -l'
alias myip 'curl ipinfo.io/ip; echo ""'
alias query 'xbps-query -Rs'
alias commits 'git log origin/main..HEAD --oneline'
## Basic project picker using fzf
function pp
set -l project (find ~/Projects -mindepth 1 -maxdepth 1 -type d | awk -F/ '{print $NF "\t" $0}' | fzf --with-nth=1)
test -z "$project"; and return
set project (echo $project | cut -f2)
cd $project; and clear
end
# ==============================================================================
# GIT PROMPT CONFIG
# (used by fish_git_prompt, called from fish_prompt.fish below)
# ==============================================================================
set -g __fish_git_prompt_show_informative_status
set -g __fish_git_prompt_char_stagedstate '●'
set -g __fish_git_prompt_char_dirtystate '+'
set -g __fish_git_prompt_char_untrackedstate ''
set -g __fish_git_prompt_color_branch magenta
set -g __fish_git_prompt_color_stagedstate yellow
set -g __fish_git_prompt_color_dirtystate red
# ==============================================================================
# PROMPT
# ==============================================================================
function fish_prompt
set_color green
echo -n (whoami)
set_color normal
echo -n '@'
set_color blue
echo -n (prompt_hostname)
set_color normal
echo -n ':'
set_color cyan
echo -n (prompt_pwd)
set_color normal
fish_git_prompt
echo -n '$ '
end
-4
View File
@@ -3,12 +3,8 @@
) )
;; HHKB Professional Classic (Linux) ;; HHKB Professional Classic (Linux)
;;
;; Small key left of Space = Muhenkan ;; Small key left of Space = Muhenkan
;; Large key left of Space = Left Alt ;; Large key left of Space = Left Alt
;;
;; AwesomeWM:
;; modkey = "Mod4"
(defsrc (defsrc
esc 1 2 3 4 5 6 7 8 9 0 - = \ grv esc 1 2 3 4 5 6 7 8 9 0 - = \ grv
-56
View File
@@ -1,56 +0,0 @@
# ============================================================================
# Kitty Configuration
# ============================================================================
enable_audio_bell no
term xterm-256color
# ----------------------------------------------------------------------------
# Font
# ----------------------------------------------------------------------------
font_family JetBrainsMono Nerd Font
font_size 12.0
# ----------------------------------------------------------------------------
# Window
# ----------------------------------------------------------------------------
window_padding_width 10
window_padding_height 10
# ----------------------------------------------------------------------------
# Cursor
# ----------------------------------------------------------------------------
cursor_shape beam
cursor_blink_interval 0.5
# ----------------------------------------------------------------------------
# Layout
# ----------------------------------------------------------------------------
enabled_layouts splits
# ----------------------------------------------------------------------------
# Splits
# ----------------------------------------------------------------------------
# Vertical split
map ctrl+v launch --location=vsplit --cwd=current
# Close current kitty split
map ctrl+q close_window
# ----------------------------------------------------------------------------
# Colors
# ----------------------------------------------------------------------------
foreground #e8e8e8
background #121212
cursor #D4D4D4
cursor_text_color #1F1F1F
color0 #1F1F1F
color1 #F44747
color2 #6A9955
color3 #DCDCAA
color4 #569CD6
color5 #C586C0
color6 #56B6C2
color7 #D4D4D4
color8 #808080
+125 -128
View File
@@ -12,177 +12,174 @@ DO_INSTALL=false
CONFIRM_MODE=true # only true when no args are passed CONFIRM_MODE=true # only true when no args are passed
usage() { usage() {
echo "Usage: $0 [-l] [-i]" echo "Usage: $0 [-l] [-i]"
echo " -l Only create symlinks (no confirmation)" echo " -l Only create symlinks (no confirmation)"
echo " -i Only install system packages (no confirmation)" echo " -i Only install system packages (no confirmation)"
echo " (no args = do both, with confirmation)" echo " (no args = do both, with confirmation)"
exit 1 exit 1
} }
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
DO_LINKS=true DO_LINKS=true
DO_INSTALL=true DO_INSTALL=true
CONFIRM_MODE=true CONFIRM_MODE=true
else else
CONFIRM_MODE=false CONFIRM_MODE=false
while getopts ":lih" opt; do while getopts ":lih" opt; do
case $opt in case $opt in
l) DO_LINKS=true ;; l) DO_LINKS=true ;;
i) DO_INSTALL=true ;; i) DO_INSTALL=true ;;
h) usage ;; h) usage ;;
*) usage ;; *) usage ;;
esac esac
done done
fi fi
# --------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------
## Helper function for linking ## Helper function for linking
# --------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------
link_file() { link_file() {
local src="$1" local src="$1"
local dest="$2" local dest="$2"
if [ -L "$dest" ]; then if [ -L "$dest" ]; then
if [ "$(readlink "$dest")" == "$src" ]; then if [ "$(readlink "$dest")" == "$src" ]; then
echo "✅ Symlink already correct: $dest → $src" echo "✅ Symlink already correct: $dest → $src"
((SKIPPED++)) ((SKIPPED++))
else else
echo "⚠️ $dest is a symlink but points to the wrong target." echo "⚠️ $dest is a symlink but points to the wrong target."
echo " Replacing with correct symlink..." echo " Replacing with correct symlink..."
rm "$dest" rm "$dest"
ln -s "$src" "$dest" ln -s "$src" "$dest"
echo "🔁 Fixed: $dest → $src" echo "🔁 Fixed: $dest → $src"
((CREATED++)) ((CREATED++))
fi fi
elif [ -e "$dest" ]; then elif [ -e "$dest" ]; then
echo "⚠️ $dest exists but is not a symlink. Skipping." echo "⚠️ $dest exists but is not a symlink. Skipping."
((SKIPPED++)) ((SKIPPED++))
else else
mkdir -p "$(dirname "$dest")" mkdir -p "$(dirname "$dest")"
ln -s "$src" "$dest" ln -s "$src" "$dest"
echo "✅ Linked: $dest → $src" echo "✅ Linked: $dest → $src"
((CREATED++)) ((CREATED++))
fi fi
} }
# --------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------
## LINK SYMLINKS ## LINK SYMLINKS
# --------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------
if [ "$DO_LINKS" = true ]; then if [ "$DO_LINKS" = true ]; then
if [ "$CONFIRM_MODE" = true ]; then if [ "$CONFIRM_MODE" = true ]; then
read -p "❓ Do you want to create symlinks for your dotfiles? [y/N] " confirm read -p "❓ Do you want to create symlinks for your dotfiles? [y/N] " confirm
case "$confirm" in case "$confirm" in
[Yy]*) ;; # continue below [Yy]*) ;; # continue below
*) DO_LINKS=false ;; *) DO_LINKS=false ;;
esac esac
fi fi
fi fi
if [ "$DO_LINKS" = true ]; then if [ "$DO_LINKS" = true ]; then
echo "🔗 Checking and creating symlinks..." echo "🔗 Checking and creating symlinks..."
CREATED=0 CREATED=0
SKIPPED=0 SKIPPED=0
link_file "$DOTFILES_DIR/config/bash/bashrc" "$HOME/.bashrc" # Modern shell & editor setup
link_file "$DOTFILES_DIR/config/kanata" "$HOME/.config/kanata" link_file "$DOTFILES_DIR/config/fish/config.fish" "$HOME/.config/fish/config.fish"
link_file "$DOTFILES_DIR/config/alacritty" "$HOME/.config/alacritty" link_file "$DOTFILES_DIR/config/kanata" "$HOME/.config/kanata"
link_file "$DOTFILES_DIR/config/nvim" "$HOME/.config/nvim" link_file "$DOTFILES_DIR/config/emacs" "$HOME/.config/emacs"
link_file "$DOTFILES_DIR/scripts/bin" "$HOME/.local/bin" link_file "$DOTFILES_DIR/scripts/bin" "$HOME/.local/bin"
echo "" echo ""
echo "🧾 Summary: $CREATED symlink(s) created or fixed, $SKIPPED skipped." echo "🧾 Summary: $CREATED symlink(s) created or fixed, $SKIPPED skipped."
echo "" echo ""
echo "✅ Symlink setup complete." echo "✅ Symlink setup complete."
echo "" echo ""
fi fi
# --------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------
## INSTALL SYSTEM PACKAGES ## INSTALL SYSTEM PACKAGES
# --------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------
if [ "$DO_INSTALL" = true ]; then if [ "$DO_INSTALL" = true ]; then
if [ "$CONFIRM_MODE" = true ]; then if [ "$CONFIRM_MODE" = true ]; then
read -p "❓ Do you want to install system packages? [y/N] " confirm read -p "❓ Do you want to install system packages? [y/N] " confirm
case "$confirm" in case "$confirm" in
[Yy]*) ;; # continue below [Yy]*) ;; # continue below
*) DO_INSTALL=false ;; *) DO_INSTALL=false ;;
esac esac
fi fi
fi fi
if [ "$DO_INSTALL" = true ]; then if [ "$DO_INSTALL" = true ]; then
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
## ADD NONFREE REPOS ## ADD NONFREE REPOS
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
echo "📦 Checking nonfree repositories..." echo "📦 Checking nonfree repositories..."
REPO_PACKAGES=(void-repo-nonfree) REPO_PACKAGES=(void-repo-nonfree)
# Only add multilib-nonfree on x86_64 # Only add multilib-nonfree on x86_64
if [ "$(uname -m)" = "x86_64" ]; then if [ "$(uname -m)" = "x86_64" ]; then
REPO_PACKAGES+=(void-repo-multilib-nonfree) REPO_PACKAGES+=(void-repo-multilib-nonfree)
fi fi
MISSING_REPOS=() MISSING_REPOS=()
for repo in "${REPO_PACKAGES[@]}"; do for repo in "${REPO_PACKAGES[@]}"; do
if ! xbps-query -p pkgver "$repo" >/dev/null 2>&1; then if ! xbps-query -p pkgver "$repo" >/dev/null 2>&1; then
MISSING_REPOS+=("$repo") MISSING_REPOS+=("$repo")
fi fi
done done
if [ ${#MISSING_REPOS[@]} -eq 0 ]; then if [ ${#MISSING_REPOS[@]} -eq 0 ]; then
echo "✅ Nonfree repositories already enabled." echo "✅ Nonfree repositories already enabled."
else else
echo "📦 Enabling repositories: ${MISSING_REPOS[*]}" echo "📦 Enabling repositories: ${MISSING_REPOS[*]}"
sudo xbps-install -Sy "${MISSING_REPOS[@]}" sudo xbps-install -Sy "${MISSING_REPOS[@]}"
fi fi
echo "" echo ""
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
## INSTALL REQUIRED PACKAGES ## INSTALL REQUIRED PACKAGES
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
REQUIRED_PACKAGES=( REQUIRED_PACKAGES=(
# system # system & shell
pfetch fuse pfetch fuse3 fish-shell
# network & download # network & download
wget curl ca-certificates gnupg rsync wget curl ca-certificates gnupg rsync
# core utilities # core utilities & CLI tools
git fd jq fzf ripgrep tree direnv make bat git fd jq fzf ripgrep tree direnv make
ark unzip p7zip tar gzip bzip2 xz kanata bat unzip 7zip tar gzip bzip2 xz ark
gitu mpv xfce4-screenshooter xkill xwininfo
# build & dev tools xdotool wmctrl
alacritty base-devel valgrind tree-sitter-cli go nodejs # build & dev tools
# fonts emacs-x11 alacritty base-devel valgrind go
noto-fonts-ttf noto-fonts-emoji )
# kde
xdg-desktop-portal xdg-desktop-portal-kde
)
MISSING_PACKAGES=() MISSING_PACKAGES=()
echo "🔍 Checking for missing packages..." echo "🔍 Checking for missing packages..."
echo "" echo ""
# Check which packages are missing using xbps-query # Check which packages are missing using xbps-query
for pkg in "${REQUIRED_PACKAGES[@]}"; do for pkg in "${REQUIRED_PACKAGES[@]}"; do
if ! xbps-query -p pkgver "$pkg" >/dev/null 2>&1; then if ! xbps-query -p pkgver "$pkg" >/dev/null 2>&1; then
MISSING_PACKAGES+=("$pkg") MISSING_PACKAGES+=("$pkg")
fi fi
done done
if [ ${#MISSING_PACKAGES[@]} -eq 0 ]; then if [ ${#MISSING_PACKAGES[@]} -eq 0 ]; then
echo "✅ All required packages are already installed." echo "✅ All required packages are already installed."
else else
echo "📦 Syncing repository indexes..." echo "📦 Syncing repository indexes..."
sudo xbps-install -S sudo xbps-install -S
echo "📦 Installing missing packages: ${MISSING_PACKAGES[*]}" echo "📦 Installing missing packages: ${MISSING_PACKAGES[*]}"
sudo xbps-install "${MISSING_PACKAGES[@]}" sudo xbps-install "${MISSING_PACKAGES[@]}"
fi fi
echo "" echo ""
echo "✅ Package setup complete." echo "✅ Package setup complete."
echo "" echo ""
fi fi
+281
View File
@@ -0,0 +1,281 @@
#!/usr/bin/env bash
# focus - small window helpers for xfwm4
# focus next|prev move focus right/left through windows (stops at the ends)
# focus up|down focus the nearest window directly above/below, if any
# focus tile master/stack tiling: active window left, the rest stacked right
# (a single window is simply maximized)
# Deps: wmctrl xdotool xprop xwininfo
set -u
# ---- config -----------------------------------------------------------------
MASTER_RATIO=50 # master width as % of the usable width
GAP=0 # px between windows and around the screen edge
USE_WORKAREA=1 # 1 = ask xfwm4 for the usable area (already excludes panels)
PANEL_TOP=0 # extra px to keep free on each side; if USE_WORKAREA=0,
PANEL_BOTTOM=0 # put your panel sizes here instead
PANEL_LEFT=0
PANEL_RIGHT=0
SETTLE=0.05 # seconds to let xfwm4 finish un-maximizing before moving
VERIFY=1 # 1 = measure each window afterwards and fix pixel offsets
VERIFY_TRIES=2 # correction passes per window
# ---- generic helpers --------------------------------------------------------
die() { echo "${0##*/}: $*" >&2; exit 1; }
usage() { echo "usage: ${0##*/} next|prev|up|down|tile" >&2; exit 1; }
# window geometry from wmctrl, keyed by id (filled by collect_windows)
declare -A GX GY GW GH
need() {
local c
for c in "$@"; do command -v "$c" >/dev/null || die "missing dependency: $c"; done
}
# Active window id in wmctrl's 0x%08x format (0x00000000 if none)
active_window() {
local d
d=$(xdotool getactivewindow 2>/dev/null) || d=0
printf '0x%08x' "$d"
}
# index_of ID -> prints index in WINS, or -1
index_of() {
local i
for i in "${!WINS[@]}"; do
[[ ${WINS[i]} == "$1" ]] && { echo "$i"; return; }
done
echo -1
}
# collect_windows focus|tile -> fills WINS, ordered left to right on screen
# (then top to bottom), so "next" moves right and "prev" moves left.
# focus: normal windows + dialogs, minimized included (focusing restores them)
# vert: normal windows + dialogs, minimized skipped (they have no real position)
# tile: normal windows only, minimized skipped
collect_windows() {
local mode=$1 cur id desk x y w h props
local -a found=()
cur=$(xdotool get_desktop) || die "cannot read current desktop"
WINS=()
while read -r id desk x y w h _; do
[[ $desk == "$cur" || $desk == -1 ]] || continue # this desktop or sticky
props=$(xprop -id "$id" _NET_WM_WINDOW_TYPE _NET_WM_STATE 2>/dev/null) || continue
if [[ $props == *"_NET_WM_WINDOW_TYPE(ATOM)"* ]]; then
if [[ $mode == tile ]]; then
[[ $props == *_NET_WM_WINDOW_TYPE_NORMAL* ]] || continue
else
[[ $props == *_NET_WM_WINDOW_TYPE_NORMAL* || $props == *_NET_WM_WINDOW_TYPE_DIALOG* ]] || continue
fi
fi
[[ $props == *_NET_WM_STATE_SKIP_TASKBAR* ]] && continue # panels, desktop, notifyd
[[ $mode != focus && $props == *_NET_WM_STATE_HIDDEN* ]] && continue
GX[$id]=$x GY[$id]=$y GW[$id]=$w GH[$id]=$h
found+=("$x $y $id")
done < <(wmctrl -lG)
(( ${#found[@]} )) || return 0
while read -r _ _ id; do WINS+=("$id"); done < <(printf '%s\n' "${found[@]}" | sort -n -k1,1 -k2,2)
}
# ---- focus ------------------------------------------------------------------
focus_cycle() {
local dir=$1 n idx
collect_windows focus
n=${#WINS[@]}
(( n > 0 )) || return 0
idx=$(index_of "$(active_window)")
if (( idx < 0 )); then
# nothing of ours focused (desktop/panel): enter at the matching end
[[ $dir == next ]] && idx=0 || idx=$(( n - 1 ))
elif [[ $dir == next ]]; then
(( idx < n - 1 )) || return 0 # already rightmost: stop, no wrap
(( idx += 1 ))
else
(( idx > 0 )) || return 0 # already leftmost: stop, no wrap
(( idx -= 1 ))
fi
wmctrl -ia "${WINS[idx]}"
}
# focus_vertical up|down -- nearest window straight above/below the active one.
# "Straight above/below" = shares some horizontal span with it. No match: do nothing.
focus_vertical() {
local dir=$1 act id ax1 ax2 acy cy dy best="" best_dy=-1
collect_windows vert
act=$(active_window)
[[ -n ${GX[$act]+x} ]] || return 0
ax1=${GX[$act]}; ax2=$(( ax1 + GW[$act] ))
acy=$(( GY[$act] + GH[$act] / 2 ))
for id in "${WINS[@]}"; do
[[ $id == "$act" ]] && continue
(( GX[$id] < ax2 && GX[$id] + GW[$id] > ax1 )) || continue # no horizontal overlap
cy=$(( GY[$id] + GH[$id] / 2 ))
if [[ $dir == up ]]; then dy=$(( acy - cy )); else dy=$(( cy - acy )); fi
(( dy > 0 )) || continue # wrong side
if (( best_dy < 0 || dy < best_dy )); then best=$id best_dy=$dy; fi
done
[[ -n $best ]] && wmctrl -ia "$best"
return 0
}
# ---- geometry helpers -------------------------------------------------------
# workarea -> WA_X WA_Y WA_W WA_H (usable rectangle on this desktop)
workarea() {
local cur raw i
local -a a
cur=$(xdotool get_desktop)
raw=$(xprop -root _NET_WORKAREA 2>/dev/null)
if (( USE_WORKAREA )) && [[ $raw == *=* ]]; then
IFS=', ' read -r -a a <<< "${raw#*= }"
i=$(( cur * 4 ))
(( i + 3 < ${#a[@]} )) || i=0
WA_X=${a[i]} WA_Y=${a[i+1]} WA_W=${a[i+2]} WA_H=${a[i+3]}
else
read -r WA_W WA_H < <(xdotool getdisplaygeometry)
WA_X=0 WA_Y=0
fi
(( WA_X += PANEL_LEFT, WA_Y += PANEL_TOP,
WA_W -= PANEL_LEFT + PANEL_RIGHT, WA_H -= PANEL_TOP + PANEL_BOTTOM ))
}
# frame_extents ID -> FL FR FT FB (decoration size; 0 if not reported)
frame_extents() {
local raw
FL=0 FR=0 FT=0 FB=0
raw=$(xprop -id "$1" _NET_FRAME_EXTENTS 2>/dev/null) || return 0
[[ $raw == *=* ]] && IFS=', ' read -r FL FR FT FB <<< "${raw#*= }"
}
# client_position ID -> CX CY (real on-screen top-left of the client area)
client_position() {
read -r CX CY < <(xwininfo -id "$1" 2>/dev/null | awk '
/Absolute upper-left X/ {x=$NF} /Absolute upper-left Y/ {y=$NF}
END {print x+0, y+0}')
}
# ---- window actions ---------------------------------------------------------
# Drop states that make xfwm4 ignore move/resize (maximized, xfwm4 edge-tiling, fullscreen, shaded)
reset_state() {
wmctrl -ir "$1" -b remove,maximized_vert,maximized_horz
wmctrl -ir "$1" -b remove,fullscreen,shaded
}
# maximize ID -- clear fullscreen/shaded, then set the WM's maximized state
maximize() {
wmctrl -ir "$1" -b remove,fullscreen,shaded
wmctrl -ir "$1" -b add,maximized_vert,maximized_horz
wmctrl -ia "$1"
}
# place ID X Y W H -- X Y W H is the OUTER rectangle including decorations
place() {
local id=$1 x=$2 y=$3 w=$4 h=$5 cw ch
frame_extents "$id"
cw=$(( w - FL - FR )); (( cw < 1 )) && cw=1
ch=$(( h - FT - FB )); (( ch < 1 )) && ch=1
# gravity 1 (NorthWest): x,y = top-left of the frame, w,h = client size
wmctrl -ir "$id" -e "1,$x,$y,$cw,$ch"
}
# verify ID X Y W H -- measure where the window really landed and nudge it if off
verify() {
local id=$1 x=$2 y=$3 w=$4 h=$5 try dx dy
for (( try = 0; try < VERIFY_TRIES; try++ )); do
frame_extents "$id"
client_position "$id"
dx=$(( CX - (x + FL) ))
dy=$(( CY - (y + FT) ))
(( dx == 0 && dy == 0 )) && return 0
place "$id" $(( x - dx )) $(( y - dy )) "$w" "$h"
sleep "$SETTLE"
done
}
# ---- layout -----------------------------------------------------------------
# layout_master_stack N -> fills RECTS with "x y w h" outer rectangles, index 0 = master
# Integer remainders are handed out so the tiles cover the area exactly, no 1px gaps.
layout_master_stack() {
local n=$1 x0 y0 w0 h0 mw sw sx avail base rem i y hh
RECTS=()
x0=$(( WA_X + GAP )); y0=$(( WA_Y + GAP ))
w0=$(( WA_W - 2 * GAP )); h0=$(( WA_H - 2 * GAP ))
if (( n == 1 )); then
RECTS+=("$x0 $y0 $w0 $h0")
return
fi
mw=$(( (w0 - GAP) * MASTER_RATIO / 100 ))
sw=$(( w0 - GAP - mw ))
sx=$(( x0 + mw + GAP ))
RECTS+=("$x0 $y0 $mw $h0")
(( n -= 1 ))
avail=$(( h0 - (n - 1) * GAP ))
base=$(( avail / n )); rem=$(( avail % n ))
y=$y0
for (( i = 0; i < n; i++ )); do
hh=$(( base + (i < rem ? 1 : 0) ))
RECTS+=("$sx $y $sw $hh")
(( y += hh + GAP ))
done
}
# ---- tile -------------------------------------------------------------------
tile() {
local n idx master i
(( VERIFY )) && need xwininfo
collect_windows tile
n=${#WINS[@]}
(( n > 0 )) || return 0
# only one window: let xfwm4 maximize it (real maximized state, not fullscreen)
if (( n == 1 )); then
maximize "${WINS[0]}"
return 0
fi
# active window becomes master, the rest keep their order in the stack
idx=$(index_of "$(active_window)")
if (( idx > 0 )); then
master=${WINS[idx]}
WINS=("$master" "${WINS[@]:0:idx}" "${WINS[@]:idx+1}")
fi
workarea
layout_master_stack "$n"
for i in "${!WINS[@]}"; do reset_state "${WINS[i]}"; done
sleep "$SETTLE"
for i in "${!WINS[@]}"; do
# shellcheck disable=SC2086
place "${WINS[i]}" ${RECTS[i]}
done
if (( VERIFY )); then
sleep "$SETTLE"
for i in "${!WINS[@]}"; do
# shellcheck disable=SC2086
verify "${WINS[i]}" ${RECTS[i]}
done
fi
wmctrl -ia "${WINS[0]}"
}
# ---- main -------------------------------------------------------------------
need wmctrl xdotool xprop
case ${1:-next} in
next|prev) focus_cycle "${1:-next}" ;;
up|down) focus_vertical "$1" ;;
tile) tile ;;
*) usage ;;
esac
+28 -11
View File
@@ -1,23 +1,40 @@
#!/bin/bash #!/bin/bash
# ---------------------------------------------------------------------------------
# Odin compiler install recipe
# Target: Void Linux
# Builds from source - recommended method on Linux
# ---------------------------------------------------------------------------------
set -e set -e
ODIN_DIR="$HOME/.odin" ODIN_DIR="$HOME/.odin"
echo "Installing Odin build dependencies..." echo "Installing Odin build dependencies..."
sudo xbps-install -Sy llvm18 llvm18-devel clang18 libstdc++-devel git-lfs sudo xbps-install -S
git lfs install sudo xbps-install -y llvm18-devel clang18 git-lfs base-devel
git lfs install --force
echo "Cloning Odin repository..." echo "Cloning Odin repository..."
git clone https://github.com/odin-lang/Odin "$ODIN_DIR" if [ -d "$ODIN_DIR" ]; then
cd "$ODIN_DIR" echo "Directory $ODIN_DIR already exists. Pulling latest..."
cd "$ODIN_DIR" && git pull
else
git clone https://github.com/odin-lang/Odin "$ODIN_DIR"
cd "$ODIN_DIR"
fi
echo "Building Odin compiler..." # Detect available LLVM 18 config tool name on Void
LLVM_CONFIG=$(command -v llvm-config) make release-native LLVM_CFG=""
for cfg in llvm-config-18 llvm-config18 llvm-config; do
if command -v "$cfg" >/dev/null 2>&1; then
LLVM_CFG="$cfg"
break
fi
done
if [ -z "$LLVM_CFG" ]; then
echo "❌ Error: Could not locate a valid llvm-config binary."
exit 1
fi
echo "Building Odin compiler using $LLVM_CFG..."
LLVM_CONFIG="$LLVM_CFG" make release-native
echo "" echo ""
echo "✓ Odin install complete." echo "✓ Odin install complete."
echo " Add to your path if needed: export PATH=\"\$HOME/.odin:\$PATH\""
echo " Then verify with: odin version" echo " Then verify with: odin version"
-16
View File
@@ -1,16 +0,0 @@
#!/bin/bash
# ---------------------------------------------------------------------------------
# PHP install recipe
# Fetches the void php version and composer package
# ---------------------------------------------------------------------------------
set -e
# install the Void linux php version
sudo xbps-install php php-mysql php-sqlite php-ffi php-fpm php-intl php-xsl php-imagick php-gd
# install/download composer
sudo xbps-install composer
echo ""
echo "✅ PHP + Composer setup complete."
+15 -5
View File
@@ -1,14 +1,24 @@
#!/bin/bash #!/bin/bash
# --------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------
# Raylib-go dependency install recipe # Raylib / Raylib-go dependency install recipe
# Target: Void Linux # Target: Void Linux
# Installs system libs needed for raylib to run # Installs system development libraries needed for Raylib / GLFW / OpenGL
# --------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------
set -e set -e
echo "Installing raylib-go system dependencies..." echo "Installing Raylib system dependencies..."
sudo xbps-install make alsa-lib-devel libglvnd-devel libX11-devel libXrandr-devel libXi-devel libXcursor-devel libXinerama-devel mesa MesaLib-devel sudo xbps-install -S
sudo xbps-install -y \
base-devel \
alsa-lib-devel \
MesaLib-devel \
libX11-devel \
libXrandr-devel \
libXi-devel \
libXcursor-devel \
libXinerama-devel \
libXxf86vm-devel
echo "" echo ""
echo "✓ Raylib-go dependencies installed." echo "✓ Raylib dependencies installed."
echo "" echo ""
+64
View File
@@ -0,0 +1,64 @@
#!/bin/bash
# ---------------------------------------------------------------------------------
# Steam install recipe
# Target: Void Linux (x86_64 glibc only)
# Enables nonfree + multilib repos, installs Steam, 32-bit runtime libs, GPU drivers
# Usage: GPU=amd|nvidia|intel ./steam.sh (default: amd)
# ---------------------------------------------------------------------------------
set -e
GPU="${GPU:-amd}"
if [ "$(xbps-uhelper arch)" != "x86_64" ]; then
echo "Steam requires x86_64 glibc. Aborting." >&2
exit 1
fi
echo "Enabling nonfree and multilib repositories..."
sudo xbps-install -Sy void-repo-nonfree void-repo-multilib void-repo-multilib-nonfree
sudo xbps-install -Sy # sync the newly added repos
echo "Installing Steam and 32-bit runtime libraries..."
sudo xbps-install -y \
steam \
steam-udev-rules \
libgcc-32bit \
libstdc++-32bit \
libdrm-32bit \
libglvnd-32bit \
mesa-dri \
mesa-dri-32bit \
vulkan-loader \
vulkan-loader-32bit \
alsa-lib-32bit \
libpulseaudio-32bit
echo "Installing GPU drivers ($GPU)..."
case "$GPU" in
amd)
sudo xbps-install -y \
mesa-vulkan-radeon mesa-vulkan-radeon-32bit \
mesa-vaapi
;;
nvidia)
sudo xbps-install -y nvidia nvidia-libs nvidia-libs-32bit
;;
intel)
sudo xbps-install -y \
mesa-vulkan-intel mesa-vulkan-intel-32bit \
intel-video-accel
;;
*)
echo "Unknown GPU '$GPU' (amd|nvidia|intel)" >&2
exit 1
;;
esac
echo "Reloading udev rules..."
sudo udevadm control --reload
sudo udevadm trigger
echo ""
echo "✓ Steam installed. Log out/in (or reboot) before first launch."
echo ""
-35
View File
@@ -1,35 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
echo "==> Installing dependencies..."
sudo xbps-install -S sassc gtk-engine-murrine gtk+3-devel
WORKDIR="$(mktemp -d)"
cd "$WORKDIR"
echo "==> Cloning Qogir theme..."
git clone --depth=1 https://github.com/vinceliuice/Qogir-theme.git
echo "==> Installing Qogir theme (dark, void icon, default square corners)..."
cd "$WORKDIR/Qogir-theme"
sudo ./install.sh -d /usr/share/themes -c dark -t default -i void
echo "==> Installing libadwaita (GTK4) link..."
sudo ./install.sh -d /usr/share/themes -c dark -t default -i void -l
cd "../"
echo "==> Cloning Qogir Icon theme..."
git clone --depth=1 git@github.com:vinceliuice/Qogir-icon-theme.git
cd "$WORKDIR/Qogir-icon-theme"
echo "==> Installing Qogir icons..."
sudo ./install.sh -d /home/jason/.icons
echo "==> Cleaning up..."
cd "$HOME"
sudo rm -rf "$WORKDIR"
echo ""
echo "Done. Now set in XFCE Settings:"
echo " Appearance -> Style: Qogir-Dark"
echo " Window Manager -> Theme: Qogir-Dark"
+67
View File
@@ -0,0 +1,67 @@
#!/bin/sh
# square-xfwm4-corners.sh (v2)
# Makes ~/.themes/Default-Square: an exact copy of the xfwm4 "Default" theme
# with square top corners, keeping the thin dark outline and highlight.
# Usage: ./square-xfwm4-corners.sh [ACTIVE_TITLE_COLOR]
# e.g. ./square-xfwm4-corners.sh '#ff9900' (or a name like orange)
# no argument = keep the theme's normal title colour
set -eu
ACTIVE_TITLE_COLOR="${1:-}"
case "$ACTIVE_TITLE_COLOR" in
''|\#[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]|\#[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]) ;;
*[!a-zA-Z]*) echo "Colour must be #rgb, #rrggbb or a plain name like orange"; exit 1 ;;
esac
SRC=/usr/share/themes/Default/xfwm4
DST_THEME="$HOME/.themes/Default-Square"
DST="$DST_THEME/xfwm4"
[ -d "$SRC" ] || { echo "Missing $SRC"; exit 1; }
# Warn if the installed theme differs from the version these overlays were made from
want=349096e386ab06feddff55aa404bed0a
have=$(md5sum "$SRC/top-left-active.png" 2>/dev/null | cut -d' ' -f1 || true)
[ "$have" = "$want" ] || echo "Warning: your Default theme differs from the expected version; result may be slightly off."
# Fresh copy (also cleans up the result of the first version of this script)
rm -rf "$DST_THEME"
mkdir -p "$DST_THEME"
cp -r "$SRC" "$DST"
# 1) Base layer (XPM): make the transparent corner pixels use the frame colour
for f in "$DST"/top-left-*.xpm "$DST"/top-right-*.xpm; do
awk '
/"[^"]*"/ && !hdr { hdr = 1; split(substr($0, index($0,"\"")+1), a, /[ \t"]+/); nc = a[3]; cpp = a[4]; print; next }
hdr && seen < nc && /"/ {
seen++; s = substr($0, index($0,"\"")+1); s = substr(s, 1, index(s,"\"")-1)
key[seen] = substr(s, 1, cpp); spec[seen] = substr(s, cpp+1); pre[seen] = substr($0, 1, index($0,"\"")-1)
isnone[seen] = (tolower(spec[seen]) ~ /c[ \t]+none/)
if (!isnone[seen] && fill == "") fill = spec[seen]
if (seen == nc) for (i = 1; i <= nc; i++) print pre[i] "\"" key[i] (isnone[i] ? fill : spec[i]) "\","
next }
{ print }' "$f" > "$f.tmp" && mv "$f.tmp" "$f"
done
# 2) Overlay (PNG): square versions of the outline/highlight images
write_png() { printf '%s' "$2" | base64 -d > "$DST/$1"; }
write_png top-left-active.png 'iVBORw0KGgoAAAANSUhEUgAAAAgAAAAdCAYAAACXFC2jAAAASklEQVR42mNkYGBoYMADWLi5udm+fPnShlPB/////zMwMPzHqQBK41TAxEAAsPz79+8/ZSYQcgMdrBj1JpIbGBkZ/5FtwqgCCAAAJ9onK5/spQ0AAAAASUVORK5CYII='
write_png top-left-inactive.png 'iVBORw0KGgoAAAANSUhEUgAAAAgAAAAdCAYAAACXFC2jAAAASklEQVR42mNkYGBoYMADWLi5udm+fPnShlPB/////zMwMPzHqQBK41TAxEAAsPz79+8/ZSYQcgMdrBj1JpIbGBkZ/5FtwqgCCAAAJ9onK5/spQ0AAAAASUVORK5CYII='
write_png top-right-active.png 'iVBORw0KGgoAAAANSUhEUgAAAAgAAAAdCAYAAACXFC2jAAAAR0lEQVR42u2PMQ7AIAwDz6hjXszEy+MOZSUMlZi41dY5ETAokO1YhRHRH8Crgm2XBYDGhtKQmf5nODRx35wGSVnk+xtu4eMFmCwkTAAQh0MAAAAASUVORK5CYII='
write_png top-right-inactive.png 'iVBORw0KGgoAAAANSUhEUgAAAAgAAAAdCAYAAACXFC2jAAAAR0lEQVR42u2PMQ7AIAwDz6hjXszEy+MOZSUMlZi41dY5ETAokO1YhRHRH8Crgm2XBYDGhtKQmf5nODRx35wGSVnk+xtu4eMFmCwkTAAQh0MAAAAASUVORK5CYII='
# 3) Optional: colour of the focused window's title text
if [ -n "$ACTIVE_TITLE_COLOR" ]; then
rc="$DST/themerc"
if grep -q '^active_text_color=' "$rc"; then
sed -i "s|^active_text_color=.*|active_text_color=$ACTIVE_TITLE_COLOR|" "$rc"
else
echo "active_text_color=$ACTIVE_TITLE_COLOR" >> "$rc"
fi
echo "Active title colour: $ACTIVE_TITLE_COLOR"
fi
echo "Created $DST_THEME"
xfconf-query -c xfwm4 -p /general/theme -s Default 2>/dev/null || true
xfconf-query -c xfwm4 -p /general/theme -s Default-Square 2>/dev/null \
&& echo "Applied theme 'Default-Square'." \
|| echo "Select 'Default-Square' in Settings > Window Manager > Style."