initial commit
This commit is contained in:
commit
23d4795228
99 changed files with 6691 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
result
|
||||||
|
.direnv/
|
||||||
392
README.md
Normal file
392
README.md
Normal file
|
|
@ -0,0 +1,392 @@
|
||||||
|
# NixOS Migration Guide
|
||||||
|
|
||||||
|
## Before you start
|
||||||
|
|
||||||
|
Things to have ready:
|
||||||
|
|
||||||
|
- A USB stick (4GB+)
|
||||||
|
- WiFi password
|
||||||
|
- This guide on your phone
|
||||||
|
|
||||||
|
Your nix-config already has both `homeConfigurations.barrett` (standalone
|
||||||
|
home-manager, what you use now on Arch) and `nixosConfigurations.xps15` (full
|
||||||
|
NixOS). The flake, configuration.nix, and all home-manager modules are ready.
|
||||||
|
The only file you're missing is `hosts/xps15/hardware-configuration.nix`, which
|
||||||
|
gets generated during install.
|
||||||
|
|
||||||
|
## 1. Prep on Arch (before wiping)
|
||||||
|
|
||||||
|
### Back up
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Secrets
|
||||||
|
cp -r ~/.gnupg /tmp/gnupg-backup
|
||||||
|
cp -r ~/.ssh /tmp/ssh-backup
|
||||||
|
cp -r ~/.local/share/pass /tmp/pass-backup
|
||||||
|
|
||||||
|
# Fonts (not in nixpkgs)
|
||||||
|
tar cf /tmp/fonts.tar ~/.local/share/fonts
|
||||||
|
|
||||||
|
# Browser profile
|
||||||
|
tar cf /tmp/zen.tar ~/.zen
|
||||||
|
|
||||||
|
# Any uncommitted work
|
||||||
|
cd ~/dev && git status # check each repo
|
||||||
|
|
||||||
|
# Wallpapers and lock screen images
|
||||||
|
tar cf /tmp/img.tar ~/img
|
||||||
|
```
|
||||||
|
|
||||||
|
Copy all of `/tmp/*-backup` and `/tmp/*.tar` to the USB stick or another
|
||||||
|
machine.
|
||||||
|
|
||||||
|
### Push this repo
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd ~/nix-config # (as barrett, or sg barrett)
|
||||||
|
git push
|
||||||
|
```
|
||||||
|
|
||||||
|
### Download NixOS ISO
|
||||||
|
|
||||||
|
Grab the minimal ISO from https://nixos.org/download — you want the "Minimal
|
||||||
|
ISO image" (not graphical), x86_64.
|
||||||
|
|
||||||
|
Flash it:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo dd bs=4M if=nixos-minimal-*.iso of=/dev/sdX status=progress oflag=sync
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Boot the installer
|
||||||
|
|
||||||
|
Reboot, mash F12 for boot menu, pick USB.
|
||||||
|
|
||||||
|
You'll land in a root shell. Connect to WiFi:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
systemctl start wpa_supplicant
|
||||||
|
wpa_cli
|
||||||
|
> add_network 0
|
||||||
|
> set_network 0 ssid "YourSSID"
|
||||||
|
> set_network 0 psk "YourPassword"
|
||||||
|
> enable_network 0
|
||||||
|
> quit
|
||||||
|
```
|
||||||
|
|
||||||
|
Or if you prefer `iwd` (available in the installer too):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
iwctl
|
||||||
|
[iwd]# station wlan0 scan
|
||||||
|
[iwd]# station wlan0 get-networks
|
||||||
|
[iwd]# station wlan0 connect YourSSID
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify: `ping nixos.org`
|
||||||
|
|
||||||
|
## 3. Partition
|
||||||
|
|
||||||
|
Your current disk layout (from fstab):
|
||||||
|
|
||||||
|
| Mount | FS | UUID |
|
||||||
|
|----------|------|-------------------|
|
||||||
|
| `/` | ext4 | `1ac6e3de-...` |
|
||||||
|
| `/boot/efi` | vfat | `5646-BF32` |
|
||||||
|
| swap | swap | `39cde381-...` |
|
||||||
|
|
||||||
|
### Option A: Reuse existing partitions (if dual-boot / keeping data)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Find your partitions
|
||||||
|
lsblk -f
|
||||||
|
|
||||||
|
# Format root (THIS WIPES ARCH)
|
||||||
|
mkfs.ext4 -L nixos /dev/nvme0n1pX
|
||||||
|
|
||||||
|
# Mount
|
||||||
|
mount /dev/nvme0n1pX /mnt
|
||||||
|
mkdir -p /mnt/boot/efi
|
||||||
|
mount /dev/nvme0n1pY /mnt/boot/efi
|
||||||
|
swapon /dev/nvme0n1pZ
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option B: Fresh partition table
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Wipe and repartition
|
||||||
|
fdisk /dev/nvme0n1
|
||||||
|
|
||||||
|
# Create:
|
||||||
|
# 1. EFI partition (512M, type EFI System)
|
||||||
|
# 2. Swap partition (16G or match your RAM)
|
||||||
|
# 3. Root partition (rest of disk, type Linux filesystem)
|
||||||
|
|
||||||
|
mkfs.fat -F 32 /dev/nvme0n1p1
|
||||||
|
mkswap /dev/nvme0n1p2
|
||||||
|
mkfs.ext4 -L nixos /dev/nvme0n1p3
|
||||||
|
|
||||||
|
mount /dev/nvme0n1p3 /mnt
|
||||||
|
mkdir -p /mnt/boot/efi
|
||||||
|
mount /dev/nvme0n1p1 /mnt/boot/efi
|
||||||
|
swapon /dev/nvme0n1p2
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. Generate hardware config
|
||||||
|
|
||||||
|
```sh
|
||||||
|
nixos-generate-config --root /mnt
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates:
|
||||||
|
|
||||||
|
- `/mnt/etc/nixos/configuration.nix` (ignore this, we have our own)
|
||||||
|
- `/mnt/etc/nixos/hardware-configuration.nix` (we need this)
|
||||||
|
|
||||||
|
Copy it into your config structure:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mkdir -p /mnt/home/barrett/nix-config/hosts/xps15
|
||||||
|
cp /mnt/etc/nixos/hardware-configuration.nix /mnt/home/barrett/nix-config/hosts/xps15/
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5. Get your config onto the new system
|
||||||
|
|
||||||
|
### Option A: Clone from git (needs network)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
nix-shell -p git
|
||||||
|
git clone https://github.com/YOUR/nix-config /mnt/home/barrett/nix-config
|
||||||
|
cp /mnt/etc/nixos/hardware-configuration.nix /mnt/home/barrett/nix-config/hosts/xps15/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option B: Copy from USB
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mount /dev/sdX1 /mnt2 # your usb
|
||||||
|
cp -r /mnt2/nix-config /mnt/home/barrett/nix-config
|
||||||
|
cp /mnt/etc/nixos/hardware-configuration.nix /mnt/home/barrett/nix-config/hosts/xps15/
|
||||||
|
```
|
||||||
|
|
||||||
|
## 6. Install
|
||||||
|
|
||||||
|
```sh
|
||||||
|
nixos-install --flake /mnt/home/barrett/nix-config#xps15
|
||||||
|
```
|
||||||
|
|
||||||
|
It will:
|
||||||
|
|
||||||
|
- Build the full system closure
|
||||||
|
- Install GRUB
|
||||||
|
- Ask you to set the root password
|
||||||
|
|
||||||
|
This takes a while. Let it run.
|
||||||
|
|
||||||
|
## 7. First boot
|
||||||
|
|
||||||
|
```sh
|
||||||
|
reboot
|
||||||
|
```
|
||||||
|
|
||||||
|
Remove the USB. GRUB should appear. Boot NixOS.
|
||||||
|
|
||||||
|
Log in as root (password you just set), then set barrett's password:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
passwd barrett
|
||||||
|
```
|
||||||
|
|
||||||
|
Log out, log in as barrett.
|
||||||
|
|
||||||
|
## 8. Post-install setup
|
||||||
|
|
||||||
|
### Fix ownership
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo chown -R barrett:users ~/nix-config
|
||||||
|
```
|
||||||
|
|
||||||
|
### Home-manager (already integrated)
|
||||||
|
|
||||||
|
Your flake uses `home-manager.nixosModules.home-manager` so HM is part of the
|
||||||
|
system build. No separate `home-manager switch` needed — it all happens during
|
||||||
|
`nixos-rebuild switch`.
|
||||||
|
|
||||||
|
### Restore secrets
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# From USB or wherever you backed up
|
||||||
|
cp -r /path/to/gnupg-backup ~/.gnupg
|
||||||
|
chmod 700 ~/.gnupg
|
||||||
|
chmod 600 ~/.gnupg/*
|
||||||
|
|
||||||
|
cp -r /path/to/ssh-backup ~/.ssh
|
||||||
|
chmod 700 ~/.ssh
|
||||||
|
chmod 600 ~/.ssh/*
|
||||||
|
|
||||||
|
cp -r /path/to/pass-backup ~/.local/share/pass
|
||||||
|
```
|
||||||
|
|
||||||
|
### Restore fonts
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mkdir -p ~/.local/share/fonts
|
||||||
|
tar xf /path/to/fonts.tar -C /
|
||||||
|
fc-cache -fv
|
||||||
|
```
|
||||||
|
|
||||||
|
### Restore images
|
||||||
|
|
||||||
|
```sh
|
||||||
|
tar xf /path/to/img.tar -C /
|
||||||
|
```
|
||||||
|
|
||||||
|
### Restore browser profile
|
||||||
|
|
||||||
|
```sh
|
||||||
|
tar xf /path/to/zen.tar -C /
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rebuild (the main command going forward)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo nixos-rebuild switch --flake ~/nix-config#xps15
|
||||||
|
```
|
||||||
|
|
||||||
|
## 9. Gaps — things still needed in configuration.nix
|
||||||
|
|
||||||
|
Your `configuration.nix` already covers: GRUB, nvidia, iwd, keyd, pipewire,
|
||||||
|
docker, libvirtd, openssh, hyprland, bluetooth, zsh, xdg portals.
|
||||||
|
|
||||||
|
Still missing:
|
||||||
|
|
||||||
|
### Must add
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# /bin/sh = dash (you have a pacman hook for this on Arch)
|
||||||
|
environment.binsh = "${pkgs.dash}/bin/dash";
|
||||||
|
|
||||||
|
# doas (you use this instead of sudo on Arch)
|
||||||
|
security.doas = {
|
||||||
|
enable = true;
|
||||||
|
extraRules = [{
|
||||||
|
groups = [ "wheel" ];
|
||||||
|
persist = true;
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Auto timezone (replaces your tzupdate timer)
|
||||||
|
services.automatic-timezoned.enable = true;
|
||||||
|
# (already in your config, just confirming)
|
||||||
|
|
||||||
|
# Multilib equivalent — enable 32-bit support for Steam/Wine if needed
|
||||||
|
# hardware.graphics.enable32Bit = true;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Should add
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# Reflector equivalent — NixOS handles mirrors differently, but you may want
|
||||||
|
# to pin a substituter or add cachix
|
||||||
|
nix.settings = {
|
||||||
|
experimental-features = [ "nix-command" "flakes" ];
|
||||||
|
# already there, just noting
|
||||||
|
};
|
||||||
|
|
||||||
|
# geoclue for timezone detection
|
||||||
|
services.geoclue2.enable = true;
|
||||||
|
|
||||||
|
# X11 session (spectrwm/dwm) — if you want to keep X11 as an option
|
||||||
|
services.xserver = {
|
||||||
|
enable = true;
|
||||||
|
videoDrivers = [ "nvidia" ];
|
||||||
|
windowManager.spectrwm.enable = true;
|
||||||
|
# or just use xinit manually
|
||||||
|
};
|
||||||
|
|
||||||
|
# Fonts — system-wide
|
||||||
|
fonts.packages = with pkgs; [
|
||||||
|
jetbrains-mono
|
||||||
|
joypixels
|
||||||
|
font-awesome
|
||||||
|
# Your custom fonts (berkeley-mono etc) aren't in nixpkgs,
|
||||||
|
# keep them in ~/.local/share/fonts
|
||||||
|
];
|
||||||
|
|
||||||
|
# Yubikey / smartcard
|
||||||
|
services.pcscd.enable = true;
|
||||||
|
|
||||||
|
# QEMU/KVM
|
||||||
|
virtualisation.libvirtd.qemu.package = pkgs.qemu_full;
|
||||||
|
|
||||||
|
# Firewall (you have iptables on Arch)
|
||||||
|
networking.firewall.enable = true;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Packages to add to environment.systemPackages or HM
|
||||||
|
|
||||||
|
Compare your 207 explicit Arch packages against what's in
|
||||||
|
`home/modules/packages.nix`. The big categories not yet covered:
|
||||||
|
|
||||||
|
- **TeX**: texlive, biber, typst, quarto — add to HM packages
|
||||||
|
- **Languages**: rustup, go, ocaml, opam, uv, luarocks — add to HM packages
|
||||||
|
(or use devShells per-project)
|
||||||
|
- **Dev tools**: cmake, ninja, gdb, valgrind, perf — add to HM or devShells
|
||||||
|
- **CLI**: fastfetch, socat, rsync, bind (dig), time — add to HM packages
|
||||||
|
- **AUR equivalents**: voxtype, pikaur (not needed), sioyek (already in HM),
|
||||||
|
basedpyright, pistol, clipmenu (not needed on Wayland)
|
||||||
|
|
||||||
|
### Things you DON'T need on NixOS
|
||||||
|
|
||||||
|
- pacman hooks (dash, nvidia) — use NixOS options instead
|
||||||
|
- pikaur/AUR — use nixpkgs, overlays, or flake inputs
|
||||||
|
- reflector — not applicable
|
||||||
|
- mkinitcpio — NixOS uses its own initrd builder
|
||||||
|
- GRUB manual config — declarative via `boot.loader.grub`
|
||||||
|
|
||||||
|
## 10. Day-to-day workflow
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Edit config
|
||||||
|
nvim ~/nix-config/hosts/xps15/configuration.nix
|
||||||
|
# or any home-manager module
|
||||||
|
nvim ~/nix-config/home/modules/shell.nix
|
||||||
|
|
||||||
|
# Rebuild
|
||||||
|
sudo nixos-rebuild switch --flake ~/nix-config#xps15
|
||||||
|
|
||||||
|
# Update all inputs
|
||||||
|
nix flake update --flake ~/nix-config
|
||||||
|
sudo nixos-rebuild switch --flake ~/nix-config#xps15
|
||||||
|
|
||||||
|
# Rollback if something breaks
|
||||||
|
sudo nixos-rebuild switch --flake ~/nix-config#xps15 --rollback
|
||||||
|
# or pick a previous generation from GRUB
|
||||||
|
|
||||||
|
# Garbage collect old generations
|
||||||
|
sudo nix-collect-garbage -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## 11. Checklist
|
||||||
|
|
||||||
|
- [ ] Back up gnupg, ssh, pass, fonts, img, zen profile
|
||||||
|
- [ ] Push nix-config repo
|
||||||
|
- [ ] Flash NixOS minimal ISO to USB
|
||||||
|
- [ ] Boot USB, connect WiFi
|
||||||
|
- [ ] Partition and mount
|
||||||
|
- [ ] Generate hardware-configuration.nix
|
||||||
|
- [ ] Get nix-config onto /mnt
|
||||||
|
- [ ] `nixos-install --flake /mnt/home/barrett/nix-config#xps15`
|
||||||
|
- [ ] Set root password, reboot
|
||||||
|
- [ ] Set barrett password, log in
|
||||||
|
- [ ] Fix nix-config ownership
|
||||||
|
- [ ] Restore secrets (gnupg, ssh, pass)
|
||||||
|
- [ ] Restore fonts, images, browser profile
|
||||||
|
- [ ] `sudo nixos-rebuild switch --flake ~/nix-config#xps15`
|
||||||
|
- [ ] Verify: terminal, editor, browser, WM all working
|
||||||
|
- [ ] Add missing packages to configuration.nix / HM modules
|
||||||
|
- [ ] Add `environment.binsh = dash`
|
||||||
|
- [ ] Add doas config
|
||||||
|
- [ ] Add fonts.packages
|
||||||
|
- [ ] Add pcscd for Yubikey
|
||||||
|
- [ ] Commit hardware-configuration.nix
|
||||||
16
config/X11/xinitrc
Normal file
16
config/X11/xinitrc
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/sh
|
||||||
|
if [ -d /etc/X11/xinit/xinitrc.d ]; then
|
||||||
|
for f in /etc/X11/xinit/xinitrc.d/*; do
|
||||||
|
[ -x "$f" ] && . "$f"
|
||||||
|
done
|
||||||
|
unset f
|
||||||
|
fi
|
||||||
|
|
||||||
|
x setup
|
||||||
|
x mon
|
||||||
|
x bg ~/img/wp/one/progress.jpg ~/img/wp/one/lilies.jpg
|
||||||
|
setxkbmap -layout us -variant colemak &
|
||||||
|
pgrep -u "$USER" -f clipmenud >/dev/null || clipmenud &
|
||||||
|
# dwmblocks &
|
||||||
|
# dwm
|
||||||
|
spectrwm
|
||||||
7
config/X11/xmodmap
Normal file
7
config/X11/xmodmap
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
remove Control = Control_R
|
||||||
|
add mod3 = Control_R
|
||||||
|
remove mod1 = Alt_R
|
||||||
|
add mod2 = Alt_R
|
||||||
|
|
||||||
|
remove Shift = Shift_R
|
||||||
|
remove Mod4 = Super_L
|
||||||
32
config/X11/xresources.gruvbox
Normal file
32
config/X11/xresources.gruvbox
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
Xcursor.theme: Adwaita
|
||||||
|
Xcursor.size: 32
|
||||||
|
|
||||||
|
Xft.dpi: 103
|
||||||
|
|
||||||
|
*background: #1d2021
|
||||||
|
*foreground: #d4be98
|
||||||
|
|
||||||
|
! Black + DarkGrey
|
||||||
|
*color0: #32302f
|
||||||
|
*color8: #32302f
|
||||||
|
! DarkRed + Red
|
||||||
|
*color1: #ea6962
|
||||||
|
*color9: #ea6962
|
||||||
|
! DarkGreen + Green
|
||||||
|
*color2: #a9b665
|
||||||
|
*color10: #a9b665
|
||||||
|
! DarkYellow + Yellow
|
||||||
|
*color3: #d8a657
|
||||||
|
*color11: #d8a657
|
||||||
|
! DarkBlue + Blue
|
||||||
|
*color4: #7daea3
|
||||||
|
*color12: #7daea3
|
||||||
|
! DarkMagenta + Magenta
|
||||||
|
*color5: #d3869b
|
||||||
|
*color13: #d3869b
|
||||||
|
! DarkCyan + Cyan
|
||||||
|
*color6: #89b482
|
||||||
|
*color14: #89b482
|
||||||
|
! LightGrey + White
|
||||||
|
*color7: #d4be98
|
||||||
|
*color15: #d4be98
|
||||||
26
config/X11/xresources.light
Normal file
26
config/X11/xresources.light
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
Xcursor.theme: Adwaita
|
||||||
|
Xcursor.size: 32
|
||||||
|
|
||||||
|
Xft.dpi: 103
|
||||||
|
|
||||||
|
*background: #ffffff
|
||||||
|
*foreground: #000000
|
||||||
|
|
||||||
|
*color0: #000000
|
||||||
|
*color1: #b22222
|
||||||
|
*color2: #228222
|
||||||
|
*color3: #b8860b
|
||||||
|
*color4: #27408b
|
||||||
|
*color5: #8b008b
|
||||||
|
*color6: #00bfff
|
||||||
|
*color7: #ffffff
|
||||||
|
|
||||||
|
! 8 Bright Colors
|
||||||
|
*color8: #555555
|
||||||
|
*color9: #ff0000
|
||||||
|
*color10: #00ff00
|
||||||
|
*color11: #ffa500
|
||||||
|
*color12: #0000ff
|
||||||
|
*color13: #ff00ff
|
||||||
|
*color14: #00ffff
|
||||||
|
*color15: #ffffff
|
||||||
2
config/lf/cleaner
Executable file
2
config/lf/cleaner
Executable file
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/sh
|
||||||
|
exec kitten icat --clear --stdin no --transfer-mode memory </dev/null >/dev/tty
|
||||||
250
config/lf/lf.lua
Normal file
250
config/lf/lf.lua
Normal file
|
|
@ -0,0 +1,250 @@
|
||||||
|
_G.lf = _G.lf or {}
|
||||||
|
|
||||||
|
function _G.lf.setup()
|
||||||
|
vim.opt.swapfile = false
|
||||||
|
vim.opt.backup = false
|
||||||
|
vim.opt.writebackup = false
|
||||||
|
vim.opt.termguicolors = true
|
||||||
|
|
||||||
|
vim.pack.add({
|
||||||
|
{
|
||||||
|
src = "https://github.com/nvim-treesitter/nvim-treesitter.git",
|
||||||
|
name = "nvim-treesitter",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src = "https://github.com/barrettruth/midnight.nvim.git",
|
||||||
|
name = "midnight.nvim",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.cmd('silent TSInstall all')
|
||||||
|
|
||||||
|
vim.api.nvim_create_autocmd("OptionSet", {
|
||||||
|
pattern = "background",
|
||||||
|
callback = function()
|
||||||
|
vim.cmd.colorscheme(vim.o.background == "dark" and "midnight" or "daylight")
|
||||||
|
end,
|
||||||
|
group = vim.api.nvim_create_augroup("Midnight", { clear = true }),
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
local hl_cache = {}
|
||||||
|
local reset = "\27[0m"
|
||||||
|
|
||||||
|
---@param name string
|
||||||
|
---@return string
|
||||||
|
local function get_fg_ansi(name)
|
||||||
|
if hl_cache[name] then
|
||||||
|
return hl_cache[name]
|
||||||
|
end
|
||||||
|
|
||||||
|
local hl = vim.api.nvim_get_hl(0, { name = name, link = false })
|
||||||
|
|
||||||
|
if not hl.fg then
|
||||||
|
hl_cache[name] = ""
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local r = bit.rshift(bit.band(hl.fg, 0xff0000), 16)
|
||||||
|
local g = bit.rshift(bit.band(hl.fg, 0x00ff00), 8)
|
||||||
|
local b = bit.band(hl.fg, 0x0000ff)
|
||||||
|
|
||||||
|
local ansi = string.format("\27[38;2;%d;%d;%dm", r, g, b)
|
||||||
|
hl_cache[name] = ansi
|
||||||
|
return ansi
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param lines string[]
|
||||||
|
---@return boolean
|
||||||
|
local function render_with_vim_syntax(lines)
|
||||||
|
local ok = pcall(vim.cmd.syntax, "enable")
|
||||||
|
if not ok then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
for lnum, text in ipairs(lines) do
|
||||||
|
if #text == 0 then
|
||||||
|
io.write("\n")
|
||||||
|
else
|
||||||
|
local rendered = {}
|
||||||
|
local current_group = nil
|
||||||
|
local chunk_start = 1
|
||||||
|
|
||||||
|
for col = 1, #text do
|
||||||
|
local syn_id = vim.fn.synID(lnum, col, 1)
|
||||||
|
local group = vim.fn.synIDattr(syn_id, "name")
|
||||||
|
|
||||||
|
if group ~= current_group then
|
||||||
|
if current_group then
|
||||||
|
local chunk = text:sub(chunk_start, col - 1)
|
||||||
|
local ansi = get_fg_ansi(current_group)
|
||||||
|
if ansi ~= "" then
|
||||||
|
table.insert(rendered, ansi)
|
||||||
|
table.insert(rendered, chunk)
|
||||||
|
table.insert(rendered, reset)
|
||||||
|
else
|
||||||
|
table.insert(rendered, chunk)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
current_group = group
|
||||||
|
chunk_start = col
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if current_group then
|
||||||
|
local chunk = text:sub(chunk_start)
|
||||||
|
local ansi = get_fg_ansi(current_group)
|
||||||
|
if ansi ~= "" then
|
||||||
|
table.insert(rendered, ansi)
|
||||||
|
table.insert(rendered, chunk)
|
||||||
|
table.insert(rendered, reset)
|
||||||
|
else
|
||||||
|
table.insert(rendered, chunk)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local line = table.concat(rendered)
|
||||||
|
io.write(line .. "\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
io.flush()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param lines string[]
|
||||||
|
local function render_plain(lines)
|
||||||
|
for _, line in ipairs(lines) do
|
||||||
|
io.write(line .. "\n")
|
||||||
|
end
|
||||||
|
io.flush()
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param buf number
|
||||||
|
---@param lines string[]
|
||||||
|
---@param filetype string
|
||||||
|
---@param preview_line_count number
|
||||||
|
---@return table<number, table<number, {[1]: number, [2]: number, [3]: string}>>
|
||||||
|
local function collect_treesitter_highlights(buf, lines, filetype, preview_line_count)
|
||||||
|
local parser = vim.treesitter.get_parser(buf)
|
||||||
|
local trees = parser:parse()
|
||||||
|
if not trees or #trees == 0 then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local root = trees[1]:root()
|
||||||
|
local query = vim.treesitter.query.get(filetype, "highlights")
|
||||||
|
if not query then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
---@type table<number, table<number, {[1]: number, [2]: number, [3]: string}>>
|
||||||
|
local line_highlights = {}
|
||||||
|
|
||||||
|
for id, node in query:iter_captures(root, buf, 0, preview_line_count) do
|
||||||
|
local name = query.captures[id]
|
||||||
|
local start_row, start_col, end_row, end_col = node:range()
|
||||||
|
|
||||||
|
for row = start_row, end_row do
|
||||||
|
line_highlights[row] = line_highlights[row] or {}
|
||||||
|
local s_col = row == start_row and start_col or 0
|
||||||
|
local e_col = row == end_row and end_col or #lines[row + 1]
|
||||||
|
table.insert(line_highlights[row], { s_col, e_col, name })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, highlights in pairs(line_highlights) do
|
||||||
|
table.sort(highlights, function(a, b)
|
||||||
|
if a[1] == b[1] then
|
||||||
|
return a[2] > b[2]
|
||||||
|
end
|
||||||
|
return a[1] < b[1]
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
return line_highlights
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param lines string[]
|
||||||
|
---@param line_highlights table<number, table<number, {[1]: number, [2]: number, [3]: string}>>
|
||||||
|
---@param filetype string
|
||||||
|
local function render_with_treesitter(lines, line_highlights, filetype)
|
||||||
|
for i, text in ipairs(lines) do
|
||||||
|
local row = i - 1
|
||||||
|
local highlights = line_highlights[row] or {}
|
||||||
|
|
||||||
|
if #highlights == 0 then
|
||||||
|
io.write(text .. "\n")
|
||||||
|
else
|
||||||
|
local rendered = {}
|
||||||
|
local pos = 0
|
||||||
|
---@type {[1]: number, [2]: number}[]
|
||||||
|
local used_ranges = {}
|
||||||
|
|
||||||
|
for _, hl in ipairs(highlights) do
|
||||||
|
local s_col, e_col, name = hl[1], hl[2], hl[3]
|
||||||
|
|
||||||
|
local skip = false
|
||||||
|
for _, used in ipairs(used_ranges) do
|
||||||
|
if s_col >= used[1] and s_col < used[2] then
|
||||||
|
skip = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not skip then
|
||||||
|
if pos < s_col then
|
||||||
|
table.insert(rendered, text:sub(pos + 1, s_col))
|
||||||
|
end
|
||||||
|
|
||||||
|
local chunk = text:sub(s_col + 1, e_col)
|
||||||
|
local ansi = get_fg_ansi("@" .. name .. "." .. filetype)
|
||||||
|
if ansi == "" then
|
||||||
|
ansi = get_fg_ansi("@" .. name)
|
||||||
|
end
|
||||||
|
|
||||||
|
if ansi ~= "" then
|
||||||
|
table.insert(rendered, ansi)
|
||||||
|
table.insert(rendered, chunk)
|
||||||
|
table.insert(rendered, reset)
|
||||||
|
else
|
||||||
|
table.insert(rendered, chunk)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(used_ranges, { s_col, e_col })
|
||||||
|
pos = e_col
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if pos < #text then
|
||||||
|
table.insert(rendered, text:sub(pos + 1))
|
||||||
|
end
|
||||||
|
|
||||||
|
io.write(table.concat(rendered) .. "\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
io.flush()
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param filepath string
|
||||||
|
---@param preview_line_count number
|
||||||
|
function _G.lf.preview(filepath, preview_line_count)
|
||||||
|
vim.cmd.edit(filepath)
|
||||||
|
vim.cmd.colorscheme(vim.env.THEME)
|
||||||
|
|
||||||
|
local buf = vim.api.nvim_get_current_buf()
|
||||||
|
local lines = vim.api.nvim_buf_get_lines(buf, 0, preview_line_count, false)
|
||||||
|
|
||||||
|
local ft = vim.filetype.match({ buf = buf, filename = filepath })
|
||||||
|
|
||||||
|
local tsok, result = pcall(collect_treesitter_highlights, buf, lines, ft, preview_line_count)
|
||||||
|
|
||||||
|
if tsok and next(result) ~= nil then
|
||||||
|
render_with_treesitter(lines, result, ft)
|
||||||
|
elseif render_with_vim_syntax(lines) then
|
||||||
|
return
|
||||||
|
else
|
||||||
|
render_plain(lines)
|
||||||
|
end
|
||||||
|
end
|
||||||
72
config/lf/previewer
Executable file
72
config/lf/previewer
Executable file
|
|
@ -0,0 +1,72 @@
|
||||||
|
#!/bin/sh
|
||||||
|
FILE_PATH="$1"
|
||||||
|
w="$2"
|
||||||
|
h="$3"
|
||||||
|
x="$4"
|
||||||
|
y="$5"
|
||||||
|
|
||||||
|
CACHE_DIR="$HOME/.cache/lf/thumbnail"
|
||||||
|
mkdir -p "$CACHE_DIR"
|
||||||
|
|
||||||
|
CACHE_BASE="$CACHE_DIR/$(stat --printf '%n\0%i\0%F\0%s\0%W\0%Y' -- "$(readlink -f "$FILE_PATH")" | sha256sum | awk '{print $1}')"
|
||||||
|
|
||||||
|
get_cell_size() {
|
||||||
|
size_info=$(kitten @ get-window-size --self)
|
||||||
|
cell_w=$(echo "$size_info" | awk 'BEGIN{RS="[{} ,]"} /"xpixels"/{gsub(/"/,"",$0); split($0,a,":"); x=a[2]} /"cols"/{gsub(/"/,"",$0); split($0,a,":"); c=a[2]} END{if(c) print int(x/c); else print 8}')
|
||||||
|
cell_h=$(echo "$size_info" | awk 'BEGIN{RS="[{} ,]"} /"ypixels"/{gsub(/"/,"",$0); split($0,a,":"); y=a[2]} /"rows"/{gsub(/"/,"",$0); split($0,a,":"); r=a[2]} END{if(r) print int(y/r); else print 16}')
|
||||||
|
}
|
||||||
|
|
||||||
|
draw() {
|
||||||
|
kitten icat --stdin no --transfer-mode memory --place "${w}x${h}@${x}x${y}" "$1" </dev/null >/dev/tty
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
get_cell_size
|
||||||
|
preview_px_w=$((w * ${cell_w:-8} - 16))
|
||||||
|
preview_px_h=$((h * ${cell_h:-16} - 16))
|
||||||
|
PREVIEW_LINE_COUNT=200
|
||||||
|
|
||||||
|
mime_type=$(file -Lb --mime-type "$FILE_PATH")
|
||||||
|
|
||||||
|
case "$mime_type" in
|
||||||
|
image/gif | video/*)
|
||||||
|
if [ "$(stat -c %Y "$FILE_PATH" 2>/dev/null || echo 0)" -gt "$(stat -c %Y "${CACHE_BASE}.jpg" 2>/dev/null || echo 0)" ]; then
|
||||||
|
ffmpeg -y -i "$FILE_PATH" -vf "select=eq(n\,0),scale=${preview_px_w}:-1" -vframes 1 "${CACHE_BASE}.jpg"
|
||||||
|
fi
|
||||||
|
draw "${CACHE_BASE}.jpg"
|
||||||
|
;;
|
||||||
|
image/svg+xml | image/svg)
|
||||||
|
if [ "$(stat -c %Y "$FILE_PATH")" -gt "$(stat -c %Y "${CACHE_BASE}.png" 2>/dev/null || echo 0)" ]; then
|
||||||
|
rsvg-convert --keep-aspect-ratio --width "$preview_px_w" --format=png "$FILE_PATH" -o "${CACHE_BASE}.png"
|
||||||
|
fi
|
||||||
|
draw "${CACHE_BASE}.png"
|
||||||
|
;;
|
||||||
|
image/*)
|
||||||
|
draw "$FILE_PATH"
|
||||||
|
;;
|
||||||
|
application/pdf)
|
||||||
|
if [ "$(stat -c %Y "$FILE_PATH")" -gt "$(stat -c %Y "${CACHE_BASE}.jpg" 2>/dev/null || echo 0)" ]; then
|
||||||
|
pdftoppm -f 1 -l 1 -scale-to-x "$preview_px_w" -scale-to-y -1 -singlefile -jpeg -- "$FILE_PATH" "${CACHE_BASE}"
|
||||||
|
fi
|
||||||
|
draw "${CACHE_BASE}.jpg"
|
||||||
|
;;
|
||||||
|
application/epub+zip | application/x-mobipocket-ebook)
|
||||||
|
if [ "$(stat -c %Y "$FILE_PATH")" -gt "$(stat -c %Y "${CACHE_BASE}.png" 2>/dev/null || echo 0)" ]; then
|
||||||
|
gnome-epub-thumbnailer -s "$preview_px_w" "$FILE_PATH" "${CACHE_BASE}.png" 2>/dev/null || convert -size "${preview_px_w}x${preview_px_w}" xc:gray "${CACHE_BASE}.png"
|
||||||
|
fi
|
||||||
|
[ -f "${CACHE_BASE}.png" ] && draw "${CACHE_BASE}.png"
|
||||||
|
;;
|
||||||
|
audio/*)
|
||||||
|
if [ "$(stat -c %Y "$FILE_PATH")" -gt "$(stat -c %Y "${CACHE_BASE}.jpg" 2>/dev/null || echo 0)" ]; then
|
||||||
|
ffmpeg -y -i "$FILE_PATH" -an -vcodec copy "${CACHE_BASE}.jpg" 2>/dev/null || convert -size "${preview_px_w}x${preview_px_w}" xc:gray "${CACHE_BASE}.jpg"
|
||||||
|
fi
|
||||||
|
draw "${CACHE_BASE}.jpg"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
nvim --headless -u NONE \
|
||||||
|
-c "luafile $XDG_CONFIG_HOME/lf/lf.lua" \
|
||||||
|
-c "lua lf.setup()" \
|
||||||
|
-c "lua lf.preview([[${FILE_PATH}]], ${PREVIEW_LINE_COUNT})" \
|
||||||
|
-c "quitall!"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
53
config/lf/sort.py
Executable file
53
config/lf/sort.py
Executable file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def categorize_and_sort(directory: str) -> list[str]:
|
||||||
|
try:
|
||||||
|
entries = os.listdir(directory)
|
||||||
|
except (PermissionError, FileNotFoundError):
|
||||||
|
return []
|
||||||
|
|
||||||
|
folders: list[str] = []
|
||||||
|
files: list[str] = []
|
||||||
|
dotfolders: list[str] = []
|
||||||
|
dotfiles: list[str] = []
|
||||||
|
|
||||||
|
for entry in entries:
|
||||||
|
full_path = os.path.join(directory, entry)
|
||||||
|
is_hidden = entry.startswith(".")
|
||||||
|
is_dir = os.path.isdir(full_path)
|
||||||
|
|
||||||
|
if not is_hidden and is_dir:
|
||||||
|
folders.append(entry)
|
||||||
|
elif not is_hidden and not is_dir:
|
||||||
|
files.append(entry)
|
||||||
|
elif is_hidden and is_dir:
|
||||||
|
dotfolders.append(entry)
|
||||||
|
else:
|
||||||
|
dotfiles.append(entry)
|
||||||
|
|
||||||
|
folders.sort(key=str.lower)
|
||||||
|
files.sort(key=str.lower)
|
||||||
|
dotfolders.sort(key=str.lower)
|
||||||
|
dotfiles.sort(key=str.lower)
|
||||||
|
|
||||||
|
return folders + files + dotfolders + dotfiles
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
directory = os.getcwd()
|
||||||
|
else:
|
||||||
|
directory = sys.argv[1]
|
||||||
|
|
||||||
|
sorted_entries = categorize_and_sort(directory)
|
||||||
|
|
||||||
|
for entry in sorted_entries:
|
||||||
|
print(entry)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
18
config/nvim/.luacheckrc
Normal file
18
config/nvim/.luacheckrc
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
-- Rerun tests only if their modification time changed.
|
||||||
|
cache = true
|
||||||
|
|
||||||
|
ignore = {
|
||||||
|
"122", -- Setting a read-only field of a global variable.
|
||||||
|
"212", -- Unused argument, In the case of callback function, _arg_name is easier to understand than _, so this option is set to off.
|
||||||
|
"631", -- max_line_length, vscode pkg URL is too long
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Global objects defined by the C code
|
||||||
|
read_globals = {
|
||||||
|
"vim",
|
||||||
|
}
|
||||||
|
|
||||||
|
include_files = { "lua", "tests" }
|
||||||
|
exclude_files = { ".luacheckrc", "tests/**/*_spec.lua" }
|
||||||
|
|
||||||
|
-- vim: ft=lua tw=80
|
||||||
1
config/nvim/after/ftplugin/c.lua
Normal file
1
config/nvim/after/ftplugin/c.lua
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
vim.o.shiftwidth = 2
|
||||||
1
config/nvim/after/ftplugin/cpp.lua
Normal file
1
config/nvim/after/ftplugin/cpp.lua
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
vim.opt.indentkeys:remove(':')
|
||||||
2
config/nvim/after/ftplugin/fugitive.lua
Normal file
2
config/nvim/after/ftplugin/fugitive.lua
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
bmap({ 'n', '<leader>Gh', '<cmd>diffget //2<cr>' })
|
||||||
|
bmap({ 'n', '<leader>Gl', '<cmd>diffget //3<cr>' })
|
||||||
5
config/nvim/after/ftplugin/help.lua
Normal file
5
config/nvim/after/ftplugin/help.lua
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
vim.o.number = true
|
||||||
|
vim.o.conceallevel = 0
|
||||||
|
vim.o.relativenumber = true
|
||||||
|
|
||||||
|
bmap({ 'n', 'q', vim.cmd.helpclose })
|
||||||
2
config/nvim/after/ftplugin/html.lua
Normal file
2
config/nvim/after/ftplugin/html.lua
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
vim.o.shiftwidth = 2
|
||||||
|
vim.o.textwidth = 80
|
||||||
1
config/nvim/after/ftplugin/htmldjango.lua
Normal file
1
config/nvim/after/ftplugin/htmldjango.lua
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
vim.o.shiftwidth = 2
|
||||||
2
config/nvim/after/ftplugin/javascript.lua
Normal file
2
config/nvim/after/ftplugin/javascript.lua
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
vim.o.shiftwidth = 2
|
||||||
|
vim.o.makeprg = 'node %'
|
||||||
2
config/nvim/after/ftplugin/man.lua
Normal file
2
config/nvim/after/ftplugin/man.lua
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
vim.o.number = true
|
||||||
|
vim.o.relativenumber = true
|
||||||
2
config/nvim/after/ftplugin/markdown.lua
Normal file
2
config/nvim/after/ftplugin/markdown.lua
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
vim.o.conceallevel = 1
|
||||||
|
vim.o.textwidth = 80
|
||||||
1
config/nvim/after/ftplugin/python.lua
Normal file
1
config/nvim/after/ftplugin/python.lua
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
vim.o.makeprg = 'python %'
|
||||||
1
config/nvim/after/ftplugin/rust.lua
Normal file
1
config/nvim/after/ftplugin/rust.lua
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
vim.o.makeprg = 'cargo run'
|
||||||
1
config/nvim/after/ftplugin/sh.lua
Normal file
1
config/nvim/after/ftplugin/sh.lua
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
vim.o.makeprg = 'sh %'
|
||||||
103
config/nvim/after/plugin/lsp.lua
Normal file
103
config/nvim/after/plugin/lsp.lua
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
local lsp = require('config.lsp')
|
||||||
|
|
||||||
|
vim.diagnostic.config({
|
||||||
|
signs = false,
|
||||||
|
float = {
|
||||||
|
format = function(diagnostic)
|
||||||
|
return ('%s (%s)'):format(diagnostic.message, diagnostic.source)
|
||||||
|
end,
|
||||||
|
header = '',
|
||||||
|
prefix = ' ',
|
||||||
|
},
|
||||||
|
jump = { float = true },
|
||||||
|
})
|
||||||
|
|
||||||
|
local function prepare_capabilities()
|
||||||
|
local capabilities = vim.lsp.protocol.make_client_capabilities()
|
||||||
|
capabilities.textDocument.completion.completionItem.snippetSupport = false
|
||||||
|
|
||||||
|
local ok, blink = pcall(require, 'blink.cmp')
|
||||||
|
|
||||||
|
return ok and blink.get_lsp_capabilities(capabilities) or capabilities
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.lsp.config('*', {
|
||||||
|
on_attach = lsp.on_attach,
|
||||||
|
capabilities = prepare_capabilities(),
|
||||||
|
flags = { debounce_text_changes = 0 },
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.api.nvim_create_autocmd('LspAttach', {
|
||||||
|
callback = function(opts)
|
||||||
|
local client = vim.lsp.get_client_by_id(opts.data.client_id)
|
||||||
|
|
||||||
|
if
|
||||||
|
client
|
||||||
|
and (
|
||||||
|
client:supports_method('textDocument/formatting')
|
||||||
|
or client:supports_method('formatting')
|
||||||
|
)
|
||||||
|
then
|
||||||
|
local modes = { 'n' }
|
||||||
|
|
||||||
|
if
|
||||||
|
client:supports_method('textDocument/rangeFormatting')
|
||||||
|
or client:supports_method('rangeFormatting')
|
||||||
|
then
|
||||||
|
table.insert(modes, 'x')
|
||||||
|
end
|
||||||
|
|
||||||
|
bmap({
|
||||||
|
modes,
|
||||||
|
'gF',
|
||||||
|
lsp.format,
|
||||||
|
}, { buffer = opts.buf, silent = false })
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
group = vim.api.nvim_create_augroup('ALspFormat', { clear = true }),
|
||||||
|
})
|
||||||
|
|
||||||
|
for _, server in ipairs({
|
||||||
|
'bashls',
|
||||||
|
'basedpyright',
|
||||||
|
'clangd',
|
||||||
|
'cssls',
|
||||||
|
'emmet_language_server',
|
||||||
|
'eslint',
|
||||||
|
'html',
|
||||||
|
'mdx_analyzer',
|
||||||
|
'jsonls',
|
||||||
|
'vtsls',
|
||||||
|
'pytest_lsp',
|
||||||
|
'lua_ls',
|
||||||
|
'ruff',
|
||||||
|
'tinymist',
|
||||||
|
}) do
|
||||||
|
local ok, config = pcall(require, 'lsp.' .. server)
|
||||||
|
if ok and config then
|
||||||
|
vim.lsp.config(server, config)
|
||||||
|
else
|
||||||
|
vim.lsp.config(server, {})
|
||||||
|
end
|
||||||
|
vim.lsp.enable(server)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- remove duplicate entries from goto defintion list
|
||||||
|
-- example: https://github.com/LuaLS/lua-language-server/issues/2451
|
||||||
|
local locations_to_items = vim.lsp.util.locations_to_items
|
||||||
|
vim.lsp.util.locations_to_items = function(locations, offset_encoding)
|
||||||
|
local lines = {}
|
||||||
|
local loc_i = 1
|
||||||
|
for _, loc in ipairs(vim.deepcopy(locations)) do
|
||||||
|
local uri = loc.uri or loc.targetUri
|
||||||
|
local range = loc.range or loc.targetSelectionRange
|
||||||
|
if lines[uri .. range.start.line] then
|
||||||
|
table.remove(locations, loc_i)
|
||||||
|
else
|
||||||
|
loc_i = loc_i + 1
|
||||||
|
end
|
||||||
|
lines[uri .. range.start.line] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
return locations_to_items(locations, offset_encoding)
|
||||||
|
end
|
||||||
5
config/nvim/after/queries/html/highlights.scm.disabled
Normal file
5
config/nvim/after/queries/html/highlights.scm.disabled
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
;; extends
|
||||||
|
(attribute (attribute_name) @att_name (#eq? @att_name "class")
|
||||||
|
(quoted_attribute_value (attribute_value) @att_val (#set! @att_val conceal ".")
|
||||||
|
)
|
||||||
|
)
|
||||||
5
config/nvim/after/queries/javascript/highlights.scm
Normal file
5
config/nvim/after/queries/javascript/highlights.scm
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
;; extends
|
||||||
|
(jsx_attribute (property_identifier) @att_name (#eq? @att_name "className")
|
||||||
|
(string (string_fragment) @att_val (#set! @att_val conceal ".")
|
||||||
|
)
|
||||||
|
)
|
||||||
2
config/nvim/after/queries/jsx/highlights.scm
Normal file
2
config/nvim/after/queries/jsx/highlights.scm
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
;; inherits: jsx
|
||||||
|
;; extends
|
||||||
2
config/nvim/after/queries/tsx/highlights.scm
Normal file
2
config/nvim/after/queries/tsx/highlights.scm
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
;; inherits: jsx
|
||||||
|
;; extends
|
||||||
10
config/nvim/filetype.lua
Normal file
10
config/nvim/filetype.lua
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
vim.filetype.add({
|
||||||
|
extension = {
|
||||||
|
log = 'log',
|
||||||
|
mdx = 'mdx',
|
||||||
|
},
|
||||||
|
filename = {
|
||||||
|
['requirements.txt'] = 'config',
|
||||||
|
dunstrc = 'dosini'
|
||||||
|
},
|
||||||
|
})
|
||||||
65
config/nvim/init.lua
Normal file
65
config/nvim/init.lua
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
vim.g.mapleader = ' '
|
||||||
|
|
||||||
|
function _G.map(mapping, opts)
|
||||||
|
vim.keymap.set(
|
||||||
|
mapping[1],
|
||||||
|
mapping[2],
|
||||||
|
mapping[3],
|
||||||
|
vim.tbl_extend('keep', opts or {}, { silent = true })
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
function _G.bmap(mapping, opts)
|
||||||
|
_G.map(mapping, vim.tbl_extend('force', opts or {}, { buffer = 0 }))
|
||||||
|
end
|
||||||
|
local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim'
|
||||||
|
if not vim.uv.fs_stat(lazypath) then
|
||||||
|
vim.fn.system({
|
||||||
|
'git',
|
||||||
|
'clone',
|
||||||
|
'https://github.com/folke/lazy.nvim.git',
|
||||||
|
lazypath,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.opt.rtp:prepend(lazypath)
|
||||||
|
require('lazy').setup('plugins', {
|
||||||
|
git = { url_format = 'git@github.com:%s.git' },
|
||||||
|
change_detection = { enabled = false },
|
||||||
|
performance = {
|
||||||
|
cache = {
|
||||||
|
enabled = true,
|
||||||
|
},
|
||||||
|
reset_packpath = true,
|
||||||
|
rtp = {
|
||||||
|
reset = true,
|
||||||
|
disabled_plugins = {
|
||||||
|
'gzip',
|
||||||
|
'netrwPlugin',
|
||||||
|
'tarPlugin',
|
||||||
|
'tohtml',
|
||||||
|
'tutor',
|
||||||
|
'zipPlugin',
|
||||||
|
'2html_plugin',
|
||||||
|
'getscript',
|
||||||
|
'getscriptPlugin',
|
||||||
|
'logipat',
|
||||||
|
'netrw',
|
||||||
|
'netrwSettings',
|
||||||
|
'netrwFileHandlers',
|
||||||
|
'tar',
|
||||||
|
'tarPlugin',
|
||||||
|
'rrhelper',
|
||||||
|
'vimball',
|
||||||
|
'vimballPlugin',
|
||||||
|
'zip',
|
||||||
|
'zipPlugin',
|
||||||
|
'tutor',
|
||||||
|
'rplugin',
|
||||||
|
'synmenu',
|
||||||
|
'optwin',
|
||||||
|
'bugreport',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
50
config/nvim/lazy-lock.json
Normal file
50
config/nvim/lazy-lock.json
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
{
|
||||||
|
"LuaSnip": { "branch": "master", "commit": "dae4f5aaa3574bd0c2b9dd20fb9542a02c10471c" },
|
||||||
|
"SchemaStore.nvim": { "branch": "main", "commit": "cd9e8c22f6ad2012ac395725080cc5737297d840" },
|
||||||
|
"blink.cmp": { "branch": "main", "commit": "b137f63d89d0285ca76eed12e1923220e0aff8c1" },
|
||||||
|
"blink.indent": { "branch": "main", "commit": "9c80820ca77218a8d28e70075d6f44a1609911fe" },
|
||||||
|
"cloak.nvim": { "branch": "main", "commit": "648aca6d33ec011dc3166e7af3b38820d01a71e4" },
|
||||||
|
"dial.nvim": { "branch": "master", "commit": "f2634758455cfa52a8acea6f142dcd6271a1bf57" },
|
||||||
|
"format-ts-errors.nvim": { "branch": "main", "commit": "4b7418d6689bc0fd3c1db0500c67133422522384" },
|
||||||
|
"fzf-lua": { "branch": "main", "commit": "1cd4d8f36789061aa7b7d0718bc13849f92d6d77" },
|
||||||
|
"gitsigns.nvim": { "branch": "main", "commit": "abf82a65f185bd54adc0679f74b7d6e1ada690c9" },
|
||||||
|
"grapple.nvim": { "branch": "main", "commit": "b41ddfc1c39f87f3d1799b99c2f0f1daa524c5f7" },
|
||||||
|
"highlight-undo.nvim": { "branch": "main", "commit": "ee32e12693d70e66f954d09a504a7371d110fc27" },
|
||||||
|
"lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
|
||||||
|
"lazydev.nvim": { "branch": "main", "commit": "5231c62aa83c2f8dc8e7ba957aa77098cda1257d" },
|
||||||
|
"live-rename.nvim": { "branch": "main", "commit": "3a3cddf23b89a17992f9ca67afc5858077769462" },
|
||||||
|
"live-server.nvim": { "branch": "main", "commit": "58f2e30e029a57dbda15c5749edd8d642578859f" },
|
||||||
|
"markdown-preview.nvim": { "branch": "master", "commit": "a923f5fc5ba36a3b17e289dc35dc17f66d0548ee" },
|
||||||
|
"mini.bufremove": { "branch": "main", "commit": "10857aa39160c127694151828914df3131ba83b6" },
|
||||||
|
"mini.misc": { "branch": "main", "commit": "b647b64321c34d4868d158282bb89e49f0d6838b" },
|
||||||
|
"mini.pairs": { "branch": "main", "commit": "4089aa6ea6423e02e1a8326a7a7a00159f6f5e04" },
|
||||||
|
"none-ls-extras.nvim": { "branch": "main", "commit": "6ced4fc4072c7b269ba95bb596196cc76e00b280" },
|
||||||
|
"none-ls.nvim": { "branch": "main", "commit": "3c206dfedf5f1385e9d29f85ffaec7874358592a" },
|
||||||
|
"nvim-colorizer.lua": { "branch": "master", "commit": "81e676d3203c9eb6e4c0ccf1eba1679296ef923f" },
|
||||||
|
"nvim-lspconfig": { "branch": "master", "commit": "419b082102fa813739588dd82e19a8b6b2442855" },
|
||||||
|
"nvim-navic": { "branch": "master", "commit": "f5eba192f39b453675d115351808bd51276d9de5" },
|
||||||
|
"nvim-surround": { "branch": "main", "commit": "1098d7b3c34adcfa7feb3289ee434529abd4afd1" },
|
||||||
|
"nvim-treesitter": { "branch": "main", "commit": "568ede7e79172a0fe7c9d631454a97ad968deaf2" },
|
||||||
|
"nvim-treesitter-textobjects": { "branch": "main", "commit": "52bda74e087034408e2d563cb4499c1601038f9d" },
|
||||||
|
"nvim-vtsls": { "branch": "main", "commit": "0b5f73c9e50ce95842ea07bb3f05c7d66d87d14a" },
|
||||||
|
"oil.nvim": { "branch": "master", "commit": "f55b25e493a7df76371cfadd0ded5004cb9cd48a" },
|
||||||
|
"overseer.nvim": { "branch": "master", "commit": "5828bdbd86677497613033c142f0a8624489216f" },
|
||||||
|
"plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" },
|
||||||
|
"rustaceanvim": { "branch": "master", "commit": "796f06742e373012b860dc20f9ecccbfc670dc28" },
|
||||||
|
"snacks.nvim": { "branch": "main", "commit": "fe7cfe9800a182274d0f868a74b7263b8c0c020b" },
|
||||||
|
"telescope.nvim": { "branch": "master", "commit": "ad7d9580338354ccc136e5b8f0aa4f880434dcdc" },
|
||||||
|
"treesj": { "branch": "main", "commit": "186084dee5e9c8eec40f6e39481c723dd567cb05" },
|
||||||
|
"typescript-tools.nvim": { "branch": "master", "commit": "c2f5910074103705661e9651aa841e0d7eea9932" },
|
||||||
|
"typst-preview.nvim": { "branch": "master", "commit": "e123a7ab64e52d836e00dea9251e85b201f38966" },
|
||||||
|
"vim-abolish": { "branch": "master", "commit": "dcbfe065297d31823561ba787f51056c147aa682" },
|
||||||
|
"vim-fugitive": { "branch": "master", "commit": "61b51c09b7c9ce04e821f6cf76ea4f6f903e3cf4" },
|
||||||
|
"vim-jsx-pretty": { "branch": "master", "commit": "6989f1663cc03d7da72b5ef1c03f87e6ddb70b41" },
|
||||||
|
"vim-sleuth": { "branch": "master", "commit": "be69bff86754b1aa5adcbb527d7fcd1635a84080" },
|
||||||
|
"vim-textobj-entire": { "branch": "master", "commit": "64a856c9dff3425ed8a863b9ec0a21dbaee6fb3a" },
|
||||||
|
"vim-textobj-indent": { "branch": "master", "commit": "deb76867c302f933c8f21753806cbf2d8461b548" },
|
||||||
|
"vim-textobj-line": { "branch": "master", "commit": "1a6780d29adcf7e464e8ddbcd0be0a9df1a37339" },
|
||||||
|
"vim-textobj-sentence": { "branch": "master", "commit": "c5dd562aff2c389dfc8cd55e6499854d352a80b8" },
|
||||||
|
"vim-textobj-user": { "branch": "master", "commit": "41a675ddbeefd6a93664a4dc52f302fe3086a933" },
|
||||||
|
"vim-textobj-xmlattr": { "branch": "master", "commit": "694a297f1d75fd527e87da9769f3c6519a87ebb1" },
|
||||||
|
"vimtex": { "branch": "master", "commit": "f707368022cdb851716be0d2970b90599c84a6a6" }
|
||||||
|
}
|
||||||
156
config/nvim/lua/config/fold.lua
Normal file
156
config/nvim/lua/config/fold.lua
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
--- @class Fold
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
---@param bufnr number the buffer number
|
||||||
|
---@return boolean whether the below foldexpr() is applicable to the buffer
|
||||||
|
local function is_foldexpr(bufnr)
|
||||||
|
local ok, parser = pcall(vim.treesitter.get_parser, bufnr)
|
||||||
|
return ok and parser
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @return string Fold level (as string for foldexpr)
|
||||||
|
function M.foldexpr()
|
||||||
|
local line = vim.v.lnum
|
||||||
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
|
local foldnestmax = vim.wo.foldnestmax
|
||||||
|
local ok, parser = pcall(vim.treesitter.get_parser, bufnr)
|
||||||
|
if not ok or not parser then
|
||||||
|
return '0'
|
||||||
|
end
|
||||||
|
local trees = parser:parse()
|
||||||
|
if not trees or #trees == 0 then
|
||||||
|
return '0'
|
||||||
|
end
|
||||||
|
local root = trees[1]:root()
|
||||||
|
local line_text = vim.fn.getline(line)
|
||||||
|
local positions = {}
|
||||||
|
local first_col = line_text:match('^%s*()')
|
||||||
|
if first_col and first_col <= #line_text then
|
||||||
|
table.insert(positions, first_col - 1)
|
||||||
|
end
|
||||||
|
local last_col = line_text:find('%S%s*$')
|
||||||
|
if last_col then
|
||||||
|
table.insert(positions, last_col - 1)
|
||||||
|
end
|
||||||
|
if #positions == 0 then
|
||||||
|
table.insert(positions, 0)
|
||||||
|
end
|
||||||
|
local function is_foldable(node_type)
|
||||||
|
return
|
||||||
|
-- functions/methods
|
||||||
|
node_type == 'function_definition'
|
||||||
|
or node_type == 'function_declaration'
|
||||||
|
or node_type == 'method_definition'
|
||||||
|
or node_type == 'method_declaration'
|
||||||
|
or node_type == 'function_item'
|
||||||
|
-- structs/unions
|
||||||
|
or node_type == 'class_definition'
|
||||||
|
or node_type == 'class_declaration'
|
||||||
|
or node_type == 'class_specifier'
|
||||||
|
or node_type == 'struct_item'
|
||||||
|
or node_type == 'struct_specifier'
|
||||||
|
or node_type == 'struct_type'
|
||||||
|
-- interfaces
|
||||||
|
or node_type == 'union_specifier'
|
||||||
|
or node_type == 'interface_declaration'
|
||||||
|
or node_type == 'interface_definition'
|
||||||
|
or node_type == 'interface_type'
|
||||||
|
-- type decls/defs
|
||||||
|
or node_type == 'type_declaration'
|
||||||
|
or node_type == 'type_definition'
|
||||||
|
-- traits
|
||||||
|
or node_type == 'trait_item'
|
||||||
|
-- enums
|
||||||
|
or node_type == 'enum_declaration'
|
||||||
|
or node_type == 'enum_specifier'
|
||||||
|
-- namespace/modules
|
||||||
|
or node_type == 'enum_item'
|
||||||
|
or node_type == 'impl_item'
|
||||||
|
or node_type == 'namespace_definition'
|
||||||
|
or node_type == 'namespace_declaration'
|
||||||
|
or node_type == 'internal_module'
|
||||||
|
or node_type == 'mod_item'
|
||||||
|
end
|
||||||
|
local function should_fold(n)
|
||||||
|
if not n then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local srow, _, erow, _ = n:range()
|
||||||
|
return (erow - srow + 1) >= vim.wo.foldminlines
|
||||||
|
end
|
||||||
|
local function nested_fold_level(node)
|
||||||
|
if not node then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
local level = 0
|
||||||
|
local temp = node
|
||||||
|
while temp do
|
||||||
|
if is_foldable(temp:type()) and should_fold(temp) then
|
||||||
|
level = level + 1
|
||||||
|
end
|
||||||
|
temp = temp:parent()
|
||||||
|
end
|
||||||
|
return level
|
||||||
|
end
|
||||||
|
local function starts_on_line(n)
|
||||||
|
local srow, _, _, _ = n:range()
|
||||||
|
return srow + 1 == line
|
||||||
|
end
|
||||||
|
local max_level = 0
|
||||||
|
local is_start = false
|
||||||
|
for _, col in ipairs(positions) do
|
||||||
|
local node =
|
||||||
|
root:named_descendant_for_range(line - 1, col, line - 1, col)
|
||||||
|
if node then
|
||||||
|
local raw_level = nested_fold_level(node)
|
||||||
|
max_level = math.max(max_level, math.min(raw_level, foldnestmax))
|
||||||
|
local temp = node
|
||||||
|
while temp do
|
||||||
|
local this_level = nested_fold_level(temp)
|
||||||
|
if
|
||||||
|
is_foldable(temp:type())
|
||||||
|
and should_fold(temp)
|
||||||
|
and starts_on_line(temp)
|
||||||
|
and this_level <= foldnestmax
|
||||||
|
then
|
||||||
|
is_start = true
|
||||||
|
end
|
||||||
|
temp = temp:parent()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if max_level == 0 then
|
||||||
|
return '0'
|
||||||
|
end
|
||||||
|
if is_start then
|
||||||
|
return '>' .. max_level
|
||||||
|
end
|
||||||
|
return tostring(max_level)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function M.setup()
|
||||||
|
vim.opt.fillchars:append({
|
||||||
|
fold = ' ',
|
||||||
|
foldopen = 'v',
|
||||||
|
foldclose = '>',
|
||||||
|
foldsep = ' ',
|
||||||
|
})
|
||||||
|
vim.o.foldlevel = 1
|
||||||
|
vim.o.foldtext = ''
|
||||||
|
vim.o.foldnestmax = 2
|
||||||
|
vim.o.foldminlines = 5
|
||||||
|
vim.api.nvim_create_autocmd('FileType', {
|
||||||
|
pattern = '*',
|
||||||
|
callback = function(opts)
|
||||||
|
-- do not override fold settings if not applicable
|
||||||
|
if is_foldexpr(opts.bufnr) then
|
||||||
|
vim.wo.foldmethod = 'expr'
|
||||||
|
vim.wo.foldexpr = 'v:lua.require("config.fold").foldexpr()'
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
group = vim.api.nvim_create_augroup('AFold', { clear = true }),
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
32
config/nvim/lua/config/fzf_reload.lua
Normal file
32
config/nvim/lua/config/fzf_reload.lua
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
local M = {}
|
||||||
|
M.opts = nil
|
||||||
|
|
||||||
|
function M.setup(opts)
|
||||||
|
M.opts = vim.deepcopy(opts)
|
||||||
|
-- allow connections from `theme` script
|
||||||
|
local socket_path = ('/tmp/nvim-%d.sock'):format(vim.fn.getpid())
|
||||||
|
vim.fn.serverstart(socket_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@disable_fzf_lua_reload boolean?
|
||||||
|
function M.reload(disable_fzf_lua_reload)
|
||||||
|
local lines = vim.fn.readfile(vim.fn.expand('~/.config/fzf/themes/theme'))
|
||||||
|
if not lines or #lines == 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local colors = {}
|
||||||
|
for color_spec in table.concat(lines, '\n'):gmatch('--color=([^%s]+)') do
|
||||||
|
for k, v in color_spec:gmatch('([^:,]+):([^,]+)') do
|
||||||
|
colors[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not M.opts then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
M.opts.fzf_colors = colors
|
||||||
|
if not disable_fzf_lua_reload then
|
||||||
|
require('fzf-lua').setup(M.opts)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
7
config/nvim/lua/config/lines/init.lua
Normal file
7
config/nvim/lua/config/lines/init.lua
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
return {
|
||||||
|
setup = function()
|
||||||
|
vim.o.statusline = '%!v:lua.require("config.lines.statusline").statusline()'
|
||||||
|
vim.o.statuscolumn =
|
||||||
|
'%!v:lua.require("config.lines.statuscolumn").statuscolumn()'
|
||||||
|
end,
|
||||||
|
}
|
||||||
25
config/nvim/lua/config/lines/statuscolumn.lua
Normal file
25
config/nvim/lua/config/lines/statuscolumn.lua
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
return {
|
||||||
|
num = function()
|
||||||
|
if math.abs(vim.v.virtnum) > 0 then
|
||||||
|
return ''
|
||||||
|
elseif vim.v.relnum == 0 then
|
||||||
|
return '%#CursorLineNr#' .. vim.v.lnum
|
||||||
|
end
|
||||||
|
|
||||||
|
return '%#LineNr#' .. vim.v.relnum
|
||||||
|
end,
|
||||||
|
fold = function()
|
||||||
|
local expr = require('config.fold').foldexpr()
|
||||||
|
if expr:sub(1, 1) == '>' then
|
||||||
|
if vim.fn.foldclosed(vim.v.lnum) ~= -1 then
|
||||||
|
return '>'
|
||||||
|
else
|
||||||
|
return 'v'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return ' '
|
||||||
|
end,
|
||||||
|
statuscolumn = function()
|
||||||
|
return '%{%v:lua.require("config.lines.statuscolumn").fold()%}%s%=%{%v:lua.require("config.lines.statuscolumn").num()%} '
|
||||||
|
end,
|
||||||
|
}
|
||||||
139
config/nvim/lua/config/lines/statusline.lua
Normal file
139
config/nvim/lua/config/lines/statusline.lua
Normal file
|
|
@ -0,0 +1,139 @@
|
||||||
|
local empty = require('config.utils').empty
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
local mode = {
|
||||||
|
prefix = 'mode',
|
||||||
|
-- highlight = 'white',
|
||||||
|
value = function()
|
||||||
|
local mode_to_text = {
|
||||||
|
n = 'NORMAL',
|
||||||
|
i = 'INSERT',
|
||||||
|
v = 'VISUAL',
|
||||||
|
V = 'V-LINE',
|
||||||
|
['\22'] = 'V-BLOCK',
|
||||||
|
R = 'REPLACE',
|
||||||
|
c = 'COMMAND',
|
||||||
|
}
|
||||||
|
|
||||||
|
return mode_to_text[vim.fn.mode()]
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
local file = {
|
||||||
|
prefix = 'fp',
|
||||||
|
-- highlight = 'blue',
|
||||||
|
value = function()
|
||||||
|
return vim.fn.expand('%:~')
|
||||||
|
-- return vim.fn.pathshorten(vim.fn.expand('%:~'))
|
||||||
|
-- return vim.fn.fnamemodify(
|
||||||
|
-- vim.fn.bufname(vim.api.nvim_get_current_buf()),
|
||||||
|
-- ':~:.'
|
||||||
|
-- )
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
local git = {
|
||||||
|
prefix = 'git',
|
||||||
|
-- highlight = 'magenta',
|
||||||
|
value = function()
|
||||||
|
return vim.b.gitsigns_head
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
local modified = {
|
||||||
|
value = function()
|
||||||
|
return vim.api.nvim_get_option_value('modified', { buf = 0 }) and '+w'
|
||||||
|
or ''
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
local navic = {
|
||||||
|
prefix = 'loc',
|
||||||
|
value = function()
|
||||||
|
return require('nvim-navic').get_location()
|
||||||
|
end,
|
||||||
|
condition = function()
|
||||||
|
local ok, _ = pcall(require, 'nvim-navic')
|
||||||
|
return ok
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
local search = {
|
||||||
|
prefix = '/',
|
||||||
|
value = function()
|
||||||
|
local count = vim.fn.searchcount({ maxcount = 999 })
|
||||||
|
|
||||||
|
return string.format(
|
||||||
|
'%s (%s/%d)',
|
||||||
|
vim.fn.getreg('/'),
|
||||||
|
count.current,
|
||||||
|
count.total
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
condition = function()
|
||||||
|
local status, searchcount = pcall(vim.fn.searchcount)
|
||||||
|
|
||||||
|
if not status or not searchcount or vim.tbl_isempty(searchcount) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
return searchcount.total > 0
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
local filetype = {
|
||||||
|
prefix = function()
|
||||||
|
return empty(
|
||||||
|
vim.api.nvim_get_option_value(
|
||||||
|
'filetype',
|
||||||
|
{ buf = vim.api.nvim_get_current_buf() }
|
||||||
|
)
|
||||||
|
) and 'bt' or 'ft'
|
||||||
|
end,
|
||||||
|
-- highlight = 'green',
|
||||||
|
value = function()
|
||||||
|
local ft = vim.api.nvim_get_option_value(
|
||||||
|
'filetype',
|
||||||
|
{ buf = vim.api.nvim_get_current_buf() }
|
||||||
|
)
|
||||||
|
|
||||||
|
if empty(ft) then
|
||||||
|
ft = vim.bo.buftype
|
||||||
|
end
|
||||||
|
|
||||||
|
return ft
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
local lineinfo = {
|
||||||
|
prefix = 'lnnr',
|
||||||
|
-- highlight = 'yellow',
|
||||||
|
value = '%c:%l/%L',
|
||||||
|
}
|
||||||
|
|
||||||
|
M.components = {
|
||||||
|
left = {
|
||||||
|
[1] = mode,
|
||||||
|
[2] = git,
|
||||||
|
[3] = file,
|
||||||
|
[4] = navic,
|
||||||
|
[5] = modified,
|
||||||
|
},
|
||||||
|
right = {
|
||||||
|
[1] = search,
|
||||||
|
[2] = lineinfo,
|
||||||
|
[3] = filetype,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
local format_components = require('config.lines.utils').format_components
|
||||||
|
|
||||||
|
M.statusline = function()
|
||||||
|
return ('%s%%=%s'):format(
|
||||||
|
format_components(M.components.left),
|
||||||
|
format_components(M.components.right)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
41
config/nvim/lua/config/lines/utils.lua
Normal file
41
config/nvim/lua/config/lines/utils.lua
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
local utils = require('config.utils')
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
local function vorfn(val_or_fn)
|
||||||
|
if type(val_or_fn) == 'function' then
|
||||||
|
return val_or_fn()
|
||||||
|
end
|
||||||
|
|
||||||
|
return val_or_fn
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.format_components(components)
|
||||||
|
local side = {}
|
||||||
|
|
||||||
|
for i = 1, #components do
|
||||||
|
local component = components[i]
|
||||||
|
|
||||||
|
local highlight = vim.env.THEME == 'midnight' and 'Normal'
|
||||||
|
or component.highlight
|
||||||
|
|
||||||
|
if
|
||||||
|
vorfn(component.condition) ~= false
|
||||||
|
and not utils.empty(vorfn(component.value))
|
||||||
|
then
|
||||||
|
side[#side + 1] = ('%%#%s#%s%%#%s#'):format(
|
||||||
|
highlight,
|
||||||
|
vorfn(component.value),
|
||||||
|
component.highlight or 'Normal'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if #side > 0 then
|
||||||
|
return (' %s '):format(table.concat(side, ' │ '))
|
||||||
|
end
|
||||||
|
|
||||||
|
return ''
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
97
config/nvim/lua/config/lsp.lua
Normal file
97
config/nvim/lua/config/lsp.lua
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
local Methods = vim.lsp.protocol.Methods
|
||||||
|
|
||||||
|
function M.on_attach(client, bufnr)
|
||||||
|
if client:supports_method(Methods.textDocument_hover) then
|
||||||
|
bmap({ 'n', 'K', vim.lsp.buf.hover })
|
||||||
|
end
|
||||||
|
|
||||||
|
if client:supports_method(Methods.textDocument_documentSymbol) then
|
||||||
|
local ok, navic = pcall(require, 'nvim-navic')
|
||||||
|
if ok then
|
||||||
|
navic.attach(client, bufnr)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok, _ = pcall(require, 'fzf-lua')
|
||||||
|
|
||||||
|
local mappings = {
|
||||||
|
{
|
||||||
|
Methods.textDocument_codeAction,
|
||||||
|
'gra',
|
||||||
|
ok and '<cmd>FzfLua lsp_code_actions<CR>'
|
||||||
|
or vim.lsp.buf.code_action,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Methods.textDocument_declaration,
|
||||||
|
'gD',
|
||||||
|
ok and '<cmd>FzfLua lsp_declarations<CR>'
|
||||||
|
or vim.lsp.buf.declaration,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Methods.textDocument_definition,
|
||||||
|
'gd',
|
||||||
|
ok and '<cmd>FzfLua lsp_definitions<CR>' or vim.lsp.buf.definition,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Methods.textDocument_implementation,
|
||||||
|
'gri',
|
||||||
|
ok and '<cmd>FzfLua lsp_implementations<CR>'
|
||||||
|
or vim.lsp.buf.implementation,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Methods.textDocument_references,
|
||||||
|
'grr',
|
||||||
|
ok and '<cmd>FzfLua lsp_references<CR>' or vim.lsp.buf.references,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Methods.textDocument_typeDefinition,
|
||||||
|
'grt',
|
||||||
|
ok and '<cmd>FzfLua lsp_typedefs<CR>'
|
||||||
|
or vim.lsp.buf.type_definition,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Methods.textDocument_documentSymbol,
|
||||||
|
'gs',
|
||||||
|
ok and '<cmd>FzfLua lsp_document_symbols<CR>'
|
||||||
|
or vim.lsp.buf.document_symbol,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Methods.workspace_diagnostic,
|
||||||
|
'gw',
|
||||||
|
ok and '<cmd>FzfLua lsp_workspace_diagnostics<CR>'
|
||||||
|
or vim.diagnostic.setqflist,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Methods.workspace_symbol,
|
||||||
|
'gS',
|
||||||
|
ok and '<cmd>FzfLua lsp_workspace_symbols<CR>'
|
||||||
|
or vim.lsp.buf.workspace_symbol,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, m in ipairs(mappings) do
|
||||||
|
local method, key, cmd = unpack(m)
|
||||||
|
if client:supports_method(method) then
|
||||||
|
bmap({ 'n', key, cmd })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local FORMAT_LSPS = { 'null-ls', 'clangd', 'tinymist', 'ruff' }
|
||||||
|
|
||||||
|
function M.format(opts)
|
||||||
|
local format_opts = vim.tbl_extend('force', opts or {}, {
|
||||||
|
filter = function(c)
|
||||||
|
if c.name == 'typescript-tools' then
|
||||||
|
vim.cmd.TSToolsOrganizeImports()
|
||||||
|
end
|
||||||
|
return vim.tbl_contains(FORMAT_LSPS, c.name)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
vim.lsp.buf.format(format_opts)
|
||||||
|
vim.cmd.w()
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
15
config/nvim/lua/config/projects.lua
Normal file
15
config/nvim/lua/config/projects.lua
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
local project_configs = {
|
||||||
|
cavauto = {
|
||||||
|
lsp = {
|
||||||
|
clangd = {
|
||||||
|
cmd = { 'socat', '-', 'TCP:localhost:12345' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
local function project_name()
|
||||||
|
return vim.fn.fnamemodify(vim.fn.getcwd(), ':t')
|
||||||
|
end
|
||||||
|
|
||||||
|
return project_configs[project_name()] or {}
|
||||||
101
config/nvim/lua/config/tmux.lua
Normal file
101
config/nvim/lua/config/tmux.lua
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
local projects = {
|
||||||
|
{
|
||||||
|
name = 'bmath',
|
||||||
|
paths = { vim.env.HOME .. '/dev/bmath' },
|
||||||
|
cmd = 'cmake -B build -DCMAKE_BUILD_TYPE=Debug && cmake --build build && ctest --test-dir build --output-on-failure',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = 'neovim',
|
||||||
|
paths = { vim.env.HOME .. '/dev/neovim' },
|
||||||
|
cmd = 'make',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = 'barrettruth.com',
|
||||||
|
paths = { vim.env.HOME .. '/dev/barrettruth.com' },
|
||||||
|
cmd = 'pnpm dev',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = 'philipmruth.com',
|
||||||
|
paths = { vim.env.HOME .. '/dev/philipmruth.com' },
|
||||||
|
cmd = 'pnpm dev',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
---@type overseer.Task|nil
|
||||||
|
local current_task = nil
|
||||||
|
|
||||||
|
local actions = {
|
||||||
|
nvim = function()
|
||||||
|
local ok, oil = pcall(require, 'oil')
|
||||||
|
|
||||||
|
if not ok then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
oil.open()
|
||||||
|
end,
|
||||||
|
git = function()
|
||||||
|
vim.cmd.Git()
|
||||||
|
vim.cmd.only()
|
||||||
|
end,
|
||||||
|
run = function()
|
||||||
|
local ok, overseer = pcall(require, 'overseer')
|
||||||
|
|
||||||
|
if not ok then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local cwd = vim.fn.getcwd()
|
||||||
|
local match = nil
|
||||||
|
for _, p in ipairs(projects) do
|
||||||
|
if vim.tbl_contains(p.paths, cwd) then
|
||||||
|
match = p
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not match then
|
||||||
|
vim.notify_once(
|
||||||
|
'No task defined for this project',
|
||||||
|
vim.log.levels.WARN
|
||||||
|
)
|
||||||
|
vim.cmd('q!')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if
|
||||||
|
current_task
|
||||||
|
and (current_task.cwd ~= cwd or current_task.name ~= match.name)
|
||||||
|
then
|
||||||
|
if current_task:is_running() then
|
||||||
|
current_task:stop()
|
||||||
|
end
|
||||||
|
current_task:dispose(true)
|
||||||
|
current_task = nil
|
||||||
|
end
|
||||||
|
if not current_task or not current_task:is_running() then
|
||||||
|
current_task = overseer.new_task({
|
||||||
|
name = match.name,
|
||||||
|
cmd = match.cmd,
|
||||||
|
cwd = cwd,
|
||||||
|
env = match.env,
|
||||||
|
})
|
||||||
|
current_task:start()
|
||||||
|
end
|
||||||
|
current_task:open_output()
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
function M.run(subcmd)
|
||||||
|
if not subcmd then
|
||||||
|
error('No subcommand provided')
|
||||||
|
end
|
||||||
|
|
||||||
|
if not vim.tbl_contains(vim.tbl_keys(actions), subcmd) then
|
||||||
|
error('Invalid subcommand: ' .. subcmd)
|
||||||
|
end
|
||||||
|
|
||||||
|
actions[subcmd]()
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
7
config/nvim/lua/config/utils.lua
Normal file
7
config/nvim/lua/config/utils.lua
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
function M.empty(s)
|
||||||
|
return s == '' or s == nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
9
config/nvim/lua/lsp/bashls.lua
Normal file
9
config/nvim/lua/lsp/bashls.lua
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
return {
|
||||||
|
on_attach = function(_, bufnr)
|
||||||
|
require('config.lsp').on_attach(_, bufnr)
|
||||||
|
local bufname = vim.api.nvim_buf_get_name(bufnr)
|
||||||
|
if string.match(bufname, '%.env') then
|
||||||
|
vim.diagnostic.enable(false, { bufnr = bufnr })
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
39
config/nvim/lua/lsp/clangd.lua
Normal file
39
config/nvim/lua/lsp/clangd.lua
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
local config = require('config.projects')
|
||||||
|
|
||||||
|
local clangd_settings = {
|
||||||
|
filetypes = { 'c', 'cpp', 'objc', 'objcpp', 'cuda' },
|
||||||
|
cmd = {
|
||||||
|
'clangd',
|
||||||
|
'--clang-tidy',
|
||||||
|
'-j=4',
|
||||||
|
'--background-index',
|
||||||
|
'--completion-style=bundled',
|
||||||
|
'--header-insertion=iwyu',
|
||||||
|
'--header-insertion-decorators=false',
|
||||||
|
},
|
||||||
|
capabilities = {
|
||||||
|
textDocument = {
|
||||||
|
completion = {
|
||||||
|
editsNearCursor = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
local project_settings = (config.lsp and config.lsp.clangd)
|
||||||
|
and config.lsp.clangd
|
||||||
|
|
||||||
|
vim.api.nvim_create_autocmd('LspAttach', {
|
||||||
|
callback = function(args)
|
||||||
|
local client = vim.lsp.get_client_by_id(args.data.client_id)
|
||||||
|
if client and client.name == 'clangd' then
|
||||||
|
bmap(
|
||||||
|
{ 'n', 'gh', vim.cmd.ClangdSwitchSourceHeader },
|
||||||
|
{ buffer = args.buf }
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
group = vim.api.nvim_creat_augroup('AClangdKeymap', { clear = true }),
|
||||||
|
})
|
||||||
|
|
||||||
|
return vim.tbl_extend('force', clangd_settings, project_settings or {})
|
||||||
18
config/nvim/lua/lsp/cssls.lua
Normal file
18
config/nvim/lua/lsp/cssls.lua
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
return {
|
||||||
|
cmd = { 'vscode-css-language-server', '--stdio' },
|
||||||
|
filetypes = { 'css', 'scss', 'less' },
|
||||||
|
settings = {
|
||||||
|
css = {
|
||||||
|
lint = {
|
||||||
|
unknownAtRules = 'ignore',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
capabilities = {
|
||||||
|
textDocument = {
|
||||||
|
completion = {
|
||||||
|
completionItem = { snippetSupport = true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
30
config/nvim/lua/lsp/emmet_language_server.lua
Normal file
30
config/nvim/lua/lsp/emmet_language_server.lua
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
return {
|
||||||
|
cmd = { 'emmet-language-server', '--stdio' },
|
||||||
|
filetypes = {
|
||||||
|
'astro',
|
||||||
|
'css',
|
||||||
|
'eruby',
|
||||||
|
'html',
|
||||||
|
'htmlangular',
|
||||||
|
'htmldjango',
|
||||||
|
'javascriptreact',
|
||||||
|
'less',
|
||||||
|
'pug',
|
||||||
|
'sass',
|
||||||
|
'scss',
|
||||||
|
'svelte',
|
||||||
|
'templ',
|
||||||
|
'typescriptreact',
|
||||||
|
'vue',
|
||||||
|
},
|
||||||
|
init_options = {
|
||||||
|
showSuggestionsAsSnippets = true,
|
||||||
|
},
|
||||||
|
capabilities = {
|
||||||
|
textDocument = {
|
||||||
|
completion = {
|
||||||
|
completionItem = { snippetSupport = true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
5
config/nvim/lua/lsp/eslint.lua
Normal file
5
config/nvim/lua/lsp/eslint.lua
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
return {
|
||||||
|
settings = {
|
||||||
|
format = false,
|
||||||
|
},
|
||||||
|
}
|
||||||
9
config/nvim/lua/lsp/html.lua
Normal file
9
config/nvim/lua/lsp/html.lua
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
return {
|
||||||
|
capabilities = {
|
||||||
|
textDocument = {
|
||||||
|
completion = {
|
||||||
|
completionItem = { snippetSupport = true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
15
config/nvim/lua/lsp/jsonls.lua
Normal file
15
config/nvim/lua/lsp/jsonls.lua
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
return {
|
||||||
|
capabilities = {
|
||||||
|
textDocument = {
|
||||||
|
completion = {
|
||||||
|
completionItem = { snippetSupport = true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
settings = {
|
||||||
|
json = {
|
||||||
|
schemas = require('schemastore').json.schemas(),
|
||||||
|
validate = { enable = true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
19
config/nvim/lua/lsp/lua_ls.lua
Normal file
19
config/nvim/lua/lsp/lua_ls.lua
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
return {
|
||||||
|
settings = {
|
||||||
|
Lua = {
|
||||||
|
codeLens = { enable = true },
|
||||||
|
completion = { keywordSnippet = 'Disable' },
|
||||||
|
diagnostics = { globals = { 'vim' } },
|
||||||
|
hint = {
|
||||||
|
enable = true,
|
||||||
|
arrayIndex = 'Disable',
|
||||||
|
semicolon = 'Disable',
|
||||||
|
},
|
||||||
|
runtime = { version = 'LuaJIT' },
|
||||||
|
telemetry = { enable = false },
|
||||||
|
workspace = {
|
||||||
|
checkThirdParty = false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
5
config/nvim/lua/lsp/mdx_analyzer.lua
Normal file
5
config/nvim/lua/lsp/mdx_analyzer.lua
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
return {
|
||||||
|
cmd = { 'mdx-language-server', '--stdio' },
|
||||||
|
filetypes = { 'mdx' },
|
||||||
|
root_markers = { 'package.json' },
|
||||||
|
}
|
||||||
11
config/nvim/lua/lsp/pytest_lsp.lua
Normal file
11
config/nvim/lua/lsp/pytest_lsp.lua
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
return {
|
||||||
|
cmd = { 'pytest-language-server' },
|
||||||
|
filetypes = { 'python' },
|
||||||
|
root_markers = {
|
||||||
|
'pyproject.toml',
|
||||||
|
'setup.py',
|
||||||
|
'setup.cfg',
|
||||||
|
'pytest.ini',
|
||||||
|
'.git',
|
||||||
|
},
|
||||||
|
}
|
||||||
28
config/nvim/lua/lsp/rust-analyzer.lua
Normal file
28
config/nvim/lua/lsp/rust-analyzer.lua
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
return {
|
||||||
|
standalone = false,
|
||||||
|
capabilities = { general = { positionEncodings = { 'utf-16' } } },
|
||||||
|
settings = {
|
||||||
|
['rust-analyzer'] = {
|
||||||
|
checkOnSave = {
|
||||||
|
overrideCommand = {
|
||||||
|
'cargo',
|
||||||
|
'clippy',
|
||||||
|
'--message-format=json',
|
||||||
|
'--',
|
||||||
|
'-W',
|
||||||
|
'clippy::expect_used',
|
||||||
|
'-W',
|
||||||
|
'clippy::pedantic',
|
||||||
|
'-W',
|
||||||
|
'clippy::unwrap_used',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
on_attach = function(...)
|
||||||
|
require('config.lsp').on_attach(...)
|
||||||
|
bmap({ 'n', '\\Rc', '<cmd>RustLsp codeAction<cr>' })
|
||||||
|
bmap({ 'n', '\\Rm', '<cmd>RustLsp expandMacro<cr>' })
|
||||||
|
bmap({ 'n', '\\Ro', '<cmd>RustLsp openCargo<cr>' })
|
||||||
|
end,
|
||||||
|
}
|
||||||
14
config/nvim/lua/lsp/tailwindcss.lua
Normal file
14
config/nvim/lua/lsp/tailwindcss.lua
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
return {
|
||||||
|
filetypes = {
|
||||||
|
'javascript',
|
||||||
|
'javascriptreact',
|
||||||
|
'typescript',
|
||||||
|
'typescriptreact',
|
||||||
|
},
|
||||||
|
root_markers = {
|
||||||
|
'tailwind.config.js',
|
||||||
|
'tailwind.config.ts',
|
||||||
|
'postcss.config.js',
|
||||||
|
'postcss.config.ts',
|
||||||
|
},
|
||||||
|
}
|
||||||
12
config/nvim/lua/lsp/tinymist.lua
Normal file
12
config/nvim/lua/lsp/tinymist.lua
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
return {
|
||||||
|
filetypes = { 'typst' },
|
||||||
|
settings = {
|
||||||
|
formatterMode = 'typstyle',
|
||||||
|
semanticTokens = 'disable',
|
||||||
|
lint = {
|
||||||
|
enabled = true,
|
||||||
|
when = 'onType',
|
||||||
|
-- when = 'onSave'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
169
config/nvim/lua/plugins/cp.lua
Normal file
169
config/nvim/lua/plugins/cp.lua
Normal file
|
|
@ -0,0 +1,169 @@
|
||||||
|
local default_cpp_lang = {
|
||||||
|
extension = 'cc',
|
||||||
|
commands = {
|
||||||
|
build = {
|
||||||
|
'g++',
|
||||||
|
'-std=c++23',
|
||||||
|
'-O2',
|
||||||
|
'-Wall',
|
||||||
|
'-Wextra',
|
||||||
|
'-Wpedantic',
|
||||||
|
'-Wshadow',
|
||||||
|
'-Wconversion',
|
||||||
|
'-Wformat=2',
|
||||||
|
'-Wfloat-equal',
|
||||||
|
'-Wundef',
|
||||||
|
'-fdiagnostics-color=always',
|
||||||
|
'-DLOCAL',
|
||||||
|
'{source}',
|
||||||
|
'-o',
|
||||||
|
'{binary}',
|
||||||
|
},
|
||||||
|
run = { '{binary}' },
|
||||||
|
debug = {
|
||||||
|
'g++',
|
||||||
|
'-std=c++23',
|
||||||
|
'-g3',
|
||||||
|
'-fsanitize=address,undefined',
|
||||||
|
'-fno-omit-frame-pointer',
|
||||||
|
'-fstack-protector-all',
|
||||||
|
'-D_GLIBCXX_DEBUG',
|
||||||
|
'-DLOCAL',
|
||||||
|
'{source}',
|
||||||
|
'-o',
|
||||||
|
'{binary}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
local default_python_lang = {
|
||||||
|
extension = 'py',
|
||||||
|
commands = {
|
||||||
|
run = { 'python', '{source}' },
|
||||||
|
debug = { 'python', '{source}' },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
local clang_format_content = [[BasedOnStyle: LLVM
|
||||||
|
IndentWidth: 2
|
||||||
|
UseTab: Never
|
||||||
|
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
AllowShortLambdasOnASingleLine: None
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortEnumsOnASingleLine: false
|
||||||
|
AllowShortCaseExpressionOnASingleLine: false
|
||||||
|
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
ColumnLimit: 100
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
BinPackArguments: false
|
||||||
|
BinPackParameters: false]]
|
||||||
|
|
||||||
|
return {
|
||||||
|
'barrettruth/cp.nvim',
|
||||||
|
dir = '~/dev/cp.nvim',
|
||||||
|
cmd = 'CP',
|
||||||
|
keys = {
|
||||||
|
{ '<leader>ce', '<cmd>CP edit<cr>' },
|
||||||
|
{ '<leader>cp', '<cmd>CP panel<cr>' },
|
||||||
|
{ '<leader>cP', '<cmd>CP pick<cr>' },
|
||||||
|
{ '<leader>cr', '<cmd>CP run<cr>' },
|
||||||
|
{ '<leader>cd', '<cmd>CP run --debug<cr>' },
|
||||||
|
{ '<leader>cc', '<cmd>CP cache read<cr>' },
|
||||||
|
{ ']c', '<cmd>CP next<cr>' },
|
||||||
|
{ '[c', '<cmd>CP prev<cr>' },
|
||||||
|
},
|
||||||
|
dependencies = {
|
||||||
|
'L3MON4D3/LuaSnip',
|
||||||
|
'nvim-telescope/telescope.nvim',
|
||||||
|
},
|
||||||
|
config = function()
|
||||||
|
require('cp').setup({
|
||||||
|
languages = {
|
||||||
|
cpp = default_cpp_lang,
|
||||||
|
python = default_python_lang,
|
||||||
|
},
|
||||||
|
platforms = {
|
||||||
|
codeforces = {
|
||||||
|
enabled_languages = { 'cpp', 'python' },
|
||||||
|
default_language = 'cpp',
|
||||||
|
},
|
||||||
|
atcoder = {
|
||||||
|
enabled_languages = { 'cpp', 'python' },
|
||||||
|
default_language = 'cpp',
|
||||||
|
},
|
||||||
|
cses = {},
|
||||||
|
},
|
||||||
|
ui = { picker = 'fzf-lua' },
|
||||||
|
hooks = {
|
||||||
|
setup_io_input = function(buf)
|
||||||
|
require('cp.helpers').clearcol(buf)
|
||||||
|
end,
|
||||||
|
setup_io_output = function(buf)
|
||||||
|
require('cp.helpers').clearcol(buf)
|
||||||
|
end,
|
||||||
|
before_run = function(_)
|
||||||
|
require('config.lsp').format({ async = true })
|
||||||
|
end,
|
||||||
|
before_debug = function(_)
|
||||||
|
require('config.lsp').format({ async = true })
|
||||||
|
end,
|
||||||
|
setup_code = function(state)
|
||||||
|
vim.opt_local.winbar = ''
|
||||||
|
vim.opt_local.foldlevel = 0
|
||||||
|
vim.opt_local.foldmethod = 'marker'
|
||||||
|
vim.opt_local.foldmarker = '{{{,}}}'
|
||||||
|
vim.opt_local.foldtext = ''
|
||||||
|
vim.diagnostic.enable(false)
|
||||||
|
|
||||||
|
local buf = vim.api.nvim_get_current_buf()
|
||||||
|
local lines = vim.api.nvim_buf_get_lines(buf, 0, 1, true)
|
||||||
|
if #lines > 1 or (#lines == 1 and lines[1] ~= '') then
|
||||||
|
local pos = vim.api.nvim_win_get_cursor(0)
|
||||||
|
vim.cmd('normal! zx')
|
||||||
|
vim.api.nvim_win_set_cursor(0, pos)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local trigger = state.get_platform() or ''
|
||||||
|
vim.api.nvim_buf_set_lines(buf, 0, -1, false, { trigger })
|
||||||
|
vim.api.nvim_win_set_cursor(0, { 1, #trigger })
|
||||||
|
vim.cmd.startinsert({ bang = true })
|
||||||
|
vim.schedule(function()
|
||||||
|
local ls = require('luasnip')
|
||||||
|
if ls.expandable() then
|
||||||
|
vim.api.nvim_create_autocmd('TextChanged', {
|
||||||
|
buffer = buf,
|
||||||
|
once = true,
|
||||||
|
callback = function()
|
||||||
|
vim.schedule(function()
|
||||||
|
local pos =
|
||||||
|
vim.api.nvim_win_get_cursor(0)
|
||||||
|
vim.cmd('normal! zx')
|
||||||
|
vim.api.nvim_win_set_cursor(0, pos)
|
||||||
|
end)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
ls.expand()
|
||||||
|
end
|
||||||
|
vim.cmd.stopinsert()
|
||||||
|
end)
|
||||||
|
local clang_format_path = vim.fn.getcwd()
|
||||||
|
.. '/.clang-format'
|
||||||
|
if vim.fn.filereadable(clang_format_path) == 0 then
|
||||||
|
vim.fn.writefile(
|
||||||
|
vim.split(clang_format_content, '\n'),
|
||||||
|
clang_format_path
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
filename = function(_, _, problem_id)
|
||||||
|
return problem_id
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
}
|
||||||
149
config/nvim/lua/plugins/fzf.lua
Normal file
149
config/nvim/lua/plugins/fzf.lua
Normal file
|
|
@ -0,0 +1,149 @@
|
||||||
|
return {
|
||||||
|
'ibhagwan/fzf-lua',
|
||||||
|
config = function(_, opts)
|
||||||
|
require('fzf-lua').setup(opts)
|
||||||
|
|
||||||
|
vim.api.nvim_create_autocmd('FileType', {
|
||||||
|
pattern = 'fzf',
|
||||||
|
callback = function()
|
||||||
|
vim.opt_local.number = false
|
||||||
|
vim.opt_local.relativenumber = false
|
||||||
|
end,
|
||||||
|
group = vim.api.nvim_create_augroup(
|
||||||
|
'AFzfHighlights',
|
||||||
|
{ clear = true }
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
local ok, fzf_reload = pcall(require, 'config.fzf_reload')
|
||||||
|
if ok then
|
||||||
|
fzf_reload.setup(opts)
|
||||||
|
fzf_reload.reload(true)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
keys = {
|
||||||
|
{
|
||||||
|
'<c-t>',
|
||||||
|
function()
|
||||||
|
local fzf = require('fzf-lua')
|
||||||
|
local git_dir = vim.fn
|
||||||
|
.system('git rev-parse --git-dir 2>/dev/null')
|
||||||
|
:gsub('\n', '')
|
||||||
|
if vim.v.shell_error == 0 and git_dir ~= '' then
|
||||||
|
fzf.git_files({ cwd_prompt = false })
|
||||||
|
else
|
||||||
|
fzf.files()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{ '<c-l>', '<cmd>FzfLua live_grep<cr>' },
|
||||||
|
{ '<leader>f/', '<cmd>FzfLua search_history<cr>' },
|
||||||
|
{ '<leader>f:', '<cmd>FzfLua command_history<cr>' },
|
||||||
|
{ '<leader>fa', '<cmd>FzfLua autocmds<cr>' },
|
||||||
|
{ '<leader>fB', '<cmd>FzfLua builtin<cr>' },
|
||||||
|
{ '<leader>fb', '<cmd>FzfLua buffers<cr>' },
|
||||||
|
{ '<leader>fc', '<cmd>FzfLua commands<cr>' },
|
||||||
|
{
|
||||||
|
'<leader>fe',
|
||||||
|
'<cmd>FzfLua files cwd=~/.config<cr>',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'<leader>ff',
|
||||||
|
function()
|
||||||
|
require('fzf-lua').files({ cwd = vim.fn.expand('%:h') })
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'<leader>fg',
|
||||||
|
function()
|
||||||
|
require('fzf-lua').live_grep({ cwd = vim.fn.expand('%:h') })
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{ '<leader>fH', '<cmd>FzfLua highlights<cr>' },
|
||||||
|
{ '<leader>fh', '<cmd>FzfLua help_tags<cr>' },
|
||||||
|
{ '<leader>fl', '<cmd>FzfLua loclist<cr>' },
|
||||||
|
{ '<leader>fm', '<cmd>FzfLua man_pages<cr>' },
|
||||||
|
{ '<leader>fq', '<cmd>FzfLua quickfix<cr>' },
|
||||||
|
{ '<leader>fr', '<cmd>FzfLua resume<cr>' },
|
||||||
|
{
|
||||||
|
'<leader>fs',
|
||||||
|
'<cmd>FzfLua files cwd=~/.local/bin/scripts<cr>',
|
||||||
|
},
|
||||||
|
{ '<leader>GB', '<cmd>FzfLua git_branches<cr>' },
|
||||||
|
{ '<leader>Gb', '<cmd>FzfLua git_worktrees<cr>' },
|
||||||
|
{ 'gq', '<cmd>FzfLua quickfix<cr>' },
|
||||||
|
{ 'gl', '<cmd>FzfLua loclist<cr>' },
|
||||||
|
},
|
||||||
|
opts = {
|
||||||
|
files = {
|
||||||
|
cmd = vim.env.FZF_CTRL_T_COMMAND,
|
||||||
|
file_icons = false,
|
||||||
|
no_header_i = true,
|
||||||
|
},
|
||||||
|
fzf_args = (vim.env.FZF_DEFAULT_OPTS or ''):gsub(
|
||||||
|
'%-%-color=[^%s]+',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
grep = {
|
||||||
|
file_icons = false,
|
||||||
|
no_header_i = true,
|
||||||
|
RIPGREP_CONFIG_PATH = vim.env.RIPGREP_CONFIG_PATH,
|
||||||
|
},
|
||||||
|
lsp = {
|
||||||
|
includeDeclaration = false,
|
||||||
|
jump1 = true,
|
||||||
|
symbols = {
|
||||||
|
symbol_hl_prefix = '@',
|
||||||
|
symbol_style = 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
winopts = {
|
||||||
|
border = 'single',
|
||||||
|
preview = {
|
||||||
|
hidden = 'hidden',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions = {
|
||||||
|
files = {
|
||||||
|
default = function(...)
|
||||||
|
require('fzf-lua.actions').file_edit(...)
|
||||||
|
end,
|
||||||
|
['ctrl-l'] = function(...)
|
||||||
|
local a = require('fzf-lua.actions')
|
||||||
|
a.file_sel_to_ll(...)
|
||||||
|
vim.cmd.lclose()
|
||||||
|
end,
|
||||||
|
['ctrl-q'] = function(...)
|
||||||
|
local a = require('fzf-lua.actions')
|
||||||
|
a.file_sel_to_qf(...)
|
||||||
|
vim.cmd.cclose()
|
||||||
|
end,
|
||||||
|
['ctrl-h'] = function(...)
|
||||||
|
require('fzf-lua.actions').toggle_hidden(...)
|
||||||
|
end,
|
||||||
|
['ctrl-v'] = function(...)
|
||||||
|
require('fzf-lua.actions').file_vsplit(...)
|
||||||
|
end,
|
||||||
|
['ctrl-x'] = function(...)
|
||||||
|
require('fzf-lua.actions').file_split(...)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
border = 'single',
|
||||||
|
git = {
|
||||||
|
files = {
|
||||||
|
cmd = 'git ls-files --cached --others --exclude-standard',
|
||||||
|
},
|
||||||
|
worktrees = {
|
||||||
|
fzf_args = ((vim.env.FZF_DEFAULT_OPTS or '')
|
||||||
|
:gsub('%-%-bind=ctrl%-a:select%-all', '')
|
||||||
|
:gsub('--color=[^%s]+', '')),
|
||||||
|
},
|
||||||
|
branches = {
|
||||||
|
fzf_args = ((vim.env.FZF_DEFAULT_OPTS or '')
|
||||||
|
:gsub('%-%-bind=ctrl%-a:select%-all', '')
|
||||||
|
:gsub('--color=[^%s]+', '')),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
57
config/nvim/lua/plugins/git.lua
Normal file
57
config/nvim/lua/plugins/git.lua
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
---@type number|nil
|
||||||
|
local git_tab = nil
|
||||||
|
|
||||||
|
---@type string|nil
|
||||||
|
local prev = nil
|
||||||
|
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
'tpope/vim-fugitive',
|
||||||
|
cmd = 'Git',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'folke/snacks.nvim',
|
||||||
|
---@type snacks.Config
|
||||||
|
opts = { gitbrowse = {} },
|
||||||
|
keys = {
|
||||||
|
{ '<leader>Go', '<cmd>lua Snacks.gitbrowse()<cr>' },
|
||||||
|
{ '<leader>Gi', '<cmd>lua Snacks.picker.gh_issue()<cr>' },
|
||||||
|
{ '<leader>Gp', '<cmd>lua Snacks.picker.gh_pr()<cr>' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'lewis6991/gitsigns.nvim',
|
||||||
|
keys = {
|
||||||
|
{ '[g', '<cmd>Gitsigns next_hunk<cr>' },
|
||||||
|
{ ']g', '<cmd>Gitsigns prev_hunk<cr>' },
|
||||||
|
{ '<leader>Gb', '<cmd>Gitsigns toggle_current_line_blame<cr>' },
|
||||||
|
{
|
||||||
|
'<leader>Gs',
|
||||||
|
function()
|
||||||
|
if vim.opt.signcolumn:get() == 'no' then
|
||||||
|
prev = vim.opt.signcolumn:get()
|
||||||
|
vim.opt.signcolumn = 'yes'
|
||||||
|
else
|
||||||
|
vim.opt.signcolumn = prev
|
||||||
|
end
|
||||||
|
vim.cmd.Gitsigns('toggle_signs')
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
event = 'VeryLazy',
|
||||||
|
opts = {
|
||||||
|
current_line_blame_formatter_nc = function()
|
||||||
|
return {}
|
||||||
|
end,
|
||||||
|
signs = {
|
||||||
|
-- use boxdraw chars
|
||||||
|
add = { text = '│' },
|
||||||
|
change = { text = '│' },
|
||||||
|
delete = { text = '_' },
|
||||||
|
topdelete = { text = '‾' },
|
||||||
|
changedelete = { text = '│' },
|
||||||
|
},
|
||||||
|
signcolumn = false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
374
config/nvim/lua/plugins/lsp.lua
Normal file
374
config/nvim/lua/plugins/lsp.lua
Normal file
|
|
@ -0,0 +1,374 @@
|
||||||
|
return {
|
||||||
|
'neovim/nvim-lspconfig',
|
||||||
|
{
|
||||||
|
'folke/lazydev.nvim',
|
||||||
|
ft = 'lua',
|
||||||
|
opts = {
|
||||||
|
library = {
|
||||||
|
{ path = '${3rd}/luv/library' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'saghen/blink.cmp',
|
||||||
|
build = 'cargo build --release',
|
||||||
|
dependencies = 'folke/lazydev.nvim',
|
||||||
|
---@module 'blink.cmp'
|
||||||
|
---@type blink.cmp.Config
|
||||||
|
event = { 'InsertEnter', 'CmdlineEnter' },
|
||||||
|
config = function(_, opts)
|
||||||
|
vim.o.pumheight = 15
|
||||||
|
opts.completion.menu.max_height = vim.o.pumheight
|
||||||
|
|
||||||
|
require('blink.cmp').setup(opts)
|
||||||
|
end,
|
||||||
|
opts = {
|
||||||
|
keymap = {
|
||||||
|
['<c-p>'] = { 'select_prev' },
|
||||||
|
['<c-n>'] = { 'show', 'select_next' },
|
||||||
|
['<c-space>'] = {},
|
||||||
|
['<c-y>'] = {
|
||||||
|
function(cmp)
|
||||||
|
return cmp.snippet_active() and cmp.accept()
|
||||||
|
or cmp.select_and_accept()
|
||||||
|
end,
|
||||||
|
'snippet_forward',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
completion = {
|
||||||
|
menu = {
|
||||||
|
auto_show = false,
|
||||||
|
scrollbar = false,
|
||||||
|
draw = {
|
||||||
|
columns = function(ctx)
|
||||||
|
if ctx.mode == 'cmdline' then
|
||||||
|
return {
|
||||||
|
{ 'label', 'label_description', gap = 1 },
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return {
|
||||||
|
{ 'label', 'label_description' },
|
||||||
|
{ 'kind' },
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
cmdline = {
|
||||||
|
completion = {
|
||||||
|
menu = {
|
||||||
|
auto_show = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
keymap = {
|
||||||
|
['<left>'] = false,
|
||||||
|
['<right>'] = false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sources = {
|
||||||
|
default = { 'lsp', 'path', 'snippets', 'buffer' },
|
||||||
|
providers = {
|
||||||
|
lazydev = {
|
||||||
|
name = 'LazyDev',
|
||||||
|
module = 'lazydev.integrations.blink',
|
||||||
|
score_offset = 100,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
keys = { { '<c-n>', mode = 'i' } },
|
||||||
|
opts_extend = { 'sources.default' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'nvimtools/none-ls.nvim',
|
||||||
|
config = function()
|
||||||
|
local null_ls = require('null-ls')
|
||||||
|
local builtins = null_ls.builtins
|
||||||
|
local code_actions, diagnostics, formatting, hover =
|
||||||
|
builtins.code_actions,
|
||||||
|
builtins.diagnostics,
|
||||||
|
builtins.formatting,
|
||||||
|
builtins.hover
|
||||||
|
|
||||||
|
null_ls.setup({
|
||||||
|
border = 'single',
|
||||||
|
sources = {
|
||||||
|
require('none-ls.code_actions.eslint_d'),
|
||||||
|
code_actions.gitrebase,
|
||||||
|
|
||||||
|
diagnostics.buf,
|
||||||
|
diagnostics.checkmake,
|
||||||
|
require('none-ls.diagnostics.cpplint').with({
|
||||||
|
extra_args = {
|
||||||
|
'--filter',
|
||||||
|
'-legal/copyright',
|
||||||
|
'-whitespace/indent',
|
||||||
|
},
|
||||||
|
prepend_extra_args = true,
|
||||||
|
}),
|
||||||
|
require('none-ls.diagnostics.eslint_d'),
|
||||||
|
diagnostics.hadolint,
|
||||||
|
diagnostics.mypy.with({
|
||||||
|
extra_args = { '--check-untyped-defs' },
|
||||||
|
runtime_condition = function(params)
|
||||||
|
return vim.fn.executable('mypy') == 1
|
||||||
|
and require('null-ls.utils').path.exists(
|
||||||
|
params.bufname
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
}),
|
||||||
|
diagnostics.selene,
|
||||||
|
diagnostics.vacuum,
|
||||||
|
diagnostics.zsh,
|
||||||
|
|
||||||
|
formatting.black,
|
||||||
|
formatting.isort.with({
|
||||||
|
extra_args = { '--profile', 'black' },
|
||||||
|
}),
|
||||||
|
formatting.buf,
|
||||||
|
formatting.cbfmt,
|
||||||
|
formatting.cmake_format,
|
||||||
|
require('none-ls.formatting.latexindent'),
|
||||||
|
formatting.prettierd.with({
|
||||||
|
env = {
|
||||||
|
XDG_RUNTIME_DIR = vim.env.XDG_RUNTIME_DIR
|
||||||
|
or (
|
||||||
|
(
|
||||||
|
vim.env.XDG_DATA_HOME
|
||||||
|
or (vim.env.HOME .. '/.local/share')
|
||||||
|
)
|
||||||
|
.. '/prettierd'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
extra_args = function(params)
|
||||||
|
if params.ft == 'jsonc' then
|
||||||
|
return { '--trailing-comma', 'none' }
|
||||||
|
end
|
||||||
|
return {}
|
||||||
|
end,
|
||||||
|
filetypes = {
|
||||||
|
'css',
|
||||||
|
'graphql',
|
||||||
|
'html',
|
||||||
|
'javascript',
|
||||||
|
'javascriptreact',
|
||||||
|
'json',
|
||||||
|
'jsonc',
|
||||||
|
'markdown',
|
||||||
|
'mdx',
|
||||||
|
'typescript',
|
||||||
|
'typescriptreact',
|
||||||
|
'yaml',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
formatting.shfmt.with({
|
||||||
|
extra_args = { '-i', '2' },
|
||||||
|
}),
|
||||||
|
formatting.stylua.with({
|
||||||
|
condition = function(utils)
|
||||||
|
return utils.root_has_file({
|
||||||
|
'stylua.toml',
|
||||||
|
'.stylua.toml',
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
}),
|
||||||
|
|
||||||
|
hover.dictionary,
|
||||||
|
hover.printenv,
|
||||||
|
},
|
||||||
|
on_attach = require('config.lsp').on_attach,
|
||||||
|
debounce = 0,
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
dependencies = 'nvimtools/none-ls-extras.nvim',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'b0o/SchemaStore.nvim',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'saecki/live-rename.nvim',
|
||||||
|
event = 'LspAttach',
|
||||||
|
config = function(_, opts)
|
||||||
|
local live_rename = require('live-rename')
|
||||||
|
|
||||||
|
live_rename.setup(opts)
|
||||||
|
|
||||||
|
vim.api.nvim_create_autocmd('LspAttach', {
|
||||||
|
callback = function(o)
|
||||||
|
local clients = vim.lsp.get_clients({ buffer = o.buf })
|
||||||
|
for _, client in ipairs(clients) do
|
||||||
|
if client:supports_method('textDocument/rename') then
|
||||||
|
bmap(
|
||||||
|
{ 'n', 'grn', live_rename.rename },
|
||||||
|
{ buffer = o.buf }
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
group = vim.api.nvim_create_augroup(
|
||||||
|
'ALiveRename',
|
||||||
|
{ clear = true }
|
||||||
|
),
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
keys = { 'grn' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'yioneko/nvim-vtsls',
|
||||||
|
config = function(_, opts)
|
||||||
|
require('vtsls').config(opts)
|
||||||
|
end,
|
||||||
|
dependencies = {
|
||||||
|
{
|
||||||
|
'davidosomething/format-ts-errors.nvim',
|
||||||
|
ft = {
|
||||||
|
'javascript',
|
||||||
|
'javascriptreact',
|
||||||
|
'typescript',
|
||||||
|
'typescriptreact',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ft = {
|
||||||
|
'javascript',
|
||||||
|
'javascriptreact',
|
||||||
|
'typescript',
|
||||||
|
'typescriptreact',
|
||||||
|
},
|
||||||
|
opts = {
|
||||||
|
on_attach = function(_, bufnr)
|
||||||
|
bmap(
|
||||||
|
{ 'n', 'gD', vim.cmd.VtsExec('goto_source_definition') },
|
||||||
|
{ buffer = bufnr }
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
settings = {
|
||||||
|
typescript = {
|
||||||
|
inlayHints = {
|
||||||
|
parameterNames = { enabled = 'literals' },
|
||||||
|
parameterTypes = { enabled = true },
|
||||||
|
variableTypes = { enabled = true },
|
||||||
|
propertyDeclarationTypes = { enabled = true },
|
||||||
|
functionLikeReturnTypes = { enabled = true },
|
||||||
|
enumMemberValues = { enabled = true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
handlers = {
|
||||||
|
['textDocument/publishDiagnostics'] = function(_, result, ctx)
|
||||||
|
if not result.diagnostics then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local idx = 1
|
||||||
|
while idx <= #result.diagnostics do
|
||||||
|
local entry = result.diagnostics[idx]
|
||||||
|
|
||||||
|
local formatter =
|
||||||
|
require('format-ts-errors')[entry.code]
|
||||||
|
entry.message = formatter and formatter(entry.message)
|
||||||
|
or entry.message
|
||||||
|
|
||||||
|
if vim.tbl_contains({ 80001, 80006 }, entry.code) then
|
||||||
|
table.remove(result.diagnostics, idx)
|
||||||
|
else
|
||||||
|
idx = idx + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.lsp.diagnostic.on_publish_diagnostics(_, result, ctx)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'pmizio/typescript-tools.nvim',
|
||||||
|
opts = {
|
||||||
|
on_attach = function(_, bufnr)
|
||||||
|
bmap(
|
||||||
|
{ 'n', 'gD', vim.cmd.TSToolsGoToSourceDefinition },
|
||||||
|
{ buffer = bufnr }
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
handlers = {
|
||||||
|
['textDocument/publishDiagnostics'] = function(_, result, ctx)
|
||||||
|
if not result.diagnostics then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local idx = 1
|
||||||
|
while idx <= #result.diagnostics do
|
||||||
|
local entry = result.diagnostics[idx]
|
||||||
|
|
||||||
|
local formatter =
|
||||||
|
require('format-ts-errors')[entry.code]
|
||||||
|
entry.message = formatter and formatter(entry.message)
|
||||||
|
or entry.message
|
||||||
|
|
||||||
|
if vim.tbl_contains({ 80001, 80006 }, entry.code) then
|
||||||
|
table.remove(result.diagnostics, idx)
|
||||||
|
else
|
||||||
|
idx = idx + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.lsp.diagnostic.on_publish_diagnostics(_, result, ctx)
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
expose_as_code_action = 'all',
|
||||||
|
-- tsserver_path = vim.env.XDG_DATA_HOME .. '/pnpm/tsserver',
|
||||||
|
tsserver_file_preferences = {
|
||||||
|
includeInlayarameterNameHints = 'all',
|
||||||
|
includeInlayarameterNameHintsWhenArgumentMatchesName = false,
|
||||||
|
includeInlayFunctionParameterTypeHints = true,
|
||||||
|
includeInlayVariableTypeHints = true,
|
||||||
|
includeInlayVariableTypeHintsWhenTypeMatchesName = false,
|
||||||
|
includeInlayPropertyDeclarationTypeHints = true,
|
||||||
|
includeInlayFunctionLikeReturnTypeHints = true,
|
||||||
|
includeInlayEnumMemberValueHints = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
dependencies = {
|
||||||
|
'nvim-lua/plenary.nvim',
|
||||||
|
},
|
||||||
|
ft = {
|
||||||
|
'javascript',
|
||||||
|
'javascriptreact',
|
||||||
|
'typescript',
|
||||||
|
'typescriptreact',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'mrcjkb/rustaceanvim',
|
||||||
|
ft = { 'rust' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'SmiteshP/nvim-navic',
|
||||||
|
opts = {
|
||||||
|
depth_limit = 3,
|
||||||
|
depth_limit_indicator = '…',
|
||||||
|
icons = {
|
||||||
|
enabled = false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
event = 'LspAttach',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'chomosuke/typst-preview.nvim',
|
||||||
|
ft = 'typst',
|
||||||
|
version = '1.*',
|
||||||
|
opts = {
|
||||||
|
open_cmd = ('%s %%s --new-window'):format(vim.env.BROWSER),
|
||||||
|
invert_colors = 'auto',
|
||||||
|
dependencies_bin = {
|
||||||
|
tinymist = vim.fn.exepath('tinymist'),
|
||||||
|
websocat = vim.fn.exepath('websocat'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
keys = { { '<leader>t', '<cmd>TypstPreviewToggle<cr>' } },
|
||||||
|
},
|
||||||
|
}
|
||||||
430
config/nvim/lua/plugins/nvim.lua
Normal file
430
config/nvim/lua/plugins/nvim.lua
Normal file
|
|
@ -0,0 +1,430 @@
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
'barrettruth/live-server.nvim',
|
||||||
|
build = 'pnpm add -g live-server',
|
||||||
|
cmd = { 'LiveServerStart', 'LiveServerStart' },
|
||||||
|
config = true,
|
||||||
|
keys = { { '<leader>L', '<cmd>LiveServerToggle<cr>' } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'echasnovski/mini.pairs',
|
||||||
|
config = true,
|
||||||
|
event = 'InsertEnter',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'iamcco/markdown-preview.nvim',
|
||||||
|
build = 'pnpm up && cd app && pnpm install',
|
||||||
|
ft = { 'markdown' },
|
||||||
|
config = function()
|
||||||
|
vim.cmd([[
|
||||||
|
function OpenMarkdownPreview(url)
|
||||||
|
exec "silent !$BROWSER -n --args " . a:url
|
||||||
|
endfunction
|
||||||
|
]])
|
||||||
|
vim.g.mkdp_auto_close = 0
|
||||||
|
vim.g.mkdp_browserfunc = 'OpenMarkdownPreview'
|
||||||
|
vim.api.nvim_create_autocmd('FileType', {
|
||||||
|
pattern = 'markdown',
|
||||||
|
callback = function(opts)
|
||||||
|
bmap(
|
||||||
|
{ 'n', '<leader>m', vim.cmd.MarkdownPreviewToggle },
|
||||||
|
{ buffer = opts.buf }
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
group = vim.api.nvim_create_augroup(
|
||||||
|
'AMarkdownKeybind',
|
||||||
|
{ clear = true }
|
||||||
|
),
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'lervag/vimtex',
|
||||||
|
init = function()
|
||||||
|
vim.g.vimtex_view_method = 'general'
|
||||||
|
vim.g.vimtex_compiler_method = 'latexmk'
|
||||||
|
vim.g.vimtex_callback_progpath = '/usr/bin/nvim'
|
||||||
|
vim.g.vimtex_quickfix_mode = 0
|
||||||
|
end,
|
||||||
|
ft = { 'plaintext', 'tex' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'L3MON4D3/LuaSnip',
|
||||||
|
build = 'make install_jsregexp',
|
||||||
|
config = function()
|
||||||
|
local ls = require('luasnip')
|
||||||
|
|
||||||
|
ls.filetype_extend('htmldjango', { 'html' })
|
||||||
|
ls.filetype_extend('markdown', { 'html' })
|
||||||
|
ls.filetype_extend('javascriptreact', { 'javascript', 'html' })
|
||||||
|
ls.filetype_extend('typescript', { 'javascript' })
|
||||||
|
ls.filetype_extend(
|
||||||
|
'typescriptreact',
|
||||||
|
{ 'javascriptreact', 'javascript', 'html' }
|
||||||
|
)
|
||||||
|
|
||||||
|
require('luasnip.loaders.from_lua').lazy_load()
|
||||||
|
end,
|
||||||
|
keys = {
|
||||||
|
-- restore digraph mapping
|
||||||
|
{ '<c-d>', '<c-k>', mode = 'i' },
|
||||||
|
{
|
||||||
|
'<c-space>',
|
||||||
|
'<cmd>lua require("luasnip").expand()<cr>',
|
||||||
|
mode = 'i',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'<c-h>',
|
||||||
|
'<cmd>lua if require("luasnip").jumpable(-1) then require("luasnip").jump(-1) end<cr>',
|
||||||
|
mode = { 'i', 's' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'<c-l>',
|
||||||
|
'<cmd>lua if require("luasnip").jumpable(1) then require("luasnip").jump(1) end<cr>',
|
||||||
|
mode = { 'i', 's' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'<c-j>',
|
||||||
|
'<cmd>lua if require("luasnip").choice_active() then require("luasnip").change_choice(-1) end<cr>',
|
||||||
|
mode = 'i',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'<c-k>',
|
||||||
|
'<cmd>lua if require("luasnip").choice_active() then require("luasnip").change_choice(1) end<cr>',
|
||||||
|
mode = 'i',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
opts = {
|
||||||
|
region_check_events = 'InsertEnter',
|
||||||
|
delete_check_events = {
|
||||||
|
'TextChanged',
|
||||||
|
'TextChangedI',
|
||||||
|
'InsertLeave',
|
||||||
|
},
|
||||||
|
ext_opts = {
|
||||||
|
[require('luasnip.util.types').choiceNode] = {
|
||||||
|
active = {
|
||||||
|
virt_text = {
|
||||||
|
{
|
||||||
|
' <- ',
|
||||||
|
vim.wo.cursorline and 'CursorLine' or 'Normal',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'laytan/cloak.nvim',
|
||||||
|
config = true,
|
||||||
|
keys = { { '<leader>Ct', '<cmd>CloakToggle<cr>' } },
|
||||||
|
event = 'BufReadPre .env*',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'maxmellon/vim-jsx-pretty',
|
||||||
|
ft = {
|
||||||
|
'javascript',
|
||||||
|
'javascriptreact',
|
||||||
|
'typescript',
|
||||||
|
'typescriptreact',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'monaqa/dial.nvim',
|
||||||
|
config = function(_)
|
||||||
|
local augend = require('dial.augend')
|
||||||
|
require('dial.config').augends:register_group({
|
||||||
|
default = {
|
||||||
|
augend.integer.alias.decimal_int,
|
||||||
|
augend.integer.alias.hex,
|
||||||
|
augend.integer.alias.octal,
|
||||||
|
augend.integer.alias.binary,
|
||||||
|
augend.constant.alias.bool,
|
||||||
|
augend.constant.alias.alpha,
|
||||||
|
augend.constant.alias.Alpha,
|
||||||
|
augend.semver.alias.semver,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
keys = {
|
||||||
|
{
|
||||||
|
'<c-a>',
|
||||||
|
function()
|
||||||
|
require('dial.map').manipulate('increment', 'normal')
|
||||||
|
end,
|
||||||
|
mode = 'n',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'<c-x>',
|
||||||
|
function()
|
||||||
|
require('dial.map').manipulate('decrement', 'normal')
|
||||||
|
end,
|
||||||
|
mode = 'n',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'g<c-a>',
|
||||||
|
function()
|
||||||
|
require('dial.map').manipulate('increment', 'gnormal')
|
||||||
|
end,
|
||||||
|
mode = 'n',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'g<c-x>',
|
||||||
|
function()
|
||||||
|
require('dial.map').manipulate('decrement', 'gnormal')
|
||||||
|
end,
|
||||||
|
mode = 'n',
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
'<c-a>',
|
||||||
|
function()
|
||||||
|
require('dial.map').manipulate('increment', 'visual')
|
||||||
|
end,
|
||||||
|
mode = 'v',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'<c-x>',
|
||||||
|
function()
|
||||||
|
require('dial.map').manipulate('decrement', 'visual')
|
||||||
|
end,
|
||||||
|
mode = 'v',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'g<c-a>',
|
||||||
|
function()
|
||||||
|
require('dial.map').manipulate('increment', 'gvisual')
|
||||||
|
end,
|
||||||
|
mode = 'v',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'g<c-x>',
|
||||||
|
function()
|
||||||
|
require('dial.map').manipulate('decrement', 'gvisual')
|
||||||
|
end,
|
||||||
|
mode = 'v',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'cbochs/grapple.nvim',
|
||||||
|
opts = {
|
||||||
|
scope = 'git_branch',
|
||||||
|
icons = false,
|
||||||
|
status = false,
|
||||||
|
win_opts = {
|
||||||
|
title = '',
|
||||||
|
footer = '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
keys = {
|
||||||
|
{ '<leader>ha', '<cmd>Grapple toggle<cr>' },
|
||||||
|
{ '<leader>hd', '<cmd>Grapple untag<cr>' },
|
||||||
|
{ '<leader>hq', '<cmd>Grapple toggle_tags<cr>' },
|
||||||
|
|
||||||
|
{ '<c-1>', '<cmd>Grapple select index=1<cr>' },
|
||||||
|
{ '<c-2>', '<cmd>Grapple select index=2<cr>' },
|
||||||
|
{ '<c-3>', '<cmd>Grapple select index=3<cr>' },
|
||||||
|
{ '<c-4>', '<cmd>Grapple select index=4<cr>' },
|
||||||
|
|
||||||
|
{ ']h', '<cmd>Grapple cycle_tags next<cr>' },
|
||||||
|
{ '[h', '<cmd>Grapple cycle_tags prev<cr>' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'catgoose/nvim-colorizer.lua',
|
||||||
|
opts = {
|
||||||
|
user_default_options = {
|
||||||
|
names = false,
|
||||||
|
rrggbbaa = true,
|
||||||
|
css = true,
|
||||||
|
css_fn = true,
|
||||||
|
rgb_fn = true,
|
||||||
|
hsl_fn = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
event = 'VeryLazy',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'stevearc/oil.nvim',
|
||||||
|
config = function(_, opts)
|
||||||
|
require('oil').setup(opts)
|
||||||
|
vim.api.nvim_create_autocmd('BufEnter', {
|
||||||
|
callback = function()
|
||||||
|
local ft = vim.bo.filetype
|
||||||
|
if ft == '' then
|
||||||
|
local path = vim.fn.expand('%:p')
|
||||||
|
if vim.fn.isdirectory(path) == 1 then
|
||||||
|
vim.cmd('Oil ' .. path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
group = vim.api.nvim_create_augroup('AOil', { clear = true }),
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
event = 'VeryLazy',
|
||||||
|
keys = {
|
||||||
|
{ '-', '<cmd>e .<cr>' },
|
||||||
|
{ '_', vim.cmd.Oil },
|
||||||
|
},
|
||||||
|
opts = {
|
||||||
|
skip_confirm_for_simple_edits = true,
|
||||||
|
prompt_save_on_select_new_entry = false,
|
||||||
|
float = { border = 'single' },
|
||||||
|
view_options = {
|
||||||
|
is_hidden_file = function(name, bufnr)
|
||||||
|
local dir = require('oil').get_current_dir(bufnr)
|
||||||
|
if not dir then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if vim.startswith(name, '.') then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local git_dir = vim.fn.finddir('.git', dir .. ';')
|
||||||
|
if git_dir == '' then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local fullpath = dir .. '/' .. name
|
||||||
|
local result =
|
||||||
|
vim.fn.systemlist({ 'git', 'check-ignore', fullpath })
|
||||||
|
return #result > 0
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
keymaps = {
|
||||||
|
['<C-h>'] = false,
|
||||||
|
['<C-t>'] = false,
|
||||||
|
['<C-l>'] = false,
|
||||||
|
['<C-r>'] = 'actions.refresh',
|
||||||
|
['<C-s>'] = { 'actions.select', opts = { vertical = true } },
|
||||||
|
['<C-x>'] = { 'actions.select', opts = { horizontal = true } },
|
||||||
|
['q'] = function()
|
||||||
|
local ok, bufremove = pcall(require, 'mini.bufremove')
|
||||||
|
if ok then
|
||||||
|
bufremove.delete()
|
||||||
|
else
|
||||||
|
vim.cmd.bd()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'echasnovski/mini.misc',
|
||||||
|
config = true,
|
||||||
|
keys = {
|
||||||
|
{
|
||||||
|
'<c-w>m',
|
||||||
|
"<cmd>lua MiniMisc.zoom(0, { title = '', border = 'none' })<cr>",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'nvim-mini/mini.bufremove',
|
||||||
|
config = true,
|
||||||
|
keys = {
|
||||||
|
{
|
||||||
|
'<leader>bd',
|
||||||
|
'<cmd>lua MiniBufremove.delete()<cr>',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'<leader>bw',
|
||||||
|
'<cmd>lua MiniBufremove.wipeout()<cr>',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ 'tpope/vim-abolish', event = 'VeryLazy' },
|
||||||
|
{ 'tpope/vim-sleuth', event = 'BufReadPost' },
|
||||||
|
{
|
||||||
|
'kylechui/nvim-surround',
|
||||||
|
config = true,
|
||||||
|
keys = {
|
||||||
|
{ 'cs', mode = 'n' },
|
||||||
|
{ 'ds', mode = 'n' },
|
||||||
|
{ 'ys', mode = 'n' },
|
||||||
|
{ 'yS', mode = 'n' },
|
||||||
|
{ 'yss', mode = 'n' },
|
||||||
|
{ 'ySs', mode = 'n' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'tzachar/highlight-undo.nvim',
|
||||||
|
config = true,
|
||||||
|
keys = { 'u', 'U' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'kana/vim-textobj-user',
|
||||||
|
dependencies = {
|
||||||
|
{
|
||||||
|
'kana/vim-textobj-entire',
|
||||||
|
keys = {
|
||||||
|
{ 'ae', mode = { 'o', 'x' } },
|
||||||
|
{ 'ie', mode = { 'o', 'x' } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'kana/vim-textobj-line',
|
||||||
|
keys = {
|
||||||
|
{ 'al', mode = { 'o', 'x' } },
|
||||||
|
{ 'il', mode = { 'o', 'x' } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'kana/vim-textobj-indent',
|
||||||
|
keys = {
|
||||||
|
{ 'ai', mode = { 'o', 'x' } },
|
||||||
|
{ 'ii', mode = { 'o', 'x' } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'preservim/vim-textobj-sentence',
|
||||||
|
keys = {
|
||||||
|
{ 'as', mode = { 'o', 'x' } },
|
||||||
|
{ 'is', mode = { 'o', 'x' } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'whatyouhide/vim-textobj-xmlattr',
|
||||||
|
keys = {
|
||||||
|
{ 'ax', mode = { 'o', 'x' } },
|
||||||
|
{ 'ix', mode = { 'o', 'x' } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'saghen/blink.indent',
|
||||||
|
opts = {
|
||||||
|
blocked = {
|
||||||
|
filetypes = {
|
||||||
|
include_defaults = true,
|
||||||
|
'fugitive',
|
||||||
|
'markdown',
|
||||||
|
'typst',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
static = {
|
||||||
|
char = '│',
|
||||||
|
},
|
||||||
|
scope = { enabled = false },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'barrettruth/midnight.nvim',
|
||||||
|
dir = '~/dev/midnight.nvim',
|
||||||
|
init = function()
|
||||||
|
vim.api.nvim_create_autocmd({ 'OptionSet' }, {
|
||||||
|
pattern = 'background',
|
||||||
|
callback = function()
|
||||||
|
vim.cmd.colorscheme(
|
||||||
|
vim.o.background == 'dark' and 'midnight' or 'daylight'
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
group = vim.api.nvim_create_augroup(
|
||||||
|
'AColorScheme',
|
||||||
|
{ clear = true }
|
||||||
|
),
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
}
|
||||||
30
config/nvim/lua/plugins/overseer.lua
Normal file
30
config/nvim/lua/plugins/overseer.lua
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
return {
|
||||||
|
'stevearc/overseer.nvim',
|
||||||
|
init = function()
|
||||||
|
vim.api.nvim_create_autocmd('VimLeavePre', {
|
||||||
|
callback = function()
|
||||||
|
local overseer = require('overseer')
|
||||||
|
for _, task in ipairs(overseer.list_tasks()) do
|
||||||
|
if task:is_running() then
|
||||||
|
task:stop()
|
||||||
|
end
|
||||||
|
task:dispose(true)
|
||||||
|
end
|
||||||
|
current_task = nil
|
||||||
|
end,
|
||||||
|
group = vim.api.nvim_create_augroup('AOverseer', { clear = true }),
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
opts = {
|
||||||
|
strategy = 'terminal',
|
||||||
|
task_list = {
|
||||||
|
bindings = {
|
||||||
|
q = '<Cmd>OverseerClose<CR>',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
keys = {
|
||||||
|
{ '<leader>Oa', '<cmd>OverseerTaskAction<cr>' },
|
||||||
|
{ '<leader>Ob', '<cmd>OverseerBuild<cr>' },
|
||||||
|
},
|
||||||
|
}
|
||||||
156
config/nvim/lua/plugins/treesitter.lua
Normal file
156
config/nvim/lua/plugins/treesitter.lua
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
'nvim-treesitter/nvim-treesitter',
|
||||||
|
branch = 'main',
|
||||||
|
build = ':TSUpdate',
|
||||||
|
lazy = false,
|
||||||
|
init = function()
|
||||||
|
vim.api.nvim_create_autocmd('FileType', {
|
||||||
|
pattern = '*',
|
||||||
|
callback = function()
|
||||||
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
|
local lines = vim.api.nvim_buf_line_count(bufnr)
|
||||||
|
|
||||||
|
if lines < 5000 then
|
||||||
|
pcall(vim.treesitter.start)
|
||||||
|
else
|
||||||
|
vim.notify_once(
|
||||||
|
('Skipping tree-sitter for bufnr %s; file too large (%s >= 5000 lines)'):format(
|
||||||
|
bufnr,
|
||||||
|
lines
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
group = vim.api.nvim_create_augroup(
|
||||||
|
'ATreeSitter',
|
||||||
|
{ clear = true }
|
||||||
|
),
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
keys = {
|
||||||
|
{
|
||||||
|
'<leader>T',
|
||||||
|
function()
|
||||||
|
local lang_map = { htmldjango = 'html' }
|
||||||
|
local bufnr = vim.api.nvim_get_current_buf()
|
||||||
|
local parser = vim.treesitter.get_parser(bufnr)
|
||||||
|
local lang = parser:lang()
|
||||||
|
local path = (
|
||||||
|
vim.env.NVIM_APPNAME or vim.fn.stdpath('config')
|
||||||
|
)
|
||||||
|
.. ('/after/queries/%s/highlights.scm'):format(
|
||||||
|
lang_map[lang] or lang
|
||||||
|
)
|
||||||
|
|
||||||
|
if vim.loop.fs_stat(path) then
|
||||||
|
vim.fn.rename(path, path .. '.disabled')
|
||||||
|
elseif vim.loop.fs_stat(path .. '.disabled') then
|
||||||
|
vim.fn.rename(path .. '.disabled', path)
|
||||||
|
end
|
||||||
|
vim.cmd.TSBufToggle('highlight')
|
||||||
|
vim.cmd.TSBufToggle('highlight')
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'nvim-treesitter/nvim-treesitter-textobjects',
|
||||||
|
branch = 'main',
|
||||||
|
dependencies = 'nvim-treesitter/nvim-treesitter',
|
||||||
|
init = function()
|
||||||
|
vim.g.no_plugin_maps = true
|
||||||
|
end,
|
||||||
|
opts = {
|
||||||
|
select = {
|
||||||
|
enable = true,
|
||||||
|
lookahead = true,
|
||||||
|
},
|
||||||
|
move = {
|
||||||
|
enable = true,
|
||||||
|
set_jumps = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
config = function(_, opts)
|
||||||
|
require('nvim-treesitter-textobjects').setup(opts)
|
||||||
|
|
||||||
|
local select = require('nvim-treesitter-textobjects.select')
|
||||||
|
local select_maps = {
|
||||||
|
{ 'aa', '@parameter.outer' },
|
||||||
|
{ 'ia', '@parameter.inner' },
|
||||||
|
{ 'ab', '@block.outer' },
|
||||||
|
{ 'ib', '@block.inner' },
|
||||||
|
{ 'as', '@class.outer' },
|
||||||
|
{ 'is', '@class.inner' },
|
||||||
|
{ 'aC', '@call.outer' },
|
||||||
|
{ 'iC', '@call.inner' },
|
||||||
|
{ 'af', '@function.outer' },
|
||||||
|
{ 'if', '@function.inner' },
|
||||||
|
{ 'ai', '@conditional.outer' },
|
||||||
|
{ 'ii', '@conditional.inner' },
|
||||||
|
{ 'aL', '@loop.outer' },
|
||||||
|
{ 'iL', '@loop.inner' },
|
||||||
|
}
|
||||||
|
for _, m in ipairs({ 'x', 'o' }) do
|
||||||
|
for _, t in ipairs(select_maps) do
|
||||||
|
map({
|
||||||
|
m,
|
||||||
|
t[1],
|
||||||
|
function()
|
||||||
|
select.select_textobject(t[2], 'textobjects', m)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local move = require('nvim-treesitter-textobjects.move')
|
||||||
|
local move_maps = {
|
||||||
|
{ ']a', 'goto_next_start', '@parameter.inner' },
|
||||||
|
{ ']s', 'goto_next_start', '@class.outer' },
|
||||||
|
{ ']f', 'goto_next_start', '@function.outer' },
|
||||||
|
{ ']i', 'goto_next_start', '@conditional.outer' },
|
||||||
|
{ ']/', 'goto_next_start', '@comment.outer' },
|
||||||
|
{ ']A', 'goto_next_end', '@parameter.inner' },
|
||||||
|
{ ']F', 'goto_next_end', '@function.outer' },
|
||||||
|
{ ']I', 'goto_next_end', '@conditional.outer' },
|
||||||
|
{ '[a', 'goto_previous_start', '@parameter.inner' },
|
||||||
|
{ '[s', 'goto_previous_start', '@class.outer' },
|
||||||
|
{ '[f', 'goto_previous_start', '@function.outer' },
|
||||||
|
{ '[i', 'goto_previous_start', '@conditional.outer' },
|
||||||
|
{ '[/', 'goto_previous_start', '@comment.outer' },
|
||||||
|
{ '[A', 'goto_previous_end', '@parameter.inner' },
|
||||||
|
{ '[F', 'goto_previous_end', '@function.outer' },
|
||||||
|
{ '[I', 'goto_previous_end', '@conditional.outer' },
|
||||||
|
}
|
||||||
|
for _, m in ipairs({ 'n', 'x', 'o' }) do
|
||||||
|
for _, t in ipairs(move_maps) do
|
||||||
|
map({
|
||||||
|
m,
|
||||||
|
t[1],
|
||||||
|
function()
|
||||||
|
move[t[2]](t[3], 'textobjects')
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local ts_repeat =
|
||||||
|
require('nvim-treesitter-textobjects.repeatable_move')
|
||||||
|
for _, m in ipairs({ 'n', 'x', 'o' }) do
|
||||||
|
map({ m, ';', ts_repeat.repeat_last_move_next })
|
||||||
|
map({ m, ',', ts_repeat.repeat_last_move_previous })
|
||||||
|
map({ m, 'f', ts_repeat.builtin_f_expr }, { expr = true })
|
||||||
|
map({ m, 'F', ts_repeat.builtin_F_expr }, { expr = true })
|
||||||
|
map({ m, 't', ts_repeat.builtin_t_expr }, { expr = true })
|
||||||
|
map({ m, 'T', ts_repeat.builtin_T_expr }, { expr = true })
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'Wansmer/treesj',
|
||||||
|
config = true,
|
||||||
|
keys = {
|
||||||
|
{ 'gt', '<cmd>lua require("treesj").toggle()<cr>' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
19
config/nvim/luasnippets/c.lua
Normal file
19
config/nvim/luasnippets/c.lua
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
return {
|
||||||
|
s('/* ', fmt('/* {} */', { i(1) })),
|
||||||
|
s('pr', fmt('printf("{}", {});', { i(1), i(2) })),
|
||||||
|
s(
|
||||||
|
'main',
|
||||||
|
fmt(
|
||||||
|
[[
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void) {{
|
||||||
|
{}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}}
|
||||||
|
]],
|
||||||
|
{ i(1) }
|
||||||
|
)
|
||||||
|
),
|
||||||
|
}
|
||||||
179
config/nvim/luasnippets/cpp.lua
Normal file
179
config/nvim/luasnippets/cpp.lua
Normal file
|
|
@ -0,0 +1,179 @@
|
||||||
|
local ls = require('luasnip')
|
||||||
|
local s, i, fmt = ls.snippet, ls.insert_node, require('luasnip.extras.fmt').fmt
|
||||||
|
|
||||||
|
local cppsnippets = {}
|
||||||
|
|
||||||
|
local template = [=[#include <bits/stdc++.h> // {{{{{{
|
||||||
|
|
||||||
|
#include <version>
|
||||||
|
#ifdef __cpp_lib_ranges_enumerate
|
||||||
|
#include <ranges>
|
||||||
|
namespace rv = std::views;
|
||||||
|
namespace rs = std::ranges;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma GCC optimize("O2,unroll-loops")
|
||||||
|
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
using i32 = int32_t;
|
||||||
|
using u32 = uint32_t;
|
||||||
|
using i64 = int64_t;
|
||||||
|
using u64 = uint64_t;
|
||||||
|
using f64 = double;
|
||||||
|
using f128 = long double;
|
||||||
|
|
||||||
|
#if __cplusplus >= 202002L
|
||||||
|
template <typename T>
|
||||||
|
constexpr T MIN = std::numeric_limits<T>::min();
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr T MAX = std::numeric_limits<T>::max();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LOCAL
|
||||||
|
#define db(...) std::print(__VA_ARGS__)
|
||||||
|
#define dbln(...) std::println(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define db(...)
|
||||||
|
#define dbln(...)
|
||||||
|
#endif
|
||||||
|
// }}}}}}]=]
|
||||||
|
|
||||||
|
-- utility snippets
|
||||||
|
for _, snippet in ipairs({
|
||||||
|
s('in', fmt('#include {}', { i(1) })),
|
||||||
|
s(
|
||||||
|
'main',
|
||||||
|
fmt(
|
||||||
|
[[#include <iostream>
|
||||||
|
|
||||||
|
int main() {{
|
||||||
|
{}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}}]],
|
||||||
|
{ i(1) }
|
||||||
|
)
|
||||||
|
),
|
||||||
|
s('pr', fmt('std::cout << {}', { i(1) })),
|
||||||
|
s('s', fmt('std::{}', { i(1) })),
|
||||||
|
s(
|
||||||
|
'pbds',
|
||||||
|
fmt(
|
||||||
|
[[
|
||||||
|
#include <ext/pb_ds/assoc_container.hpp>
|
||||||
|
#include <ext/pb_ds/tree_policy.hpp>
|
||||||
|
|
||||||
|
namespace pbds = __gnu_pbds;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
using hashset = pbds::gp_hash_table<T, pbds::null_type>;
|
||||||
|
|
||||||
|
template <class K, class V>
|
||||||
|
using hashmap = pbds::gp_hash_table<K, V>;
|
||||||
|
|
||||||
|
template <class K, class V>
|
||||||
|
using multitreemap =
|
||||||
|
pbds::tree<K, V, less_equal<K>, pbds::rb_tree_tag,
|
||||||
|
pbds::tree_order_statistics_node_update>;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
using treeset =
|
||||||
|
pbds::tree<T, pbds::null_type, less<T>, pbds::rb_tree_tag,
|
||||||
|
pbds::tree_order_statistics_node_update>;
|
||||||
|
|
||||||
|
template <class K, class V>
|
||||||
|
using treemap =
|
||||||
|
pbds::tree<K, V, less<K>, pbds::rb_tree_tag,
|
||||||
|
pbds::tree_order_statistics_node_update>;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
using treemultiset =
|
||||||
|
pbds::tree<T, pbds::null_type, less_equal<T>, pbds::rb_tree_tag,
|
||||||
|
pbds::tree_order_statistics_node_update>;
|
||||||
|
]],
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
),
|
||||||
|
}) do
|
||||||
|
table.insert(cppsnippets, snippet)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, entry in ipairs({
|
||||||
|
{
|
||||||
|
trig = 'codeforces',
|
||||||
|
body = template .. [[
|
||||||
|
|
||||||
|
|
||||||
|
void solve() {{
|
||||||
|
{}
|
||||||
|
}}
|
||||||
|
|
||||||
|
int main() {{ // {{{{{{
|
||||||
|
std::cin.exceptions(std::cin.failbit);
|
||||||
|
#ifdef LOCAL
|
||||||
|
std::cerr.rdbuf(std::cout.rdbuf());
|
||||||
|
std::cout.setf(std::ios::unitbuf);
|
||||||
|
std::cerr.setf(std::ios::unitbuf);
|
||||||
|
#else
|
||||||
|
std::cin.tie(nullptr)->sync_with_stdio(false);
|
||||||
|
#endif
|
||||||
|
u32 tc = 1;
|
||||||
|
std::cin >> tc;
|
||||||
|
for (u32 t = 0; t < tc; ++t) {{
|
||||||
|
solve();
|
||||||
|
}}
|
||||||
|
return 0;
|
||||||
|
}} // vim: set foldmethod=marker foldmarker={{{{{{,}}}}}}]],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
trig = 'atcoder',
|
||||||
|
body = template .. [[
|
||||||
|
|
||||||
|
|
||||||
|
void solve() {{
|
||||||
|
{}
|
||||||
|
}}
|
||||||
|
|
||||||
|
int main() {{ // {{{{{{
|
||||||
|
std::cin.exceptions(std::cin.failbit);
|
||||||
|
#ifdef LOCAL
|
||||||
|
std::cerr.rdbuf(std::cout.rdbuf());
|
||||||
|
std::cout.setf(std::ios::unitbuf);
|
||||||
|
std::cerr.setf(std::ios::unitbuf);
|
||||||
|
#else
|
||||||
|
std::cin.tie(nullptr)->sync_with_stdio(false);
|
||||||
|
#endif
|
||||||
|
solve();
|
||||||
|
return 0;
|
||||||
|
}} // vim: set foldmethod=marker foldmarker={{{{{{,}}}}}}]],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
trig = 'cses',
|
||||||
|
body = template .. [[
|
||||||
|
|
||||||
|
|
||||||
|
void solve() {{
|
||||||
|
{}
|
||||||
|
}}
|
||||||
|
|
||||||
|
int main() {{ // {{{{{{
|
||||||
|
std::cin.exceptions(std::cin.failbit);
|
||||||
|
#ifdef LOCAL
|
||||||
|
std::cerr.rdbuf(std::cout.rdbuf());
|
||||||
|
std::cout.setf(std::ios::unitbuf);
|
||||||
|
std::cerr.setf(std::ios::unitbuf);
|
||||||
|
#else
|
||||||
|
std::cin.tie(nullptr)->sync_with_stdio(false);
|
||||||
|
#endif
|
||||||
|
solve();
|
||||||
|
return 0;
|
||||||
|
}} // vim: set foldmethod=marker foldmarker={{{{{{,}}}}}}]],
|
||||||
|
},
|
||||||
|
}) do
|
||||||
|
table.insert(cppsnippets, s(entry.trig, fmt(entry.body, { i(1) })))
|
||||||
|
end
|
||||||
|
|
||||||
|
return cppsnippets
|
||||||
11
config/nvim/luasnippets/html.lua
Normal file
11
config/nvim/luasnippets/html.lua
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
local word = function(index)
|
||||||
|
return f(function(name)
|
||||||
|
return name[1][1]:match('([^ ]*)')
|
||||||
|
end, { index })
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
s('<', fmt('<{}>\n\t{}\n</{}>', { i(1), i(2), word(1) })),
|
||||||
|
s('>', fmt('<{}>{}</{}>', { i(1), i(2), word(1) })),
|
||||||
|
s('/', fmt('<{} />', { i(1) })),
|
||||||
|
}
|
||||||
14
config/nvim/luasnippets/python.lua
Normal file
14
config/nvim/luasnippets/python.lua
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
return {
|
||||||
|
s(
|
||||||
|
'main',
|
||||||
|
fmt(
|
||||||
|
[[def main() -> None:
|
||||||
|
{}
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
]],
|
||||||
|
{ i(1) }
|
||||||
|
)
|
||||||
|
),
|
||||||
|
}
|
||||||
12
config/nvim/nvim-pack-lock.json
Normal file
12
config/nvim/nvim-pack-lock.json
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"plugins": {
|
||||||
|
"midnight.nvim": {
|
||||||
|
"rev": "45c447a1902e7bd5b8e0de99bb5068de9ac1efba",
|
||||||
|
"src": "https://github.com/barrettruth/midnight.nvim.git"
|
||||||
|
},
|
||||||
|
"nvim-treesitter": {
|
||||||
|
"rev": "6e42d823ce0a5a76180c473c119c7677738a09d1",
|
||||||
|
"src": "https://github.com/nvim-treesitter/nvim-treesitter.git"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
75
config/nvim/plugin/autocmds.lua
Normal file
75
config/nvim/plugin/autocmds.lua
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
local api, au = vim.api, vim.api.nvim_create_autocmd
|
||||||
|
|
||||||
|
local aug = api.nvim_create_augroup('AAugs', { clear = true })
|
||||||
|
|
||||||
|
au('BufEnter', {
|
||||||
|
command = 'setl formatoptions-=cro spelloptions=camel,noplainbuffer',
|
||||||
|
group = aug,
|
||||||
|
})
|
||||||
|
|
||||||
|
au({ 'TermOpen', 'BufWinEnter' }, {
|
||||||
|
callback = function(args)
|
||||||
|
if vim.bo[args.buf].buftype == 'terminal' then
|
||||||
|
vim.opt_local.number = true
|
||||||
|
vim.opt_local.relativenumber = true
|
||||||
|
vim.cmd.startinsert()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
group = aug,
|
||||||
|
})
|
||||||
|
|
||||||
|
au('BufWritePost', {
|
||||||
|
pattern = (
|
||||||
|
os.getenv('XDG_CONFIG_HOME') or (os.getenv('HOME') .. '/.config')
|
||||||
|
) .. '/dunst/dunstrc',
|
||||||
|
callback = function()
|
||||||
|
vim.fn.system('killall dunst && nohup dunst &; disown')
|
||||||
|
end,
|
||||||
|
group = aug,
|
||||||
|
})
|
||||||
|
|
||||||
|
au('BufReadPost', {
|
||||||
|
command = 'sil! normal g`"',
|
||||||
|
group = aug,
|
||||||
|
})
|
||||||
|
|
||||||
|
au({ 'BufRead', 'BufNewFile' }, {
|
||||||
|
pattern = '*/templates/*.html',
|
||||||
|
callback = function(opts)
|
||||||
|
vim.api.nvim_set_option_value(
|
||||||
|
'filetype',
|
||||||
|
'htmldjango',
|
||||||
|
{ buf = opts.buf }
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
group = aug,
|
||||||
|
})
|
||||||
|
|
||||||
|
au('TextYankPost', {
|
||||||
|
callback = function()
|
||||||
|
vim.highlight.on_yank({ higroup = 'Visual', timeout = 300 })
|
||||||
|
end,
|
||||||
|
group = aug,
|
||||||
|
})
|
||||||
|
|
||||||
|
au({ 'FocusLost', 'BufLeave', 'VimLeave' }, {
|
||||||
|
pattern = '*',
|
||||||
|
callback = function()
|
||||||
|
vim.cmd('silent! wall')
|
||||||
|
end,
|
||||||
|
group = aug,
|
||||||
|
})
|
||||||
|
|
||||||
|
au({ 'VimEnter', 'BufWinEnter', 'BufEnter' }, {
|
||||||
|
callback = function()
|
||||||
|
vim.api.nvim_set_option_value('cursorline', true, { scope = 'local' })
|
||||||
|
end,
|
||||||
|
group = aug,
|
||||||
|
})
|
||||||
|
|
||||||
|
au('WinLeave', {
|
||||||
|
callback = function()
|
||||||
|
vim.api.nvim_set_option_value('cursorline', false, { scope = 'local' })
|
||||||
|
end,
|
||||||
|
group = aug,
|
||||||
|
})
|
||||||
1
config/nvim/plugin/fold.lua
Normal file
1
config/nvim/plugin/fold.lua
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
require('config.fold').setup()
|
||||||
68
config/nvim/plugin/keymaps.lua
Normal file
68
config/nvim/plugin/keymaps.lua
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
map({
|
||||||
|
'n',
|
||||||
|
'gx',
|
||||||
|
function()
|
||||||
|
local url = vim.fn.expand('<cfile>', nil)
|
||||||
|
|
||||||
|
if not url:match('https') and url:match('/') then
|
||||||
|
url = 'https://github.com/' .. url
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.fn.jobstart({ vim.env.BROWSER, url })
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
map({ { 'i', 'c' }, '<c-a>', '<esc>' })
|
||||||
|
|
||||||
|
for key, cmd in pairs({
|
||||||
|
left = 'vertical resize -10',
|
||||||
|
right = 'vertical resize +10',
|
||||||
|
down = 'resize +10',
|
||||||
|
up = 'resize -10',
|
||||||
|
}) do
|
||||||
|
map({
|
||||||
|
'n',
|
||||||
|
('<%s>'):format(key),
|
||||||
|
function()
|
||||||
|
vim.cmd(cmd)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
map({ 'n', 'J', 'mzJ`z' })
|
||||||
|
|
||||||
|
map({ 'x', 'p', '"_dp' })
|
||||||
|
map({ 'x', 'P', '"_dP' })
|
||||||
|
map({ 't', '<esc>', '<c-\\><c-n>' })
|
||||||
|
|
||||||
|
map({ 'n', '<leader>iw', '<cmd>setlocal wrap!<cr>' })
|
||||||
|
map({ 'n', '<leader>is', '<cmd>setlocal spell!<cr>' })
|
||||||
|
local state = nil
|
||||||
|
|
||||||
|
map({
|
||||||
|
'n',
|
||||||
|
'<leader>iz',
|
||||||
|
function()
|
||||||
|
if state then
|
||||||
|
for k, v in pairs(state) do
|
||||||
|
vim.opt_local[k] = v
|
||||||
|
end
|
||||||
|
state = nil
|
||||||
|
else
|
||||||
|
state = {
|
||||||
|
number = vim.opt_local.number:get(),
|
||||||
|
relativenumber = vim.opt_local.relativenumber:get(),
|
||||||
|
signcolumn = vim.opt_local.signcolumn:get(),
|
||||||
|
statuscolumn = vim.opt_local.statuscolumn:get(),
|
||||||
|
laststatus = vim.opt_local.laststatus:get(),
|
||||||
|
cmdheight = vim.opt_local.cmdheight:get(),
|
||||||
|
}
|
||||||
|
vim.opt_local.number = false
|
||||||
|
vim.opt_local.relativenumber = false
|
||||||
|
vim.opt_local.signcolumn = 'no'
|
||||||
|
vim.opt_local.statuscolumn = ''
|
||||||
|
vim.opt_local.laststatus = 0
|
||||||
|
vim.opt_local.cmdheight = 0
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
1
config/nvim/plugin/lines.lua
Normal file
1
config/nvim/plugin/lines.lua
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
require('config.lines').setup()
|
||||||
76
config/nvim/plugin/options.lua
Normal file
76
config/nvim/plugin/options.lua
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
local o, opt = vim.o, vim.opt
|
||||||
|
|
||||||
|
o.autowrite = true
|
||||||
|
|
||||||
|
o.breakindent = true
|
||||||
|
|
||||||
|
o.conceallevel = 0
|
||||||
|
|
||||||
|
opt.diffopt:append('linematch:60')
|
||||||
|
|
||||||
|
o.expandtab = true
|
||||||
|
|
||||||
|
o.exrc = true
|
||||||
|
o.secure = true
|
||||||
|
|
||||||
|
opt.foldcolumn = 'auto:1'
|
||||||
|
opt.signcolumn = 'no'
|
||||||
|
|
||||||
|
opt.fillchars = {
|
||||||
|
eob = ' ',
|
||||||
|
vert = '│',
|
||||||
|
diff = '╱',
|
||||||
|
}
|
||||||
|
|
||||||
|
opt.iskeyword:append('-')
|
||||||
|
|
||||||
|
o.laststatus = 3
|
||||||
|
|
||||||
|
o.linebreak = true
|
||||||
|
|
||||||
|
o.list = true
|
||||||
|
opt.listchars = {
|
||||||
|
space = ' ',
|
||||||
|
trail = '·',
|
||||||
|
tab = ' ',
|
||||||
|
}
|
||||||
|
|
||||||
|
opt.matchpairs:append('<:>')
|
||||||
|
|
||||||
|
o.number = true
|
||||||
|
o.relativenumber = true
|
||||||
|
|
||||||
|
opt.path:append('**')
|
||||||
|
|
||||||
|
o.scrolloff = 8
|
||||||
|
|
||||||
|
o.shiftwidth = 2
|
||||||
|
|
||||||
|
opt.shortmess:append('acCIs')
|
||||||
|
|
||||||
|
o.showmode = false
|
||||||
|
|
||||||
|
o.showtabline = 0
|
||||||
|
|
||||||
|
o.spellfile = (vim.env.XDG_DATA_HOME or (vim.env.HOME .. '/.local/share'))
|
||||||
|
.. '/nvim/spell.encoding.add'
|
||||||
|
|
||||||
|
o.splitkeep = 'screen'
|
||||||
|
|
||||||
|
o.splitbelow = true
|
||||||
|
o.splitright = true
|
||||||
|
|
||||||
|
o.swapfile = false
|
||||||
|
|
||||||
|
o.termguicolors = true
|
||||||
|
|
||||||
|
o.undodir = (vim.env.XDG_DATA_HOME or (vim.env.HOME .. '/.local/share'))
|
||||||
|
.. '/nvim/undo'
|
||||||
|
o.undofile = true
|
||||||
|
|
||||||
|
o.updatetime = 50
|
||||||
|
|
||||||
|
o.winborder = 'single'
|
||||||
|
o.winbar = ''
|
||||||
|
|
||||||
|
o.wrap = false
|
||||||
6
config/nvim/selene.toml
Normal file
6
config/nvim/selene.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
std = "vim"
|
||||||
|
|
||||||
|
exclude = [".luacheckrc"]
|
||||||
|
|
||||||
|
[rules]
|
||||||
|
mixed_table = "allow"
|
||||||
4
config/nvim/stylua.toml
Normal file
4
config/nvim/stylua.toml
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
quote_style = "AutoPreferSingle"
|
||||||
|
indent_type = "Spaces"
|
||||||
|
column_width = 80
|
||||||
|
collapse_simple_statement = "Never"
|
||||||
12
config/nvim/vim.toml
Normal file
12
config/nvim/vim.toml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
[selene]
|
||||||
|
base = "lua52"
|
||||||
|
name = "vim"
|
||||||
|
|
||||||
|
[vim]
|
||||||
|
any = true
|
||||||
|
|
||||||
|
[map]
|
||||||
|
any = true
|
||||||
|
|
||||||
|
[bmap]
|
||||||
|
any = true
|
||||||
1
config/zen/containers.json
Normal file
1
config/zen/containers.json
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":5,"lastUserContextId":5,"identities":[{"icon":"fingerprint","color":"blue","l10nId":"user-context-personal","public":true,"userContextId":1},{"icon":"briefcase","color":"orange","l10nId":"user-context-work","public":true,"userContextId":2},{"icon":"dollar","color":"green","l10nId":"user-context-banking","public":true,"userContextId":3},{"icon":"cart","color":"pink","l10nId":"user-context-shopping","public":true,"userContextId":4},{"public":false,"icon":"","color":"","name":"userContextIdInternal.thumbnail","accessKey":"","userContextId":5},{"userContextId":4294967295,"public":false,"icon":"","color":"","name":"userContextIdInternal.webextStorageLocal","accessKey":""}]}
|
||||||
4
config/zen/extensions.txt
Normal file
4
config/zen/extensions.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{446900e4-71c2-419f-a6a7-df9c091e268b}: Bitwarden Password Manager
|
||||||
|
addon@darkreader.org: Dark Reader
|
||||||
|
jid1-D7momAzRw417Ag@jetpack: Wikiwand - knowledge, with context
|
||||||
|
uBlock0@raymondhill.net: uBlock Origin
|
||||||
1
config/zen/handlers.json
Normal file
1
config/zen/handlers.json
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{"defaultHandlersVersion":{},"mimeTypes":{"application/pdf":{"action":3,"extensions":["pdf"]},"image/webp":{"action":3,"extensions":["webp"]},"image/avif":{"action":3,"extensions":["avif"]},"image/jxl":{"action":3,"extensions":["jxl"]}},"schemes":{"mailto":{"stubEntry":true,"handlers":[null,{"name":"Gmail","uriTemplate":"https://mail.google.com/mail/?extsrc=mailto&url=%s"}]},"io.element.desktop":{"action":4},"element":{"action":4}},"isDownloadsImprovementsAlreadyMigrated":false}
|
||||||
11
config/zen/user.js
Normal file
11
config/zen/user.js
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
user_pref("browser.urlbar.shortcuts.bookmarks", false);
|
||||||
|
user_pref("browser.urlbar.shortcuts.history", false);
|
||||||
|
user_pref("browser.urlbar.shortcuts.tabs", false);
|
||||||
|
user_pref("zen.tabs.show-newtab-vertical", false);
|
||||||
|
user_pref("zen.theme.border-radius", 0);
|
||||||
|
user_pref("zen.theme.content-element-separation", 0);
|
||||||
|
user_pref("zen.view.compact.enable-at-startup", false);
|
||||||
|
user_pref("zen.view.compact.hide-toolbar", true);
|
||||||
|
user_pref("zen.view.compact.toolbar-hide-after-hover.duration", 0);
|
||||||
|
user_pref("zen.view.experimental-no-window-controls", true);
|
||||||
|
user_pref("zen.workspaces.continue-where-left-off", true);
|
||||||
50
config/zen/userChrome.css
Normal file
50
config/zen/userChrome.css
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
#vertical-pinned-tabs-container > .zen-workspace-tabs-section[hidden="true"] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
tabs {
|
||||||
|
counter-reset: tab-counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
hbox.zen-essentials-container tab:not([zen-glance-tab="true"]),
|
||||||
|
zen-workspace[active] tab:not([zen-glance-tab="true"]) {
|
||||||
|
counter-increment: tab-counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (-moz-bool-pref: "zen.view.sidebar-expanded") {
|
||||||
|
tab:not([zen-glance-tab="true"]) > .tab-stack > .tab-content::before {
|
||||||
|
content: counter(tab-counter);
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 100%;
|
||||||
|
color: inherit;
|
||||||
|
z-index: -100;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
margin-left: 3px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media not (-moz-bool-pref: "zen.view.sidebar-expanded") {
|
||||||
|
tab:not([zen-glance-tab="true"]) > .tab-stack > .tab-content::before {
|
||||||
|
content: counter(tab-counter) "";
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
left: 1px;
|
||||||
|
z-index: -100;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 100%;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.zen-current-workspace-indicator {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#zen-media-controls-toolbar {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
1
config/zen/zen-keyboard-shortcuts.json
Normal file
1
config/zen/zen-keyboard-shortcuts.json
Normal file
File diff suppressed because one or more lines are too long
195
flake.lock
generated
Normal file
195
flake.lock
generated
Normal file
|
|
@ -0,0 +1,195 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": [
|
||||||
|
"neovim-nightly",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1769996383,
|
||||||
|
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"home-manager": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1769397130,
|
||||||
|
"narHash": "sha256-TTM4KV9IHwa181X7afBRbhLJIrgynpDjAXJFMUOWfyU=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"rev": "c37679d37bdbecf11bbe3c5eb238d89ca4f60641",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"home-manager_2": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"zen-browser",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1769872935,
|
||||||
|
"narHash": "sha256-07HMIGQ/WJeAQJooA7Kkg1SDKxhAiV6eodvOwTX6WKI=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"rev": "f4ad5068ee8e89e4a7c2e963e10dd35cd77b37b7",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"neovim-nightly": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
|
"neovim-src": "neovim-src",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1770336287,
|
||||||
|
"narHash": "sha256-czvrg8uyf2VWRmbobsthTAIJCg1GH4mEekyW01AvHco=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "neovim-nightly-overlay",
|
||||||
|
"rev": "1cd999cdf20536ac6a6d1aa17ba0242eefd2312b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "neovim-nightly-overlay",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"neovim-src": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1770334851,
|
||||||
|
"narHash": "sha256-FvT3T0l8eNr1Hv+D1Sj1jM/2vLkonLxpadTk6gdYHAo=",
|
||||||
|
"owner": "neovim",
|
||||||
|
"repo": "neovim",
|
||||||
|
"rev": "db133879b2a115cdf982b2899f154f1851d59a60",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "neovim",
|
||||||
|
"repo": "neovim",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixos-hardware": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1769302137,
|
||||||
|
"narHash": "sha256-QEDtctEkOsbx8nlFh4yqPEOtr4tif6KTqWwJ37IM2ds=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixos-hardware",
|
||||||
|
"rev": "a351494b0e35fd7c0b7a1aae82f0afddf4907aa8",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixos-hardware",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1770169770,
|
||||||
|
"narHash": "sha256-awR8qIwJxJJiOmcEGgP2KUqYmHG4v/z8XpL9z8FnT1A=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "aa290c9891fa4ebe88f8889e59633d20cc06a5f2",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1770169770,
|
||||||
|
"narHash": "sha256-awR8qIwJxJJiOmcEGgP2KUqYmHG4v/z8XpL9z8FnT1A=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "aa290c9891fa4ebe88f8889e59633d20cc06a5f2",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_3": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1769461804,
|
||||||
|
"narHash": "sha256-msG8SU5WsBUfVVa/9RPLaymvi5bI8edTavbIq3vRlhI=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "bfc1b8a4574108ceef22f02bafcf6611380c100d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"home-manager": "home-manager",
|
||||||
|
"neovim-nightly": "neovim-nightly",
|
||||||
|
"nixos-hardware": "nixos-hardware",
|
||||||
|
"nixpkgs": "nixpkgs_2",
|
||||||
|
"zen-browser": "zen-browser"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zen-browser": {
|
||||||
|
"inputs": {
|
||||||
|
"home-manager": "home-manager_2",
|
||||||
|
"nixpkgs": "nixpkgs_3"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1770382887,
|
||||||
|
"narHash": "sha256-on4vg7ctpMPzKWcvXPtV095aal6KUPDSKV9+I8HhQtY=",
|
||||||
|
"owner": "0xc000022070",
|
||||||
|
"repo": "zen-browser-flake",
|
||||||
|
"rev": "58aa8fb418e2853382d52453a6a7739125f2b8e0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "0xc000022070",
|
||||||
|
"repo": "zen-browser-flake",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
57
flake.nix
Normal file
57
flake.nix
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
{
|
||||||
|
description = "Barrett Ruth's Nix Configuration";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||||
|
home-manager = {
|
||||||
|
url = "github:nix-community/home-manager";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
nixos-hardware.url = "github:NixOS/nixos-hardware";
|
||||||
|
neovim-nightly.url = "github:nix-community/neovim-nightly-overlay";
|
||||||
|
zen-browser.url = "github:0xc000022070/zen-browser-flake";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { nixpkgs, home-manager, nixos-hardware, neovim-nightly, zen-browser, ... }:
|
||||||
|
let
|
||||||
|
system = "x86_64-linux";
|
||||||
|
pkgs = import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
config.allowUnfreePredicate = pkg: builtins.elem (nixpkgs.lib.getName pkg) [
|
||||||
|
"slack"
|
||||||
|
"claude-code"
|
||||||
|
"nvidia-x11"
|
||||||
|
"nvidia-settings"
|
||||||
|
];
|
||||||
|
overlays = [ neovim-nightly.overlays.default ];
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
nixosConfigurations.xps15 = nixpkgs.lib.nixosSystem {
|
||||||
|
inherit system;
|
||||||
|
modules = [
|
||||||
|
nixos-hardware.nixosModules.dell-xps-15-9500-nvidia
|
||||||
|
./hosts/xps15/configuration.nix
|
||||||
|
home-manager.nixosModules.home-manager
|
||||||
|
{
|
||||||
|
home-manager.useGlobalPkgs = true;
|
||||||
|
home-manager.useUserPackages = true;
|
||||||
|
home-manager.users.barrett = import ./home/home.nix;
|
||||||
|
home-manager.extraSpecialArgs = {
|
||||||
|
inherit zen-browser system;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
specialArgs = {
|
||||||
|
inherit nixpkgs;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
homeConfigurations.barrett = home-manager.lib.homeManagerConfiguration {
|
||||||
|
inherit pkgs;
|
||||||
|
extraSpecialArgs = {
|
||||||
|
inherit zen-browser system;
|
||||||
|
};
|
||||||
|
modules = [ ./home/home.nix ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
33
home/home.nix
Normal file
33
home/home.nix
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
{ lib, config, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
isNixOS = builtins.pathExists /etc/NIXOS;
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
./modules/theme.nix
|
||||||
|
./modules/shell.nix
|
||||||
|
./modules/terminal.nix
|
||||||
|
./modules/git.nix
|
||||||
|
./modules/editor.nix
|
||||||
|
./modules/ui.nix
|
||||||
|
./modules/packages.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
config = {
|
||||||
|
theme = "midnight";
|
||||||
|
|
||||||
|
home.username = "barrett";
|
||||||
|
home.homeDirectory = "/home/${config.home.username}";
|
||||||
|
home.stateVersion = "24.11";
|
||||||
|
|
||||||
|
xdg.enable = true;
|
||||||
|
targets.genericLinux.enable = !isNixOS;
|
||||||
|
news.display = "silent";
|
||||||
|
|
||||||
|
home.file.".local/bin/scripts" = {
|
||||||
|
source = config.lib.file.mkOutOfStoreSymlink "${config.home.homeDirectory}/nix-config/scripts";
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.home-manager.enable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
17
home/modules/editor.nix
Normal file
17
home/modules/editor.nix
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
{ pkgs, config, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
home.sessionVariables = {
|
||||||
|
EDITOR = "nvim";
|
||||||
|
MANPAGER = "nvim +Man!";
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.neovim = {
|
||||||
|
enable = true;
|
||||||
|
defaultEditor = true;
|
||||||
|
viAlias = true;
|
||||||
|
vimAlias = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.configFile."nvim".source = config.lib.file.mkOutOfStoreSymlink "${config.home.homeDirectory}/nix-config/config/nvim";
|
||||||
|
}
|
||||||
95
home/modules/git.nix
Normal file
95
home/modules/git.nix
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
{ pkgs, config, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
programs.git = {
|
||||||
|
enable = true;
|
||||||
|
lfs.enable = true;
|
||||||
|
|
||||||
|
ignores = [
|
||||||
|
"*.swp"
|
||||||
|
"*.swo"
|
||||||
|
"*~"
|
||||||
|
".vscode/"
|
||||||
|
".idea/"
|
||||||
|
".DS_Store"
|
||||||
|
"Thumbs.db"
|
||||||
|
"*.o"
|
||||||
|
"*.a"
|
||||||
|
"*.so"
|
||||||
|
"*.pyc"
|
||||||
|
"__pycache__/"
|
||||||
|
"node_modules/"
|
||||||
|
"target/"
|
||||||
|
"dist/"
|
||||||
|
"build/"
|
||||||
|
"out/"
|
||||||
|
"*.class"
|
||||||
|
"*.log"
|
||||||
|
".env"
|
||||||
|
".env.local"
|
||||||
|
".envrc"
|
||||||
|
"venv/"
|
||||||
|
".mypy_cache/"
|
||||||
|
"result"
|
||||||
|
"result-*"
|
||||||
|
".claude/settings.local.json"
|
||||||
|
];
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
user = {
|
||||||
|
name = "Barrett Ruth";
|
||||||
|
email = "br@barrettruth.com";
|
||||||
|
};
|
||||||
|
alias = {
|
||||||
|
a = "add";
|
||||||
|
b = "branch";
|
||||||
|
c = "commit";
|
||||||
|
acp = "!acp() { git add . && git commit -m \"$*\" && git push; }; acp";
|
||||||
|
cane = "commit --amend --no-edit";
|
||||||
|
cf = "config";
|
||||||
|
ch = "checkout";
|
||||||
|
cl = "clone";
|
||||||
|
cp = "cherry-pick";
|
||||||
|
d = "diff";
|
||||||
|
dt = "difftool";
|
||||||
|
f = "fetch";
|
||||||
|
i = "init";
|
||||||
|
lg = "log --oneline --graph --decorate";
|
||||||
|
m = "merge";
|
||||||
|
p = "pull";
|
||||||
|
pu = "push";
|
||||||
|
r = "remote";
|
||||||
|
rb = "rebase";
|
||||||
|
rs = "restore";
|
||||||
|
rt = "reset";
|
||||||
|
s = "status";
|
||||||
|
sm = "submodule";
|
||||||
|
st = "stash";
|
||||||
|
sw = "switch";
|
||||||
|
wt = "worktree";
|
||||||
|
};
|
||||||
|
init.defaultBranch = "main";
|
||||||
|
core = {
|
||||||
|
editor = "nvim";
|
||||||
|
whitespace = "fix,-indent-with-non-tab,trailing-space,cr-at-eol";
|
||||||
|
};
|
||||||
|
color.ui = "auto";
|
||||||
|
diff.tool = "codediff";
|
||||||
|
difftool.prompt = false;
|
||||||
|
difftool.codediff.cmd = "nvim -c 'CodeDiff' $LOCAL $REMOTE";
|
||||||
|
merge.tool = "codediff";
|
||||||
|
mergetool.prompt = false;
|
||||||
|
mergetool.codediff.cmd = "nvim -c 'CodeDiff' $LOCAL $REMOTE $MERGED";
|
||||||
|
push.autoSetupRemote = true;
|
||||||
|
credential.helper = "cache";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.gh = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
git_protocol = "ssh";
|
||||||
|
prompt = "enabled";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
92
home/modules/packages.nix
Normal file
92
home/modules/packages.nix
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
{ pkgs, lib, config, zen-browser, system, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
zen = true;
|
||||||
|
sioyek = true;
|
||||||
|
vesktop = true;
|
||||||
|
neovim = config.programs.neovim.enable;
|
||||||
|
in {
|
||||||
|
home.sessionVariables = lib.optionalAttrs zen {
|
||||||
|
BROWSER = "zen-browser";
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.mpv.enable = true;
|
||||||
|
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
signal-desktop
|
||||||
|
slack
|
||||||
|
bitwarden-desktop
|
||||||
|
claude-code
|
||||||
|
]
|
||||||
|
++ lib.optionals zen [ zen-browser.packages.${system}.default ]
|
||||||
|
++ lib.optionals sioyek [ pkgs.sioyek ]
|
||||||
|
++ lib.optionals vesktop [ pkgs.vesktop ];
|
||||||
|
|
||||||
|
home.activation.linkZenProfile = lib.mkIf zen (
|
||||||
|
lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||||
|
zen_config="$HOME/.zen"
|
||||||
|
repo_zen="${config.home.homeDirectory}/nix-config/config/zen"
|
||||||
|
|
||||||
|
if [ ! -d "$zen_config" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
profile=""
|
||||||
|
for d in "$zen_config"/*.Default\ \(release\); do
|
||||||
|
[ -d "$d" ] && profile="$d" && break
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$profile" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$profile/chrome"
|
||||||
|
|
||||||
|
for f in userChrome.css user.js containers.json handlers.json zen-keyboard-shortcuts.json; do
|
||||||
|
src="$repo_zen/$f"
|
||||||
|
if [ "$f" = "userChrome.css" ]; then
|
||||||
|
dest="$profile/chrome/$f"
|
||||||
|
else
|
||||||
|
dest="$profile/$f"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -f "$src" ] || continue
|
||||||
|
|
||||||
|
if [ -L "$dest" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$dest" ]; then
|
||||||
|
rm "$dest"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ln -s "$src" "$dest"
|
||||||
|
done
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
|
xdg.configFile."electron-flags.conf".text = ''
|
||||||
|
--enable-features=WaylandWindowDecorations
|
||||||
|
--ozone-platform-hint=auto
|
||||||
|
'';
|
||||||
|
|
||||||
|
xdg.mimeApps = {
|
||||||
|
enable = true;
|
||||||
|
defaultApplications = {}
|
||||||
|
// lib.optionalAttrs zen {
|
||||||
|
"x-scheme-handler/http" = "zen.desktop";
|
||||||
|
"x-scheme-handler/https" = "zen.desktop";
|
||||||
|
"text/html" = "zen.desktop";
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs neovim {
|
||||||
|
"text/plain" = "nvim.desktop";
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs sioyek {
|
||||||
|
"application/pdf" = "sioyek.desktop";
|
||||||
|
"application/epub" = "sioyek.desktop";
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs vesktop {
|
||||||
|
"x-scheme-handler/discord" = "vesktop.desktop";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
504
home/modules/shell.nix
Normal file
504
home/modules/shell.nix
Normal file
|
|
@ -0,0 +1,504 @@
|
||||||
|
{ pkgs, lib, config, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
c = config.colors;
|
||||||
|
isNixOS = builtins.pathExists /etc/NIXOS;
|
||||||
|
|
||||||
|
ripgrep = config.programs.ripgrep.enable;
|
||||||
|
|
||||||
|
rust = true;
|
||||||
|
go = true;
|
||||||
|
node = true;
|
||||||
|
python = true;
|
||||||
|
ocaml = true;
|
||||||
|
docker = true;
|
||||||
|
aws = true;
|
||||||
|
psql = true;
|
||||||
|
sqlite = true;
|
||||||
|
in {
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
pure-prompt
|
||||||
|
xclip
|
||||||
|
tree
|
||||||
|
jq
|
||||||
|
curl
|
||||||
|
wget
|
||||||
|
unzip
|
||||||
|
tesseract
|
||||||
|
gnumake
|
||||||
|
gcc
|
||||||
|
file
|
||||||
|
ffmpeg
|
||||||
|
poppler-utils
|
||||||
|
librsvg
|
||||||
|
imagemagick
|
||||||
|
];
|
||||||
|
|
||||||
|
home.sessionVariables = {
|
||||||
|
LESSHISTFILE = "-";
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs ripgrep {
|
||||||
|
RIPGREP_CONFIG_PATH = "${config.xdg.configHome}/rg/config";
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs rust {
|
||||||
|
CARGO_HOME = "${config.xdg.dataHome}/cargo";
|
||||||
|
RUSTUP_HOME = "${config.xdg.dataHome}/rustup";
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs go {
|
||||||
|
GOPATH = "${config.xdg.dataHome}/go";
|
||||||
|
GOMODCACHE = "${config.xdg.cacheHome}/go/mod";
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs node {
|
||||||
|
NPM_CONFIG_USERCONFIG = "${config.xdg.configHome}/npm/npmrc";
|
||||||
|
NODE_REPL_HISTORY = "${config.xdg.stateHome}/node_repl_history";
|
||||||
|
PNPM_HOME = "${config.xdg.dataHome}/pnpm";
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs python {
|
||||||
|
PYTHONSTARTUP = "${config.xdg.configHome}/python/pythonrc";
|
||||||
|
PYTHON_HISTORY = "${config.xdg.stateHome}/python_history";
|
||||||
|
PYTHONPYCACHEPREFIX = "${config.xdg.cacheHome}/python";
|
||||||
|
PYTHONUSERBASE = "${config.xdg.dataHome}/python";
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs ocaml {
|
||||||
|
OPAMROOT = "${config.xdg.dataHome}/opam";
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs docker {
|
||||||
|
DOCKER_CONFIG = "${config.xdg.configHome}/docker";
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs aws {
|
||||||
|
AWS_SHARED_CREDENTIALS_FILE = "${config.xdg.configHome}/aws/credentials";
|
||||||
|
AWS_CONFIG_FILE = "${config.xdg.configHome}/aws/config";
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs psql {
|
||||||
|
PSQL_HISTORY = "${config.xdg.stateHome}/psql_history";
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs sqlite {
|
||||||
|
SQLITE_HISTORY = "${config.xdg.stateHome}/sqlite_history";
|
||||||
|
};
|
||||||
|
|
||||||
|
home.sessionPath = [
|
||||||
|
"${config.home.homeDirectory}/.local/bin"
|
||||||
|
"${config.home.homeDirectory}/.local/bin/scripts"
|
||||||
|
]
|
||||||
|
++ lib.optionals rust [ "${config.xdg.dataHome}/cargo/bin" ]
|
||||||
|
++ lib.optionals go [ "${config.xdg.dataHome}/go/bin" ]
|
||||||
|
++ lib.optionals node [ "${config.xdg.dataHome}/pnpm" ];
|
||||||
|
|
||||||
|
xdg.configFile."npm/npmrc" = lib.mkIf node {
|
||||||
|
text = ''
|
||||||
|
prefix=''${XDG_DATA_HOME}/npm
|
||||||
|
cache=''${XDG_CACHE_HOME}/npm
|
||||||
|
init-module=''${XDG_CONFIG_HOME}/npm/config/npm-init.js
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.configFile."python/pythonrc" = lib.mkIf python {
|
||||||
|
text = ''
|
||||||
|
import atexit
|
||||||
|
import os
|
||||||
|
import readline
|
||||||
|
|
||||||
|
history = os.path.join(os.environ.get('XDG_STATE_HOME', os.path.expanduser('~/.local/state')), 'python_history')
|
||||||
|
|
||||||
|
try:
|
||||||
|
readline.read_history_file(history)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def write_history():
|
||||||
|
try:
|
||||||
|
readline.write_history_file(history)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
atexit.register(write_history)
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.configFile."rg/config" = lib.mkIf ripgrep {
|
||||||
|
text = ''
|
||||||
|
--column
|
||||||
|
--no-heading
|
||||||
|
--smart-case
|
||||||
|
--no-follow
|
||||||
|
--glob=!pnpm-lock.yaml
|
||||||
|
--glob=!*.json
|
||||||
|
--glob=!venv/
|
||||||
|
--glob=!pyenv/
|
||||||
|
--ignore-file=${config.xdg.configHome}/git/ignore
|
||||||
|
--no-messages
|
||||||
|
--color=auto
|
||||||
|
--colors=line:style:nobold
|
||||||
|
--colors=line:fg:242
|
||||||
|
--colors=match:fg:green
|
||||||
|
--colors=match:style:bold
|
||||||
|
--colors=path:fg:blue
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.zsh = {
|
||||||
|
enable = true;
|
||||||
|
dotDir = "${config.xdg.configHome}/zsh";
|
||||||
|
|
||||||
|
history = {
|
||||||
|
path = "${config.xdg.stateHome}/zsh_history";
|
||||||
|
size = 2000;
|
||||||
|
save = 2000;
|
||||||
|
ignoreDups = true;
|
||||||
|
ignoreAllDups = true;
|
||||||
|
ignoreSpace = true;
|
||||||
|
extended = true;
|
||||||
|
append = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
shellAliases = {
|
||||||
|
ls = "eza";
|
||||||
|
l = "ls --color=auto --group-directories-first";
|
||||||
|
ll = "l -alF";
|
||||||
|
la = "ll -R";
|
||||||
|
g = "git";
|
||||||
|
nv = "nvim";
|
||||||
|
pe = "printenv";
|
||||||
|
};
|
||||||
|
|
||||||
|
completionInit = ''
|
||||||
|
autoload -U compinit && compinit -d "$XDG_STATE_HOME/zcompdump" -u
|
||||||
|
zmodload zsh/complist
|
||||||
|
zstyle ':completion:*' list-colors ''${(s.:.)LS_COLORS}
|
||||||
|
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-za-z}'
|
||||||
|
'';
|
||||||
|
|
||||||
|
initContent = ''
|
||||||
|
export THEME="''${THEME:-${config.theme}}"
|
||||||
|
|
||||||
|
setopt auto_cd
|
||||||
|
unsetopt beep notify
|
||||||
|
unset completealiases
|
||||||
|
|
||||||
|
bindkey -v
|
||||||
|
bindkey '^[[3~' delete-char
|
||||||
|
bindkey '^P' up-line-or-history
|
||||||
|
bindkey '^N' down-line-or-history
|
||||||
|
bindkey '^J' backward-char
|
||||||
|
bindkey '^K' forward-char
|
||||||
|
|
||||||
|
export PURE_PROMPT_SYMBOL=">"
|
||||||
|
export PURE_PROMPT_VICMD_SYMBOL="<"
|
||||||
|
export PURE_GIT_UP_ARROW="^"
|
||||||
|
export PURE_GIT_DOWN_ARROW="v"
|
||||||
|
export PURE_GIT_STASH_SYMBOL="="
|
||||||
|
export PURE_CMD_MAX_EXEC_TIME=5
|
||||||
|
export PURE_GIT_PULL=0
|
||||||
|
export PURE_GIT_UNTRACKED_DIRTY=1
|
||||||
|
zstyle ':prompt:pure:git:stash' show yes
|
||||||
|
|
||||||
|
fpath+=("${pkgs.pure-prompt}/share/zsh/site-functions")
|
||||||
|
autoload -Uz promptinit && promptinit
|
||||||
|
prompt pure
|
||||||
|
|
||||||
|
autoload -Uz add-zle-hook-widget
|
||||||
|
function _cursor_shape() {
|
||||||
|
case $KEYMAP in
|
||||||
|
vicmd) echo -ne '\e[2 q' ;;
|
||||||
|
viins|main) echo -ne '\e[6 q' ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
function _cursor_init() { echo -ne '\e[6 q'; }
|
||||||
|
add-zle-hook-widget zle-keymap-select _cursor_shape
|
||||||
|
add-zle-hook-widget zle-line-init _cursor_init
|
||||||
|
|
||||||
|
export FZF_COMPLETION_TRIGGER=\;
|
||||||
|
export FZF_TMUX=1
|
||||||
|
|
||||||
|
fzf-config-widget() {
|
||||||
|
file="$(fd --type file --hidden . ~/.config | sed "s|$HOME|~|g" | fzf)"
|
||||||
|
[ -n "$file" ] || { zle reset-prompt; return; }
|
||||||
|
file="${file/#\~/$HOME}"
|
||||||
|
BUFFER="nvim $file"
|
||||||
|
zle accept-line
|
||||||
|
}
|
||||||
|
zle -N fzf-config-widget
|
||||||
|
bindkey '^E' fzf-config-widget
|
||||||
|
|
||||||
|
'' + lib.optionalString ocaml ''
|
||||||
|
[[ ! -r "$OPAMROOT/opam-init/init.zsh" ]] || source "$OPAMROOT/opam-init/init.zsh" > /dev/null 2> /dev/null
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.fzf = {
|
||||||
|
enable = true;
|
||||||
|
enableZshIntegration = true;
|
||||||
|
defaultCommand = "rg --files --hidden";
|
||||||
|
defaultOptions = [
|
||||||
|
"--bind=ctrl-a:select-all"
|
||||||
|
"--bind=ctrl-f:half-page-down"
|
||||||
|
"--bind=ctrl-b:half-page-up"
|
||||||
|
"--no-scrollbar"
|
||||||
|
"--no-info"
|
||||||
|
"--color=fg:${c.fg},bg:${c.bg},hl:${c.accent}"
|
||||||
|
"--color=fg+:${c.fg},bg+:${c.bgAlt},hl+:${c.accent}"
|
||||||
|
"--color=info:${c.green},prompt:${c.accent},pointer:${c.fg},marker:${c.green},spinner:${c.fg}"
|
||||||
|
];
|
||||||
|
changeDirWidgetCommand = "fd --type d --hidden";
|
||||||
|
fileWidgetCommand = "rg --files --hidden";
|
||||||
|
historyWidgetOptions = [ "--reverse" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.eza = {
|
||||||
|
enable = true;
|
||||||
|
enableZshIntegration = false;
|
||||||
|
git = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.zoxide = {
|
||||||
|
enable = true;
|
||||||
|
enableZshIntegration = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.direnv = {
|
||||||
|
enable = true;
|
||||||
|
enableZshIntegration = true;
|
||||||
|
nix-direnv.enable = true;
|
||||||
|
stdlib = ''
|
||||||
|
layout_uv() {
|
||||||
|
if [[ ! -d .venv ]]; then
|
||||||
|
uv venv
|
||||||
|
fi
|
||||||
|
source .venv/bin/activate
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.ripgrep.enable = true;
|
||||||
|
|
||||||
|
programs.fd = {
|
||||||
|
enable = true;
|
||||||
|
hidden = true;
|
||||||
|
ignores = [
|
||||||
|
".git/"
|
||||||
|
"node_modules/"
|
||||||
|
"target/"
|
||||||
|
"venv/"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.tmux = {
|
||||||
|
enable = true;
|
||||||
|
shortcut = "x";
|
||||||
|
keyMode = "vi";
|
||||||
|
mouse = true;
|
||||||
|
escapeTime = 0;
|
||||||
|
historyLimit = 50000;
|
||||||
|
baseIndex = 1;
|
||||||
|
aggressiveResize = true;
|
||||||
|
focusEvents = true;
|
||||||
|
sensibleOnTop = false;
|
||||||
|
|
||||||
|
plugins = with pkgs.tmuxPlugins; [
|
||||||
|
resurrect
|
||||||
|
{
|
||||||
|
plugin = continuum;
|
||||||
|
extraConfig = ''
|
||||||
|
set -g @continuum-restore 'on'
|
||||||
|
set -g @continuum-save-interval '10'
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
extraConfig = ''
|
||||||
|
set -g prefix M-x
|
||||||
|
unbind C-b
|
||||||
|
bind M-x send
|
||||||
|
|
||||||
|
set -g default-terminal "$TERM"
|
||||||
|
set -g default-shell "$SHELL"
|
||||||
|
|
||||||
|
set -g renumber-windows on
|
||||||
|
set -g pane-base-index 1
|
||||||
|
|
||||||
|
set -g status-position bottom
|
||||||
|
set -g status-interval 5
|
||||||
|
set -g status-left ' '
|
||||||
|
set -g status-right ''
|
||||||
|
set-hook -g session-created 'run "mux bar #S"'
|
||||||
|
set-hook -g session-closed 'run "mux bar #S"'
|
||||||
|
set-hook -g client-session-changed 'run "mux bar #S"'
|
||||||
|
|
||||||
|
set -g status-bg '${c.bg}'
|
||||||
|
set -g status-fg '${c.fg}'
|
||||||
|
set -g window-status-style fg='${c.fg}'
|
||||||
|
set -g window-status-current-style fg='${c.fg}'
|
||||||
|
set -g window-status-bell-style fg='${c.bellFg}',bg='${c.bg}',bold
|
||||||
|
set -g window-status-activity-style fg='${c.activityFg}',bg='${c.bg}',bold
|
||||||
|
set -g pane-border-style fg='${c.border}'
|
||||||
|
set -g pane-active-border-style fg='${c.fg}'
|
||||||
|
|
||||||
|
set -as terminal-features ",$TERM:RGB"
|
||||||
|
set -as terminal-overrides ",*:U8=1"
|
||||||
|
set -as terminal-overrides ',*:Smulx=\E[4::%p1%dm'
|
||||||
|
set -as terminal-overrides ',*:Setulc=\E[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m'
|
||||||
|
|
||||||
|
unbind Left; bind h selectp -L
|
||||||
|
unbind Down; bind j selectp -D
|
||||||
|
unbind Up; bind k selectp -U
|
||||||
|
unbind Right; bind l selectp -R
|
||||||
|
|
||||||
|
unbind m; bind m choose-tree -Z "join-pane -t '%%'"
|
||||||
|
unbind n; bind n break-pane
|
||||||
|
unbind p; bind p choose-tree -Z "join-pane -s '%%'"
|
||||||
|
|
||||||
|
bind -r Left resizep -L 5
|
||||||
|
bind -r Right resizep -R 5
|
||||||
|
bind -r Up resizep -U 5
|
||||||
|
bind -r Down resizep -D 5
|
||||||
|
|
||||||
|
unbind c; bind c neww -c '#{pane_current_path}'
|
||||||
|
unbind \'; bind \' splitw -hc '#{pane_current_path}'
|
||||||
|
unbind \-; bind \- splitw -vc '#{pane_current_path}'
|
||||||
|
|
||||||
|
unbind y; bind y copy-mode
|
||||||
|
|
||||||
|
bind -T copy-mode-vi v send -X begin-selection
|
||||||
|
bind -T copy-mode-vi y send -X copy-pipe-and-cancel 'xclip -in -sel c'
|
||||||
|
|
||||||
|
unbind C-b; bind C-b set status
|
||||||
|
unbind C-m; bind C-m set mouse\; run 'mux bar #S'
|
||||||
|
|
||||||
|
unbind e; bind e neww -n 'tmux.conf' "sh -c 'nvim $XDG_CONFIG_HOME/tmux/tmux.conf && tmux source $XDG_CONFIG_HOME/tmux/tmux.conf'"
|
||||||
|
|
||||||
|
unbind H; bind H run 'mux switch 0'\; run 'mux bar #S'
|
||||||
|
unbind J; bind J run 'mux switch 1'\; run 'mux bar #S'
|
||||||
|
unbind K; bind K run 'mux switch 2'\; run 'mux bar #S'
|
||||||
|
unbind L; bind L run 'mux switch 3'\; run 'mux bar #S'
|
||||||
|
unbind \$; bind \$ run 'mux switch 4'\; run 'mux bar #S'
|
||||||
|
|
||||||
|
unbind Tab; bind Tab switchc -l
|
||||||
|
|
||||||
|
set-hook -g client-light-theme 'source ${config.xdg.configHome}/tmux/themes/daylight.conf'
|
||||||
|
set-hook -g client-dark-theme 'source ${config.xdg.configHome}/tmux/themes/midnight.conf'
|
||||||
|
|
||||||
|
unbind N; bind N run 'mux nvim'
|
||||||
|
unbind C; bind C run 'mux claude'
|
||||||
|
unbind R; bind R run 'mux run'
|
||||||
|
unbind T; bind T run 'mux term'
|
||||||
|
unbind G; bind G run 'mux git'
|
||||||
|
|
||||||
|
set -g lock-after-time 300
|
||||||
|
set -g lock-command "pipes -p 2"
|
||||||
|
|
||||||
|
set -g @resurrect-capture-pane-contents on
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.configFile."tmux/themes/midnight.conf".text = ''
|
||||||
|
set -g status-bg '#121212'
|
||||||
|
set -g status-fg '#e0e0e0'
|
||||||
|
set -g window-status-style fg='#e0e0e0'
|
||||||
|
set -g window-status-current-style fg='#e0e0e0'
|
||||||
|
set -g window-status-bell-style fg='#ff6b6b',bg='#121212',bold
|
||||||
|
set -g window-status-activity-style fg='#7aa2f7',bg='#121212',bold
|
||||||
|
set -g pane-border-style fg='#3d3d3d'
|
||||||
|
set -g pane-active-border-style fg='#e0e0e0'
|
||||||
|
'';
|
||||||
|
|
||||||
|
xdg.configFile."tmux/themes/daylight.conf".text = ''
|
||||||
|
set -g status-bg '#f5f5f5'
|
||||||
|
set -g status-fg '#1a1a1a'
|
||||||
|
set -g window-status-style fg='#1a1a1a'
|
||||||
|
set -g window-status-current-style fg='#1a1a1a'
|
||||||
|
set -g window-status-bell-style fg='#c7254e',bg='#f5f5f5',bold
|
||||||
|
set -g window-status-activity-style fg='#3b5bdb',bg='#f5f5f5',bold
|
||||||
|
set -g pane-border-style fg='#e8e8e8'
|
||||||
|
set -g pane-active-border-style fg='#1a1a1a'
|
||||||
|
'';
|
||||||
|
|
||||||
|
programs.lf = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
drawbox = true;
|
||||||
|
number = true;
|
||||||
|
relativenumber = true;
|
||||||
|
hidden = true;
|
||||||
|
shell = "zsh";
|
||||||
|
icons = false;
|
||||||
|
incsearch = true;
|
||||||
|
scrolloff = 4;
|
||||||
|
tabstop = 2;
|
||||||
|
smartcase = true;
|
||||||
|
dircounts = true;
|
||||||
|
info = "size";
|
||||||
|
ratios = "1:2:3";
|
||||||
|
timefmt = "2006-01-02 15:04:05 -0700";
|
||||||
|
previewer = "~/.config/lf/previewer";
|
||||||
|
cleaner = "~/.config/lf/cleaner";
|
||||||
|
};
|
||||||
|
|
||||||
|
commands = {
|
||||||
|
open = ''$${{
|
||||||
|
setsid -f xdg-open "$f" 2>/dev/null 2>&1 &
|
||||||
|
}}'';
|
||||||
|
sopen = ''$${{
|
||||||
|
for f in $fx; do
|
||||||
|
setsid -f xdg-open "$f" >/dev/null 2>&1 &
|
||||||
|
done
|
||||||
|
}}'';
|
||||||
|
rmd = ''$${{
|
||||||
|
set -f
|
||||||
|
while IFS= read -r dir; do
|
||||||
|
rmdir -v -- "$dir"
|
||||||
|
done <<< "$fx"
|
||||||
|
}}'';
|
||||||
|
rmf = ''$${{
|
||||||
|
set -f
|
||||||
|
while IFS= read -r file; do
|
||||||
|
rm -v -- "$file"
|
||||||
|
done <<< "$fx"
|
||||||
|
}}'';
|
||||||
|
resize = ''%{{
|
||||||
|
w=$(tmux display-message -p '#{pane_width}' || tput cols)
|
||||||
|
if [ $w -le 62 ]; then
|
||||||
|
lf -remote "send $id set ratios 1:4"
|
||||||
|
lf -remote "send $id set nopreview"
|
||||||
|
elif [ $w -le 80 ]; then
|
||||||
|
lf -remote "send $id set ratios 1:2:2"
|
||||||
|
elif [ $w -le 100 ]; then
|
||||||
|
lf -remote "send $id set ratios 1:2:3"
|
||||||
|
else
|
||||||
|
lf -remote "send $id set ratios 2:4:5"
|
||||||
|
fi
|
||||||
|
}}'';
|
||||||
|
on-init = ''%{{
|
||||||
|
lf -remote "send $id resize"
|
||||||
|
}}'';
|
||||||
|
};
|
||||||
|
|
||||||
|
keybindings = {
|
||||||
|
"<c-o>" = ":sopen; quit";
|
||||||
|
"." = "set hidden!";
|
||||||
|
"ad" = "push $mkdir<space>";
|
||||||
|
"af" = "push $touch<space>";
|
||||||
|
"xd" = "rmd";
|
||||||
|
"xf" = "rmf";
|
||||||
|
"H" = "jump-prev";
|
||||||
|
"L" = "jump-next";
|
||||||
|
"<c-t>" = ''$lf -remote "send $id select $(fzf)"'';
|
||||||
|
"zz" = "push :z<space>";
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = ''
|
||||||
|
set shellopts '-eu'
|
||||||
|
set ifs "\n"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.configFile."lf/previewer" = {
|
||||||
|
source = config.lib.file.mkOutOfStoreSymlink "${config.home.homeDirectory}/nix-config/config/lf/previewer";
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.configFile."lf/cleaner" = {
|
||||||
|
source = config.lib.file.mkOutOfStoreSymlink "${config.home.homeDirectory}/nix-config/config/lf/cleaner";
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.configFile."lf/lf.lua".source = config.lib.file.mkOutOfStoreSymlink "${config.home.homeDirectory}/nix-config/config/lf/lf.lua";
|
||||||
|
xdg.configFile."lf/sort.py".source = config.lib.file.mkOutOfStoreSymlink "${config.home.homeDirectory}/nix-config/config/lf/sort.py";
|
||||||
|
}
|
||||||
95
home/modules/terminal.nix
Normal file
95
home/modules/terminal.nix
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
{ pkgs, config, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
c = config.colors;
|
||||||
|
in {
|
||||||
|
home.sessionVariables = {
|
||||||
|
TERMINAL = "ghostty";
|
||||||
|
TERM = "xterm-ghostty";
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.ghostty = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
font-family = "Berkeley Mono";
|
||||||
|
font-feature = "-calt";
|
||||||
|
font-size = 20;
|
||||||
|
adjust-cell-height = "10%";
|
||||||
|
|
||||||
|
theme = "dark:midnight,light:daylight";
|
||||||
|
|
||||||
|
cursor-style-blink = false;
|
||||||
|
shell-integration-features = "no-cursor";
|
||||||
|
|
||||||
|
window-decoration = false;
|
||||||
|
window-padding-x = 0;
|
||||||
|
window-padding-y = 0;
|
||||||
|
window-padding-color = "background";
|
||||||
|
app-notifications = "no-clipboard-copy,no-config-reload";
|
||||||
|
resize-overlay = "never";
|
||||||
|
mouse-scroll-multiplier = 0.5;
|
||||||
|
quit-after-last-window-closed = true;
|
||||||
|
confirm-close-surface = false;
|
||||||
|
|
||||||
|
keybind = [
|
||||||
|
"clear"
|
||||||
|
"alt+r=reload_config"
|
||||||
|
"alt+y=copy_to_clipboard"
|
||||||
|
"alt+p=paste_from_clipboard"
|
||||||
|
"alt+shift+h=decrease_font_size:1"
|
||||||
|
"alt+shift+l=increase_font_size:1"
|
||||||
|
"shift+enter=text:\\n"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.configFile."ghostty/themes/midnight".text = ''
|
||||||
|
palette = 0=#121212
|
||||||
|
palette = 1=#ff6b6b
|
||||||
|
palette = 2=#98c379
|
||||||
|
palette = 3=#e5c07b
|
||||||
|
palette = 4=#7aa2f7
|
||||||
|
palette = 5=#c678dd
|
||||||
|
palette = 6=#56b6c2
|
||||||
|
palette = 7=#e0e0e0
|
||||||
|
palette = 8=#666666
|
||||||
|
palette = 9=#f48771
|
||||||
|
palette = 10=#b5e890
|
||||||
|
palette = 11=#f0d197
|
||||||
|
palette = 12=#9db8f7
|
||||||
|
palette = 13=#e298ff
|
||||||
|
palette = 14=#7dd6e0
|
||||||
|
palette = 15=#ffffff
|
||||||
|
background = #121212
|
||||||
|
foreground = #e0e0e0
|
||||||
|
cursor-color = #ff6b6b
|
||||||
|
cursor-text = #121212
|
||||||
|
selection-background = #2d2d2d
|
||||||
|
selection-foreground = #e0e0e0
|
||||||
|
'';
|
||||||
|
|
||||||
|
xdg.configFile."ghostty/themes/daylight".text = ''
|
||||||
|
palette = 0=#f5f5f5
|
||||||
|
palette = 1=#c7254e
|
||||||
|
palette = 2=#2d7f3e
|
||||||
|
palette = 3=#996800
|
||||||
|
palette = 4=#3b5bdb
|
||||||
|
palette = 5=#ae3ec9
|
||||||
|
palette = 6=#1098ad
|
||||||
|
palette = 7=#1a1a1a
|
||||||
|
palette = 8=#999999
|
||||||
|
palette = 9=#e03e52
|
||||||
|
palette = 10=#37b24d
|
||||||
|
palette = 11=#f59f00
|
||||||
|
palette = 12=#4c6ef5
|
||||||
|
palette = 13=#da77f2
|
||||||
|
palette = 14=#15aabf
|
||||||
|
palette = 15=#000000
|
||||||
|
background = #f5f5f5
|
||||||
|
foreground = #1a1a1a
|
||||||
|
cursor-color = #e03e52
|
||||||
|
cursor-text = #f5f5f5
|
||||||
|
selection-background = #ebebeb
|
||||||
|
selection-foreground = #1a1a1a
|
||||||
|
'';
|
||||||
|
}
|
||||||
50
home/modules/theme.nix
Normal file
50
home/modules/theme.nix
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
palettes = {
|
||||||
|
midnight = {
|
||||||
|
bg = "#121212";
|
||||||
|
fg = "#e0e0e0";
|
||||||
|
bgAlt = "#2d2d2d";
|
||||||
|
fgAlt = "#666666";
|
||||||
|
border = "#3d3d3d";
|
||||||
|
accent = "#7aa2f7";
|
||||||
|
green = "#98c379";
|
||||||
|
red = "#ff6b6b";
|
||||||
|
yellow = "#e5c07b";
|
||||||
|
blue = "#7aa2f7";
|
||||||
|
magenta = "#c678dd";
|
||||||
|
cyan = "#56b6c2";
|
||||||
|
bellFg = "#ff6b6b";
|
||||||
|
activityFg = "#7aa2f7";
|
||||||
|
};
|
||||||
|
daylight = {
|
||||||
|
bg = "#f5f5f5";
|
||||||
|
fg = "#1a1a1a";
|
||||||
|
bgAlt = "#ebebeb";
|
||||||
|
fgAlt = "#999999";
|
||||||
|
border = "#e8e8e8";
|
||||||
|
accent = "#3b5bdb";
|
||||||
|
green = "#2d7f3e";
|
||||||
|
red = "#c7254e";
|
||||||
|
yellow = "#996800";
|
||||||
|
blue = "#3b5bdb";
|
||||||
|
magenta = "#ae3ec9";
|
||||||
|
cyan = "#1098ad";
|
||||||
|
bellFg = "#c7254e";
|
||||||
|
activityFg = "#3b5bdb";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options.theme = lib.mkOption {
|
||||||
|
type = lib.types.enum [ "midnight" "daylight" ];
|
||||||
|
default = "midnight";
|
||||||
|
};
|
||||||
|
|
||||||
|
options.colors = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf lib.types.str;
|
||||||
|
readOnly = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
config.colors = palettes.${config.theme};
|
||||||
|
}
|
||||||
504
home/modules/ui.nix
Normal file
504
home/modules/ui.nix
Normal file
|
|
@ -0,0 +1,504 @@
|
||||||
|
{ pkgs, lib, config, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
isNixOS = builtins.pathExists /etc/NIXOS;
|
||||||
|
c = config.colors;
|
||||||
|
|
||||||
|
nvidia = true;
|
||||||
|
backlightDevice = "intel_backlight";
|
||||||
|
in {
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
wl-clipboard
|
||||||
|
cliphist
|
||||||
|
grim
|
||||||
|
slurp
|
||||||
|
libnotify
|
||||||
|
brightnessctl
|
||||||
|
pamixer
|
||||||
|
xorg.xinit
|
||||||
|
xorg.xmodmap
|
||||||
|
xorg.xrdb
|
||||||
|
];
|
||||||
|
|
||||||
|
wayland.windowManager.hyprland = {
|
||||||
|
enable = true;
|
||||||
|
package = lib.mkIf (!isNixOS) null;
|
||||||
|
portalPackage = lib.mkIf (!isNixOS) null;
|
||||||
|
systemd.enable = isNixOS;
|
||||||
|
|
||||||
|
extraConfig = ''
|
||||||
|
exec-once = dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=Hyprland THEME
|
||||||
|
exec-once = systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=Hyprland THEME
|
||||||
|
|
||||||
|
monitor=,preferred,auto,1
|
||||||
|
|
||||||
|
env = XDG_CURRENT_DESKTOP,Hyprland
|
||||||
|
env = XDG_SESSION_TYPE,wayland
|
||||||
|
env = ELECTRON_OZONE_PLATFORM_HINT,wayland
|
||||||
|
env = GTK_USE_PORTAL,1
|
||||||
|
env = OZONE_PLATFORM,wayland
|
||||||
|
env = QT_QPA_PLATFORM,wayland
|
||||||
|
env = GDK_BACKEND,wayland,x11
|
||||||
|
env = SDL_VIDEODRIVER,wayland
|
||||||
|
'' + lib.optionalString nvidia ''
|
||||||
|
env = LIBVA_DRIVER_NAME,nvidia
|
||||||
|
env = __GLX_VENDOR_LIBRARY_NAME,nvidia
|
||||||
|
env = NVD_BACKEND,direct
|
||||||
|
env = GBM_BACKEND,nvidia-drm
|
||||||
|
env = GSK_RENDERER,ngl
|
||||||
|
env = __NV_PRIME_RENDER_OFFLOAD,1
|
||||||
|
env = __VK_LAYER_NV_optimus,NVIDIA_only
|
||||||
|
'' + ''
|
||||||
|
|
||||||
|
env = XCURSOR_SIZE,24
|
||||||
|
env = HYPRCURSOR_SIZE,24
|
||||||
|
'' + lib.optionalString nvidia ''
|
||||||
|
cursor {
|
||||||
|
no_hardware_cursors = true
|
||||||
|
}
|
||||||
|
'' + ''
|
||||||
|
|
||||||
|
general {
|
||||||
|
gaps_in = 0
|
||||||
|
gaps_out = 0
|
||||||
|
border_size = 5
|
||||||
|
col.active_border = rgb(${builtins.substring 1 6 c.fg})
|
||||||
|
col.inactive_border = rgb(${builtins.substring 1 6 c.bg})
|
||||||
|
layout = master
|
||||||
|
resize_on_border = true
|
||||||
|
}
|
||||||
|
|
||||||
|
master {
|
||||||
|
new_status = slave
|
||||||
|
new_on_top = false
|
||||||
|
mfact = 0.50
|
||||||
|
}
|
||||||
|
|
||||||
|
decoration {
|
||||||
|
rounding = 0
|
||||||
|
active_opacity = 1.0
|
||||||
|
inactive_opacity = 1.0
|
||||||
|
blur {
|
||||||
|
enabled = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
animations {
|
||||||
|
enabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
kb_layout = us,us
|
||||||
|
kb_variant = ,colemak
|
||||||
|
follow_mouse = 1
|
||||||
|
sensitivity = 0
|
||||||
|
touchpad {
|
||||||
|
tap-to-click = false
|
||||||
|
}
|
||||||
|
repeat_delay = 300
|
||||||
|
repeat_rate = 50
|
||||||
|
}
|
||||||
|
|
||||||
|
exec-once = dunst
|
||||||
|
exec-once = wl-paste --watch cliphist store
|
||||||
|
exec-once = hyprpaper
|
||||||
|
exec-once = hypridle
|
||||||
|
exec-once = hypr spawnfocus --ws 1 $TERMINAL -e mux
|
||||||
|
exec-once = hypr spawnfocus --ws 2 $BROWSER
|
||||||
|
|
||||||
|
bindul = , XF86AudioRaiseVolume, exec, hypr volume up
|
||||||
|
bindul = , XF86AudioLowerVolume, exec, hypr volume down
|
||||||
|
bindul = , XF86AudioMute, exec, hypr volume toggle
|
||||||
|
|
||||||
|
bindul = , XF86MonBrightnessUp, exec, hypr brightness up
|
||||||
|
bindul = , XF86MonBrightnessDown, exec, hypr brightness down
|
||||||
|
|
||||||
|
bindu = ALT, SPACE, exec, rofi -show run
|
||||||
|
bindu = ALT, TAB, workspace, previous
|
||||||
|
bindu = ALT, A, cyclenext
|
||||||
|
bindu = ALT, B, exec, pkill -USR1 waybar || waybar
|
||||||
|
bindu = ALT, D, layoutmsg, swapprev
|
||||||
|
bindu = ALT, F, cyclenext, prev
|
||||||
|
bindu = ALT, H, resizeactive, -15 0
|
||||||
|
bindu = ALT, J, resizeactive, 0 15
|
||||||
|
bindu = ALT, K, resizeactive, 0 -15
|
||||||
|
bindu = ALT, L, resizeactive, 15 0
|
||||||
|
bindu = ALT, Q, killactive,
|
||||||
|
bindu = ALT, U, layoutmsg, swapnext
|
||||||
|
|
||||||
|
bindu = ALT CTRL, B, exec, hypr pull bitwarden-desktop
|
||||||
|
bindu = ALT CTRL, C, exec, hypr pull $BROWSER
|
||||||
|
bindu = ALT CTRL, D, exec, hypr pull discord
|
||||||
|
bindu = ALT CTRL, S, exec, hypr pull signal-desktop
|
||||||
|
bindu = ALT CTRL, T, exec, hypr pull Telegram
|
||||||
|
bindu = ALT CTRL, V, exec, hypr pull vesktop
|
||||||
|
bindu = ALT CTRL, Y, exec, hypr pull sioyek
|
||||||
|
|
||||||
|
bindu = ALT SHIFT, RETURN, exec, hypr spawnfocus --ws 1 $TERMINAL
|
||||||
|
bindu = ALT SHIFT, B, exec, hypr spawnfocus --ws 9 bitwarden-desktop
|
||||||
|
bindu = ALT SHIFT, C, exec, hypr spawnfocus --ws 2 $BROWSER --ozone-platform=wayland
|
||||||
|
bindu = ALT SHIFT, D, exec, hypr spawnfocus --ws 5 discord
|
||||||
|
bindu = ALT SHIFT, F, togglefloating
|
||||||
|
bindu = ALT SHIFT, G, exec, hypr pull $TERMINAL
|
||||||
|
bindu = ALT SHIFT, Q, exec, hypr exit
|
||||||
|
bindu = ALT SHIFT, R, exec, hyprctl reload && notify-send -u low 'hyprland reloaded'
|
||||||
|
bindu = ALT SHIFT, S, exec, hypr spawnfocus --ws 6 signal-desktop
|
||||||
|
bindu = ALT SHIFT, T, exec, hypr spawnfocus --ws 6 Telegram
|
||||||
|
bindu = ALT SHIFT, V, exec, hypr spawnfocus --ws 5 vesktop
|
||||||
|
bindu = ALT SHIFT, Y, exec, hypr spawnfocus --ws 3 sioyek
|
||||||
|
|
||||||
|
bind = , XF86Tools, submap, scripts
|
||||||
|
submap = scripts
|
||||||
|
|
||||||
|
bind = , A, exec, ctl audio out
|
||||||
|
bind = , C, exec, bash -lc 'cliphist list | rofi -dmenu -p "copy to clipboard" --lines 15 | cliphist decode | wl-copy'
|
||||||
|
bind = , F, exec, [float; fullscreen] ghostty -e lf
|
||||||
|
bind = , K, exec, ctl keyboard toggle
|
||||||
|
bind = , O, exec, ctl ocr
|
||||||
|
bind = , P, exec, hypr pull
|
||||||
|
bind = , S, exec, ctl screenshot
|
||||||
|
bind = , T, exec, theme
|
||||||
|
|
||||||
|
bind = , catchall, submap, reset
|
||||||
|
submap = reset
|
||||||
|
|
||||||
|
misc {
|
||||||
|
force_default_wallpaper = 0
|
||||||
|
disable_hyprland_logo = true
|
||||||
|
}
|
||||||
|
|
||||||
|
bindu = ALT, 1, workspace, 1
|
||||||
|
bindu = ALT, 2, workspace, 2
|
||||||
|
bindu = ALT, 3, workspace, 3
|
||||||
|
bindu = ALT, 4, workspace, 4
|
||||||
|
bindu = ALT, 5, workspace, 5
|
||||||
|
bindu = ALT, 6, workspace, 6
|
||||||
|
bindu = ALT, 7, workspace, 7
|
||||||
|
bindu = ALT, 8, workspace, 8
|
||||||
|
bindu = ALT, 9, workspace, 9
|
||||||
|
|
||||||
|
bindu = ALT SHIFT, 1, movetoworkspace, 1
|
||||||
|
bindu = ALT SHIFT, 2, movetoworkspace, 2
|
||||||
|
bindu = ALT SHIFT, 3, movetoworkspace, 3
|
||||||
|
bindu = ALT SHIFT, 4, movetoworkspace, 4
|
||||||
|
bindu = ALT SHIFT, 5, movetoworkspace, 5
|
||||||
|
bindu = ALT SHIFT, 6, movetoworkspace, 6
|
||||||
|
bindu = ALT SHIFT, 7, movetoworkspace, 7
|
||||||
|
bindu = ALT SHIFT, 8, movetoworkspace, 8
|
||||||
|
bindu = ALT SHIFT, 9, movetoworkspace, 9
|
||||||
|
|
||||||
|
bindu = ALT CTRL, 1, movetoworkspacesilent, 1
|
||||||
|
bindu = ALT CTRL, 2, movetoworkspacesilent, 2
|
||||||
|
bindu = ALT CTRL, 3, movetoworkspacesilent, 3
|
||||||
|
bindu = ALT CTRL, 4, movetoworkspacesilent, 4
|
||||||
|
bindu = ALT CTRL, 5, movetoworkspacesilent, 5
|
||||||
|
bindu = ALT CTRL, 6, movetoworkspacesilent, 6
|
||||||
|
bindu = ALT CTRL, 7, movetoworkspacesilent, 7
|
||||||
|
bindu = ALT CTRL, 8, movetoworkspacesilent, 8
|
||||||
|
bindu = ALT CTRL, 9, movetoworkspacesilent, 9
|
||||||
|
|
||||||
|
workspace = w[tv1], gapsout:0, gapsin:0
|
||||||
|
workspace = f[1], gapsout:0, gapsin:0
|
||||||
|
windowrule = match:float 0, match:workspace w[tv1], border_size 0
|
||||||
|
windowrule = match:float 0, match:workspace w[tv1], rounding 0
|
||||||
|
windowrule = match:float 0, match:workspace f[1], border_size 0
|
||||||
|
windowrule = match:float 0, match:workspace f[1], rounding 0
|
||||||
|
|
||||||
|
windowrule = match:class ^(xdg-desktop-portal-gtk)$, float on
|
||||||
|
windowrule = match:class ^(xdg-desktop-portal-gtk)$, size monitor_w * 0.5 monitor_h * 0.6
|
||||||
|
windowrule = match:class ^(xdg-desktop-portal-kde)$, float on
|
||||||
|
windowrule = match:class ^(xdg-desktop-portal-kde)$, size monitor_w * 0.5 monitor_h * 0.6
|
||||||
|
windowrule = match:class ^(xdg-desktop-portal-hyprland)$, float on
|
||||||
|
windowrule = match:class ^(xdg-desktop-portal-hyprland)$, size monitor_w * 0.5 monitor_h * 0.6
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
services.hypridle = {
|
||||||
|
enable = true;
|
||||||
|
package = lib.mkIf (!isNixOS) null;
|
||||||
|
settings = {
|
||||||
|
general = {
|
||||||
|
lock_cmd = "wp lock && hyprlock";
|
||||||
|
after_sleep_cmd = "hyprctl dispatch dpms on";
|
||||||
|
};
|
||||||
|
listener = [
|
||||||
|
{
|
||||||
|
timeout = 300;
|
||||||
|
on-timeout = "wp lock && hyprlock";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
timeout = 600;
|
||||||
|
on-timeout = "hyprctl dispatch dpms off";
|
||||||
|
on-resume = "hyprctl dispatch dpms on";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
timeout = 1800;
|
||||||
|
on-timeout = "systemctl suspend";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.hyprlock = {
|
||||||
|
enable = true;
|
||||||
|
package = lib.mkIf (!isNixOS) null;
|
||||||
|
settings = {
|
||||||
|
general = {
|
||||||
|
hide_cursor = true;
|
||||||
|
grace = 0;
|
||||||
|
};
|
||||||
|
background = [{
|
||||||
|
monitor = "";
|
||||||
|
path = "~/img/screen/lock.jpg";
|
||||||
|
}];
|
||||||
|
animations.enabled = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.hyprpaper = {
|
||||||
|
enable = true;
|
||||||
|
package = lib.mkIf (!isNixOS) null;
|
||||||
|
settings = {
|
||||||
|
wallpaper = [ ",~/img/screen/wallpaper.jpg" ];
|
||||||
|
splash = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.waybar = {
|
||||||
|
enable = true;
|
||||||
|
settings.mainBar = {
|
||||||
|
reload_style_on_change = true;
|
||||||
|
layer = "top";
|
||||||
|
position = "top";
|
||||||
|
exclusive = true;
|
||||||
|
height = 34;
|
||||||
|
|
||||||
|
modules-left = [ "hyprland/workspaces" "hyprland/window" ];
|
||||||
|
modules-center = [];
|
||||||
|
modules-right = [ "backlight" "pulseaudio" "network" "battery" "clock" ];
|
||||||
|
|
||||||
|
"hyprland/workspaces" = {
|
||||||
|
disable-scroll = true;
|
||||||
|
all-outputs = true;
|
||||||
|
format = "{icon}";
|
||||||
|
format-icons = {
|
||||||
|
"1" = "i";
|
||||||
|
"2" = "ii";
|
||||||
|
"3" = "iii";
|
||||||
|
"4" = "iv";
|
||||||
|
"5" = "v";
|
||||||
|
"6" = "vi";
|
||||||
|
"7" = "vii";
|
||||||
|
"8" = "viii";
|
||||||
|
"9" = "ix";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
"hyprland/window" = {
|
||||||
|
format = " {} [{}]";
|
||||||
|
separate-outputs = true;
|
||||||
|
max-length = 80;
|
||||||
|
rewrite = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
pulseaudio = {
|
||||||
|
format = "volume:{volume}% │ ";
|
||||||
|
format-muted = "volume:{volume}% (muted) │ ";
|
||||||
|
interval = 2;
|
||||||
|
signal = 1;
|
||||||
|
tooltip-format = "Audio Output: {desc}";
|
||||||
|
};
|
||||||
|
|
||||||
|
network = {
|
||||||
|
format-wifi = "wifi:{essid} │ ";
|
||||||
|
format-ethernet = "eth:{interface} │ ";
|
||||||
|
format-disconnected = "wifi:off │ ";
|
||||||
|
format-disabled = "network:disabled";
|
||||||
|
interval = 10;
|
||||||
|
signal = 1;
|
||||||
|
tooltip-format-wifi = "Signal: {signalStrength}%\nIP: {ipaddr}/{cidr}";
|
||||||
|
tooltip-format-ethernet = "IP: {ipaddr}/{cidr}\nGateway: {gwaddr}";
|
||||||
|
tooltip-format-disconnected = "Network: disconnected";
|
||||||
|
};
|
||||||
|
|
||||||
|
backlight = {
|
||||||
|
device = backlightDevice;
|
||||||
|
format = "brightness:{percent}% │ ";
|
||||||
|
signal = 1;
|
||||||
|
tooltip = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
battery = {
|
||||||
|
format = "battery:-{capacity}% │ ";
|
||||||
|
format-charging = "battery:+{capacity}% │ ";
|
||||||
|
format-full = "battery:{capacity}% │ ";
|
||||||
|
states = {
|
||||||
|
hi = 30;
|
||||||
|
mid = 20;
|
||||||
|
lo = 10;
|
||||||
|
ultralo = 5;
|
||||||
|
};
|
||||||
|
events = {
|
||||||
|
on-discharging-hi = "notify-send -u low 'battery 30%'";
|
||||||
|
on-discharging-mid = "notify-send -u normal 'battery 20%'";
|
||||||
|
on-discharging-lo = "notify-send -u critical 'battery 10%'";
|
||||||
|
on-discharging-ultralo = "notify-send -u critical 'battery 5%'";
|
||||||
|
on-charging-100 = "notify-send -u low 'battery 100%'";
|
||||||
|
};
|
||||||
|
interval = 30;
|
||||||
|
signal = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
clock = {
|
||||||
|
format = "{:%H:%M:%S %d/%m/%Y} ";
|
||||||
|
interval = 1;
|
||||||
|
tooltip-format = "{:%A, %d %B %Y\nTimezone: %Z}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
style = ''
|
||||||
|
* {
|
||||||
|
font-family: "Berkeley Mono", monospace;
|
||||||
|
font-size: 15px;
|
||||||
|
color: ${c.fg};
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#waybar {
|
||||||
|
background: ${c.bg};
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces button {
|
||||||
|
padding: 0 10px;
|
||||||
|
color: ${c.fg};
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces button.focused,
|
||||||
|
#workspaces button.active {
|
||||||
|
background: ${c.bgAlt};
|
||||||
|
color: ${c.fg};
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltip {
|
||||||
|
color: ${c.fg};
|
||||||
|
background-color: ${c.bgAlt};
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltip * {
|
||||||
|
color: ${c.fg};
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.rofi = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.rofi;
|
||||||
|
font = "Berkeley Mono 15";
|
||||||
|
extraConfig = {
|
||||||
|
show-icons = false;
|
||||||
|
};
|
||||||
|
theme = let
|
||||||
|
inherit (config.lib.formats.rasi) mkLiteral;
|
||||||
|
in {
|
||||||
|
"*" = {
|
||||||
|
selected-normal-foreground = mkLiteral "${c.fg}";
|
||||||
|
foreground = mkLiteral "${c.fg}";
|
||||||
|
normal-foreground = mkLiteral "@foreground";
|
||||||
|
alternate-normal-background = mkLiteral "${c.bg}";
|
||||||
|
background = mkLiteral "${c.bgAlt}";
|
||||||
|
alternate-normal-foreground = mkLiteral "@foreground";
|
||||||
|
normal-background = mkLiteral "@background";
|
||||||
|
selected-normal-background = mkLiteral "${c.accent}";
|
||||||
|
border-color = mkLiteral "${c.fgAlt}";
|
||||||
|
spacing = 2;
|
||||||
|
separatorcolor = mkLiteral "@foreground";
|
||||||
|
background-color = mkLiteral "rgba ( 0, 0, 0, 0 % )";
|
||||||
|
};
|
||||||
|
window = {
|
||||||
|
background-color = mkLiteral "@background";
|
||||||
|
border = 1;
|
||||||
|
padding = 5;
|
||||||
|
};
|
||||||
|
mainbox = {
|
||||||
|
border = 0;
|
||||||
|
padding = 0;
|
||||||
|
};
|
||||||
|
listview = {
|
||||||
|
fixed-height = 0;
|
||||||
|
border = mkLiteral "2px 0px 0px";
|
||||||
|
border-color = mkLiteral "@separatorcolor";
|
||||||
|
spacing = mkLiteral "2px";
|
||||||
|
scrollbar = false;
|
||||||
|
padding = mkLiteral "2px 0px 0px";
|
||||||
|
};
|
||||||
|
element = {
|
||||||
|
border = 0;
|
||||||
|
padding = mkLiteral "1px";
|
||||||
|
};
|
||||||
|
element-text = {
|
||||||
|
background-color = mkLiteral "inherit";
|
||||||
|
text-color = mkLiteral "inherit";
|
||||||
|
};
|
||||||
|
"element.normal.normal" = {
|
||||||
|
background-color = mkLiteral "@normal-background";
|
||||||
|
text-color = mkLiteral "@normal-foreground";
|
||||||
|
};
|
||||||
|
"element.selected.normal" = {
|
||||||
|
background-color = mkLiteral "@selected-normal-background";
|
||||||
|
text-color = mkLiteral "@selected-normal-foreground";
|
||||||
|
};
|
||||||
|
"element.alternate.normal" = {
|
||||||
|
background-color = mkLiteral "@alternate-normal-background";
|
||||||
|
text-color = mkLiteral "@alternate-normal-foreground";
|
||||||
|
};
|
||||||
|
inputbar = {
|
||||||
|
spacing = 0;
|
||||||
|
text-color = mkLiteral "@normal-foreground";
|
||||||
|
padding = mkLiteral "1px";
|
||||||
|
children = map mkLiteral [ "prompt" "textbox-prompt-colon" "entry" "case-indicator" ];
|
||||||
|
};
|
||||||
|
textbox-prompt-colon = {
|
||||||
|
expand = false;
|
||||||
|
str = ":";
|
||||||
|
margin = mkLiteral "0px 0.3em 0em 0em";
|
||||||
|
text-color = mkLiteral "@normal-foreground";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.dunst = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
global = {
|
||||||
|
font = "Berkeley Mono 15";
|
||||||
|
frame_color = c.fgAlt;
|
||||||
|
separator_color = "frame";
|
||||||
|
background = c.bg;
|
||||||
|
foreground = c.fg;
|
||||||
|
};
|
||||||
|
urgency_low = {
|
||||||
|
background = c.bg;
|
||||||
|
foreground = c.fg;
|
||||||
|
};
|
||||||
|
urgency_normal = {
|
||||||
|
background = c.bg;
|
||||||
|
foreground = c.fg;
|
||||||
|
};
|
||||||
|
urgency_critical = {
|
||||||
|
background = c.bg;
|
||||||
|
foreground = c.red;
|
||||||
|
frame_color = c.red;
|
||||||
|
};
|
||||||
|
experimental = {
|
||||||
|
per_monitor_dpi = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
xdg.configFile."X11".source = config.lib.file.mkOutOfStoreSymlink "${config.home.homeDirectory}/nix-config/config/X11";
|
||||||
|
}
|
||||||
104
hosts/xps15/configuration.nix
Normal file
104
hosts/xps15/configuration.nix
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./hardware-configuration.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.loader.grub = {
|
||||||
|
enable = true;
|
||||||
|
device = "nodev";
|
||||||
|
efiSupport = true;
|
||||||
|
useOSProber = true;
|
||||||
|
gfxmodeEfi = "1920x1080x32";
|
||||||
|
gfxpayloadEfi = "keep";
|
||||||
|
};
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
boot.loader.efi.efiSysMountPoint = "/boot/efi";
|
||||||
|
boot.kernelParams = [ "nvidia-drm.modeset=1" "ibt=off" "loglevel=3" "quiet" ];
|
||||||
|
|
||||||
|
networking.hostName = "xps15";
|
||||||
|
networking.wireless.iwd = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
General.EnableNetworkConfiguration = true;
|
||||||
|
Settings.AutoConnect = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.automatic-timezoned.enable = true;
|
||||||
|
i18n.defaultLocale = "en_US.UTF-8";
|
||||||
|
|
||||||
|
security.pam.services.hyprlock = {};
|
||||||
|
|
||||||
|
users.users.barrett = {
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = [ "wheel" "docker" "libvirt" "storage" "power" ];
|
||||||
|
shell = pkgs.zsh;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.zsh.enable = true;
|
||||||
|
programs.hyprland.enable = true;
|
||||||
|
|
||||||
|
hardware.nvidia = {
|
||||||
|
open = true;
|
||||||
|
modesetting.enable = true;
|
||||||
|
prime = {
|
||||||
|
offload.enable = true;
|
||||||
|
intelBusId = "PCI:0:2:0";
|
||||||
|
nvidiaBusId = "PCI:1:0:0";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
hardware.graphics.enable = true;
|
||||||
|
hardware.bluetooth.enable = true;
|
||||||
|
|
||||||
|
services.keyd = {
|
||||||
|
enable = true;
|
||||||
|
keyboards.default = {
|
||||||
|
ids = [ "*" ];
|
||||||
|
settings = {
|
||||||
|
main = {
|
||||||
|
capslock = "overload(control, esc)";
|
||||||
|
leftcontrol = "capslock";
|
||||||
|
leftmeta = "A-x";
|
||||||
|
rightalt = "f13";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.pipewire = {
|
||||||
|
enable = true;
|
||||||
|
alsa.enable = true;
|
||||||
|
jack.enable = true;
|
||||||
|
pulse.enable = true;
|
||||||
|
wireplumber.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.openssh.enable = true;
|
||||||
|
|
||||||
|
virtualisation.docker.enable = true;
|
||||||
|
virtualisation.libvirtd.enable = true;
|
||||||
|
programs.virt-manager.enable = true;
|
||||||
|
|
||||||
|
xdg.portal = {
|
||||||
|
enable = true;
|
||||||
|
extraPortals = with pkgs; [
|
||||||
|
xdg-desktop-portal-gtk
|
||||||
|
xdg-desktop-portal-hyprland
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
vim
|
||||||
|
wget
|
||||||
|
git
|
||||||
|
ntfs3g
|
||||||
|
efibootmgr
|
||||||
|
dmidecode
|
||||||
|
];
|
||||||
|
|
||||||
|
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||||
|
|
||||||
|
system.stateVersion = "24.11";
|
||||||
|
}
|
||||||
94
scripts/ctl
Executable file
94
scripts/ctl
Executable file
|
|
@ -0,0 +1,94 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
screenshot)
|
||||||
|
dir="$HOME/img/ss"
|
||||||
|
mkdir -p "$dir"
|
||||||
|
file="$dir/$(openssl rand -hex 10)-$(date +'%Y-%m-%d_%H-%M-%S').png"
|
||||||
|
if [ "${XDG_SESSION_TYPE:-}" = "wayland" ]; then
|
||||||
|
grim -g "$(slurp)" "$file" && wl-copy < "$file"
|
||||||
|
else
|
||||||
|
maim -s "$file" && xclip -selection clipboard -t image/png -i "$file" &
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
ocr)
|
||||||
|
dir="$HOME/img/ss"
|
||||||
|
mkdir -p "$dir"
|
||||||
|
file="$dir/$(openssl rand -hex 10)-$(date +'%Y-%m-%d_%H-%M-%S').png"
|
||||||
|
if [ "${XDG_SESSION_TYPE:-}" = "wayland" ]; then
|
||||||
|
(
|
||||||
|
region="$(slurp)"
|
||||||
|
[ -n "$region" ] || exit 0
|
||||||
|
grim -g "$region" "$file" &&
|
||||||
|
tesseract -l eng "$file" - 2>/dev/null | wl-copy
|
||||||
|
) </dev/null >/dev/null 2>&1 &
|
||||||
|
else
|
||||||
|
(
|
||||||
|
maim -s "$file" &&
|
||||||
|
tesseract -l eng "$file" - 2>/dev/null | xclip -selection clipboard -in
|
||||||
|
) </dev/null >/dev/null 2>&1 &
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
keyboard)
|
||||||
|
case "$2" in
|
||||||
|
toggle)
|
||||||
|
if [ "${XDG_SESSION_TYPE:-}" = "wayland" ]; then
|
||||||
|
if [ "$XDG_CURRENT_DESKTOP" = "Hyprland" ]; then
|
||||||
|
hyprctl switchxkblayout current next
|
||||||
|
elif [ "$XDG_CURRENT_DESKTOP" = "sway" ]; then
|
||||||
|
if swaymsg -t get_inputs | grep -qi "Colemak"; then
|
||||||
|
swaymsg input type:keyboard xkb_variant "''"
|
||||||
|
else
|
||||||
|
swaymsg input type:keyboard xkb_variant colemak
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
current="$(setxkbmap -query | awk '/variant/{print $2}')"
|
||||||
|
if [ "$current" = "colemak" ]; then
|
||||||
|
setxkbmap -layout us
|
||||||
|
else
|
||||||
|
setxkbmap -layout us -variant colemak
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: ctl keyboard {toggle}" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
audio)
|
||||||
|
case "$2" in
|
||||||
|
out)
|
||||||
|
sinks="$(pactl list short sinks | awk '{print $1": "$2}')"
|
||||||
|
[ -z "$sinks" ] && exit 0
|
||||||
|
count="$(printf "%s\n" "$sinks" | wc -l)"
|
||||||
|
if [ "$XDG_SESSION_TYPE" = x11 ]; then
|
||||||
|
choice="$(printf "%s\n" "$sinks" | dmenu -i -l "$count" -p "select sink:" | cut -d: -f1)"
|
||||||
|
else
|
||||||
|
choice="$(printf "%s\n" "$sinks" | rofi -dmenu -i -lines "$count" -p "select sink" | cut -d: -f1)"
|
||||||
|
fi
|
||||||
|
[ "$choice" ] && pactl set-default-sink "$choice"
|
||||||
|
;;
|
||||||
|
in)
|
||||||
|
sources="$(pactl list short sources | awk '{print $1": "$2}')"
|
||||||
|
[ -z "$sources" ] && exit 0
|
||||||
|
count="$(printf "%s\n" "$sources" | wc -l)"
|
||||||
|
if [ "$XDG_SESSION_TYPE" = x11 ]; then
|
||||||
|
choice="$(printf "%s\n" "$sources" | dmenu -i -l "$count" -p "select source:" | cut -d: -f1)"
|
||||||
|
else
|
||||||
|
choice="$(printf "%s\n" "$sources" | rofi -dmenu -i -lines "$count" -p "select source" | cut -d: -f1)"
|
||||||
|
fi
|
||||||
|
[ "$choice" ] && pactl set-default-source "$choice"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: ctl audio {in|out}" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: ctl {screenshot|ocr|keyboard|audio}" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
23
scripts/doc
Executable file
23
scripts/doc
Executable file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
dir="$HOME/doc"
|
||||||
|
test -d "$dir" || exit
|
||||||
|
|
||||||
|
if [ "$XDG_SESSION_TYPE" = x11 ]; then
|
||||||
|
picker() { dmenu -i -l 10 -p "Select file or folder: "; }
|
||||||
|
else
|
||||||
|
picker() { rofi -dmenu -i -l 10 -p "Select file or folder"; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
while :; do
|
||||||
|
choice="$(find "$dir" -not -path "$dir/.*" -mindepth 1 -maxdepth 1 \( -type d -printf "%f/\n" -o -type f -printf "%f\n" \) | picker)"
|
||||||
|
|
||||||
|
[ -n "$choice" ] || break
|
||||||
|
|
||||||
|
if [ -d "$dir/${choice%/}" ]; then
|
||||||
|
dir="$dir/${choice%/}"
|
||||||
|
elif [ -f "$dir/$choice" ]; then
|
||||||
|
sioyek "$dir/$choice" &
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
283
scripts/hypr
Executable file
283
scripts/hypr
Executable file
|
|
@ -0,0 +1,283 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: hypr <subcommand> [app] [args...]
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
volume {up,down,toggle} Adjust volume accordingly and notify
|
||||||
|
brightness {up,down} Adjust brightness accordingly and notify
|
||||||
|
spawnfocus <app> [args...] Focus existing window or spawn app with args
|
||||||
|
pull [app] Pull window to current workspace (picker if no app)
|
||||||
|
borders Initialize dynamic borders
|
||||||
|
exit Safely exit hyprland
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h, --help Show this help message
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -z "$1" ] && {
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
case "$cmd" in
|
||||||
|
-h | --help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
exit)
|
||||||
|
pkill hypridle
|
||||||
|
pkill hyprpaper
|
||||||
|
hyprctl dispatch exit
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
brightness)
|
||||||
|
BRIGHT_STEP=5
|
||||||
|
max_brightness="$(brightnessctl max)"
|
||||||
|
case "$1" in
|
||||||
|
up)
|
||||||
|
brightnessctl set "$BRIGHT_STEP"%+
|
||||||
|
notify-send -u low -t 2500 -r 5555 "brightness $(brightnessctl get | awk -v max="$max_brightness" '{printf "%d%%", $1*100/max}')"
|
||||||
|
;;
|
||||||
|
down)
|
||||||
|
brightnessctl set "$BRIGHT_STEP"%-
|
||||||
|
notify-send -u low -t 2500 -r 5555 "brightness $(brightnessctl get | awk -v max="$max_brightness" '{printf "%d%%", $1*100/max}')"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid subcommand: $1" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
volume)
|
||||||
|
SINK="@DEFAULT_SINK@"
|
||||||
|
VOL_STEP=5
|
||||||
|
get_vol() { pactl get-sink-volume "$SINK" | awk 'NR==1{print $5+0}'; }
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
up)
|
||||||
|
vol=$(get_vol)
|
||||||
|
[ "$vol" -lt 100 ] && vol=$((vol + VOL_STEP))
|
||||||
|
[ "$vol" -gt 100 ] && vol=100
|
||||||
|
pactl set-sink-volume "$SINK" "${vol}%"
|
||||||
|
;;
|
||||||
|
down)
|
||||||
|
vol=$(get_vol)
|
||||||
|
vol=$((vol - VOL_STEP))
|
||||||
|
[ "$vol" -lt 0 ] && vol=0
|
||||||
|
pactl set-sink-volume "$SINK" "${vol}%"
|
||||||
|
;;
|
||||||
|
toggle)
|
||||||
|
pactl set-sink-mute "$SINK" toggle
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid subcommand: $1" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
muted=$(pactl get-sink-mute "$SINK" | awk '{print $2}')
|
||||||
|
vol=$(get_vol)
|
||||||
|
[ "$vol" -gt 100 ] && vol=100
|
||||||
|
|
||||||
|
if [ "$muted" = "yes" ]; then
|
||||||
|
notify-send -u low -t 2500 -r 5556 "volume: ${vol}% (muted)"
|
||||||
|
else
|
||||||
|
notify-send -u low -t 2500 -r 5556 "volume: ${vol}%"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
pull)
|
||||||
|
APP="$1"
|
||||||
|
if [ -n "$APP" ]; then
|
||||||
|
case "$APP" in
|
||||||
|
google-chrome | google-chrome-stable) CLASS="google-chrome" ;;
|
||||||
|
chromium | ungoogled-chromium) CLASS="Chromium" ;;
|
||||||
|
firefox) CLASS="firefox" ;;
|
||||||
|
alacritty) CLASS="Alacritty" ;;
|
||||||
|
code | vscodium) CLASS="Code" ;;
|
||||||
|
signal-desktop | signal) CLASS="signal" ;;
|
||||||
|
telegram-desktop | telegram) CLASS="TelegramDesktop" ;;
|
||||||
|
ghostty) CLASS="com.mitchellh.ghostty" ;;
|
||||||
|
bitwarden-desktop | bitwarden) CLASS="Bitwarden" ;;
|
||||||
|
slack) CLASS="Slack" ;;
|
||||||
|
discord) CLASS="discord" ;;
|
||||||
|
vesktop) CLASS="vesktop" ;;
|
||||||
|
*) CLASS="$APP" ;;
|
||||||
|
esac
|
||||||
|
CUR_ADDR=$(hyprctl -j activewindow | jq -r '.address')
|
||||||
|
WIN_ADDRS=$(
|
||||||
|
hyprctl -j clients 2>/dev/null | jq -r --arg class "$CLASS" '
|
||||||
|
.[]? | select(
|
||||||
|
((.xdgTag // "") | ascii_downcase | contains($class | ascii_downcase)) or
|
||||||
|
((.initialClass // "") | ascii_downcase | contains($class | ascii_downcase)) or
|
||||||
|
((.class // "") | ascii_downcase | contains($class | ascii_downcase))
|
||||||
|
) | "\(.class)\t\(.title)\t\(.address)"'
|
||||||
|
)
|
||||||
|
WIN_COUNT=$(echo "$WIN_ADDRS" | grep -c .)
|
||||||
|
if [ "$WIN_COUNT" -eq 1 ]; then
|
||||||
|
WIN_ADDR=$(echo "$WIN_ADDRS" | awk -F'\t' '{print $3}')
|
||||||
|
elif [ "$WIN_COUNT" -gt 1 ]; then
|
||||||
|
SELECTED=$(echo "$WIN_ADDRS" |
|
||||||
|
awk -F'\t' -v cur="$CUR_ADDR" '{if($3!=cur) print $1 ": " $2 "\t" $3}' |
|
||||||
|
rofi -dmenu -i -p "pull window")
|
||||||
|
WIN_ADDR=$(echo "$SELECTED" | awk -F'\t' '{print $2}')
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ -z "$SELECTED" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
if [ -z "$WIN_ADDR" ]; then
|
||||||
|
CUR_ADDR=$(hyprctl -j activewindow | jq -r '.address')
|
||||||
|
WIN_ADDRS=$(hyprctl -j clients 2>/dev/null | jq -r '.[]? | "\(.class)\t\(.title)\t\(.address)"')
|
||||||
|
SELECTED=$(echo "$WIN_ADDRS" |
|
||||||
|
awk -F'\t' -v cur="$CUR_ADDR" '{if($3!=cur) print $1 ": " $2 "\t" $3}' |
|
||||||
|
rofi -dmenu -i -p "pull window")
|
||||||
|
WIN_ADDR=$(echo "$SELECTED" | awk -F'\t' '{print $2}')
|
||||||
|
fi
|
||||||
|
if [ -n "$WIN_ADDR" ]; then
|
||||||
|
CURRENT_WS="$(hyprctl activeworkspace | head -n1 | awk -F'[()]' '{print $2}')"
|
||||||
|
hyprctl dispatch movetoworkspace "$CURRENT_WS,address:$WIN_ADDR"
|
||||||
|
hyprctl dispatch focuswindow "address:$WIN_ADDR"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
spawnfocus)
|
||||||
|
WS=""
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--ws)
|
||||||
|
if [ $# -lt 2 ]; then
|
||||||
|
echo "Missing workspace number after --ws"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
WS="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
echo "Unknown option $1"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
APP="$1"
|
||||||
|
[ -z "$APP" ] && {
|
||||||
|
echo 'Specify an app'
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
shift
|
||||||
|
|
||||||
|
case "$APP" in
|
||||||
|
google-chrome | google-chrome-stable) CLASS="google-chrome" ;;
|
||||||
|
chromium | ungoogled-chromium) CLASS="Chromium" ;;
|
||||||
|
firefox) CLASS="firefox" ;;
|
||||||
|
alacritty) CLASS="Alacritty" ;;
|
||||||
|
code | vscodium) CLASS="Code" ;;
|
||||||
|
signal-desktop | signal) CLASS="signal" ;;
|
||||||
|
telegram-desktop | telegram) CLASS="TelegramDesktop" ;;
|
||||||
|
ghostty) CLASS="com.mitchellh.ghostty" ;;
|
||||||
|
bitwarden-desktop | bitwarden) CLASS="Bitwarden" ;;
|
||||||
|
slack) CLASS="Slack" ;;
|
||||||
|
discord) CLASS="discord" ;;
|
||||||
|
vesktop) CLASS="vesktop" ;;
|
||||||
|
*) CLASS="$APP" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
WIN_ADDRS=$(hyprctl -j clients 2>/dev/null | jq -r --arg class "$CLASS" '
|
||||||
|
.[]? | select(
|
||||||
|
((.xdgTag // "") | ascii_downcase | contains($class | ascii_downcase)) or
|
||||||
|
((.initialClass // "") | ascii_downcase | contains($class | ascii_downcase)) or
|
||||||
|
((.class // "") | ascii_downcase | contains($class | ascii_downcase))
|
||||||
|
) | "\(.class)\t\(.title)\t\(.address)"
|
||||||
|
')
|
||||||
|
|
||||||
|
WIN_COUNT=$(echo "$WIN_ADDRS" | grep -c .)
|
||||||
|
|
||||||
|
if [ "$WIN_COUNT" -eq 0 ]; then
|
||||||
|
WIN_ADDR=""
|
||||||
|
elif [ "$WIN_COUNT" -eq 1 ]; then
|
||||||
|
WIN_ADDR=$(echo "$WIN_ADDRS" | awk -F'\t' '{print $3}')
|
||||||
|
elif [ "$WIN_COUNT" -gt 1 ]; then
|
||||||
|
SELECTED=$(echo "$WIN_ADDRS" | awk -F'\t' '{print $1 ": " $2 "\t" $3}' | rofi -dmenu -i -p "select window")
|
||||||
|
|
||||||
|
if [ -z "$SELECTED" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
WIN_ADDR=$(echo "$SELECTED" | awk -F'\t' '{print $2}')
|
||||||
|
fi
|
||||||
|
if [ -n "$WIN_ADDR" ]; then
|
||||||
|
if [ -n "$WS" ]; then
|
||||||
|
WIN_WS=$(hyprctl clients -j | jq -r --arg addr "$WIN_ADDR" '.[] | select(.address == $addr) | .workspace.id')
|
||||||
|
|
||||||
|
if [ "$WIN_WS" != "$WS" ]; then
|
||||||
|
hyprctl dispatch movetoworkspacesilent "$WS,address:$WIN_ADDR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
hyprctl dispatch workspace "$WS"
|
||||||
|
else
|
||||||
|
WIN_WS=$(hyprctl clients -j | jq -r --arg addr "$WIN_ADDR" '.[] | select(.address == $addr) | .workspace.id')
|
||||||
|
|
||||||
|
hyprctl dispatch workspace "$WIN_WS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
hyprctl dispatch focuswindow "address:$WIN_ADDR"
|
||||||
|
else
|
||||||
|
EXISTING_HEX=$(hyprctl -j clients 2>/dev/null | jq -r --arg class "$CLASS" '
|
||||||
|
.[]? | select(
|
||||||
|
((.xdgTag // "") | ascii_downcase | contains($class | ascii_downcase)) or
|
||||||
|
((.initialClass // "") | ascii_downcase | contains($class | ascii_downcase)) or
|
||||||
|
((.class // "") | ascii_downcase | contains($class | ascii_downcase))
|
||||||
|
) | .address | ltrimstr("0x")
|
||||||
|
' | tr '\n' ' ')
|
||||||
|
|
||||||
|
if [ -n "$WS" ]; then
|
||||||
|
hyprctl dispatch workspace "$WS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
"$APP" &
|
||||||
|
else
|
||||||
|
"$APP" "$@" &
|
||||||
|
fi
|
||||||
|
|
||||||
|
socat -u UNIX-CONNECT:"$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock" - | while read -r line; do
|
||||||
|
case "$line" in
|
||||||
|
openwindow*)
|
||||||
|
window_id=$(echo "$line" | cut -d'>' -f3 | cut -d',' -f1)
|
||||||
|
event_class=$(echo "$line" | cut -d'>' -f3 | cut -d',' -f3)
|
||||||
|
class_lower=$(echo "$event_class" | tr '[:upper:]' '[:lower:]')
|
||||||
|
target_lower=$(echo "$CLASS" | tr '[:upper:]' '[:lower:]')
|
||||||
|
case "$class_lower" in
|
||||||
|
*"$target_lower"*)
|
||||||
|
case " $EXISTING_HEX " in
|
||||||
|
*" $window_id "*) ;;
|
||||||
|
*)
|
||||||
|
addr="0x$window_id"
|
||||||
|
if [ -n "$WS" ]; then
|
||||||
|
hyprctl dispatch movetoworkspacesilent "$WS,address:$addr"
|
||||||
|
fi
|
||||||
|
hyprctl dispatch focuswindow "address:$addr"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown subcommand: $cmd"
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
118
scripts/mux
Executable file
118
scripts/mux
Executable file
|
|
@ -0,0 +1,118 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
spawn_or_focus() {
|
||||||
|
name="$1"
|
||||||
|
cmd="$2"
|
||||||
|
|
||||||
|
if tmux list-windows -F '#{window_name}' | grep -Fx "$name" >/dev/null; then
|
||||||
|
tmux select-window -t "${name}"
|
||||||
|
else
|
||||||
|
if [ -n "$cmd" ]; then
|
||||||
|
tmux new-window -c '#{pane_current_path}' -n "${name}" "$cmd"
|
||||||
|
else
|
||||||
|
tmux new-window -c '#{pane_current_path}' -n "${name}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
bar)
|
||||||
|
[ "$2" ] || exit
|
||||||
|
mouse=""
|
||||||
|
if [ "$(tmux show-options | grep mouse | awk '{ print $NF }')" = "on" ]; then
|
||||||
|
mouse='[m]'
|
||||||
|
fi
|
||||||
|
set -f
|
||||||
|
keys="H J K L"
|
||||||
|
bar_content=""
|
||||||
|
i=0
|
||||||
|
total=$(tmux ls -F x | wc -l)
|
||||||
|
for line in $(tmux ls -F '#{session_id}:#{session_name}'); do
|
||||||
|
sid="${line%%:*}"
|
||||||
|
sname="${line#*:}"
|
||||||
|
if [ $i -lt 4 ]; then
|
||||||
|
key=$(echo "$keys" | cut -d' ' -f $((i + 1)))
|
||||||
|
elif [ $i -eq $((total - 1)) ]; then
|
||||||
|
key='$'
|
||||||
|
else
|
||||||
|
key='?'
|
||||||
|
fi
|
||||||
|
star=""
|
||||||
|
[ "$sname" = "$2" ] && star="*"
|
||||||
|
bar_content="$bar_content#[range=session|${sid}]$key:$sname$star#[norange] "
|
||||||
|
i=$((i + 1))
|
||||||
|
done
|
||||||
|
set +f
|
||||||
|
left='#[align=left list=on] #{W:#[range=window|#{window_index}]#{window_index}:#{window_name}#{window_flags}#[norange] }#[nolist]'
|
||||||
|
right="#[align=right]$mouse $bar_content"
|
||||||
|
tmux set -g 'status-format[0]' "$left$right"
|
||||||
|
;;
|
||||||
|
switch)
|
||||||
|
session="$(tmux ls -F '#S' | tail -n "+$(($2 + 1))" | head -1)"
|
||||||
|
tmux switch -t "$session"
|
||||||
|
;;
|
||||||
|
exec)
|
||||||
|
name="$(basename "$PWD")"
|
||||||
|
project="$(basename "$(dirname "$PWD")")/$name"
|
||||||
|
|
||||||
|
case "$project" in
|
||||||
|
*/bmath)
|
||||||
|
cmd='cmake -B build -DCMAKE_BUILD_TYPE=Debug && cmake --build build && ctest --test-dir build --output-on-failure'
|
||||||
|
;;
|
||||||
|
*/ag)
|
||||||
|
cmd='cp -f autograder.py example && cd example && ./run_autograder'
|
||||||
|
;;
|
||||||
|
*/project-a-10)
|
||||||
|
cmd='. venv/bin/activate && python manage.py runserver'
|
||||||
|
;;
|
||||||
|
*/theCourseForum2)
|
||||||
|
cmd='docker compose up'
|
||||||
|
;;
|
||||||
|
*/atlas | */tinyground)
|
||||||
|
cmd='pnpm run dev'
|
||||||
|
;;
|
||||||
|
*/interview-prep)
|
||||||
|
cmd='pnpm run dev'
|
||||||
|
;;
|
||||||
|
*/neovim)
|
||||||
|
cmd='make'
|
||||||
|
;;
|
||||||
|
*/TestCppClient)
|
||||||
|
cmd='rm -f TestCppClientStatic && cmake -S . -B build/ && make && ./TestCppClientStatic'
|
||||||
|
;;
|
||||||
|
sl/*)
|
||||||
|
cmd='make clean install && make clean'
|
||||||
|
[ "$name" = 'slock' ] && cmd="doas $cmd"
|
||||||
|
;;
|
||||||
|
*/barrettruth.com)
|
||||||
|
cmd='pnpm dev'
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo " > $cmd" | sed "s|$HOME|~|g"
|
||||||
|
eval "$cmd"
|
||||||
|
;;
|
||||||
|
claude)
|
||||||
|
spawn_or_focus claude 'claude --chrome'
|
||||||
|
;;
|
||||||
|
nvim)
|
||||||
|
spawn_or_focus nvim 'nvim -c "lua require([[config.tmux]]).run([[nvim]])"'
|
||||||
|
;;
|
||||||
|
git)
|
||||||
|
pane_path=$(tmux display-message -p '#{pane_current_path}')
|
||||||
|
if ! git -C "$pane_path" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||||
|
tmux display-message "Not a git repository"
|
||||||
|
else
|
||||||
|
spawn_or_focus git 'nvim -c "lua require([[config.tmux]]).run([[git]])"'
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
run)
|
||||||
|
spawn_or_focus run 'nvim -c "lua require([[config.tmux]]).run([[run]])"'
|
||||||
|
;;
|
||||||
|
term)
|
||||||
|
spawn_or_focus term
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
tmux attach
|
||||||
|
;;
|
||||||
|
esac
|
||||||
227
scripts/pipes
Executable file
227
scripts/pipes
Executable file
|
|
@ -0,0 +1,227 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# pipes.sh: Animated pipes terminal screensaver.
|
||||||
|
# https://github.com/pipeseroni/pipes.sh
|
||||||
|
#
|
||||||
|
# Copyright (c) 2015-2018 Pipeseroni/pipes.sh contributors
|
||||||
|
# Copyright (c) 2013-2015 Yu-Jie Lin
|
||||||
|
# Copyright (c) 2010 Matthew Simpson
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
VERSION=1.3.0
|
||||||
|
|
||||||
|
M=32768 # Bash RANDOM maximum + 1
|
||||||
|
p=1 # number of pipes
|
||||||
|
f=75 # frame rate
|
||||||
|
s=13 # probability of straight fitting
|
||||||
|
r=2000 # characters limit
|
||||||
|
t=0 # iteration counter for -r character limit
|
||||||
|
w=80 # terminal size
|
||||||
|
h=24
|
||||||
|
|
||||||
|
# ab -> sets[][idx] = a*4 + b
|
||||||
|
# 0: up, 1: right, 2: down, 3: left
|
||||||
|
# 00 means going up , then going up -> ┃
|
||||||
|
# 12 means going right, then going down -> ┓
|
||||||
|
sets=(
|
||||||
|
"┃┏ ┓┛━┓ ┗┃┛┗ ┏━"
|
||||||
|
"│╭ ╮╯─╮ ╰│╯╰ ╭─"
|
||||||
|
"│┌ ┐┘─┐ └│┘└ ┌─"
|
||||||
|
"║╔ ╗╝═╗ ╚║╝╚ ╔═"
|
||||||
|
"|+ ++-+ +|++ +-"
|
||||||
|
"|/ \/-\ \|/\ /-"
|
||||||
|
".. .... .... .."
|
||||||
|
".o oo.o o.oo o."
|
||||||
|
"-\ /\|/ /-\/ \|"
|
||||||
|
"╿┍ ┑┚╼┒ ┕╽┙┖ ┎╾"
|
||||||
|
"████▀▀███▀█▀▀██▀"
|
||||||
|
)
|
||||||
|
|
||||||
|
# pipes'
|
||||||
|
x=() # current position
|
||||||
|
y=()
|
||||||
|
l=() # current directions
|
||||||
|
# 0: up, 1: right, 2: down, 3: left
|
||||||
|
n=() # new directions
|
||||||
|
v=() # current types
|
||||||
|
c=() # current color
|
||||||
|
|
||||||
|
# selected pipes'
|
||||||
|
V=() # types (indexes to sets[])
|
||||||
|
C=() # colors
|
||||||
|
VN=0 # number of selected types
|
||||||
|
CN=0 # number of selected colors
|
||||||
|
|
||||||
|
# switches
|
||||||
|
RNDSTART=0 # randomize starting position and direction
|
||||||
|
BOLD=1
|
||||||
|
NOCOLOR=0
|
||||||
|
KEEPCT=0 # keep pipe color and type
|
||||||
|
|
||||||
|
|
||||||
|
parse() {
|
||||||
|
OPTIND=1
|
||||||
|
while getopts "p:t:c:f:s:r:RBCKhv" arg; do
|
||||||
|
case $arg in
|
||||||
|
p) ((p = (OPTARG > 0) ? OPTARG : p));;
|
||||||
|
t)
|
||||||
|
if [[ "$OPTARG" = c???????????????? ]]; then
|
||||||
|
V+=(${#sets[@]})
|
||||||
|
sets+=("${OPTARG:1}")
|
||||||
|
else
|
||||||
|
((OPTARG >= 0 && OPTARG < ${#sets[@]})) && V+=($OPTARG)
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
c) [[ $OPTARG =~ ^[0-7]$ ]] && C+=($OPTARG);;
|
||||||
|
f) ((f = (OPTARG > 19 && OPTARG < 101) ? OPTARG : f));;
|
||||||
|
s) ((s = (OPTARG > 4 && OPTARG < 16) ? OPTARG : s));;
|
||||||
|
r) ((r = (OPTARG >= 0) ? OPTARG : r));;
|
||||||
|
R) RNDSTART=1;;
|
||||||
|
B) BOLD=0;;
|
||||||
|
C) NOCOLOR=1;;
|
||||||
|
K) KEEPCT=1;;
|
||||||
|
h) echo -e "Usage: $(basename $0) [OPTION]..."
|
||||||
|
echo -e "Animated pipes terminal screensaver.\n"
|
||||||
|
echo -e " -p [1-]\tnumber of pipes (D=1)."
|
||||||
|
echo -e " -t [0-$((${#sets[@]} - 1))]\ttype of pipes, can be used more than once (D=0)."
|
||||||
|
echo -e " -c [0-7]\tcolor of pipes, can be used more than once (D=1 2 3 4 5 6 7 0)."
|
||||||
|
echo -e " -t c[16 chars]\tcustom type of pipes."
|
||||||
|
echo -e " -f [20-100]\tframerate (D=75)."
|
||||||
|
echo -e " -s [5-15]\tprobability of a straight fitting (D=13)."
|
||||||
|
echo -e " -r LIMIT\treset after x characters, 0 if no limit (D=2000)."
|
||||||
|
echo -e " -R \t\trandomize starting position and direction."
|
||||||
|
echo -e " -B \t\tno bold effect."
|
||||||
|
echo -e " -C \t\tno color."
|
||||||
|
echo -e " -K \t\tpipes keep their color and type when hitting the screen edge."
|
||||||
|
echo -e " -h\t\thelp (this screen)."
|
||||||
|
echo -e " -v\t\tprint version number.\n"
|
||||||
|
exit 0;;
|
||||||
|
v) echo "$(basename -- "$0") $VERSION"
|
||||||
|
exit 0
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# set default values if not by options
|
||||||
|
((${#V[@]})) || V=(0)
|
||||||
|
VN=${#V[@]}
|
||||||
|
((${#C[@]})) || C=(1 2 3 4 5 6 7 0)
|
||||||
|
CN=${#C[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
# clear out standard input
|
||||||
|
read -t 0.001 && cat </dev/stdin>/dev/null
|
||||||
|
|
||||||
|
# terminal has no smcup and rmcup capabilities
|
||||||
|
((FORCE_RESET)) && reset && exit 0
|
||||||
|
|
||||||
|
tput reset # fix for konsole, see pipeseroni/pipes.sh#43
|
||||||
|
tput rmcup
|
||||||
|
tput cnorm
|
||||||
|
# stty echo
|
||||||
|
((NOCOLOR)) && echo -ne '\e[0m'
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
resize() {
|
||||||
|
w=$(tput cols) h=$(tput lines)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
init() {
|
||||||
|
local i
|
||||||
|
|
||||||
|
resize
|
||||||
|
trap resize SIGWINCH
|
||||||
|
ci=$((KEEPCT ? 0 : CN * RANDOM / M))
|
||||||
|
vi=$((KEEPCT ? 0 : VN * RANDOM / M))
|
||||||
|
for ((i = 0; i < p; i++)); {((
|
||||||
|
n[i] = 0,
|
||||||
|
l[i] = RNDSTART ? RANDOM % 4 : 0,
|
||||||
|
x[i] = RNDSTART ? w * RANDOM / M : w / 2,
|
||||||
|
y[i] = RNDSTART ? h * RANDOM / M : h / 2,
|
||||||
|
c[i] = C[ci],
|
||||||
|
v[i] = V[vi],
|
||||||
|
ci = (ci + 1) % CN,
|
||||||
|
vi = (vi + 1) % VN
|
||||||
|
));}
|
||||||
|
|
||||||
|
# stty -echo
|
||||||
|
tput smcup || FORCE_RESET=1
|
||||||
|
tput civis
|
||||||
|
tput clear
|
||||||
|
trap cleanup HUP TERM
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local i
|
||||||
|
|
||||||
|
parse "$@"
|
||||||
|
init "$@"
|
||||||
|
|
||||||
|
# any key press exits the loop and this script
|
||||||
|
trap 'break 2' INT
|
||||||
|
while REPLY=; do
|
||||||
|
read -t 0.0$((1000 / f)) -n 1 2>/dev/null
|
||||||
|
case "$REPLY" in
|
||||||
|
P) ((s = s < 15 ? s + 1 : s));;
|
||||||
|
O) ((s = s > 3 ? s - 1 : s));;
|
||||||
|
F) ((f = f < 100 ? f + 1 : f));;
|
||||||
|
D) ((f = f > 20 ? f - 1 : f));;
|
||||||
|
B) ((BOLD = (BOLD + 1) % 2));;
|
||||||
|
C) ((NOCOLOR = (NOCOLOR + 1) % 2));;
|
||||||
|
K) ((KEEPCT = (KEEPCT + 1) % 2));;
|
||||||
|
?) break;;
|
||||||
|
esac
|
||||||
|
for ((i = 0; i < p; i++)); do
|
||||||
|
# New position:
|
||||||
|
# l[] direction = 0: up, 1: right, 2: down, 3: left
|
||||||
|
((l[i] % 2)) && ((x[i] += -l[i] + 2, 1)) || ((y[i] += l[i] - 1))
|
||||||
|
|
||||||
|
# Loop on edges (change color on loop):
|
||||||
|
((!KEEPCT && (x[i] >= w || x[i] < 0 || y[i] >= h || y[i] < 0))) \
|
||||||
|
&& ((c[i] = C[CN * RANDOM / M], v[i] = V[VN * RANDOM / M]))
|
||||||
|
((x[i] = (x[i] + w) % w))
|
||||||
|
((y[i] = (y[i] + h) % h))
|
||||||
|
|
||||||
|
# New random direction:
|
||||||
|
((n[i] = s * RANDOM / M - 1))
|
||||||
|
((n[i] = (n[i] > 1 || n[i] == 0) ? l[i] : l[i] + n[i]))
|
||||||
|
((n[i] = (n[i] < 0) ? 3 : n[i] % 4))
|
||||||
|
|
||||||
|
# Print:
|
||||||
|
tput cup ${y[i]} ${x[i]}
|
||||||
|
echo -ne "\e[${BOLD}m"
|
||||||
|
((NOCOLOR)) && echo -ne "\e[0m" || echo -ne "\e[3${c[i]}m"
|
||||||
|
echo -n "${sets[v[i]]:l[i]*4+n[i]:1}"
|
||||||
|
l[i]=${n[i]}
|
||||||
|
done
|
||||||
|
((r > 0 && t * p >= r)) && tput reset && tput civis && t=0 || ((t++))
|
||||||
|
done
|
||||||
|
|
||||||
|
cleanup
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
main "$@"
|
||||||
|
|
||||||
122
scripts/theme
Executable file
122
scripts/theme
Executable file
|
|
@ -0,0 +1,122 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
themes="daylight
|
||||||
|
midnight"
|
||||||
|
|
||||||
|
as_list="$(printf "%s\n" "$themes" | awk 'NF{printf "\"%s\",", $0}' | sed 's/,$//')"
|
||||||
|
|
||||||
|
case "$(uname)" in
|
||||||
|
Linux)
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
theme="$1"
|
||||||
|
else
|
||||||
|
if [ "$XDG_SESSION_TYPE" = "wayland" ]; then
|
||||||
|
theme="$(printf "%s\n" "$themes" | rofi -dmenu -p 'theme')"
|
||||||
|
else
|
||||||
|
theme="$(printf "%s\n" "$themes" | dmenu -p 'select theme: ')"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
Darwin)
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
theme="$1"
|
||||||
|
else
|
||||||
|
theme="$(
|
||||||
|
osascript <<EOF
|
||||||
|
set theList to {$as_list}
|
||||||
|
|
||||||
|
set chosenTheme to (choose from list theList ¬
|
||||||
|
with title "Theme" ¬
|
||||||
|
with prompt "Pick a theme" ¬
|
||||||
|
OK button name "Apply" ¬
|
||||||
|
cancel button name "Cancel" ¬
|
||||||
|
without empty selection allowed)
|
||||||
|
|
||||||
|
if chosenTheme is false then
|
||||||
|
return ""
|
||||||
|
else
|
||||||
|
return item 1 of chosenTheme
|
||||||
|
end if
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
[ -z "$theme" ] && exit 1
|
||||||
|
echo "$themes" | grep -Fxq "$theme" || exit 1
|
||||||
|
|
||||||
|
case "$(uname)" in
|
||||||
|
Linux)
|
||||||
|
if command -v gsettings >/dev/null 2>&1; then
|
||||||
|
case "$theme" in
|
||||||
|
midnight)
|
||||||
|
gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark'
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
gsettings set org.gnome.desktop.interface color-scheme 'prefer-light'
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ "$XDG_SESSION_TYPE" = "wayland" ] && {
|
||||||
|
if [ "$XDG_CURRENT_DESKTOP" = 'Hyprland' ]; then
|
||||||
|
current_theme=$(readlink "$XDG_CONFIG_HOME/hypr/theme.conf" 2>/dev/null | awk -F/ '{print $NF}' | sed 's/\.conf$//')
|
||||||
|
if [ "$current_theme" != "$theme" ]; then
|
||||||
|
ln -sf "$XDG_CONFIG_HOME/hypr/themes/$theme.conf" "$XDG_CONFIG_HOME/hypr/theme.conf"
|
||||||
|
ln -sf "$XDG_CONFIG_HOME/waybar/themes/$theme.css" "$XDG_CONFIG_HOME/waybar/themes/theme.css"
|
||||||
|
hyprctl reload
|
||||||
|
pkill -USR1 waybar
|
||||||
|
pkill -USR1 waybar
|
||||||
|
fi
|
||||||
|
elif [ "$XDG_CURRENT_DESKTOP" = 'sway' ]; then
|
||||||
|
current_theme=$(readlink "$XDG_CONFIG_HOME/sway/themes/theme" 2>/dev/null | sed 's|.*/||')
|
||||||
|
if [ "$current_theme" != "$theme" ]; then
|
||||||
|
test -f "$XDG_CONFIG_HOME/sway/themes/theme" && ln -sf "$XDG_CONFIG_HOME/sway/themes/$theme" "$XDG_CONFIG_HOME/sway/themes/theme"
|
||||||
|
swaymsg reload
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
test -d "$XDG_CONFIG_HOME/rofi/themes" && ln -sf "$XDG_CONFIG_HOME/rofi/themes/$theme.rasi" "$XDG_CONFIG_HOME/rofi/themes/theme.rasi"
|
||||||
|
;;
|
||||||
|
Darwin)
|
||||||
|
case "$theme" in
|
||||||
|
daylight)
|
||||||
|
osascript -e 'tell app "System Events" to tell appearance preferences to set dark mode to false' 2>/dev/null || true
|
||||||
|
;;
|
||||||
|
midnight)
|
||||||
|
osascript -e 'tell app "System Events" to tell appearance preferences to set dark mode to true' 2>/dev/null || true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if tmux list-sessions >/dev/null 2>&1; then
|
||||||
|
test -f "$XDG_CONFIG_HOME/tmux/tmux.conf" && tmux source-file "$XDG_CONFIG_HOME/tmux/tmux.conf"
|
||||||
|
[ "$TMUX" ] && tmux refresh-client -S
|
||||||
|
fi
|
||||||
|
|
||||||
|
test -d "$XDG_CONFIG_HOME/fzf/themes" && ln -sf "$XDG_CONFIG_HOME/fzf/themes/$theme" "$XDG_CONFIG_HOME/fzf/themes/theme"
|
||||||
|
test -d "$XDG_CONFIG_HOME/rg/themes" && ln -sf "$XDG_CONFIG_HOME/rg/themes/$theme" "$XDG_CONFIG_HOME/rg/themes/theme"
|
||||||
|
test -d "$XDG_CONFIG_HOME/task/themes" && ln -sf "$XDG_CONFIG_HOME/task/themes/$theme.theme" "$XDG_CONFIG_HOME/task/themes/theme.theme"
|
||||||
|
|
||||||
|
if command -v claude >/dev/null 2>&1; then
|
||||||
|
case "$theme" in
|
||||||
|
daylight)
|
||||||
|
claude config set theme light
|
||||||
|
;;
|
||||||
|
midnight)
|
||||||
|
claude config set theme dark
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
test -f ~/.zshenv && sed -i "s|^\(export THEME=\).*|\1$theme|" ~/.zshenv
|
||||||
|
|
||||||
|
for socket in /tmp/nvim-*.sock; do
|
||||||
|
test -S "$socket" && nvim --server "$socket" --remote-expr "luaeval('require(\"config.fzf_reload\").reload()')" 2>/dev/null || true
|
||||||
|
done
|
||||||
144
scripts/wp
Executable file
144
scripts/wp
Executable file
|
|
@ -0,0 +1,144 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from PIL import Image, ImageDraw
|
||||||
|
|
||||||
|
HOME = os.environ["HOME"]
|
||||||
|
DIR = f"{HOME}/img/screen"
|
||||||
|
os.makedirs(DIR, exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
|
def get_resolution():
|
||||||
|
output = "1920x1080"
|
||||||
|
if "WAYLAND_DISPLAY" in os.environ:
|
||||||
|
desktop = os.environ.get("XDG_CURRENT_DESKTOP", "")
|
||||||
|
if desktop == "Hyprland":
|
||||||
|
output = (
|
||||||
|
subprocess.check_output(
|
||||||
|
"hyprctl monitors -j | jq -r '.[] | select(.focused==true) | .width, .height' | paste -sd x -",
|
||||||
|
shell=True,
|
||||||
|
)
|
||||||
|
.decode()
|
||||||
|
.strip()
|
||||||
|
)
|
||||||
|
elif desktop == "sway":
|
||||||
|
output = (
|
||||||
|
subprocess.check_output(
|
||||||
|
"swaymsg -t get_outputs -r | jq -r '.[] | select(.active==true) | .current_mode.width,.current_mode.height' | paste -sd x -",
|
||||||
|
shell=True,
|
||||||
|
)
|
||||||
|
.decode()
|
||||||
|
.strip()
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
output = (
|
||||||
|
subprocess.check_output(
|
||||||
|
"xrandr | grep '*' | awk '{print $1}'", shell=True
|
||||||
|
)
|
||||||
|
.decode()
|
||||||
|
.strip()
|
||||||
|
)
|
||||||
|
return map(int, output.split("x"))
|
||||||
|
|
||||||
|
|
||||||
|
def lock():
|
||||||
|
W, H = get_resolution()
|
||||||
|
UNIT = 16
|
||||||
|
grid_w = W // UNIT
|
||||||
|
grid_h = H // UNIT
|
||||||
|
|
||||||
|
bg_color = tuple(random.randint(0, 255) for _ in range(3))
|
||||||
|
img = Image.new("RGB", (W, H), bg_color)
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
|
||||||
|
MU = 0.8
|
||||||
|
SIGMA = 0.7
|
||||||
|
SCALE_FACTOR = 1.8
|
||||||
|
|
||||||
|
S = {(x, y) for x in range(grid_w) for y in range(grid_h)}
|
||||||
|
N = len(S)
|
||||||
|
|
||||||
|
while S:
|
||||||
|
if random.random() < 1 / N:
|
||||||
|
break
|
||||||
|
gx, gy = S.pop()
|
||||||
|
w_units = max(
|
||||||
|
1,
|
||||||
|
min(
|
||||||
|
grid_w - gx,
|
||||||
|
int(round(random.lognormvariate(MU, SIGMA) * SCALE_FACTOR)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
h_units = max(
|
||||||
|
1,
|
||||||
|
min(
|
||||||
|
grid_h - gy,
|
||||||
|
int(round(random.lognormvariate(MU, SIGMA) * SCALE_FACTOR)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
|
||||||
|
|
||||||
|
dx = random.choice([1, -1])
|
||||||
|
dy = random.choice([1, -1])
|
||||||
|
|
||||||
|
gx_end = gx + dx * (w_units - 1)
|
||||||
|
gy_end = gy + dy * (h_units - 1)
|
||||||
|
|
||||||
|
x0, x1 = sorted([gx, gx_end])
|
||||||
|
y0, y1 = sorted([gy, gy_end])
|
||||||
|
|
||||||
|
draw.rectangle(
|
||||||
|
[x0 * UNIT, y0 * UNIT, (x1 + 1) * UNIT - 1, (y1 + 1) * UNIT - 1],
|
||||||
|
fill=color,
|
||||||
|
)
|
||||||
|
|
||||||
|
img.save(f"{DIR}/lock.jpg", quality=95)
|
||||||
|
|
||||||
|
|
||||||
|
def wall():
|
||||||
|
W, H = get_resolution()
|
||||||
|
|
||||||
|
colors = [
|
||||||
|
"#aa0000",
|
||||||
|
"#ff3333",
|
||||||
|
"#ff7777",
|
||||||
|
"#ffbb55",
|
||||||
|
"#ffcc88",
|
||||||
|
"#ff88ff",
|
||||||
|
"#aaaaff",
|
||||||
|
"#77ddbb",
|
||||||
|
"#77ff77",
|
||||||
|
"#cccccc",
|
||||||
|
]
|
||||||
|
|
||||||
|
colors.reverse()
|
||||||
|
|
||||||
|
img = Image.new("RGB", (W, H), "white")
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
|
||||||
|
num_bars = len(colors)
|
||||||
|
|
||||||
|
for i, color in enumerate(reversed(colors)):
|
||||||
|
top = round(i * H / num_bars)
|
||||||
|
bottom = round((i + 1) * H / num_bars)
|
||||||
|
draw.rectangle([0, top, W, bottom], fill=color)
|
||||||
|
|
||||||
|
img.save(f"{DIR}/wallpaper.jpg", quality=95)
|
||||||
|
|
||||||
|
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("Usage: wp {lock|wall}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
cmd = sys.argv[1]
|
||||||
|
if cmd == "lock":
|
||||||
|
lock()
|
||||||
|
elif cmd == "wall":
|
||||||
|
wall()
|
||||||
|
else:
|
||||||
|
print("Usage: wp {lock|wall}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
56
scripts/x
Executable file
56
scripts/x
Executable file
|
|
@ -0,0 +1,56 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
cmd="$1"; shift
|
||||||
|
|
||||||
|
case "$cmd" in
|
||||||
|
setup)
|
||||||
|
xrdb -merge "$XDG_CONFIG_HOME"/X11/xresources."$THEME"
|
||||||
|
xset b off
|
||||||
|
xset m 0
|
||||||
|
xset r rate 300 50
|
||||||
|
xset s 300
|
||||||
|
xset dpms 420 540 720
|
||||||
|
xmodmap "$XDG_CONFIG_HOME"/X11/xmodmap
|
||||||
|
xss-lock -- slock &
|
||||||
|
;;
|
||||||
|
bg)
|
||||||
|
randr="$(xrandr | rg ' connected ')"
|
||||||
|
mons="$(echo "$randr" | wc -l)"
|
||||||
|
wpdir="$HOME"/img/wp
|
||||||
|
|
||||||
|
[ "$1" ] && bgone="$1" || bgone="$wpdir"/one/cliff.jpg
|
||||||
|
cmd="feh --no-fehbg --bg-fill $bgone"
|
||||||
|
|
||||||
|
if [ "$mons" = 2 ]; then
|
||||||
|
[ "$2" ] && bgtwo="$2" || bgtwo="$wpdir"/two/lilies.jpg
|
||||||
|
cmd="$cmd --bg-fill $bgtwo"
|
||||||
|
else
|
||||||
|
cmd="feh --no-fehbg --bg-fill $bgone"
|
||||||
|
fi
|
||||||
|
|
||||||
|
eval "$cmd"
|
||||||
|
;;
|
||||||
|
mon)
|
||||||
|
mons="$(xrandr | rg --no-config ' connected ' | awk '{ print $1 }')"
|
||||||
|
|
||||||
|
one="$(echo "$mons" | head -n 1)"
|
||||||
|
two="$(echo "$mons" | tail -n 1)"
|
||||||
|
case "$two" in
|
||||||
|
*None* | "$one")
|
||||||
|
unset two
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
xrandr --auto
|
||||||
|
|
||||||
|
xrandr --output "$one" --primary --mode 1920x1200 --scale 1x1 --set TearFree on --dpi 161.73
|
||||||
|
|
||||||
|
[ -z "$two" ] && exit
|
||||||
|
|
||||||
|
xrandr --output "$one" --pos 960x2160 --output "$two" --scale 1.5x1.5 --pos 0x0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: x {setup|bg|mon}" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
Loading…
Add table
Add a link
Reference in a new issue