Compare commits
39 Commits
550810939f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 8c06125493 | |||
| d7863ed010 | |||
| 5bb60e1a35 | |||
| 00d3b3c3d9 | |||
| 379e008024 | |||
| e1c3745f3b | |||
| 1a49af00cc | |||
| d3c89f89f6 | |||
| ccd02e718b | |||
| 179f2a10fe | |||
| befd7d745c | |||
| 59752bb8d4 | |||
| 3b2a183bcb | |||
| 663a9cc377 | |||
| 9f2c2cb72d | |||
| 1fb68b7541 | |||
| b745401cc4 | |||
| 6a1355edc6 | |||
| fddbf187ee | |||
| 25612fc232 | |||
| 0faf3e3eef | |||
| a5401e517b | |||
| 0b2309fa0f | |||
| ccf9327a9b | |||
| affdb7fb9b | |||
| d9e59b61cf | |||
| a91f225f08 | |||
| 6d5236d8dd | |||
| e314363e8b | |||
| bb3d06a857 | |||
| 84b4a7d7b8 | |||
| f22eb5d964 | |||
| b32ab5a8ab | |||
| 6b1217f75a | |||
| 51fb1aec9d | |||
| 69527e3d61 | |||
| 24db65b6ed | |||
| ae3fe68e2a | |||
| 7e606e21ad |
+3
-1
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 ""
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 }},
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
|
||||
# ==============================================================================
|
||||
|
||||
@@ -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
@@ -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 &{{
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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>")
|
||||
|
||||
@@ -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' })
|
||||
@@ -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;
|
||||
},
|
||||
)
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Executable
+68
@@ -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"
|
||||
Executable
+47
@@ -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"
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
# Nothing to clean for the previewer above, but lf requires this script.
|
||||
exit 0
|
||||
Executable
+17
@@ -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
|
||||
Executable
+30
@@ -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
|
||||
Executable
+27
@@ -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
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
awesome-client 'show_dim()'
|
||||
rofi -show drun "$@"
|
||||
awesome-client 'hide_dim()'
|
||||
@@ -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."
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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."
|
||||
@@ -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"
|
||||
Executable
+17
@@ -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."
|
||||
Executable
+14
@@ -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 ""
|
||||
Executable
+35
@@ -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"
|
||||
Reference in New Issue
Block a user