# -*- geiser-default-implementation: chicken; -*- #+TITLE: Mowedline init Load the =matchable= module so I can use =match-lambda=. #+BEGIN_SRC scheme (use matchable dbus) #+END_SRC Set the default font and color to something nicer. #+BEGIN_SRC scheme (text-widget-font "Fantasque Sans Mono-13:bold") (text-widget-color "#ededed") #+END_SRC Define a convenience function to check if a formatter's argument is not some text. #+BEGIN_SRC scheme (define (not-text? text) (or (null? text) (and (not (pair? text)) (string-null? text)))) #+END_SRC Define a convenience function that adds spaces around its argument if its argument is text. #+BEGIN_SRC scheme (define (text-maybe-pad-both text) (if (not-text? text) text (list " " text " "))) #+END_SRC Define a convenience function to add a Font Awesome icon to a widget. #+BEGIN_SRC scheme (define (add-fa-icon icon) (lambda (text) (if (not-text? text) text (list (list 'font "FontAwesome-10" (string-append " " icon " ")) text)))) #+END_SRC * Tag list This formatter will parse the herbstluftwm tag status line, which looks like this: #+BEGIN_EXAMPLE #1 -2 :3 :4 :5 .6 .7 .8 .9 #+END_EXAMPLE And turn it into something more useful. The symbols before the tag names (numbers) have the following meaning: - =#= :: This tag is currently active. - =-= :: This tag is visible on another monitor. - =:= :: This tag isn't displayed, but has windows on it. - =.= :: This tag isn't displayed and is empty. - =!= :: This tag has an urgent window on it. First the tag line has to be split into separate parts. Each tag status/name pair is split by a tab character and each status is only one character. So I split the whole string on tabs and then make a list out of each individual part, for easy access to the status character. So we end up with something like: #+BEGIN_EXAMPLE ((#\# #\1) (#\- #\2) (#\: #\3) ...) #+END_EXAMPLE #+BEGIN_SRC scheme (define (split-tag-list str) (map string->list (string-split str "\t"))) #+END_SRC Next we turn each part into something practical for display in mowedline. #+BEGIN_SRC scheme (define tag-display (match-lambda ((#\# . name-list) (list '(color "#ececec" font "FontAwesome-10" "") (string-append " " (list->string name-list) " "))) ((#\- . _) '((color "#bfbfbf" font "FontAwesome-10" "") " ")) ((#\: . _) '((color "#969696" font "FontAwesome-10" "") " ")) ((#\! . _) '((color "#a85454" font "FontAwesome-10" "") " ")) (_ '()))) (define (tag-list-display tag-list) (map tag-display tag-list)) #+END_SRC Finally, bring it all together in a function that can be used as a mowedline text formatter. #+BEGIN_SRC scheme (define (tag-list-formatter text) (tag-list-display (split-tag-list text))) #+END_SRC Define the widget to be used in the window. #+BEGIN_SRC scheme (define taglist-widget (widget:text #:name "taglist" #:format tag-list-formatter)) #+END_SRC * Email Define a widget to show email notifications in. #+BEGIN_SRC scheme (define email-widget (widget:text #:name "email" #:format (compose text-maybe-pad-left (add-fa-icon "")))) #+END_SRC * The window Create a mowedline window, put it at the bottom. #+BEGIN_SRC scheme (define clipboard-widget (widget:text #:format text-maybe-pad-left)) (let ((ctx (make-context #:service 'org.gnome.GPaste #:interface 'org.gnome.GPaste1 #:path "/org/gnome/GPaste"))) (register-signal-handler ctx "Update" (lambda (type replace id) (update clipboard-widget "Text copied!") (thread-start! (make-thread (lambda () (thread-sleep! 3) (update clipboard-widget ""))))))) (window #:position 'bottom #:width 1843 #:margin-bottom 15 #:margin-left 46 #:margin-right 15 #:background 'transparent taglist-widget (widget:spacer #:flex 1) clipboard-widget (widget:text #:name "irc" #:format (lambda (text) (text-maybe-pad-left (with-input-from-string text read)))) email-widget (widget:clock #:format text-maybe-pad-left)) #+END_SRC