diff --git a/README.md b/README.md index c52523c..e73792e 100644 --- a/README.md +++ b/README.md @@ -183,10 +183,12 @@ If you **don’t have the physical macropad**, the table below shows which keybi | `§` | Cheatsheet | | `1` | Open fold | | `2` | Close fold | -| `e1` | Previous error | -| `e2` | Next error | -| `e3` | See error message | -| `e4` | See list of errors | +| `e4` | Previous error | +| `e5` | Next error | +| `e1` | See error message | +| `e3` | See list of errors | +| `e2` | Show correction | +| `e` | Stop grammar LSP | | `f1` | Telescope files | | `f2` | Telescope grep | | `f3` | Telescope buffers | @@ -197,6 +199,8 @@ If you **don’t have the physical macropad**, the table below shows which keybi | `g4` | Go to implementation | | `g5` | Show references | | `` | Launch runner (terminal) | +| `r1` | Run fugit | +| `t` | Count syllabes (french) | All moving macros with ``, `g`, and the recording with `q` are disabled. --- diff --git a/docs/printing.md b/docs/printing.md new file mode 100644 index 0000000..2a6520d --- /dev/null +++ b/docs/printing.md @@ -0,0 +1,187 @@ +Control dashboard: http://localhost:631 + +--- + +# 🧾 Core controls + +```bash +lp file.pdf +``` + +```bash +-d PRINTER # choose printer +-n NUM # number of copies +-t "TITLE" # job name +-q NUM # priority (1–100, higher = sooner) +``` +Printer at the house: `HP_OfficeJet_Pro_7740`. I can't make printing without USB work... + +--- + +## If printer stuck: + +```bash id="enable1" +sudo cupsenable HP_OfficeJet_Pro_7740 +``` + +--- + + +```bash id="accept1" +sudo cupsaccept HP_OfficeJet_Pro_7740 +``` + + +```bash id="cancel1" +cancel -a HP_OfficeJet_Pro_7740 +``` + + +#### 🧪 Verify state + +```bash id="check1" +lpstat -p -d +``` + +You want: + +``` +HP_OfficeJet_Pro_7740 idle, accepting jobs +``` + +--- + +# 📄 Page selection + +```bash +-P 1-5,8,10-20 # specific pages / ranges +-o page-ranges= # same as -P (sometimes more reliable) +``` + +Example: + +```bash +lp -o page-ranges=142-184 file.pdf +``` + +--- + +# 📐 Layout & scaling + +```bash +-o fit-to-page +-o scaling=100 # percent +-o media=A4 +-o orientation-requested=4 # landscape +``` + +Orientation values: + +* `3` = portrait +* `4` = landscape + +--- + +# 🧠 Duplex (double-sided) + +```bash +-o sides=one-sided +-o sides=two-sided-long-edge +-o sides=two-sided-short-edge +``` + +--- + +# 📚 Multiple pages per sheet + +```bash +-o number-up=2 +-o number-up=4 +-o number-up=6 +-o number-up=9 +-o number-up=16 +``` + +--- + +# 🖼️ Image handling + +```bash +-o fit-to-page +-o position=center +-o saturation=100 +-o brightness=100 +``` + +--- + +# 🎨 Color / quality + +```bash +-o ColorModel=Color +-o ColorModel=Gray + +-o print-quality=3 # draft +-o print-quality=4 # normal +-o print-quality=5 # high +``` + +--- + +# 📦 Paper / tray + +```bash +-o media=A4 +-o media=Letter +-o InputSlot=tray1 +-o InputSlot=manual +``` + +--- + +# 🔁 Job handling + +```bash +-H hold # hold job +-H resume # resume job +-H immediate # print ASAP +``` + +--- + +# 🔍 Debug / info + +```bash +lpstat -p -d # printers + default +lpstat -o # jobs +lpoptions -l # printer-specific options +``` + +--- + +# 🔥 Real-world example (what you actually want) + +```bash +lp -d HP_LaserJet \ + -o page-ranges=142-184 \ + -o sides=two-sided-long-edge \ + -o media=A4 \ + -o print-quality=5 \ + file.pdf +``` + +--- + +# ⚠️ Important reality check + +Not all printers support all options. The **real supported ones** come from: + +```bash +lpoptions -p PRINTER_NAME -l +``` + +That command is gold—use it. + +--- + +If you want, tell me your **printer model**, and I’ll give you a *perfect command tuned to it* (no guessing, no trial and error). diff --git a/flake.lock b/flake.lock index a7666f0..d704c3d 100755 --- a/flake.lock +++ b/flake.lock @@ -11,11 +11,11 @@ ] }, "locked": { - "lastModified": 1772764582, - "narHash": "sha256-hSwjmpXHFqzSXrndVekA0IheKrbC7wi0IbfZTYwlmXw=", + "lastModified": 1777726295, + "narHash": "sha256-Db9B3uTLDSj7zjQ4L3tIk9RcxHXbWRKw5fw8JozikyI=", "owner": "caelestia-dots", "repo": "cli", - "rev": "4bcd42f482d038b98145b0b03388244b68b7d35d", + "rev": "a00e71d6b7572a8dbbb7945a45b79acf2401ad56", "type": "github" }, "original": { @@ -33,11 +33,11 @@ "quickshell": "quickshell" }, "locked": { - "lastModified": 1776670101, - "narHash": "sha256-VmPWtG6H+k2tgGnpYwNO5YueHOBdOXXTiBTrjXqcHag=", + "lastModified": 1777891103, + "narHash": "sha256-/b87CUV9NEh4YYtG6tGGbbSJurqkfwZQ5rZNiIBJWYw=", "owner": "caelestia-dots", "repo": "shell", - "rev": "b94ee8d41bad1ea59395d6184425036fa7121bc5", + "rev": "54cdd80c1b7671deeb057cc554f83e436765596a", "type": "github" }, "original": { @@ -53,11 +53,11 @@ ] }, "locked": { - "lastModified": 1775425411, - "narHash": "sha256-KY6HsebJHEe5nHOWP7ur09mb0drGxYSzE3rQxy62rJo=", + "lastModified": 1777851538, + "narHash": "sha256-Gp8qwTEYNoy2yvmErVGlvLOQvrtEECCAKbonW7VJef8=", "owner": "nix-community", "repo": "home-manager", - "rev": "0d02ec1d0a05f88ef9e74b516842900c41f0f2fe", + "rev": "cc09c0f9b7eaa95c2d9827338a5eb03d32505ca5", "type": "github" }, "original": { @@ -119,11 +119,11 @@ }, "nixpkgs-unstable": { "locked": { - "lastModified": 1776329215, - "narHash": "sha256-a8BYi3mzoJ/AcJP8UldOx8emoPRLeWqALZWu4ZvjPXw=", + "lastModified": 1777826146, + "narHash": "sha256-wQ/iN5Zp5VIa3ebBibijPnLyKhor+xEbDy4d0goa9Zs=", "owner": "nixos", "repo": "nixpkgs", - "rev": "b86751bc4085f48661017fa226dee99fab6c651b", + "rev": "73c703c22422b8951895a960959dbbaca7296492", "type": "github" }, "original": { @@ -135,11 +135,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1776560675, - "narHash": "sha256-p68udKWWh7+V4ZPpcMDq0gTHWNZJnr4JPI+kHPPE40o=", + "lastModified": 1777673416, + "narHash": "sha256-5c2POKPOjU40Kh0MirOdScBLG0bu9TAuPYAtPRNZMBs=", "owner": "nixos", "repo": "nixpkgs", - "rev": "e07580dae39738e46609eaab8b154de2488133ce", + "rev": "26ef669cffa904b6f6832ab57b77892a37c1a671", "type": "github" }, "original": { @@ -157,11 +157,11 @@ ] }, "locked": { - "lastModified": 1772925576, - "narHash": "sha256-mMoiXABDtkSJxCYDrkhJ/TrrJf5M46oUfIlJvv2gkZ0=", + "lastModified": 1777706159, + "narHash": "sha256-TuD8hw9lkRCEb+6v93iB7HDvcmvH8R0qyD6wBmPGfv8=", "ref": "refs/heads/master", - "rev": "15a84097653593dd15fad59a56befc2b7bdc270d", - "revCount": 750, + "rev": "8db8ca1fecfcce8def1f9265fa1742baa0e0c271", + "revCount": 813, "type": "git", "url": "https://git.outfoxxed.me/outfoxxed/quickshell" }, diff --git a/flake.nix b/flake.nix index 3313439..0554d6b 100644 --- a/flake.nix +++ b/flake.nix @@ -38,7 +38,7 @@ pkgs = nixpkgs.legacyPackages.${system}; pkgs-unstable = import nixpkgs-unstable { inherit system; - config.allowUnfree = false; + config.allowUnfree = true; #hplipWithPlugins is unfree... }; in { nixosConfigurations = { diff --git a/hosts/laptop/configuration.nix b/hosts/laptop/configuration.nix index bf89d8b..faee357 100755 --- a/hosts/laptop/configuration.nix +++ b/hosts/laptop/configuration.nix @@ -20,6 +20,9 @@ ../../modules/nixos/nixUtils.nix ../../hostsModules/laptop/nixos/udev.nix ../../hostsModules/laptop/nixos/disk.nix + ../../modules/nixos/printer.nix + ../../hostsModules/laptop/nixos/ollama.nix # llm config + ../../modules/nixos/mullvad.nix # vpn config ]; @@ -50,10 +53,21 @@ extraSpecialArgs = {inherit inputs pkgs-unstable;}; }; + services.dbus.enable = true; + security.polkit.enable = true; + environment.pathsToLink = [ "/share/applications" "/share/xdg-desktop-portal" ]; + xdg.portal = { + enable = true; + + extraPortals = [ + pkgs.xdg-desktop-portal-wlr + pkgs.xdg-desktop-portal-gtk + ]; + }; # removes uxterm services.xserver.excludePackages = [pkgs.xterm]; # Bootloader. @@ -120,8 +134,6 @@ # Configure console keymap console.keyMap = "fr_CH"; - # Enable CUPS to print documents. - services.printing.enable = true; # Enable sound with pipewire. services.pulseaudio.enable = false; @@ -156,7 +168,7 @@ # Allow unfree packages - nixpkgs.config.allowUnfree = true; # Nonfree packages: Obsidian + nixpkgs.config.allowUnfree = true; # Nonfree packages: hplipWithPlugin # List packages installed in system profile. To search, run: # $ nix search wget @@ -243,6 +255,7 @@ clang-tools python311Packages.python-lsp-server lua-language-server + ltex-ls-plus pylint black nixd @@ -262,7 +275,8 @@ pkgs-unstable.nixpkgs-review pkgs-unstable.nixfmt-tree pkgs-unstable.treefmt - kakoune + pkgs-unstable.tor-browser + pkgs-unstable.bitwarden-desktop ]; # fonts diff --git a/hosts/laptop/home.nix b/hosts/laptop/home.nix index 6959bb2..236732d 100755 --- a/hosts/laptop/home.nix +++ b/hosts/laptop/home.nix @@ -41,6 +41,8 @@ ../../modules/home-manager/eza.nix # ls replacement ../../modules/home-manager/vivify.nix # neovim markdown viewer (has also config for qutebrowser #../../modules/home-manager/micro.nix # micro text editor. Not main editor (used for testing for notewrapper) + ../../modules/home-manager/sbb-tui.nix # cff TUI app + ../../modules/home-manager/mullvad.nix # mullvad vpn ../../modules/other/desktopEntries.nix # creates .desktop files ]; @@ -78,6 +80,7 @@ (pkgs.callPackage ../../modules/scripts/manix.nix {}) (pkgs.callPackage ../../modules/scripts/man.nix {}) (pkgs.callPackage ../../modules/scripts/trimmer.nix {}) + (pkgs.callPackage ../../modules/scripts/syllabes.nix {}) # python script to get number of syllabes in french (pkgs.callPackage ../../hostsModules/laptop/qt/qtbatticon.nix {}) #pkgs pkgs.gruvbox-gtk-theme diff --git a/hostsModules/laptop/nixos/battery.nix b/hostsModules/laptop/nixos/battery.nix index 1e2080e..1cacc63 100644 --- a/hostsModules/laptop/nixos/battery.nix +++ b/hostsModules/laptop/nixos/battery.nix @@ -1,5 +1,8 @@ # https://discourse.nixos.org/t/what-is-the-best-option-for-power-management/63406/2 -{...}: +{ + lib, + config, + ...}: # we just activate tlp unconditonally #let # cfg = config.custom; @@ -18,6 +21,14 @@ # config = lib.mkIf cfg.battery.enable { powerManagement.powertop.enable = true; # enable powertop auto tuning on startup. + # Acording to https://community.frame.work/t/solved-keys-stick-and-repeat-after-being-released/51153/12 + # Some powertop bug is responsable for the problem of the random keypress being stuck + # fix: from https://git.gabbie.blue/blue/nixconf/src/commit/2d1bc6dad4684c019b6b3e894408e76e2734806c/hosts/gabbielaptop/configuration.nix#L68 + powerManagement.powertop.postStart = '' + ${lib.getExe' config.systemd.package "udevadm"} trigger -c bind -s usb -a idVendor=32ac -a idProduct=0018 + # Retrigger macropad udev rules + ${lib.getExe' config.systemd.package "udevadm"} trigger -c bind -s usb -a idVendor=32ac -a idProduct=0013 + ''; services.system76-scheduler.settings.cfsProfiles.enable = true; # Better scheduling for CPU cycles - thanks System76!!! services.thermald.enable = true; # Enable thermald, the temperature management daemon. (only necessary if on Intel CPUs) services.power-profiles-daemon.enable = false; # Disable GNOMEs power management diff --git a/hostsModules/laptop/nixos/ollama.nix b/hostsModules/laptop/nixos/ollama.nix new file mode 100644 index 0000000..f9658bf --- /dev/null +++ b/hostsModules/laptop/nixos/ollama.nix @@ -0,0 +1,25 @@ +{ + pkgs-unstable, + ... +}: { + services.ollama = { + enable = true; + package = pkgs-unstable.ollama-vulkan; + #port = 11434; + #host = "127.0.0.1:11434"; + # loadModels load them directly into ram at startup. Doesn't download them. + #loadModels = [ "mistral:7b" ]; # don't forget the :xxxxx for ex: "mixtral" don't work + #syncModels = true; + }; + systemd.services.ollama.serviceConfig.ExecStartPost = [ # use this to auto download models + "${pkgs-unstable.ollama-vulkan}/bin/ollama pull mistral:7b" + ]; + /*services.open-webui = { + enable = true; + port = 8080; + environment = { + OLLAMA_BASE_URL = "http://127.0.0.1:11434"; + WEBUI_AUTH = "True"; + }; + };*/ +} diff --git a/hostsModules/laptop/nixos/udev.nix b/hostsModules/laptop/nixos/udev.nix index cfae078..b89c224 100644 --- a/hostsModules/laptop/nixos/udev.nix +++ b/hostsModules/laptop/nixos/udev.nix @@ -12,5 +12,13 @@ # taken from here SUBSYSTEMS=="usb", ATTRS{idVendor}=="32ac", ATTRS{idProduct}=="0013", TAG+="uaccess" SUBSYSTEMS=="usb", ATTRS{idVendor}=="32ac", ATTRS{idProduct}=="0018", TAG+="uaccess" + + # acording to https://community.frame.work/t/solved-keys-stick-and-repeat-after-being-released/51153/12 + # the random keypress stuck comes from conflict between powertop and udev + # fix from: https://git.gabbie.blue/blue/nixconf/src/commit/2d1bc6dad4684c019b6b3e894408e76e2734806c/hosts/gabbielaptop/configuration.nix#L68 + # disable USB auto suspend for framework keyboard + ACTION=="bind", SUBSYSTEM=="usb", ATTR{idVendor}=="32ac", ATTR{idProduct}=="0018", TEST=="power/control", ATTR{power/control}="on" + # disable USB auto suspend for framework macropad + ACTION=="bind", SUBSYSTEM=="usb", ATTR{idVendor}=="32ac", ATTR{idProduct}=="0013", TEST=="power/control", ATTR{power/control}="on" ''; } diff --git a/modules/home-manager/librewolf.nix b/modules/home-manager/librewolf.nix index 3bf6b80..08f13c8 100644 --- a/modules/home-manager/librewolf.nix +++ b/modules/home-manager/librewolf.nix @@ -38,7 +38,7 @@ # "https://metrics.internal.contre.io/d/cUITC74Vksd/podman-revamped?orgId=1&from=2026-02-23T19:29:26.304Z&to=2026-02-23T19:59:26.304Z&timezone=browser&var-Filters=&var-namespace=alloy&var-level=error&var-level=debug&var-level=info&var-level=warn&refresh=5s&kiosk=true"; # disable welcome page "browser.newtabpage.enabled" = true; # disable new tab page "full-screen-api.ignore-widgets" = true; # fullscreen within window - "browser.toolbars.bookmarks.visibility" = "always"; # hide bookmarks toolbar + "browser.toolbars.bookmarks.visibility" = "never"; # hide bookmarks toolbar "browser.aboutConfig.showWarning" = false; # disable warning about about:config "media.videocontrols.picture-in-picture.video-toggle.enabled" = false; # disable picture in picture button @@ -148,6 +148,10 @@ install_url = "https://addons.mozilla.org/firefox/downloads/latest/trackmenot/latest.xpi"; installation_mode = "force_installed"; }; + "{446900e4-71c2-419f-a6a7-df9c091e268b}" = { + install_url = "https://addons.mozilla.org/firefox/downloads/file/4749958/bitwarden_password_manager-latest.xpi"; + installation_mode = "force_installed"; + }; }; DisableTelemetry = true; DisableFirefoxStudies = true; @@ -296,7 +300,13 @@ name = "Nixos Config"; tags = ["github"]; keyword = "github"; - url = "https://github.com/Totorile1/nixos"; + url = "https://github.com/tomasriveral/nixos"; + } + { + name = "Public AI"; + tags = ["ai" "chatgpt" "apertus"]; + keyword = "apertus"; + url = "https://chat.publicai.co/"; } ]; }; diff --git a/modules/home-manager/mullvad.nix b/modules/home-manager/mullvad.nix new file mode 100644 index 0000000..c0b9a5b --- /dev/null +++ b/modules/home-manager/mullvad.nix @@ -0,0 +1,13 @@ +# see also ../nixos/mullvad.nix +{ + ... +}: { + programs.mullvad-vpn = { + enable = true; + # see https://github.com/mullvad/mullvadvpn-app/blob/main/desktop/packages/mullvad-vpn/src/main/gui-settings.ts for options + settings = { + autoConnect = true; + autoStart = true; + }; + }; +} diff --git a/modules/home-manager/neovim.nix b/modules/home-manager/neovim.nix index 5314706..88bf199 100644 --- a/modules/home-manager/neovim.nix +++ b/modules/home-manager/neovim.nix @@ -249,10 +249,27 @@ local capabilities = require('cmp_nvim_lsp').default_capabilities() -- Diagnostics - vim.keymap.set("n", "e1", function() vim.diagnostic.jump({ prev=true, count = 1 }) end, { desc = "Previous diagnostic" }) - vim.keymap.set("n", "e2", function() vim.diagnostic.jump({ prev=false, count = 1 }) end, { desc = "Next diagnostic" }) - vim.keymap.set("n", "e3", vim.diagnostic.open_float, { desc = "Show diagnostic" }) - vim.keymap.set("n", "e4", vim.diagnostic.setloclist, { desc = "Diagnostic list" }) + vim.keymap.set("n", "e4", function() vim.diagnostic.jump({ prev=true, count = 1 }) end, { desc = "Previous diagnostic" }) + vim.keymap.set("n", "e5", function() vim.diagnostic.jump({ prev=false, count = 1 }) end, { desc = "Next diagnostic" }) + vim.keymap.set("n", "e1", vim.diagnostic.open_float, { desc = "Show diagnostic" }) + vim.keymap.set("n", "e3", vim.diagnostic.setloclist, { desc = "Diagnostic list" }) + vim.keymap.set("n", "e2", vim.lsp.buf.code_action, { desc = "Show correction" }) + + vim.keymap.set("n", "e", function() + local clients = vim.lsp.get_clients({ name = "ltex" }) + + if #clients > 0 then + -- Stop LTeX + for _, client in ipairs(clients) do + client.stop() + end + print("LTeX OFF") + else + -- Start LTeX + vim.cmd("LspStart ltex") + print("LTeX ON") + end + end, { desc = "Toggle LTeX" }) vim.diagnostic.config({ update_in_insert = false, -- i don't get any new error when in insert @@ -283,18 +300,22 @@ -- LSP server setup vim.lsp.config("lua_ls", { cmd = { "lua-language-server" }, filetypes = { "lua" }, root_dir = vim.fs.dirname, on_attach = on_attach }) vim.lsp.config("clangd", { - cmd = { "clangd" }, + cmd = { "clangd", "--header-insertion=never" }, filetypes = { "c","cpp","objc","objcpp" }, on_attach = on_attach , init_options = { + clangdFileStatus = true, usePlaceholders = true, completeUnimported = false, -- this adds a bunch of #include even thought they are #included in another header file + headerInsertion = false, + headerInsertionDecorators = false, + addDependencyHeaders = false, semanticHighlighting = true} }) - vim.lsp.config("nixd", { + vim.lsp.config("nixd", { cmd = { "nixd" }, - filetyypes = { "nix" }, + filetypes = { "nix" }, on_attach = on_attach, }) vim.lsp.config("pylsp", { @@ -311,8 +332,47 @@ } }) vim.lsp.config("texlab", { cmd = { "texlab" }, filetypes = { "tex" }, on_attach = on_attach }) + vim.lsp.config("ltex", { + cmd = { "ltex-ls-plus" }, + filetypes = { "markdown", "text", "tex", "plaintex" }, + on_attach = on_attach, + + settings = { + ltex = { + language = "fr", + + enabled = { + "markdown", + "text", + "tex", + "plaintex", + }, + + completionEnabled = true, + diagnosticSeverity = "information", + + additionalRules = { + enablePickyRules = false, + motherTongue = "fr", + }, + + dictionary = { + ["fr"] = { + "icelle", + "icelui", + "iceux", + "maldoror", + "evariste", + "galois", + "arno", + "dessacrer", + }, + }, + }, + }, + }) - vim.lsp.enable({ "lua_ls", "clangd", "pylsp", "texlab", "nixd"}) + vim.lsp.enable({ "lua_ls", "clangd", "pylsp", "texlab", "nixd", "ltex"}) -- ========================= -- DASHBOARD -- ========================= @@ -421,6 +481,13 @@ --================== vim.keymap.set('n', 'r1', 'Fugit2', { desc = 'Open git helper' }) + vim.keymap.set("n", "t", function() + local line = vim.api.nvim_get_current_line() + + local result = vim.fn.system({ "custom-syllabes" }, line) + + print(vim.trim(result)) + end, { desc = "Count syllables (current line)" }) -- ========================= -- telescope -- ======================= diff --git a/modules/home-manager/result b/modules/home-manager/result new file mode 120000 index 0000000..7b4d62c --- /dev/null +++ b/modules/home-manager/result @@ -0,0 +1 @@ +/nix/store/c0iwr0v7bjfka094wv6hd1hjmrkx9hm9-options.json \ No newline at end of file diff --git a/modules/home-manager/sbb-tui.nix b/modules/home-manager/sbb-tui.nix new file mode 100644 index 0000000..af0698b --- /dev/null +++ b/modules/home-manager/sbb-tui.nix @@ -0,0 +1,32 @@ +{ + pkgs-unstable, + ... +}: { + home.packages = [ + pkgs-unstable.sbb-tui + ]; + home.file.".config/sbb-tui/config.yaml" = { + enable = true; +# Gruvbox (from https://github.com/Necrom4/sbb-tui/blob/master/docs/themes.md) + text = '' +ui: + nerdfont: true + theme: + text: "#EBDBB2" + textMuted: "#928374" + error: "#FB4934" + warning: "#FB4934" + borderFocused: "#FABD2F" + borderUnfocused: "#504945" + badgeKeyFg: "#282828" + badgeKeyBg: "#FABD2F" + badgeVehicleFg: "#EBDBB2" + badgeVehicleBg: "#458588" + badgeModelFg: "#282828" + badgeModelBg: "#FB4934" + badgeCompanyFg: "#282828" + badgeCompanyBg: "#EBDBB2" + logo: "#EBDBB2" +''; + }; +} diff --git a/modules/nixos/mullvad.nix b/modules/nixos/mullvad.nix new file mode 100644 index 0000000..e635f0c --- /dev/null +++ b/modules/nixos/mullvad.nix @@ -0,0 +1,10 @@ +# see also ../home-manager/mullvad.nix +{ + pkgs-unstable, + ... +}: { + services.mullvad-vpn = { + enable = true; + package = pkgs-unstable.mullvad-vpn; + }; +} diff --git a/modules/nixos/printer.nix b/modules/nixos/printer.nix new file mode 100644 index 0000000..1a9994f --- /dev/null +++ b/modules/nixos/printer.nix @@ -0,0 +1,43 @@ +{ + config, + pkgs, + ... +}: { + #https://wiki.nixos.org/wiki/Printing + services.avahi = { + enable = true; + nssmdns4 = true; + openFirewall = true; + }; + + # Enable CUPS to print documents. + services.printing = { + enable = true; + drivers = with pkgs; [ + cups-filters + #cups-browsed + #gutenprint + #gutenprintBin + hplipWithPlugin + hplip + ]; + }; + services.ipp-usb.enable = true; + environment.systemPackages = with pkgs; [ + kdePackages.print-manager + ghostscript + hplipWithPlugin + ]; +hardware.printers = { + ensurePrinters = [ + { + name = "HP_OfficeJet_Pro_7740"; + location = "Home"; + deviceUri = "hp:/usb/OfficeJet_Pro_7740_series"; + model = "drv:///hp/hpcups.drv/hp-officejet_pro_7740_series.ppd"; + } + ]; + + ensureDefaultPrinter = "HP_OfficeJet_Pro_7740"; +}; +} diff --git a/modules/other/desktopEntries.nix b/modules/other/desktopEntries.nix index d47438e..6836d2c 100644 --- a/modules/other/desktopEntries.nix +++ b/modules/other/desktopEntries.nix @@ -1,9 +1,7 @@ { ... }: -# add a desktop entry here if you have an error like -# Failed to register with host portal QDBusError("org.freedesktop.portal.Error.Failed", "Could not register app ID: App info not found for 'org.quickshell'") - +# see ../../docs/printing.md { home.file.".local/share/applications/org.quickshell.desktop" = { enable = true; @@ -19,4 +17,16 @@ X-DBUS-ServiceName=org.quickshell ''; }; + home.file.".local/share/applications/org.kde.PrintQueue.desktop" = { + enable = true; + text = '' + [Desktop Entry] + Type=Application + Name=Print Queue + Exec=print-queue + Icon=printer + Categories=Utility; + StartupNotify=true + ''; + }; } diff --git a/modules/packages/plint.nix b/modules/packages/plint.nix new file mode 100644 index 0000000..6622506 --- /dev/null +++ b/modules/packages/plint.nix @@ -0,0 +1,51 @@ +{ lib +, python3Packages +, fetchFromGitLab +, frhyme +, haspirater +}: + +python3Packages.buildPythonApplication rec { + pname = "plint"; + + # No PyPI version mentioned; upstream is git-based + version = "unstable-2026-04-28"; + + src = fetchFromGitLab { + owner = "a3nm"; + repo = "plint"; + rev = "master"; + sha256 = lib.fakeSha256; # replace after first build + }; + + propagatedBuildInputs = [ + frhyme + haspirater + python3Packages.cherrypy + ]; + + # plint uses scripts + data generation steps, so disable strict tests + doCheck = false; + + preBuild = '' + # required data generation steps from README + echo "Generating frhyme.json..." + (cd frhyme/lexique && ./lexique_retrieve.sh > lexique.txt) + (cd frhyme && ./make.sh 4 lexique/lexique.txt additions > frhyme.json) + + echo "Generating occurrences file..." + ./lexique_occurrences_retrieve.sh > data/occurrences || true + ''; + + postInstall = '' + # ensure CLI entry point exists + install -Dm755 plint.py $out/bin/plint + ''; + + meta = with lib; { + description = "French poetry validator (metrics, rhymes, template checking)"; + homepage = "https://gitlab.com/a3nm/plint"; + license = licenses.gpl3Plus; + platforms = platforms.unix; + }; +} diff --git a/modules/scripts/syllabes.nix b/modules/scripts/syllabes.nix new file mode 100644 index 0000000..cb7ec98 --- /dev/null +++ b/modules/scripts/syllabes.nix @@ -0,0 +1,173 @@ +{ pkgs, python3Packages, ... }: + +pkgs.writers.writePython3Bin "custom-syllabes" { + libraries = [ + python3Packages.pyphen + ]; +} '' +import sys +import pyphen + +dic = pyphen.Pyphen(lang="fr") + +text = sys.stdin.read().strip() + +chunks = [] +total = 0 + +for w in text.split(): + hyphenated = dic.inserted(w) + parts = hyphenated.split("-") + chunks.append("/".join(parts)) + total += len(parts) + +print(f"{total} ({'/'.join(chunks)})") +'' +/* used IPA but had a deprecated dependency +{ pkgs, python3Packages, ... }: + +pkgs.writers.writePython3Bin "custom-syllabes" { + libraries = [ + python3Packages.epitran + python3Packages.setuptools + ]; +} '' +import sys +import epitran +import re + +epi = epitran.Epitran("fra-Latn") + + +def count_syllables_ipa(ipa): + return len(re.findall(r"[aeiouyɑɛœɔ̃ɑ̃ɛ̃œ̃]", ipa)) + + +text = sys.stdin.read().strip() + +total = 0 +chunks = [] + +for word in text.split(): + ipa = epi.transliterate(word) + syllables = count_syllables_ipa(ipa) + + total += syllables + chunks.append(f"{word}/{ipa}") + +print(f"{total} ({' | '.join(chunks)})") +''*/ +/*{ pkgs, ... }: + +let + lexique = pkgs.fetchurl { + url = "http://www.lexique.org/databases/Lexique383/Lexique383.tsv"; + sha256 = "sha256-Y3ujenZ6ZmecSDcdZz7OUMv1QbSaTkDlmJY9Tz+85Ss="; + }; + +in +pkgs.writers.writePython3Bin "custom-syllabes" { + libraries = [ pkgs.python3Packages.pandas ]; +} '' +import os +import sys +import pandas as pd +import re + +# ---------------------------- +# Load Lexique383 +# ---------------------------- +LEX_PATH = os.environ.get( + "LEXIQUE_PATH", + "${lexique}" +) + +df = pd.read_csv(LEX_PATH, sep="\t", low_memory=False) + +lex = dict(zip(df["ortho"].str.lower(), df["phon"])) + + +# ---------------------------- +# phoneme-based syllabification +# ---------------------------- + +VOWELS = set([ + "a", "e", "ɛ", "ə", "i", "o", "ɔ", "u", "y", + "ɑ̃", "ɛ̃", "ɔ̃", "œ̃" +]) + + +def is_vowel(ph): + return any(v in ph for v in VOWELS) + + +def syllabify_phonemes(phonemes): + syllables = [] + cur = "" + + for p in phonemes: + cur += p + + if is_vowel(p): + syllables.append(cur) + cur = "" + + if cur and syllables: + syllables[-1] += cur + elif cur: + syllables.append(cur) + + return syllables + + +# ---------------------------- +# poetic adjustment (basic) +# ---------------------------- + +def apply_rules(word, phon, syllables): + # e muet at end (very rough heuristic) + if phon.endswith("ə") or phon.endswith("e"): + if len(syllables) > 1: + syllables = syllables[:-1] + return syllables + + +# ---------------------------- +# main counter +# ---------------------------- + +def count_word(word): + w = re.sub(r"[^a-zàâçéèêëîïôûùœæ']", "", word.lower()) + if not w: + return 0, [] + + phon = lex.get(w) + if not phon: + # fallback heuristic + syls = re.findall(r"[aeiouyàâéèêëîïôûùœæ]+", w) + return len(syls), syls + + phonemes = phon.split() + syls = syllabify_phonemes(phonemes) + syls = apply_rules(w, phon, syls) + + return len(syls), syls + + +def main(): + text = sys.stdin.read().strip() + total = 0 + out = [] + + for w in text.split(): + c, syls = count_word(w) + total += c + if syls: + out.append("/".join(syls)) + + print(f"{total} ({' '.join(out)})") + + +if __name__ == "__main__": + main() +''*/