Compare commits

...

44 commits

Author SHA1 Message Date
f0d39800d6 docs: polish ArchASP dotfiles README 2026-09-25 06:20:16 +02:00
79b08a5369 fix(systemd): make user enablement links portable 2026-09-25 05:48:49 +02:00
75289913f6 docs: rewrite ArchASP dotfiles guide 2026-09-25 05:46:27 +02:00
c54d7d22bf chore(gtk): preserve active bookmarks 2026-09-25 05:46:15 +02:00
c071bee8f7 chore(nvim): preserve active plugin configuration 2026-09-25 05:46:14 +02:00
1f3438624e feat(shell): preserve active user workflow 2026-09-25 05:46:14 +02:00
72c663f719 fix(session): repair active desktop configuration 2026-09-25 05:46:05 +02:00
60a00adf8e chore(dotfiles): untrack machine-generated artifacts 2026-09-25 05:46:03 +02:00
dfd2599a5e chore(system): refresh package and service inventories 2026-09-25 05:44:06 +02:00
b475faba2a fix(systemd): track canonical user units 2026-09-25 05:42:29 +02:00
8551db9e35 feat(bin): track canonical user launchers 2026-09-25 05:42:29 +02:00
7da6cec15c fix(stow): restore reproducible package deployment 2026-09-25 05:39:26 +02:00
de7b8e283e chore(dotfiles): remove stale runtime artifacts 2026-09-25 05:37:28 +02:00
ed6888a033 chore(dotfiles): remove retired desktop components 2026-09-25 05:36:06 +02:00
grayTerminal-sh
525a263c27 README.md 2026-07-26 23:40:30 +02:00
grayTerminal-sh
6d11442134 update 2026-07-26 23:34:14 +02:00
grayTerminal-sh
7b74e20dc7 update 2026-07-26 21:11:35 +02:00
grayTerminal-sh
76f89d79c0 update 2026-06-10 10:26:17 +02:00
grayTerminal-sh
09d5afa549 modification autostart sway 2026-06-10 10:20:41 +02:00
grayTerminal-sh
3c9b1427be README.md 2026-06-06 08:56:02 +02:00
grayTerminal-sh
365fa00891 README.md 2026-06-06 08:50:52 +02:00
grayTerminal-sh
af2ae5380e README.md 2026-06-06 08:47:54 +02:00
grayTerminal-sh
2c631074fe README.md 2026-06-06 08:44:55 +02:00
grayTerminal-sh
1180784880 screenshot README.md 2026-06-06 08:39:06 +02:00
grayTerminal-sh
4efa9d244d README.md 2026-06-06 08:29:42 +02:00
grayTerminal-sh
90e6e1e134 README.md 2026-06-06 08:26:42 +02:00
grayTerminal-sh
09638119f3 README.md 2026-06-06 08:23:05 +02:00
grayTerminal-sh
a869246478 README.md 2026-06-06 07:59:52 +02:00
grayTerminal-sh
4aad94cb5c README.md 2026-06-06 07:58:11 +02:00
grayTerminal-sh
76879b91e5 README.md 2026-06-06 07:54:09 +02:00
grayTerminal-sh
adf6dd1163 ajout .local/bin/batlimit 2026-06-05 13:01:27 +02:00
grayTerminal-sh
c60bd49d51 update 2026-06-05 11:09:04 +02:00
grayTerminal-sh
1eec305b93 update 2026-06-05 10:03:55 +02:00
grayTerminal-sh
031864d448 Remove runtime data from repository 2026-06-05 09:43:42 +02:00
grayTerminal-sh
a0c1a2d197 update hyprwisper and atuin 2026-06-05 09:37:01 +02:00
grayTerminal-sh
faa9676ef1 plugin heic yazi 2026-06-03 14:15:15 +02:00
grayTerminal-sh
506bf37d72 update 2026-05-30 22:24:26 +02:00
grayTerminal-sh
68f26b1261 general 2026-05-30 09:35:14 +02:00
grayTerminal-sh
07d68b06d6 ajout atuin 2026-05-26 10:50:52 +02:00
grayTerminal-sh
2f09785761 config nvim + modif config mangowm 2026-05-24 00:48:17 +02:00
grayTerminal-sh
73ab06d1bb rules mango 2026-05-21 18:01:45 +02:00
grayTerminal-sh
03dafbe3ab README.md 2026-05-20 23:45:36 +02:00
grayTerminal-sh
be4e96ebc3 README.md 2026-05-20 23:43:21 +02:00
grayTerminal-sh
32d124441e ajout whisper + modif binds MangoWM 2026-05-20 23:13:15 +02:00
163 changed files with 4217 additions and 3710 deletions

View file

@ -1,16 +1,16 @@
NetworkManager-dispatcher.service
NetworkManager-wait-online.service
NetworkManager.service
avahi-daemon.service
blueman-mechanism.service
bluetooth.service
cups.service
getty@.service
greetd.service
grub-btrfsd.service
libvirtd.service
NetworkManager-dispatcher.service
NetworkManager-wait-online.service
NetworkManager.service
nftables.service
power-profiles-daemon.service
seatd.service
systemd-oomd.service
systemd-resolved.service
nginx.service
sshd.service
systemd-timesyncd.service
tlp-pd.service
tlp.service
wg-quick@wg0.service

View file

@ -0,0 +1,7 @@
avahi-daemon.socket
cups.path
cups.socket
fstrim.timer
snapper-cleanup.timer
snapper-timeline.timer
systemd-userdbd.socket

View file

@ -0,0 +1,6 @@
arch-sentinel-sample.timer
battery-low-notify.timer
gnome-keyring-daemon.socket
p11-kit-server.socket
pipewire-pulse.socket
pipewire.socket

42
.assets/external-tools.md Normal file
View file

@ -0,0 +1,42 @@
# Outils hors Pacman
Cet inventaire décrit les dépendances observées le 25 septembre 2026 qui ne
sont pas restaurées par `pkglist-pacman.txt` ou `pkglist-aur.txt`.
## Cargo
- `ytmusic-tui 0.2.1` (`cargo install ytmusic-tui`)
## npm utilisateur
Le préfixe actif est `~/.local/npm` et `.zshrc` l'ajoute à `PATH`.
- `@earendil-works/pi-coding-agent@0.84.3`
- `context-mode@1.0.169`
- `prettier@3.9.6`
## Builds et projets locaux
Ces éléments sont volontairement hors du dépôt de dotfiles. Les liens ou
unités du dépôt supposent leur présence à ces emplacements :
- `~/.local/src/arch-sentinel` fournit `~/.local/bin/arch-sentinel` ;
- `~/Documents/trainlog` fournit les exécutables et agents Trainlog ;
- `~/Documents/Lardon` fournit la session FreeCAD et ses outils ;
- `~/Documents/labfy-remote-ui` fournit `labfy-remote-ui` ;
- `~/Applications/openmvs-2.4.0` fournit OpenMVS au pipeline `scan3d` ;
- `~/.codex/packages/standalone/current` fournit le lien utilisateur `codex`.
## Helpers système locaux
Ces fichiers sous `/usr/local` ne sont possédés par aucun paquet. Ils relèvent
de la couche système `arch-system`, pas de ce dépôt utilisateur :
- `/usr/local/sbin/batlimit-set` ;
- `/usr/local/sbin/vmware-stack`.
## Problème système connu
`wg-quick@wg0.service` est activé mais échoue au démarrage car `resolvconf`
signale une divergence de signature pour `/etc/resolv.conf`. La correction
appartient à `arch-system` et n'est pas appliquée ici.

View file

@ -1,18 +1,6 @@
[terminal]
# The VT to run the greeter on. Can be "next", "current" or a number
# designating the VT.
vt = 1
# The default session, also known as the greeter.
[default_session]
# `agreety` is the bundled agetty/login-lookalike. You can replace `/bin/sh`
# with whatever you want started, such as `sway`.
command = "sway --config /etc/greetd/sway-config"
# The user to run the command as. The privileges this user must have depends
# on the greeter. A graphical greeter may for example require the user to be
# in the `video` group.
user = ""
command = "tuigreet --remember --asterisks --time --greeting 'Welcome to ArchASP' --theme 'container=brightblack;border=magenta;text=white;greet=brightmagenta;prompt=cyan;input=brightcyan;time=brightyellow;error=red;button=green;action=green' --cmd 'uwsm start default' --power-shutdown 'shutdown -h now' --power-reboot 'reboot'"
user = "greeter"

View file

@ -1,60 +0,0 @@
# SPDX-FileCopyrightText: 2022 Harish Rajagopal <harish.rajagopals@gmail.com>
#
# SPDX-License-Identifier: GPL-3.0-or-later
[background]
# Path to the background image
path = "/home/fy59/Images/Wallpapers/sway.png"
# How the background image covers the screen if the aspect ratio doesn't match
# Available values: "Fill", "Contain", "Cover", "ScaleDown"
# Refer to: https://docs.gtk.org/gtk4/enum.ContentFit.html
# NOTE: This is ignored if ReGreet isn't compiled with GTK v4.8 support.
fit = "Cover"
[GTK]
# Whether to use the dark theme
application_prefer_dark_theme = true
# Cursor theme name
cursor_theme_name = "catppuccin-mocha-lavender-cursors"
# Whether to blink the cursor
cursor_blink = true
# Font name and size
font_name = "jetbrains mono nerd font 14"
# Icon theme name
icon_theme_name = "Tela-blue-dark"
# GTK theme name
theme_name = "catppuccin-mocha-lavender-standard+default"
[commands]
# The command used to reboot the system
reboot = ["systemctl", "reboot"]
# The command used to shut down the system
poweroff = ["systemctl", "poweroff"]
[appearance]
# The message that initially displays on startup
greeting_msg = "Welcome back!"
[widget.clock]
# strftime format argument
# See https://docs.rs/jiff/0.1.14/jiff/fmt/strtime/index.html#conversion-specifications
format = "%H:%M"
# How often to update the text
resolution = "500ms"
# Override system timezone (IANA Time Zone Database name, aka /etc/zoneinfo path)
# Remove to use the system time zone.
timezone = "Europe/Paris"
# Ask GTK to make the label at least this wide. This helps keeps the parent element layout and width consistent.
# Experiment with different widths, the interpretation of this value is entirely up to GTK.
label_width = 150

View file

@ -1,14 +0,0 @@
exec "regreet; swaymsg exit"
include /etc/sway/config.d/*
### Keyboard
input * {
xkb_layout fr
xkb_variant oss
}
### Touchpad
input "type:touchpad" {
tap enabled
tap_button_map lrm
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 53 KiB

17
.assets/pkglist-aur.txt Normal file
View file

@ -0,0 +1,17 @@
appflowy-bin
bibata-cursor-theme
bridge-utils
colmap
colmap-debug
freeimage
go-mtpfs-git
hyprwhspr
jmtpfs
limine-snapper-sync
limusic-bin
meshlab-bin
mozjpeg-debug
proton-pass-bin
spicetify-marketplace-bin
vmware-workstation
yay

View file

@ -1,202 +1,251 @@
7zip
accountsservice
acpi
alsa-utils
amass
amd-ucode
amdgpu_top
android-file-transfer
android-tools
ansible
atuin
autotiling
axel
base
base-devel
bash-completion
bat
bat-extras
bear
bind
blueman
bluez
bluez-utils
brightnessctl
broadcom-wl-dkms
btop
btrfs-progs
calcure
catppuccin-cursors-mocha
catppuccin-gtk-theme-mocha
ccache
clang
cliphist
cpio
cloc
cmake
composer
cowsay
cppcheck
cppdap
cpupower
cups
dante
deezer
dgop
dialog
discord
cups-pk-helper
dmidecode
dnsmasq
docker
dosfstools
ecryptfs-utils
edk2-ovmf
efibootmgr
eigen
evince
evtest
exfatprogs
eza
fastfetch
fd
ffmpegthumbnailer
figlet
file-roller
firefox
firefox-i18n-fr
foomatic-db
foomatic-db-gutenprint-ppds
foomatic-db-nonfree
foomatic-db-nonfree-ppds
foomatic-db-ppds
fuse-overlayfs
fuse2
flatpak
freecad
fzf
gammastep
ggml-vulkan
gimp
gimp-help-fr
git
github-cli
gnome-themes-extra
gnome-keyring
gnu-free-fonts
gobuster
google-chrome
greetd-regreet
gphoto2
gradle
greetd-tuigreet
grim
grub
grub-btrfs
gst-libav
gst-plugin-gtk4
gst-plugin-pipewire
gst-plugins-bad
gst-plugins-base
gst-plugins-good
gst-plugins-ugly
gum
hashcat
gtk4
gtklock
gtklock-playerctl-module
gtklock-powerbar-module
gtklock-userinfo-module
gvfs
heimdall
hplip
hunspell-en_us
hunspell-fr
i3status-rust
inter-font
inxi
ifuse
imagemagick
inotify-tools
jadx
jdk-openjdk
jdk17-openjdk
john
jq
julia
kitty
libspng
libvirt
linux
less
libgsf
libheif
libimobiledevice
libjpeg-turbo
libmtp
libplist
libpulse
limine
linux-firmware
linux-headers
lsb-release
lsd
maim
man-db
linux-lts
linux-lts-headers
linux-zen
linux-zen-headers
llama-cpp
luarocks
mako
man-pages
man-pages-fr
mercurial
mtools
memtest86+
memtest86+-efi
mesa-utils
meson
mold
mpv
mtpfs
neovim
networkmanager
nikto
nmsurf
nextcloud-client
nginx
nodejs
noto-fonts
noto-fonts-cjk
notcurses
noto-fonts-emoji
noto-fonts-extra
npm
nss-mdns
openbsd-netcat
openvpn
optipng
os-prober
otf-font-awesome
ntfs-3g
ntp
nvme-cli
openresolv
openssh
pacman-contrib
pamixer
parallel
pass
pavucontrol
perl-image-exiftool
php
pipewire
pipewire-alsa
pipewire-jack
pipewire-libcamera
pipewire-pulse
playerctl
pnpm
polkit-gnome
power-profiles-daemon
podman
powertop
protonmail-bridge
pyenv
python-gobject
pyright
python-i3ipc
python-jedi
python-pip
python-pipx
python-pyamdgpuinfo
python-pyquery
python-utils
qalculate-gtk
qt5-quickcontrols2
python-jsonschema
python-opencv
python-pipenv
python-psutil
python-pynvim
python-textual
qt5-wayland
qt5ct
qt6-wayland
qt6ct
radeontop
rclone
reflector
renderdoc
rhash
ripgrep
rust
rocm-smi-lib
rofi
rsync
ruby
rustup
samba
sane
sane-airscan
sassc
scrollmpris-git
seat
seatd
seclists
slop
sbctl
slurp
snap-pac-grub
smartmontools
snap-pac
snapper
sof-firmware
spirv-headers
spotify-launcher
sqlitebrowser
starship
stow
strace
sudo
sway
swaybg
swayfx
swayidle
swayimg
swaylock-effects
swaylock
swaync
systemd-resolvconf
system-config-printer
tcpdump
testdisk
texinfo
tea
tela-circle-icon-theme-all
terminus-font
tesseract
tesseract-data-eng
tesseract-data-fra
thunar
thunar-archive-plugin
thunar-volman
thunderbird
thunderbird-i18n-fr
tlp
tlp-pd
tlp-rdw
tmux
traceroute
transmission-cli
transmission-gtk
tree
ttf-bitstream-vera
tree-sitter-cli
ttf-dejavu
ttf-droid
ttf-fantasque-nerd
ttf-fira-code
ttf-fira-sans
ttf-firacode-nerd
ttf-jetbrains-mono
ttf-liberation
ttf-nerd-fonts-symbols-mono
ttf-noto-nerd
ttf-victor-mono
umockdev
ttf-jetbrains-mono-nerd
tumbler
typst
unrar
unzip
usbmuxd
usbutils
vde2
w3m
uwsm
valgrind
vcpkg
vlc
volk
vulkan-headers
vulkan-radeon
vulkan-tools
vulkan-utility-libraries
vulkan-validation-layers
waybar
wayland-utils
webp-pixbuf-loader
wev
wget
whois
wireguard-tools
wl-clip-persist
wireplumber
wl-clipboard
wlopm
wlr-randr
wlsunset
wofi
wttrbar
xclip
xdg-desktop-portal-gtk
wpa_supplicant
xdg-desktop-portal
xdg-desktop-portal-wlr
xdg-user-dirs
xf86-video-nouveau
xmlstarlet
xf86-video-amdgpu
xorg-xrdb
xorg-xwayland
xournalpp
yarn
yazi
zip
yt-dlp
zoxide
zram-generator
zsh
zsh-autocomplete
zsh-autosuggestions
zsh-completions
zsh-history-substring-search
zsh-syntax-highlighting

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 806 KiB

29
.gitignore vendored Normal file
View file

@ -0,0 +1,29 @@
atuin/.local/share/
hyprwhspr/.local/share/
# Generated language/package-manager data
**/__pycache__/
*.py[cod]
**/node_modules/
# Local editor/application backups
*.bak
*.old
# Hyprwhspr runtime endpoints are recreated below XDG_RUNTIME_DIR.
hyprwhspr/.config/hyprwhspr/audio_level
hyprwhspr/.config/hyprwhspr/recording_control
hyprwhspr/.config/hyprwhspr/recording_status
# Machine-local or project-owned launchers exposed through ~/.local/bin.
bin/.local/bin/agy
bin/.local/bin/android
bin/.local/bin/arch-sentinel
bin/.local/bin/codex
bin/.local/bin/goose
bin/.local/bin/labfy-remote-ui
bin/.local/bin/trainlog
bin/.local/bin/trainlog-bt-watch
bin/.local/bin/trainlog-btd
bin/.local/bin/trainlog-sync-once
bin/.local/bin/trainlog-syncd

12
.gitmodules vendored Normal file
View file

@ -0,0 +1,12 @@
[submodule "zsh/.zsh/plugins/fast-syntax-highlighting"]
path = zsh/.zsh/plugins/fast-syntax-highlighting
url = https://github.com/zdharma-continuum/fast-syntax-highlighting.git
[submodule "zsh/.zsh/plugins/fzf-tab"]
path = zsh/.zsh/plugins/fzf-tab
url = https://github.com/Aloxaf/fzf-tab.git
[submodule "zsh/.zsh/plugins/zsh-autosuggestions"]
path = zsh/.zsh/plugins/zsh-autosuggestions
url = https://github.com/zsh-users/zsh-autosuggestions.git
[submodule "tmux/.config/tmux/plugins/catppuccin/tmux"]
path = tmux/.config/tmux/plugins/catppuccin/tmux
url = https://github.com/catppuccin/tmux.git

802
README.md
View file

