;;; oni-smt.el --- Smart Modeline Themes configuration -*- lexical-binding: t; -*- ;; Copyright (C) 2019 Tom Willemse ;; Author: Tom Willemse ;; Keywords: local ;; Version: 2019.0904.210822 ;; Package-Requires: (smart-mode-line oni-flycheck) ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; Configuration for `smt-themes'. ;;; Code: (require 'flycheck) (require 'svg-mode-line-themes) ;; (require 'mode-icons) (defun oni-smt-flycheck-errors-text (_) "Show an indicator of the number of errors and warnings from flycheck." (when flycheck-mode (let* ((counts (flycheck-count-errors flycheck-current-errors)) (err-color (if (smt/window-active-p) "#a85454" "#969696")) (warn-color (if (smt/window-active-p) "#a88654" "#969696")) (info-color (if (smt/window-active-p) "#5476a8" "#969696")) (err-count (alist-get 'error counts 0)) (warn-count (alist-get 'warning counts 0)) (info-count (alist-get 'info counts 0))) `(tspan " " (tspan :fill ,err-color ,err-count) "/" (tspan :fill ,warn-color ,warn-count) "/" (tspan :fill ,info-color ,info-count))))) (smt/defwidget oni-smt-flycheck-errors :text #'oni-smt-flycheck-errors-text) (defun oni-smt-jabber-activity-text (_) "Show jabber activity indicator." (if (and (smt/window-active-p) (boundp 'jabber-activity-mode-string) (not (equal jabber-activity-mode-string ""))) (concat jabber-activity-mode-string " "))) (smt/defwidget oni-smt-jabber-activity :text #'oni-smt-jabber-activity-text) ;;; TODO Turn: ;; #("message: (FORMAT-STRING &rest ARGS)" ;; 0 7 (face font-lock-function-name-face) ;; 10 23 (face eldoc-highlight-function-argument)) ;;; into: ;;; (tspan (tspan :fill (fg-color font-lock-function-name-face) "message:") ;;; " (" ;;; (tspan :fill (fg-color highlight-function-argument) "FORMAT-STRING") ;;; " &rest ARGS)") (defvar oni-smt-eldoc-message nil) (defun oni-smt-eldoc-minibuffer-message (format-string &rest args) (if (minibufferp) (progn (add-hook 'minibuffer-exit-hook (lambda () (setq oni-smt-eldoc-message nil eldoc-mode-line-string nil eldoc-last-message nil)) nil t) (setq oni-smt-eldoc-message (when (stringp format-string) (apply 'format format-string args))) (force-mode-line-update t)) (apply 'message format-string args))) (smt/defwidget oni-smt-eldoc-message :text (lambda (widget) (ignore widget) (when oni-smt-eldoc-message `(tspan :fill "#bfbfbf" " (" (tspan :fill "#5476a8" ,oni-smt-eldoc-message) ")")))) (defun oni-smt-yoshi-title-style (_) "Fill color for either active or inactive windows." (list :fill (if (smt/window-active-p) "#65a854" "#969696") :font-weight (if (smt/window-active-p) "bold" "normal"))) (smt/defwidget oni-smt-po-counters :text (lambda (widget) (ignore widget) (when (eql major-mode 'po-mode) (format " %dt+%df+%du+%do" po-translated-counter po-fuzzy-counter po-untranslated-counter po-obsolete-counter)))) (smt/defwidget oni-smt-buffer-identification :style 'oni-smt-yoshi-title-style :text (lambda (widget) (ignore widget) (concat (string-trim (substring-no-properties (format-mode-line mode-line-buffer-identification))) (when (and (or buffer-file-name buffer-offer-save) (buffer-modified-p)) "*")))) (smt/defwidget oni-smt-current-dictionary :text (lambda (widget) (ignore widget) (if flyspell-mode (concat " " (or ispell-current-dictionary ispell-local-dictionary flyspell-default-dictionary))))) (smt/defwidget oni-smt-erc :text (lambda (_) (when (boundp 'erc-modified-channels-alist) erc-modified-channels-object))) (smt/defwidget oni-smt-position :text (lambda (_) (format-mode-line "%l/%c:%p"))) (defun oni-smt-read-only/write (_) "Show a locked or unlocked icon." `(tspan :font-family "FontAwesome" :font-size 13 ,(if buffer-read-only " " " "))) (smt/defwidget oni-smt-rwo :text #'oni-smt-read-only/write) (defun oni-smt-extra-minor-modes (minor-modes) "Add some more info to MINOR-MODES." (if (boundp 'evil-state) (let ((l (capitalize (elt (symbol-name evil-state) 0)))) `(tspan ,minor-modes (tspan :fill "#54a875" ,(char-to-string l)))) minor-modes)) (add-function :filter-return (symbol-function 'smt/minor-mode-indicator-text) #'oni-smt-extra-minor-modes) (smt/defrow oni-smt-right :prototype 'default-right :widgets '(oni-smt-jabber-activity oni-smt-erc major-mode oni-smt-current-dictionary oni-smt-flycheck-errors version-control minor-modes) :margin 17) ;; (defun smt/r-export-image (row theme) ;; `(image ;; :x ,(if (equal (smt/r-align row) "left") ;; (* (smt/r-margin row) ;; (frame-char-width)) ;; (- (smt/window-pixel-width) ;; (* (smt/r-margin row) ;; (frame-char-width)))) ;; :y 2 ;; :width 16 ;; :height 16 ;; :xlink:href ,(concat "data:image/png;base64," ;; (let ((name (nth 1 (mode-icons-get-icon-spec mode-name)))) ;; (if name ;; (with-temp-buffer ;; (insert-file-contents (concat (mode-icons-get-icon-file name) ".png")) ;; (base64-encode-region (point-min) (point-max)) ;; (buffer-substring-no-properties (point-min) (point-max))) ;; mode-name))))) ;; (smt/defrow oni-smt-major-mode ;; :prototype 'default-right ;; :export 'smt/r-export-image ;; :margin 40) (smt/defrow oni-smt-left :prototype 'default-left :widgets '(buffer-info oni-smt-rwo oni-smt-buffer-identification oni-smt-po-counters which-function oni-smt-eldoc-message)) (smt/defrow oni-smt-position :prototype 'default-position :widgets '(oni-smt-position)) (defun oni-smt-major-mode-style (widget) (ignore widget) '(:fill "#ccc" :font-family "Signika" :filter nil :font-weight "regular" :font-style "italic")) (defun oni-smt-background (_) "" (let ((stops '(("0%" "#484848" 0.3) ("25%" "#484848" 0.3) ("75%" "#484848" 0.3) ("100%" "#111111" 0.3)))) `((\defs (linearGradient :id "twisted" :x1 "0%" :y1 "0%" :x2 "100%" :y2 "25%" (stop :offset ,(first (nth 1 stops)) :stop-color ,(second (nth 1 stops)) :stop-opacity ,(third (nth 1 stops))) (stop :offset ,(first (nth 2 stops)) :stop-color ,(second (nth 2 stops)) :stop-opacity ,(third (nth 2 stops))) (stop :offset ,(first (nth 3 stops)) :stop-color ,(second (nth 3 stops)) :stop-opacity ,(third (nth 3 stops))) (stop :offset ,(first (nth 4 stops)) :stop-color ,(second (nth 4 stops)) :stop-opacity ,(third (nth 4 stops))))) (rect :width "100%" :height "100%" :x 0 :y 0 :fill "url(#twisted)")))) (defun oni-smt-overlay (_) "" (let ((stops '(("0%" "#FFFFFF" 0.1) ("20%" "#111111" 0.0) ("90%" "#111111" 0.5) ("100%" "#111111" 0.8)))) `((\defs (linearGradient :id "over-gradient" :x1 "0%" :y1 "0%" :x2 "0%" :y2 "100%" (stop :offset ,(first (nth 1 stops)) :stop-color ,(second (nth 1 stops)) :stop-opacity ,(third (nth 1 stops))) (stop :offset ,(first (nth 2 stops)) :stop-color ,(second (nth 2 stops)) :stop-opacity ,(third (nth 2 stops))) (stop :offset ,(first (nth 3 stops)) :stop-color ,(second (nth 3 stops)) :stop-opacity ,(third (nth 3 stops))) (stop :offset ,(first (nth 4 stops)) :stop-color ,(second (nth 4 stops)) :stop-opacity ,(third (nth 4 stops))))) (rect :width "100%" :height "100%" :x 0 :y 0 :fill "url(#over-gradient)")))) (smt/deftheme oni-smt :prototype 'black-crystal :overlay 'oni-smt-overlay :background 'oni-smt-background :local-widgets (list (cons 'major-mode (smt/make-widget :prototype 'major-mode :style 'oni-smt-major-mode-style))) :rows '(oni-smt-left oni-smt-position oni-smt-right)) (add-function :override (symbol-function 'eldoc-minibuffer-message) #'oni-smt-eldoc-minibuffer-message) (provide 'oni-smt) ;;; oni-smt.el ends here