;;; ;; Define Functions ;;; (defun check-temp (sensor) "Check temperature for a given sensor. Arguments: SENSOR: The sensor to check (e.g., 'cpu0.temp0'). Returns: The temperature string or nil if unavailable." (let ((temp (run-shell-command-and-format (format nil "sysctl -n hw.sensors.~A 2>/dev/null" sensor)))) (unless (string= temp "^Rnil^r") temp))) (defun show-temp (&optional custom-sensor) "Retrieve and format the CPU temperature. Arguments: CUSTOM-SENSOR: Optional. A string representing a custom sensor to check. Returns: STRING: Formatted CPU temperature or '^Rnil^r' if unavailable. This function attempts to get the CPU temperature using the hw.sensors tree of sysctl. If a custom sensor is provided, it tries that first. Otherwise, it tries .acpithinkpad0.temp0, then .cpu0.temp0, and finally .adt0.temp0. If all fail, it returns '^Rnil^r'." (or (and custom-sensor (check-temp custom-sensor)) (check-temp "acpithinkpad0.temp0") (check-temp "km0.temp0") (check-temp "cpu0.temp0") (check-temp "adt0.temp0") "^Rnil^r")) (defun show-volume (type) "Retrieve and format the current volume level for a given audio type. Arguments: TYPE: A string representing the audio type (e.g., 'output' or 'input'). Returns: STRING: Formatted volume level as a percentage, or '^Rnil^r' if unavailable. This function uses safe-sndioctl to query the volume level of the specified type, formats it as a percentage, and handles error cases." (let* ((control (format nil "~a.level" type)) (output (safe-sndioctl control))) (if (string-equal output "") "^Rnil^r" (format nil "~,1f%" (* 100 (read-from-string output)))))) (defun battery-stuff () (string-trim '(#\Space #\Newline) (run-shell-command "/home/ladot/.local/bin/battery" t))) (defun mem-stuff () (string-trim '(#\Space #\Newline) (run-shell-command "/home/ladot/.local/bin/memory" t))) (defun temp-stuff () (string-trim '(#\Space #\Newline) (run-shell-command "/home/ladot/.local/bin/cputemp" t))) (defun cpu-stuff () (string-trim '(#\Space #\Newline) (run-shell-command "/home/ladot/.local/bin/cpuusage" t))) ;;; ;; Formatting ;;; ;; Constants (defparameter pipe " | ") (defparameter group-bracket-color "^7*") ;; White (defparameter group-content-color "^6*") ;; Aqua (defparameter audio-bracket-color "^4*") ;; Orange ^8* (defparameter audio-content-color "^2*") ;; Green (defparameter status-bracket-color "^5*") ;; Magenta (defparameter status-content-color "^3*") ;; Yellow (defparameter win-bracket-color "^1*") ;; Red (defparameter win-content-color "^7*" ) ;; White ;; Components (defvar group-fmt "%g") ;; Group ID's (defvar win-fmt "%W") ;; Window Name (defvar audio-fmt (list '(:eval (concatenate 'string (battery-stuff))))) ;'(:eval (show-volume "output")) ;"/" ;'(:eval (show-volume "input")))) (defvar status-fmt (list ;;'(:eval (concatenate 'string (battery-stuff) pipe)) ;; Battery '(:eval (concatenate 'string (mem-stuff) pipe)) '(:eval (concatenate 'string (temp-stuff) pipe)) '(:eval (concatenate 'string (cpu-stuff))))) (defvar other-fmt (list ;;right ;;'(:eval (when (> *reps* 0) ;;(format nil "^1^B(Reps ~A)^n " *reps*))) ;; Date "^7" "%d" ;; Battery ;;'(:eval (concatenate 'string (battery-stuff))) ;;'(:eval (format nil " ^7[^n~A^7]^n " (battery-stuff))) )) ;; Generate a Component of a given color (defun generate-mode-line-component (out-color in-color component &optional right-alignment) "Generate a colored component for the mode line. Arguments: OUT-COLOR: String representing the color for brackets. IN-COLOR: String representing the color for the component content. COMPONENT: The content to be displayed in the component. RIGHT-ALIGNMENT: If non-nil, the component will be right-aligned. Returns: LIST: A list representing the formatted mode line component. This function creates a formatted component for the mode line with specified colors and optional right alignment. Example usage: (generate-mode-line-component \"^8\" \"^6\" \"%g\") This returns a LIST with: Outer bracket color: \"^8\" Content color: \"^6\" Format string: \"%g\" Returned list: (\"^8\" \"[\" \"^6\" \"%g\" \"^8\" \"]\")" (if right-alignment (list "^>" out-color "[" in-color component out-color "]") (list out-color "[" in-color component out-color "]"))) (defun generate-mode-line () "Build and set the complete mode line format. This function constructs the mode line by combining various components with appropriate colors and formatting. It sets the *screen-mode-line-format* variable with the constructed mode line." (setf *screen-mode-line-format* (list (generate-mode-line-component group-bracket-color group-content-color group-fmt) (generate-mode-line-component audio-bracket-color audio-content-color audio-fmt) (generate-mode-line-component status-bracket-color status-content-color status-fmt) (generate-mode-line-component win-bracket-color win-content-color win-fmt) (generate-mode-line-component audio-bracket-color audio-content-color other-fmt t) ))) ;; Actually load my modeline (generate-mode-line) ;; Format Modeline (setf *mode-line-background-color* "#1D2021" *mode-line-border-color* "#3c3836" *mode-line-border-width* 2 *mode-line-pad-x* 4 *mode-line-pad-y* 6 *mode-line-timeout* 1) ;; mode line on all heads (dolist (h (screen-heads (current-screen))) (enable-mode-line (current-screen) h t))