(define-module (oni home services rofi) #:use-module (gnu services configuration) #:use-module (gnu packages xdisorg) #:use-module (gnu home services) #:use-module (gnu home services utils) #:use-module (guix packages) #:use-module (guix gexp) #:use-module (guix records) #:use-module (guix i18n) #:use-module (guix modules) #:use-module (guix diagnostics) #:use-module (oni home services xbindkeys) #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) #:use-module (ice-9 match) #:use-module (ice-9 regex) #:use-module (ice-9 common-list) #:export (home-rofi-service-type home-rofi-configuration home-rofi-default-service)) ;;; This module has been copied from ;;; https://github.com/nouun/jayu/blob/92ff6629da686f0ddc96a4d6cb2a657c76795bc6/jayu/home/services/xdisorg.scm (define-configuration/no-serialization home-rofi-configuration (package (package rofi) "Package to use for setting Rofi") (config (alist '()) "rofi config") (theme (alist '()) "theme config")) (define color-regexp (make-regexp (string-append "(" ;; #RGB "#[a-zA-Z0-9]{3}" "|" ;; #RGBA "#[a-zA-Z0-9]{4}" "|" ;; #RRGGBB "#[a-zA-Z0-9]{6}" "|" ;; #RRGGBBAA "#[a-zA-Z0-9]{8}" "|" ;; rgb(123, 123, 123) "rgba?. *[0-9]{1,3} *%? *, *[0-9]{1,3} *%? *, *[0-9]{1,3} *%? *" "|" ;; rgba(123, 123, 123, 0.1) "rgba?. *[0-9]{1,3} *%? *, *[0-9]{1,3} *%? *, *[0-9]{1,3} *%? *, [0-9]\\.[0-9]*" "|" ;; rgba(123, 123, 123, 100%) "rgba?. *[0-9]{1,3} *%? *, *[0-9]{1,3} *%? *, *[0-9]{1,3} *%? *, [0-9]{1,3} *% *" ;;children ")"))) (define (format-rofi-value val) (cond ((list? val) (string-join (map format-rofi-value val) " ")) ((boolean? val) (if val "true" "false")) ((number? val) (string-append (object->string val) (if (not (eq? 0 val)) "px" ""))) ((symbol? val) (object->string val)) ((string? val) (let ((color-match (regexp-exec color-regexp val))) (if (or (string-prefix? "@" val) (regexp-match? color-match)) val (string-append "\"" val "\"")))) (else val))) (define (format-rofi-config config) (let ((key (object->string (car config))) (value (cdr config))) (define (format-children children) (string-append "[" (string-join (map object->string children) ",") "]")) (string-append key ": " (if (eq? 'children (car config)) (format-children value) (format-rofi-value value)) ";"))) (define (serialize-rofi-config config) (list (string-append "configuration {\n " (string-join (map format-rofi-config config) "\n ") "\n}\n"))) (define (format-rofi-theme theme) (let ((keys (map (λ (s) (if (symbol? s) (symbol->string s) (object->string s))) (butlast theme 1))) (values (car (list-tail theme (- (length theme) 1))))) (string-append (string-join keys ", ") " {\n " (string-join (map format-rofi-config values) "\n ") "\n}\n"))) (define (serialize-rofi-theme theme) (string-join (map format-rofi-theme theme) "\n")) (define (home-rofi-files-service conf) `(("rofi/config.rasi" ,(apply mixed-text-file "config.rasi" (append ;; Main config (serialize-rofi-config (home-rofi-configuration-config conf)) ;; Apply theme (if (not (eq? (home-rofi-configuration-theme conf) '())) (list "\n@import \"guix\"\n") '())))) ("rofi/guix.rasi" ,(mixed-text-file "guix.rasi" (serialize-rofi-theme (home-rofi-configuration-theme conf)))))) (define (home-rofi-profile-service config) (list (home-rofi-configuration-package config))) (define (home-rofi-extension old-config extension-configs) (match old-config (($ package* config* theme*) (home-rofi-configuration (package package*) (config (append config* (append-map home-rofi-configuration-config extension-configs))) (theme (append theme* (append-map home-rofi-configuration-theme extension-configs))))))) (define (add-rofi-xbindkeys-keybindings config) (home-xbindkeys-extension (keybindings '(((mod4 r) . "herbstclient spawn rofi -modi drun -show drun") ((mod4 w) . "herbstclient spawn rofi -show window -window-command \"/home/chelys/usr/bin/hlwm-switch-to-window {window}\""))))) (define home-rofi-service-type (service-type (name 'home-rofi) (extensions (list (service-extension home-xdg-configuration-files-service-type home-rofi-files-service) (service-extension home-profile-service-type home-rofi-profile-service) (service-extension home-xbindkeys-service-type add-rofi-xbindkeys-keybindings))) (compose concatenate) (extend home-rofi-extension) (default-value (home-rofi-configuration)) (description "Configure Rofi"))) (define (generate-home-rofi-documentation) (generate-documentation `((home-rofi-configuration ,home-rofi-configuration-fields)) 'home-rofi-configuration)) (define-public home-rofi-default-service (service home-rofi-service-type (home-rofi-configuration (config '((kb-cancel . "Escape,Control+g") (window-format . "{c} {t}"))) (theme '((* ((text-color . "#bfbfbf") (background-color . "#3f4242") (lightbg . "#5b6161") (red . "#a85454") (orange . "#faa41a") (blue . "#1f2c3f") (selected-normal-foreground . "@text-color") (normal-foreground . "@text-color") (alternate-normal-background . "@background-color") (selected-urgent-foreground . "@text-color") (urgent-foreground . "@text-color") (alternate-urgent-background . "@background-color") (active-foreground . "@text-color") (selected-active-foreground . "@text-color") (alternate-normal-foreground . "@text-color") (alternate-active-background . "@blue") (bordercolor . "@text-color") (normal-background . "@background-color") (selected-normal-background . "@blue") (separatorcolor . "@orange") (spacing . 2) (urgent-background . "@red") (alternate-urgent-foreground . "@text-color") (selected-urgent-background . "@red") (alternate-active-foreground . "@text-color") (selected-active-background . "@blue") (active-background . "@red") (font . "Fantasque Sans Mono 14"))) (window ((border . 0) (text-color . "@text-color") (background-color . "rgba(0, 0, 0, 0%)") (padding . 5) (text-color . "@bordercolor") (background-color . "@background-color"))) (mainbox ((border . 0) (padding . 0))) (message ((border . "1px dash 0px 0px") (text-color . "@separatorcolor") (padding . "2px 0px 0px"))) (textbox ((text-color . "@text-color"))) (listview ((fixed-height . 0) (border . "2px 0px 0px") (padding . "2px 0px 0px") (text-color . "@separatorcolor"))) (element ((border . 0) (children "element-icon" "element-text") (spacing . "5px"))) (element.normal.normal ((text-color . "@normal-foreground") (background-color . "@normal-background"))) (element.normal.urgent ((text-color . "@urgent-foreground") (background-color . "@urgent-background"))) (element.normal.active ((text-color . "@active-foreground") (background-color . "@active-background"))) (element.selected.urgent ((text-color . "@selected-urgent-foreground") (background-color . "@selected-urgent-background"))) (element.selected.active ((text-color . "@selected-active-foreground") (background-color . "@selected-active-foreground"))) (element.alternate.normal ((text-color . "@alternate-normal-foreground") (background-color . "@alternate-normal-background"))) (element.alternate.urgent ((text-color . "@alternate-urgent-foreground") (background-color . "@alternate-urgent-background"))) (element.alternate.active ((text-color . "@alternate-active-foreground") (background-color . "@alternate-active-background"))) (mode-switcher ((border . "1px dash 0px 0px"))) (#{button selected}# ((text-color . "@selected-normal-foreground") (background-color . "@selected-normal-background"))) (inputbar ((spacing . 0) (border . "0px") (children "prompt" "textbox-prompt-colon" "entry" "case-indicator"))) (#{button normal}# ((text-color . "@text-color"))) (text-prompt-color ((expand . #f) (str . ":") (margin . "0px 0.3em 0em 0em") (text-color . "@normal-foreground"))))))))