diff --git a/emacs/.emacs.d/init.org b/emacs/.emacs.d/init.org index e2e3821..b0162eb 100644 --- a/emacs/.emacs.d/init.org +++ b/emacs/.emacs.d/init.org @@ -254,12 +254,33 @@ To start off, first I need to enable lexical binding. * Theme + Load my personal theme. I sometimes change it to a different theme, + but for some reason I always come crawling back to it. + #+BEGIN_SRC emacs-lisp (add-to-list 'custom-theme-load-path (concat user-emacs-directory "vendor-lisp/yoshi-theme")) (load-theme 'yoshi :no-confirm) #+END_SRC + Load my personal SVG mode-line theme. + + #+BEGIN_SRC emacs-lisp + (require 'svg-mode-line-themes) + (require 'oni-smt) + + (smt/enable) + (smt/set-theme 'oni-smt) + #+END_SRC + + Because SVG mode-line themes doesn't include the box around the + mode-line, remove it (my personal theme adds it as padding). + + #+BEGIN_SRC emacs-lisp + (set-face-attribute 'mode-line nil :box nil) + (set-face-attribute 'mode-line-inactive nil :box nil) + #+END_SRC + * Diminish I really don't need to see some of the minor modes. diff --git a/emacs/.emacs.d/site-lisp/oni-smt.el b/emacs/.emacs.d/site-lisp/oni-smt.el new file mode 100644 index 0000000..a39bc57 --- /dev/null +++ b/emacs/.emacs.d/site-lisp/oni-smt.el @@ -0,0 +1,252 @@ +;;; oni-smt.el --- My SVG mode-line theme -*- lexical-binding: t; -*- + +;; Copyright (C) 2014 Tom Willemse + +;; Author: Tom Willemse +;; Keywords: faces + +;; 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: + +;; + +;;; Code: + +(require 'svg-mode-line-themes) +(require 'flycheck) + +;; (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