Compare commits

...

54 Commits

Author SHA1 Message Date
jasonhilder 8c06125493 Really never ends. 2026-07-03 10:45:31 +02:00
jasonhilder d7863ed010 Its just dotfiles... 2026-07-03 09:28:42 +02:00
jasonhilder 5bb60e1a35 Getting old now... 2026-07-03 08:13:08 +02:00
jasonhilder 00d3b3c3d9 Testing new remote 2026-07-02 10:17:39 +02:00
jasonhilder 379e008024 Added overlay for rofi menus 2026-07-02 08:21:47 +02:00
jasonhilder e1c3745f3b Awesomewm config into modules. 2026-07-02 07:44:28 +02:00
jasonhilder 1a49af00cc Awesome updates.
Setup naughty for the notification manager.
Stoped default notification service.
Made better rules for window placement.
2026-07-02 07:06:06 +02:00
jasonhilder d3c89f89f6 Rofi scripts for extra menus 2026-07-02 07:04:59 +02:00
jasonhilder ccd02e718b Cleanup/updates for new software.
Dropped xfwm for awesomewm
Themed it accordingly, theme, icons, cursor, rofi
Cleaned up picom for awesome and made better animations
Install script cleanup and removed unneeded tools
2026-07-01 10:31:20 +02:00
jasonhilder 179f2a10fe Cleanup, no longer in use config + scripts. 2026-07-01 10:06:05 +02:00
jasonhilder befd7d745c Update for rofi corner radius. 2026-06-24 10:36:26 +02:00
jasonhilder 59752bb8d4 Updates to lackluster theme, newline/space cleanup 2026-06-24 10:35:48 +02:00
jasonhilder 3b2a183bcb dont store binary files 2026-06-23 21:10:38 +02:00
jasonhilder 663a9cc377 Cleanup formatting layout randoms 2026-06-23 21:10:18 +02:00
jasonhilder 9f2c2cb72d personal daily use scripts 2026-06-23 21:09:41 +02:00
jasonhilder 1fb68b7541 Better theming and cleanup for picom 2026-06-23 21:04:28 +02:00
jasonhilder b745401cc4 Using picom now 2026-06-23 21:03:02 +02:00
jasonhilder 6a1355edc6 removed zed settings, not for me 2026-06-23 21:02:29 +02:00
jasonhilder fddbf187ee scripts are split between local and installs 2026-06-23 21:01:42 +02:00
jasonhilder 25612fc232 Zed editor settings and symlinks. 2026-06-23 08:34:58 +02:00
jasonhilder 0faf3e3eef Small alias change. 2026-06-22 11:00:42 +02:00
jasonhilder a5401e517b Initial commit for zed try out settings. 2026-06-22 11:00:07 +02:00
jasonhilder 0b2309fa0f Added nvim tree over netrw, just feels better 2026-06-19 15:50:26 +02:00
jasonhilder ccf9327a9b Small alias, updated install for delta. 2026-06-19 12:14:41 +02:00
jasonhilder affdb7fb9b Cleanups for void. 2026-06-18 14:31:10 +02:00
jasonhilder d9e59b61cf Removed gitu tui, cleaned install.sh package list. 2026-06-18 14:24:08 +02:00
jasonhilder a91f225f08 Added polybar + rofi configs and symlinks 2026-06-17 08:16:54 +02:00
jasonhilder 6d5236d8dd Cleanup for minimal setup, nearly there! 2026-06-17 08:06:44 +02:00
jasonhilder e314363e8b Update README.md 2026-06-15 11:03:17 +02:00
jasonhilder bb3d06a857 Random changes for void/xfce x11 setup. 2026-06-15 08:02:12 +02:00
jasonhilder 84b4a7d7b8 theme script for xfce4 2026-06-12 09:56:08 +02:00
jasonhilder f22eb5d964 Small updates for void. 2026-06-12 09:39:46 +02:00
jasonhilder b32ab5a8ab Updated/cleaned install scripts for void. 2026-06-12 09:36:35 +02:00
jasonhilder 6b1217f75a Small tweaks for void. 2026-06-12 08:42:24 +02:00
jasonhilder 51fb1aec9d Better binds and terminal support 2026-06-12 08:42:11 +02:00
jasonhilder 69527e3d61 Updates for the void... 2026-06-11 16:32:53 +02:00
jasonhilder 24db65b6ed Who knows... 2026-06-11 09:11:50 +02:00
jasonhilder ae3fe68e2a Cleanup 2026-06-03 07:20:22 +02:00
jasonhilder 7e606e21ad Triming the fat. 2026-06-02 12:24:18 +02:00
jasonhilder 550810939f Alacritty theme for kintsugi 2026-05-31 07:19:48 +02:00
jasonhilder b10e979a0a Removed tmux. 2026-05-31 07:19:42 +02:00
jasonhilder 133f9b1169 Neovim rework.
Consolidated modules into a single file. Added syntax files over using
treesitter.
2026-05-31 07:18:25 +02:00
jasonhilder 1da7b9512e Cleanup shell dropping tmux. 2026-05-27 09:10:47 +02:00
jasonhilder e1a4aae5c1 dropping Tree sitter. 2026-05-27 09:10:38 +02:00
jasonhilder f3497b97a9 Moved php install into dedicated script. 2026-05-27 09:10:20 +02:00
jasonhilder 8e63ee325b fish config cleanup. 2026-05-26 08:07:51 +02:00
jasonhilder 20bcf236ca Nvim cleanup. 2026-05-26 08:07:43 +02:00
jasonhilder 6256b9da66 Added new system dependancies. 2026-05-26 08:07:24 +02:00
jasonhilder 1eed4b819a What am I doing with my life... 2026-05-22 08:02:56 +02:00
jasonhilder 456c2593a4 added php installs. 2026-05-21 11:35:44 +02:00
jasonhilder 17144b3a74 Cleanup. 2026-05-21 11:35:39 +02:00
jasonhilder 7568ee801b Quick theme kintsugi. 2026-05-21 10:04:38 +02:00
jasonhilder 0149b1a64f Small theme changes and updates. 2026-05-20 13:03:53 +02:00
jasonhilder e0fae18689 Major change to use mini suit of plugins. 2026-05-20 13:03:35 +02:00
38 changed files with 1557 additions and 787 deletions
+3 -1
View File
@@ -2,4 +2,6 @@ config/fish/conf.d
config/fish/functions
config/fish/fish_variables
config/nvim/nvim-pack-lock.json
config/alacritty/dank-theme.toml
config/awesome/bling
scripts/bin/Obsidian
scripts/bin/ols
+43 -34
View File
@@ -7,42 +7,44 @@ A deliberately minimal dotfile configuration.
Over the years I have grown tired of tweaking config files for every component of my desktop.
This repository contains only the essentials.
Start with a minimal Debian 13 (Trixie) install — SSH server and system essentials only, no desktop environment.
Start with a minimal **Void Linux** install using the XFCE4 base image.
## What's Inside
```
.
├── config/
│ ├── alacritty/ # Alacritty terminal configuration
│ ├── fish/ # Fish shell configuration
│ ├── gitu/ # Git TUI settings
│ ├── kanata/ # Keyboard remapping
│ ├── lf/ # Terminal file manager
│ ├── nvim/ # Neovim setup
│ └── tmux/ # Tmux configuration
├── scripts/
│ ├── setup_docker # Docker install recipe
│ ├── setup_golang # Golang + go tools install recipe
── setup_kanata # Kanata + systemd service setup
── bootstrap.sh # Fresh system setup (run once, before install.sh)
│ ├── install_odin # Odin compiler install recipe
│ ├── install_php # PHP install recipe
── install_raylib_deps # Raylib dependencies
── install_theme # XFCE4 theme setup
└── install.sh # Dotfile symlinks and package installation
```
## Prerequisites
## Desktop Bootstrap
Before running `install.sh`, take care of the following manually:
The bootstrap script to set up DMS essentiallys, networking, audio, Helium, and GTK theming:
./bootstrap.sh
Once complete, restore personal files from backup drive (SSH keys, documents, projects, fonts, wallpapers), then continue with the steps below.
- `sudo xbps-install -Su` — sync and update
- Set up SSH keys
- Clone this repo
- Install a Nerd Font
## Software Installation
This will install, setup config files for my personal choices of software to use on top of the desktop
Installs packages and creates config symlinks on top of the XFCE4 base image.
### Install Options
# Interactive mode (with confirmations)
```sh
# Interactive mode (prompts for confirmation at each step)
./install.sh
# Only create symlinks
@@ -50,39 +52,46 @@ This will install, setup config files for my personal choices of software to use
# Only install packages
./install.sh -i
```
## What Gets Installed
The script installs essential development tools via `apt`:
The script enables `void-repo-nonfree` (and `void-repo-multilib-nonfree` on x86_64), then installs
packages via `xbps-install`:
- **CLI Tools**: `wget`, `curl`, `fzf`, `fd-find`, `ripgrep`, `tree`, `btop`, `direnv`, `bat`, `jq`, `lf`, `unzip`
- **Development**: `build-essential`, `make`, `bear`, `valgrind`
- **Shell**: `fish`
- **CLI Tools**: `wget`, `curl`, `git`, `unzip`, `fzf`, `fd`, `ripgrep`, `bat`, `direnv`, `tree`, `jq`, `lf`, `rsync`, `pfetch`
- **Development**: `base-devel`, `make`, `valgrind`, `tree-sitter-cli`, `go`
- **Shell**: `fish-shell`
- **Terminal**: `alacritty`
- **Multiplexer**: `tmux`
- **Other**: `ca-certificates`, `gnupg`, `libfuse2`
- **Keyboard**: `kanata`
- **Desktop**: `polybar`, `rofi`, `xdotool`, `wmctrl`
- **Fonts**: `noto-fonts-ttf`, `noto-fonts-emoji`
- **Other**: `ca-certificates`, `gnupg`, `fuse`
## Symlinks Created
- `~/.tmux.conf``./config/tmux/.tmux.conf`
- `~/.config/alacritty``./config/alacritty`
- `~/.config/fish` `./config/fish`
- `~/.config/kanata` `./config/kanata`
- `~/.config/nvim` `./config/nvim`
- `~/.config/gitu` `./config/gitu`
- `~/.config/lf` `./config/lf`
| Symlink | Target |
|---|---|
| `~/.config/alacritty` | `./config/alacritty` |
| `~/.config/fish` | `./config/fish` |
| `~/.config/kanata` | `./config/kanata` |
| `~/.config/nvim` | `./config/nvim` |
| `~/.config/lf` | `./config/lf` |
## Scripts
Self-contained recipes for tooling that goes beyond the core install. Each script can be run independently as needed:
Self-contained recipes for tooling that goes beyond the core install. Each can be run independently:
./scripts/setup_docker
./scripts/setup_golang
./scripts/setup_kanata
```sh
./scripts/install_odin
./scripts/install_php
./scripts/install_raylib_deps
./scripts/install_theme
```
These are not run automatically by `install.sh` — they are opt-in.
---
This setup prioritizes **stability** and **simplicity** over customization. DankMaterialShell with niri handles the heavy lifting for tiling and aesthetics.
This setup prioritises **stability** and **simplicity** over customisation.
Void Linux + XFCE4 + X11 provides a fast, predictable base with minimal moving parts.
-52
View File
@@ -1,52 +0,0 @@
#!/bin/bash
# ---------------------------------------------------------------------------------
# Bootstrap script for fresh Debian 13 (Trixie) install
# Run this after a minimal install (SSH server + system essentials, no desktop)
# ---------------------------------------------------------------------------------
set -e
echo "🔧 Installing pre-requisites..."
sudo apt install -y curl network-manager nemo pipewire pipewire-pulse wireplumber polkit-kde-agent-1 wl-clipboard
# ---------------------------------------------------------------------------------
# Install DankMaterialShell
# ---------------------------------------------------------------------------------
echo "🎨 Installing DankMaterialShell..."
curl -fsSL https://install.danklinux.com | sh
echo "🔊 Enabling audio and networking services..."
sudo systemctl --user enable --now pipewire pipewire-pulse wireplumber
sudo systemctl enable --now NetworkManager
# ---------------------------------------------------------------------------------
# Fix network interfaces — keep only the loopback interface
# ---------------------------------------------------------------------------------
echo "🌐 Fixing network interfaces..."
echo " Commenting out everything except the lo loopback in /etc/network/interfaces"
sudo sed -i '/^auto\|^iface\|^allow-hotplug/{/lo/!s/^/#/}' /etc/network/interfaces
sudo systemctl restart networking
sudo systemctl restart NetworkManager
sudo systemctl restart dms
# ---------------------------------------------------------------------------------
# Install Helium Browser
# ---------------------------------------------------------------------------------
echo "🌍 Installing Helium Browser..."
curl -fsSL https://raw.githubusercontent.com/imputnet/helium-linux/main/pubkey.asc | sudo gpg --dearmor -o /usr/share/keyrings/helium.gpg
echo "deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/helium.gpg] https://pkg.helium.computer/deb stable main" | sudo tee /etc/apt/sources.list.d/helium.list
sudo apt update && sudo apt install -y helium-bin
# ---------------------------------------------------------------------------------
# Install adw-gtk3 (GTK app theming for DMS)
# ---------------------------------------------------------------------------------
echo "🎨 Installing adw-gtk3..."
curl -s https://julianfairfax.codeberg.page/package-repo/pub.gpg | gpg --dearmor | sudo dd of=/usr/share/keyrings/julians-package-repo.gpg
echo 'deb [ signed-by=/usr/share/keyrings/julians-package-repo.gpg ] https://julianfairfax.codeberg.page/package-repo/debs packages main' | sudo tee /etc/apt/sources.list.d/julians-package-repo.list
sudo apt update && sudo apt install -y adw-gtk3
# ---------------------------------------------------------------------------------
echo ""
echo "✅ Bootstrap complete."
echo ""
+5 -4
View File
@@ -1,22 +1,23 @@
[general]
import = [ "~/.config/alacritty/dank-theme.toml" ]
[font]
size = 13.5
size = 12
offset = { x = 0, y = 3 }
normal = { family = "JetBrainsMono Nerd Font", style = "Regular" }
[window]
# opacity = 0.99
# startup_mode = "Maximized"
padding.x = 10
padding.y = 10
decorations = "None"
[cursor]
style.shape = "Beam"
style.blinking = "Always"
# Kanagawa Wave Alacritty Colors
[colors.primary]
background = '#101010'
foreground = '#dcd7ba'
[colors.normal]
black = '#090618'
+116
View File
@@ -0,0 +1,116 @@
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local beautiful = require("beautiful")
local colors = require("config.colors")
local widgets = require("config.widgets")
local M = {}
local taglist_buttons = gears.table.join(
awful.button({ }, 1, function(t) t:view_only() end),
awful.button({ modkey }, 1, function(t) if client.focus then client.focus:move_to_tag(t) end end),
awful.button({ }, 3, awful.tag.viewtoggle)
)
local function set_wallpaper(s)
if beautiful.wallpaper then
local wp = beautiful.wallpaper
if type(wp) == "function" then wp = wp(s) end
gears.wallpaper.maximized(wp, s, true)
end
end
screen.connect_signal("property::geometry", set_wallpaper)
function M.setup()
awful.screen.connect_for_each_screen(function(s)
set_wallpaper(s)
awful.tag({ "1", "2", "3", "4", "5" }, s, awful.layout.layouts[1])
s.mypromptbox = awful.widget.prompt()
s.mylayoutbox = awful.widget.layoutbox(s)
s.mylayoutbox:buttons(gears.table.join(
awful.button({ }, 1, function() awful.layout.inc(1) end),
awful.button({ }, 3, function() awful.layout.inc(-1) end)
))
s.mytaglist = awful.widget.taglist {
screen = s, filter = awful.widget.taglist.filter.all, buttons = taglist_buttons,
style = { shape = function(cr, w, h) gears.shape.rounded_rect(cr, w, h, 4) end },
layout = { spacing = 4, layout = wibox.layout.fixed.horizontal },
widget_template = {
{ { id = "text_role", widget = wibox.widget.textbox }, left = 10, right = 10, top = 4, bottom = 4, widget = wibox.container.margin },
id = "background_role", widget = wibox.container.background,
},
}
-- Per-screen monitor widgets (created here so multi-monitor stays valid)
local title = widgets.make_title()
local vol = widgets.make_vol()
local cpu = widgets.make_cpu()
local brightness = widgets.make_brightness()
local clock = wibox.widget.textclock("%Y-%m-%d %H:%M")
local right = wibox.layout.fixed.horizontal()
local function push(w) right:add(widgets.padded(w, 4, 4)) end
push(wibox.widget.systray()); right:add(widgets.sep())
push(vol); right:add(widgets.sep())
push(cpu); right:add(widgets.sep())
push(clock);
push(brightness);
push(s.mylayoutbox)
s.mywibox = awful.wibar {
position = "top", screen = s, height = 45, bg = colors.background, fg = colors.white,
shape = function(cr, w, h) gears.shape.rounded_rect(cr, w, h, 0) end,
}
s.mywibox:setup {
layout = wibox.container.margin, left = 8, right = 8, top = 10, bottom = 10,
{
layout = wibox.layout.align.horizontal,
{ -- Left: workspaces + focused window title
layout = wibox.layout.fixed.horizontal,
widgets.padded(s.mytaglist, 8, 4), s.mypromptbox,
{ title, left = 18, widget = wibox.container.margin },
},
nil, -- empty center
widgets.padded(right, 4, 12),
}
}
end)
-- Overlay for rofi launchers
local dim_overlay = wibox({
visible = false,
ontop = true,
type = "splash",
bg = "#00000099",
})
dim_overlay.name = "awesome_dim_overlay"
awful.screen.connect_for_each_screen(function(s)
dim_overlay.screen = s -- adjust if you want it per-screen vs spanning all
end)
-- span the primary screen's geometry (or loop over all screens if you use a multi-monitor dim)
local function update_dim_geometry()
local geo = screen.primary.geometry
dim_overlay:geometry(geo)
end
update_dim_geometry()
screen.connect_signal("property::geometry", update_dim_geometry)
-- expose functions over awesome-client
_G.show_dim = function() dim_overlay.visible = true end
_G.hide_dim = function() dim_overlay.visible = false end
-- Prime the window so X/picom register its type before first real use,
-- avoiding a one-time grow animation on the very first show_dim() call
dim_overlay.visible = true
gears.timer.delayed_call(function()
dim_overlay.visible = false
end)
end
return M
+12
View File
@@ -0,0 +1,12 @@
return {
background = "#111111",
background_alt = "#1a1a1a",
foreground = "#dcd7ba", -- kanagawa foreground
accent = "#6a9589", -- black (bright) - muted gray, same role as old #6e6e6e
accent_alt = "#7fb4ca", -- blue (normal) - crystalBlue
red = "#e82424", -- red (bright) - samuraiRed, vivid
green = "#98bb6c", -- green (bright) - springGreen
yellow = "#e6c384", -- yellow (bright) - carpYellow
disabled = "#6a9589", -- cyan (normal) - muted, low-contrast
white = "#ffffff", -- white (normal) - dimmer than foreground
}
+85
View File
@@ -0,0 +1,85 @@
local awful = require("awful")
local gears = require("gears")
local hotkeys_popup = require("awful.hotkeys_popup")
local menubar = require("menubar")
local M = {}
M.globalkeys = gears.table.join(
awful.key({ modkey }, "s", hotkeys_popup.show_help, { description = "show help", group = "awesome" }),
-- Directional focus (vim keys)
awful.key({ modkey }, "h", function() awful.client.focus.bydirection("left") end, { description = "focus left", group = "client" }),
awful.key({ modkey }, "j", function() awful.client.focus.bydirection("down") end, { description = "focus down", group = "client" }),
awful.key({ modkey }, "k", function() awful.client.focus.bydirection("up") end, { description = "focus up", group = "client" }),
awful.key({ modkey }, "l", function() awful.client.focus.bydirection("right") end, { description = "focus right", group = "client" }),
-- Directional move (swap clients in the tiling layout)
awful.key({ modkey, "Control" }, "h", function() awful.client.swap.bydirection("left") end, { description = "move left", group = "client" }),
awful.key({ modkey, "Control" }, "j", function() awful.client.swap.bydirection("down") end, { description = "move down", group = "client" }),
awful.key({ modkey, "Control" }, "k", function() awful.client.swap.bydirection("up") end, { description = "move up", group = "client" }),
awful.key({ modkey, "Control" }, "l", function() awful.client.swap.bydirection("right") end, { description = "move right", group = "client" }),
-- Resize the master/other split
awful.key({ modkey, "Shift" }, "h", function() awful.tag.incmwfact(-0.05) end, { description = "shrink master", group = "layout" }),
awful.key({ modkey, "Shift" }, "l", function() awful.tag.incmwfact( 0.05) end, { description = "grow master", group = "layout" }),
-- Launching / layout
awful.key({ modkey }, "Return", function() awful.spawn(terminal) end, { description = "open a terminal", group = "launcher" }),
awful.key({ modkey }, "e", function() awful.spawn("thunar") end, { description = "Filemanager", group = "system" }),
awful.key({ modkey }, "w", function() awful.layout.inc(1) end, { description = "next layout", group = "layout" }),
-- screenshooter
awful.key({ modkey, "Control" }, "p", function() awful.spawn("xfce4-screenshooter") end, { description = "screenshot", group = "system" }),
-- Alt tab current workspace windows
awful.key({ "Mod1" }, "Tab", function() awful.client.focus.byidx(1) end),
-- Media keys
awful.key({ }, "XF86AudioRaiseVolume", function() awful.spawn.easy_async_with_shell([[sh -c 'pactl set-sink-volume "$(pactl get-default-sink)" +2%']]) end, { description = "volume up", group = "media" }),
awful.key({ }, "XF86AudioLowerVolume", function() awful.spawn.easy_async_with_shell([[sh -c 'pactl set-sink-volume "$(pactl get-default-sink)" -2%']]) end, { description = "volume down", group = "media" }),
awful.key({ }, "XF86AudioMute", function() awful.spawn.easy_async_with_shell([[sh -c 'pactl set-sink-mute "$(pactl get-default-sink)" toggle']]) end, { description = "toggle mute", group = "media" }),
-- rofi menus
awful.key({ modkey }, "space", function() awful.spawn("/home/jason/.local/bin/runrofi") end, { description = "application launcher", group = "launcher" }),
awful.key({ modkey }, "`", function() awful.spawn("/home/jason/.local/bin/powermenu") end, { description = "power menu", group = "system" }),
awful.key({ modkey }, "a", function() awful.spawn("/home/jason/.local/bin/audioswitch") end, { description = "audio output", group = "system" }),
awful.key({ modkey }, "b", function () awful.spawn("/home/jason/.local/bin/bookmarks") end, {description = "bookmarks", group = "internet"}),
-- Awesome control
awful.key({ modkey, "Control" }, "r", awesome.restart, { description = "reload awesome", group = "awesome" })
)
-- Workspace keys 1..5: Alt+N view, Alt+Shift+N move client to tag
for i = 1, 5 do
M.globalkeys = gears.table.join(M.globalkeys,
awful.key({ modkey }, "#" .. i + 9, function()
local screen = awful.screen.focused()
local tag = screen.tags[i]
if tag then tag:view_only() end
end, { description = "view tag #" .. i, group = "tag" }),
awful.key({ modkey, "Control" }, "#" .. i + 9, function()
if client.focus then
local tag = client.focus.screen.tags[i]
if tag then client.focus:move_to_tag(tag) end
end
end, { description = "move focused client to tag #" .. i, group = "tag" })
)
end
M.clientkeys = gears.table.join(
awful.key({ modkey }, "q", function(c) c:kill() end, { description = "kill window", group = "client" }),
awful.key({ modkey }, "f", function(c) c.fullscreen = not c.fullscreen; c:raise() end, { description = "toggle fullscreen", group = "client" }),
awful.key({ modkey }, "m", function(c) c:swap(awful.client.getmaster()) end, { description = "make master", group = "client" }),
awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle, { description = "toggle floating", group = "client" })
)
M.clientbuttons = gears.table.join(
awful.button({ }, 1, function(c) c:emit_signal("request::activate", "mouse_click", { raise = true }) end),
awful.button({ modkey }, 1, function(c) c:emit_signal("request::activate", "mouse_click", { raise = true }); awful.mouse.client.move(c) end),
awful.button({ modkey }, 3, function(c) c:emit_signal("request::activate", "mouse_click", { raise = true }); awful.mouse.client.resize(c) end)
)
return M
+20
View File
@@ -0,0 +1,20 @@
local awful = require("awful")
local beautiful = require("beautiful")
local keys = require("config.keys")
return {
{ rule = { }, properties = {
border_width = beautiful.border_width, border_color = beautiful.border_normal,
focus = awful.client.focus.filter, raise = true,
keys = keys.clientkeys, buttons = keys.clientbuttons,
screen = awful.screen.preferred,
placement = awful.placement.no_overlap + awful.placement.no_offscreen,
}},
{ rule_any = {
instance = { "pinentry" },
class = { "Arandr", "Blueman-manager", "Gpick", "Pavucontrol" },
name = { "Event Tester" },
role = { "AlarmWindow", "pop-up" },
}, properties = { floating = true }},
}
+27
View File
@@ -0,0 +1,27 @@
local gears = require("gears")
local awful = require("awful")
local beautiful = require("beautiful")
client.connect_signal("manage", function(c)
if awesome.startup and not c.size_hints.user_position and not c.size_hints.program_position then
awful.placement.no_offscreen(c)
end
-- New windows open into the stack (to the right); first window becomes master.
if not awesome.startup then awful.client.setslave(c) end
-- 0 or ie 13 = corner radius
c.shape = function(cr, width, height) gears.shape.rounded_rect(cr, width, height, 0) end
end)
client.connect_signal("property::floating", function(c)
if c.floating and c.type ~= "notification" then awful.placement.centered(c, { honor_workarea = true }) end
end)
client.connect_signal("manage", function(c)
if c.floating and c.type ~= "notification" then awful.placement.centered(c, { honor_workarea = true }) end
end)
-- Focus follows mouse (i3-like). Comment out for click-to-focus only.
client.connect_signal("mouse::enter", function(c) c:emit_signal("request::activate", "mouse_enter", { raise = false }) end)
client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
+47
View File
@@ -0,0 +1,47 @@
local gears = require("gears")
local beautiful = require("beautiful")
local naughty = require("naughty")
local colors = require("config.colors")
beautiful.init(gears.filesystem.get_themes_dir() .. "default/theme.lua")
beautiful.useless_gap = 8
beautiful.gap_single_client = true
beautiful.font = "JetBrainsMono Nerd Font 11"
beautiful.border_width = 4
beautiful.border_normal = colors.background_alt
beautiful.border_focus = colors.accent
beautiful.taglist_bg_focus = colors.accent
beautiful.taglist_fg_focus = colors.background
beautiful.taglist_fg_occupied = colors.accent
beautiful.taglist_bg_occupied = colors.background
beautiful.taglist_fg_empty = colors.white
beautiful.taglist_bg_empty = colors.background
beautiful.taglist_bg_urgent = colors.red
beautiful.taglist_fg_urgent = colors.background
beautiful.bg_systray = colors.background
beautiful.systray_icon_spacing = 4
-- Notifications, styled to match the wibar/client theme
naughty.config.defaults.position = "top_right"
naughty.config.defaults.timeout = 5
naughty.config.padding = 12
naughty.config.defaults.margin = 12
naughty.config.defaults.spacing = 8
naughty.config.defaults.icon_size = 48
naughty.config.defaults.border_width = 3
naughty.config.defaults.font = "JetBrainsMono Nerd Font 12"
naughty.config.defaults.shape = function(cr, w, h) gears.shape.rounded_rect(cr, w, h, 13) end
naughty.config.presets.normal = {
bg = colors.background, fg = colors.foreground, border_color = colors.background_alt,
border_width = 3, font = "JetBrainsMono Nerd Font 12", timeout = 5,
}
naughty.config.presets.low = naughty.config.presets.normal
naughty.config.presets.critical = {
bg = colors.background, fg = colors.red, border_color = colors.red,
border_width = 3, font = "JetBrainsMono Nerd Font 12", timeout = 0, -- stays until dismissed
}
+118
View File
@@ -0,0 +1,118 @@
local awful = require("awful")
local gears = require("gears")
local wibox = require("wibox")
local colors = require("config.colors")
local M = {}
-- "ICON value" with ICON tinted accent, like polybar's *-prefix-foreground.
function M.label(icon, val)
return string.format("<span foreground='%s'>%s</span> %s", colors.white, icon, val or "")
end
-- A slim separator in the disabled color, like polybar's separator.
function M.sep()
local w = wibox.widget.textbox()
w.markup = string.format("<span foreground='%s00'> </span>", colors.disabled)
return w
end
-- Wrap a widget in a small margin so bar modules aren't crammed together.
function M.padded(w, left, right)
return wibox.container.margin(w, left or 8, right or 8)
end
-- Focused window title (polybar xwindow / %title%)
function M.make_title()
local t = wibox.widget.textbox()
local function update()
local c = client.focus
t.markup = c and string.format("<span foreground='%s'>%s</span>", colors.white, gears.string.xml_escape(c.name or "")) or ""
end
client.connect_signal("focus", update)
client.connect_signal("unfocus", update)
client.connect_signal("property::name", update)
return t
end
-- CPU usage % (two top samples so the reading is accurate)
function M.make_cpu()
return awful.widget.watch(
{ "bash", "-c", [[LANG=C top -bn2 -d0.3 | grep -m2 '^%Cpu' | tail -1 | awk '{printf "%.0f", 100 - $8}']] },
3, function(w, out) w.markup = M.label("<span font_size='large'> </span>", out:gsub("%s+$", "") .. "%") end)
end
-- Volume: click to mute, scroll to adjust, right-click for the mixer.
-- Keeps its own refresh() so button presses update instantly instead of
-- waiting on the polling timer.
function M.make_vol()
local w = wibox.widget.textbox()
local vol_script = [[
sink=$(LANG=C pactl get-default-sink 2>/dev/null)
m=$(LANG=C pactl get-sink-mute "$sink" 2>/dev/null | grep -oE 'yes|no')
v=$(LANG=C pactl get-sink-volume "$sink" 2>/dev/null | grep -oE '[0-9]+%' | head -n1)
echo "$m $v"
]]
local function shell_quote(s) return "'" .. s:gsub("'", "'\\''") .. "'" end
local vol_cmd = "sh -c " .. shell_quote(vol_script)
local function refresh()
awful.spawn.easy_async_with_shell(vol_cmd, function(out)
local muted, pct = out:match("(%a+)%s+(%d+)%%")
if muted == nil and pct == nil then
w.markup = string.format("<span foreground='%s'><span font_size='large'>󱄠</span> n/a</span>", colors.disabled)
return
end
muted = muted == "yes"
pct = pct or "0"
w.markup = muted and string.format("<span foreground='%s'>MUTE</span>", colors.yellow) or M.label("<span font_size='large'>󱄠</span>", pct .. "%")
end)
end
w:buttons(gears.table.join(
awful.button({ }, 1, function() awful.spawn("/home/jason/.local/bin/audioswitch") end),
awful.button({ }, 3, function() awful.spawn.easy_async_with_shell([[sh -c 'pactl set-sink-mute "$(pactl get-default-sink)" toggle']], function() refresh() end) end),
awful.button({ }, 4, function() awful.spawn.easy_async_with_shell([[sh -c 'pactl set-sink-volume "$(pactl get-default-sink)" +2%']], function() refresh() end) end),
awful.button({ }, 5, function() awful.spawn.easy_async_with_shell([[sh -c 'pactl set-sink-volume "$(pactl get-default-sink)" -2%']], function() refresh() end) end)
))
gears.timer { timeout = 2, call_now = true, autostart = true, callback = refresh }
return w
end
-- Brightness: click to toggle between night (default gamma) and day (boosted).
function M.make_brightness()
local OUTPUT = "HDMI-A-0"
local DAY_CMD = "xrandr --output " .. OUTPUT .. " --set CTM \"1.1,0,0,0,1.1,0,0,0,1.1\" --gamma 1.08:1.08:1.08"
local NIGHT_CMD = "xrandr --output " .. OUTPUT .. " --set CTM \"1,0,0,0,1,0,0,0,1\" --gamma 1.0:1.0:1.0"
local w = wibox.widget.textbox()
local is_day = true
local function render()
local icon = is_day and " 󱁞 " or " 󱠩 "
w.markup = string.format(
"<span font_family='JetBrainsMono Nerd Font' foreground='%s' font_size='large'>%s</span>",
colors.white, icon
)
end
local function apply(day)
local cmd = day and DAY_CMD or NIGHT_CMD
awful.spawn.easy_async_with_shell(cmd, function()
is_day = day
render()
end)
end
w:buttons(gears.table.join(
awful.button({ }, 1, function() apply(not is_day) end)
))
apply(true)
return w
end
return M
+52
View File
@@ -0,0 +1,52 @@
pcall(require, "luarocks.loader")
local gears = require("gears")
local awful = require("awful")
require("awful.autofocus")
local naughty = require("naughty")
local bling = require("bling")
-- Global config
modkey = "Mod1" -- Alt. Use "Mod4" for the Super/Windows key.
terminal = "alacritty"
editor = os.getenv("EDITOR") or "nano"
-- Layouts: suit.tile = master column LEFT, stack column RIGHT.
awful.layout.layouts = { awful.layout.suit.tile, awful.layout.suit.max }
-- Kill xfce4-notifyd on startup (with a short delay + retry, in case it
-- hasn't started yet at this point in the session)
awful.spawn.easy_async_with_shell("pkill xfce4-notifyd", function() end)
gears.timer.start_new(3, function()
awful.spawn.easy_async_with_shell("pkill xfce4-notifyd", function() end)
return false -- don't repeat
end)
-- Error handling
if awesome.startup_errors then
naughty.notify({ preset = naughty.config.presets.critical, title = "Error during startup", text = awesome.startup_errors })
end
do
local in_error = false
awesome.connect_signal("debug::error", function(err)
if in_error then return end
in_error = true
naughty.notify({ preset = naughty.config.presets.critical, title = "An error happened", text = tostring(err) })
in_error = false
end)
end
-- Modules (order matters: theme before bar, keys before rules)
require("config.theme")
local keys = require("config.keys")
require("config.bar").setup()
root.keys(keys.globalkeys)
awful.rules.rules = require("config.rules")
require("config.signals")
-- Wallpaper
bling.module.wallpaper.setup {
wallpaper = { "/home/jason/Pictures/Wallpapers/farewell.jpg" },
position = "fit",
background = "#181818",
}
+32 -76
View File
@@ -3,13 +3,22 @@
# ==============================================================================
# Disable fish greeting
set -g fish_greeting
set -g fish_prompt_pwd_dir_length 999
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 "/usr/local/nvim_012/bin/nvim"
set -gx VISUAL "/usr/local/nvim_012/bin/nvim"
set -gx EDITOR "nvim"
set -gx VISUAL "nvim"
set -gx MANPAGER "nvim +Man!"
set -gx BROWSER firefox
set -gx TERM xterm-256color
# set -gx TERM xterm-256color
set -gx COLORTERM truecolor
set -gx LANG "en_US.UTF-8"
set -gx LC_ALL "en_US.UTF-8"
@@ -61,7 +70,7 @@ 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 -C'
alias tree='tree --dirsfirst -C'
# Safety aliases
alias rm='rm -I --preserve-root'
@@ -73,64 +82,39 @@ alias ln='ln -i'
alias df='df -h'
alias du='du -h'
alias free='free -h'
alias bat='batcat --theme="gruvbox-dark" --paging=never '
alias bat='bat --theme="ansi" --paging=never'
# Application shortcuts
alias nvim='/usr/local/nvim_012/bin/nvim'
alias vim='nvim'
alias vi='nvim'
alias v='nvim'
alias :q='exit'
alias files='nemo .'
alias lg='gitu'
alias ldk='lazydocker'
alias lg='lazygit'
alias files='thunar .'
alias fetch='pfetch'
# Custom shortcuts
alias reload='source ~/.config/fish/config.fish'
alias dotman='bash ~/.dotfiles/install.sh'
alias wiki='cd ~/Wiki/ && nvim index.md'
alias dots='cd ~/.dotfiles && nvim'
alias doti='bash ~/.dotfiles/install.sh -i'
alias dotl='bash ~/.dotfiles/install.sh -l'
alias myip='curl ipinfo.io/ip; echo ""'
alias lspmake='bear -- make -B'
alias tc='tmux attach'
alias td='tmux detach'
alias db='lazysql'
alias query='xbps-query -Rs'
alias commits='git log origin/main..HEAD --oneline'
# Docker shortcuts
alias services-up='docker compose -f /home/jason/Documents/Compose/local-services/docker-compose.yaml up -d'
alias services-down='docker compose -f /home/jason/Documents/Compose/local-services/docker-compose.yaml down'
# ==============================================================================
# FUNCTIONS
# ==============================================================================
# Project Manager
## Basic project picker using mini sessions and neovim
function pp
set -l project_file "$HOME/.projects"
set project (
find ~/Projects -mindepth 1 -maxdepth 1 -type d |
awk -F/ '{print $NF "\t" $0}' |
fzf --with-nth=1
)
# Create the file if it doesn't exist
if not test -f "$project_file"
touch "$project_file"
if test -z "$project"
return
end
if count $argv >/dev/null
# Case 1: Path provided - Add to list
set -l absolute_path (realpath $argv[1])
if grep -Fxq "$absolute_path" "$project_file"
echo "Project already exists in list."
else
echo "$absolute_path" >>"$project_file"
echo "Added: $absolute_path"
end
else
# Case 2: No arguments - Select and Open
set -l selection (cat "$project_file" | awk -F'/' '{print $NF "\t" $0}' | fzf --height 40% --reverse --header="Select Project" --with-nth=1 --delimiter=(printf '\t') | cut -f2)
if test -n "$selection"
clear
cd "$selection"
commandline -f repaint # Ensures the prompt updates after cd
end
end
set project (echo $project | cut -f2)
cd $project && clear
end
# ==============================================================================
@@ -151,31 +135,3 @@ set -g __fish_git_prompt_separator ' '
set -g __fish_git_prompt_char_dirtystate '+'
set -g __fish_git_prompt_char_stagedstate '●'
set -g __fish_git_prompt_char_untrackedfiles ''
# Auto-attach to tmux on interactive shell start
if status is-interactive && not set -q TMUX
# Get all session names matching shell, shell-2, shell-3 etc
set sessions (tmux list-sessions -F '#S' 2>/dev/null)
if test (count $sessions) -eq 0
tmux new-session -s shell
else
# Check if any shell session is unattached and attach it
set target (tmux list-sessions -F '#{session_name} #{session_attached}' 2>/dev/null \
| grep '^shell' | grep ' 0$' | head -1 | awk '{print $1}')
if test -n "$target"
tmux attach -t $target
else
# All shell sessions attached — find next number
set nums 1
for s in $sessions
if string match -rq '^shell-(\d+)$' $s
set nums $nums (string replace 'shell-' '' $s)
end
end
set next (math (string join \n $nums | sort -n | tail -1) + 1)
tmux new-session -s shell-$next
end
end
end
-8
View File
@@ -1,8 +0,0 @@
[general]
always_show_help.enabled = true
collapsed_sections = ["staged_changes"]
refresh_on_file_change.enabled = true
stash_list_limit = 20
recent_commits_limit = 100
mouse_support = true
mouse_scroll_lines = 3
+7 -2
View File
@@ -16,8 +16,8 @@ set sortby natural
set dirfirst true
# ── Preview ──────────────────────────────────────────────────────────────────
set previewer ~/.local/bin/lf-preview
set cleaner ~/.local/bin/lf-cleaner
set previewer ~/.local/bin/lfpreview
set cleaner ~/.local/bin/lfcleaner
# ── Keybindings ──────────────────────────────────────────────────────────────
@@ -61,6 +61,11 @@ map <space> toggle
map mf push %touch<space>
map md push %mkdir<space>-p<space>
cmd extract ${{
lfextract "$f"
}}
map z extract
# ── Commands ─────────────────────────────────────────────────────────────────
cmd select-and-quit &{{
+95 -36
View File
@@ -1,37 +1,26 @@
require("vim._core.ui2").enable({})
map = vim.keymap.set
vim.g.mapleader = " "
vim.g.termguicolors = true -- Enable 24-bit RGB colors
vim.o.nu = true -- Show line numbers
vim.o.relativenumber = true -- Show relative line numbers
vim.o.cursorline = true -- Highlight the line where the cursor is
vim.o.wrap = false -- Don't wrap long lines to the next line
vim.o.list = true -- Show invisible characters (tabs, trailing spaces)
vim.o.scrolloff = 15 -- Keep 15 lines above/below cursor when scrolling
vim.o.winborder = 'rounded' -- Use rounded borders for floating windows
vim.o.ignorecase = true -- Ignore case in search patterns
vim.o.smartcase = true -- ...unless search contains an uppercase letter
vim.o.hlsearch = true -- Keep search results highlighted
vim.o.incsearch = true -- Show search results as you type
vim.o.path = "**" -- Search down into subdirectories (classic Vim)
vim.o.expandtab = true -- Use spaces instead of tabs
vim.o.shiftwidth = 4 -- 4 spaces per indent
vim.o.tabstop = 4 -- 4 spaces for a tab
vim.o.softtabstop = 4 -- Tab key inserts 4 spaces
vim.o.swapfile = false -- Disable creation of .swp files
vim.o.backup = false -- Disable backup files
vim.o.undofile = true -- Save undo history to a file
vim.o.splitright = true -- Open vertical splits to the right
vim.o.splitbelow = true -- Open horizontal splits below
vim.o.timeoutlen = 300 -- Time (ms) to wait for a mapped sequence to complete
vim.o.autocomplete = true
vim.o.showmode = false
vim.opt.clipboard = "unnamedplus"
vim.o.completeopt = 'menuone,noselect'
vim.o.undodir = os.getenv("HOME") .. "/.cache/nvim/undodir"
vim.o.termguicolors = true
vim.o.nu = true
vim.o.swapfile = false
vim.o.winborder = "single"
vim.o.winblend = 0
vim.o.pumblend = 0
vim.o.scrolloff = 20
vim.o.shiftwidth = 4
vim.o.tabstop = 4
vim.o.softtabstop = 4
vim.o.path = "**"
vim.o.clipboard = "unnamedplus"
vim.o.foldmethod = "expr"
vim.o.foldexpr = "v:lua.vim.treesitter.foldexpr()"
vim.o.foldlevel = 99
vim.o.completeopt = "menuone,noselect,fuzzy,nosort"
vim.o.undofile = true
vim.o.undodir = os.getenv("HOME") .. "/.cache/nvim/undodir"
vim.o.errorformat = "%f(%l:%c) %m,%-G%.%#"
-- -----------------------------
-- @BINDS
-- -----------------------------
map("t", "<ESC><ESC>", "<C-\\><C-n>")
map({"t", "n"}, "<C-h>", "<C-\\><C-n><C-w><C-h>")
map({"t", "n"}, "<C-j>", "<C-\\><C-n><C-w><C-j>")
@@ -43,9 +32,79 @@ map("v", "J", ":m '>+1<CR>gv=gv")
map("v", "K", ":m '<-2<CR>gv=gv")
map("v", "<S-Tab>", "<gv")
map("v", "<Tab>" , ">gv")
map("n", "<leader>p", ":b#<CR>")
map("n", "<leader>e", ":Ex<CR>")
map("n", "<leader>x", ":bd<CR>")
map("n", "<C-p>", ":find ")
map("n", "<C-e>", ":Lex<CR>")
map("n", "<C-backspace>", ":bd<CR>")
map("i", "<C-h>", vim.lsp.buf.signature_help)
-- -----------------------------
-- @PLUGINS
-- -----------------------------
vim.pack.add({
{ src = 'https://github.com/ibhagwan/fzf-lua' },
{ src = 'https://github.com/neovim/nvim-lspconfig' },
{ src = 'https://github.com/echasnovski/mini.nvim' },
{ src = 'https://github.com/nvim-tree/nvim-tree.lua' },
{ src = 'https://github.com/romus204/tree-sitter-manager.nvim' },
{ src = 'https://github.com/lukas-reineke/indent-blankline.nvim' },
{ src = 'https://github.com/rebelot/kanagawa.nvim' },
{ src = 'https://github.com/rose-pine/neovim' },
{ src = 'https://github.com/xiyaowong/transparent.nvim' },
})
require("autocmds")
require("plugins")
require("terminal")
require("mini.completion").setup()
require('mini.statusline').setup({})
require("tree-sitter-manager").setup()
require("ibl").setup({
indent = { char = "" },
scope = { show_start = false, show_end = false },
})
vim.cmd.colorscheme('kanagawa')
vim.api.nvim_set_hl(0, "WinSeparator", { fg = "#54546D" })
-- Lsp specific, uses nvim-lspconfigs with the below
vim.lsp.enable({ "gopls", "ols" })
map("n", "gd", ":lua vim.lsp.buf.definition()<CR>")
map("n", "gr", ":lua vim.lsp.buf.rename()<CR>")
map("n", "ga", ":lua vim.lsp.buf.code_action()<CR>")
require("fzf-lua").setup({})
map("n", "<C-p>", ":FzfLua files<CR>")
map("n", "<C-m>", ":FzfLua buffers<CR>")
map("n", "<C-i>", ":FzfLua diagnostics_workspace<CR>")
map("n", "<C-f>", ":FzfLua live_grep<CR>")
map("n", "<C-b>", ":FzfLua grep_curbuf<CR>")
require("nvim-tree").setup()
map("n", "<C-e>", ":NvimTreeToggle<CR>")
-- -----------------------------
-- @AUTOCMDS
-- -----------------------------
-- Terminals should open with insert mode
vim.api.nvim_create_autocmd({ "BufEnter", "TermEnter", "WinEnter" }, {
pattern = "term://*",
callback = function()
if vim.bo.buftype == "terminal" then
vim.schedule(function()
vim.cmd("startinsert")
end)
end
end
})
-- highlights yanked text
vim.api.nvim_create_autocmd("TextYankPost", {
callback = function()
vim.highlight.on_yank({
higroup = "IncSearch",
timeout = 200,
})
end,
})
-- removes trailing whitespace on save
vim.api.nvim_create_autocmd("BufWritePre", {
callback = function()
local save_cursor = vim.fn.getpos(".")
vim.cmd([[%s/\s\+$//e]])
vim.fn.setpos(".", save_cursor)
end,
})
-122
View File
@@ -1,122 +0,0 @@
-- Terminals should open with insert mode
vim.api.nvim_create_autocmd("BufEnter", { pattern = "term://*", callback = function() vim.cmd("startinsert") end })
-- Start treesitter
vim.api.nvim_create_autocmd('FileType', {
pattern = '*',
callback = function()
pcall(vim.treesitter.start)
end,
})
-- highlights yanked text
vim.api.nvim_create_autocmd("TextYankPost", {
callback = function()
vim.highlight.on_yank({
higroup = "IncSearch",
timeout = 200,
})
end,
})
-- Set absolute numbers when in insert mode otherwise relativenumbers
local nums = vim.api.nvim_create_augroup('smart_numbers', {})
vim.api.nvim_create_autocmd('InsertEnter', {
group = nums,
callback = function()
vim.opt.relativenumber = false
end,
})
vim.api.nvim_create_autocmd('InsertLeave', {
group = nums,
callback = function()
vim.opt.relativenumber = true
end,
})
-- removes trailing whitespace on save
vim.api.nvim_create_autocmd("BufWritePre", {
callback = function()
local save_cursor = vim.fn.getpos(".")
vim.cmd([[%s/\s\+$//e]])
vim.fn.setpos(".", save_cursor)
end,
})
-- Lsp autocomplete
vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup('my.lsp', {}),
callback = function(ev)
local client = vim.lsp.get_client_by_id(ev.data.client_id)
if not client then return end
-- Set completeopt for a better experience
vim.opt.completeopt = { 'menu', 'menuone', 'noinsert', 'noselect' }
-- Enable completion if the server supports it
if client:supports_method('textDocument/completion') then
vim.lsp.completion.enable(true, client.id, ev.buf, {
autotrigger = true, -- false = manual trigger only
})
end
end,
})
-- Define highlight groups
vim.api.nvim_set_hl(0, "TodoFix", { fg = "#FF5555", bold = true })
vim.api.nvim_set_hl(0, "TodoTodo", { fg = "#FFB86C", bold = true })
vim.api.nvim_set_hl(0, "TodoNote", { fg = "#A8D8FF", bold = true })
vim.api.nvim_set_hl(0, "TodoInfo", { fg = "#98DB6F", bold = true })
-- Match and highlight keywords in comments
local keywords = {
{ pattern = "FIX:.*", group = "TodoFix" },
{ pattern = "TODO:.*", group = "TodoTodo" },
{ pattern = "NOTE:.*", group = "TodoNote" },
{ pattern = "INFO:.*", group = "TodoInfo" },
}
vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost" }, {
callback = function()
for _, kw in ipairs(keywords) do
vim.fn.matchadd(kw.group, kw.pattern)
end
end,
})
-- Format: whole file or visual selection via :Fc
local function smart_format()
local mode = vim.fn.mode()
local in_visual = mode == "v" or mode == "V" or mode == "\22"
local clients = vim.lsp.get_clients({ bufnr = 0 })
local has_formatter = false
for _, client in ipairs(clients) do
if client.supports_method("textDocument/formatting") then
has_formatter = true
break
end
end
if in_visual then
if has_formatter then
vim.lsp.buf.format({
range = {
start = vim.api.nvim_buf_get_mark(0, "<"),
["end"] = vim.api.nvim_buf_get_mark(0, ">"),
},
})
else
vim.cmd("normal! gv=")
end
else
if has_formatter then
vim.lsp.buf.format({ async = false })
else
local view = vim.fn.winsaveview()
vim.cmd("normal! gg=G")
vim.fn.winrestview(view)
end
end
end
vim.api.nvim_create_user_command("FF", smart_format, { range = true })
-53
View File
@@ -1,53 +0,0 @@
vim.pack.add({
{ src = "https://github.com/ibhagwan/fzf-lua" },
{ src = "https://github.com/neovim/nvim-lspconfig" },
{ src = "https://github.com/romus204/tree-sitter-manager.nvim" },
{ src = "https://github.com/rebelot/kanagawa.nvim" },
{ src = "https://github.com/tribela/transparent.nvim" },
{ src = "https://github.com/nvim-lualine/lualine.nvim" }
})
vim.cmd(":colorscheme kanagawa")
require("tree-sitter-manager").setup({})
local theme = require('lualine.themes.kanagawa')
for _, mode in pairs(theme) do
if mode.b then mode.b.bg = '#16161D' end
if mode.c then mode.c.bg = '#16161D' end
if mode.x then mode.x.bg = '#16161D' end
if mode.y then mode.y.bg = '#16161D' end
if mode.z then mode.z.bg = '#16161D' end
end
require('lualine').setup({
options = {
theme = theme,
component_separators = '',
section_separators = '',
},
sections = {
lualine_a = {'mode'},
lualine_b = {},
lualine_c = {'filename'},
lualine_x = {'diagnostics'},
lualine_y = {},
lualine_z = {'lsp_status', 'location'},
},
})
require("fzf-lua").setup()
map("n", "<leader>f", ":lua FzfLua.files()<CR>")
map("n", "<leader>o", ":lua FzfLua.buffers()<CR>")
map("n", "<leader>h", ":lua FzfLua.help_tags()<CR>")
map("n", "<leader>d", ":lua FzfLua.diagnostics_document()<CR>")
map("n", "<leader>a", ":lua FzfLua.lsp_code_actions()<CR>")
map("n", "<leader>ss", ":lua FzfLua.grep_project()<CR>")
map("n", "<leader>sf", ":lua FzfLua.grep_curbuf()<CR>")
map("n", "<leader>sw", ":lua FzfLua.grep_cword()<CR>")
-- Lsp specific, uses nvim-lspconfigs with the below
vim.lsp.enable({ "gopls", "ols" })
map("n", "L", ":lua vim.diagnostic.open_float()<CR>")
map("n", "gd", ":lua vim.lsp.buf.definition()<CR>")
map("n", "<leader>r", ":lua vim.lsp.buf.rename()<CR>")
+58
View File
@@ -0,0 +1,58 @@
local term_buf = nil
local function open_term_split()
vim.cmd('botright vsplit')
local win = vim.api.nvim_get_current_win()
if term_buf and vim.api.nvim_buf_is_valid(term_buf) then
vim.api.nvim_win_set_buf(win, term_buf)
else
vim.cmd('terminal')
term_buf = vim.api.nvim_get_current_buf()
end
vim.api.nvim_win_set_width(win, math.floor(vim.o.columns * 0.37))
vim.cmd('startinsert')
end
local function toggle_term()
-- Check if terminal is already visible in a window
for _, win in ipairs(vim.api.nvim_list_wins()) do
if vim.api.nvim_win_get_buf(win) == term_buf then
vim.api.nvim_win_close(win, false)
return
end
end
open_term_split()
end
local function open_term_fullscreen()
if term_buf and vim.api.nvim_buf_is_valid(term_buf) then
vim.api.nvim_set_current_buf(term_buf)
else
vim.cmd('terminal')
term_buf = vim.api.nvim_get_current_buf()
end
vim.cmd('startinsert')
end
local function prev_non_term_buf()
local cur = vim.api.nvim_get_current_buf()
local bufs = vim.fn.getbufinfo({ buflisted = 1 })
local candidates = {}
for _, info in ipairs(bufs) do
if info.bufnr ~= cur and vim.bo[info.bufnr].buftype ~= 'terminal' then
table.insert(candidates, info)
end
end
if #candidates == 0 then
print('No previous non-terminal buffer')
return
end
table.sort(candidates, function(a, b) return a.lastused > b.lastused end)
vim.api.nvim_set_current_buf(candidates[1].bufnr)
end
map('n', '<C-j>', toggle_term, { desc = 'Toggle terminal split' })
map('n', '<C-o>', open_term_fullscreen, { desc = 'Open terminal fullscreen' })
map('t', '<C-o>', prev_non_term_buf, { desc = 'Exit terminal mode' })
map('t', '<C-j>', toggle_term, { desc = 'Toggle terminal split' })
map('t', '<C-o>', prev_non_term_buf, { desc = 'Exit terminal mode' })
+286
View File
@@ -0,0 +1,286 @@
#################################
# Fading #
#################################
fading = false;
fade-in-step = 0.04;
fade-out-step = 0.04;
#################################
# Corners #
#################################
# corner-radius = 0;
#################################
# FAST SNAPPY ANIMATIONS #
#################################
match = "window_type = 'normal'";
animations = (
{
triggers = ["close"];
opacity = {
curve = "cubic-bezier(0,1,1,1)";
duration = 0.3;
start = "window-raw-opacity-before";
end = 0;
};
blur-opacity = "opacity";
shadow-opacity = "opacity";
scale-x = {
curve = "cubic-bezier(0,1.3,1,1)";
duration = 0.3;
start = 1;
end = 0.6;
};
scale-y = "scale-x";
offset-x = "(1 - scale-x) / 2 * window-width";
offset-y = "(1 - scale-y) / 2 * window-height";
shadow-scale-x = "scale-x";
shadow-scale-y = "scale-y";
shadow-offset-x = "offset-x";
shadow-offset-y = "offset-y";
},
{
triggers = ["open"];
opacity = {
curve = "cubic-bezier(0,1,1,1)";
duration = 0.5;
start = 0;
end = "window-raw-opacity";
};
blur-opacity = "opacity";
shadow-opacity = "opacity";
scale-x = {
curve = "cubic-bezier(0,1.3,1,1)";
duration = 0.5;
start = 0.6;
end = 1;
};
scale-y = "scale-x";
offset-x = "(1 - scale-x) / 2 * window-width";
offset-y = "(1 - scale-y) / 2 * window-height";
shadow-scale-x = "scale-x";
shadow-scale-y = "scale-y";
shadow-offset-x = "offset-x";
shadow-offset-y = "offset-y";
},
{
triggers = ["geometry"];
scale-x = {
curve = "cubic-bezier(0,0,0,1.28)";
duration = 0.5;
start = "window-width-before / window-width";
end = 1;
};
scale-x-reverse = {
curve = "cubic-bezier(0,0,0,1.28)";
duration = 0.3;
start = "window-width / window-width-before";
end = 1;
};
scale-y = {
curve = "cubic-bezier(0,0,0,1.28)";
duration = 0.5;
start = "window-height-before / window-height";
end = 1;
};
scale-y-reverse = {
curve = "cubic-bezier(0,0,0,1.28)";
duration = 0.5;
start = "window-height / window-height-before";
end = 1;
};
offset-x = {
curve = "cubic-bezier(0,0,0,1.28)";
duration = 0.5;
start = "window-x-before - window-x";
end = 0;
};
offset-y = {
curve = "cubic-bezier(0,0,0,1.28)";
duration = 0.5;
start = "window-y-before - window-y";
end = 0;
};
shadow-scale-x = "scale-x";
shadow-scale-y = "scale-y";
shadow-offset-x = "offset-x";
shadow-offset-y = "offset-y";
},
)
#################################
# General Settings #
#################################
backend = "glx";
dithered-present = false;
vsync = true;
detect-rounded-corners = true;
detect-client-opacity = true;
detect-transient = true;
use-damage = true;
log-level = "warn";
#################################
# Window Rules #
#################################
rules: (
# No rounded corners on dock and desktop
{
match = "window_type = 'dock' || window_type = 'desktop'";
corner-radius = 0;
},
{
match = "class_g = 'Rofi'";
animations = (
{
triggers = ["open", "show"];
opacity = {
curve = "cubic-bezier(0, 1, 1, 1)";
duration = 0.2;
start = 0;
end = "window-raw-opacity";
};
shadow-opacity = "opacity";
scale-y = {
curve = "cubic-bezier(0.2, 0, 0, 1)";
duration = 0.2;
start = 0.55;
end = 1;
};
shadow-scale-y = "scale-y";
},
{
triggers = ["close", "hide"];
opacity = {
curve = "cubic-bezier(0, 1, 1, 1)";
duration = 0.15;
start = "window-raw-opacity-before";
end = 0;
};
shadow-opacity = "opacity";
scale-y = {
curve = "cubic-bezier(0.2, 0, 0, 1)";
duration = 0.15;
start = 1;
end = 0.55;
};
shadow-scale-y = "scale-y";
},
);
},
{
match = "window_type = 'splash' && name = 'awesome_dim_overlay'";
animations = ();
shadow = false;
corner-radius = 0;
fade = false;
},
)
+122
View File
@@ -0,0 +1,122 @@
* {
/* -- Palette, matches colors{} in awesome rc.lua -- */
bg0: #111111; /* colors.background */
bg1: #1a1a1a; /* colors.background_alt */
fg0: #dcd7ba; /* colors.foreground */
fg-selected: #ffffff; /* colors.white */
accent: #6a9589; /* colors.accent */
accent-alt: #727169; /* colors.accent_alt */
red: #e82424; /* colors.red */
disabled: #6a9589; /* colors.disabled */
font: "JetBrainsMono Nerd Font 14";
background-color: transparent;
text-color: @fg0;
}
window {
transparency: "real";
/* Anchor top-center, right below the wibar. */
location: north;
anchor: north;
y-offset: 48px;
width: 32em;
height: 26em; /* fixed — box size no longer changes with result count */
background-color: @bg0;
border: 3px;
border-color: @accent;
border-radius: -1px; /* matches gears.shape.rounded_rect radius in rc.lua */
padding: 14px;
}
mainbox {
children: [ inputbar, message, listview, mode-switcher ];
spacing: 10px;
background-color: transparent;
}
/* -- Search field -- */
inputbar {
children: [ prompt, entry ];
spacing: 10px;
background-color: @bg1;
border-radius: 10px;
padding: 10px 14px;
}
prompt {
text-color: @accent-alt;
}
entry {
placeholder: "Search";
placeholder-color: @disabled;
text-color: @fg0;
cursor: text;
}
/* -- List/grid toggle icons, top-right (matches screenshot) -- */
mode-switcher {
enabled: false; /* flip to true if you use rofi's built-in mode tabs */
}
/* -- Results -- */
listview {
lines: 8;
columns: 1;
spacing: 6px;
scrollbar: false;
background-color: transparent;
fixed-height: true; /* box height stays locked, doesn't shrink/grow with result count */
dynamic: false; /* don't resize dynamically as you type either */
}
/*
* Rofi tracks row state as a combination of position (normal/alternate,
* i.e. even/odd rows for banding) and status (normal/urgent/active/selected).
* Each combination needs its own selector or a competing @theme import
* (if you have one elsewhere in your rofi config) can still win on states
* this file doesn't explicitly cover. Pinning all of them here.
*/
element {
padding: 10px 12px;
border-radius: 10px;
orientation: horizontal;
}
element normal.normal,
element alternate.normal {
background-color: @bg1;
text-color: @fg0;
}
element normal.urgent,
element alternate.urgent {
background-color: @bg1;
text-color: @red;
}
element normal.active,
element alternate.active {
background-color: @bg1;
text-color: @accent-alt;
}
element selected.normal {
background-color: @accent-alt;
text-color: @fg-selected;
}
element selected.urgent {
background-color: @red;
text-color: @fg-selected;
}
element selected.active {
background-color: @accent-alt;
text-color: @bg0;
}
element-icon {
size: 24px;
padding: 0 12px 0 0;
vertical-align: 0.5;
background-color: transparent;
}
element-text {
vertical-align: 0.5;
text-color: inherit;
background-color: transparent;
}
message {
background-color: @bg1;
border-radius: 10px;
padding: 8px 12px;
}
textbox {
text-color: @fg0;
}
-51
View File
@@ -1,51 +0,0 @@
# Terminal colors
set -g default-terminal "tmux-256color"
set -as terminal-features ",xterm*:RGB"
set -g mouse on
set -g base-index 1
set -g pane-base-index 1
set -s escape-time 10
# remap prefix from 'C-b' to 'C-f'
unbind l
unbind C-b
set-option -g prefix C-f
bind-key C-f send-prefix
# reload config file
bind r source-file ~/.config/tmux/tmux.conf
# switch panes using Alt-arrow without prefix
setw -g mode-keys vi
bind -n C-h select-pane -L
bind -n C-l select-pane -R
bind -n C-k select-pane -U
bind -n C-j select-pane -D
bind h select-pane -L
bind l select-pane -R
bind k select-pane -U
bind j select-pane -D
bind f resize-pane -Z
bind m command-prompt "new-session -s %1"
# split pane
unbind '"'
unbind %
bind 'v' split-window -h -l 45% -c "#{pane_current_path}"
bind 't' split-window -v -l 40% -c "#{pane_current_path}"
bind j run-shell -b "~/.local/bin/tmux-toggle-term float"
bind g run-shell 'tmux popup -d "#{pane_current_path}" -xC -yC -w90% -h90% -E gitu'
bind e run-shell 'tmux popup -d "#{pane_current_path}" -xC -yC -w90% -h90% -E "~/.local/bin/tmux-lf"'
## STATUS BAR ##################################################################
## Status bar design
set -g status-justify left
set -g status-position top
set -g status-bg '#16161D'
set -g status-fg '#DCD7BA'
set -g status-left-length 20
set -g status-right ' #[fg=colour232,bg="#af875f",bold]#{?client_prefix, [PFX] ,} #[fg="#1c1c1c",bg="#767676",bold][#S] '
set -g status-left ' '
+65 -19
View File
@@ -2,7 +2,6 @@
# ---------------------------------------------------------------------------------
## GLOBAL VARS
# ---------------------------------------------------------------------------------
DOTFILES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# ---------------------------------------------------------------------------------
@@ -84,13 +83,15 @@ if [ "$DO_LINKS" = true ]; then
CREATED=0
SKIPPED=0
link_file "$DOTFILES_DIR/config/tmux" "$HOME/.config/tmux"
link_file "$DOTFILES_DIR/config/kanata" "$HOME/.config/kanata"
link_file "$DOTFILES_DIR/config/fish" "$HOME/.config/fish"
link_file "$DOTFILES_DIR/config/alacritty" "$HOME/.config/alacritty"
link_file "$DOTFILES_DIR/config/nvim" "$HOME/.config/nvim"
link_file "$DOTFILES_DIR/config/gitu" "$HOME/.config/gitu"
link_file "$DOTFILES_DIR/config/lf" "$HOME/.config/lf"
link_file "$DOTFILES_DIR/config/picom" "$HOME/.config/picom"
link_file "$DOTFILES_DIR/config/awesome" "$HOME/.config/awesome"
link_file "$DOTFILES_DIR/config/rofi" "$HOME/.config/rofi"
link_file "$DOTFILES_DIR/config/nvim" "$HOME/.config/nvim"
link_file "$DOTFILES_DIR/scripts/bin" "$HOME/.local/bin"
echo ""
echo "🧾 Summary: $CREATED symlink(s) created or fixed, $SKIPPED skipped."
@@ -114,13 +115,55 @@ if [ "$DO_INSTALL" = true ]; then
fi
if [ "$DO_INSTALL" = true ]; then
# -----------------------------------------------------------------------------
## ADD NONFREE REPOS
# -----------------------------------------------------------------------------
echo "📦 Checking nonfree repositories..."
REPO_PACKAGES=(void-repo-nonfree)
# Only add multilib-nonfree on x86_64
if [ "$(uname -m)" = "x86_64" ]; then
REPO_PACKAGES+=(void-repo-multilib-nonfree)
fi
MISSING_REPOS=()
for repo in "${REPO_PACKAGES[@]}"; do
if ! xbps-query -p pkgver "$repo" >/dev/null 2>&1; then
MISSING_REPOS+=("$repo")
fi
done
if [ ${#MISSING_REPOS[@]} -eq 0 ]; then
echo "✅ Nonfree repositories already enabled."
else
echo "📦 Enabling repositories: ${MISSING_REPOS[*]}"
sudo xbps-install -Sy "${MISSING_REPOS[@]}"
fi
echo ""
# -----------------------------------------------------------------------------
## INSTALL REQUIRED PACKAGES
# -----------------------------------------------------------------------------
REQUIRED_PACKAGES=(
# system essentials
wget curl git unzip lf jq alacritty fzf
fd-find direnv ripgrep tree bat syncthing
build-essential make bear valgrind fish
tmux ca-certificates gnupg libfuse2
fonts-symbola fonts-noto fonts-noto-color-emoji
# network & download
wget curl ca-certificates gnupg rsync
# core utilities
git unzip jq fzf tree direnv make
# modern cli replacements
lf fd ripgrep bat delta lazygit
# shell & terminal
fish-shell alacritty
# build & dev tools
base-devel valgrind tree-sitter-cli go
# system
pfetch fuse
# window manager & desktop
picom xdotool wmctrl polybar rofi kanata
# fonts
noto-fonts-ttf noto-fonts-emoji
)
MISSING_PACKAGES=()
@@ -128,11 +171,9 @@ if [ "$DO_INSTALL" = true ]; then
echo "🔍 Checking for missing packages..."
echo ""
# Check which packages are missing using dpkg
# Check which packages are missing using xbps-query
for pkg in "${REQUIRED_PACKAGES[@]}"; do
# dpkg-query checks for the installed status.
# We check for a non-zero exit status which indicates the package is NOT installed.
if ! dpkg-query -W -f='${Status}' "$pkg" 2>/dev/null | grep -q "install ok installed"; then
if ! xbps-query -p pkgver "$pkg" >/dev/null 2>&1; then
MISSING_PACKAGES+=("$pkg")
fi
done
@@ -140,16 +181,21 @@ if [ "$DO_INSTALL" = true ]; then
if [ ${#MISSING_PACKAGES[@]} -eq 0 ]; then
echo "✅ All required packages are already installed."
else
echo "📦 Updating package lists..."
# Update package lists before installing
sudo apt update
echo "📦 Syncing repository indexes..."
sudo xbps-install -S
echo "📦 Installing missing packages: ${MISSING_PACKAGES[*]}"
# Use sudo apt install for installing on Debian
sudo apt install "${MISSING_PACKAGES[@]}"
sudo xbps-install "${MISSING_PACKAGES[@]}"
fi
echo ""
echo "✅ Package setup complete."
echo ""
fi
# TODO: these need to go somewhere!
# xfconf-query -c xfce4-session -np '/shutdown/ShowSuspend' -t 'bool' -s 'false'
# xfconf-query -c xfce4-session -np '/shutdown/ShowHibernate' -t 'bool' -s 'false'
# xfconf-query -c xfce4-session -np '/shutdown/ShowHybridSleep' -t 'bool' -s 'false'
# xfconf-query -c xfce4-session -np '/shutdown/ShowSwitchUser' -t 'bool' -s 'false'
# xfconf-query -c xfwm4 -p /general/placement_ratio -s 100
# xfconf-query -c xfwm4 -p /general/use_compositing -s false
+68
View File
@@ -0,0 +1,68 @@
#!/usr/bin/env bash
# rofi-audio-switch: pick a PulseAudio/PipeWire sink via rofi
set -euo pipefail
awesome-client 'show_dim()' >/dev/null 2>&1
trap 'awesome-client "hide_dim()" >/dev/null 2>&1' EXIT
# Get list of sinks: index, name, description
mapfile -t sinks < <(pactl list sinks | awk -F': ' '
/^Sink #/ { idx=$2 }
/Name:/ { name=$2 }
/Description:/ { desc=$2; print idx"\t"name"\t"desc }
')
if [ "${#sinks[@]}" -eq 0 ]; then
notify-send "Audio Switch" "No sinks found"
exit 1
fi
current_sink=$(pactl get-default-sink)
# Build rofi menu: show description, mark current with a star
menu=""
for line in "${sinks[@]}"; do
name=$(echo "$line" | cut -f2)
desc=$(echo "$line" | cut -f3)
if [ "$name" = "$current_sink" ]; then
menu+="* $desc\n"
else
menu+=" $desc\n"
fi
done
chosen=$(echo -e "$menu" | rofi -dmenu -i -p "Audio Output" -markup-rows \
-theme-str 'listview { lines: 3; }' \
-theme-str 'window { height: 220px; }')
[ -z "$chosen" ] && exit 0
# Strip the leading marker to match description text
chosen_desc=$(echo "$chosen" | sed 's/^[* ] //')
# Find matching sink name for that description
target_name=""
for line in "${sinks[@]}"; do
desc=$(echo "$line" | cut -f3)
if [ "$desc" = "$chosen_desc" ]; then
target_name=$(echo "$line" | cut -f2)
break
fi
done
if [ -z "$target_name" ]; then
notify-send "Audio Switch" "Could not resolve selection"
exit 1
fi
# Set as default sink
pactl set-default-sink "$target_name"
# Move all currently running streams to the new sink
mapfile -t inputs < <(pactl list short sink-inputs | cut -f1)
for input in "${inputs[@]}"; do
pactl move-sink-input "$input" "$target_name"
done
notify-send "Audio Switch" "Switched to: $chosen_desc"
+47
View File
@@ -0,0 +1,47 @@
#!/usr/bin/env bash
# rofi-bookmarks: pick a Chromium bookmark and open it (new tab or new window)
set -euo pipefail
awesome-client 'show_dim()' >/dev/null 2>&1
trap 'awesome-client "hide_dim()" >/dev/null 2>&1' EXIT
BOOKMARKS_FILE="$HOME/.config/chromium/Default/Bookmarks"
if [ ! -f "$BOOKMARKS_FILE" ]; then
notify-send "Bookmarks" "Chromium bookmarks file not found"
exit 1
fi
# Recursively walk the bookmark tree (roots -> bookmark_bar / other / synced)
# and emit "title\turl" for every leaf ("type": "url"), skipping folders.
list=$(jq -r '
def walk_nodes:
if .type == "url" then
"\(.name)\t\(.url)"
elif .children then
.children[] | walk_nodes
else
empty
end;
.roots | to_entries[] | .value | walk_nodes
' "$BOOKMARKS_FILE")
if [ -z "$list" ]; then
notify-send "Bookmarks" "No bookmarks found"
exit 0
fi
chosen=$(echo "$list" | awk -F'\t' '{print $1}' | rofi -dmenu -i -p "Bookmarks" \
-theme-str 'listview { lines: 5; }' \
-theme-str 'window { width: 21%; }' \
-theme-str 'window { height: 400px; }')
[ -z "$chosen" ] && exit 0
url=$(echo "$list" | awk -F'\t' -v title="$chosen" '$1 == title { print $2; exit }')
[ -z "$url" ] && exit 0
# Open in a new tab of the existing Chromium window if one's running,
# otherwise this also launches Chromium fresh with that tab.
chromium --new-tab "$url"
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
# Nothing to clean for the previewer above, but lf requires this script.
exit 0
+17
View File
@@ -0,0 +1,17 @@
#!/bin/sh
for file in "$@"; do
case "$file" in
*.tar) tar xvf "$file" ;;
*.tar.gz|*.tgz) tar xzvf "$file" ;;
*.tar.bz2|*.tbz2) tar xjvf "$file" ;;
*.tar.xz|*.txz) tar xJvf "$file" ;;
*.zip) unzip "$file" ;;
*.rar) unrar x "$file" ;;
*.7z) 7z x "$file" ;;
*.gz) gunzip "$file" ;;
*.bz2) bunzip2 "$file" ;;
*.xz) unxz "$file" ;;
*) echo "Unknown archive type: $file" ;;
esac
done
+30
View File
@@ -0,0 +1,30 @@
#!/bin/sh
file="$1"
w="$2"
h="$3"
case "$(file -Lb --mime-type "$file")" in
text/*|application/json|application/x-empty|inode/x-empty)
bat --theme="ansi" --color=always --style=numbers --line-range=:500 --terminal-width="$w" "$file"
;;
image/*)
echo "Image: $file"
;;
application/pdf)
pdftotext -l 10 -nopgbrk -q "$file" - | fold -s -w "$w"
;;
application/zip|application/x-tar|application/x-rar|application/x-7z-compressed|application/gzip|application/x-bzip2|application/x-xz)
echo "Archive: $file"
echo
case "$file" in
*.zip) unzip -l "$file" ;;
*.tar|*.tar.*|*.tgz) tar tf "$file" ;;
*.rar) unrar l "$file" ;;
*.7z) 7z l "$file" ;;
*) echo "Archive listing not supported" ;;
esac
;;
*)
file -Lb "$file"
;;
esac
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env bash
# rofi-power-menu: logout / restart / shutdown via rofi
set -euo pipefail
awesome-client 'show_dim()' >/dev/null 2>&1
trap 'awesome-client "hide_dim()" >/dev/null 2>&1' EXIT
options=" Logout\n Restart\n Shutdown"
chosen=$(echo -e "$options" | rofi -dmenu -i -p "Power" -markup-rows \
-theme-str 'listview { lines: 3; }' \
-theme-str 'window { height: 240px; }')
[ -z "$chosen" ] && exit 0
case "$chosen" in
*Logout*)
loginctl terminate-session ${XDG_SESSION_ID-}
;;
*Restart*)
loginctl reboot
;;
*Shutdown*)
loginctl poweroff
;;
esac
+4
View File
@@ -0,0 +1,4 @@
#!/bin/sh
awesome-client 'show_dim()'
rofi -show drun "$@"
awesome-client 'hide_dim()'
-30
View File
@@ -1,30 +0,0 @@
#!/bin/bash
# ---------------------------------------------------------------------------------
# Docker install recipe
# ---------------------------------------------------------------------------------
set -e
echo "Removing old Docker packages if present..."
sudo apt-get remove -y docker docker-engine docker.io containerd runc 2>/dev/null || true
echo "Adding Docker signing key..."
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "Adding Docker repository..."
bash -c 'echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null'
echo "Installing Docker..."
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
echo "Adding current user to docker group..."
sudo groupadd docker 2>/dev/null || true
sudo usermod -aG docker $USER
echo ""
echo "✓ Docker install complete."
echo "Log out and back in for group changes to take effect."
-77
View File
@@ -1,77 +0,0 @@
#!/bin/bash
# ---------------------------------------------------------------------------------
# Golang install recipe
# Fetches the latest stable Go release, installs to /usr/local/go,
# then installs go-based CLI tools.
# ---------------------------------------------------------------------------------
set -e
# ---------------------------------------------------------------------------------
# Detect architecture
# ---------------------------------------------------------------------------------
ARCH=$(dpkg --print-architecture)
case "$ARCH" in
amd64) GO_ARCH="amd64" ;;
arm64) GO_ARCH="arm64" ;;
*)
echo "❌ Unsupported architecture: $ARCH"
exit 1
;;
esac
# ---------------------------------------------------------------------------------
# Fetch latest stable Go version
# ---------------------------------------------------------------------------------
echo "🔍 Fetching latest stable Go version..."
GO_VERSION=$(curl -fsSL "https://go.dev/dl/?mode=json" | grep -o '"version":"go[^"]*"' | head -1 | grep -o 'go[0-9.]*')
if [ -z "$GO_VERSION" ]; then
echo "❌ Failed to fetch latest Go version."
exit 1
fi
echo "✅ Latest Go version: $GO_VERSION"
# ---------------------------------------------------------------------------------
# Download and install
# ---------------------------------------------------------------------------------
TARBALL="${GO_VERSION}.linux-${GO_ARCH}.tar.gz"
DOWNLOAD_URL="https://go.dev/dl/${TARBALL}"
echo "📦 Downloading $TARBALL..."
curl -fsSL "$DOWNLOAD_URL" -o "/tmp/${TARBALL}"
echo "📂 Installing to /usr/local/go..."
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "/tmp/${TARBALL}"
rm "/tmp/${TARBALL}"
# ---------------------------------------------------------------------------------
# Verify install
# ---------------------------------------------------------------------------------
export PATH=$PATH:/usr/local/go/bin
echo "🔍 Verifying Go install..."
/usr/local/go/bin/go version
# ---------------------------------------------------------------------------------
# Install Go-based CLI tools
# ---------------------------------------------------------------------------------
echo ""
echo "📦 Installing Go-based CLI tools..."
echo " → gopls"
go install golang.org/x/tools/gopls@latest
echo " → lazydocker"
go install github.com/jesseduffield/lazydocker@latest
echo " → lf"
env CGO_ENABLED=0 go install -trimpath -ldflags="-s -w" github.com/gokcehan/lf@latest
echo ""
echo "✅ Golang setup complete."
echo " Restart your shell or run: source ~/.config/fish/config.fish"
-83
View File
@@ -1,83 +0,0 @@
#!/bin/bash
# ---------------------------------------------------------------------------------
# Kanata install recipe
# Downloads the latest Linux binary from GitHub, installs to ~/.local/bin,
# and sets up a systemd user service.
# ---------------------------------------------------------------------------------
set -e
INSTALL_DIR="$HOME/.local/bin"
CONFIG_DIR="$HOME/.config/kanata"
SERVICE_PATH="/lib/systemd/system/kanata.service"
BINARY_NAME="kanata"
# ---------------------------------------------------------------------------------
# Fetch latest release version from GitHub API
# ---------------------------------------------------------------------------------
echo "🔍 Fetching latest Kanata release..."
LATEST_VERSION=$(curl -fsSL "https://api.github.com/repos/jtroo/kanata/releases/latest" | grep '"tag_name"' | head -1 | grep -o 'v[0-9.]*')
if [ -z "$LATEST_VERSION" ]; then
echo "❌ Failed to fetch latest Kanata version."
exit 1
fi
echo "✅ Latest Kanata version: $LATEST_VERSION"
# ---------------------------------------------------------------------------------
# Download binary
# ---------------------------------------------------------------------------------
DOWNLOAD_URL="https://github.com/jtroo/kanata/releases/download/${LATEST_VERSION}/kanata_linux_x64"
echo "📦 Downloading kanata_linux_x64..."
mkdir -p "$INSTALL_DIR"
curl -fsSL "$DOWNLOAD_URL" -o "$INSTALL_DIR/$BINARY_NAME"
chmod +x "$INSTALL_DIR/$BINARY_NAME"
echo "✅ Installed: $INSTALL_DIR/$BINARY_NAME"
# ---------------------------------------------------------------------------------
# Verify a config file exists
# ---------------------------------------------------------------------------------
if [ ! -f "$CONFIG_DIR/kanata.kbd" ]; then
echo "⚠️ No config found at $CONFIG_DIR/kanata.kbd"
echo " Make sure your dotfiles are synced before enabling the service."
fi
# ---------------------------------------------------------------------------------
# Write systemd service file
# ---------------------------------------------------------------------------------
echo "⚙️ Writing systemd service to $SERVICE_PATH..."
sudo tee "$SERVICE_PATH" > /dev/null <<EOF
[Unit]
Description=Kanata keyboard remapper
Documentation=https://github.com/jtroo/kanata
[Service]
Type=simple
ExecStart=$INSTALL_DIR/$BINARY_NAME --cfg $CONFIG_DIR/kanata.kbd
Restart=never
[Install]
WantedBy=default.target
EOF
echo "✅ Service file written."
# ---------------------------------------------------------------------------------
# Enable and start the service
# ---------------------------------------------------------------------------------
echo "🚀 Enabling and starting kanata service..."
sudo systemctl daemon-reload
sudo systemctl enable kanata.service
sudo systemctl start kanata.service
echo ""
echo "✅ Kanata setup complete."
echo " Binary : $INSTALL_DIR/$BINARY_NAME"
echo " Config : $CONFIG_DIR/kanata.kbd"
echo " Service: systemctl status kanata"
-27
View File
@@ -1,27 +0,0 @@
#!/bin/bash
# ---------------------------------------------------------------------------------
# Raylib-go dependency install recipe
# Target: Debian 13 Trixie
# Installs system libs needed for github.com/gen2brain/raylib-go
# ---------------------------------------------------------------------------------
set -e
echo "Installing raylib-go system dependencies..."
sudo apt-get update
sudo apt-get install -y \
build-essential \
pkg-config \
libasound2-dev \
libx11-dev \
libxrandr-dev \
libxi-dev \
libxcursor-dev \
libxinerama-dev \
libgl1-mesa-dev \
libglu1-mesa-dev \
libwayland-dev \
libxkbcommon-dev
echo ""
echo "✓ Raylib-go dependencies installed."
echo ""
@@ -1,32 +1,22 @@
#!/bin/bash
# ---------------------------------------------------------------------------------
# Odin compiler install recipe
# Target: Debian 13 Trixie
# Target: Void Linux
# Builds from source - recommended method on Linux
# ---------------------------------------------------------------------------------
set -e
ODIN_DIR="$HOME/odin"
echo "Installing Odin build dependencies..."
sudo apt-get update
sudo apt-get install -y clang llvm lld
sudo xbps-install -Sy llvm18 llvm18-devel clang18 libstdc++-devel
echo "Cloning Odin repository..."
git clone https://github.com/odin-lang/Odin "$ODIN_DIR"
cd "$ODIN_DIR"
echo "Building Odin compiler..."
./build_odin.sh release
echo "Adding Odin to PATH..."
if ! grep -q 'odin' "$HOME/.bashrc"; then
echo "export PATH=\$PATH:$ODIN_DIR" >> "$HOME/.bashrc"
fi
LLVM_CONFIG=$(command -v llvm-config) make release-native
echo ""
echo "✓ Odin install complete."
echo " Compiler: $ODIN_DIR/odin"
echo ""
echo " Run: source ~/.bashrc (or open a new terminal)"
echo " Then verify with: odin version"
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
# ---------------------------------------------------------------------------------
# Golang install recipe
# Fetches the void php version
# then installs composer with php
# ---------------------------------------------------------------------------------
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."
+14
View File
@@ -0,0 +1,14 @@
#!/bin/bash
# ---------------------------------------------------------------------------------
# Raylib-go dependency install recipe
# Target: Void Linux
# Installs system libs needed for raylib to run
# ---------------------------------------------------------------------------------
set -e
echo "Installing raylib-go system dependencies..."
sudo xbps-install make alsa-lib-devel libglvnd-devel libX11-devel libXrandr-devel libXi-devel libXcursor-devel libXinerama-devel mesa MesaLib-devel
echo ""
echo "✓ Raylib-go dependencies installed."
echo ""
+35
View File
@@ -0,0 +1,35 @@
#!/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"