@ -1,621 +1,291 @@
# ArchASP – Arch Sway Professor
<p align="center">
<img src=".assets/screen.jpg" alt="ArchASP — Sway desktop" width="100%">
</p>
<h1 align="center">ArchASP Dotfiles</h1>
<p align="center">
<img src=https://raw.githubusercontent.com/grayTerminal-sh/archasp/main/.assets/screen.jpg width="600" height="400" alt="screenshot">
</picture>
Personal Arch Linux configuration focused on:
- Keyboard-driventerminal-first
- Terminal-first workflow with Sway and MangoWM, Neovim, Kitty
- Catppuccin Mocha themed UI.
- Cyber Learning
**Goal** :
all reproducible from a single install script and a GNU Stow‑managed dotfiles repo.
<p>
[Installation Guide](#installation-on-existing-system)
[Greetd/Regreet config](#regreet-config)
[Snapper install & config](#snapper-config)
## Status
ArchASP is currently in active development.
If you want to contribute, improve the codebase, suggest ideas, or help
shape the installer workflow, feel free to contribute to that repository
too.
---
## Overview
This repo contains my entire user configuration, including:
- Zsh shell configuration with plugins, history tuning, fuzzy-finding and Python helpers
- A Catppuccin Mocha desktop theme applied consistently across GTK 3/4, Qt
- Sway configuration split into modular files with custom keybinds, bar, rules and styling
- Neovim configuration using Lua, Lazy, Treesitter, LSP and a full plugin setup
- Kitty terminal configuration with a large theme collection and a current theme
- Extra configs for GTK, Qt, TUI tools (yazi, fastfetch, calcure, bat, eza, cliphist, i3status-rust)
- Systemd user services for background daemons (idle/lock, clipboard, theming, sync, etc.)
The goal is to provide an opinionated but reusable starting point for an Arch/Linux tiling window manager environment.
---
## Required packages
This setup assumes the following tools are installed (Arch package names):
- [swayfx](https://github.com/WillPower3309/swayfx) (Wayland tiling window manager)
- [swaylock-effects](https://github.com/mortie/swaylock-effects)
- [swayidle](https://github.com/swaywm/swayidle)
- [wofi](https://github.com/SimplyCEO/wofi) (Wayland application launcher)
- [i3status-rust](https://github.com/greshake/i3status-rust?tab=readme-ov-file) (status bar blocks)
- [kitty](https://github.com/kovidgoyal/kitty) (terminal emulator)
- [neovim](https://github.com/neovim/neovim) (text editor)
- [zsh](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH) (shell)
- [starship](https://github.com/starship/starship) (prompt)
- [fzf](https://github.com/junegunn/fzf) (fuzzy finder)
- [fd](https://github.com/sharkdp/fd) (fast file search, used by fzf)
- [ripgrep](https://github.com/burntsushi/ripgrep) (rg, fast grep)
- [eza](https://github.com/eza-community/eza) (ls replacement)
- [fastfetch](https://github.com/fastfetch-cli/fastfetch) (system info on shell startup)
- [yazi](https://github.com/sxyazi/yazi) (terminal file manager)
- [bat](https://github.com/sharkdp/bat) (cat replacement with syntax highlighting)
- [cliphist](https://github.com/sentriz/cliphist) (Wayland clipboard manager)
- [calcure](https://github.com/anufrievroman/calcure) (terminal calendar and tasks)
- [zoxide](https://github.com/ajeetdsouza/zoxide) (smart cd)
- [pyenv](https://github.com/jorgenschaefer/pyvenv) (Python version manager)
- [git](https://github.com/git/git) (version control)
- [yay](https://github.com/jguer/yay) (AUR helper)
- [gtk3](https://github.com/gooroom/gtk3)
- [gtk4](https://gitlab.gnome.org/GNOME/gtk/)
- [catppuccin-gtk-theme-mocha](https://github.com/catppuccin/gtk)
- [catppuccin-cursors-mocha](https://github.com/catppuccin/cursors)
- [greetd](https://github.com/kennylevinsen/greetd)
- [tuigreet](https://github.com/apognu/tuigreet)
- [systemd](https://github.com/systemd/systemd) (init system, login manager and user services used for greetd, idle/lock, snapper, timers, etc.)
- [wlogout](https://github.com/ArtsyMacaw/wlogout) (Power tool for waybar)
- [waybar](https://github.com/Alexays/Waybar) (Status bar with MangoWM)
- [mangown](https://github.com/mangowm/mango) (Windows compositor)
---
## Zsh configuration
The Zsh configuration (`.zshrc`) is kept intentionally minimal and fast, while providing a modern shell experience.
Main features:
- Clean history settings (shared, deduplicated, trimmed) with a large history size
- Completion system using `compinit`, cached in `~/.cache/zsh`, with case-insensitive matching and colored completions
- Fastfetch banner on interactive shell startup if available
- Plugin setup without a plugin manager:
- `zsh-autosuggestions`
- `fast-syntax-highlighting`
- `fzf-tab`
- Prompt powered by `starship` with config in `~/.config/starship.toml`
- Incremental history search via `zsh-history-substring-search` (up/down arrows)
- Tight integration with `fzf` and `zoxide`:
- Custom `FZF_DEFAULT_COMMAND` and previews using `bat`
- Key bindings and completion from the system `fzf` scripts
- Convenient aliases:
- Navigation (`..`, `...`, `....`)
- Tools (`b` for yazi, `n` for neovim)
- Git shortcuts (`g`, `gs`, `ga`, `gc`, `gp`, `gl`)
- `eza` replacing `ls` with different presets
- `rg` as default grep-like search
- OSINT helpers:
- `whois-ip`, `geoip`, `myip`, `headers`, `dns`, `subdomains`, `shot`, `topcmd`
- Arch Linux workflow:
- `pacman` and `yay` aliases for install, upgrade, cleanup, orphan handling
- `journalctl` aliases (`jlog`, `jfollow`, `jboot`)
- Utility functions:
- `extract` for unpacking many archive formats
- `mkcd` to create and enter a directory
- `psgrep` to search running processes
- Python / pyenv helpers:
- pyenv initialization
- `va` to activate `venv/` or `.venv/`
- aliases for creating, destroying and managing virtualenvs and `requirements.txt`
---
## Themes: `.themes/Catppuccin-Mocha`
This directory contains the Catppuccin Mocha theme adapted for several environments:
- `cinnamon/`
Cinnamon desktop theme, including CSS and assets like checkboxes, toggles and window control icons.
- `gnome-shell/`
GNOME Shell theme with CSS files and SVG assets for shell elements (calendar, toggles, process animation).
- `gtk-2.0/`, `gtk-3.0/`, `gtk-4.0/`
GTK themes for legacy and modern GTK applications, including:
- `gtkrc` and `gtkrc.hidpi` for GTK2
- `gtk.css` and `gtk-dark.css` plus a large set of SVG assets for GTK3/4 widgets (checkboxes, radio buttons, sliders, etc.).
- `metacity-1/`
Window manager theme for Metacity-based environments.
- `plank/`
Theme for the Plank dock (`dock.theme`).
- `xfwm4/`
Theme configuration for XFWM4 window manager.
- `index.theme`
The theme index file used by the system to register Catppuccin Mocha.
This ensures a consistent Catppuccin Mocha look across desktops, apps and widgets.
---
## Yazi: `.config/yazi`
Configuration utilisateur reproductible pour une station Arch Linux sous
Wayland, déployée package par package avec GNU Stow.
</p>
<p align="center">
<img src=https://raw.githubusercontent.com/grayTerminal-sh/archasp/main/.assets/yazi.jpg width="600" height="400" alt="screenshot">
</img>
<code>Arch Linux</code> · <code>Sway</code> · <code>GNU Stow</code> ·
<code>systemd --user</code> · <code>Zsh</code>
</p>
Configuration for the Yazi terminal file manager:
- `yazi.toml`
Main Yazi configuration.
- `theme.toml`
Custom Yazi theme to match the overall colors.
- `keymap.toml`
Custom key mappings for navigation and actions.
- `package.toml`
Package metadata for the configuration.
- `flavors/tokyo-night.yazi/`
Additional theme flavor based on Tokyo Night, with its own README, flavor definition and preview.
---
## Wofi: `.config/wofi`
Configuration for Wofi, a Wayland application launcher and cliphist manager:
- `config`
Main Wofi settings (mode, matching, behavior).
- `style.css`
CSS styling to match the Catppuccin-like look.
- `wifi`
Script or configuration used to manage Wi-Fi selection via Wofi.
---
## Starship: `.config/starship.toml`
<p align="center">
<img src=https://raw.githubusercontent.com/grayTerminal-sh/archasp/main/.assets/starship.jpg width="600" height="400" alt="screenshot">
</img>
<a href="#overview">Overview</a> ·
<a href="#desktop-stack">Desktop</a> ·
<a href="#shell-stack">Shell</a> ·
<a href="#repository-layout">Layout</a> ·
<a href="#deployment">Deployment</a> ·
<a href="#rebuilding-archasp">Rebuild</a>
</p>
Prompt configuration for the Starship prompt, referenced from `.zshrc`.
It defines the segments, colors and layout of the prompt to integrate visually with the rest of the setup.
<a id="overview"></a>
---
## ✦ Overview
## Sway: `.config/sway`
Ce dépôt contient la couche **utilisateur** d'ArchASP : session graphique,
applications terminal, shell, scripts personnels et unités systemd user. La
couche **système/root** est volontairement séparée.
Sway configuration is split into multiple modular files for clarity:
| Dépôt | Responsabilité |
| --- | --- |
| **`.dotfiles`** | Sway, Kitty, Neovim, Zsh, scripts, thèmes et services utilisateur |
| **[`arch-system`](https://git.labfytools.com/fy59/arch-system)** | Installation Arch, boot, stockage, réseau, paquets, `/etc` et helpers root |
- `config`
Main Sway configuration file that typically includes the others.
- `autostart.conf`
Applications and services launched automatically when Sway starts.
- `bar.conf`
Status bar configuration, including integration with `i3status-rust`.
- `bind.conf`
Keybindings for window management, launching applications, workspaces, etc.
- `input.conf`
Input configuration (keyboard, touchpad, etc.).
- `rules.conf`
Window rules (floating windows, specific workspaces, etc.).
- `style.conf`, `swayfx.conf`, `tty-style.conf`
Visual tweaks, SwayFX configuration and TTY-like styling.
- `catppuccin-mocha`
Theme-related configuration for Sway using the Catppuccin Mocha palette.
- `i3status.toml`
Configuration file for `i3status-rust` used in the bar.
- `assets/screen.jpg`
Screenshot or background asset.
- `scripts/`
Helper scripts:
- `cliphist-wofi-img` to integrate clipboard history with Wofi and images
- `inactive-windows-transparency.py` for window transparency effects
- `README.md`
Local documentation for the Sway setup.
Cette séparation évite de mêler état personnel et administration système. Le
dépôt reste néanmoins spécifique à la machine : sorties Sway, périphériques,
chemins sous `/home/fy59` et projets externes doivent être relus avant un
déploiement ailleurs.
---
<a id="desktop-stack"></a>
## Qt: `.config/qt5ct` and `.config/qt6ct`
## ✦ Desktop Stack
Qt theming configuration using `qt5ct` and `qt6ct`:
- `colors/catppuccin-mocha-lavender.conf`
Qt colour scheme matching the Catppuccin Mocha palette.
- `qss/`
Extra styling via Qt Style Sheets.
- `qt5ct.conf`, `qt6ct.conf`
Main Qt configuration files for both Qt5 and Qt6, aligning fonts, colors and style.
---
## Neovim: `.config/nvim`
<p align="center">
<img src=https://raw.githubusercontent.com/grayTerminal-sh/archasp/main/.assets/nvim.jpg width="600" height="400" alt="screenshot">
</img>
</p>
Neovim configuration built in Lua with a modern plugin stack:
- `init.lua`
Entry point that sets up Neovim and loads modules.
- `lua/config/`
Core configuration:
- `lazy.lua` for the Lazy plugin manager
- `maps.lua` for key mappings
- `markdown.lua` for markdown-related settings
- `lua/plugins/`
Plugin configuration files, one per plugin or group:
- `bufferline.lua`
- `catppuccin.lua`
- `cmp.lua`
- `colorscheme.lua`
- `filebrowser.lua`
- `gitsign.lua`
- `lsp.lua`
- `mini-icons.lua`
- `mini_map.lua`
- `neowiki.lua`
- `nvim-autopair.lua`
- `outline.lua`
- `render-markdown.lua`
- `starter.lua`
- `neo-tree.lua`
- `telescope.lua`
- `treesitter.lua`
- `ui.lua`
- `vim-fugitive.lua`
- `witch-key.lua` (which-key style helper)
- `nvim-tree.lua.old` (old configuration kept for reference)
- `lazy-lock.json`
Lockfile for Lazy to pin exact plugin versions.
- `assets/`
Screenshots and images for documentation (`nvim-starter.*`, `screen.jpg`).
- `LICENSE.md`, `readme.md`
Local documentation and license for the Neovim configuration.
This setup gives a modern, IDE-like Neovim experience with LSP, Treesitter, file browsing, git integration, markdown rendering and more.
---
## Kitty: `.config/kitty`
Kitty terminal configuration and themes:
<p align="center">
<img src=https://raw.githubusercontent.com/grayTerminal-sh/archasp/main/.assets/kitty.jpg width="600" height="400" alt="screenshot">
</img>
</p>
- `kitty.conf`
Main Kitty configuration (fonts, window behavior, keybindings, etc.).
- `current-theme.conf`
Includes or defines the currently active theme.
- `kitty-themes/`
A full copy of the kitty-themes collection:
- `LICENSE.md`, `README.md`, `CONTRIBUTING.md`
- `themes/*.conf`
Hundreds of ready-to-use color schemes (Solarized, Dracula, Gruvbox, Monokai variants, Catppuccin-like themes, etc.).
This allows instant switching between many color schemes while defaulting to a Catppuccin-style dark theme.
---
## Snapper
Snapper is used here to manage Btrfs snapshots for the root filesystem.
Its main configuration for this setup lives in /etc/snapper/configs/root, where snapshot limits and cleanup rules are defined.
Together with grub-btrfs, this configuration is integrated into GRUB so that the created snapshots appear as additional boot entries in the GRUB menu and can be selected directly at startup.
---
## wiki
This wiki is my personal cybersecurity knowledge base.
It centralizes course notes, lab write‑ups and reference material for networking, blue team and red team topics, so I can grow a coherent skill set over time instead of scattered notes.
The structure is intentionally simple: foundations first, then focused sections for tools and defensive/offensive techniques, plus dedicated reference indexes to quickly jump back to key resources when needed.
All my notes live in a Neovim‑driven wiki.
From a terminal session, I just launch:
```shell
nvim
```
and use
```
<leader>ww
```
to open my main index page, then navigate through Markdown links like a lightweight personal documentation site.
---
## Other configs
Additional directories complete the environment:
- `.config/i3status-rust/`
Used by the Sway bar via `i3status.toml` (config content is referenced from Sway’s side).
<p align="center">
<img src=https://raw.githubusercontent.com/grayTerminal-sh/archasp/main/.assets/i3s.jpg width="600" height="400" alt="screenshot">
</img>
</p>
- `.config/gtk-3.0/` and `.config/gtk-4.0/`
GTK settings and overrides for applications using GTK3/GTK4 (bookmarks, settings backups, etc.).
- `.config/fastfetch/config.jsonc`
Fastfetch configuration controlling system summary display in the terminal.
<p align="center">
<img src=https://raw.githubusercontent.com/grayTerminal-sh/archasp/main/.assets/fastfetch.jpg width="600" height="400" alt="screenshot">
</img>
</p>
- `.config/eza/catppuccin-mocha-lavender.yml`
eza color theme file tuned to match Catppuccin Mocha.
<p align="center">
<img src=https://raw.githubusercontent.com/grayTerminal-sh/archasp/main/.assets/eza.jpg width="600" height="400" alt="screenshot">
</img>
</p>
- `.config/cliphist/config`
Configuration for cliphist clipboard manager.
- `.config/calcure/`
Calcure TUI calendar and task manager configuration:
- `config.ini`
- `events.csv`
- `tasks.csv`
- `info.log`
- `.config/bat/themes/Catppuccin Mocha.tmTheme`
Bat syntax highlighting theme, again using Catppuccin Mocha.
<p align="center">
<img src=https://raw.githubusercontent.com/grayTerminal-sh/archasp/main/.assets/bat.jpg width="600" height="400" alt="screenshot">
</img>
</p>
---
## Installation (on existing system)
### YAY install
```shell
sudo pacman -S stow git base-devel
cd /tmp
git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si
```text
greetd
└─ tuigreet
└─ UWSM
└─ Sway
├─ Swaybar ── i3status-rs
├─ Mako notifications
├─ Wofi launcher
├─ Swaylock verrouillage
├─ Cliphist historique du presse-papiers
└─ Kitty terminal
```
### Git clone & themes install
| Fonction | Composant canonique |
| --- | --- |
| Session | `greetd → tuigreet → uwsm start default → sway.desktop` |
| Compositor | Sway / SwayFX |
| Barre | Swaybar avec i3status-rs |
| Notifications | Mako |
| Launcher | Wofi |
| Verrouillage et idle | Swaylock + swayidle |
| Presse-papiers | wl-clipboard + Cliphist |
| Terminal | Kitty |
| Profils d'énergie | TLP via l'interface utilisateur `tlpctl` |
```shell
yay -S catppuccin-cursors-mocha catppuccin-gtk-theme-mocha && git clone https://github.com/grayTerminal-sh/archasp.git
`uwsm/.config/uwsm/default-id` sélectionne `sway.desktop`. La copie de
référence de greetd se trouve dans `.assets/greetd/config.toml`; son
installation sous `/etc/greetd` appartient à `arch-system`.
<a id="shell-stack"></a>
## ✦ Shell Stack
```text
Zsh
├─ Starship
├─ Atuin
├─ FZF
├─ Zoxide
├─ Eza
├─ Bat
└─ Yazi
```
### Move dotfiles
`.zprofile` démarre la session graphique via UWSM lorsque celui-ci autorise un
démarrage. `.zshenv` publie le socket de l'agent SSH utilisateur. L'historique,
les bases et la clé Atuin restent strictement locaux et hors Git.
```shell
mkdir ~/.dotfiles &&\
mv ~/archasp/* ~/.dotfiles &&\
rm -r ~/archasp
<a id="repository-layout"></a>
## ✦ Repository Layout
Chaque répertoire de premier niveau, hors `.assets` et `.git`, est un package
GNU Stow indépendant. Son arborescence reproduit le chemin attendu depuis
`$HOME`.
```text
.dotfiles/
├── sway/.config/sway/ → ~/.config/sway/
├── i3status-rust/.config/ → ~/.config/i3status-rust/
├── kitty/.config/kitty/ → ~/.config/kitty/
├── nvim/.config/nvim/ → ~/.config/nvim/
├── systemd/.config/systemd/user/ → ~/.config/systemd/user/
├── bin/.local/bin/ → ~/.local/bin/
├── zsh/.zshrc → ~/.zshrc
├── zsh/.zprofile → ~/.zprofile
└── .assets/ inventaires et références, non déployés
```
### Config backup
### Packages principaux
```shell
cd &&\
mkdir ~/.config/config_backup &&\
mv ~/.config/bat ~/.config/config_backup &&\
mv ~/.config/btop ~/.config/config_backup &&\
mv ~/.config/calcure ~/.config/config_backup &&\
mv ~/.config/cliphist ~/.config/config_backup &&\
mv ~/.config/eza ~/.config/config_backup &&\
mv ~/.config/fastfetch ~/.config/config_backup &&\
mv ~/.config/gtk-3.0 ~/.config/config_backup &&\
mv ~/.config/gtk-4.O ~/.config/config_backup &&\
mv ~/.config/icons ~/.config/config_backup &&\
mv ~/.config/kitty ~/.config/config_backup &&\
mv ~/.config/mango ~/.config/mango_backup &&\
mv ~/.config/nvim ~/.config/config_backup &&\
mv ~/.config/qt5ct ~/.config/config_backup &&\
mv ~/.config/qt6ct ~/.config/config_backup &&\
mv ~/.config/starship ~/.config/config_backup &&\
mv ~/.config/sway ~/.config/config_backup &&\
mv ~/.config/swaylock ~/.config/config_backup &&\
mv ~/.config/swaync ~/.config/config_backup &&\
mv ~/.config/themes ~/.config/config_backup &&\
mv ~/.config/wofi ~/.config/config_backup &&\
mv ~/.config/yazi ~/.config/config_backup &&\
mv ~/.config/zsh ~/.config/config_backup
```
| Groupe | Packages Stow |
| --- | --- |
| Desktop | `sway`, `swaylock`, `mako`, `wofi`, `cliphist`, `i3status-rust` |
| Terminal et shell | `kitty`, `zsh`, `starship`, `atuin`, `fzf`, `eza`, `bat`, `yazi` |
| Développement | `nvim`, `tmux`, `opencode`, `bin` |
| Services | `systemd`, `uwsm` |
| Apparence | `gtk-3.0`, `gtklock`, `qt5ct`, `qt6ct`, `themes`, `icons`, `wallpapers` |
| Outils | `btop`, `fastfetch`, `hyprwhspr`, `ytmusic-tui` |
### Stow dotfiles & install packages
Les thèmes, icônes et wallpapers sont volontairement versionnés. Les
exécutables issus de projets externes restent hors Git même lorsqu'un script
ou une unité user les utilise.
```shell
cd ~/.dotfiles
```
### Sous-modules
```shell
stow *\
```
Les plugins Zsh et Tmux sont épinglés par Git :
```shell
yay -S \
mangowm-git swayfx wofi i3status-rust kitty neovim zsh \
starship fzf fd ripgrep eza fastfetch yazi bat \
cliphist calcure zoxide pyenv git \
gtk3 gtk4 catppuccin-gtk-theme-mocha \
catppuccin-cursors-mocha swaylock-effects \
swayidle greetd greetd-tuigreet grim slurp \
snapper brtfs-progs grub-snapper
```
| Intégration | Chemin |
| --- | --- |
| Fast Syntax Highlighting | `zsh/.zsh/plugins/fast-syntax-highlighting` |
| FZF Tab | `zsh/.zsh/plugins/fzf-tab` |
| Zsh Autosuggestions | `zsh/.zsh/plugins/zsh-autosuggestions` |
| Catppuccin Tmux | `tmux/.config/tmux/plugins/catppuccin/tmux` |
### greetd-tuigreet config
<a id="deployment"></a>
---
## ✦ Deployment
```toml
# /etc/greetd/config.toml
### Prérequis
[terminal]
# The VT to run the greeter on. Can be "next", "current" or a number
# designating the VT.
vt = 1
- Git ;
- GNU Stow ;
- les paquets décrits dans `.assets` ;
- une sauvegarde des fichiers existants qui pourraient entrer en conflit.
# The default session, also known as the greeter.
[default_session]
command = "tuigreet tuigreet --time --greeting 'Welcome to ArchASP' --theme 'container=brightblack;border=magenta;text=white;greet=brightmagenta;prompt=cyan;input=brightcyan;time=brightyellow;error=red;button=green;action=green' --cmd mango --power-shutdown 'shutdown -h now' --power-reboot 'reboot'"
# The user to run the command as. The privileges this user must have depends
# on the greeter. A graphical greeter may for example require the user to be
# in the `video` group.
user = "greetd"
```
---
```desktop
# /usr/share/wayland-sessions/mango.desktop
[Desktop Entry]
Encoding=UTF-8
Name=Mango
DesktopNames=mango;wlroots
Comment=mango WM
Exec=/home/fy59/.local/bin/mango-session.sh
Icon=mango
Type=Application
```
---
```sh
# /etc/greetd/sway-config
exec "regreet; swaymsg exit"
include /etc/sway/config.d/*
### Keyboard (modify it)
input * {
xkb_layout fr
xkb_variant oss
}
### Touchpad
input "type:touchpad" {
tap enabled
tap_button_map lrm
}
```
---
```sh
#!/bin/sh
# .local/bin/mango-session.sh
systemctl --user start wayland-session.target
exec mango
```
### Clone
```bash
chmod +x ~/.local/bin/mango-session.sh
git clone --recurse-submodules \
ssh://git@git.labfytools.com:2223/fy59/Dotfiles_ArchAP.git \
"$HOME/.dotfiles"
cd "$HOME/.dotfiles"
git submodule update --init --recursive
```
---
### Dry-run Stow
```shell
sudo systemctl enable --now greetd.service
Construire la liste des packages à partir des répertoires de premier niveau :
```bash
mapfile -t packages < <(
find . -mindepth 1 -maxdepth 1 -type d \
! -name .git ! -name .assets -printf '%f\n' | sort
)
stow --no --verbose=2 --target="$HOME" "${packages[@]}"
```
### Snapper config
Examiner tout conflit avant le déploiement réel :
```shell
sudo snapper -c root create-config /\
sudo snapper -c root create-config /@
```bash
stow --verbose=2 --target="$HOME" "${packages[@]}"
```
```shell
sudo systemctl enable --now grub-btrfsd.service grub-btrfs.path
> Stow reçoit les **noms des packages**. La racine du dépôt n'est pas un
> package : ne pas utiliser `stow .`.
<a id="package-inventory"></a>
## ✦ Package Inventory
| Fichier | Source | Contenu |
| --- | --- | --- |
| `.assets/pkglist-pacman.txt` | `pacman -Qqen` | Paquets officiels explicitement installés |
| `.assets/pkglist-aur.txt` | `pacman -Qqem` | Paquets foreign/AUR explicitement installés |
| `.assets/enabled-services.txt` | systemd système | Services système activés |
| `.assets/enabled-system-aux-units.txt` | systemd système | Timers, sockets et paths activés |
| `.assets/enabled-user-aux-units.txt` | systemd user | Timers, sockets et paths utilisateur activés |
| `.assets/external-tools.md` | inventaire manuel | Cargo, npm, builds locaux, projets et helpers `/usr/local` |
Ces fichiers sont des instantanés vérifiables, pas un installateur. Les paquets
AUR, outils Cargo/npm et builds locaux doivent être restaurés séparément.
<a id="services"></a>
## ✦ Services
Le package `systemd` contient les unités utilisateur ainsi que leurs liens
d'activation relatifs. Il couvre notamment Cliphist, swayidle, GNOME Keyring,
l'agent SSH, les notifications de batterie et les intégrations Trainlog,
Lardon et Arch Sentinel.
Après une modification :
```bash
systemctl --user daemon-reload
systemd-analyze --user verify ~/.config/systemd/user/*.service
```
```shell
sudo grub-mkconfig -o /boot/grub/grub.cfg
Certaines unités lancent du code externe au dépôt. Leurs chemins et
dépendances sont documentés dans `.assets/external-tools.md`. Les services
système et toute modification de `/etc` restent sous la responsabilité
d'`arch-system`.
<a id="secrets"></a>
## ✦ Secrets
Ce dépôt n'a pas vocation à contenir :
- clés SSH, GPG, WireGuard ou Atuin ;
- `.netrc`, mots de passe, tokens, cookies ou credentials ;
- configurations privées Rclone, GitHub CLI ou Nextcloud ;
- bases de données, historiques shell ou états applicatifs personnels.
Les ignorer dans le HEAD ne suffit pas : un secret déjà commité doit être
renouvelé, puis supprimé de tout l'historique avant publication.
<a id="rebuilding-archasp"></a>
## ✦ Rebuilding ArchASP
```text
┌──────────────────────────────────────────────────────┐
│ arch-system │
│ Arch · boot · stockage · réseau · paquets · /etc │
└──────────────────────────┬───────────────────────────┘
│ socle système prêt
▼
┌──────────────────────────────────────────────────────┐
│ .dotfiles │
│ Stow · session · shell · scripts · systemd user │
└──────────────────────────┬───────────────────────────┘
│ restaurations externes
▼
┌──────────────────────────────────────────────────────┐
│ AUR · Cargo/npm · projets locaux · secrets · données│
└──────────────────────────────────────────────────────┘
```
```config
# /etc/snapper/configs/root
# subvolume to snapshot
SUBVOLUME="/"
# filesystem type
FSTYPE="btrfs"
Ordre de reconstruction recommandé :
1. restaurer la couche système avec `arch-system` ;
2. installer Git et GNU Stow ;
3. cloner ce dépôt avec ses sous-modules ;
4. restaurer les paquets officiels puis examiner les paquets AUR ;
5. effectuer le dry-run et déployer les packages Stow ;
6. restaurer les outils Cargo/npm et les projets locaux nécessaires ;
7. restaurer les secrets et données applicatives depuis une sauvegarde sûre ;
8. valider puis activer les unités systemd voulues.
# btrfs qgroup for space aware cleanup algorithms
QGROUP=""
Le dépôt ne reconstruit pas seul les projets sous `Documents`, OpenMVS local,
les helpers `/usr/local`, les secrets, les bases applicatives ou les réglages
matériels propres à la machine.
<a id="repository-mirrors"></a>
# fraction or absolute size of the filesystems space the snapshots may use
SPACE_LIMIT="0.5"
## ✦ Repository Mirrors
# fraction or absolute size of the filesystems space that should be free
FREE_LIMIT="0.2"
| Rôle | Hébergement | URL |
| --- | --- | --- |
| Upstream principal | Forgejo | `ssh://git@git.labfytools.com:2223/fy59/Dotfiles_ArchAP.git` |
| Miroir public | GitHub | `https://github.com/labfytools/Dotfiles_ArchAP` |
Le fetch d'`origin` reste attaché à Forgejo. Ses URLs de push publient vers
Forgejo et GitHub afin qu'un `git push origin main` maintienne les deux copies.
# users and groups allowed to work with config
ALLOW_USERS=""
ALLOW_GROUPS=""
<a id="license"></a>
# sync users and groups from ALLOW_USERS and ALLOW_GROUPS to .snapshots
# directory
SYNC_ACL="no"
## ✦ License
# start comparing pre- and post-snapshot in background after creating
# post-snapshot
BACKGROUND_COMPARISON="yes"
# run daily number cleanup
NUMBER_CLEANUP="yes"
# limit for number cleanup
NUMBER_MIN_AGE="3600"
NUMBER_LIMIT="5"
NUMBER_LIMIT_IMPORTANT="1"
# create hourly snapshots
TIMELINE_CREATE="yes"
# cleanup hourly snapshots after some time
TIMELINE_CLEANUP="yes"
# limits for timeline cleanup
TIMELINE_MIN_AGE="3600"
TIMELINE_LIMIT_HOURLY="0"
TIMELINE_LIMIT_DAILY="3"
TIMELINE_LIMIT_WEEKLY="0"
TIMELINE_LIMIT_MONTHLY="0"
TIMELINE_LIMIT_QUARTERLY="0"
TIMELINE_LIMIT_YEARLY="0"
# cleanup empty pre-post-pairs
EMPTY_PRE_POST_CLEANUP="yes"
# limits for empty pre-post-pair cleanup
EMPTY_PRE_POST_MIN_AGE="3600"
```
Aucune licence n'est actuellement déclarée pour ce dépôt.

View file

@ -0,0 +1,371 @@
## Base directory for Atuin data files (databases, keys, session, etc.)
## All data file paths default to being relative to this directory.
## linux/mac: ~/.local/share/atuin (or XDG_DATA_HOME/atuin)
## windows: %USERPROFILE%/.local/share/atuin
# data_dir = "~/.local/share/atuin"
## where to store your database, default is your system data directory
## linux/mac: ~/.local/share/atuin/history.db
## windows: %USERPROFILE%/.local/share/atuin/history.db
# db_path = "~/.history.db"
## where to store your encryption key, default is your system data directory
## linux/mac: ~/.local/share/atuin/key
## windows: %USERPROFILE%/.local/share/atuin/key
# key_path = "~/.key"
## where to store your auth session token, default is your system data directory
## linux/mac: ~/.local/share/atuin/session
## windows: %USERPROFILE%/.local/share/atuin/session
# session_path = "~/.session"
## date format used, either "us" or "uk"
# dialect = "us"
## default timezone to use when displaying time
## either "l", "local" to use the system's current local timezone, or an offset
## from UTC in the format of "<+|->H[H][:M[M][:S[S]]]"
## for example: "+9", "-05", "+03:30", "-01:23:45", etc.
# timezone = "local"
## enable or disable automatic sync
# auto_sync = true
## enable or disable automatic update checks
# update_check = true
## address of the sync server
# sync_address = "https://api.atuin.sh"
## how often to sync history. note that this is only triggered when a command
## is ran, so sync intervals may well be longer
## set it to 0 to sync after every command
# sync_frequency = "10m"
## which search mode to use
## possible values: prefix, fulltext, fuzzy, skim
search_mode = "prefix"
## which filter mode to use by default
## possible values: "global", "host", "session", "session-preload", "directory", "workspace"
## consider using search.filters to customize the enablement and order of filter modes
filter_mode = "global"
## With workspace filtering enabled, Atuin will filter for commands executed
## in any directory within a git repository tree (default: false).
##
## To use workspace mode by default when available, set this to true and
## set filter_mode to "workspace" or leave it unspecified and
## set search.filters to include "workspace" before other filter modes.
# workspaces = false
## which filter mode to use when atuin is invoked from a shell up-key binding
## the accepted values are identical to those of "filter_mode"
## leave unspecified to use same mode set in "filter_mode"
# filter_mode_shell_up_key_binding = "global"
## which search mode to use when atuin is invoked from a shell up-key binding
## the accepted values are identical to those of "search_mode"
## leave unspecified to use same mode set in "search_mode"
search_mode_shell_up_key_binding = "prefix"
## which style to use
## possible values: auto, full, compact
style = "compact"
## the maximum number of lines the interface should take up
## set it to 0 to always go full screen
inline_height = 20
## the maximum number of lines the interface should take up
## when atuin is invoked from a shell up-key binding
## the accepted values are identical to those of "inline_height"
# inline_height_shell_up_key_binding = 0
## Invert the UI - put the search bar at the top , Default to `false`
# invert = false
## enable or disable showing a preview of the selected command
## useful when the command is longer than the terminal width and is cut off
show_preview = true
## what to do when the escape key is pressed when searching
## possible values: return-original, return-query
# exit_mode = "return-original"
## possible values: emacs, subl
# word_jump_mode = "emacs"
## characters that count as a part of a word
# word_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
## number of context lines to show when scrolling by pages
# scroll_context_lines = 1
## use ctrl instead of alt as the shortcut modifier key for numerical UI shortcuts
## alt-0 .. alt-9
# ctrl_n_shortcuts = false
## Show numeric shortcuts (1..9) beside list items in the TUI
## set to false to hide the moving numbers if you find them distracting
# show_numeric_shortcuts = true
## default history list format - can also be specified with the --format arg
# history_format = "{time}\t{command}\t{duration}"
## Defaults to true. If enabled, strip trailing spaces and tabs from commands
## before saving them to history.
## Escaped trailing spaces (for example `printf foo\\ `) are preserved.
# strip_trailing_whitespace = true
## prevent commands matching any of these regexes from being written to history.
## Note that these regular expressions are unanchored, i.e. if they don't start
## with ^ or end with $, they'll match anywhere in the command.
## For details on the supported regular expression syntax, see
## https://docs.rs/regex/latest/regex/#syntax
# history_filter = [
# "^secret-cmd",
# "^innocuous-cmd .*--secret=.+",
# ]
## prevent commands run with cwd matching any of these regexes from being written
## to history. Note that these regular expressions are unanchored, i.e. if they don't
## start with ^ or end with $, they'll match anywhere in CWD.
## For details on the supported regular expression syntax, see
## https://docs.rs/regex/latest/regex/#syntax
# cwd_filter = [
# "^/very/secret/area",
# ]
## Configure the maximum height of the preview to show.
## Useful when you have long scripts in your history that you want to distinguish
## by more than the first few lines.
# max_preview_height = 4
## Configure whether or not to show the help row, which includes the current Atuin
## version (and whether an update is available), a keymap hint, and the total
## amount of commands in your history.
# show_help = true
## Configure whether or not to show tabs for search and inspect
# show_tabs = true
## Configure whether or not the tabs row may be auto-hidden, which includes the current Atuin
## tab, such as Search or Inspector, and other tabs you may wish to see. This will
## only be hidden if there are fewer than this count of lines available, and does not affect the use
## of keyboard shortcuts to switch tab. 0 to never auto-hide, default is 8 (lines).
## This is ignored except in `compact` mode.
# auto_hide_height = 8
## Defaults to true. This matches history against a set of default regex, and will not save it if we get a match. Defaults include
## 1. AWS key id
## 2. Github pat (old and new)
## 3. Slack oauth tokens (bot, user)
## 4. Slack webhooks
## 5. Stripe live/test keys
# secrets_filter = true
## Defaults to true. If enabled, upon hitting enter Atuin will immediately execute the command,
## whereas tab will put the command in the prompt for editing.
## If set to false, both enter and tab will place the command in the prompt for editing.
## This applies for new installs. Old installs will keep the old behaviour unless configured otherwise.
enter_accept = true
## Defaults to false. If enabled, when triggered after &&, || or |, Atuin will complete commands to chain rather than replace the current line.
# command_chaining = false
## Defaults to "emacs". This specifies the keymap on the startup of `atuin
## search`. If this is set to "auto", the startup keymap mode in the Atuin
## search is automatically selected based on the shell's keymap where the
## keybinding is defined. If this is set to "emacs", "vim-insert", or
## "vim-normal", the startup keymap mode in the Atuin search is forced to be
## the specified one.
# keymap_mode = "auto"
## Cursor style in each keymap mode. If specified, the cursor style is changed
## in entering the cursor shape. Available values are "default" and
## "{blink,steady}-{block,underline,bar}".
# keymap_cursor = { emacs = "blink-block", vim_insert = "blink-block", vim_normal = "steady-block" }
# network_connect_timeout = 5
# network_timeout = 5
## Timeout (in seconds) for acquiring a local database connection (sqlite)
# local_timeout = 5
## Set this to true and Atuin will minimize motion in the UI - timers will not update live, etc.
## Alternatively, set env NO_MOTION=true
# prefers_reduced_motion = false
[stats]
## Set commands where we should consider the subcommand for statistics. Eg, kubectl get vs just kubectl
# common_subcommands = [
# "apt",
# "cargo",
# "composer",
# "dnf",
# "docker",
# "dotnet",
# "git",
# "go",
# "ip",
# "jj",
# "kubectl",
# "nix",
# "nmcli",
# "npm",
# "pecl",
# "pnpm",
# "podman",
# "port",
# "systemctl",
# "tmux",
# "yarn",
# ]
## Set commands that should be totally stripped and ignored from stats
# common_prefix = ["sudo"]
## Set commands that will be completely ignored from stats
# ignored_commands = [
# "cd",
# "ls",
# "vi"
# ]
[keys]
# Defaults to true. If disabled, using the up/down key won't exit the TUI when scrolled past the first/last entry.
# scroll_exits = true
# Defaults to true. The left arrow key will exit the TUI when scrolling before the first character
# exit_past_line_start = true
# Defaults to true. The right arrow key performs the same functionality as Tab and copies the selected line to the command line to be modified.
# accept_past_line_end = true
# Defaults to false. The left arrow key performs the same functionality as Tab and copies the selected line to the command line to be modified.
# accept_past_line_start = false
# Defaults to false. The backspace key performs the same functionality as Tab and copies the selected line to the command line to be modified when at the start of the line.
# accept_with_backspace = false
[sync]
# Enable sync v2 by default
# This ensures that sync v2 is enabled for new installs only
# In a later release it will become the default across the board
records = true
[preview]
## which preview strategy to use to calculate the preview height (respects max_preview_height).
## possible values: auto, static
## auto: length of the selected command.
## static: length of the longest command stored in the history.
## fixed: use max_preview_height as fixed height.
# strategy = "auto"
[daemon]
## Enables using the daemon to sync.
# enabled = false
## Automatically start and manage the daemon when needed.
## Not compatible with `systemd_socket = true`.
# autostart = false
## How often the daemon should sync in seconds
# sync_frequency = 300
## The path to the unix socket used by the daemon (on unix systems)
## linux/mac: ~/.local/share/atuin/atuin.sock
## windows: Not Supported
# socket_path = "~/.local/share/atuin/atuin.sock"
## The daemon pidfile used for lifecycle management.
## Defaults to the Atuin data directory.
# pidfile_path = "~/.local/share/atuin/atuin-daemon.pid"
## Use systemd socket activation rather than opening the given path (the path must still be correct for the client)
## linux: false
## mac/windows: Not Supported
# systemd_socket = false
## The port that should be used for TCP on non unix systems
# tcp_port = 8889
# [theme]
## Color theme to use for rendering in the terminal.
## There are some built-in themes, including the base theme ("default"),
## "autumn" and "marine". You can add your own themes to the "./themes" subdirectory of your
## Atuin config (or ATUIN_THEME_DIR, if provided) as TOML files whose keys should be one or
## more of AlertInfo, AlertWarn, AlertError, Annotation, Base, Guidance, Important, and
## the string values as lowercase entries from this list:
## https://ogeon.github.io/docs/palette/master/palette/named/index.html
## If you provide a custom theme file, it should be called "NAME.toml" and the theme below
## should be the stem, i.e. `theme = "NAME"` for your chosen NAME.
name = "catppuccin"
## Whether the theme manager should output normal or extra information to help fix themes.
## Boolean, true or false. If unset, left up to the theme manager.
# debug = true
[search]
## The list of enabled filter modes, in order of priority.
## The "workspace" mode is skipped when not in a workspace or workspaces = false.
## Default filter mode can be overridden with the filter_mode setting.
# filters = [ "global", "host", "session", "session-preload", "workspace", "directory" ]
[tmux]
## Enable using atuin with tmux popup (requires tmux >= 3.2)
## When enabled and running inside tmux, Atuin will use a popup window for interactive search.
## Set to false to disable the popup.
## This can also be controlled with the ATUIN_TMUX_POPUP environment variable.
## Note: The tmux popup is currently supported in zsh, bash, and fish shells. This currently doesn't work with iTerm native tmux integration.
# enabled = false
## Width of the tmux popup window
## Can be a percentage, or integer (e.g. "100" means 100 characters wide)
# width = "80%"
## Height of the tmux popup window
## Can be a percentage, or integer (e.g. "100" means 100 lines tall)
# height = "60%"
[ui]
## Columns to display in the interactive search, from left to right.
## The selection indicator (" > ") is always shown first implicitly.
##
## Each column can be specified as a simple string (uses default width)
## or as an object with type, width, and expand:
## { type = "directory", width = 30, expand = true }
##
## Available column types (with default widths):
## duration (5) - Command execution duration (e.g., "123ms")
## time (8) - Relative time since execution (e.g., "59m ago")
## datetime (16) - Absolute timestamp (e.g., "2025-01-22 14:35")
## directory (20) - Working directory (truncated if too long)
## host (15) - Hostname where command was run
## user (10) - Username
## exit (3) - Exit code (colored by success/failure)
## command (*) - The command itself (expands by default)
##
## The "expand" option (default: true for command, false for others) makes a
## column fill remaining space. Only one column should have expand = true.
##
## Default:
# columns = ["duration", "time", "command"]
##
## Examples:
##
## Minimal - more space for commands:
# columns = ["duration", "command"]
##
## With wider directory column:
# columns = ["duration", { type = "directory", width = 30 }, "command"]
##
## Show host for multi-machine sync users:
# columns = ["duration", "time", "host", "command"]
##
## Show exit codes prominently:
# columns = ["exit", "duration", "command"]
##
## Make directory expand instead of command:
# columns = ["duration", "time", { type = "directory", expand = true }, { type = "command", expand = false }]

View file

@ -0,0 +1,12 @@
[theme]
name = "catppuccin"
[colors]
AlertInfo = "#a6e3a1"
AlertWarn = "#fab387"
AlertError = "#f38ba8"
Annotation = "#b4befe"
Base = "#cdd6f4"
Guidance = "#9399b2"
Important = "#f38ba8"
Title = "#b4befe"

124
bin/.local/bin/aurinstall Executable file
View file

@ -0,0 +1,124 @@
#!/bin/bash
set -euo pipefail
AUR_DIR="$HOME/Aur"
EDITOR_CMD="${EDITOR:-nvim}"
ASK_EDIT=0
FORCE_EDIT=0
DOWNLOAD_ONLY=0
while getopts ":eEd" opt; do
case "$opt" in
e) ASK_EDIT=1 ;;
E) FORCE_EDIT=1 ;;
d) DOWNLOAD_ONLY=1 ;;
*)
echo "Usage: aurinstall [-e|-E] [-d] <paquet1> [paquet2 ...]"
exit 1
;;
esac
done
shift $((OPTIND - 1))
RESET='\033[0m'
BOLD='\033[1m'
RED='\033[1;31m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
CYAN='\033[1;36m'
info() { printf "${BLUE}==>${RESET} %s\n" "$1"; }
ok() { printf "${GREEN}==>${RESET} %s\n" "$1"; }
warn() { printf "${YELLOW}==>${RESET} %s\n" "$1"; }
error() { printf "${RED}==>${RESET} %s\n" "$1"; }
section() { printf "\n${CYAN}${BOLD}>>> %s${RESET}\n" "$1"; }
if [[ $# -lt 1 ]]; then
error "Usage: aurinstall [-e|-E] [-d] <paquet1> [paquet2 ...]"
exit 1
fi
mkdir -p "$AUR_DIR"
if [[ "$DOWNLOAD_ONLY" -eq 0 ]]; then
sudo -v || exit 1
while true; do
sudo -n true || exit
sleep 30
done 2>/dev/null &
SUDO_LOOP_PID=$!
trap 'kill "$SUDO_LOOP_PID" 2>/dev/null' EXIT INT TERM
fi
for pkg in "$@" ; do
section "$pkg"
cd "$AUR_DIR" || exit 1
if [[ "$DOWNLOAD_ONLY" -eq 0 ]] && pacman -Q "$pkg" >/dev/null 2>&1; then
warn "$pkg est déjà installé, on passe."
continue
fi
if [[ -d "$pkg/.git" ]]; then
warn "$pkg déjà cloné, utilisation du dossier existant"
cd "$pkg" || { error "Impossible d'entrer dans $pkg"; continue; }
pull_output=$(git pull --ff-only 2>&1) || {
error "git pull failed pour $pkg"
cd "$AUR_DIR" || exit 1
continue
}
printf "%s\n" "$pull_output"
else
info "Clonage de $pkg"
if ! git clone "https://aur.archlinux.org/${pkg}.git"; then
error "Impossible de cloner $pkg"
continue
fi
cd "$pkg" || { error "Impossible d'entrer dans $pkg"; continue; }
fi
if [[ "$FORCE_EDIT" -eq 1 ]]; then
info "Ouverture de PKGBUILD et .SRCINFO dans $EDITOR_CMD"
"$EDITOR_CMD" PKGBUILD .SRCINFO
elif [[ "$ASK_EDIT" -eq 1 || "$DOWNLOAD_ONLY" -eq 1 ]]; then
printf "${YELLOW}Éditer PKGBUILD/.SRCINFO pour %s ? [y/N] ${RESET}" "$pkg"
read -r ans
if [[ "$ans" == "y" || "$ans" == "Y" ]]; then
"$EDITOR_CMD" PKGBUILD .SRCINFO
fi
fi
if [[ "$DOWNLOAD_ONLY" -eq 1 ]]; then
ok "$pkg prêt pour audit dans $AUR_DIR/$pkg"
continue
fi
info "Vérifie au minimum source=(), checksums, prepare()/build()/package() et validpgpkeys si présents"
rm -f ./*.pkg.tar ./*.pkg.tar.*
if ! makepkg -sf; then
error "Build failed pour $pkg"
cd "$AUR_DIR" || exit 1
continue
fi
pkgfile=$(find . -maxdepth 1 -type f \( -name '*.pkg.tar' -o -name '*.pkg.tar.*' \) ! -name '*.sig' | head -n1 || true)
echo "DEBUG: pkgfile='$pkgfile'"
if [[ -z "$pkgfile" ]]; then
error "Aucun paquet généré pour $pkg"
cd "$AUR_DIR" || exit 1
continue
fi
info "Installation de $pkgfile"
if ! sudo pacman -U --noconfirm "$pkgfile"; then
error "Install failed pour $pkg"
cd "$AUR_DIR" || exit 1
continue
fi
ok "$pkg installé avec succès"
done

59
bin/.local/bin/aurremove Executable file
View file

@ -0,0 +1,59 @@
#!/bin/bash
set -euo pipefail
AUR_DIR="$HOME/Aur"
RESET='\033[0m'
BOLD='\033[1m'
RED='\033[1;31m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
CYAN='\033[1;36m'
info() { printf "${BLUE}==>${RESET} %s\n" "$1"; }
ok() { printf "${GREEN}==>${RESET} %s\n" "$1"; }
warn() { printf "${YELLOW}==>${RESET} %s\n" "$1"; }
error() { printf "${RED}==>${RESET} %s\n" "$1"; }
section() { printf "\n${CYAN}${BOLD}>>> %s${RESET}\n" "$1"; }
if [[ $# -lt 1 ]]; then
error "Usage: aurremove <paquet1> [paquet2 ...]"
exit 1
fi
sudo -v || exit 1
while true; do
sudo -n true || exit
sleep 30
done 2>/dev/null &
SUDO_LOOP_PID=$!
trap 'kill "$SUDO_LOOP_PID" 2>/dev/null' EXIT INT TERM
for pkg in "$@" ; do
section "$pkg"
if ! pacman -Q "$pkg" >/dev/null 2>&1; then
warn "$pkg n'est pas installé"
continue
fi
info "Désinstallation de $pkg"
if ! sudo pacman -Rns "$pkg"; then
error "Échec de suppression pour $pkg"
continue
fi
ok "$pkg supprimé du système"
if [[ -d "$AUR_DIR/$pkg" ]]; then
printf "${YELLOW}Supprimer aussi le dossier %s ? [y/N] ${RESET}" "$AUR_DIR/$pkg"
read -r ans
if [[ "$ans" == "y" || "$ans" == "Y" ]]; then
rm -rf "$AUR_DIR/$pkg"
ok "Dossier $AUR_DIR/$pkg supprimé"
else
warn "Dossier conservé : $AUR_DIR/$pkg"
fi
fi
done

155
bin/.local/bin/aursearch Executable file
View file

@ -0,0 +1,155 @@
#!/bin/bash
set -euo pipefail
RPC_BASE="https://aur.archlinux.org/rpc/?v=5"
SEARCH_BY="name-desc"
DETAILS=0
QUIET=0
LIMIT=10
SORT_BY="popularity"
RESET='\033[0m'
BOLD='\033[1m'
RED='\033[1;31m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
CYAN='\033[1;36m'
info() { printf "${BLUE}==>${RESET} %s\n" "$1"; }
ok() { printf "${GREEN}==>${RESET} %s\n" "$1"; }
warn() { printf "${YELLOW}==>${RESET} %s\n" "$1"; }
error() { printf "${RED}==>${RESET} %s\n" "$1" >&2; }
section() { printf "\n${CYAN}${BOLD}>>> %s${RESET}\n" "$1"; }
die() {
error "$1"
exit 1
}
usage() {
cat <<'USAGE'
Usage: aursearch [options] <recherche>
Options:
-n rechercher seulement dans le nom
-m rechercher par mainteneur
-d afficher les détails complets
-q afficher seulement les noms des paquets
-l N limiter le nombre de résultats (défaut : 10)
-s mode trier par : popularity | votes | name | modified | submitted
-h afficher cette aide
Exemples:
aursearch proton
aursearch -n sway
aursearch -m Eschwartz
aursearch -d rustdesk
aursearch -q -l 20 python
USAGE
}
require_cmd() {
command -v "$1" >/dev/null 2>&1 || die "Commande requise manquante : $1"
}
while getopts ":nmdql:s:h" opt; do
case "$opt" in
n) SEARCH_BY="name" ;;
m) SEARCH_BY="maintainer" ;;
d) DETAILS=1 ;;
q) QUIET=1 ;;
l)
[[ "$OPTARG" =~ ^[0-9]+$ ]] || die "-l attend un entier"
LIMIT="$OPTARG"
;;
s)
case "$OPTARG" in
popularity|votes|name|modified|submitted) SORT_BY="$OPTARG" ;;
*) die "Mode de tri invalide : $OPTARG" ;;
esac
;;
h)
usage
exit 0
;;
*)
usage
exit 1
;;
esac
done
shift $((OPTIND - 1))
[[ $# -ge 1 ]] || {
usage
exit 1
}
require_cmd curl
require_cmd jq
query="$*"
encoded_query=$(printf '%s' "$query" | jq -sRr @uri)
url="${RPC_BASE}&type=search&by=${SEARCH_BY}&arg=${encoded_query}"
json=$(curl -fsSL "$url") || die "Échec de requête vers l'AUR"
count=$(jq '.resultcount // 0' <<< "$json")
if (( count == 0 )); then
warn "Aucun résultat pour : $query"
exit 0
fi
sorted=$(jq --arg sort "$SORT_BY" '
.results
| if $sort == "name" then sort_by(.Name)
elif $sort == "votes" then sort_by(.NumVotes // 0) | reverse
elif $sort == "submitted" then sort_by(.FirstSubmitted // 0) | reverse
elif $sort == "modified" then sort_by(.LastModified // 0) | reverse
else sort_by(.Popularity // 0) | reverse
end
' <<< "$json")
limited=$(jq --argjson limit "$LIMIT" '.[0:$limit]' <<< "$sorted")
shown=$(jq 'length' <<< "$limited")
if (( QUIET == 1 )); then
jq -r '.[].Name' <<< "$limited"
exit 0
fi
info "$count résultat(s) trouvé(s), affichage de $shown entrée(s)"
if (( DETAILS == 1 )); then
jq -r '
.[] |
"\(.Name)\n" +
" Version : \(.Version // "?")\n" +
" Votes : \(.NumVotes // 0)\n" +
" Popularité : \(.Popularity // 0)\n" +
" Mainteneur : \(.Maintainer // "orphan")\n" +
" Soumis le : \(.FirstSubmitted // 0 | strftime("%Y-%m-%d %H:%M"))\n" +
" Modifié le : \(.LastModified // 0 | strftime("%Y-%m-%d %H:%M"))\n" +
" Hors date : \(if .OutOfDate then "yes" else "no" end)\n" +
" URL AUR : https://aur.archlinux.org/packages/\(.Name)\n" +
" Description : \(.Description // "")\n"
' <<< "$limited"
else
jq -r '
.[] |
[
.Name,
(.Version // "?"),
((.NumVotes // 0) | tostring),
((.Popularity // 0) | tostring),
(.Maintainer // "orphan")
] | @tsv
' <<< "$limited" | awk 'BEGIN {
printf "%-32s %-22s %-8s %-12s %-20s\n", "Nom", "Version", "Votes", "Popularité", "Mainteneur";
printf "%-32s %-22s %-8s %-12s %-20s\n", "--------------------------------", "----------------------", "--------", "------------", "--------------------";
}
{
printf "%-32s %-22s %-8s %-12s %-20s\n", $1, $2, $3, $4, $5;
}'
fi

194
bin/.local/bin/aurupdate Executable file
View file

@ -0,0 +1,194 @@
#!/bin/bash
set -euo pipefail
AUR_DIR="${AUR_DIR:-$HOME/Aur}"
END_UPDATE="Mis à jour avec succès ;p."
SYSTEM_NAME="$(cat /etc/hostname 2>/dev/null || echo "unknown")"
RESET='\033[0m'
BOLD='\033[1m'
RED='\033[1;31m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
CYAN='\033[1;36m'
info() { printf "${BLUE}==>${RESET} %s\n" "$1"; }
ok() { printf "${GREEN}==>${RESET} %s\n" "$1"; }
warn() { printf "${YELLOW}==>${RESET} %s\n" "$1"; }
error() { printf "${RED}==>${RESET} %s\n" "$1"; }
section() { printf "\n${CYAN}${BOLD}>>> %s${RESET}\n" "$1"; }
[[ -d "$AUR_DIR" ]] || {
error "Répertoire AUR introuvable : $AUR_DIR"
exit 1
}
sudo -v || exit 1
while true; do
sudo -n true || exit
sleep 30
done 2>/dev/null &
SUDO_LOOP_PID=$!
trap 'kill "$SUDO_LOOP_PID" 2>/dev/null' EXIT INT TERM
cd "$AUR_DIR" || exit 1
shopt -s nullglob
repos=(*/)
shopt -u nullglob
if [[ ${#repos[@]} -eq 0 ]]; then
warn "Aucun dépôt AUR dans $AUR_DIR"
exit 0
fi
declare -a outdated_repos=()
audit_repo() {
local repo="$1"
local branch upstream local_rev remote_rev base_rev
cd "$AUR_DIR/$repo" || return 1
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
error "$repo n'est pas un dépôt git valide"
return 1
fi
branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null || true)
[[ -n "$branch" ]] || {
warn "$repo : HEAD détachée, ignoré"
return 1
}
if ! git remote update --prune >/dev/null 2>&1; then
error "Impossible de contacter le remote pour $repo"
return 1
fi
upstream=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null || true)
[[ -n "$upstream" ]] || upstream="origin/$branch"
local_rev=$(git rev-parse HEAD 2>/dev/null || true)
remote_rev=$(git rev-parse "$upstream" 2>/dev/null || true)
base_rev=$(git merge-base HEAD "$upstream" 2>/dev/null || true)
if [[ -z "$remote_rev" || -z "$local_rev" || -z "$base_rev" ]]; then
error "Impossible de comparer $repo avec $upstream"
return 1
fi
if [[ "$local_rev" == "$remote_rev" ]]; then
return 1
fi
if [[ "$local_rev" != "$base_rev" ]]; then
warn "$repo a des commits locaux non poussés, ignoré"
return 1
fi
outdated_repos+=("$repo")
return 0
}
ask_update() {
local repo="$1"
while true; do
printf "${YELLOW}Mettre à jour %s ? [y/N/q] ${RESET}" "$repo"
read -r ans
case "$ans" in
y|Y) return 0 ;;
n|N|"") return 1 ;;
q|Q) return 2 ;;
*) warn "Réponse invalide, utilise y, n ou q" ;;
esac
done
}
info "Scan des dépôts AUR..."
for d in "${repos[@]}"; do
repo="${d%/}"
audit_repo "$repo" || true
done
if [[ ${#outdated_repos[@]} -eq 0 ]]; then
ok "Aucune mise à jour AUR détectée"
exit 0
fi
section "Mises à jour détectées"
for repo in "${outdated_repos[@]}"; do
cd "$AUR_DIR/$repo" || continue
upstream=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null || echo "origin/HEAD")
printf "${YELLOW}- %s${RESET}\n" "$repo"
git --no-pager log --oneline --decorate HEAD.."$upstream" | sed 's/^/ /'
done
declare -a selected_repos=()
section "Sélection"
for repo in "${outdated_repos[@]}"; do
if ask_update "$repo"; then
selected_repos+=("$repo")
else
rc=$?
if [[ $rc -eq 2 ]]; then
warn "Sélection interrompue"
break
fi
fi
done
if [[ ${#selected_repos[@]} -eq 0 ]]; then
warn "Aucun paquet sélectionné"
exit 0
fi
section "Paquets sélectionnés"
for repo in "${selected_repos[@]}"; do
printf "${GREEN}- %s${RESET}\n" "$repo"
done
for repo in "${selected_repos[@]}"; do
cd "$AUR_DIR/$repo" || continue
section "$repo"
info "Récupération des changements"
if ! git pull --ff-only; then
error "git pull failed for $repo"
continue
fi
info "Vérifie au minimum PKGBUILD, sources, checksums et fonctions de build"
rm -f ./*.pkg.tar.*
if ! makepkg -sf; then
error "Build failed for $repo"
continue
fi
pkgfile=$(find . -maxdepth 1 -type f -name '*.pkg.tar.*' ! -name '*.sig' | head -n1 || true)
if [[ -z "$pkgfile" ]]; then
error "Aucun paquet trouvé pour $repo"
continue
fi
info "Installation de $pkgfile"
if ! sudo pacman -U --noconfirm "$pkgfile"; then
error "Install failed for $repo"
continue
fi
ok "$repo installé avec succès"
done
printf "\n"
if command -v figlet >/dev/null 2>&1; then
figlet -f slant "$SYSTEM_NAME" | while IFS= read -r line; do
printf "${GREEN}%s${RESET}\n" "$line"
done
printf "${GREEN}%s${RESET}\n" "$END_UPDATE"
else
printf "${GREEN}%s : %s${RESET}\n" "$SYSTEM_NAME" "$END_UPDATE"
fi

39
bin/.local/bin/batlimit Executable file
View file

@ -0,0 +1,39 @@
#!/usr/bin/env bash
set -euo pipefail
readonly BATTERY="BAT1"
readonly THRESHOLD_FILE="/sys/class/power_supply/${BATTERY}/charge_control_end_threshold"
readonly CAPACITY_FILE="/sys/class/power_supply/${BATTERY}/capacity"
readonly STATUS_FILE="/sys/class/power_supply/${BATTERY}/status"
readonly HELPER="/usr/local/sbin/batlimit-set"
if [[ ! -e "$THRESHOLD_FILE" ]]; then
echo "Erreur : aucun seuil de charge disponible pour ${BATTERY}."
exit 1
fi
read -rp "Niveau max de charge voulu [%] : " STOP
if [[ ! "$STOP" =~ ^[0-9]+$ ]]; then
echo "Erreur : entre un nombre entier."
exit 1
fi
if (( STOP < 40 || STOP > 100 )); then
echo "Erreur : choisis une valeur entre 40 et 100."
exit 1
fi
if ! sudo -n "$HELPER" "$STOP"; then
echo "Erreur : impossible d’appliquer le seuil."
exit 1
fi
CURRENT_THRESHOLD=$(<"$THRESHOLD_FILE")
echo
echo "Batterie : ${BATTERY}"
echo "Seuil appliqué : ${CURRENT_THRESHOLD}%"
echo "Charge actuelle : $(<"$CAPACITY_FILE")%"
echo "État : $(<"$STATUS_FILE")"

View file

@ -0,0 +1,20 @@
#!/bin/sh
BAT="BAT1"
THRESHOLD=20
STATE_FILE="${XDG_RUNTIME_DIR:-/tmp}/battery-low-notified"
capacity=$(cat /sys/class/power_supply/$BAT/capacity 2>/dev/null)
bat_status=$(cat /sys/class/power_supply/$BAT/status 2>/dev/null)
[ -z "$capacity" ] && exit 0
[ -z "$bat_status" ] && exit 0
if [ "$bat_status" = "Discharging" ] && [ "$capacity" -le "$THRESHOLD" ]; then
if [ ! -f "$STATE_FILE" ]; then
notify-send -u critical -t 10000 "Batterie faible" "Batterie à ${capacity}% — branche le chargeur."
touch "$STATE_FILE"
fi
else
rm -f "$STATE_FILE"
fi

View file

@ -0,0 +1,4 @@
#!/bin/sh
wl-paste --type text --watch cliphist store &
wl-paste --type image --watch cliphist store &
wait

10
bin/.local/bin/colmap-amd Executable file
View file

@ -0,0 +1,10 @@
#!/bin/sh
# Évite un rendu logiciel Mesa accidentel.
unset LIBGL_ALWAYS_SOFTWARE
unset MESA_LOADER_DRIVER_OVERRIDE
# Utilise Xwayland/GLX pour le contexte OpenGL de SIFTGPU.
export QT_QPA_PLATFORM=xcb
exec colmap "$@"

21
bin/.local/bin/dcnvim Executable file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -e
PROJECT_DIR="$(pwd)"
devcontainer up --workspace-folder "$PROJECT_DIR" >/dev/null
CONTAINER_ID="$(
docker ps -q \
--filter "label=devcontainer.local_folder=$PROJECT_DIR"
)"
if [ -z "$CONTAINER_ID" ]; then
echo "Aucun conteneur trouvé"
exit 1
fi
export DEVCONTAINER_ID="$CONTAINER_ID"
nvim "$@"

33
bin/.local/bin/firefox-scribd Executable file
View file

@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -euo pipefail
readonly PROFILE="$HOME/.mozilla/firefox-scribd"
readonly URL="${1:-https://fr.scribd.com/}"
case "$URL" in
http://scribd.com/*|https://scribd.com/*|\
http://*.scribd.com/*|https://*.scribd.com/*)
;;
*)
notify-send \
"Firefox Scribd" \
"URL refusée : ce lanceur accepte uniquement scribd.com"
exit 2
;;
esac
mkdir -p "$PROFILE"
exec systemd-run \
--user \
--scope \
--quiet \
--unit="firefox-scribd-$(date +%s)-$$" \
--slice=app-graphical.slice \
--property=MemoryMax=8G \
--property=MemorySwapMax=0 \
/usr/bin/firefox \
--no-remote \
--profile "$PROFILE" \
--new-window "$URL"

3
bin/.local/bin/i3s_restart Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
pkill i3status-rs
i3status-rs ~/.config/i3status-rust/config.toml &

10
bin/.local/bin/kitty-ssh-add.sh Executable file
View file

@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -e
cd "$HOME"
# lance ssh-add dans ce kitty
ssh-add "$HOME/.ssh/id_ed25519-admin"
# quand c'est fini, on lance un shell interactif normal
exec zsh

58
bin/.local/bin/nextcloud-sync Executable file
View file

@ -0,0 +1,58 @@
#!/usr/bin/env bash
set -u
readonly LOCAL_DIR="$HOME/Documents"
readonly SERVER_URL="https://cloud.labfytools.com"
readonly LOG_DIR="$HOME/.local/state/nextcloud"
readonly LOG_FILE="$LOG_DIR/sync.log"
readonly LOCK_FILE="${XDG_RUNTIME_DIR:-/tmp}/nextcloud-sync.lock"
mkdir -p "$LOG_DIR"
# Empêche deux synchronisations simultanées.
exec 9>"$LOCK_FILE"
if ! flock -n 9; then
notify-send \
-a "Nextcloud" \
-u normal \
"Nextcloud" \
"Une synchronisation est déjà en cours."
exit 0
fi
notify-send \
-a "Nextcloud" \
-u low \
"Nextcloud" \
"Synchronisation en cours…"
{
printf '\n=== %s ===\n' "$(date --iso-8601=seconds)"
} >> "$LOG_FILE"
if nextcloudcmd \
-n \
"$LOCAL_DIR" \
"$SERVER_URL" >> "$LOG_FILE" 2>&1
then
notify-send \
-a "Nextcloud" \
-u normal \
"Nextcloud" \
"✅ Synchronisation réussie."
printf 'Résultat : réussite\n' >> "$LOG_FILE"
else
status=$?
notify-send \
-a "Nextcloud" \
-u critical \
"Nextcloud" \
"❌ Synchronisation échouée — code ${status}."
printf 'Résultat : échec, code %d\n' "$status" >> "$LOG_FILE"
exit "$status"
fi

108
bin/.local/bin/opencode-away Executable file
View file

@ -0,0 +1,108 @@
#!/usr/bin/env bash
set -u
usage() {
printf '%s\n' 'usage: opencode-away [--check] [opencode arguments...]'
}
require_command() {
command -v "$1" >/dev/null 2>&1 || {
printf 'opencode-away: required command not found: %s\n' "$1" >&2
return 1
}
}
if [[ ${1-} == --help ]]; then
usage
exit 0
fi
check_only=0
if [[ ${1-} == --check ]]; then
check_only=1
shift
fi
require_command opencode || exit 127
require_command systemd-inhibit || exit 127
require_command git || exit 127
require_command ps || exit 127
require_command kill || exit 127
if [[ $(systemd-inhibit --help 2>&1) != *handle-lid-switch* ]]; then
printf '%s\n' 'opencode-away: systemd-inhibit lacks handle-lid-switch' >&2
exit 3
fi
if ! git rev-parse --show-toplevel >/dev/null 2>&1; then
printf '%s\n' 'opencode-away: run this command inside a Git worktree' >&2
exit 2
fi
if ((check_only)); then
printf '%s\n' 'OpenCode away mode check: OK'
printf 'repository: %s\n' "$(git rev-parse --show-toplevel)"
printf 'opencode: %s\n' "$(command -v opencode)"
printf 'systemd-inhibit: %s\n' "$(command -v systemd-inhibit)"
exit 0
fi
declare -a suspended_pids=()
cleanup_done=0
restore_swayidle() {
local pid
((cleanup_done)) && return 0
cleanup_done=1
for pid in "${suspended_pids[@]}"; do
if kill -0 "$pid" 2>/dev/null &&
[[ $(ps -o comm= -p "$pid" 2>/dev/null) == swayidle ]]; then
kill -CONT "$pid" 2>/dev/null || true
fi
done
if ((${#suspended_pids[@]})); then
printf '%s\n' 'swayidle restored'
fi
}
trap restore_swayidle EXIT
while read -r pid state; do
[[ $pid =~ ^[0-9]+$ ]] || continue
[[ $state == T* ]] && continue
if kill -STOP "$pid" 2>/dev/null; then
suspended_pids+=("$pid")
fi
done < <(ps -C swayidle -o pid=,stat= 2>/dev/null)
printf '%s\n' 'OpenCode away mode'
printf '%s\n' 'sleep inhibited'
printf '%s\n' 'lid switch inhibited'
if ((${#suspended_pids[@]})); then
printf 'swayidle suspended:'
printf ' %s' "${suspended_pids[@]}"
printf '\n'
else
printf '%s\n' 'swayidle suspended: none active'
fi
export LARDON_OPENCODE_LONG_RUN=1
if [[ -n ${OPENCODE_AWAY_COMMAND-} ]]; then
child_command=(bash -c "$OPENCODE_AWAY_COMMAND")
else
child_command=(opencode --auto "$@")
fi
systemd-inhibit \
--what=sleep:idle:handle-lid-switch \
--who='OpenCode Long Run' \
--why='Autonomous Lardon3D development ticket' \
--mode=block \
"${child_command[@]}"
child_status=$?
restore_swayidle
exit "$child_status"

91
bin/.local/bin/pi-dev Executable file
View file

@ -0,0 +1,91 @@
#!/usr/bin/env bash
set -Eeuo pipefail
SWAYIDLE_MODE="none"
declare -a SWAYIDLE_CMD=()
cleanup() {
rc=$?
trap - EXIT INT TERM HUP
printf '\n[pi-dev] Arrêt de la session...\n'
# Restaurer swayidle exactement selon son mode d'origine.
case "$SWAYIDLE_MODE" in
systemd)
printf '[pi-dev] Redémarrage de swayidle.service...\n'
systemctl --user start swayidle.service || true
;;
process)
if ((${#SWAYIDLE_CMD[@]})); then
printf '[pi-dev] Redémarrage de swayidle...\n'
nohup "${SWAYIDLE_CMD[@]}" \
>/dev/null 2>&1 &
fi
;;
esac
printf '[pi-dev] Session restaurée.\n'
exit "$rc"
}
trap cleanup EXIT INT TERM HUP
#
# 1. Neutraliser swayidle
#
if systemctl --user is-active --quiet swayidle.service 2>/dev/null; then
SWAYIDLE_MODE="systemd"
printf '[pi-dev] Neutralisation de swayidle.service...\n'
systemctl --user stop swayidle.service
else
SWAYIDLE_PID="$(pgrep -xo swayidle || true)"
if [[ -n "$SWAYIDLE_PID" ]]; then
SWAYIDLE_MODE="process"
# Sauvegarder exactement argv avant d'arrêter swayidle.
mapfile -d '' SWAYIDLE_CMD \
< "/proc/$SWAYIDLE_PID/cmdline"
printf '[pi-dev] Neutralisation de swayidle (PID %s)...\n' \
"$SWAYIDLE_PID"
kill "$SWAYIDLE_PID"
# Attendre sa disparition.
for _ in {1..20}; do
kill -0 "$SWAYIDLE_PID" 2>/dev/null || break
sleep 0.05
done
fi
fi
#
# 2. Lancer Pi avec inhibition de la fermeture du capot
#
# L'inhibitor existe uniquement pendant que Pi tourne.
#
printf '[pi-dev] swayidle neutralisé.\n'
printf '[pi-dev] Veille fermeture du capot neutralisée.\n'
printf '[pi-dev] Lancement de Pi / OpenRouter.\n\n'
systemd-inhibit \
--what=handle-lid-switch \
--who="pi-dev" \
--why="Session de développement Pi / Lardon3D" \
--mode=block \
pi "$@"

697
bin/.local/bin/scan3d Executable file
View file

@ -0,0 +1,697 @@
#!/usr/bin/env bash
set -Eeuo pipefail
# scan3d
# Pipeline interactif :
# photos -> pré-tri -> COLMAP -> OpenMVS -> maillage texturé
#
# Les photos originales ne sont jamais déplacées ni supprimées.
# Le script s'arrête avant l'ouverture de MeshLab.
OPENMVS_BIN="${OPENMVS_BIN:-$HOME/Applications/openmvs-2.4.0/openmvs}"
OPENMVS_IMAGE="${OPENMVS_IMAGE:-localhost/openmvs:2.4.0}"
THREADS="${SCAN3D_THREADS:-4}"
SEQUENTIAL_OVERLAP="${SCAN3D_OVERLAP:-20}"
RESOLUTION_LEVEL="${SCAN3D_RESOLUTION_LEVEL:-3}"
NUMBER_VIEWS="${SCAN3D_NUMBER_VIEWS:-4}"
MIN_FREE_GIB="${SCAN3D_MIN_FREE_GIB:-45}"
USE_GPU=1
KEEP_DEPTHMAPS=0
RED=$'\e[31m'
GREEN=$'\e[32m'
YELLOW=$'\e[33m'
BLUE=$'\e[34m'
BOLD=$'\e[1m'
RESET=$'\e[0m'
log() {
printf '\n%s%s==>%s %s\n' "$BOLD" "$BLUE" "$RESET" "$*"
}
ok() {
printf '%s✓%s %s\n' "$GREEN" "$RESET" "$*"
}
warn() {
printf '%s⚠%s %s\n' "$YELLOW" "$RESET" "$*" >&2
}
die() {
printf '%sERREUR:%s %s\n' "$RED" "$RESET" "$*" >&2
exit 1
}
cleanup_on_error() {
local code=$?
if (( code != 0 )); then
printf '\n%sLe pipeline s’est arrêté avec le code %d.%s\n' \
"$RED" "$code" "$RESET" >&2
printf 'Relance simplement %sscan3d%s pour reprendre à la dernière étape validée.\n' \
"$BOLD" "$RESET" >&2
fi
}
trap cleanup_on_error EXIT
prompt_default() {
local prompt="$1"
local default="$2"
local answer
read -r -e -p "$prompt [$default] : " answer
printf '%s' "${answer:-$default}"
}
yes_no() {
local prompt="$1"
local default="${2:-n}"
local answer suffix
if [[ "$default" == "o" ]]; then
suffix="[O/n]"
else
suffix="[o/N]"
fi
while true; do
read -r -p "$prompt $suffix : " answer
answer="${answer:-$default}"
case "${answer,,}" in
o|oui|y|yes) return 0 ;;
n|non|no) return 1 ;;
*) printf 'Réponds par o ou n.\n' ;;
esac
done
}
require_command() {
command -v "$1" >/dev/null 2>&1 || die "commande introuvable : $1"
}
run_logged() {
local logfile="$1"
shift
mkdir -p "$(dirname "$logfile")"
"$@" 2>&1 | tee "$logfile"
}
natural_list() {
find "$@" -print0 | sort -zV
}
choose_source_dir() {
local default_dir="$PWD"
local entered
while true; do
entered="$(prompt_default 'Dossier contenant les photos' "$default_dir")"
entered="${entered/#\~/$HOME}"
entered="$(realpath -m "$entered")"
if [[ -d "$entered" ]]; then
RAW_DIR="$entered"
return
fi
warn "Le dossier n’existe pas : $entered"
done
}
choose_categories() {
printf '\n%sQuelles photos utiliser pour la reconstruction ?%s\n' "$BOLD" "$RESET"
printf ' 1) Bonnes uniquement — recommandé\n'
printf ' 2) Bonnes + suspectes — plus complet, plus risqué\n'
printf ' 3) Toutes, y compris mauvaises — déconseillé\n'
local choice
while true; do
read -r -p 'Choix [1] : ' choice
choice="${choice:-1}"
case "$choice" in
1)
SELECTED_CATEGORIES=("bonnes")
CATEGORY_LABEL="bonnes"
return
;;
2)
SELECTED_CATEGORIES=("bonnes" "suspectes")
CATEGORY_LABEL="bonnes-suspectes"
return
;;
3)
SELECTED_CATEGORIES=("bonnes" "suspectes" "mauvaises")
CATEGORY_LABEL="toutes"
return
;;
*)
printf 'Choisis 1, 2 ou 3.\n'
;;
esac
done
}
write_tri_script() {
cat > "$TRI_PY" <<'PY'
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import csv
import re
import sys
from dataclasses import dataclass
from pathlib import Path
import cv2
import numpy as np
from PIL import Image
EXTENSIONS = {".jpg", ".jpeg", ".png", ".tif", ".tiff", ".webp"}
@dataclass
class Result:
path: Path
category: str
sharpness: float
white: float
black: float
brightness: float
reason: str
def natural_key(path: Path) -> list[object]:
return [
int(part) if part.isdigit() else part.lower()
for part in re.split(r"(\d+)", path.name)
]
def load_gray(path: Path) -> np.ndarray:
with Image.open(path) as source:
source = source.convert("L")
gray = np.asarray(source)
height, width = gray.shape
maximum_dimension = 1600
if max(width, height) > maximum_dimension:
scale = maximum_dimension / max(width, height)
gray = cv2.resize(
gray,
(
max(1, round(width * scale)),
max(1, round(height * scale)),
),
interpolation=cv2.INTER_AREA,
)
return gray
def analyze(path: Path) -> tuple[dict[str, float] | None, str]:
try:
gray = load_gray(path)
except Exception as error:
return None, f"illisible: {error}"
return {
"sharpness": float(cv2.Laplacian(gray, cv2.CV_64F).var()),
"white": float(np.count_nonzero(gray >= 250) / gray.size * 100),
"black": float(np.count_nonzero(gray <= 5) / gray.size * 100),
"brightness": float(gray.mean()),
}, ""
def classify(path: Path, metrics: dict[str, float] | None, error: str) -> Result:
if metrics is None:
return Result(path, "mauvaises", 0.0, 0.0, 0.0, 0.0, error)
sharpness = metrics["sharpness"]
white = metrics["white"]
black = metrics["black"]
brightness = metrics["brightness"]
reasons: list[str] = []
if sharpness < 100:
reasons.append("très floue")
elif sharpness < 170:
reasons.append("floue possible")
if white > 20:
reasons.append("très surexposée")
elif white > 8:
reasons.append("surexposition possible")
if black > 35:
reasons.append("très sombre")
elif black > 15:
reasons.append("ombres bouchées possibles")
if brightness > 225 or brightness < 25:
reasons.append("luminosité extrême")
severe = (
sharpness < 100
or white > 20
or black > 35
or brightness > 225
or brightness < 25
)
if severe:
category = "mauvaises"
elif reasons:
category = "suspectes"
else:
category = "bonnes"
return Result(
path,
category,
sharpness,
white,
black,
brightness,
"; ".join(reasons) or "ok",
)
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("images", type=Path)
parser.add_argument("--output", type=Path, required=True)
args = parser.parse_args()
images_dir = args.images.expanduser().resolve()
output_dir = args.output.expanduser().resolve()
excluded_roots = {
output_dir,
images_dir / "scan3d",
images_dir / "tri_resultat",
images_dir / "test_colmap",
images_dir / "colmap_complet",
}
images: list[Path] = []
for path in images_dir.rglob("*"):
if not path.is_file() or path.is_symlink():
continue
if path.suffix.lower() not in EXTENSIONS:
continue
if any(root == path or root in path.parents for root in excluded_roots):
continue
images.append(path)
images.sort(key=natural_key)
if not images:
print("Aucune image trouvée.", file=sys.stderr)
return 1
print(f"{len(images)} images trouvées.")
results: list[Result] = []
for index, path in enumerate(images, 1):
metrics, error = analyze(path)
results.append(classify(path, metrics, error))
print(
f"\rAnalyse {index}/{len(images)} : {path.name[:55]:55s}",
end="",
flush=True,
)
print()
output_dir.mkdir(parents=True, exist_ok=True)
for category in ("bonnes", "suspectes", "mauvaises"):
category_dir = output_dir / category
if category_dir.exists():
for child in category_dir.iterdir():
if child.is_symlink() or child.is_file():
child.unlink()
category_dir.mkdir(parents=True, exist_ok=True)
with (output_dir / "resultats.csv").open(
"w", encoding="utf-8", newline=""
) as csv_file:
writer = csv.writer(csv_file)
writer.writerow(
[
"fichier",
"categorie",
"netteté",
"blanc_pct",
"noir_pct",
"luminosité",
"raison",
]
)
counters = {"bonnes": 0, "suspectes": 0, "mauvaises": 0}
for result in results:
counters[result.category] += 1
link_name = f"{counters[result.category]:06d}_{result.path.name}"
link_path = output_dir / result.category / link_name
link_path.symlink_to(result.path.resolve())
writer.writerow(
[
str(result.path),
result.category,
f"{result.sharpness:.2f}",
f"{result.white:.2f}",
f"{result.black:.2f}",
f"{result.brightness:.2f}",
result.reason,
]
)
for category in ("bonnes", "suspectes", "mauvaises"):
count = sum(result.category == category for result in results)
print(f"{category}: {count}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
PY
}
podman_openmvs() {
podman run --rm \
-v "$OPENMVS_BIN:/openmvs:ro,Z" \
-v "$WORK_DIR:/data:Z" \
-w /data/openmvs \
"$OPENMVS_IMAGE" \
"$@"
}
printf '%s\n' "${BOLD}scan3d — pipeline photogrammétrique COLMAP + OpenMVS${RESET}"
require_command colmap
require_command podman
require_command /usr/bin/python
require_command realpath
require_command sort
require_command find
require_command sqlite3
/usr/bin/python - <<'PY' >/dev/null 2>&1 || die \
"Modules Python manquants. Installe : sudo pacman -S python-opencv python-numpy python-pillow"
import cv2
import numpy
from PIL import Image
PY
[[ -x "$OPENMVS_BIN/InterfaceCOLMAP" ]] ||
die "OpenMVS introuvable dans : $OPENMVS_BIN"
[[ -x "$OPENMVS_BIN/DensifyPointCloud" ]] ||
die "DensifyPointCloud introuvable dans : $OPENMVS_BIN"
podman image exists "$OPENMVS_IMAGE" ||
die "Image Podman absente : $OPENMVS_IMAGE"
choose_source_dir
PROJECT_ROOT="$RAW_DIR/scan3d"
TRI_DIR="$PROJECT_ROOT/tri"
TRI_PY="$PROJECT_ROOT/tri_photos.py"
mkdir -p "$PROJECT_ROOT"
write_tri_script
if [[ -f "$TRI_DIR/resultats.csv" ]]; then
if yes_no "Un tri existe déjà. Le réutiliser ?" o; then
ok "Tri existant conservé."
else
log "Nouveau tri des photos"
rm -rf "$TRI_DIR"
/usr/bin/python "$TRI_PY" "$RAW_DIR" --output "$TRI_DIR"
fi
else
log "Tri des photos"
/usr/bin/python "$TRI_PY" "$RAW_DIR" --output "$TRI_DIR"
fi
printf '\nRésultat du tri :\n'
for category in bonnes suspectes mauvaises; do
count="$(find "$TRI_DIR/$category" -maxdepth 1 -type l 2>/dev/null | wc -l)"
printf ' %-11s : %s\n' "$category" "$count"
done
choose_categories
WORK_DIR="$PROJECT_ROOT/projet-$CATEGORY_LABEL"
if [[ -d "$WORK_DIR" ]] && find "$WORK_DIR" -mindepth 1 -print -quit | grep -q .; then
printf '\nUn projet existe déjà : %s\n' "$WORK_DIR"
printf ' 1) Reprendre là où il s’est arrêté\n'
printf ' 2) Tout effacer et recommencer\n'
printf ' 3) Annuler\n'
while true; do
read -r -p 'Choix [1] : ' resume_choice
resume_choice="${resume_choice:-1}"
case "$resume_choice" in
1) break ;;
2)
rm -rf "$WORK_DIR"
break
;;
3) exit 0 ;;
*) printf 'Choisis 1, 2 ou 3.\n' ;;
esac
done
fi
mkdir -p "$WORK_DIR"/{images,sparse,logs,openmvs}
free_gib="$(df -Pk "$WORK_DIR" | awk 'NR==2 {printf "%d", $4/1024/1024}')"
printf '\nEspace libre : %s Gio\n' "$free_gib"
if (( free_gib < MIN_FREE_GIB )); then
warn "Moins de ${MIN_FREE_GIB} Gio libres."
yes_no "Continuer malgré le risque de remplir le disque ?" n ||
exit 1
fi
if yes_no "Conserver les cartes de profondeur après le résultat final ?" n; then
KEEP_DEPTHMAPS=1
fi
if yes_no "Utiliser la Radeon via OpenGL pour l’extraction et le matching ?" o; then
USE_GPU=1
else
USE_GPU=0
fi
log "Préparation des images sélectionnées"
rm -rf "$WORK_DIR/images"
mkdir -p "$WORK_DIR/images"
index=1
for category in "${SELECTED_CATEGORIES[@]}"; do
while IFS= read -r -d '' image; do
target="$(readlink -f "$image")"
[[ -f "$target" ]] || continue
extension="${target##*.}"
extension="${extension,,}"
printf -v output_name 'img_%07d.%s' "$index" "$extension"
ln -s "$target" "$WORK_DIR/images/$output_name"
((index++))
done < <(
find "$TRI_DIR/$category" -maxdepth 1 -type l -print0 | sort -zV
)
done
IMAGE_COUNT="$(find "$WORK_DIR/images" -maxdepth 1 -type l | wc -l)"
(( IMAGE_COUNT > 0 )) || die "Aucune image sélectionnée."
ok "$IMAGE_COUNT images préparées."
DATABASE="$WORK_DIR/database.db"
if [[ ! -f "$WORK_DIR/.features.done" ]]; then
log "COLMAP — extraction des caractéristiques"
rm -f "$DATABASE"
run_logged "$WORK_DIR/logs/01-features.log" \
colmap feature_extractor \
--database_path "$DATABASE" \
--image_path "$WORK_DIR/images" \
--ImageReader.single_camera 1 \
--ImageReader.camera_model SIMPLE_RADIAL \
--FeatureExtraction.use_gpu "$USE_GPU"
touch "$WORK_DIR/.features.done"
else
ok "Extraction déjà terminée."
fi
if [[ ! -f "$WORK_DIR/.matching.done" ]]; then
log "COLMAP — matching séquentiel"
run_logged "$WORK_DIR/logs/02-matching.log" \
colmap sequential_matcher \
--database_path "$DATABASE" \
--FeatureMatching.use_gpu "$USE_GPU" \
--SequentialMatching.overlap "$SEQUENTIAL_OVERLAP"
touch "$WORK_DIR/.matching.done"
else
ok "Matching déjà terminé."
fi
if [[ ! -f "$WORK_DIR/.mapper.done" ]]; then
log "COLMAP — reconstruction clairsemée"
rm -rf "$WORK_DIR/sparse"
mkdir -p "$WORK_DIR/sparse"
run_logged "$WORK_DIR/logs/03-mapper.log" \
colmap mapper \
--database_path "$DATABASE" \
--image_path "$WORK_DIR/images" \
--output_path "$WORK_DIR/sparse"
touch "$WORK_DIR/.mapper.done"
else
ok "Reconstruction clairsemée déjà terminée."
fi
BEST_MODEL=""
BEST_REGISTERED=-1
while IFS= read -r model; do
analysis="$(colmap model_analyzer --path "$model" 2>&1 || true)"
registered="$(
awk -F': ' '/Registered images:/ {print $NF; exit}' <<<"$analysis" |
tr -dc '0-9'
)"
[[ -n "$registered" ]] || registered=0
printf '%s\n' "$analysis" > "$model/model-analysis.txt"
printf ' Modèle %-5s : %s images enregistrées\n' \
"$(basename "$model")" "$registered"
if (( registered > BEST_REGISTERED )); then
BEST_REGISTERED="$registered"
BEST_MODEL="$model"
fi
done < <(
find "$WORK_DIR/sparse" -mindepth 1 -maxdepth 1 -type d | sort -V
)
[[ -n "$BEST_MODEL" ]] || die "COLMAP n’a produit aucun modèle."
printf '%s\n' "$BEST_MODEL" > "$WORK_DIR/best-model.txt"
ok "Meilleur modèle : $BEST_REGISTERED/$IMAGE_COUNT images."
DENSE_DIR="$WORK_DIR/dense"
if [[ ! -f "$WORK_DIR/.undistort.done" ]]; then
log "COLMAP — correction des images"
rm -rf "$DENSE_DIR"
run_logged "$WORK_DIR/logs/04-undistort.log" \
colmap image_undistorter \
--image_path "$WORK_DIR/images" \
--input_path "$BEST_MODEL" \
--output_path "$DENSE_DIR" \
--output_type COLMAP
touch "$WORK_DIR/.undistort.done"
else
ok "Images déjà corrigées."
fi
if [[ ! -f "$WORK_DIR/openmvs/scene.mvs" ]]; then
log "OpenMVS — import du modèle COLMAP"
run_logged "$WORK_DIR/logs/05-interface-colmap.log" \
podman_openmvs \
/openmvs/InterfaceCOLMAP \
--input-file /data/dense \
--image-folder /data/dense/images \
--output-file /data/openmvs/scene.mvs \
--working-folder /data/openmvs \
--verbosity 1
else
ok "Projet OpenMVS déjà importé."
fi
if [[ ! -f "$WORK_DIR/openmvs/scene_dense.ply" ]]; then
log "OpenMVS — densification"
run_logged "$WORK_DIR/logs/06-densify.log" \
podman_openmvs \
/openmvs/DensifyPointCloud \
--input-file /data/openmvs/scene.mvs \
--output-file /data/openmvs/scene_dense.mvs \
--working-folder /data/openmvs \
--resolution-level "$RESOLUTION_LEVEL" \
--number-views "$NUMBER_VIEWS" \
--max-threads "$THREADS" \
--verbosity 1
else
ok "Nuage dense déjà généré."
fi
if [[ ! -f "$WORK_DIR/openmvs/scene_dense_mesh.ply" ]]; then
log "OpenMVS — reconstruction du maillage"
run_logged "$WORK_DIR/logs/07-reconstruct-mesh.log" \
podman_openmvs \
/openmvs/ReconstructMesh \
--input-file /data/openmvs/scene_dense.mvs \
--output-file /data/openmvs/scene_dense_mesh.mvs \
--working-folder /data/openmvs \
--max-threads "$THREADS" \
--min-point-distance 4 \
--verbosity 1
else
ok "Maillage déjà reconstruit."
fi
if [[ ! -f "$WORK_DIR/openmvs/scene_dense_mesh_refine.ply" ]]; then
log "OpenMVS — raffinement du maillage"
run_logged "$WORK_DIR/logs/08-refine-mesh.log" \
podman_openmvs \
/openmvs/RefineMesh \
--input-file /data/openmvs/scene_dense.mvs \
--mesh-file /data/openmvs/scene_dense_mesh.ply \
--output-file /data/openmvs/scene_dense_mesh_refine.mvs \
--working-folder /data/openmvs \
--resolution-level "$RESOLUTION_LEVEL" \
--max-threads "$THREADS" \
--verbosity 1
else
ok "Maillage déjà raffiné."
fi
if [[ ! -f "$WORK_DIR/openmvs/scene_dense_mesh_refine_texture.ply" ]]; then
log "OpenMVS — texturage"
run_logged "$WORK_DIR/logs/09-texture-mesh.log" \
podman_openmvs \
/openmvs/TextureMesh \
--input-file /data/openmvs/scene_dense.mvs \
--mesh-file /data/openmvs/scene_dense_mesh_refine.ply \
--output-file /data/openmvs/scene_dense_mesh_refine_texture.mvs \
--working-folder /data/openmvs \
--max-threads "$THREADS" \
--verbosity 1
else
ok "Maillage déjà texturé."
fi
if (( !KEEP_DEPTHMAPS )); then
log "Nettoyage des cartes de profondeur intermédiaires"
find "$WORK_DIR/openmvs" -maxdepth 1 -type f \
\( -name 'depth*.png' -o -name 'depth*.conf.png' \) \
-delete
fi
FINAL="$WORK_DIR/openmvs/scene_dense_mesh_refine_texture.ply"
[[ -f "$FINAL" ]] || die "Le modèle final est absent."
trap - EXIT
printf '\n%s%sSCAN 3D TERMINÉ%s\n' "$BOLD" "$GREEN" "$RESET"
printf 'Modèle texturé :\n %s\n' "$FINAL"
printf 'Images enregistrées : %s/%s\n' "$BEST_REGISTERED" "$IMAGE_COUNT"
printf 'Espace occupé : '
du -sh "$WORK_DIR" | awk '{print $1}'
printf '\nPour l’ouvrir manuellement :\n'
printf ' meshlab %q\n' "$FINAL"

430
bin/.local/bin/scan3d-watch Executable file
View file

@ -0,0 +1,430 @@
#!/usr/bin/env python3
"""scan3d-watch — TUI Textual en lecture seule pour scan3d."""
from __future__ import annotations
import os
import re
import sys
from dataclasses import dataclass
from pathlib import Path
from time import monotonic
import psutil
from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.containers import Horizontal, Vertical
from textual.widgets import Footer, Label, ProgressBar, Static
PROCESS_NAMES = {
"colmap",
"DensifyPointCloud",
"ReconstructMesh",
"RefineMesh",
"TextureMesh",
"InterfaceCOLMAP",
}
PROGRESS_PATTERNS = (
re.compile(r"Processing image \[(\d+)/(\d+)\]"),
re.compile(r"Estimated depth-maps (\d+) \((\d+)%"),
re.compile(r"Geometric-consistent estimated depth-maps (\d+) \((\d+)%"),
re.compile(r"Dense fused depth-maps (\d+) \((\d+)%"),
)
PHASES = (
("features", "Extraction"),
("sequential", "Matching séquentiel"),
("vocab", "Matching global"),
("transitive", "Matching transitif"),
("matching", "Matching"),
("mapper", "Mapper"),
("undistort", "Undistortion"),
("interface", "Import OpenMVS"),
("densify", "Densification"),
("reconstruct", "Maillage"),
("refine", "Raffinement"),
("texture", "Texturage"),
)
@dataclass
class Progress:
phase: str = "En attente"
current: int = 0
total: int = 0
percent: float = 0.0
message: str = ""
def human_bytes(value: int | float) -> str:
units = ("o", "Kio", "Mio", "Gio", "Tio")
number = float(value)
for unit in units:
if abs(number) < 1024 or unit == units[-1]:
return f"{number:.1f} {unit}"
number /= 1024
return f"{number:.1f} Tio"
def directory_size(path: Path) -> int:
total = 0
try:
for root, _dirs, files in os.walk(path):
for name in files:
try:
total += (Path(root) / name).stat().st_size
except OSError:
pass
except OSError:
pass
return total
def find_project(root: Path) -> Path:
scan3d = root / "scan3d"
return scan3d if scan3d.is_dir() else root
def latest_log(project: Path) -> Path | None:
logs: list[Path] = []
try:
logs = [path for path in project.rglob("*.log") if path.is_file()]
except OSError:
return None
return max(logs, key=lambda path: path.stat().st_mtime, default=None)
def read_tail(path: Path, lines: int = 12) -> list[str]:
try:
with path.open("rb") as file:
file.seek(0, os.SEEK_END)
size = file.tell()
block = 8192
data = b""
while size > 0 and data.count(b"\n") <= lines:
read_size = min(block, size)
size -= read_size
file.seek(size)
data = file.read(read_size) + data
return data.decode("utf-8", errors="replace").splitlines()[-lines:]
except OSError:
return []
def detect_progress(project: Path) -> Progress:
log = latest_log(project)
if log is None:
return Progress()
lower_name = log.name.lower()
phase = next(
(label for token, label in PHASES if token in lower_name),
log.stem,
)
result = Progress(phase=phase)
tail = read_tail(log, 120)
# COLMAP : extraction ou matching.
for line in reversed(tail):
match = re.search(r"Processing image \[(\d+)/(\d+)\]", line)
if match:
current = int(match.group(1))
total = int(match.group(2))
result.current = current
result.total = total
result.percent = current * 100 / total if total else 0
result.message = line.strip()
return result
# COLMAP Mapper : nombre d’images réellement enregistrées.
for line in reversed(tail):
match = re.search(r"num_reg_frames=(\d+)", line)
if not match:
continue
current = int(match.group(1))
# Le log est normalement dans projet-*/logs/.
work_dir = log.parent.parent
images_dir = work_dir / "images"
try:
total = sum(
1
for path in images_dir.iterdir()
if path.is_file() or path.is_symlink()
)
except OSError:
total = 0
result.current = current
result.total = total
result.percent = current * 100 / total if total else 0
result.message = line.strip()
return result
# OpenMVS : cartes de profondeur.
for line in reversed(tail):
match = re.search(
r"(?:Estimated|Geometric-consistent estimated|Dense fused) "
r"depth-maps (\d+) \((\d+)%",
line,
)
if match:
result.current = int(match.group(1))
result.percent = float(match.group(2))
result.message = line.strip()
return result
if tail:
result.message = tail[-1].strip()
return result
def amd_gpu() -> tuple[str, str, str]:
for card in sorted(Path("/sys/class/drm").glob("card[0-9]*")):
device = card / "device"
try:
if (device / "vendor").read_text().strip() != "0x1002":
continue
except OSError:
continue
busy = "?"
used = total = None
temperature = "?"
try:
busy = (device / "gpu_busy_percent").read_text().strip()
except OSError:
pass
try:
used = int((device / "mem_info_vram_used").read_text())
total = int((device / "mem_info_vram_total").read_text())
except (OSError, ValueError):
pass
for hwmon in (device / "hwmon").glob("hwmon*"):
try:
temperature = f"{int((hwmon / 'temp1_input').read_text()) / 1000:.0f}°C"
break
except (OSError, ValueError):
continue
vram = (
f"{human_bytes(used)}/{human_bytes(total)}"
if used is not None and total is not None
else "indisponible"
)
return f"{busy}%", vram, temperature
return "absent", "—", "—"
def active_process() -> str:
cpu_count = psutil.cpu_count(logical=True) or 1
rows: list[tuple[float, str]] = []
for process in psutil.process_iter(
["name", "cpu_percent", "memory_percent"]
):
try:
name = process.info["name"] or ""
if name not in PROCESS_NAMES:
continue
raw_cpu = float(process.info["cpu_percent"] or 0)
global_cpu = raw_cpu / cpu_count
memory = float(process.info["memory_percent"] or 0)
rows.append(
(
raw_cpu,
f"{name} CPU {global_cpu:.0f}% RAM {memory:.1f}%",
)
)
except (
psutil.NoSuchProcess,
psutil.AccessDenied,
TypeError,
):
continue
if not rows:
return "Aucun processus COLMAP/OpenMVS"
rows.sort(reverse=True)
return rows[0][1]
class Scan3DWatch(App[None]):
TITLE = "scan3d-watch"
SUB_TITLE = "lecture seule"
BINDINGS = [
Binding("q", "quit", "Quitter"),
Binding("r", "refresh_now", "Actualiser"),
Binding("l", "toggle_logs", "Logs"),
]
CSS = """
Screen {
layout: vertical;
background: #11111b;
color: #cdd6f4;
}
#title {
height: 1;
padding: 0 1;
background: #313244;
color: #cba6f7;
text-style: bold;
}
#phase {
height: 3;
padding: 0 1;
border: round #89b4fa;
}
ProgressBar {
height: 1;
margin: 0 1;
}
#stats {
height: 7;
padding: 0 1;
border: round #a6e3a1;
}
#project {
height: 5;
padding: 0 1;
border: round #f9e2af;
}
#logs {
height: 1fr;
min-height: 4;
padding: 0 1;
border: round #fab387;
overflow-y: hidden;
}
Footer {
height: 1;
}
.hidden {
display: none;
}
"""
def __init__(self, root: Path) -> None:
super().__init__()
self.root = root
self.project = find_project(root)
self.logs_visible = True
psutil.cpu_percent(interval=None)
def compose(self) -> ComposeResult:
yield Label("", id="title")
yield Static("", id="phase")
yield ProgressBar(total=100, show_eta=False, id="progress")
yield Static("", id="stats")
yield Static("", id="project")
yield Static("", id="logs")
yield Footer()
def on_mount(self) -> None:
self.refresh_data()
self.set_interval(1.0, self.refresh_data)
def action_refresh_now(self) -> None:
self.refresh_data()
def action_toggle_logs(self) -> None:
self.logs_visible = not self.logs_visible
logs = self.query_one("#logs")
logs.set_class(not self.logs_visible, "hidden")
def refresh_data(self) -> None:
progress = detect_progress(self.project)
memory = psutil.virtual_memory()
swap = psutil.swap_memory()
disk = psutil.disk_usage(self.root)
cpu = psutil.cpu_percent(interval=None)
gpu, vram, gpu_temp = amd_gpu()
self.query_one("#title", Label).update(
f"SCAN3D {self.root.name} • {self.project}"
)
progress_text = progress.phase
if progress.total:
progress_text += (
f"\n{progress.current}/{progress.total} "
f"({progress.percent:.1f}%)"
)
elif progress.percent:
progress_text += f"\n{progress.current} ({progress.percent:.1f}%)"
elif progress.message:
progress_text += "\nactivité détectée"
self.query_one("#phase", Static).update(progress_text)
self.query_one("#progress", ProgressBar).update(
total=100,
progress=max(0, min(100, progress.percent)),
)
self.query_one("#stats", Static).update(
"[b]Système[/b]\n"
f"CPU {cpu:.0f}% GPU {gpu} Temp GPU {gpu_temp}\n"
f"RAM {human_bytes(memory.used)}/{human_bytes(memory.total)} "
f"dispo {human_bytes(memory.available)}\n"
f"Swap {human_bytes(swap.used)}/{human_bytes(swap.total)} "
f"VRAM {vram}\n"
f"{active_process()}"
)
size = directory_size(self.project)
self.query_one("#project", Static).update(
"[b]Projet[/b]\n"
f"Taille {human_bytes(size)}\n"
f"Disque {human_bytes(disk.used)}/{human_bytes(disk.total)} "
f"libre {human_bytes(disk.free)}"
)
log = latest_log(self.project)
if log is None:
log_text = "[b]Logs[/b]\nAucun fichier .log trouvé"
else:
lines = read_tail(log, 8)
cleaned = [
re.sub(r"^[IWEF]\d+\s+\S+\s+\d+\s+", "", line)
for line in lines
]
log_text = f"[b]Logs — {log.name}[/b]\n" + "\n".join(cleaned)
self.query_one("#logs", Static).update(log_text)
def main() -> int:
root = Path(sys.argv[1] if len(sys.argv) > 1 else Path.cwd())
root = root.expanduser().resolve()
if not root.is_dir():
print(f"Dossier introuvable : {root}", file=sys.stderr)
return 1
Scan3DWatch(root).run()
return 0
if __name__ == "__main__":
raise SystemExit(main())

16
bin/.local/bin/sway-close Executable file
View file

@ -0,0 +1,16 @@
#!/usr/bin/env bash
app_id="$(
swaymsg -t get_tree |
jq -r '.. | objects | select(.focused? == true) |
(.app_id // .window_properties.class // "")'
)"
case "$app_id" in
limusic-app|LiMusic|limusic)
pkill -TERM -x limusic-app
;;
*)
swaymsg kill
;;
esac

View file

@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -e
# Laisser le temps aux fenêtres de se lancer
sleep 5
# Aller sur le workspace 1
swaymsg "workspace 1"
# Regrouper les trois fenêtres sur le bon workspace (au cas où)
swaymsg '[app_id="kitty-1"] move to workspace 1'
swaymsg '[app_id="kitty-2"] move to workspace 1'
swaymsg '[title="Perplexity"] move to workspace 1'
# Layout horizontal global
swaymsg '[app_id="kitty-1"] focus'
swaymsg 'move left'
# Revenir sur la zone gauche (un des kitty)
swaymsg '[app_id="kitty-2"] focus'
swaymsg 'move down'
# Envoyer Perplexity à droite
swaymsg '[title="Perplexity"] focus'
swaymsg 'move right'
# Envoyer Perplexity à droite
swaymsg '[title="Perplexity"] focus'
swaymsg 'move right'

View file

@ -0,0 +1,43 @@
#!/usr/bin/env bash
set -u
# Empêche deux lanceurs simultanés.
exec 9>"${XDG_RUNTIME_DIR:-/tmp}/thunderbird-proton.lock"
if ! flock -n 9; then
notify-send "Thunderbird" "Thunderbird est déjà en cours d’utilisation."
exit 0
fi
# Le Bridge utilise le trousseau GNOME pour ses identifiants.
systemctl --user start gnome-keyring-daemon.service
if ! systemctl --user start protonmail-bridge.service; then
notify-send -u critical \
"Proton Mail Bridge" \
"Impossible de démarrer le service."
exit 1
fi
notify-send "Proton Mail Bridge" "Démarrage du serveur de messagerie…"
# Attendre que les processus du Bridge soient réellement présents.
for _ in {1..20}; do
if pgrep -f '/usr/lib/protonmail/bridge/bridge' >/dev/null; then
break
fi
sleep 0.5
done
sleep 2
thunderbird "$@" &
# Attendre la fermeture complète de Thunderbird.
while pgrep -x thunderbird >/dev/null; do
sleep 2
done
systemctl --user stop protonmail-bridge.service
notify-send "Proton Mail Bridge" "Arrêté après la fermeture de Thunderbird."

15
bin/.local/bin/tlp-profile.sh Executable file
View file

@ -0,0 +1,15 @@
#!/bin/sh
# Récupère la ligne "TLP profile = balanced/BAT" et isole "balanced/BAT"
# profile=$(tlp-stat -s 2>/dev/null | awk -F'= ' '/TLP profile/ {print $2}')
# Optionnel : ne garder que le profil logique (performance/balanced/power-saver)
# profile=$(printf "%s" "$profile" | cut -d'/' -f1)
# [ -z "$profile" ] && profile="unknown"
# printf " %s\n" "$profile"
tlp=$(tlp-stat -s 2>/dev/null | awk -F'= ' '/TLP profile/ {print $2}')
platform=$(cat /sys/firmware/acpi/platform_profile 2>/dev/null)
printf " %s | %s\n" "$tlp" "$platform"

48
bin/.local/bin/vmware-on-demand Executable file
View file

@ -0,0 +1,48 @@
#!/usr/bin/env bash
set -u
readonly STACK_HELPER="/usr/local/sbin/vmware-stack"
readonly LOCK_FILE="${XDG_RUNTIME_DIR:-/tmp}/vmware-on-demand.lock"
services_started=0
cleanup() {
if (( services_started == 1 )); then
notify-send "VMware" "Arrêt du réseau VMware et de Samba…"
if sudo -n "$STACK_HELPER" stop; then
notify-send "VMware" "Réseau VMware et Samba arrêtés."
else
notify-send -u critical \
"VMware" \
"Impossible d’arrêter les services."
fi
fi
}
exec 9>"$LOCK_FILE"
if ! flock -n 9; then
notify-send "VMware" "Une session VMware est déjà lancée."
exit 0
fi
notify-send "VMware" "Démarrage du réseau VMware et de Samba…"
if ! sudo -n "$STACK_HELPER" start; then
notify-send -u critical \
"VMware" \
"Impossible de démarrer les services."
exit 1
fi
services_started=1
trap cleanup EXIT INT TERM
vmware "$@" &
while pgrep -x vmware >/dev/null ||
pgrep -x vmware-vmx >/dev/null; do
sleep 3
done

View file

@ -1,139 +0,0 @@
[Parameters]
folder_with_datafiles = ~/.config/calcure
calcurse_todo_file = ~/.local/share/calcurse/todo
calcurse_events_file = ~/.local/share/calcurse/apts
log_file = ~/.config/calcure/info.log
language = fr
default_view = calendar
default_calendar_view = monthly
birthdays_from_abook = Yes
show_keybindings = Yes
privacy_mode = No
show_weather = No
weather_city =
weather_metric_units = Yes
minimal_today_indicator = Yes
minimal_days_indicator = Yes
minimal_weekend_indicator = Yes
show_calendar_borders = No
show_moon_phases = No
cut_titles_by_cell_length = No
ask_confirmations = Yes
ask_confirmation_to_quit = Yes
use_unicode_icons = Yes
show_current_time = No
show_holidays = Yes
show_nothing_planned = Yes
one_timer_at_a_time = No
holiday_country = France
use_persian_calendar = No
start_week_day = 1
weekend_days = 6,7
refresh_interval = 1
data_reload_interval = 0
split_screen = Yes
right_pane_percentage = 25
journal_header = JOURNAL
event_icon = •
privacy_icon = •
today_icon = •
birthday_icon = ★
holiday_icon = ⛱
hidden_icon = ...
done_icon = ✔
todo_icon = •
important_icon = ‣
separator_icon = │
deadline_icon = ⚑
[Colors]
color_today = 2
color_events = 4
color_days = 7
color_day_names = 4
color_weekends = 1
color_weekend_names = 1
color_hints = 7
color_prompts = 7
color_confirmations = 1
color_birthdays = 1
color_holidays = 2
color_todo = 7
color_done = 6
color_title = 4
color_calendar_header = 4
color_important = 1
color_unimportant = 6
color_timer = 2
color_timer_paused = 7
color_time = 7
color_deadlines = 3
color_weather = 2
color_active_pane = 2
color_separator = 7
color_calendar_border = 7
color_ics_calendars = 2,3,1,7,4,5,2,3,1,7
color_background = -1
[Styles]
bold_today = No
bold_days = No
bold_day_names = No
bold_weekends = No
bold_weekend_names = No
bold_title = No
bold_active_pane = No
underlined_today = No
underlined_days = No
underlined_day_names = No
underlined_weekends = No
underlined_weekend_names = No
underlined_title = No
underlined_active_pane = No
strikethrough_done = No
[Event icons]
travel = ✈
plane = ✈
voyage = ✈
flight = ✈
airport = ✈
trip = 🏕
vacation = ⛱
holiday = ⛱
day-off = ⛱
hair = ✂
barber = ✂
beauty = ✂
nails = ✂
game = ♟
match = ♟
play = ♟
interview = 🎙️
conference = 🎙️
talk = 🎙️
dating = ♥
concert = ♪
dance = ♪
music = ♪
rehearsal = ♪
call = 🕻
zoom = 🕻
deadline = ⚑
over = ⚑
finish = ⚑
end = ⚑
doctor = ✚
dentist = ✚
medical = ✚
hospital = ✚
party = ☘
bar = ☘
museum = ⛬
meet = ⛬
sport = ⛷
gym = 🏋
training = ⛷
email = ✉
letter = ✉

View file

@ -1 +0,0 @@
1,2026,3,7,"ARP",1,once,normal
1 1 2026 3 7 ARP 1 once normal

View file

@ -1 +0,0 @@
[WARNING] Couldn't load birthdays. File. /home/fy59/.abook/addressbook does not exist.

View file

@ -0,0 +1 @@
max-items 50

View file

@ -1,3 +0,0 @@
max-items 50
max-size 100000

View file

@ -1,12 +1,20 @@
// ~/.config/fastfetch/config.jsonc
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"display": {
"separator": "• "
},
"logo":{
"type": "sixel",
"width": 30
// "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
// "display": {
// "separator": "• "
// },
// "logo":{
// "type": "sixel",
// "width": 30
// },
"logo": {
"type": "small",
"padding": {
"top": 4, // Top padding
"left": 3, // Left padding
"right": 3 // Right padding
}
},
"modules": [
"break",
@ -16,7 +24,7 @@
},
{
"type": "custom",
"format": "╭───────────────────────────────╮"
"format": "╭────────────────────────────────────────────╮"
},
{
"type": "os",
@ -57,7 +65,7 @@
},
{
"type": "custom",
"format": "╰───────────────────────────────╯"
"format": "╰────────────────────────────────────────────╯"
},
{
"type": "custom",

View file

@ -0,0 +1,6 @@
export FZF_DEFAULT_OPTS=" \
--color=bg+:#313244,bg:#1E1E2E,spinner:#F5E0DC,hl:#F38BA8 \
--color=fg:#CDD6F4,header:#F38BA8,info:#CBA6F7,pointer:#F5E0DC \
--color=marker:#B4BEFE,fg+:#CDD6F4,prompt:#CBA6F7,hl+:#F38BA8 \
--color=selected-bg:#45475A \
--color=border:#6C7086,label:#CDD6F4"

View file

@ -1,7 +1,6 @@
file:///home/fy59/Documents/Lardon/lardon3d
file:///home/fy59/Downloads
file:///home/fy59/Ansible
file:///home/fy59/Documents
file:///home/fy59/Musique
file:///home/fy59/Images
file:///home/fy59/Vid%C3%A9os
file:///home/fy59/T%C3%A9l%C3%A9chargements
file:///home/fy59/Pictures/Assets/
file:///home/fy59/Pictures/Assets
file:///home/fy59/Share

View file

@ -1,3 +0,0 @@
[Settings]
gtk-theme-name=Adwaita-dark
gtk-icon-theme-name = "Tela-dracula-dark"

View file

@ -1,3 +0,0 @@
[Settings]
gtk-theme-name=Adwaita-dark
gtk-icon-theme-name = "Tela-dracula-dark"

View file

@ -0,0 +1,9 @@
[main]
gtk-theme=Adwaita-dark
style=/home/fy59/.config/gtklock/style.css
background=/tmp/gtklock-blur.png
time-format=%H:%M
date-format=%A %d %B
idle-hide=true
idle-timeout=10
modules=userinfo-module;playerctl-module;powerbar-module

View file

@ -0,0 +1,53 @@
window {
background-color: #1e1e2e;
background-image: url("/tmp/gtklock-blur.png");
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
#window-box {
background-color: rgba(30, 30, 46, 0.78);
border: 1px solid #b4befe;
border-radius: 12px;
padding: 12px;
box-shadow: 0 0 32px rgba(0, 0, 0, 0.55);
}
#clock-label {
color: #cdd6f4;
font-size: 72px;
font-weight: 700;
}
#date-label {
color: #bac2de;
font-size: 22px;
margin-bottom: 18px;
}
#input-field {
color: #cdd6f4;
background-color: rgba(17, 17, 27, 0.92);
border: 1px solid #b4befe;
border-radius: 6px;
padding: 12px;
font-size: 22px;
}
label {
color: #cdd6f4;
}
button {
color: #b4befe;
background-color: #b4befe;
border-radius: 6px;
border: 1px solid #45475a;
padding: 8px 12px;
}
button:hover {
background-color: rgba(69, 71, 90, 0.95);
border-color: #89b4fa;
}

View file

@ -0,0 +1,17 @@
{
"$schema": "https://raw.githubusercontent.com/goodroot/hyprwhspr/main/share/config.schema.json",
"primary_shortcut": "SUPER+SHIFT+F23",
"recording_mode": "push_to_talk",
"keyboard_device_names": [
"AT Translated Set 2 keyboard"
],
"model": "large-v3-turbo",
"language": "fr",
"transcription_backend": "vulkan",
"start_sound_volume": 0.5,
"stop_sound_volume": 0.5,
"start_sound_path": "ping-up.ogg",
"stop_sound_path": "ping-down.ogg",
"audio_ducking": true,
"whisper_prompt_fr": "Transcrire en fran\u00e7ais avec des phrases compl\u00e8tes, une ponctuation claire et des majuscules correctes au d\u00e9but des phrases, pour les noms propres et les titres, comme dans un texte r\u00e9dig\u00e9"
}

View file

@ -5,11 +5,21 @@ theme = "ctp-mocha"
[icons]
icons = "material-nf"
[[block]]
block = "scratchpad"
[block.theme_overrides]
idle_bg = "#fab387"
idle_fg = "#1e1e2e"
[[block]]
block = "focused_window"
[block.format]
full = " $title.str(max_w:15) |"
short = " $title.str(max_w:10) |"
[block.theme_overrides]
idle_bg = "#f9e2af"
idle_fg = "#1e1e2e"
[[block]]
block = "music"
@ -25,8 +35,17 @@ action = "toggle_format"
[[block]]
block = "bluetooth"
mac = "E4:61:F4:F4:A1:F7"
format = " JBL Tune {{$battery_icon}} "
disconnected_format = " 󰂲"
format = " 󰂯 JBL Tune "
disconnected_format = " 󰂲 JBL Tune "
[[block.click]]
button = "left"
action = "blueman-manager"
[[block]]
block = "bluetooth"
mac = "1C:57:85:33:54:7F"
format = " 󰂯 EDENWOOD "
disconnected_format = " 󰂲 EDENWOOD "
[[block.click]]
button = "left"
action = "blueman-manager"
@ -35,26 +54,46 @@ action = "blueman-manager"
block = "net"
device = "wlp1s0"
format = " $icon {$signal_strength $ssid} "
[block.theme_overrides]
idle_bg = "#a6e3a1"
idle_fg = "#1e1e2e"
[[block]]
block = "sound"
step_width = 3
max_vol = 100
[block.theme_overrides]
idle_bg = "#94e2d5"
idle_fg = "#1e1e2e"
[[block]]
block = "backlight"
device = "amdgpu_bl1"
invert_icons = true
minimum = 10
[block.theme_overrides]
idle_bg = "#89dceb"
idle_fg = "#1e1e2e"
[[block]]
block = "battery"
format = " $icon $percentage "
[block.theme_overrides]
idle_bg = "#a6e3a1"
warning_bg = "#f9e2af"
critical_bg = "#f38ba8"
idle_fg = "#1e1e2e"
warning_fg = "#1e1e2e"
critical_fg = "#1e1e2e"
[[block]]
block = "custom"
command = "~/.local/bin/tlp-profile.sh"
interval = 5
[block.theme_overrides]
idle_bg = "#74c7ec"
idle_fg = "#1e1e2e"
[[block]]
block = "packages"
@ -68,25 +107,17 @@ format_up_to_date = " $icon Up to date "
# aur_command should output available updates to stdout (ie behave as echo -ne "update\n")
aur_command = "yay -Qua"
[[block]]
block = "notify"
driver = "swaync"
[[block.click]]
button = "left"
action = "show"
[[block.click]]
button = "right"
action = "toggle_paused"
[[block]]
block = "time"
interval = 60
[block.format]
full = " $icon $timestamp.datetime(f:'%d-%m-%Y %R')"
short = " $icon $timestamp.datetime(f:%R) "
format = " $timestamp.datetime(f:'%d/%m %H:%M') "
[block.theme_overrides]
idle_bg = "#b4befe"
idle_fg = "#1e1e2e"
[[block]]
block = "menu"
text = " \uf011 "
text = " \uf011 "
[[block.items]]
display = " -> Sleep <-"
cmd = "systemctl suspend"

View file

@ -30,3 +30,5 @@ cursor_trail 0
shell_integration no-cursor
include kitty-themes/themes/mocha.conf
map alt+c no_cp

View file

@ -5,10 +5,10 @@ text-color=#cdd6f4
border-color=#b4befe
progress-color=over #313244
border-radius=2
border-radius=5
# Comportement
default-timeout=5000
default-timeout=10000
ignore-timeout=1
max-visible=3
layer=overlay

View file

@ -1,37 +0,0 @@
##############################
# #
# Autostart #
# #
##############################
# =================================================
# Filtre lumière bleue (wlsunset)
# Notifications (swaync)
# gnome-keyring-daemon
# Verrouillage auto (swayidle)
# protonmail-bridge
#
# Les outils précédent ont été ajouter à systemd --user
#
# =================================================
# Wallpapers
exec-once=swaybg -i ~/.wallpapers/662412-vanilla-arch-wallpaper-linuxart.png
# Lancement au démarrage
exec-once=kitty --class kitty-1 --directory $HOME
exec-once=perplexity
exec-once=kitty --class kitty-2 --directory $HOME
exec-once=kitty --class kitty-3 --directory $HOME -- sh -c "ssh srv-admin-ext"
exec-once=chromium
exec-once=thunderbird
exec-once=spotify-launcher
exec-once=waybar
exec-once=proton-pass
# Presse-papier
exec=wl-paste --watch clipvault store
exec=wl-paste --type image/png --watch clipvault store
# Idle
exec-once=swayidle -w timeout 300 'swaylock -f -c 000000' timeout 301 'systemctl suspend' before-sleep 'swaylock -f -c 000000'

View file

@ -1,33 +0,0 @@
##############################
# #
# Binds Applications #
# #
##############################
# Applications system
binds=SUPER,Return,spawn,kitty
binds=SUPER+SHIFT,b,spawn,blueman-manager
binds=SUPER+SHIFT,p,spawn,proton-pass
binds=ALT,p,toggle_named_scratchpad,Proton Pass,none,proton-pass
binds=SUPER+SHIFT,m,spawn,protonmail-bridge
binds=SUPER+CTRL,l,spawn,swaylock
binds=SUPER+CTRL,e,spawn,wofi --cache-file=/dev/null -Dimage_size=26 -Dynamic_lines=true --location top --yoffset=10 --width=600 --height=300 --gtk-dark --show drun
binds=SUPER,v,spawn,~/.config/mango/scripts/copypast
binds=NONE,Print,spawn,~/.config/mango/scripts/screenshot-clip.sh
# Browsers & net
binds=SUPER,b,spawn,chromium
binds=SUPER+SHIFT,f,spawn,firefox
binds=SUPER,t,spawn,thunderbird
# IA's
binds=SUPER+SHIFT,XF86Assistant,spawn,perplexity
binds=SUPER,m,spawn,spotify-launcher
# Virtualisation
binds=SUPER+SHIFT,v,spawn,virt-manager
# Fichiers
binds=SUPER+SHIFT,t,spawn,thunar
binds=ALT,y,spawn,kitty --class kitty-yazi -- sh -c "yazi"

View file

@ -1,94 +0,0 @@
##############################
# #
# Navigation bindings #
# #
##############################
# switch window focus
binds=SUPER,Tab,focusstack,next
binds=ALT,Left,focusdir,left
binds=ALT,Right,focusdir,right
binds=ALT,Up,focusdir,up
binds=ALT,Down,focusdir,down
# swap window
binds=SUPER+SHIFT,Up,exchange_client,up
binds=SUPER+SHIFT,Down,exchange_client,down
binds=SUPER+SHIFT,Left,exchange_client,left
binds=SUPER+SHIFT,Right,exchange_client,right
# switch window status
binds=SUPER,g,toggleglobal,
binds=ALT,Tab,toggleoverview,
binds=ALT,backslash,togglefloating,
binds=ALT,a,togglemaximizescreen,
binds=ALT,f,togglefullscreen,
binds=ALT+SHIFT,f,togglefakefullscreen,
binds=SUPER,i,minimized,
binds=SUPER,o,toggleoverlay,
binds=SUPER+SHIFT,I,restore_minimized
binds=ALT,z,toggle_scratchpad
# tag switch
binds=SUPER,Left,viewtoleft,0
binds=CTRL,Left,viewtoleft_have_client,0
binds=SUPER,Right,viewtoright,0
binds=CTRL,Right,viewtoright_have_client,0
binds=CTRL+SUPER,Left,tagtoleft,0
binds=CTRL+SUPER,Right,tagtoright,0
binds=CTRL,ampersand,view,1,0
binds=CTRL,eacute,view,2,0
binds=CTRL,quotedbl,view,3,0
binds=CTRL,apostrophe,view,4,0
binds=CTRL,parenleft,view,5,0
binds=CTRL,minus,view,6,0
binds=CTRL,egrave,view,7,0
binds=CTRL,underscore,view,8,0
binds=CTRL,ccedilla,view,9,0
# tag: move client to the tag and focus it
# tagsilent: move client to the tag and not focus it
# bind=ALT,1,tagsilent,1
binds=ALT,ampersand,tag,1,0
binds=ALT,eacute,tag,2,0
binds=ALT,quotedbl,tag,3,0
binds=ALT,apostrophe,tag,4,0
binds=ALT,parenleft,tag,5,0
binds=ALT,minus,tag,6,0
binds=ALT,egrave,tag,7,0
binds=ALT,underscore,tag,8,0
binds=ALT,ccedilla,tag,9,0
# monitor switch
binds=ALT+SHIFT,Left,focusmon,left
binds=ALT+SHIFT,Right,focusmon,right
binds=SUPER+ALT,Left,tagmon,left
binds=SUPER+ALT,Right,tagmon,right
# gaps
binds=ALT+SHIFT,X,incgaps,1
binds=ALT+SHIFT,Z,incgaps,-1
binds=ALT+SHIFT,R,togglegaps
# movewin
# binds=CTRL+SHIFT,Up,movewin,+0,-50
# binds=CTRL+SHIFT,Down,movewin,+0,+50
# binds=CTRL+SHIFT,Left,movewin,-50,+0
# binds=CTRL+SHIFT,Right,movewin,+50,+0
# resizewin
binds=CTRL+ALT,Up,resizewin,+0,-10
binds=CTRL+ALT,Down,resizewin,+0,+10
binds=CTRL+ALT,Left,resizewin,-10,+0
binds=CTRL+ALT,Right,resizewin,+10,+0
# Mouse Button Bindings
# btn_left and btn_right can't bind none mod key
mousebind=SUPER,btn_left,moveresize,curmove
mousebind=NONE,btn_middle,togglemaximizescreen,0
mousebind=SUPER,btn_right,moveresize,curresize
# Axis Bindings
axisbind=SUPER,UP,viewtoleft_have_client
axisbind=SUPER,DOWN,viewtoright_have_client

View file

@ -1,38 +0,0 @@
##############################
# #
# Binds sys #
# #
##############################
# Key Bindings
# key name refer to `xev` or `wev` command output,
# mod keys name: super,ctrl,alt,shift,none
# Layout Bindings
# scrolle5 layout
binds=ALT,e,set_proportion,0.5
binds=ALT+SHIFT,e,set_proportion,1
binds=ALT,x,switch_proportion_preset,
# switch layou5
binds=SUPER,n,switch_layout
# reload config
binds=SUPER,r,reload_config
# exit
binds=SUPER+CTRL,q,quit
binds=SUPER,q,killclient
# Brightness
bind=NONE,XF86MonBrightnessUp,spawn,brightnessctl set +2%
bind=SHIFT,XF86MonBrightnessUp,spawn,brightnessctl set 100%
bind=NONE,XF86MonBrightnessDown,spawn,brightnessctl set 2%-
bind=SHIFT,XF86MonBrightnessDown,spawn,brightnessctl set 10%
# Volume
bind=NONE,XF86AudioRaiseVolume,spawn,wpctl set-volume @DEFAULT_SINK@ 2%+
bind=NONE,XF86AudioLowerVolume,spawn,wpctl set-volume @DEFAULT_SINK@ 2%-
bind=NONE,XF86AudioMute,spawn,wpctl set-mute @DEFAULT_SINK@ toggle
bind=SHIFT,XF86AudioMute,spawn,wpctl set-mute @DEFAULT_SOURCE@ toggle

View file

@ -1,42 +0,0 @@
##############################
# #
# Mango Config #
# #
##############################
# More option see https://github.com/DreamMaoMao/mango/wiki/
# Sources
source=~/.config/mango/rules.conf
source=~/.config/mango/style.conf
source=~/.config/mango/bind_apps.conf
source=~/.config/mango/bind_navigation.conf
source=~/.config/mango/bind_sys.conf
source=~/.config/mango/gestures.conf
source=~/.config/mango/layout_settings.conf
source=~/.config/mango/input.conf
source=~/.config/mango/output.conf
source=~/.config/mango/autostart.conf
# Overview Setting
hotarea_size=10
enable_hotarea=1
ov_tab_mode=0
overviewgappi=5
overviewgappo=30
# Misc
no_border_when_single=0
axis_bind_apply_timeout=100
focus_on_activate=1
idleinhibit_ignore_visible=0
sloppyfocus=1
warpcursor=1
focus_cross_monitor=0
focus_cross_tag=0
enable_floating_snap=0
snap_distance=30
cursor_size=24
drag_tile_to_tile=1
drag_tile_small=1

View file

@ -1,11 +0,0 @@
##############################
# #
# Gestures #
# #
##############################
# 3-finger: Window focus
gesturebind=none,left,3,focusdir,right
gesturebind=none,right,3,focusdir,left
gesturebind=none,up,3,focusdir,up
gesturebind=none,down,3,focusdir,down

View file

@ -1,29 +0,0 @@
##############################
# #
# Input #
# #
##############################
# keyboard
repeat_rate=25
repeat_delay=600
numlockon=1
xkb_rules_layout=fr
# Trackpad
# need relogin to make it apply
disable_trackpad=0
tap_to_click=1
tap_and_drag=1
drag_lock=1
trackpad_natural_scrolling=1
disable_while_typing=1
left_handed=0
middle_button_emulation=0
swipe_min_threshold=1
button_map=1
# mouse
# need relogin to make it apply
mouse_natural_scrolling=1

View file

@ -1,33 +0,0 @@
##############################
# #
# Layout settings #
# #
##############################
# layout support:
# tile,scroller,grid,deck,monocle,center_tile,vertical_tile,vertical_scroller
tagrule=id:1,layout_name:scroller
tagrule=id:2,layout_name:scroller
tagrule=id:3,layout_name:scroller
tagrule=id:4,layout_name:scroller
tagrule=id:5,layout_name:scroller
tagrule=id:6,layout_name:scroller
tagrule=id:7,layout_name:scroller
tagrule=id:8,layout_name:scroller
tagrule=id:9,layout_name:scroller
# Scroller Layout Setting
scroller_structs=20
scroller_default_proportion=0.8
scroller_focus_center=0
scroller_prefer_center=0
edge_scroller_pointer_focus=1
scroller_default_proportion_single=1.0
scroller_proportion_preset=0.5,0.8,1.0
# Master-Stack Layout Setting
new_is_master=1
default_mfact=0.55
default_nmaster=1
smartgaps=0

View file

@ -1,9 +0,0 @@
##############################
# #
# Output #
# #
##############################
# monitor
monitorrule=name:^eDP-1$,width:3200,height:2000,refresh:120,scale:1.5

View file

@ -1,35 +0,0 @@
##############################
# #
# Rules #
# #
##############################
# Tag 1 : shell / terminaux / Perplexity
windowrule=tags:1,scroller_proportion:0.5,appid:kitty-1
windowrule=tags:1,scroller_proportion:0.5,appid:perplexity
windowrule=tags:1,scroller_proportion:0.5,appid:kitty-2
# Tag 2 : Ssh serveur
windowrule=tags:2,scroller_proportion:1,appid:kitty-3
# Tag 3 : web
windowrule=tags:3,scroller_proportion:0.8,appid:chromium
windowrule=tags:3,appid:firefox
# Tag 8 : mail
windowrule=tags:8,scroller_proportion:0.5,appid:proton-bridge
windowrule=tags:8,scroller_proportion:1,appid:org.mozilla.Thunderbird
# Tag 9 : musique
# adapte la valeur d'appid à ce que ton script affiche pour Spotify
windowrule=tags:9,scroller_proportion:1,appid:Spotify
windowrule=isfloating:1,width:800,height:600,offsetx:0,offsety:0,appid:blueman-manager
windowrule=isnamedscratchpad:1,width:1000,height:700,appid:Proton Pass
# layer rule
layerrule=animation_type_open:slide,layer_name:wofi
layerrule=animation_type_close:slide,layer_name:wofi
# Specifics rules
windowrule=scroller_proportion:0.5,appid:kitty-yazi

View file

@ -1,52 +0,0 @@
#!/usr/bin/env bash
thumb_dir="${XDG_CACHE_HOME:-$HOME/.cache}/clipvault/thumbs"
mkdir -p "$thumb_dir"
clip_list="$(clipvault list)"
# nettoyer les vignettes orphelines
for thumb in "$thumb_dir"/*; do
[ -e "$thumb" ] || continue
clip_id="${thumb##*/}"
clip_id="${clip_id%.*}"
check=$(printf '%s\n' "$clip_list" | rg "^${clip_id}\s")
if [ -z "$check" ]; then
rm -f "$thumb"
fi
done
# programme gawk : détecter les entrées image, générer les thumbs, préfixer par img:
read -r -d '' prog <<EOF
match(\$0, /^([0-9]+)\s\[\[ binary data .*image\/(jpeg|jpg|png|bmp|webp)/, grp) {
id = grp[1]
ext = grp[2]
image = id "." ext
cmd = "[ -f $thumb_dir/" image " ] || printf \"" id "\\n\" | clipvault get | magick - -resize '256x256>' $thumb_dir/" image
system(cmd)
print "img:$thumb_dir/" image
next
}
1
EOF
choice=$(
gawk <<< "$clip_list" "$prog" |
wofi -I --dmenu --cache-file=/dev/null \
-Dimage_size=100 -Dynamic_lines=true \
--xoffset=600 --yoffset=20 --width=45% --height=45% --gtk-dark
)
[ -z "$choice" ] && exit 1
if [ "${choice:0:4}" = "img:" ]; then
thumb_file="${choice:4}"
clip_id="${thumb_file##*/}"
clip_id="${clip_id%.*}"
else
# on prend l’ID (premier champ) de la ligne choisie
clip_id="$(printf '%s\n' "$choice" | awk '{print $1}')"
fi
# récupérer l’entrée choisie et la remettre dans le clipboard
printf '%s\n' "$clip_id" | clipvault get | wl-copy

View file

@ -1,2 +0,0 @@
#!/usr/bin/env bash
grim -g "$(slurp)" - | wl-copy -t image/png

View file

@ -1,75 +0,0 @@
##############################
# #
# Style #
# #
##############################
# Window effect
blur=0
blur_layer=0
blur_optimized=1
blur_params_num_passes = 2
blur_params_radius = 5
blur_params_noise = 0.02
blur_params_brightness = 0.9
blur_params_contrast = 0.9
blur_params_saturation = 1.2
shadows = 0
layer_shadows = 0
shadow_only_floating = 1
shadows_size = 10
shadows_blur = 15
shadows_position_x = 0
shadows_position_y = 0
shadowscolor= 0x000000ff
border_radius=4
no_radius_when_single=0
focused_opacity=1.0
unfocused_opacity=0.8
# Animation Configuration(support type:zoom,slide)
# tag_animation_direction: 1-horizontal,0-vertical
animations=1
layer_animations=1
animation_type_open=slide
animation_type_close=slide
animation_fade_in=1
animation_fade_out=1
tag_animation_direction=1
zoom_initial_ratio=0.4
zoom_end_ratio=0.8
fadein_begin_opacity=0.5
fadeout_begin_opacity=0.8
animation_duration_move=500
animation_duration_open=400
animation_duration_tag=350
animation_duration_close=800
animation_duration_focus=0
animation_curve_open=0.46,1.0,0.29,1
animation_curve_move=0.46,1.0,0.29,1
animation_curve_tag=0.46,1.0,0.29,1
animation_curve_close=0.08,0.92,0,1
animation_curve_focus=0.46,1.0,0.29,1
animation_curve_opafadeout=0.5,0.5,0.5,0.5
animation_curve_opafadein=0.46,1.0,0.29,1
# Appearance
gappih=5
gappiv=5
gappoh=10
gappov=10
scratchpad_width_ratio=0.8
scratchpad_height_ratio=0.9
borderpx=2
rootcolor=0x201b14ff
bordercolor=0x444444ff
dropcolor=0x8FBA7C55
focuscolor=0xb4befeff
maximizescreencolor=0x89aa61ff
urgentcolor=0xad401fff
scratchpadcolor=0x516c93ff
globalcolor=0xb153a7ff
overlaycolor=0x14a57cff

View file

@ -26,38 +26,42 @@ vim.opt.clipboard = "unnamedplus"
vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1
vim.g.loaded_ruby_provider = 0
vim.g.loaded_node_provider = 0
vim.g.loaded_perl_provider = 0
-- Avant require("config.lazy")
local ts_site = vim.fn.stdpath("data") .. "/site"
if not vim.tbl_contains(vim.opt.rtp:get(), ts_site) then
vim.opt.rtp:append(ts_site)
vim.opt.rtp:append(ts_site)
end
-- charge lazy.nvim + plugins
require("config.lazy")
-- Position du curser
vim.api.nvim_create_autocmd("BufReadPost", {
callback = function()
local mark = vim.api.nvim_buf_get_mark(0, '"')
local line_count = vim.api.nvim_buf_line_count(0)
if mark[1] > 0 and mark[1] <= line_count then
vim.api.nvim_win_set_cursor(0, mark)
end
end,
callback = function()
local mark = vim.api.nvim_buf_get_mark(0, '"')
local line_count = vim.api.nvim_buf_line_count(0)
if mark[1] > 0 and mark[1] <= line_count then
vim.api.nvim_win_set_cursor(0, mark)
end
end,
})
-- Undo persistant
local undodir = vim.fn.stdpath("state") .. "/undo"
if vim.fn.isdirectory(undodir) == 0 then
vim.fn.mkdir(undodir, "p")
vim.fn.mkdir(undodir, "p")
end
vim.opt.undodir = undodir
vim.opt.undofile = true
vim.filetype.add({
pattern = { [".*/hypr/.*%.conf"] = "hyprlang" },
pattern = { [".*/hypr/.*%.conf"] = "hyprlang" },
})
-- require
require("config.filetypes")
-- Keymaps (fichier séparé)
require("config.maps")
@ -67,7 +71,48 @@ require("config.markdown")
-- Mason/LSP
require("mason-lspconfig").setup()
local Terminal = require("toggleterm.terminal").Terminal
local function get_devcontainer()
local project = vim.fn.getcwd()
local handle = io.popen(
'docker ps -q --filter "label=devcontainer.local_folder='
.. project
.. '"'
)
if not handle then
return nil
end
local container = handle:read("*a"):gsub("%s+", "")
handle:close()
if container == "" then
return nil
end
return container
end
vim.keymap.set("n", "<leader>dt", function()
local container = get_devcontainer()
if not container then
vim.notify("Aucun devcontainer actif", vim.log.levels.ERROR)
return
end
local docker_term = Terminal:new({
cmd = "docker exec -it -u vscode -w /workspace " .. container .. " zsh",
direction = "float",
hidden = true,
})
docker_term:toggle()
end, {
desc = "Docker terminal",
})
vim.cmd.colorscheme "catppuccin-mocha"

View file

@ -1,38 +1,36 @@
{
"LuaSnip": { "branch": "master", "commit": "a62e1083a3cfe8b6b206e7d3d33a51091df25357" },
"LuaSnip": { "branch": "master", "commit": "0abc8f390b278c3b4aabc4c004ac8a088b65cf24" },
"bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" },
"catppuccin": { "branch": "main", "commit": "426dbebe06b5c69fd846ceb17b42e12f890aedf1" },
"catppuccin": { "branch": "main", "commit": "edefef779ab08ce1a4a404713e3012b0d202bd35" },
"cmp-buffer": { "branch": "main", "commit": "b74fab3656eea9de20a9b8116afa3cfc4ec09657" },
"cmp-nvim-lsp": { "branch": "main", "commit": "cbc7b02bb99fae35cb42f514762b89b5126651ef" },
"cmp-path": { "branch": "main", "commit": "c642487086dbd9a93160e1679a1327be111cbc25" },
"cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" },
"friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" },
"gitsigns.nvim": { "branch": "main", "commit": "dd3f588bacbeb041be6facf1742e42097f62165d" },
"friendly-snippets": { "branch": "main", "commit": "b4d01b0fdf3c9a549961c2f9ffe8dc09be166219" },
"lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
"lualine.nvim": { "branch": "master", "commit": "131a558e13f9f28b15cd235557150ccb23f89286" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "7b01e2974a47d489bb92f47a41e4c0088ea8f86e" },
"mason.nvim": { "branch": "main", "commit": "cbf8d285e1462dd24acf3507817be2bbcb035919" },
"mini.icons": { "branch": "main", "commit": "9c7b1b90b15bdd69c52f6e31889dbc9987c30ec4" },
"mini.map": { "branch": "stable", "commit": "234eaf5cbcaee320d87e96465fbb534aa05b301e" },
"mini.starter": { "branch": "main", "commit": "35b018a035794e341ac01cb2091bbd71b3f823d0" },
"neo-tree.nvim": { "branch": "v3.x", "commit": "ebd66767191714e008ce73b769518a763ff31bdc" },
"neowiki.nvim": { "branch": "main", "commit": "85dddf6057b07d4d6772b2f90e754a18e958a865" },
"nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" },
"nvim-autopairs": { "branch": "master", "commit": "7b9923abad60b903ece7c52940e1321d39eccc79" },
"nvim-cmp": { "branch": "main", "commit": "a1d504892f2bc56c2e79b65c6faded2fd21f3eca" },
"nvim-colorizer.lua": { "branch": "master", "commit": "a065833f35a3a7cc3ef137ac88b5381da2ba302e" },
"nvim-lsp-file-operations": { "branch": "master", "commit": "b9c795d3973e8eec22706af14959bc60c579e771" },
"nvim-lspconfig": { "branch": "master", "commit": "246572944c2a1e2a646c2e7609ff619b0fe74c18" },
"lualine.nvim": { "branch": "master", "commit": "221ce6b2d999187044529f49da6554a92f740a96" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "137bd0feba2c1885545b6934d36f5e5aa6adb486" },
"mason.nvim": { "branch": "main", "commit": "2a6940af80375532e5e9e7c1f2fc6319a1b7a69d" },
"mini.starter": { "branch": "main", "commit": "25de4998197d59673f1918968a8f4060195edca0" },
"neo-tree.nvim": { "branch": "v3.x", "commit": "1a14083046d96e88e361d1da00761c40d45012f3" },
"nui.nvim": { "branch": "main", "commit": "10fc361835c856ba4233ef5ea135b919bf3dce97" },
"nvim-autopairs": { "branch": "master", "commit": "430522f95fe4fb7c511ec64f8c1a90cc6a66c05c" },
"nvim-cmp": { "branch": "main", "commit": "2ffe79f1f021def8dd1fcd81deb16f1bb0d989f3" },
"nvim-colorizer.lua": { "branch": "master", "commit": "72a05f62c52241bc7441c820eb53946f92b2e6a4" },
"nvim-lsp-file-operations": { "branch": "master", "commit": "0b939aff068c859b6f8cdbc3b3e676d038e6e15d" },
"nvim-lspconfig": { "branch": "master", "commit": "046b1a797af1effe8e0474b9af9657a3761ec58a" },
"nvim-tcss": { "branch": "main", "commit": "bf9001416158f32fe7e92c42de94de3595aa13e5" },
"nvim-treesitter": { "branch": "main", "commit": "4916d6592ede8c07973490d9322f187e07dfefac" },
"nvim-treesitter": { "branch": "main", "commit": "f603a2f4da48728f80257fb5fbb90145fd1dc173" },
"nvim-ts-autotag": { "branch": "main", "commit": "88c1453db4ba7dd24131086fe51fdf74e587d275" },
"nvim-web-devicons": { "branch": "master", "commit": "7d8dad2c837fcdf2e65997e68657c1a21c568074" },
"nvim-web-devicons": { "branch": "master", "commit": "58447c1fca354bbf184425e4a8d01deecbd6f3c4" },
"nvim-window-picker": { "branch": "main", "commit": "6382540b2ae5de6c793d4aa2e3fe6dbb518505ec" },
"outline.nvim": { "branch": "main", "commit": "c293eb56db880a0539bf9d85b4a27816960b863e" },
"outline.nvim": { "branch": "main", "commit": "2a132953b944561d45b52e4541ebfff71934a742" },
"plenary.nvim": { "branch": "master", "commit": "74b06c6c75e4eeb3108ec01852001636d85a932b" },
"render-markdown.nvim": { "branch": "main", "commit": "629eb9533ec989d9d5c6cab8f3ad5372422c24e0" },
"render-markdown.nvim": { "branch": "main", "commit": "640a3ec6d538bad17c328be373c7cad0293d9589" },
"rustaceanvim": { "branch": "main", "commit": "e9c5aaba16fead831379d5f44617547a90b913c7" },
"telescope-file-browser.nvim": { "branch": "master", "commit": "3610dc7dc91f06aa98b11dca5cc30dfa98626b7e" },
"telescope.nvim": { "branch": "0.1.x", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" },
"toggleterm.nvim": { "branch": "main", "commit": "50ea089fc548917cc3cc16b46a8211833b9e3c7c" },
"vim-fugitive": { "branch": "master", "commit": "3b753cf8c6a4dcde6edee8827d464ba9b8c4a6f0" },
"which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" }
}

View file

@ -1,8 +1,5 @@
local ts = require("nvim-treesitter.parsers")
ts.filetype_to_parsername.swayconfig = "i3"
vim.filetype.add({
pattern = {
[".*/sway/config.*"] = "swayconfig",
},
extension = {
h = "c",
},
})

View file

@ -31,5 +31,36 @@ require("lazy").setup({
-- colorscheme that will be used when installing plugins.
install = { colorscheme = { "habamax" } },
-- automatically check for plugin updates
checker = { enabled = true },
checker = { enabled = false },
})
local lazy_update_group =
vim.api.nvim_create_augroup("LazyAutoUpdate", { clear = true })
-- Fermer l'interface lorsque la mise à jour est terminée
vim.api.nvim_create_autocmd("User", {
group = lazy_update_group,
pattern = "LazyUpdate",
once = true,
callback = function()
vim.schedule(function()
local ok, view = pcall(require, "lazy.view")
if ok and view.view and view.visible() then
view.view:close()
end
end)
end,
})
-- Lancer la mise à jour à l'ouverture de Neovim
vim.api.nvim_create_autocmd("VimEnter", {
group = lazy_update_group,
once = true,
callback = function()
vim.schedule(function()
require("lazy").update({
show = true,
})
end)
end,
})

View file

@ -1,40 +1,89 @@
-- Capabilities avec cmp si disponible
local capabilities = vim.lsp.protocol.make_client_capabilities()
local ok_cmp, cmp_lsp = pcall(require, "cmp_nvim_lsp")
if ok_cmp then
capabilities = cmp_lsp.default_capabilities(capabilities)
capabilities = cmp_lsp.default_capabilities(capabilities)
end
local lspconfig = require("lspconfig")
-- Groupe nettoyé à chaque chargement de la configuration
local lsp_attach_group = vim.api.nvim_create_augroup(
"fy59_lsp_attach",
{ clear = true }
)
-- Fonction appelée quand un serveur LSP se connecte à un buffer
local on_attach = function(_, bufnr)
local map = function(mode, lhs, rhs, desc)
vim.keymap.set(mode, lhs, rhs, { buffer = bufnr, desc = desc })
end
-- Keymaps LSP
vim.api.nvim_create_autocmd("LspAttach", {
group = lsp_attach_group,
-- Keymaps de base LSP
map("n", "gd", vim.lsp.buf.definition, "LSP: Go to definition")
map("n", "gr", vim.lsp.buf.references, "LSP: References")
map("n", "K", vim.lsp.buf.hover, "LSP: Hover")
map("n", "<leader>rn", vim.lsp.buf.rename, "LSP: Rename")
map("n", "<leader>ca", vim.lsp.buf.code_action, "LSP: Code action")
map("n", "[d", vim.diagnostic.goto_prev, "LSP: Prev diagnostic")
map("n", "]d", vim.diagnostic.goto_next, "LSP: Next diagnostic")
callback = function(args)
local bufnr = args.buf
-- Format on save (si le serveur sait formater)
vim.api.nvim_create_autocmd("BufWritePre", {
buffer = bufnr,
callback = function()
vim.lsp.buf.format({ async = false })
local map = function(lhs, rhs, desc)
vim.keymap.set("n", lhs, rhs, {
buffer = bufnr,
desc = desc,
})
end
map("ld", vim.lsp.buf.definition, "LSP: Go to definition")
map("lD", vim.lsp.buf.declaration, "LSP: Go to declaration")
map("lr", vim.lsp.buf.references, "LSP: References")
map("K", vim.lsp.buf.hover, "LSP: Hover")
map("<leader>rn", vim.lsp.buf.rename, "LSP: Rename")
map("<leader>ca", vim.lsp.buf.code_action, "LSP: Code action")
map("<leader>e", vim.diagnostic.open_float, "LSP: Show diagnostic")
map("[d", function()
vim.diagnostic.jump({ count = -1 })
end, "LSP: Prev diagnostic")
map("]d", function()
vim.diagnostic.jump({ count = 1 })
end, "LSP: Next diagnostic")
end,
})
end
-- Pyright pour Python
-- Exemple approximatif avec la future API
local cfg = vim.lsp._config -- ou vim.lsp.config selon la version
cfg.setup("pyright", {
on_attach = on_attach,
capabilities = capabilities,
})
-- Configuration des serveurs
vim.lsp.config("pyright", {
capabilities = capabilities,
})
vim.lsp.config("bashls", {
capabilities = capabilities,
})
vim.lsp.config("lua_ls", {
capabilities = capabilities,
settings = {
Lua = {
diagnostics = {
globals = { "vim" },
},
},
},
})
vim.lsp.config("clangd", {
capabilities = capabilities,
cmd = {
"clangd",
"--background-index",
"--clang-tidy",
},
on_attach = function(client)
client.server_capabilities.semanticTokensProvider = nil
end,
})
-- Activation des serveurs
vim.lsp.enable({
"clangd",
"pyright",
"bashls",
"lua_ls",
})
-- rust_analyzer est géré par rustaceanvim

View file

@ -1,61 +1,103 @@
local map = vim.keymap.set
local opts = { noremap = true, silent = true }
-- Recherche
map("n", "<leader>h", "<cmd>nohlsearch<cr>", { desc = "Clear hlsearch" })
-- neo-tree
vim.keymap.set("n", "<C-n>", "<cmd>Neotree toggle<CR>", { silent = true, desc = "Explorer" })
map("n", "<C-n>", "<cmd>Neotree toggle<CR>", { silent = true, desc = "Explorer" })
local telescope = require("telescope.builtin")
-- Fuzzy find files
vim.keymap.set("n", "<leader>ff", telescope.find_files, { desc = "Find files" })
-- Live grep
vim.keymap.set("n", "<leader>fg", telescope.live_grep, { desc = "Live grep" })
-- Buffers
vim.keymap.set("n", "<leader>fb", telescope.buffers, { desc = "Find buffers" })
-- Help tags
vim.keymap.set("n", "<leader>fh", telescope.help_tags, { desc = "Find help" })
-- Telescope
map("n", "<leader>ff", telescope.find_files, { desc = "Find files" })
map("n", "<leader>fg", telescope.live_grep, { desc = "Live grep" })
map("n", "<leader>fb", telescope.buffers, { desc = "Find buffers" })
map("n", "<leader>fh", telescope.help_tags, { desc = "Find help" })
-- LSP
vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts)
vim.keymap.set("n", "gr", vim.lsp.buf.references, opts)
vim.keymap.set("n", "K", vim.lsp.buf.hover, opts)
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts)
vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, opts)
vim.keymap.set("n", "<leader>d", vim.diagnostic.open_float, opts)
vim.keymap.set("n", "[d", vim.diagnostic.goto_prev, opts)
vim.keymap.set("n", "]d", vim.diagnostic.goto_next, opts)
map("n", "gd", vim.lsp.buf.definition, opts)
map("n", "gr", vim.lsp.buf.references, opts)
map("n", "K", vim.lsp.buf.hover, opts)
map("n", "<leader>rn", vim.lsp.buf.rename, opts)
map("n", "<leader>ca", vim.lsp.buf.code_action, opts)
map("n", "<leader>d", vim.diagnostic.open_float, opts)
map("n", "[d", vim.diagnostic.goto_prev, opts)
map("n", "]d", vim.diagnostic.goto_next, opts)
-- Indenter en mode Visuel avec Tab / Shift-Tab
vim.keymap.set("v", "<Tab>", ">gv", { desc = "Indent selection" })
vim.keymap.set("v", "<S-Tab>", "<gv", { desc = "Unindent selection" })
require("which-key").add({
-- mappings sans <leader>
{ "f", group = "find" },
{ "ff", "<cmd>Telescope find_files<cr>", desc = "Find files" },
{ "fg", "<cmd>Telescope live_grep<cr>", desc = "Live grep" },
{ "fb", "<cmd>Telescope buffers<cr>", desc = "Buffers" },
{ "fh", "<cmd>Telescope help_tags<cr>", desc = "Help tags" },
-- mappings sans <leader>
{ "<leader>f", group = "find" },
{ "ff", "<cmd>Telescope find_files<cr>", desc = "Find files" },
{ "fg", "<cmd>Telescope live_grep<cr>", desc = "Live grep" },
{ "fb", "<cmd>Telescope buffers<cr>", desc = "Buffers" },
{ "fh", "<cmd>Telescope help_tags<cr>", desc = "Help tags" },
{ "w", group = "write" },
{ "ww", "<cmd>w<cr>", desc = "Write file" },
{ "w", group = "write" },
{ "ww", "<cmd>w<cr>", desc = "Write file" },
-- mappings sous <leader>
{ "<leader>f", group = "file" },
{ "<leader>ff", "<cmd>Telescope find_files<cr>", desc = "Find files" },
{ "<leader>fg", "<cmd>Telescope live_grep<cr>", desc = "Live grep" },
--Git
{ "<leader>g", group = "Git"},
{ "<leader>gs", "<cmd>Git status<cr>", desc = "Git status" },
{ "<leader>ga", "<cmd>Git add .<cr>", desc = "Git add all" },
{ "<leader>gc", "<cmd>Git commit<cr>", desc = "Git commit" },
{ "<leader>gp", "<cmd>Git push<cr>", desc = "Git push" },
})
vim.keymap.set("x", "<Tab>", ">gv", { desc = "Indent selection" })
vim.keymap.set("x", "<S-Tab>", "<gv", { desc = "Unindent selection" })
local function devcontainer()
local container = vim.fn.getenv("DEVCONTAINER_ID")
if container == vim.NIL or container == nil or container == "" then
vim.notify("Aucun DEVCONTAINER_ID trouvé", vim.log.levels.ERROR)
return nil
end
return tostring(container)
end
local function docker_cmd(cmd)
local container = devcontainer()
if not container then
return
end
vim.cmd("write")
vim.cmd("terminal docker exec -it -u vscode " .. container .. " zsh -lc '" .. cmd .. "'")
end
vim.keymap.set("n", "<F5>", function()
local file = vim.fn.expand("%")
local out = vim.fn.expand("%:r")
docker_cmd("gcc -Wall -Wextra -std=c17 -g " .. file .. " -o " .. out)
end, { desc = "GCC compile current file" })
vim.keymap.set("n", "<F6>", function()
local out = vim.fn.expand("%:r")
docker_cmd("./" .. out)
end, { desc = "Run current program" })
vim.keymap.set("n", "<F7>", function()
local out = vim.fn.expand("%:r")
docker_cmd("gdb ./" .. out)
end, { desc = "Debug with GDB" })
vim.keymap.set("n", "<F8>", function()
local out = vim.fn.expand("%:r")
docker_cmd("valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./" .. out)
end, { desc = "Run Valgrind" })
vim.keymap.set("n", "<leader>cb", function()
docker_cmd(
"cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON && cmake --build build --parallel")
end, { desc = "CMake build" })
vim.keymap.set("n", "<leader>cc", function()
docker_cmd("cmake --build build --target clean")
end, { desc = "CMake clean" })
vim.keymap.set("n", "<leader>cp", function()
docker_cmd("cppcheck --enable=all --std=c17 --suppress=missingIncludeSystem -I include src")
end, { desc = "Cppcheck project" })

View file

@ -1,6 +1,5 @@
return {
"norcalli/nvim-colorizer.lua",
config = function()
require("colorizer").setup()
end,
"catgoose/nvim-colorizer.lua",
event = "BufReadPre",
opts = {},
}

View file

@ -1,9 +0,0 @@
return {
{
"lewis6991/gitsigns.nvim",
opts = {
current_line_blame = true,
},
},
}

View file

@ -1,15 +1,42 @@
return {
"mason-org/mason-lspconfig.nvim",
opts = {
ensure_installed = {
"pyright"
-- Mason
{
"mason-org/mason.nvim",
opts = {},
},
-- Bridge Mason <-> lspconfig
{
"mason-org/mason-lspconfig.nvim",
opts = {
ensure_installed = {
"pyright", -- Python (tu l'avais déjà)
"bashls", -- Bash
"lua_ls", -- Lua
-- rust_analyzer : géré par rustaceanvim, pas ici
},
automatic_enable = {
exclude = { "rust_analyzer" },
},
},
dependencies = {
{ "mason-org/mason.nvim", opts = {} },
"neovim/nvim-lspconfig",
},
},
dependencies = {
{
"mason-org/mason.nvim",
opts = {}
},
-- nvim-lspconfig : chargé, config dans lsp-setup.lua
{
"neovim/nvim-lspconfig",
config = function()
require("config.lsp-setup")
end,
},
-- Rust : rustaceanvim
{
"mrcjkb/rustaceanvim",
version = "^5",
lazy = false,
},
}

View file

@ -1,13 +0,0 @@
-- lua/plugins/mini-icons.lua
return {
"nvim-mini/mini.icons",
lazy = true, -- ou enlève lazy si tu veux partout
opts = {
-- style = "glyph", -- icônes Nerd Font (par défaut)
-- style = "ascii", -- si ton terminal n’a pas de Nerd Font
},
config = function(_, opts)
require("mini.icons").setup(opts)
end,
}

View file

@ -1,30 +0,0 @@
return {
{
"echasnovski/mini.map",
branch = "stable",
config = function()
local map = require("mini.map")
map.setup({
symbols = {
encode = map.gen_encode_symbols.dot("4x2"),
},
integrations = {
map.gen_integration.builtin_search(),
map.gen_integration.diagnostic(),
map.gen_integration.gitsigns(),
},
})
-- PAS d'ouverture auto : bloc autocmd commenté
-- <leader>p : toggle minimap
vim.keymap.set("n", "<leader>p", function()
map.toggle()
end, {
desc = "Toggle minimap",
})
end,
},
}

View file

@ -1,17 +0,0 @@
return {
"echaya/neowiki.nvim",
opts = {
wiki_dirs = {
-- neowiki.nvim supports both absolute and tilde-expanded paths
{ name = "Pentest", path = "~/.dotfiles/wiki/Wiki/pentest/" },
{ name = "Osint", path = "~/.dotfiles/wiki/Wiki/osint/" },
{ name = "Python", path = "~/.dotfiles/wiki/Wiki/python/" },
{ name = "ArchASP", path = "~/.dotfiles/wiki/Wiki/archasp/" },
},
},
keys = {
{ "<leader>ww", "<cmd>lua require('neowiki').open_wiki()<cr>", desc = "Open Wiki" },
{ "<leader>wW", "<cmd>lua require('neowiki').open_wiki_floating()<cr>", desc = "Open Wiki in Floating Window" },
{ "<leader>wT", "<cmd>lua require('neowiki').open_wiki_new_tab()<cr>", desc = "Open Wiki in Tab" },
},
}

View file

@ -1,11 +1,10 @@
return {
{
"windwp/nvim-autopairs",
event = "InsertEnter",
opts = {
disable_filetype = { "TelescopePrompt", "vim" },
-- tu pourras ajuster ici (ignored_next_char, fast_wrap, etc.)
{
"windwp/nvim-autopairs",
event = "InsertEnter",
opts = {
disable_filetype = { "TelescopePrompt", "vim" },
-- tu pourras ajuster ici (ignored_next_char, fast_wrap, etc.)
},
},
},
}

View file

@ -1,12 +0,0 @@
return {
"nvim-tree/nvim-tree.lua",
dependencies = { "nvim-tree/nvim-web-devicons" },
opts = {
hijack_netrw = true,
sync_root_with_cwd = true,
view = { width = 30 },
renderer = { group_empty = true },
filters = { dotfiles = false },
},
}

View file

@ -1,15 +1,18 @@
---@type LazySpec
--@type LazySpec
return {
{
"MeanderingProgrammer/render-markdown.nvim",
dependencies = {
"nvim-treesitter/nvim-treesitter",
"nvim-tree/nvim-web-devicons", -- ou mini.icons si tu utilises mini
{
"MeanderingProgrammer/render-markdown.nvim",
dependencies = {
"nvim-treesitter/nvim-treesitter",
"nvim-tree/nvim-web-devicons", -- ou mini.icons si tu utilises mini
},
opts = {
-- preset = "lazy", -- tu peux tester ce preset plus tard
enabled = true,
file_types = { "markdown" },
latex = {
enabled = false,
},
},
},
opts = {
-- preset = "lazy", -- tu peux tester ce preset plus tard
enabled = true,
file_types = { "markdown" },
},
},
}

View file

@ -1,46 +1,40 @@
return {
{
"nvim-mini/mini.starter",
version = false,
config = function()
local starter = require("mini.starter")
{
"nvim-mini/mini.starter",
version = false,
config = function()
local starter = require("mini.starter")
starter.setup({
starter.setup({
autoopen = true,
header = table.concat({
"███╗ ██╗███████╗ ██████╗ ██╗ ██╗██╗███╗ ███╗",
"████╗ ██║██╔════╝██╔═══██╗██║ ██║██║████╗ ████║",
"██╔██╗ ██║█████╗ ██║ ██║██║ ██║██║██╔████╔██║",
"██║╚██╗██║██╔══╝ ██║ ██║╚██╗ ██╔╝██║██║╚██╔╝██║",
"██║ ╚████║███████╗╚██████╔╝ ╚████╔╝ ██║██║ ╚═╝ ██║",
"",
"##############################################################",
"#### FY59's nvim config ####",
"##############################################################",
"",
"███╗ ██╗███████╗ ██████╗ ██╗ ██╗██╗███╗ ███╗",
"████╗ ██║██╔════╝██╔═══██╗██║ ██║██║████╗ ████║",
"██╔██╗ ██║█████╗ ██║ ██║██║ ██║██║██╔████╔██║",
"██║╚██╗██║██╔══╝ ██║ ██║╚██╗ ██╔╝██║██║╚██╔╝██║",
"██║ ╚████║███████╗╚██████╔╝ ╚████╔╝ ██║██║ ╚═╝ ██║",
"",
"##############################################################",
"#### FY59's nvim config ####",
"##############################################################",
"",
}, "\n"),
items = {
starter.sections.recent_files(8),
{
name = "Open Wiki",
action = "edit ~/wiki/index.md", -- adapte le chemin
section = "󰖬 Wiki",
},
starter.sections.telescope(),
{
name = "Open Nvim config",
action = "edit ~/.config/nvim/init.lua",
section = " Config",
},
{
name = "Quit",
action = "quit",
section = "󰈆 Actions",
},
},
footer = "Happy editing – from FY59's config",
})
starter.sections.recent_files(8),
starter.sections.telescope(),
{
name = "Open Nvim config",
action = "edit ~/.config/nvim/init.lua",
section = "Config",
},
{
name = "Quit",
action = "quit",
section = "Actions",
},
},
footer = "Happy editing – from FY59's config",
})
end,
},
},
}

View file

@ -0,0 +1,7 @@
return {
"akinsho/toggleterm.nvim",
version = "*",
config = function()
require("toggleterm").setup()
end,
}

View file

@ -1,27 +1,29 @@
return {
"nvim-treesitter/nvim-treesitter",
build = ":TSUpdate",
opts = {
ensure_installed = {
"bash",
"c",
"lua",
"vim",
"vimdoc",
"markdown",
"markdown_inline",
"query",
"python",
"html",
"nvim-treesitter/nvim-treesitter",
build = ":TSUpdate",
opts = {
ensure_installed = {
"bash",
"c",
"lua",
"vim",
"vimdoc",
"markdown",
"markdown_inline",
"query",
"python",
"html",
"yaml",
"latex",
"rust",
},
auto_install = true,
highlight = {
enable = true,
additional_vim_regex_highlighting = {},
},
indent = {
enable = true,
},
},
auto_install = true,
highlight = {
enable = true,
additional_vim_regex_highlighting = {},
},
indent = {
enable = true,
},
},
}

View file

@ -29,9 +29,7 @@ Objectif : un setup léger, lisible, facile à maintenir et à hacker.
│   ├── lsp.lua
│   ├── mini-icons.lua
│   ├── mini_map.lua
│   ├── neowiki.lua
│   ├── nvim-autopair.lua
│   ├── nvim-tree.lua.old
│   ├── outline.lua
│   ├── render-markdown.lua
│   ├── starter.lua
@ -153,16 +151,9 @@ Keymaps personnalisés :
- lewis6991/gitsigns.nvim pour les signes Git dans la marge.
- tpope/vim-fugitive
9. Notes / Wiki
- echaya/neowiki.nvim comme wiki moderne (successeur de Vimwiki).
10. starter
9. starter
- nvim-mini/mini.starter
Support Markdown + Treesitter, GTD, multiple wikis.
Mappings typiques (configurable) : <leader>ww pour ouvrir le wiki, navigation entre pages, tâches, etc.
## Keymaps principaux
- folke/which-key.nvim
@ -195,4 +186,3 @@ LSP
- <leader>h : clear search.
En Visuel : Tab / Shift-Tab → indent/désindent la sélection.

View file

@ -0,0 +1,3 @@
{
"$schema": "https://opencode.ai/config.json"
}

View file

@ -31,6 +31,8 @@ Personal SwayFX configuration, modular and lightweight, designed for everyday Wa
- swayfx
- swaylock
- swayidle
- tlp
- tlp-pd
### Bar and status
- i3status-rs
@ -45,8 +47,6 @@ Personal SwayFX configuration, modular and lightweight, designed for everyday Wa
- cliphist
- wlsunset
- brightnessctl
- powerprofilesctl
- swaync
- nm-connection-editor
- playerctl
@ -87,7 +87,7 @@ Example:
The Sway bar is placed at the top and uses `i3status-rs` as its backend.
The `i3status.toml` file includes:
The i3status-rust configuration includes:
- workspaces,
- focused window,
- music,
@ -103,11 +103,8 @@ The `i3status.toml` file includes:
## Autostart
On startup, the config launches:
- `wlsunset` for blue light reduction,
- `wl-paste --watch cliphist store` for clipboard history,
- `swayidle` for automatic locking and screen power management.
- `swaync`
On startup, Sway launches the inactive-window transparency helper, LiMusic and
`autotiling`. Wlsunset, Cliphist and swayidle are owned by user systemd units.
## Keybinds
@ -116,25 +113,26 @@ Some important shortcuts:
- `Mod + q`: close the focused window.
- `Mod + Shift + e`: exit Sway via `swaynag`.
- `Mod + r`: resize mode.
- `Mod + Shift + c`: reload the config.
- `Mod + Ctrl + l`: lock the screen.
- `Mod + Ctrl + r`: reload the config.
- `Mod + Alt + o`: lock the screen.
- `Print`: capture a selected area to the clipboard.
- `Shift + Print`: capture the full screen to the clipboard.
- `Mod + Ctrl + e`: launcher wofi
- `Mod + v`: wofi cliphist
- `Mod + F9``Mod + F10``Mod + F11`: power profiles
- `Mod + Alt + l`: launcher Wofi.
- `Mod + Alt + v`: Cliphist via Wofi.
- `Mod + F9`, `Mod + F10`, `Mod + F11`: TLP power profiles.
## Power profiles
The bar includes a `powerprofilesctl` block with:
The bar displays the current TLP and platform profiles. The related keybinds
use the unprivileged `tlpctl` interface provided by `tlp-pd`:
- `performance`,
- `balanced`,
- `power-saver`.
The related keybinds are:
- `Mod + F9`: power-saver.
- `Mod + F10`: balanced.
- `Mod + F11`: performance.
- `Mod + F9`: `tlpctl power-saver`.
- `Mod + F10`: `tlpctl balanced`.
- `Mod + F11`: `tlpctl performance`.
## Floating windows

43
sway/.config/sway/autostart Executable file → Normal file
View file

@ -2,16 +2,6 @@
# Autostart #
# =========== #
# =================================================
# Filtre lumière bleue (wlsunset)
# Notifications (swaync)
# gnome-keyring-daemon
# protonmail-bridge
#
# Les outils précédent ont été ajouter à systemd --user
#
# =================================================
# =================================================
# Transparence
# =================================================
@ -22,38 +12,11 @@ exec python3 ~/.config/sway/scripts/inactive-windows-transparency.py
# Règles d'assignation automatique
# =================================================
assign [app_id="kitty-1"] workspace 1
assign [app_id="kitty-2"] workspace 1
assign [app_id="electron" title="Perplexity"] workspace 1
assign [app_id="chromium"] workspace 2
assign [app_id="firefox"] workspace 3
assign [app_id="proton-bridge"] workspace 9
assign [app_id="org.mozilla.Thunderbird"] workspace 9
assign [class="Spotify"] workspace 10
assign [app_id="limusic-app"] workspace 10
# =================================================
# Lancement des applications
# =================================================
exec kitty --class kitty-1 --directory $HOME
exec kitty --class kitty-2 --directory $HOME
exec perplexity
exec chromium
exec thunderbird
exec spotify-launcher
exec ~/.config/sway/scripts/layout-workspace1.sh
# =================================================
# Presse-papier
# =================================================
exec wl-paste --watch clipvault store
exec wl-paste --type image/png --watch clipvault store
# =================================================
# Verrouillage auto (swayidle)
# =================================================
exec-once=swayidle -w timeout 300 'swaylock -f -c 000000' timeout 301 'systemctl suspend' before-sleep 'swaylock -f -c 000000'
exec limusic-app
exec autotiling

View file

@ -5,7 +5,7 @@
include ~/.config/sway/catppuccin-mocha
bar {
font pango:JetBrainsMono Nerd Font 12
font pango:Fira Code 12
position top
status_command i3status-rs ~/.config/i3status-rust/config.toml
colors {
@ -18,6 +18,6 @@ bar {
focused_workspace $base $mauve $crust
active_workspace $base $surface2 $text
inactive_workspace $base $base $text
urgent_workspace $base $red $crust
urgent_workspace $base $peach $crust
}
}

View file

@ -14,20 +14,20 @@ set $right l
set $term kitty
# Start a terminal
bindsym $mod+Return exec $term
bindsym $mod+Return exec $term
# Kill focused window
bindsym $mod+q kill
bindsym $mod+q exec ~/.local/bin/sway-close
# Drag floating windows by holding down $mod and left mouse button.
# Resize them with right mouse button + $mod.
# Despite the name, also works for non-floating windows.
# Change normal to inverse to use left mouse button for resizing and right
# mouse button for dragging.
floating_modifier $mod normal
floating_modifier $mod normal
# Exit sway (logs you out of your Wayland session)
bindsym $mod+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -B 'Yes, exit sway' 'swaymsg exit'
bindsym $mod+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -B 'Yes, exit sway' 'swaymsg exit'
###############################################
@ -37,28 +37,28 @@ set $term kitty
###############################################
# Move your focus around
bindsym $mod+$left focus left
bindsym $mod+$down focus down
bindsym $mod+$up focus up
bindsym $mod+$right focus right
bindsym $mod+$left focus left
bindsym $mod+$down focus down
bindsym $mod+$up focus up
bindsym $mod+$right focus right
# Or use $mod+[up|down|left|right]
bindsym $mod+Left focus left
bindsym $mod+Down focus down
bindsym $mod+Up focus up
bindsym $mod+Right focus right
bindsym $mod+Left focus left
bindsym $mod+Down focus down
bindsym $mod+Up focus up
bindsym $mod+Right focus right
# Move the focused window with the same, but add Shift
bindsym $mod+Shift+$left move left
bindsym $mod+Shift+$down move down
bindsym $mod+Shift+$up move up
bindsym $mod+Shift+$right move right
bindsym $mod+Ctrl+$left move left
bindsym $mod+Ctrl+$down move down
bindsym $mod+Ctrl+$up move up
bindsym $mod+Ctrl+$right move right
# Ditto, with arrow keys
bindsym $mod+Shift+Left move left
bindsym $mod+Shift+Down move down
bindsym $mod+Shift+Up move up
bindsym $mod+Shift+Right move right
bindsym $mod+Ctrl+Left move left
bindsym $mod+Ctrl+Down move down
bindsym $mod+Ctrl+Up move up
bindsym $mod+Ctrl+Right move right
###############################################
#
@ -67,28 +67,28 @@ set $term kitty
###############################################
# Switch to workspace
bindsym $mod+ampersand workspace number 1
bindsym $mod+eacute workspace number 2
bindsym $mod+quotedbl workspace number 3
bindsym $mod+apostrophe workspace number 4
bindsym $mod+parenleft workspace number 5
bindsym $mod+minus workspace number 6
bindsym $mod+egrave workspace number 7
bindsym $mod+underscore workspace number 8
bindsym $mod+ccedilla workspace number 9
bindsym $mod+agrave workspace number 10
bindsym $mod+ampersand workspace number 1
bindsym $mod+eacute workspace number 2
bindsym $mod+quotedbl workspace number 3
bindsym $mod+apostrophe workspace number 4
bindsym $mod+parenleft workspace number 5
bindsym $mod+minus workspace number 6
bindsym $mod+egrave workspace number 7
bindsym $mod+underscore workspace number 8
bindsym $mod+ccedilla workspace number 9
bindsym $mod+agrave workspace number 10
# Move focused container to workspace
bindsym $mod+Shift+ampersand move container to workspace number 1
bindsym $mod+Shift+eacute move container to workspace number 2
bindsym $mod+Shift+quotedbl move container to workspace number 3
bindsym $mod+Shift+apostrophe move container to workspace number 4
bindsym $mod+Shift+parenleft move container to workspace number 5
bindsym $mod+Shift+minus move container to workspace number 6
bindsym $mod+Shift+egrave move container to workspace number 7
bindsym $mod+Shift+underscore move container to workspace number 8
bindsym $mod+Shift+ccedilla move container to workspace number 9
bindsym $mod+Shift+agrave move container to workspace number 10
bindsym $mod+Ctrl+ampersand move container to workspace number 1
bindsym $mod+Ctrl+eacute move container to workspace number 2
bindsym $mod+Ctrl+quotedbl move container to workspace number 3
bindsym $mod+Ctrl+apostrophe move container to workspace number 4
bindsym $mod+Ctrl+parenleft move container to workspace number 5
bindsym $mod+Ctrl+minus move container to workspace number 6
bindsym $mod+Ctrl+egrave move container to workspace number 7
bindsym $mod+Ctrl+underscore move container to workspace number 8
bindsym $mod+Ctrl+ccedilla move container to workspace number 9
bindsym $mod+Ctrl+agrave move container to workspace number 10
# Note: workspaces can have any name you want, not just numbers.
# We just use 1-10 as the default.
@ -99,36 +99,28 @@ set $term kitty
#
###############################################
bindsym $mod+N exec swaync-client -t
###############################################
#
# Layout stuff
#
###############################################
# You can "split" the current object of your focus with
# $mod+b or $mod+v, for horizontal and vertical splits
# respectively.
# bindsym $mod+b splith
# bindsym $mod+v splitv
bindsym $mod+b splith
bindsym $mod+v splitv
# Switch the current container between different layout styles
bindsym $mod+s layout stacking
bindsym $mod+w layout tabbed
bindsym $mod+e layout toggle split
bindsym $mod+s layout stacking
bindsym $mod+w layout tabbed
bindsym $mod+e layout toggle split
# Make the current focus fullscreen
bindsym $mod+f fullscreen
bindsym $mod+f fullscreen
# Toggle the current focus between tiling and floating mode
bindsym $mod+Shift+space floating toggle
bindsym $mod+Ctrl+space floating toggle
# Swap focus between the tiling area and the floating area
bindsym $mod+space focus mode_toggle
bindsym $mod+space focus mode_toggle
# Move focus to the parent container
bindsym $mod+a focus parent
bindsym $mod+a focus parent
###############################################
#
@ -140,11 +132,10 @@ bindsym $mod+N exec swaync-client -t
# You can send windows there and get them back later.
# Move the currently focused window to the scratchpad
bindsym $mod+Shift+i move scratchpad
bindsym $mod+Ctrl+i move scratchpad
# Show the next scratchpad window or hide the focused scratchpad window.
# If there are multiple scratchpad windows, this command cycles through them.
bindsym $mod+i scratchpad show
bindsym $mod+i scratchpad show
###############################################
@ -184,14 +175,14 @@ bindsym $mod+r mode "resize"
###############################################
# Special keys to adjust volume via PulseAudio
bindsym --locked XF86AudioMute exec pactl set-sink-mute \@DEFAULT_SINK@ toggle
bindsym --locked XF86AudioLowerVolume exec pactl set-sink-volume \@DEFAULT_SINK@ -5%
bindsym --locked XF86AudioRaiseVolume exec pactl set-sink-volume \@DEFAULT_SINK@ +5%
bindsym --locked XF86AudioMicMute exec pactl set-source-mute \@DEFAULT_SOURCE@ toggle
bindsym --locked XF86AudioMute exec pactl set-sink-mute \@DEFAULT_SINK@ toggle
bindsym --locked XF86AudioLowerVolume exec pactl set-sink-volume \@DEFAULT_SINK@ -5%
bindsym --locked XF86AudioRaiseVolume exec pactl set-sink-volume \@DEFAULT_SINK@ +5%
bindsym --locked XF86AudioMicMute exec pactl set-source-mute \@DEFAULT_SOURCE@ toggle
# Special keys to adjust brightness via brightnessctl
bindsym --locked XF86MonBrightnessDown exec brightnessctl set 5%-
bindsym --locked XF86MonBrightnessUp exec brightnessctl set 5%+
bindsym --locked XF86MonBrightnessDown exec brightnessctl set 5%-
bindsym --locked XF86MonBrightnessUp exec brightnessctl set 5%+
###############################################
@ -201,7 +192,7 @@ bindsym $mod+r mode "resize"
###############################################
# Reload Sway config
bindsym $mod+Shift+c Reload
bindsym $mod+Ctrl+r Reload
###############################################
#
@ -209,19 +200,24 @@ bindsym $mod+Shift+c Reload
#
###############################################
bindsym $mod+b exec chromium
bindsym $mod+g exec google-chrome-stable
bindsym $mod+Shift+f exec firefox
bindsym $mod+p exec perplexity
bindsym $mod+m exec spotify-launcher
bindsym $mod+Shift+b exec blueman-manager
bindsym $mod+Ctrl+l exec swaylock
bindsym $mod+Ctrl+e exec wofi --cache-file=/dev/null -Dimage_size=26 -Dynamic_lines=true --location top --yoffset=10 --width=600 --height=300 --gtk-dark --show drun
bindsym $mod+t exec thunderbird
bindsym $mod+Shift+p exec proton-pass
bindsym $mod+Shift+m exec protonmail-bridge
bindsym $mod+Shift+v exec virt-manager
bindsym $mod+Shift+t exec thunar
bindsym $mod+Alt+i exec ~/.local/bin/vmware-on-demand
bindsym $mod+Alt+f exec firefox
bindsym $mod+Alt+a exec AppFlowy
bindsym $mod+Alt+g exec gimp
bindsym $mod+Alt+m exec limusic-app
bindsym $mod+Alt+b exec blueman-manager
bindsym $mod+Alt+o exec swaylock
bindsym $mod+Alt+l exec wofi --cache-file=/dev/null -Dimage_size=26 -Dynamic_lines=true --location top --yoffset=10 --width=600 --height=300 --gtk-dark --show drun
bindsym $mod+Alt+p exec proton-pass
bindsym $mod+Alt+t exec ~/.local/bin/thunderbird-proton
bindsym $mod+Alt+y exec kitty -- sh -c "yazi"
bindsym $mod+Alt+w exec gtk-launch chrome-hnpfjngllnobngcgfapefoaidbinmjnm-Default
bindsym $mod+Alt+v exec ~/.config/sway/scripts/copypast
bindsym $mod+Alt+c exec --no-startup-id kitty --app-id=lardon-freecad-log --title="Lardon · FreeCAD autopush" --directory=/home/fy59/Documents/Lardon /home/fy59/Documents/Lardon/tools/lardon-freecad-launcher
bindsym $mod+Alt+s exec sqlitebrowser
bindsym $mod+Alt+e exec sh -c 'cd /home/fy59/Documents/Enquetes/Template/labfy-investigation && exec ./labfy-investigation'
bindsym $mod+Alt+n exec ~/.local/bin/nextcloud-sync
bindsym $mod+c exec codex-desktop
###############################################
#
@ -232,12 +228,10 @@ bindsym $mod+Shift+t exec thunar
# Special key to take a screenshot with grim
# Shift Print = plein écran -> presse-papier
bindsym Shift+Print exec grim - | wl-copy -t image/png
bindsym Shift+Print exec grim - | wl-copy -t image/png
# Print = zone -> presse-papier
bindsym Print exec grim -g "$(slurp)" - | wl-copy -t image/png
bindsym $mod+v exec ~/.config/sway/scripts/cliphist-wofi-img
# Print = zone -> presse-papier
bindsym Print exec grim -g "$(slurp)" - | wl-copy -t image/png
###############################################
@ -245,7 +239,6 @@ bindsym $mod+Shift+t exec thunar
# Power Daemon
#
###############################################
bindsym $mod+F9 exec powerprofilesctl set power-saver
bindsym $mod+F10 exec powerprofilesctl set balanced
bindsym $mod+F11 exec powerprofilesctl set performance
bindsym $mod+F9 exec tlpctl power-saver
bindsym $mod+F10 exec tlpctl balanced
bindsym $mod+F11 exec tlpctl performance

View file

@ -10,5 +10,5 @@ include ~/.config/sway/bar
include ~/.config/sway/input
include ~/.config/sway/rules
include ~/.config/sway/style
include ~/.config/sway/swayfx
# include ~/.config/sway/swayfx
include ~/.config/sway/autostart

View file

@ -1 +0,0 @@

View file

@ -8,3 +8,12 @@
for_window [app_id="blueman-manager"] floating enable, resize set 40ppt 40ppt, move position center
for_window [app_id="Proton Pass"] floating enable, resize set 40ppt 40ppt, move position right top
#=================================================
# Lardon
#=================================================
for_window [app_id="lardon-freecad-log"] floating enable
for_window [app_id="lardon-freecad-log"] resize set width 850 px height 360 px
for_window [app_id="lardon-freecad-log"] move position center
for_window [app_id="lardon-freecad-log"] border pixel 2

View file

@ -0,0 +1,60 @@
#!/usr/bin/env bash
thumb_dir="${XDG_CACHE_HOME:-$HOME/.cache}/cliphist/thumbs"
mkdir -p "$thumb_dir"
clip_list="$(cliphist list)"
# Nettoyer les vignettes orphelines
for thumb in "$thumb_dir"/*; do
[ -e "$thumb" ] || continue
clip_id="${thumb##*/}"
clip_id="${clip_id%.*}"
if ! printf '%s\n' "$clip_list" | rg -q "^${clip_id}[[:space:]]"; then
rm -f "$thumb"
fi
done
read -r -d '' prog <<EOF
match(\$0, /^([0-9]+)[[:space:]]+\\[\\[ binary data .* (png|jpeg|jpg|bmp|webp) [0-9]+x[0-9]+ \\]\\]/, grp) {
id = grp[1]
ext = grp[2]
if (ext == "jpeg") ext = "jpg"
image = id "." ext
thumb = "$thumb_dir/" image
cmd = "[ -f '" thumb "' ] || printf '%s\\n' '" \$0 "' | cliphist decode | magick - -resize '256x256>' '" thumb "'"
system(cmd)
print "img:" thumb
next
}
1
EOF
choice=$(
gawk "$prog" <<< "$clip_list" |
wofi -I --dmenu --cache-file=/dev/null \
-Dimage_size=100 -Dynamic_lines=true \
--xoffset=600 --yoffset=20 --width=45% --height=45% --gtk-dark
)
[ -z "$choice" ] && exit 1
if [ "${choice:0:4}" = "img:" ]; then
thumb_file="${choice:4}"
clip_id="${thumb_file##*/}"
clip_id="${clip_id%.*}"
printf '%s\n' "$clip_list" |
rg "^${clip_id}[[:space:]]" |
head -n 1 |
cliphist decode |
wl-copy
else
printf '%s\n' "$choice" |
cliphist decode |
wl-copy
fi

View file

@ -58,7 +58,7 @@ if __name__ == "__main__":
"--opacity",
"-o",
type=str,
default="0.70",
default="0.85",
help="set inactive opacity value in range 0...1",
)
parser.add_argument(

View file

@ -3,8 +3,8 @@
#
# Default wallpaper (more resolutions are available in /usr/share/backgrounds/sway/)
output * bg ~/.wallpapers/sway.png fill
output eDP-1 mode 3200x2000 pos 3200 0 scale 1.7
output * bg /usr/share/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png fill
output eDP-1 mode 3200x2000@60Hz pos 3200 0 scale 1.4
#
# Style
@ -22,24 +22,23 @@
# set gtk+ theme
set $gnome-schema org.gnome.desktop.interface
exec_always {
gsettings set $gnome-schema gtk-theme 'catppuccin-mocha-lavender-standard+default'
gsettings set $gnome-schema font-name 'jetbrains mono nerd font 12'
gsettings set $gnome-schema color-scheme 'prefer-dark'
gsettings get $gnome-schema icon-theme 'Tela-circle-blue'
gsettings set $gnome-schema icon-theme 'Tela-circle-blue'
}
set $cursor_theme catppuccin-mocha-lavender-cursors
set $cursor_theme Bibata-Modern-Classic
set $cursor_size 24
seat seat0 xcursor_theme $cursor_theme $cursor_size
# Pas de titre, bordures fines ou nulles
default_border pixel 2
default_floating_border normal
default_floating_border pixel 2
titlebar_border_thickness 0
titlebar_padding 0 0
# Set inner/outer gaps
gaps inner 5
gaps outer -3
gaps outer 0

Some files were not shown because too many files have changed in this diff Show more