From 3e78d1f8ca5b100f39577790614433398bc6a422 Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Mon, 17 Oct 2022 21:27:59 -0500 Subject: asoi --- .gitignore | 1 + init.el | 310 +++++++++++++++++++++++++++++++++---------------------- lisp/+chicken.el | 12 +++ lisp/+emacs.el | 14 ++- lisp/+org.el | 76 ++++++++------ machines/bob.el | 5 +- 6 files changed, 256 insertions(+), 162 deletions(-) diff --git a/.gitignore b/.gitignore index c521db5..bc45f59 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ url/ # put random stuff in here scratch.el +spell-fu/ diff --git a/init.el b/init.el index d3fc88e..bed69ee 100644 --- a/init.el +++ b/init.el @@ -487,6 +487,12 @@ ;; (+kmacro-recording-indicator-mode +1) (+kmacro-block-undo-mode +1))) +(setup make-mode + (:hook (defun +make-remove-warnings () + (dolist (f '(makefile-warn-continuations + makefile-warn-suspicious-lines)) + (remove-hook 'write-file-functions f t))))) + (setup midnight (midnight-mode +1) (add-hook 'midnight-hook #'recentf-cleanup)) @@ -520,18 +526,18 @@ ) (with-eval-after-load 'transient (transient-define-prefix net-utils () - "Networking utilities" - ["Actions" - ("p" "Ping" ping) - ("i" "Ifconfig" ifconfig) - ("w" "Iwconfig" iwconfig) - ("n" "Netstat" netstat) - ("a" "Arp" arp) - ("r" "Route" route) - ("h" "Nslookup host" nslookup-host) - ("d" "Dig" dig) - ("s" "Smb Client" smbclient) - ("t" "Traceroute" traceroute)]) + "Networking utilities" + ["Actions" + ("p" "Ping" ping) + ("i" "Ifconfig" ifconfig) + ("w" "Iwconfig" iwconfig) + ("n" "Netstat" netstat) + ("a" "Arp" arp) + ("r" "Route" route) + ("h" "Nslookup host" nslookup-host) + ("d" "Dig" dig) + ("s" "Smb Client" smbclient) + ("t" "Traceroute" traceroute)]) (:+key "C-z M-n" #'net-utils))) (setup notmuch @@ -720,10 +726,7 @@ "`" #'+org-insert-tilde "~" #'+org-insert-backtick "C-c C-x l" #'org-toggle-link-display - "C-c C-x m" (lambda () (interactive) - (setq-local org-hide-emphasis-markers - (not org-hide-emphasis-markers)) - (font-lock-update)) + "C-c C-x m" #'+org-toggle-view-emphasis "C-c C-x r" #'+org-drawer-list-add-resource "C-M-k" #'kill-paragraph "C-M-t" #'transpose-paragraphs) @@ -761,7 +764,11 @@ (org-link-set-parameters "tel" :follow #'+org-tel-open) (org-link-set-parameters "sms" :follow #'+org-sms-open) (setf (alist-get "\\.x?html?\\'" org-file-apps nil nil #'equal) - #'+org-open-html)) + #'+org-open-html) + (advice-add 'org-agenda :before + (defun +org-agenda-files-uniquify (&rest _) + (setq org-agenda-files + (seq-uniq org-agenda-files))))) (:face 'org-done '((t (:inherit (modus-themes-subtle-green)))) 'org-tag '((t (:inherit (secondary-selection)))) 'org-todo '((t (:inherit (modus-themes-subtle-red))))) @@ -917,6 +924,24 @@ (:local-set comment-auto-fill-only-comments t) (:hook #'prettify-symbols-mode)) +(setup scheme + ;; I use CHICKEN + (:require +chicken) + (:with-mode scheme-mode + (:file-match (rx ".scm" eos))) + (setq scheme-mit-dialect nil + scheme-program-name (executable-find "csi") + scheme-default-implementation 'chicken) + ;; Scheme complete + (straight-use-package 'scheme-complete) + (autoload 'scheme-smart-complete "scheme-complete" nil t) + (with-eval-after-load 'scheme + (define-key scheme-mode-map (kbd "TAB") #'scheme-complete-or-indent)) + (autoload 'scheme-get-current-symbol-info "scheme-complete" nil t) + (:local-set eldoc-documentation-function #'scheme-get-current-symbol-info + lisp-indent-function #'scheme-smart-indent-function) + (:hook #'eldoc-mode)) + (setup scratch (:require +scratch) (:option initial-major-mode #'lisp-interaction-mode @@ -1064,7 +1089,14 @@ (setup (:straight apheleia) (:require apheleia +apheleia) - (+apheleia/user-save-global-mode +1)) + (+apheleia/user-save-global-mode +1) + (add-to-list 'apheleia-formatters `(fmt . ("fmt" + "-s" ; split long lines but don't refill + "-u" ; one space words, two space sentences + "-w" ; set width (fill-column) + ,(number-to-string (floor (* fill-column 1.1))) + "-g" ; goal width + ,(number-to-string fill-column))))) (setup (:straight avy) (:require avy +avy) @@ -1555,10 +1587,11 @@ (setup (:straight editorconfig) (:with-mode conf-mode (:file-match (rx ".editorconfig" eos))) - (dolist (m '(emacs-lisp-mode - lisp-mode - scheme-mode)) - (add-to-list 'editorconfig-exclude-modes m)) + (with-eval-after-load 'editorconfig + (dolist (m '(emacs-lisp-mode + lisp-mode + scheme-mode)) + (add-to-list 'editorconfig-exclude-modes m))) (editorconfig-mode +1)) (setup (:straight electric-cursor) @@ -1644,6 +1677,12 @@ (setup (:straight elpher) (:bind "l" #'elpher-back)) +(setup (:straight emacs-everywhere + (cl-loop for prog in '("xclip" "xdotool" "xprop" "xwininfo") + if (executable-find prog) + return prog + finally return nil))) + (setup (:straight embark) (:require embark +embark) @@ -1737,6 +1776,14 @@ :repo "https://codeberg.org/acdw/filldent.el")) (:+key "M-q" #'filldent-unfill-toggle)) +(setup (:straight (flymake-chicken + :host github + :repo "chicken-contrib/flymake-chicken")) + (add-hook 'scheme-mode-hook (defun +flymake-chicken-init () + (add-hook 'flymake-diagnostic-functions + #'flymake-chicken-backend + nil t)))) + (setup (:straight (flymake-collection :host github :repo "mohkale/flymake-collection")) (+ensure-after-init #'flymake-collection-hook-setup)) @@ -1756,11 +1803,11 @@ (add-hook 'modus-themes-after-load-theme-hook (defun focus-update@after-modus-load () (modus-themes-with-colors - (:face 'focus-unfocused `((t ( :foreground ,fg-inactive - :background ,bg-inactive - :weight normal - :slant normal - :extend t))))))) + (:face 'focus-unfocused `((t ( :foreground ,fg-inactive + :background ,bg-inactive + :weight normal + :slant normal + :extend t))))))) ;; XXX: This doesn't work, because notmuch overlays shit on the buffer (setf (alist-get 'notmuch-show-mode focus-mode-to-thing) 'notmuch-message) @@ -1781,24 +1828,31 @@ (setup (:straight (frowny :host nil :repo "https://codeberg.org/acdw/frowny.el")) (:option frowny-eyes (rx (any ":=") (opt "'") (? "-"))) + (add-to-list 'frowny-inhibit-modes 'vterm-mode) (global-frowny-mode +1)) -(setup (:straight (geiser - :type git - :flavor melpa - :files ("elisp/*.el" "doc/*" "geiser-pkg.el") - :pre-build ("make" "-Cdoc" "geiser.info") - :host gitlab - :repo "emacs-geiser/geiser")) - (dolist (pkg '( geiser-chicken geiser-guile - macrostep-geiser - scheme-complete)) - (straight-use-package pkg)) - (:require +chicken) - (:with-mode scheme-mode - (:file-match (rx ".scm" eos))) - (setf (alist-get "\\.scm\\'" auto-insert-alist nil nil #'equal) - '(insert "#!/bin/sh\n#| -*- scheme -*-\nexec csi -s $0 \"$@\"\n|#\n"))) +;; (setup (:straight (geiser +;; :type git +;; :flavor melpa +;; :files ("elisp/*.el" "doc/*" "geiser-pkg.el") +;; :pre-build ("make" "-Cdoc" "geiser.info") +;; :host gitlab +;; :repo "emacs-geiser/geiser")) +;; (dolist (pkg '( geiser-chicken geiser-guile +;; macrostep-geiser +;; scheme-complete)) +;; (straight-use-package pkg)) +;; (:require +chicken) +;; (+chicken-indentation-insinuate) +;; (:with-mode scheme-mode +;; (:file-match (rx ".scm" eos))) +;; (setf (alist-get "\\.scm\\'" auto-insert-alist nil nil #'equal) +;; '(insert "#!/bin/sh\n#| -*- scheme -*-\nexec csi -s $0 \"$@\"\n|#\n")) +;; ;; (when-let ((scmfmt-exe (executable-find "scmfmt"))) +;; ;; (with-eval-after-load 'apheleia +;; ;; (setf (alist-get 'scmfmt apheleia-formatters) (list scmfmt-exe)) +;; ;; (setf (alist-get 'scheme-mode apheleia-mode-alist) 'scmfmt))) +;; ) (setup (:straight (ghelp :repo "https://github.com/casouri/ghelp")) ;;; XXX: set this up! @@ -1915,9 +1969,9 @@ '(("\\( enters the room ([^)]+)\\| has left the chatroom\\)$") ("." . jabber-muc-presence-dim)) jabber-muc-colorize-foreign nil ; doesn't match my color theme - jabber-groupchat-prompt-format "[%t] %n\n" - jabber-chat-local-prompt-format "[%t] %n\n" - jabber-chat-foreign-prompt-format "[%t] %n\n" + jabber-groupchat-prompt-format "[%t] %n> " + jabber-chat-local-prompt-format "[%t] %n> " + jabber-chat-foreign-prompt-format "[%t] %n> " ;; jabber-chat-foreign-prompt-format ;; (concat +jabber-pre-prompt ;; "%n\n" @@ -1937,17 +1991,17 @@ (add-hook 'modus-themes-after-load-theme-hook (defun jabber-chat@after-modus-themes-load () (modus-themes-with-colors - (:face 'jabber-chat-prompt-foreign `((t (:foreground ,red))) - 'jabber-chat-prompt-local `((t (:foreground ,blue))) - 'jabber-chat-prompt-system `((t (:foreground ,green))))) + (:face 'jabber-chat-prompt-foreign `((t (:foreground ,red))) + 'jabber-chat-prompt-local `((t (:foreground ,blue))) + 'jabber-chat-prompt-system `((t (:foreground ,green))))) (setq jabber-muc-nick-value (pcase (frame--current-backround-mode (selected-frame)) ('light 0.5) ('dark 1.0))) (+mapc-some-buffers #'+jabber-colors-update (lambda () (derived-mode-p 'jabber-chat-mode - 'jabber-roster-mode - 'jabber-activity-mode - 'jabber-browse-mode))))) + 'jabber-roster-mode + 'jabber-activity-mode + 'jabber-browse-mode))))) (dolist (mode '(jabber-chat-mode jabber-browse-mode jabber-roster-mode @@ -2005,6 +2059,9 @@ "M-w" #'link-hint-copy-link "w" #'link-hint-copy-link "M-c" #'+link-hint-open-chrome "c" #'+link-hint-open-chrome))) +(setup (:straight lua-mode) + (:file-match (rx ".lua" eos))) + (setup (:straight (machine :host nil :repo "https://codeberg.org/acdw/machine.el")) @@ -2113,60 +2170,60 @@ "Set up mdous-themes to be mostly monochrome." ;; Major mode in the mode-line (modus-themes-with-colors - (custom-set-faces - `(font-lock-builtin-face - ((,class :inherit modus-themes-bold - :foreground unspecified))) - `(font-lock-comment-face - ((,class :inherit default - :slant normal - :height 1.0 - :foreground ,fg-comment-yellow))) - `(font-lock-comment-delimiter-face - ((,class :inherit fixed-pitch - :foreground ,fg-comment-yellow))) - `(font-lock-constant-face - ((,class :inherit underline - :foreground unspecified))) - `(font-lock-doc-face - ((,class :inherit modus-themes-slant - :foreground ,fg-docstring))) - `(font-lock-function-name-face - ((,class :foreground unspecified - :slant italic))) - `(font-lock-keyword-face - ((,class :inherit modus-themes-bold - :foreground unspecified))) - `(font-lock-negation-char-face - ((,class :inherit modus-themes-bold - :foreground unspecified))) - `(font-lock-preprocessor-face - ((,class :foreground unspecified))) - `(font-lock-regexp-grouping-backslash - ((,class :foreground ,fg-escape-char-backslash))) - `(font-lock-regexp-grouping-construct - ((,class :foreground ,fg-escape-char-construct))) - `(font-lock-string-face - ((,class :foreground ,fg-special-warm))) - `(font-lock-type-face - ((,class :inherit modus-themes-bold - :foreground unspecified))) - `(font-lock-variable-name-face - ((,class :foreground unspecified))) - `(font-lock-warning-face - ((,class :inherit modus-themes-bold - :foreground ,red-nuanced-fg))) - `(font-lock-todo-face - ((,class :inherit font-lock-comment-face - :foreground ,fg-header - :background ,yellow-intense-bg))) - ;; `(mode-line - ;; ((,class :height 100))) - ;; `(mode-line-inactive - ;; ((,class :height 100))) - ;; `(tab-bar - ;; ((,class :height 100))) - )))) + (custom-set-faces + `(font-lock-builtin-face + ((,class :inherit modus-themes-bold + :foreground unspecified))) + `(font-lock-comment-face + ((,class :inherit default + :slant normal + :height 1.0 + :foreground ,fg-comment-yellow))) + `(font-lock-comment-delimiter-face + ((,class :inherit fixed-pitch + :foreground ,fg-comment-yellow))) + `(font-lock-constant-face + ((,class :inherit underline + :foreground unspecified))) + `(font-lock-doc-face + ((,class :inherit modus-themes-slant + :foreground ,fg-docstring))) + `(font-lock-function-name-face + ((,class :foreground unspecified + :slant italic))) + `(font-lock-keyword-face + ((,class :inherit modus-themes-bold + :foreground unspecified))) + `(font-lock-negation-char-face + ((,class :inherit modus-themes-bold + :foreground unspecified))) + `(font-lock-preprocessor-face + ((,class :foreground unspecified))) + `(font-lock-regexp-grouping-backslash + ((,class :foreground ,fg-escape-char-backslash))) + `(font-lock-regexp-grouping-construct + ((,class :foreground ,fg-escape-char-construct))) + `(font-lock-string-face + ((,class :foreground ,fg-special-warm))) + `(font-lock-type-face + ((,class :inherit modus-themes-bold + :foreground unspecified))) + `(font-lock-variable-name-face + ((,class :foreground unspecified))) + `(font-lock-warning-face + ((,class :inherit modus-themes-bold + :foreground ,red-nuanced-fg))) + `(font-lock-todo-face + ((,class :inherit font-lock-comment-face + :foreground ,fg-header + :background ,yellow-intense-bg))) + ;; `(mode-line + ;; ((,class :height 100))) + ;; `(mode-line-inactive + ;; ((,class :height 100))) + ;; `(tab-bar + ;; ((,class :height 100))) + )))) (require 'dawn) (dawn-schedule #'modus-themes-load-operandi @@ -2214,8 +2271,8 @@ (add-hook 'modus-themes-after-load-theme-hook (defun +nyan-modus-update-colors () (modus-themes-with-colors - (set-face-attribute '+nyan-mode-line nil - :background bg-special-warm)))) + (set-face-attribute '+nyan-mode-line nil + :background bg-special-warm)))) (+nyan-modus-update-colors)) (+nyan-mode +1)) @@ -2402,7 +2459,7 @@ '(+modeline-track simple-modeline-segment-misc-info)))) (lambda () (when (featurep 'dired-rsync) - dired-rsync-modeline-status)) + dired-rsync-modeline-status)) ,(+modeline-concat '(+modeline-god-mode +modeline-kmacro-indicator @@ -2433,19 +2490,21 @@ (alert-add-rule :category "slack" :style 'ignore))) -(setup (:straight sly - (defvar +lisp-bin (executable-find "sbcl"))) - (:also-load sly-autoloads - +sly) - (:option inferior-lisp-program +lisp-bin - sly-kill-without-query-p t - sly-command-switch-to-existing-lisp t) - (:with-mode lisp-mode - (:bind "C-c C-z" #'sly-mrepl)) - (:with-feature sly-mrepl - (dolist (key '("RET" "")) - (:bind key #'sly-mrepl-return-at-end)) - (:bind "C-c C-c" #'sly-mrepl-return))) +;; (setup (:straight sly +;; (defvar +lisp-bin (executable-find "sbcl"))) +;; (:also-load sly-autoloads +;; +sly) +;; (:option inferior-lisp-program +lisp-bin +;; sly-kill-without-query-p t +;; sly-command-switch-to-existing-lisp t) +;; (:with-mode lisp-mode +;; (:bind "C-c C-z" #'sly-mrepl)) +;; (:with-feature sly-mrepl +;; (dolist (key '("RET" "")) +;; (:bind key #'sly-mrepl-return-at-end)) +;; (:bind "C-c C-c" #'sly-mrepl-return))) + +(setup (:straight slime)) (setup (:straight smartscan) (:with-map smartscan-map @@ -2461,9 +2520,9 @@ #'describe-gnu-project #'suspend-frame) (sophomore-disable-with 'confirm - #'save-buffers-kill-terminal) + #'save-buffers-kill-terminal) (sophomore-disable-with 'confirm-y - #'+save-buffers-quit) + #'+save-buffers-quit) (sophomore-mode +1)) (setup (:straight (spongebob-case @@ -2609,8 +2668,7 @@ (setup (:straight vterm (and module-file-suffix - (executable-find "cmake")) - :quit) + (executable-find "cmake"))) (:also-load +vterm) (:option vterm-always-compile-module t vterm-buffer-name-string "vterm: %s" diff --git a/lisp/+chicken.el b/lisp/+chicken.el index 55fc48e..15713f8 100644 --- a/lisp/+chicken.el +++ b/lisp/+chicken.el @@ -18,5 +18,17 @@ "awful" "--development-mode" (buffer-file-name)))) (t (message "Some awful error occurred!")))) +(defun +chicken-indentation-insinuate () + "Insinuate indentation from +https://wiki.call-cc.org/emacs#tweaking-stock-scheme-mode-indentation." + (defun scheme-module-indent (state indent-point normal-indent) 0) + (put 'module 'scheme-indent-function 'scheme-module-indent) + (put 'and-let* 'scheme-indent-function 1) + (put 'parameterize 'scheme-indent-function 1) + (put 'handle-exceptions 'scheme-indent-function 1) + (put 'when 'scheme-indent-function 1) + (put 'unless 'scheme-indent-function 1) + (put 'match 'scheme-indent-function 1)) + (provide '+chicken) ;;; +chicken.el ends here diff --git a/lisp/+emacs.el b/lisp/+emacs.el index b69d1a0..9158b62 100644 --- a/lisp/+emacs.el +++ b/lisp/+emacs.el @@ -316,8 +316,9 @@ ARG is passed to `backward-kill-word'." (defun +save-some-buffers-p () "Predicate for `save-some-buffers-default-predicate'. -It returns nil with remote files." - (not (file-remote-p (buffer-file-name)))) +It returns nil with remote files and those without attached files." + (and (buffer-file-name) + (not (file-remote-p (buffer-file-name))))) ;; https://www.wwwtech.de/articles/2013/may/emacs:-jump-to-matching-paren-beginning-of-block (defun +goto-matching-paren (&optional arg) @@ -333,6 +334,14 @@ It returns nil with remote files." ((looking-back "[\[\(\{]" 1) (backward-char) (forward-sexp arg)) (t (up-list arg t t)))) +(defun +delete-window-or-bury-buffer () + "Delete the current window, or bury the current buffer. +If the current window is the only window, bury the buffer." + (interactive) + (condition-case e + (delete-window) + (t (bury-buffer)))) + ;;; Bindings @@ -348,6 +357,7 @@ It returns nil with remote files." (global-set-key (kbd "C-x 4 n") #'clone-buffer) ;; https://christiantietze.de/posts/2022/07/shift-click-in-emacs-to-select/ (global-set-key (kbd "S-") #'mouse-set-mark) +(global-set-key (kbd "C-x 0") #'+delete-window-or-bury-buffer) ;;; Required libraries diff --git a/lisp/+org.el b/lisp/+org.el index 2557671..dc0ce1b 100644 --- a/lisp/+org.el +++ b/lisp/+org.el @@ -343,6 +343,7 @@ Return as a list." (+org-unsmartify) (+org-fix-blank-lines t) (org-align-tags t) + (org-hide-drawer-all) (when (buffer-narrowed-p) (goto-char (point-min)) (forward-line 1) @@ -731,39 +732,48 @@ When called with a prefix ARG, will still unconditionally call ;;; move org archives to a dedicated file -(defun +org-archive-monthwise (archive-file) - (if (file-exists-p archive-file) - (with-current-buffer (find-file-noselect archive-file) - (let ((dir (file-name-directory (file-truename archive-file))) - (prog (make-progress-reporter (format "Archiving from %s..." archive-file))) - (keep-going t)) - (goto-char (point-min)) - (while keep-going - (when-let* ((time (or (org-entry-get (point) "ARCHIVE_TIME") - (org-get-deadline-time (point)))) - (parsed-time (and time - (org-parse-time-string time))) - (refile-target (format "%s%02d-%02d.org" - dir - (decoded-time-year parsed-time) - (decoded-time-month parsed-time))) - (title-str (format "#+title: Archive for %02d-%02d (%s)\n\n" - (decoded-time-year parsed-time) - (decoded-time-month parsed-time) - (file-truename archive-file)))) - (unless (file-exists-p refile-target) - (with-current-buffer (find-file-noselect refile-target) - (insert title-str) - (save-buffer))) - (org-refile nil nil (list "" - refile-target - nil - 0))) - (progress-reporter-update prog) - (org-next-visible-heading 1) - (when (>= (point) (point-max)) - (setq keep-going nil))))) - (message "Archive file %s does not exist!" archive-file))) +;; (defun +org-archive-monthwise (archive-file) +;; (if (file-exists-p archive-file) +;; (with-current-buffer (find-file-noselect archive-file) +;; (let ((dir (file-name-directory (file-truename archive-file))) +;; (prog (make-progress-reporter (format "Archiving from %s..." archive-file))) +;; (keep-going t)) +;; (goto-char (point-min)) +;; (while keep-going +;; (when-let* ((time (or (org-entry-get (point) "ARCHIVE_TIME") +;; (org-get-deadline-time (point)))) +;; (parsed-time (and time +;; (org-parse-time-string time))) +;; (refile-target (format "%s%02d-%02d.org" +;; dir +;; (decoded-time-year parsed-time) +;; (decoded-time-month parsed-time))) +;; (title-str (format "#+title: Archive for %02d-%02d (%s)\n\n" +;; (decoded-time-year parsed-time) +;; (decoded-time-month parsed-time) +;; (file-truename archive-file)))) +;; (unless (file-exists-p refile-target) +;; (with-current-buffer (find-file-noselect refile-target) +;; (insert title-str) +;; (save-buffer))) +;; (org-refile nil nil (list "" +;; refile-target +;; nil +;; 0))) +;; (progress-reporter-update prog) +;; (org-next-visible-heading 1) +;; (when (>= (point) (point-max)) +;; (setq keep-going nil))))) +;; (message "Archive file %s does not exist!" archive-file))) + + +;;; +org-toggle-view-emphasis +;; I thought this function was already written somewhere... +(defun +org-toggle-view-emphasis () + "Toggle `org-hide-emphasis-markers' and redraw the buffer." + (interactive) + (setq-local org-hide-emphasis-markers (not org-hide-emphasis-markers)) + (font-lock-update)) ;;; el-patch diff --git a/machines/bob.el b/machines/bob.el index 7c1a16d..a408e5c 100644 --- a/machines/bob.el +++ b/machines/bob.el @@ -16,7 +16,10 @@ :courier ("Courier Prime Code" "Courier Prime") :gaegu (("Gaegu" 140) "Gaegu") ; no italic :comic (("Comic Code" 100) "Comic Code") - :go/comic (("Go Mono" 100) ("Comic Code" 100)) + :comic/fantasque (("Comic Code" 100) "Fantasque Sans Mono") + :terminus (("Terminus (TTF)" 120) "Terminus (TTF)") + :cmu (("CMU Typewriter Text" 160) "CMU Concrete") + :apl (("APL386 Unicode" 120) "Comic Code") ) "A plist of possible font combinations.") -- cgit 1.4.1-21-gabe81