Compare commits

...

39 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
40 changed files with 1457 additions and 1806 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
+58 -49
View File
@@ -7,82 +7,91 @@ 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.sh # Dotfile symlinks and package installation
```
.
├── config/
│ ├── alacritty/ # Alacritty terminal configuration
│ ├── fish/ # Fish shell configuration
│ ├── kanata/ # Keyboard remapping
│ ├── lf/ # Terminal file manager
│ ├── nvim/ # Neovim setup
│ └── tmux/ # Tmux configuration
├── scripts/
│ ├── 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)
./install.sh
```sh
# Interactive mode (prompts for confirmation at each step)
./install.sh
# Only create symlinks
./install.sh -l
# Only create symlinks
./install.sh -l
# Only install packages
./install.sh -i
# 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 ""
+33 -58
View File
@@ -1,77 +1,52 @@
[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]
# startup_mode = "Maximized"
padding.x = 10
padding.y = 10
decorations = "None"
[cursor]
style.shape = "Beam"
style.blinking = "Always"
# THEME
# Kanagawa Wave Alacritty Colors
[colors.primary]
background = "#181818"
foreground = "#E4E4E4"
[colors.cursor]
text = "#0e0e0e"
cursor = "#d4a943"
[colors.vi_mode_cursor]
text = "#0e0e0e"
cursor = "#ebcb8b"
[colors.selection]
text = "#dddddd"
background = "#47464c"
[colors.search.matches]
foreground = "#dddddd"
background = "#47464c"
[colors.search.focused_match]
foreground = "#131314"
background = "#b8943a"
[colors.footer_bar]
foreground = "#dddddd"
background = "#131314"
[colors.hints.start]
foreground = "#131314"
background = "#ebcb8b"
[colors.hints.end]
foreground = "#131314"
background = "#b8943a"
[colors.line_indicator]
foreground = "None"
background = "None"
background = '#101010'
foreground = '#dcd7ba'
[colors.normal]
black = "#131314"
red = "#b38f8f"
green = "#a3be8c"
yellow = "#ebcb8b"
blue = "#6c7a8a"
magenta = "#b3a3d3"
cyan = "#6ac6f2"
white = "#dddddd"
black = '#090618'
red = '#c34043'
green = '#76946a'
yellow = '#c0a36e'
blue = '#7e9cd8'
magenta = '#957fb8'
cyan = '#6a9589'
white = '#c8c093'
[colors.bright]
black = "#444444"
red = "#d9a6a6"
green = "#a3be8c"
yellow = "#fbe4a8"
blue = "#8fa3b3"
magenta = "#d3a3d3"
cyan = "#8ac6f2"
white = "#ffffff"
black = '#727169'
red = '#e82424'
green = '#98bb6c'
yellow = '#e6c384'
blue = '#7fb4ca'
magenta = '#938aa9'
cyan = '#7aa89f'
white = '#dcd7ba'
[colors.selection]
background = '#2d4f67'
foreground = '#c8c093'
[[colors.indexed_colors]]
index = 16
color = '#ffa066'
[[colors.indexed_colors]]
index = 17
color = '#ff5d62'
+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",
}
+33 -22
View File
@@ -3,10 +3,19 @@
# ==============================================================================
# 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
@@ -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,37 +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 prj='cd ~/Projects/ && ll'
alias dots='cd ~/.dotfiles'
alias dotman='bash ~/.dotfiles/install.sh'
alias todo='cd ~/Todo/ && 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'
## Basic project picker using mini sessions and neovim
function pp
nvim -c "lua MiniSessions.select()"
set project (
find ~/Projects -mindepth 1 -maxdepth 1 -type d |
awk -F/ '{print $NF "\t" $0}' |
fzf --with-nth=1
)
if test -z "$project"
return
end
set project (echo $project | cut -f2)
cd $project && clear
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 &{{
-87
View File
@@ -1,87 +0,0 @@
" ==============================================================================
" Vim syntax file
" Language: C Additions
" Original Author: Mikhail Wolfson, Jon Haggblad <https://github.com/octol>
" Maintainer: bfrg <https://github.com/bfrg>
" Website: https://github.com/bfrg/vim-c-cpp-modern
" Last Change: Dec 25, 2025
" ==============================================================================
" Highlight additional keywords in the comments
syn keyword cTodo contained BUG NOTE
" Highlight function names
if get(g:, 'cpp_function_highlight', 1)
syn match cUserFunction "\<\h\w*\ze\_s\{-}(\%(\*\h\w*)\_s\{-}(\)\@!"
syn match cUserFunctionPointer "\%((\s*\*\s*\)\@6<=\h\w*\ze\s*)\_s\{-}(.*)"
hi def link cUserFunction Function
hi def link cUserFunctionPointer Function
endif
" Highlight C builtin types as Statement
if get(g:, 'cpp_builtin_types_as_statement', 1)
syntax keyword cBuiltinType int long short char void signed unsigned float double
hi def link cBuiltinType Statement
endif
" Highlight struct/class member variables
if get(g:, 'cpp_member_highlight', 1)
syn match cMemberAccess "\.\|->" nextgroup=cStructMember,cppTemplateKeyword
syn match cStructMember "\<\h\w*\>\%((\|<\)\@!" contained
syn cluster cParenGroup add=cStructMember
syn cluster cPreProcGroup add=cStructMember
syn cluster cMultiGroup add=cStructMember
hi def link cStructMember Identifier
if &filetype ==# 'cpp'
syn keyword cppTemplateKeyword template
hi def link cppTemplateKeyword cppStructure
endif
endif
" Highlight names in struct, union and enum declarations
if get(g:, 'cpp_type_name_highlight', 1)
syn match cTypeName "\%(\<\%(struct\|union\|enum\)\s\+\)\@8<=\h\w*"
hi def link cTypeName Type
if &filetype ==# 'cpp'
syn match cTypeName "\%(\<\%(class\|using\|concept\|requires\)\s\+\)\@10<=\h\w*"
endif
endif
" Highlight operators
if get(g:, 'cpp_operator_highlight', 1)
syn match cOperator "[?!~*&%<>^|=,+]"
syn match cOperator "[][]"
syn match cOperator "[^:]\@1<=:[^:]\@="
syn match cOperator "-[^>]"me=e-1
syn match cOperator "/[^/*]"me=e-1
endif
" Common ANSI-standard Names
syn keyword cAnsiName
\ PRId8 PRIi16 PRIo32 PRIu64 PRId16 PRIi32 PRIo64 PRIuLEAST8 PRId32 PRIi64 PRIoLEAST8 PRIuLEAST16 PRId64 PRIiLEAST8 PRIoLEAST16 PRIuLEAST32 PRIdLEAST8 PRIiLEAST16 PRIoLEAST32 PRIuLEAST64 PRIdLEAST16 PRIiLEAST32 PRIoLEAST64 PRIuFAST8 PRIdLEAST32 PRIiLEAST64 PRIoFAST8 PRIuFAST16 PRIdLEAST64 PRIiFAST8 PRIoFAST16 PRIuFAST32 PRIdFAST8 PRIiFAST16 PRIoFAST32 PRIuFAST64 PRIdFAST16 PRIiFAST32 PRIoFAST64 PRIuMAX PRIdFAST32 PRIiFAST64 PRIoMAX PRIuPTR PRIdFAST64 PRIiMAX PRIoPTR PRIx8 PRIdMAX PRIiPTR PRIu8 PRIx16 PRIdPTR PRIo8 PRIu16 PRIx32 PRIi8 PRIo16 PRIu32 PRIx64 PRIxLEAST8 SCNd8 SCNiFAST32 SCNuLEAST32 PRIxLEAST16 SCNd16 SCNiFAST64 SCNuLEAST64 PRIxLEAST32 SCNd32 SCNiMAX SCNuFAST8 PRIxLEAST64 SCNd64 SCNiPTR SCNuFAST16 PRIxFAST8 SCNdLEAST8 SCNo8 SCNuFAST32 PRIxFAST16 SCNdLEAST16 SCNo16 SCNuFAST64 PRIxFAST32 SCNdLEAST32 SCNo32 SCNuMAX PRIxFAST64 SCNdLEAST64 SCNo64 SCNuPTR PRIxMAX SCNdFAST8 SCNoLEAST8 SCNx8 PRIxPTR SCNdFAST16 SCNoLEAST16 SCNx16 PRIX8 SCNdFAST32 SCNoLEAST32 SCNx32 PRIX16 SCNdFAST64 SCNoLEAST64 SCNx64 PRIX32 SCNdMAX SCNoFAST8 SCNxLEAST8 PRIX64 SCNdPTR SCNoFAST16 SCNxLEAST16 PRIXLEAST8 SCNi8 SCNoFAST32 SCNxLEAST32 PRIXLEAST16 SCNi16 SCNoFAST64 SCNxLEAST64 PRIXLEAST32 SCNi32 SCNoMAX SCNxFAST8 PRIXLEAST64 SCNi64 SCNoPTR SCNxFAST16 PRIXFAST8 SCNiLEAST8 SCNu8 SCNxFAST32 PRIXFAST16 SCNiLEAST16 SCNu16 SCNxFAST64 PRIXFAST32 SCNiLEAST32 SCNu32 SCNxMAX PRIXFAST64 SCNiLEAST64 SCNu64 SCNxPTR PRIXMAX SCNiFAST8 SCNuLEAST8 PRIXPTR SCNiFAST16 SCNuLEAST16 STDC CX_LIMITED_RANGE STDC FENV_ACCESS STDC FP_CONTRACT
\ errno environ and bitor not_eq xor and_eq compl or xor_eq bitand not or_eq
" Booleans
syn keyword cBoolean true false TRUE FALSE
" Default highlighting
hi def link cBoolean Boolean
hi def link cAnsiName Identifier
" Highlight all standard C keywords as Statement
" This is very similar to what other IDEs and editors do
if get(g:, 'cpp_simple_highlight', 1)
hi! def link cStorageClass Statement
hi! def link cStructure Statement
hi! def link cTypedef Statement
hi! def link cLabel Statement
endif
-825
View File
@@ -1,825 +0,0 @@
" Author: Charles Pascoe
" License: MIT (see LICENSE)
" Copyright: 2022 Charles Pascoe
" Clear any existing syntax first
syntax clear
if !exists('main_syntax')
if exists("b:current_syntax") && !get(g:, "go_highlight_override_existing_syntax", 1)
finish
endif
let b:__vim_go_syntax = 1
endif
syntax clear
syntax case match
syntax sync fromstart
" Define 'iskeyword' to include valid UTF-8 multibyte characters, some of which
" are technically supported for identifiers.
" TODO: Check UTF-16
syntax iskeyword @,48-57,_,192-255
" TODO: Check performance of lookbehinds
" TODO: Check correct use of 'skipempty'
" Struct and Interface need 'extend' so that simple matches (e.g. /struct {/)
" can contain complex nested types by extending the parent match. No other types
" should use extend
" Some things use 'contains=TOP,@Spell' to allow them to behave predictably when
" they are nested within a region with special syntax elements (e.g.
" goVarDeclGroup and goConstDeclGroup) or when imported into other syntaxes.
" The '@Spell' is required to disable spelling in these items. Only a handful
" of things should use 'transparent'.
" Config Utils {{{
let s:cleanup = []
com! -nargs=* GoDeferCleanup call add(s:cleanup, <q-args>)
GoDeferCleanup delcom GoDeferCleanup
fun s:Cleanup()
for l:cmd in s:cleanup
exec l:cmd
endfor
endfun
fun s:getconfig(keys, default)
if len(a:keys) == 0
return a:default
else
return get(g:, a:keys[0], s:getconfig(a:keys[1:], a:default))
endif
endfun
fun s:HiConfig(group, option_names, opts={})
" Most syntax is highlighted by default, unless turned off by the user
let l:opt = s:getconfig(a:option_names, get(a:opts, 'default', 1))
let l:cmd = ''
if type(l:opt) == v:t_string
if l:opt =~ '^[[:alnum:]]\+$'
exec 'hi link '.a:group.' '.l:opt
else
exec 'hi '.a:group.' '.l:opt
endif
return 1
elseif !l:opt
exec 'hi link '.a:group.' '.get(a:opts, 'offgroup', 'NONE')
endif
return l:opt
endfun
if get(g:, 'go_highlight_string_spellcheck', 1)
syntax cluster goStringSpell contains=@Spell
endif
if get(g:, 'go_highlight_comment_spellcheck', 1)
syntax cluster goCommentSpell contains=@Spell
endif
" TODO: Rethink this approach (use string/array approach)
if s:getconfig(['go_fold_function_blocks', 'go_syntax_fold'], 1)
com! -nargs=* GoFoldFunc <args> fold
else
com! -nargs=* GoFoldFunc <args>
endif
GoDeferCleanup delcom GoFoldFunc
if s:getconfig(['go_fold_struct_blocks', 'go_syntax_fold'], 1)
com! -nargs=* GoFoldStruct <args> fold
else
com! -nargs=* GoFoldStruct <args>
endif
GoDeferCleanup delcom GoFoldStruct
if s:getconfig(['go_fold_interface_blocks', 'go_syntax_fold'], 1)
com! -nargs=* GoFoldInterface <args> fold
else
com! -nargs=* GoFoldInterface <args>
endif
GoDeferCleanup delcom GoFoldInterface
if s:getconfig(['go_fold_decl_blocks', 'go_syntax_fold'], 1)
com! -nargs=* GoFoldDecl <args> fold
else
com! -nargs=* GoFoldDecl <args>
endif
GoDeferCleanup delcom GoFoldDecl
" }}} Config Utils
" Misc {{{
" Two top-level clusters to allow regions to specify what syntax they can
" contain
" NOTE: goIota technically shouldn't be here (it should only be a part of a
" const declaration group), but trying to get it to appear only in
" goConstDeclGroup would require compromising the performance of the current
" implementation or duplicating goExpr just for goConstDeclGroup.
syntax cluster goExpr contains=@goLiteral,goForRange,goDotExpr,goFuncLiteral,goCommaExpr,goOperator,goWordStart,goParenBlock,goBracketBlock,goComment,goIota
syntax cluster goStatement contains=@goExpr,@goFlowControl,goReturn,goSemicolon,goBraceBlock,goStatementStart,goConstDecl,goVarDecl,goTypeDecl,goKeywords
" 'goWordStart' reduces the number of times each of the 'nextgroups' is checked,
" but also prevents 'goImportedPackages' (a keyword syntax element) from
" overriding matches (e.g. in 'goStructLiteralField').
syntax match goWordStart /\<\ze\K/ contained nextgroup=goStructLiteral,goFuncCall,goBuiltins,goMakeBuiltin,goNewBuiltin,goImportedPackages
" 'goDotExpr' matches a dot that is found as a part of an expression, whereas
" 'goDot' is used to highlight a dot in non-expression contexts (e.g. the dot
" between a package and a type). 'goDotExpr' significantly improves the
" performance of searching for fields and type assertions.
syntax match goDot /\./ contained
syntax match goDotExpr /\./ nextgroup=@goDotExpr skipwhite skipnl
" The cluster of items that could follow a dot in an expression
syntax cluster goDotExpr contains=goFuncCall,goStructLiteral,goTypeAssertion,goField,goDotComment
" goDotComment is identical to goComment, except it doesn't break field
" highlighting across multiple lines, e.g.:
"
" foo.bar.
" baz.
" // This is goDotComment instead of a goComment
" blah
"
" Both 'baz' and 'blah' are correctly highlighted as fields
syntax region goDotComment start=+//+ end=+$+ contained contains=@goCommentSpell,goCommentTodo keepend skipwhite skipnl nextgroup=@goDotExpr
syntax region goDotComment start=+/\*+ end=+\*/+ contained contains=@goCommentSpell,goCommentTodo keepend skipwhite skipnl nextgroup=@goDotExpr
syntax match goField /\K\k*/ contained
" TODO: Only valid operators?
syntax match goAssign /=/ skipwhite nextgroup=@goExpr
syntax match goOperator /[-+*/!:=%&^<>|~]\+/ skipwhite nextgroup=@goExpr
syntax match goCommaExpr /,/ skipwhite skipnl nextgroup=@goExpr
syntax match goComma /,/ contained
syntax match goSemicolon /;/
syntax keyword goUnderscore _
hi link goField Identifier
hi link goLabel Label
hi link goOperator Operator
hi link goAssign goOperator
hi link goDot goOperator
hi link goComma Delimiter
hi link goCommaExpr goComma
hi link goSemicolon Delimiter
hi link goUnderscore Special
hi link goDotExpr goDot
hi link goDotComment goComment
call s:HiConfig('goField', ['go_highlight_fields'], #{default: 1})
call s:HiConfig('goLabel', ['go_highlight_labels'])
call s:HiConfig('goOperator', ['go_highlight_operators'])
call s:HiConfig('goDot', ['go_highlight_dot'])
call s:HiConfig('goComma', ['go_highlight_comma'], #{default: 1})
call s:HiConfig('goSemicolon', ['go_highlight_semicolon'], #{default: 1})
" }}} Misc
" Comments {{{
syntax region goComment start=+//+ end=+$+ contains=@goCommentSpell,goCommentTodo,goDirectiveComment keepend
syntax region goComment start=+/\*+ end=+\*/+ contains=@goCommentSpell,goCommentTodo keepend
syntax keyword goCommentTodo contained TODO FIXME XXX TBD NOTE
syntax region goDirectiveComment start=+//\(line \|extern \| export\|[a-z0-9]\+:[a-z0-9]\+\)+ end=+$+ contained
hi link goComment Comment
hi link goCommentTodo Todo
hi link goDirectiveComment PreProc
call s:HiConfig('goGenerateComment', ['go_highlight_generate_tags'], #{offgroup: 'goComment'})
" }}} Comments
" Literals {{{
syntax cluster goLiteral contains=goString,goRawString,goInvalidRuneLiteral,goNumberLeader,goBooleanTrue,goBooleanFalse,goNil,goSliceOrArrayLiteral,goPrimitiveTypes,goStructType,goInterfaceType,goMapLiteral,goSliceOrArrayLiteral
" Strings
syntax region goString matchgroup=goStringEnds start='"' skip=/\\\\\|\\"/ end='"\|$' oneline contains=@goStringSpell,goStringEscape,goDoubleQuoteEscape,goStringFormat
syntax match goStringEscape /\v\\%(\o{3}|x\x{2}|u\x{4}|U\x{8}|[abfnrtv\\"])/ contained
syntax match goStringFormat /\v\%%(\%|[-+# 0]*%([1-9]\d*|%(\[\d+\])?\*)?%(\.%(\d+|%(\[\d+\])?\*)?)?%(\[\d+\])?[EFGOTUXbcdefgopqstwvxf])/ contained contains=goStringFormatInvalidIndex
if s:getconfig(['go_highlight_format_string_errors'], 0)
syntax match goStringFormatInvalidIndex /\[0\]/ contained
hi link goStringFormatInvalidIndex Error
endif
" 'goInvalidRuneLiteral' is a loose match for all single-quote sequences; they
" are highlighted as errors. If they contain a valid 'goRuneLiteral' or the
" cursor is present at the end, then the 'goRuneLiteral' highlighting will
" override the 'goInvalidRuneLiteral' highlighting and thus look like a string.
syntax region goInvalidRuneLiteral start=+'+ skip=+\\.+ end=+'+ keepend oneline contains=goRuneLiteral
syntax match goRuneLiteral /\v'%(.*%#|[^\\]|\\%(\o{3}|x\x{2}|u\x{4}|U\x{8}|[abfnrtv\\']))'/ contained contains=goRuneLiteralEscape
syntax match goRuneLiteralEscape /\v\\%(\o{3}|x\x{2}|u\x{4}|U\x{8}|[abfnrtv\\'])/ contained
syntax region goRawString matchgroup=goRawStringEnds start='`' end='`' keepend
" Numbers
" 'goNumberZeroLeader' searches for a digit so that the various number patterns
" don't have to, improving match performance
syntax match goNumberLeader /\ze\<[0-9]/ nextgroup=goNumber,goNumberTypeBinary,goNumberTypeOctal,goNumberTypeHex
syntax match goNumberLeader /\ze\.[0-9]/ nextgroup=goNumber
" TODO: Highlight all forms of invalid number formatting? E.g. underscores in
" certain places
" TODO: Highlight floats differently
syntax match goNumber /\v<[0-9][0-9_]*%(\.[0-9_]*)?%([eE][-+]?[0-9][0-9_]*)?i?/ contained contains=goNumberDecimalExp
syntax match goNumber /\v\.[0-9][0-9_]*%([eE][-+]?[0-9][0-9_]*)?i?/ contained contains=goNumberDecimalExp
syntax match goNumberTypeBinary /\c0b/ contained nextgroup=goNumberBinary
syntax match goNumberBinary /[01_]\+i\?/ contained
syntax match goNumberTypeOctal /\c0o/ contained nextgroup=goNumberOctal
syntax match goNumberOctal /[0-7_]\+i\?/ contained
syntax match goNumberTypeHex /\c0x/ contained nextgroup=goNumberHex
syntax match goNumberHex /\v\c[0-9a-f_]*%(\.[0-9a-f_]*)?%([pP][-+]?[0-9a-f][0-9a-f_]*)?i?/ contained contains=goNumberHexExp
syntax match goNumberSpecialChar /[_i]/ contained containedin=goNumber,goNumberBinary,goNumberOctal,goNumberHex
syntax match goNumberError /_\{2,\}/ contained containedin=goNumber,goNumberBinary,goNumberOctal,goNumberHex
" Exponent markers
syntax match goNumberDecimalExp /\ce/ contained
syntax match goNumberHexExp /\cp/ contained
" Other
syntax keyword goBooleanTrue true
syntax keyword goBooleanFalse false
syntax keyword goNil nil
" Highlighting
hi link goString String
hi link goStringEnds goString
hi link goStringEscape SpecialChar
hi link goStringFormat SpecialChar
hi link goInvalidRuneLiteral Error
hi link goRuneLiteral Character
hi link goRuneLiteralEscape goStringFormat
hi link goRawString String
hi link goRawStringEnds goRawString
hi link goNumber Number
hi link goNumberBinary goNumber
hi link goNumberOctal goNumber
hi link goNumberHex goNumber
hi link goNumberType SpecialChar
hi link goNumberTypeBinary goNumberType
hi link goNumberTypeOctal goNumberType
hi link goNumberTypeHex goNumberType
hi link goNumberError Error
hi link goNumberDecimalExp SpecialChar
hi link goNumberHexExp goNumberDecimalExp
hi link goNumberSpecialChar SpecialChar
hi link goBooleanTrue Boolean
hi link goBooleanFalse Boolean
hi link goNil Constant
call s:HiConfig('goStringFormat', ['go_highlight_format_strings'], #{offgroup: 'goString'})
call s:HiConfig('goInvalidRuneLiteral', ['go_highlight_rune_literal_error'], #{offgroup: 'goRuneLiteral'})
" TODO: Config for highlighting special chars in numbers
" }}} Literals
" Simple Blocks {{{
syntax region goBracketBlock matchgroup=goBrackets start='\[' end='\]' transparent extend
syntax region goParenBlock matchgroup=goParens start='(' end=')' transparent extend
syntax region goBraceBlock matchgroup=goBraces start='{' end='}' transparent extend
hi link goBraces Delimiter
hi link goBrackets Delimiter
hi link goParens Delimiter
call s:HiConfig('goBraces', ['go_highlight_braces'])
call s:HiConfig('goBrackets', ['go_highlight_brackets'])
call s:HiConfig('goParens', ['go_highlight_parens'])
" }}} Simple Blocks
" Constants and Variables {{{
" TODO Slice/map assignment?
syntax match goVarAssign /\<\K\k*\%(\.\K\k*\)*\%(\s*,\s*\%(\K\k*\%(\.\K\k*\)*\)\?\)*\ze\s*\%(<<\|>>\|&^\|[-+*/%&|^]\)\?=[^=]/ contained contains=goComma,goUnderscore,goVarStructAssign skipwhite nextgroup=goOperator
syntax match goShortVarDecl /\<\K\k*\%(\s*,\s*\%(\K\k*\)\?\)*\ze\s*:=/ contained contains=goComma,goUnderscore skipwhite nextgroup=goOperator
syntax match goVarStructAssign /\<\K\k*\%(\.\K\k*\)\+/ contained contains=goDotExpr
" TODO: Should these be skipempty instead of skipnl?
syntax keyword goConstDecl const skipwhite skipnl nextgroup=goVarIdentifier,goConstDeclGroup
syntax keyword goVarDecl var skipwhite skipnl nextgroup=goVarIdentifier,goVarDeclGroup
" TODO: Remove these once you're certain goVarGroupIdentifier is not needed
" syntax region goVarDeclGroup matchgroup=goVarDeclParens start='(' end=')' contained contains=@goExpr,goComment,goSemicolon,goVarGroupIdentifier
" syntax region goConstDeclGroup matchgroup=goConstDeclParens start='(' end=')' contained contains=@goExpr,goComment,goSemicolon,goVarGroupIdentifier,goIota
GoFoldDecl syntax region goVarDeclGroup matchgroup=goVarDeclParens start='(' end=')' contained contains=@goExpr,goSemicolon,goVarIdentifier
GoFoldDecl syntax region goConstDeclGroup matchgroup=goConstDeclParens start='(' end=')' contained contains=@goExpr,goSemicolon,goVarIdentifier
" TODO: Is it worth supporting comments in goVarComma??
syntax match goVarIdentifier /\<\K\k*/ contained skipwhite nextgroup=goVarComma,@goType
syntax match goVarComma /,/ contained skipwhite skipnl nextgroup=goVarIdentifier
" TODO: Remove these once you're certain goVarGroupIdentifier is not needed
" " goVarGroupIdentifier finds positions inside a var/const declaration group
" " (e.g. 'const (...)') that may be followed by an identifier. Prevents
" " goVarIdentifier from matching in the wrong places.
" syntax match goVarGroupIdentifier /^\ze\s/ contained nextgroup=goVarIdentifier skipwhite
" syntax match goVarGroupIdentifier /[(;]\@1<=\ze\s/ contained nextgroup=goVarIdentifier skipwhite
" syntax match goVarGroupIdentifier /[(;]\@1<=\ze\<\K/ contained nextgroup=goVarIdentifier
syntax keyword goIota iota contained
hi link goConstDecl Statement
hi link goVarDecl Statement
hi link goConstDeclParens goParens
hi link goVarDeclParens goParens
hi link goVarIdentifier Identifier
hi link goVarComma goComma
hi link goVarGroupIdentifier goVarIdentifier
hi link goShortVarDecl Identifier
hi link goVarAssign Special
hi link goIota Special
let s:assignOrShortDecl = 0
" goStatementStart ideally shouldn't contain goSwitchKeywords, but the without
" this, `default:` will be highlighted using `goLabel` instead of `goSwitchKeywords`.
syntax cluster goStatementStartGroup contains=goLabel,goSwitchKeywords
call s:HiConfig('goVarIdentifier', ['go_highlight_variable_declarations'])
if s:HiConfig('goVarAssign', ['go_highlight_variable_assignments'], #{default: 1})
let s:assignOrShortDecl = 1
syntax cluster goStatementStartGroup add=goVarAssign
endif
if s:HiConfig('goShortVarDecl', ['go_highlight_short_variable_declarations','go_highlight_variable_declarations'])
let s:assignOrShortDecl = 1
syntax cluster goStatementStartGroup add=goShortVarDecl
endif
if s:assignOrShortDecl
" This lookbehind is checked for a lot of characters in the file, which is
" why goStatementStart is conditional and only added if needed. Splitting
" this into two makes it slightly faster overall.
" Note: the pattern /[{;]\@1<=/ seems to be equivalent to /[{;]\@1<=./
" which is why it had such poor performance and conflict with other
" patterns; splitting it into two specific patterns works better
syntax match goStatementStart /[{;]\@1<=\ze\s/ contained skipwhite nextgroup=@goStatementStartGroup
syntax match goStatementStart /[{;]\@1<=\ze\<\K/ contained skipwhite nextgroup=@goStatementStartGroup
endif
syntax match goStatementStart /^\ze\s/ contained skipwhite nextgroup=@goStatementStartGroup
syntax match goStatementStart /^\ze\<\K/ contained nextgroup=@goStatementStartGroup
" }}} Constants and Variables
" Packages {{{
syntax keyword goPackage package
syntax keyword goImport import skipwhite nextgroup=goImportItem,goImports
syntax region goImports matchgroup=goImportParens start='(' end=')' contained contains=goImportItem,goComment
syntax match goImportItem /\(\([\._]\|\K\k*\)\s\+\)\?"[^"]*"/ contained contains=goImportString
syntax region goImportString start='"' end='"' keepend contained
hi link goPackage Keyword
hi link goImport Keyword
hi link goImportItem Special
hi link goImportString goString
hi link goImportParens goParens
" }}} Packages
" Types {{{
syntax cluster goType contains=goPrimitiveTypes,goFuncType,goStructType,goInterfaceType,goMapType,goSliceOrArrayType,goChannel,goNonPrimitiveType,goPointer,goTypeParens
syntax match goPointer /*/ contained nextgroup=@goType
" goTypeParens is used to ensure types within parens are highlighted correctly,
" e.g. the func type in the slice literal `[](func (a, b int) bool){ ... }`
syntax region goTypeParens start='(' end=')' contained contains=@goType,goComment
syntax keyword goTypeDecl type skipwhite skipnl nextgroup=goTypeDeclName,goTypeDeclGroup
syntax match goTypeDeclName /\K\k*/ contained skipwhite skipnl nextgroup=goTypeDeclTypeParams,goTypeAssign,@goType
syntax match goTypeAssign /=/ contained skipwhite nextgroup=@goType
syntax region goTypeDeclGroup matchgroup=goTypeDeclGroupParens start='(' end=')' contained contains=goTypeDeclName,goComment
syntax region goTypeDeclTypeParams matchgroup=goTypeParamBrackets start='\[' end='\]' contained contains=goTypeParam,goComma,goComment skipwhite skipnl nextgroup=@goType
" goNonPrimitiveType is used for matching the names and packages of
" non-primitive types (i.e. types other than int, bool, string, etc.). Note the
" optional non-capturing group is later in the pattern to avoid backtracking.
syntax match goNonPrimitiveType /\<\K\k*\%(\.\K\k*\)\?\[\?/ contained contains=goPackageName,goTypeArgs
syntax match goPackageName /\<\K\k*\ze\./ contained nextgroup=goDot
syntax region goTypeArgs matchgroup=goTypeParamBrackets start='\[' end='\]' contained contains=@goType,goUnderscore,goComma,goComment
syntax keyword goPrimitiveTypes any bool byte complex128 complex64 error float32 float64 int int8 int16 int32 int64 rune string uint uint8 uint16 uint32 uint64 uintptr contained
syntax match goFuncType /func\s*(/ contained contains=goFuncTypeParens skipwhite nextgroup=@goType,goFuncTypeMultiReturnType
syntax region goFuncTypeParens matchgroup=goFuncParens start='(' end=')' contained contains=goFuncParam,goComma,goComment
syntax region goFuncTypeMultiReturnType matchgroup=goFuncMultiReturnParens start='(' end=')' contained contains=goNamedReturnValue,goComma,goComment
syntax keyword goMapType map contained skipwhite skipempty nextgroup=goMapTypeKeyType
syntax region goMapTypeKeyType matchgroup=goMapBrackets start='\[' end='\]' contained contains=@goType skipwhite nextgroup=@goType
syntax keyword goMapLiteral map contained skipwhite skipempty nextgroup=goMapLiteralKeyType
syntax region goMapLiteralKeyType matchgroup=goMapBrackets start='\[' end='\]' contained contains=@goType skipwhite nextgroup=goMapLiteralValueType
" See comment for goSliceOrArrayLiteralType, which serves the same function as goMapLiteralValueType
syntax region goMapLiteralValueType start='\S' end='\ze[{(]\|$' contained contains=goSliceMapLiteralTypeMatch skipwhite skipnl nextgroup=goMapLiteralItems
syntax region goMapLiteralItems matchgroup=goMapBraces start='{' end='}' contained contains=goStructLiteralBlock,@goExpr
syntax match goSliceOrArrayType /\[\%(\d\+\|\.\.\.\)\?\]/ contained contains=goNumber,goDot skipwhite nextgroup=@goType
" A lookbehind is used to distinguish a slice/array literal with slice indexing
syntax match goSliceOrArrayLiteral /\k\@1<!\[[0-9.]*\]\ze\%(\*\|\K\|\[\|(\)/ contained contains=goNumber,goDot skipwhite nextgroup=goSliceLiteralType
" goSliceOrArrayLiteralType allows matching complex types for slice literals
" such as a slice of functions without parentheses, e.g. "[]func(a, b Foo) Bar {
" f1, f2, f3 }", which is technically valid, albeit hard to read. The use of a
" region allows the contained matches (goSliceMapLiteralTypeMatch) to extend the
" region as necessary, allowing the type to contain braces, such as "[]struct{X,
" Y int}{ ... }"
syntax region goSliceLiteralType start='\S' end='\ze[{()]\|$' contained contains=goSliceMapLiteralTypeMatch skipwhite skipnl nextgroup=goSliceItems
syntax match goSliceMapLiteralTypeMatch /(\|\%(\%(interface\|struct\)\s*{\|[^{()]\)\+/ contained contains=@goType
syntax region goSliceItems matchgroup=goSliceBraces start='{' end='}' contained contains=goStructLiteralBlock,@goExpr
syntax match goChannel /<-chan/ contained contains=goChannelDir skipwhite nextgroup=@goType
syntax match goChannel /chan\%(<-\)\?/ contained contains=goChannelDir skipwhite nextgroup=@goType
syntax match goChannelDir /<-/ contained
hi link goPointer goOperator
" goTypeDecl should technically link to Typedef, but it looks a bit odd.
hi link goTypeDecl Keyword
hi link goTypeParens goParens
hi link goTypeDeclGroupParens goParens
hi link goTypeDeclName Type
hi link goTypeParamBrackets goBrackets
hi link goTypeAssign goOperator
hi link goPackageName Special
hi link goNonPrimitiveType Type
hi link goPrimitiveTypes Type
hi link goMapType goPrimitiveTypes
hi link goMapLiteral goPrimitiveTypes
hi link goMapBrackets Delimiter
hi link goSliceOrArrayLiteral Delimiter
hi link goSliceOrArrayType goSliceOrArrayLiteral
hi link goSliceBraces goBraces
hi link goMapBraces goBraces
hi link goChannel Type
hi link goChannelDir goOperator
hi link goFuncType Keyword
" See 'Functions' for other function highlight groups
call s:HiConfig('goTypeDeclName', ['go_highlight_types'])
call s:HiConfig('goSliceOrArrayLiteral', ['go_highlight_slice_brackets'])
call s:HiConfig('goMapBrackets', ['go_highlight_map_brackets'])
" }}} Types
" Functions {{{
" Unfortunately limited to at most 3 nested type args
syntax match goFuncCall /\v\K\k*\ze%(\(|\[\s*\n?%(,\n|[^\[\]]|\[\s*\n?%(,\n|[^\[\]]|\[[^\[\]]*\])*\])*\]\()/ contained nextgroup=goFuncCallTypeArgs,goFuncCallArgs
syntax region goFuncCallTypeArgs matchgroup=goTypeParamBrackets start='\[' end='\]' contained contains=@goType,goUnderscore,goComma,goComment nextgroup=goFuncCallArgs
syntax region goFuncCallArgs matchgroup=goFuncCallParens start='(' end=')' contained contains=@goExpr,goComment,goArgSpread
syntax keyword goFuncDecl func skipwhite skipempty nextgroup=goFuncName,goMethodReceiver
syntax keyword goFuncLiteral func contained skipwhite skipempty nextgroup=goFuncName,goFuncParams
syntax match goVariadic /\.\.\./ contained skipwhite nextgroup=@goType
syntax match goArgSpread /\.\.\./ contained
syntax match goFuncName /\K\k*/ contained skipwhite nextgroup=goFuncTypeParams,goFuncParams
syntax region goFuncTypeParams matchgroup=goTypeParamBrackets start='\[' end='\]' contained contains=goTypeParam,goComma,goComment nextgroup=goFuncParams
syntax match goTypeParam /\K\k*/ contained skipwhite skipempty nextgroup=goTypeParamComma,goTypeConstraint
syntax match goTypeParamComma /,/ contained skipwhite skipempty nextgroup=goTypeParam
" This is a region to allow use of types that have commas (e.g. function
" definitions) or nested type parameters, because they will automatically extend
" the match of the region
syntax region goTypeConstraint start='\s'ms=e+1 end=/[,\]]/me=s-1 contained contains=@goType,goTypeConstraintSymbols
syntax match goTypeConstraintSymbols /[~|]/ contained
" This is odd, but the \s*\zs at the start seems to ensure that the (\@1<!
" negative lookbehind works as desired (i.e. to not steal a match from
" goFuncMultiReturn); look into this further and try to remove this.
syntax match goFuncReturnType /\s*\zs(\@1<!\%(\%(interface\|struct\)\s*{\|[^{]\)\+/ contained contains=@goType skipwhite skipempty nextgroup=goFuncBlock
syntax region goFuncParams matchgroup=goFuncParens start='(' end=')' contained contains=goFuncParam,goComma,goComment skipwhite nextgroup=goFuncReturnType,goFuncMultiReturn,goFuncBlock
syntax region goFuncMultiReturn matchgroup=goFuncMultiReturnParens start='(' end=')' contained contains=goNamedReturnValue,goComma,goComment skipwhite skipempty nextgroup=goFuncBlock
syntax region goMethodReceiver matchgroup=goReceiverParens start='(' end=')' contained contains=goFuncParam,goComment skipwhite skipempty nextgroup=goFuncName
GoFoldFunc syntax region goFuncBlock matchgroup=goFuncBraces start='{' end='}' contained contains=@goStatement skipwhite nextgroup=goFuncCallArgs
" Previous versions (delete later)
" syntax match goFuncParam /\%(^\|[(,]\)\@1<=\s*\zs\%(\%(\K\k*\s*,\%(\s\|\n\)*\)*\%(chan\>\)\@!\K\k*\s\+\)\?\ze[^,]/ contained contains=goComma skipwhite nextgroup=@goType,goVariadic
" syntax match goFuncParam /\%(^\|[(,]\)\@1<=\s*\zs\%(\%(\K\k*\s*,\%(\s\|\n\)*\)*\%(chan\>\)\@!\K\k*\)\%(\s*,\?\%(\s\|\n\)*\%#\|\s\+\ze[^,]\)/ contained contains=goComma,goUnderscore skipwhite nextgroup=@goType,goVariadic
" syntax match goFuncParam /\%(^\|[(,]\)\@1<=\s*\zs\%(\%(\K\k*\s*,\%(\s\|\n\)*\)*\%(chan\>\)\@!\K\k*\)\%(\s*,\?\%(\s\|\n\)*\%#\ze)\|\s\+\ze[^,]\)/ contained contains=goComma,goUnderscore skipwhite nextgroup=@goType,goVariadic
" TODO: Peformance: Figure out how to eliminate at least the first \ze in
" '\ze)', because it more than doubles the time it takes to match this regex.
" ')\@1<=' didn't work for some reason (i.e. when typing a parameter name, it
" was highlighted as a type).
"
" goFuncParam: Assume the user is typing a parameter name (i.e. avoid
" highlighting parameter names as types until proven otherwise).
" conditional group allows skipping directly to type, e.g. func(SomeType) "
" ┌───────────────────────────────────────────────────────────────────────────────────────────────────┐ "
syntax match goFuncParam /\%(^\|[(,]\)\@1<=\s*\zs\%(\%(\%(\K\k*\s*,\%(\s\|\n\)*\)*\%(chan\>\)\@!\K\k*\)\%(\s*,\?\%(\s\|\n\)*\%#\ze)\|\s\+\ze[^,]\)\)\?/ contained contains=goComma,goUnderscore skipwhite nextgroup=@goType,goVariadic
" └──────────────────┘ │ └──────────────┘ │└────────────┘ │└────────────────┘ │ │ │ "
" Param must be preceded │ comma/ws/nl │ 'chan' a type, │ comma/ws/nl │ │ │ "
" by start of line, '(', │ │ not param name │ │ │ │ "
" or ',' followed by └────────────────────────────┘ └────────────────────────┘ └───────────┘ "
" whitespace zero or more previous params if this matches, then we otherwise if this "
" (e.g. 'a, b, ' in 'a, b, c') have one or more params, matches, we have "
" then cursor, then close params then type, "
" paren, e.g.: e.g.: "
" (a, b, c, |) (a, b foo) "
" The above diagrams can be found in the Monodraw file goFuncParam_Diagrams.monopic
" goFuncParam: Assume the user is typing a type (i.e. avoid highlighting custom
" types as return value names until proven otherwise)
syntax match goNamedReturnValue /\%(^\|[(,]\)\@1<=\s*\zs\%(\%(\K\k*\s*,\%(\s\|\n\)*\)*\%(chan\>\)\@!\K\k*\s\+\)\?\ze[^,]/ contained contains=goComma skipwhite nextgroup=@goType
syntax keyword goReturn return contained
hi link goFuncName Function
hi link goFuncCall Function
hi link goFuncCallParens goParens
hi link goFuncDecl goFuncType
hi link goFuncLiteral goFuncDecl
hi link goFuncParens goParens
hi link goFuncBraces goBraces
hi link goFuncMultiReturnParens goParens
hi link goReceiverParens goFuncParens
hi link goVariadic goOperator
hi link goArgSpread goVariadic
hi link goTypeParam Identifier
hi link goTypeParamComma goComma
hi link goFuncParam Identifier
hi link goNamedReturnValue NONE
hi link goReturn Statement
call s:HiConfig('goFuncCall', ['go_highlight_function_calls'])
call s:HiConfig('goFuncName', ['go_highlight_functions'])
call s:HiConfig('goFuncParens', ['go_highlight_function_parens'])
call s:HiConfig('goFuncBraces', ['go_highlight_function_braces'])
call s:HiConfig('goFuncParam', ['go_highlight_function_parameters'])
call s:HiConfig('goTypeParam', ['go_highlight_type_parameters'])
" }}} Functions
" Structs and Interfaces {{{
" Note: 'goStructTypeBlock' has 'nextgroup=goStructLiteralBlock' to handle
" anonymous struct type literals
syntax keyword goStructType struct contained skipempty skipwhite nextgroup=goStructTypeBlock
syntax region goStructTypeBlock matchgroup=goStructTypeBraces start='{' end='}' extend contained contains=goEmbeddedType,goStructTypeField,goComment,goStructTypeTag,goDot,goSemicolon skipwhite nextgroup=goStructLiteralBlock
syntax region goStructTypeTag start='`' end='`' contained
syntax region goStructTypeTag start='"' skip='\\"' end='"' contained oneline
syntax match goStructTypeField /\%(_\|\K\k*\)\%(,\s*\%(_\|\K\k*\)\)*/ contained contains=goComma,goUnderscore skipwhite nextgroup=@goType
syntax match goEmbeddedType /\*\?\K\k*\%(\.\K\k*\)\?\%(\[.*\]\)\?\%#\@1<!$/ contained contains=@goType
" It is technically possible to have a space between a struct name and the
" braces, but it's hard to reliably highlight
syntax match goStructLiteral /\v\K\k*\ze%(\{|\[\s*\n?%(,\n|[^\[\]]|\[\s*\n?%(,\n|[^\[\]]|\[[^\[\]]*\])*\])*\]\{)/ contained nextgroup=goStructLiteralTypeArgs,goStructLiteralBlock
syntax region goStructLiteralTypeArgs matchgroup=goTypeParamBrackets start='\[' end='\]' contained contains=@goType,goUnderscore,goComma,goComment nextgroup=goStructLiteralBlock
" goStructLiteralBlock contains itself to 1) prevent weird highlighting while
" typing, and 2) allow slice literals of slices of structs to highlight
" correctly
GoFoldStruct syntax region goStructLiteralBlock matchgroup=goStructBraces start='{' end='}' contained contains=goStructLiteralField,goComma,@goExpr,goStructLiteralBlock
syntax match goStructLiteralField /\<\K\k*\ze:/ contained nextgroup=goStructLiteralColon
syntax match goStructLiteralColon /:/ contained
syntax keyword goInterfaceType interface contained skipwhite skipempty nextgroup=goInterfaceBlock
GoFoldInterface syntax region goInterfaceBlock matchgroup=goInterfaceBraces start='{' end='}' contained contains=@goType,goTypeConstraintSymbols,goInterfaceMethod,goComment extend
syntax match goInterfaceMethod /\K\k*\ze(/ contained skipwhite nextgroup=goInterfaceMethodParams
syntax region goInterfaceMethodParams matchgroup=goInterfaceMethodParens start='(' end=')' contained contains=goFuncParam,goComma,goComment skipwhite nextgroup=@goType,goInterfaceMethodMultiReturn
syntax region goInterfaceMethodMultiReturn matchgroup=goFuncMultiReturnParens start='(' end=')' contained contains=goNamedReturnValue,goComma,goComment
hi link goStructType Keyword
hi link goStructTypeBraces goBraces
hi link goStructTypeField Identifier
hi link goStructTypeTag PreProc
hi link goStructLiteral goNonPrimitiveType
hi link goStructLiteralField Identifier
hi link goStructLiteralColon goSemicolon
hi link goStructLiteralComma goComma
hi link goStructBraces goBraces
hi link goInterfaceType goStructType
hi link goTypeConstraintSymbols goOperator
hi link goInterfaceBraces goBraces
hi link goInterfaceMethod goFuncName
hi link goInterfaceMethodParens goFuncParens
call s:HiConfig('goStructTypeTag', ['go_highlight_struct_tags'])
call s:HiConfig('goStructLiteralField', ['go_highlight_struct_fields'], #{default: 1})
call s:HiConfig('goStructTypeField', ['go_highlight_struct_type_fields'], #{default: 1})
" }}} Structs and Interfaces
" Builtins {{{
" `make` and `new` are matched by `goMakeBuiltin` and `goNewBuiltin` so that the
" paren block that follows can have custom highlighting for types
syntax keyword goBuiltins append cap close complex copy delete imag len max min panic print println real recover skipwhite nextgroup=goFuncCallArgs
syntax keyword goMakeBuiltin make skipwhite nextgroup=goMakeBlock
syntax region goMakeBlock matchgroup=goFuncCallParens start='(' end=')' contained contains=@goType,goMakeArguments,goComment
syntax region goMakeArguments start=',' end='\ze)' contained contains=@goExpr,gComment
syntax keyword goNewBuiltin new skipwhite nextgroup=goNewBlock
syntax region goNewBlock matchgroup=goFuncCallParens start='(' end=')' contained contains=@goType,goComment
hi link goBuiltins Special
hi link goMakeBuiltin goBuiltins
hi link goNewBuiltin goBuiltins
call s:HiConfig('goBuiltins', ['go_highlight_builtins'], #{offgroup: 'goFuncCall'})
call s:HiConfig('goFuncCallParens', ['go_highlight_function_call_parens'])
" }}} Builtins
" Flow Control {{{
syntax cluster goFlowControl contains=goGoto,goIf,goElse,goFor,goForRange,goForKeywords,goSwitch,goCase,goSelect,goSwitchKeywords
" 'goStatementStart' is used to avoid searching for 'goLabel' everywhere
syntax match goLabel /\K\k*\ze:/ contained
syntax keyword goGoto goto contained skipwhite nextgroup=goGotoLabel
syntax match goGotoLabel /\K\k*/ contained
syntax keyword goIf if contained skipwhite skipempty nextgroup=goShortVarDecl
syntax keyword goElse else contained
syntax keyword goFor for contained skipwhite skipempty nextgroup=goShortVarDecl
syntax keyword goForRange range contained
syntax keyword goForKeywords break continue contained
syntax keyword goSwitch switch contained skipwhite nextgroup=goShortVarDecl
syntax keyword goSelect select contained
syntax keyword goCase case contained skipwhite nextgroup=goShortVarDecl
syntax keyword goSwitchKeywords fallthrough default contained
syntax match goSwitchTypeCase /^\s\+case\s/ contained skipwhite nextgroup=@goType
syntax region goSwitchTypeBlock matchgroup=goSwitchTypeBraces start='{' end='}' contained contains=goSwitchTypeCase,goSwitchTypeBlockNestedBraces,@goStatement
" goSwitchTypeBlockNestedBraces prevents goSwitchTypeCase from matching "case" in a regular nested switch statement
syntax region goSwitchTypeBlockNestedBraces matchgroup=goBraces start='{' end='}' contained contains=@goStatement
hi link goGoto Statement
hi link goGotoLabel goLabel
hi link goIf Conditional
hi link goElse goIf
hi link goFor Repeat
hi link goForRange goFor
hi link goForKeywords goFor
hi link goSwitch Conditional
hi link goSelect goSwitch
hi link goCase goSwitch
hi link goSwitchKeywords goSwitch
hi link goSwitchTypeBraces goBraces
hi link goSwitchTypeCase goSwitchKeywords
" }}} Flow Control
" Misc {{{
syntax keyword goKeywords defer go contained
" goTypeAssertion is a part of the nextgroup list of goDotExpr
syntax region goTypeAssertion matchgroup=goParens start=/(/ end=/)/ contained contains=@goType
syntax match goTypeAssertion /(type)/ contained contains=goParenBlock skipwhite nextgroup=goSwitchTypeBlock
hi link goKeywords Keyword
hi link goTypeAssertion Special
" }}} Misc
" Vim-Go Compatibility {{{
" NOTE: The code in this section is a collection of verbatim extracts from
" https://github.com/fatih/vim-go/blob/master/syntax/go.vim, included here to
" ensure compatibility with vim-go's code coverage and debugging features. Refer
" to https://github.com/fatih/vim-go/blob/master/LICENSE for details on vim-go's
" source license.
hi def link goSameId Search
hi def link goDiagnosticError SpellBad
hi def link goDiagnosticWarning SpellRare
" TODO(bc): is it appropriate to define text properties in a syntax file?
" The highlight groups need to be defined before the text properties types
" are added, and when users have syntax enabled in their vimrc after
" filetype plugin on, the highlight groups won't be defined when
" ftplugin/go.vim is executed when the first go file is opened.
" See https://github.com/fatih/vim-go/issues/2658.
if has('textprop')
if empty(prop_type_get('goSameId'))
call prop_type_add('goSameId', {'highlight': 'goSameId'})
endif
if empty(prop_type_get('goDiagnosticError'))
call prop_type_add('goDiagnosticError', {'highlight': 'goDiagnosticError'})
endif
if empty(prop_type_get('goDiagnosticWarning'))
call prop_type_add('goDiagnosticWarning', {'highlight': 'goDiagnosticWarning'})
endif
endif
" :GoCoverage commands
hi def link goCoverageNormalText Comment
hi def goCoverageCovered ctermfg=green guifg=#A6E22E
hi def goCoverageUncover ctermfg=red guifg=#F92672
hi def link goDeclsFzfKeyword Keyword
hi def link goDeclsFzfFunction Function
hi def link goDeclsFzfSpecialComment SpecialComment
hi def link goDeclsFzfComment Comment
" :GoDebug commands
if exists('*go#config#HighlightDebug') && go#config#HighlightDebug()
hi def GoDebugBreakpoint term=standout ctermbg=117 ctermfg=0 guibg=#BAD4F5 guifg=Black
hi def GoDebugCurrent term=reverse ctermbg=12 ctermfg=7 guibg=DarkBlue guifg=White
endif
" }}} Vim-Go Compatibility
call s:Cleanup()
if !exists('main_syntax')
let b:current_syntax = 'go'
endif
" vim:tw=80:fdm=marker:fmr={{{,}}}:
" JASON
hi goFuncCall guifg=#8fa3b3 gui=bold
hi goField guifg=#b3a3d3 " method/field names after dot
hi goFuncName guifg=#8fa3b3 gui=bold " function declarations
-47
View File
@@ -1,47 +0,0 @@
" Author: Charles Pascoe
" License: MIT (see LICENSE)
" Copyright: 2022 Charles Pascoe
" Syntax highlighting for vim-go godoc buffers
" Clear any existing syntax first
syntax clear
if exists("b:current_syntax") && !get(g:, "go_highlight_override_existing_syntax", 1)
finish
endif
syntax clear
let b:current_syntax = 'godoc'
let main_syntax = 'godoc'
syntax include @go syntax/go.vim
unlet main_syntax
syntax match godocTypeLine /^\%1l.*$/ contains=@godocType,@go
syntax cluster godocType contains=godocTypeDecl,godocUntyped,goVarDecl,goConstDecl,goTypeDecl,goPackage,godocFuncDecl,godocField,godocVarConst
syntax match godocFuncDecl /^func\ze\s*\%(\%(\K\k*\.\)\?\K\k*\)\?(/ skipwhite nextgroup=godocFuncDeclPackage,goFuncName,godocReceiverBlock
syntax match godocFuncDeclPackage contained /\K\k*\ze\.\K\k*/ contains=goPackageName nextgroup=godocMethodDot
syntax region godocReceiverBlock contained matchgroup=godocReceiverParens start='(' end=')' contains=@goType nextgroup=godocMethodDot
syntax match godocMethodDot contained /\./ nextgroup=goFuncName
syntax keyword godocField contained field skipwhite nextgroup=godocFieldIdentifier
syntax match godocFieldIdentifier contained /\K\k*/ skipwhite nextgroup=@goType
syntax keyword godocTypeDecl contained type skipwhite skipnl nextgroup=goTypeDeclName,goTypeDeclGroup,godocTypeParameterDecl
syntax keyword godocTypeParameterDecl contained parameter skipwhite skipnl nextgroup=goTypeDeclName
syntax keyword godocVarConst contained var const skipwhite nextgroup=godocVarConstIdentifier
syntax keyword godocUntyped contained untyped skipwhite nextgroup=@goType
syntax match godocVarConstIdentifier contained /\K\k*\%(\.\K\k*\)\?/ contains=goPackageName skipwhite nextgroup=@goType
hi link godocTypeDecl goTypeDecl
hi link godocTypeParameterDecl goTypeDecl
hi link godocUntyped Type
hi link godocVarConst goVarDecl
hi link godocVarConstIdentifier goVarIdentifier
hi link godocFuncDecl goFuncDecl
hi link godocReceiverParens goReceiverParens
hi link godocField Keyword
hi link godocFieldIdentifier Identifier
hi link godocMethodDot goDot
-251
View File
@@ -1,251 +0,0 @@
" Vim syntax file
" Language: Odin
" Last changed: 2026-05-25
" Clear any existing syntax first
syntax clear
" Quit when a (custom) syntax file was already loaded
if exists("b:current_syntax")
finish
endif
syntax case match
syn keyword odinStatement do foreign import package defer return continue break
syn keyword odinStatement fallthrough using
syn keyword odinKeyword distinct proc context dynamic
syn keyword odinOperator in not_in cast transmute auto_cast
syn keyword odinOperator or_else or_return or_continue or_break
syn keyword odinRepeat for
syn keyword odinConditional if else switch when where case
syn keyword odinBoolean true false
syn keyword odinStructure matrix struct union enum bit_set bit_field map
" maybe create different groups here? odinBool, odinSignedInt, odinUnisgnedInt ...
syn keyword odinType bool b8 b16 b32 b64
syn keyword odinType int i8 i16 i32 i64 i128
syn keyword odinType uint byte u8 u16 u32 u64 u128 uintptr
syn keyword odinType i16le i32le i64le i128le u16le u32le u64le u128le
syn keyword odinType i16be i32be i64be i128be u16be u32be u64be u128be
syn keyword odinType f16 f32 f64
syn keyword odinType f16le f32le f64le
syn keyword odinType f16be f32be f64be
syn keyword odinType complex32 complex64 complex128
syn keyword odinType quaternion64 quaternion128 quaternion256
syn keyword odinType rune string cstring
syn keyword odinType typeid rawptr any
syn keyword odinNull nil
syn match odinBuiltinProc "\%(abs\|align_int_max\|clamp\|complex\|compress_values\|conj\|expand_values\|imag\|jmag\|kmag\|len\|max\|min\|offset_of\|offset_of_by_string\|offset_of_member\|offset_of_selector\|quaternion\|raw_data\|real\|size_of\|soa_unzip\|soa_zip\|swizzle\|type_info_of\|type_of\|typeid_of\)" contained
" TODO: these groups mess with other groups that don't use a \@<=
"syn match odinPtrPtr "\%(\W\)\@3<=^\{-}" display
"syn match odinPtrDeferencing "\^\+\%(\W\)\@=" display
"syn match odinTodo "FIXME" display
"syn match odinTodo "TODO" display
"syn match odinTodo "XXX" display
"JASON - todo keywords
syn match odinTodo "@TODO" display
syn match odinTodo "@FIXME\|@FIX\|@XXX" display
syn match odinTodo "@WARN\|@WARNING\|@HACK" display
syn match odinTodo "@INFO\|@NOTE\|@IDEA" display
syn match odinProbablyAType "\<_*[A-Z]\w*\>" display
" TODO: in [dynamic; asdf]int 'asdf' should be a Constant
syn match odinConstant "_*[A-Z]\w*\ze\s*::" display
syn match odinConstant "\%(\W\)\@3<=_*[A-Z_]\+\ze\%(\W\|$\)" display
syn match odinExplicitEnum "\%(\<_*[A-Z]\w\{-}\.\)\@20<=_*[A-Z]\w*\>" display
syn match odinLabel /\h\w*\ze:\s\+for/ display
syn match odinLabel "\%(\%(break\|continue\|or_continue\|or_break\)\s\+\)\@50<=\zs\h\w*" display
syn match odinAssignOp "=" display
syn match odinDeclareOp ":" display
syn match odinArithmeticOp "+\|\*\|/\|%\|-\|!" display
syn match odinVariadicOp "\.\." display
" I have no idea how to distinguish between & binaryOp and & addressOp
" maybe (\w|\d)@<!\s*&
syn match odinBinaryOp "!\|\~\||\|&" display
syn match odinComparisonOpError +=<\|=>\|=!+ display
syn match odinComparisonOp "==\|!=\|<=\|>=\|&&\|||\|[<>]" display
syn match odinRangeOpError +\%([_'"0-9A-Za-z]\s\{-}\)\@<=\.\.\ze[_'"0-9A-Za-z]+ display
syn match odinRangeOpError +\.\.>\|\.<\|\.>+ display
syn match odinRangeOp "\.\.=\|\.\.<" display
syn match odinBinaryOpError "<>\|><"
syn match odinBinaryOp "<<\|>>" display
syn match odinInteger "\%(^\|\W\)\@3<=\d[0-9_]*\%(i\|j\|k\)\?\>" display
syn match odinFloat "\%(^\|\W\)\@3<=\d[0-9_]*\%(\.\d[0-9_]*\%([eE][+-]\?\d[0-9_]*\)\?\|[eE][+-]\?\d[0-9_]*\)\%(i\|j\|k\)\?\>" display
" never knew hex floats were a thing (and it sometimes gives compiler errors as of dev-2026-05)
" but it's documented in the official EBNF file in the odin repo
syn match odinHexFloat "\%(^\|\W\)\@3<=0h\x[0-9A-Fa-f_]*\>" display
" Hex, Oct, and Bin can't be floats or imaginary
syn match odinBin "\%(^\|\W\)\@3<=0b[01][01_]*\>" display
syn match odinOct "\%(^\|\W\)\@3<=0o\o[0-7_]*\>" display
syn match odinHex "\%(^\|\W\)\@3<=0x\x[0-9A-Fa-f_]*\>" display
" table.slots[index].occupied " occupied is not an enum
syn match odinImplicitEnum "\%([^\]0-9A-Za-z_]\+\)\@<=\.\h\w*" display
syn match odinEnumDef "\<\h\w*" contained
syn match odinEnumDefConstant "\%(=\s*\)\@<=\h\w*" contained
" have to duplicate here because you can't set an enum to an imaginary or quaternion
syn match odinIntNotImg "\%(^\|\W\)\@3<=\zs\d[0-9_]*\>" display contained
syn region odinEnumDefinition start="\(:\s*enum.\{-}\)\@200<=\zs{"ms=e+1 end="}"me=s-1 contains=odinEnumDef,odinIntNotImg,odinRangeOp,odinRangeOpError,odinComment,odinCommentBlock,odinEnumDefConstant
syn match odinProcCall "\<[a-z_]\w*\ze\_s*(" display contains=odinBuiltinProc
syn match odinAllConst "[A-Z_]\w*" contained display
syn match odinCustomType "[A-Z_]\w*\ze(" contained display
syn match odinPtrType "\^\%(\h\w*\.\)*\zs[A-Z_]\w*" display
syn region odinCustomTypeRegion matchgroup=odinType start="_*[A-Z]\w*\ze(" matchgroup=NONE end=+)+me=s-1 contains=odinAllConst,odinParapoly,odinInteger,odinArithmeticOp,odinCustomType,odinType
syn match odinTypeDeclaration "[^:]:\s*\%(\[.*\]\)*\s*\%(\h\w*\.\)*\zs[A-Z_]\w*" display
syn match odinTypeDeclaration "\%(=\s*\)\@30<=\h\w*\ze{.\{-}\%(}\|$\)" display
syn match odinTypeDefinition "\h\w*\ze\s*::\s*\%(distinct\|struct\|union\|enum\|bit_field\|bit_set\)"
syn match odinSwitchUnion "\%(case.\{-}\)\@30<=[A-Z_]\w*\ze\s*:" display
"syn region odinParapolyConst start=+(+ end=+)+ contained contains=odinAllConst,odinParapolyConst,odinInteger,odinArithmeticOp,odinCustomType
syn region odinParapolyConst start=+\%(_*[A-Z]\w*\)\@30<=(+ end=+)+ contains=odinAllConst,odinParapolyConst,odinInteger,odinArithmeticOp,odinCustomType,odinParapoly
syn match odinParapoly "\$\h\w*" display
syn match odinImplicitAssertion +\%(\w\.\)\@4<=?+ display
syn region odinUnionAssertType start="\%(\h\w\{-}\.\)\@50<=("ms=e+1 end=")"me=s-1 contains=odinInteger,odinConstant,@odinTypes,odinCustomType,odinParapolyConst
syn match odinReturnType "\%(->\s*\)\@100<=(\?\zs[A-Z_]\w*\ze)\?" display
" CustomType2 is used only in UnionDefinition and can probably substituded with
" ProbablyAType, which will match less stuff but would still work so long you
" are using the idiomatic name convention
syn match odinCustomType2 "[A-Z_]\w*" contained
syn region odinUnionDefinition start="\%(:\s*union.\{-}\)\@200<=\zs{" end="}"me=s-1 contains=odinComment,odinCommentBlock,odinCustomType,odinPtrType,odinConstant,odinInteger,odinType,odinCustomType2
syn match odinParapolySpecType "\%(\$.\{-}/\)\@50<=[A-Z_]\w*" display
syn match odinProcName "\h\w*\ze\s*::\s*proc" display
"JASON - proc params
syn match odinProcParam "\h\w*\ze\s*:" contained display
syn region odinProcParams matchgroup=NONE start="proc\s*(" end=")" contains=odinProcParam,odinType,odinPtrType,odinOperator,odinParapoly,odinCallingConvention
syn match odinDirective "#\s*\h\w\{-}\>" display
syn region odinTernaryRegion matchgroup=odinTernary start="?" end=":" oneline contains=ALL display
syn match odinTernary "[?:]" contained transparent display
syn match odinAttribute "@(\h\w\{-}" contained display
syn match odinAttribute ")" contained transparent display
syn region odinAttributeRegion matchgroup=odinAttribute start="@(\h\w*\>" skip=+".\{-}).\{-}"+ end=")" contains=odinString,odinBoolean,@odinTypes,odinConstant,odinComparisonOp,odinComaparisonOpError,odinBinaryOp oneline display
syn match odinBuildTag "^\s*#+\%(build\|vet\|test\|ingnore\|private\|feature\|no-instrumentation\)" display
syn region odinBuildTagRegion matchgroup=odinBuildTag start="^\s*#+\%(build\|vet\|test\|ingnore\|private\|feature\|no-instrumentation\)" matchgroup=NONE end="$" oneline display
syn region odinComment start="//" end="$" oneline contains=odinTodo
syn region odinComment start="#!" end="$" oneline contains=odinTodo
syn region odinCommentBlock start=/\/\*/ end=/\*\// contains=odinCommentBlock,odinTodo
syn match odinEscapeChar /\\[abefnrtv"']\|\\\o\{3}\|\\x\x\{2}\|\\u\x\{4}\|\\U\x\{8}\|\\\\/ contained display
" TODO: figure out how to do the error
"syn match odinEscapeError /\\[^abefnrtv"']\|\\\%(\o\{,2}\|\o\{4,}\)\|\\x\%(\x\{3}\|\x\+\)\|\\u\x\{5,7}\|\\U\x\{9,}/ contained display
"syn match odinEscapeError /\\[^abefnrtv"']/ contained
syn region odinString start=/"/ skip=/\\"/ end=/"/ contains=odinEscapeChar oneline
syn region odinRawString start=+`+ end=+`+
syn region odinCharacter start=+'+ end=+'+ contains=odinEscapeChar oneline
" I think the minimum path is ".."
syn match odinImportPath +\%(\%(^\|*/\)\s*import.\{-}\)\@90<=".\{2,}"+ display
syn match odinPackageDeclaration "\(^package\)\@<=\s\+\h\w*" display
syn match odinCallingConventionError +\%(:\s*proc\s*\)\@90<=".*"+ display
syn match odinCallingConvention +\%(:\s*proc\s*\)\@200<="\%(std\%(call\)\?\|odin\|c\%(decl\)\?\|none\|contextless\|fast\%(call\)\?\)"+ display
syn match odinUndefined "---\ze\s*$" display
syn match odinVoidAssign "\<_\>" display
syn match odinProcRet "->" display
syn cluster odinOperators contains=odinOperator,odinArithmeticOp,odinRangeOp,odinComparisonOp
syn cluster odinTypes contains=odinType,odinTypeDefinition,odinTypeDeclaration,odinPtrType,odinReturnType
syn cluster odinNumbers contains=odinInteger,odinBin,odinOct,odinHex
hi def link odinPtrType odinType
hi def link odinTypeDeclaration odinType
hi def link odinTypeDefinition odinType
hi def link odinNull odinType
hi def link odinReturnType odinType
hi def link odinCustomType odinType
hi def link odinCustomType2 odinType
hi def link odinParapolySpecType odinType
hi def link odinSwitchUnion odinType
hi def link odinProbablyAType odinType
hi def link odinType Type
"hi def link odinPtrType Type
"hi def link odinTypeDeclaration Type
"hi def link odinTypeDefinition Type
"hi def link odinNull Type
"hi def link odinReturnType Type
"hi def link odinCustomType Type
"hi def link odinCustomType2 Type
"hi def link odinParapolySpecType Type
"hi def link odinSwitchUnion Type
"hi def link odinProbablyAType Type
hi def link odinOperator Operator
hi def link odinComparisonOp Operator
hi def link odinComparisonOpError Error
hi def link odinArithmeticOp Operator
hi def link odinBinaryOp Operator
hi def link odinBinaryOpError Error
hi def link odinRangeOp Operator
hi def link odinRangeOpError Error
hi def link odinVariadicOp Operator
hi def link odinExplicitEnum Number
hi def link odinImplicitEnum Number
hi def link odinEnumDef Number
hi def link odinInteger Number
hi def link odinIntNotImg Number
hi def link odinBin Number
hi def link odinOct Number
hi def link odinHex Number
hi def link odinFloat Float
hi def link odinHexFloat Float
hi def link odinString String
hi def link odinRawString String
hi def link odinEscapeChar Special
hi def link odinCharacter Character
"hi def link odinEscapeError Error
hi def link odinBoolean Boolean
hi def link odinStatement Statement
hi def link odinKeyword Keyword
hi def link odinRepeat Repeat
hi def link odinConditional Conditional
hi def link odinTernary Conditional
hi def link odinStructure Structure
hi def link odinConstant Constant
hi def link odinEnumDefConstant Constant
hi def link odinAllConst Constant
hi def link odinParapoly Constant
hi def link odinComment Comment
hi def link odinCommentBlock Comment
hi def link odinLabel Special
hi def link odinAttribute Macro
hi def link odinBuildTag Macro
hi def link odinDirective Define
hi def link odinCallingConvention Define
hi def link odinCallingConventionError Error
syn sync ccomment odinCommentBlock
"JASON - colors
"hi def link odinTodo Todo
"hi def link odinProcCall Function
"hi def link odinBuiltinProc Function
hi odinTodo guifg=#ebcb8b guibg=NONE gui=bold ctermfg=Yellow cterm=bold
hi odinFix guifg=#d9a6a6 guibg=NONE gui=bold ctermfg=Red cterm=bold
hi odinWarn guifg=#fbe4a8 guibg=NONE gui=bold ctermfg=Yellow cterm=bold
hi odinInfo guifg=#a3be8c guibg=NONE gui=bold ctermfg=Green cterm=bold
hi odinProcCall guifg=#8fa3b3 gui=NONE ctermfg=Blue
hi odinBuiltinProc guifg=#8fa3b3 gui=italic ctermfg=Cyan
hi odinBuiltinProc guifg=#8fa3b3 gui=NONE ctermfg=Blue
hi odinProcName guifg=#8fa3b3 gui=bold ctermfg=Blue cterm=bold
hi odinProcParam guifg=#b3a3d3 gui=NONE ctermfg=Magenta
hi def link odinImportPath String
let b:current_syntax = "odin"
+50 -130
View File
@@ -1,9 +1,7 @@
require("vim._core.ui2").enable({})
map = vim.keymap.set
vim.g.mapleader = " "
vim.g.termguicolors = true
-- mini.basics sets defaults see plugin folder for more
vim.o.termguicolors = true
vim.o.nu = true
vim.o.swapfile = false
vim.o.winborder = "single"
vim.o.winblend = 0
@@ -17,9 +15,10 @@ vim.o.clipboard = "unnamedplus"
vim.o.foldmethod = "expr"
vim.o.foldlevel = 99
vim.o.completeopt = "menuone,noselect,fuzzy,nosort"
vim.opt.shortmess:append("c")
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>")
@@ -33,10 +32,52 @@ 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>l", ":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("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
@@ -50,7 +91,6 @@ vim.api.nvim_create_autocmd({ "BufEnter", "TermEnter", "WinEnter" }, {
end
end
})
-- highlights yanked text
vim.api.nvim_create_autocmd("TextYankPost", {
callback = function()
@@ -60,7 +100,6 @@ vim.api.nvim_create_autocmd("TextYankPost", {
})
end,
})
-- removes trailing whitespace on save
vim.api.nvim_create_autocmd("BufWritePre", {
callback = function()
@@ -69,122 +108,3 @@ vim.api.nvim_create_autocmd("BufWritePre", {
vim.fn.setpos(".", save_cursor)
end,
})
-- @TERMINAL
-- -----------------------------
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', '<leader>l', prev_non_term_buf, { desc = 'Go to previous non-terminal buffer' })
map('n', '<C-j>', toggle_term, { desc = 'Toggle terminal split' })
map('n', '<C-o>', open_term_fullscreen, { desc = 'Open terminal fullscreen' })
map('t', '<C-j>', toggle_term, { desc = 'Toggle terminal split' })
map('t', '<C-o>', prev_non_term_buf, { desc = 'Exit terminal mode' })
-- @PLUGINS
-- -----------------------------
vim.pack.add({
{ src = 'https://github.com/nvim-mini/mini.nvim' },
{ src = 'https://github.com/neovim/nvim-lspconfig' },
{ src = 'https://github.com/metalelf0/kintsugi-nvim' },
{ src = 'https://github.com/xiyaowong/transparent.nvim' },
{ src = 'https://github.com/brenoprata10/nvim-highlight-colors' }
})
-- { src = 'https://github.com/romus204/tree-sitter-manager.nvim' },
-- require('tree-sitter-manager').setup()
require('nvim-highlight-colors').setup()
-- Mini setups
require('mini.extra').setup()
require('mini.pairs').setup()
require('mini.files').setup()
require('mini.surround').setup()
require('mini.sessions').setup()
require('mini.statusline').setup()
require('mini.basics').setup({options = { extra_ui = true }})
require('mini.completion').setup({lsp_completion = { auto_setup = true }})
require('mini.pick').setup({
window = {
config = function()
local height = math.floor(0.65 * vim.o.lines)
local width = math.floor(0.80 * vim.o.columns)
return {
anchor = 'NW', height = height, width = width,
row = math.floor(0.5 * (vim.o.lines - height)),
col = math.floor(0.5 * (vim.o.columns - width)),
}
end
}
})
vim.cmd(":HighlightColors Off")
vim.cmd(":colorscheme kintsugi-dark")
-- 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>")
map("n", "<leader>a", ":lua vim.lsp.buf.code_action()<CR>")
-- Mini Keybinds
map("n", "<leader>e", function() MiniFiles.open(vim.fn.getcwd()) end)
map("n", "<leader>f", function() MiniPick.builtin.files(nil, { source = { cwd = vim.fn.getcwd() } }) end)
map("n", "<leader>o", ":lua MiniPick.builtin.buffers()<CR>")
map("n", "<leader>h", ":lua MiniPick.builtin.help()<CR>")
map("n", "<leader>d", ":lua MiniExtra.pickers.diagnostic()<CR>")
map("n", "<leader>pp", ":lua MiniSessions.select()<CR>")
map("n", "<leader>ss", ":Pick buf_lines scope='current'<CR>")
map("n", "<leader>sp", function() MiniPick.builtin.grep_live(nil, { source = { cwd = vim.fn.getcwd() } }) end)
map('n', '<leader>sw', function() MiniPick.builtin.grep({ pattern = vim.fn.expand('<cword>') }) end)
-- Others
map("n", "<leader>tc", ":HighlightColors Toggle<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;
}
+65 -18
View File
@@ -2,7 +2,6 @@
# ---------------------------------------------------------------------------------
## GLOBAL VARS
# ---------------------------------------------------------------------------------
DOTFILES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# ---------------------------------------------------------------------------------
@@ -87,9 +86,12 @@ if [ "$DO_LINKS" = true ]; then
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."
@@ -113,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 bat syncthing
build-essential make bear valgrind tree
ca-certificates gnupg libfuse2 rsync fish
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=()
@@ -127,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
@@ -139,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"
-26
View File
@@ -1,26 +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
# install the Debian 13 php version
sudo apt install php-cli php-mysql php-curl php-mbstring php-zip
reload
# install/download composer
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === 'c8b085408188070d5f52bcfe4ecfbee5f727afa458b2573b8eaaf77b3419b0bf2768dc67c86944da1544f06fa544fd47') { echo 'Installer verified'.PHP_EOL; } else { echo 'Installer corrupt'.PHP_EOL; unlink('composer-setup.php'); exit(1); }"
php composer-setup.php
php -r "unlink('composer-setup.php');"
# Move composer bin
sudo mv composer.phar /usr/local/bin/composer
echo ""
echo "✅ PHP setup complete."
-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"