summaryrefslogtreecommitdiff
path: root/emacs
diff options
context:
space:
mode:
authorMatias Linares <matias.linares@comprandoengrupo.net>2023-09-25 09:33:17 -0300
committerMatias Linares <matias.linares@comprandoengrupo.net>2023-09-25 09:33:17 -0300
commit0f873d646031971dd37824181b65ce457576749e (patch)
tree4c897c8af19d50aa6746ec0c08b90b7b57046c4d /emacs
parent6c4c5513618105ea4ce081b04e0545c7c05431d8 (diff)
downloaddotfiles-0f873d646031971dd37824181b65ce457576749e.tar.gz
Add emacs configuration
Diffstat (limited to 'emacs')
-rw-r--r--emacs/custom-org-mode.el58
-rw-r--r--emacs/custom.el116
-rw-r--r--emacs/init.el426
-rw-r--r--emacs/libs/center-helm-buffer.el55
-rw-r--r--emacs/libs/lambda-line.el1825
-rw-r--r--emacs/libs/minad.el89
m---------emacs/libs/nano-emacs0
-rw-r--r--emacs/libs/penumbra-theme.el512
m---------emacs/libs/slime0
-rw-r--r--emacs/libs/utils.el17
-rw-r--r--emacs/my.el12
-rw-r--r--emacs/nano.el34
-rw-r--r--emacs/projects2
-rw-r--r--emacs/tramp37
14 files changed, 3183 insertions, 0 deletions
diff --git a/emacs/custom-org-mode.el b/emacs/custom-org-mode.el
new file mode 100644
index 0000000..0cdb277
--- /dev/null
+++ b/emacs/custom-org-mode.el
@@ -0,0 +1,58 @@
+;;; package --- custom-org-mode
+;;; Commentary:
+;; This is a package to setup an orgmode editor.
+
+;;; Code:
+;; Setup gargabe collection
+(setq gc-cons-threshold (* 80 1000 1000))
+
+(add-to-list 'load-path "~/.emacs.d/libs/nano-emacs")
+
+(setq nano-font-family-monospaced "Roboto Mono")
+(setq nano-font-family-proportional "Roboto Regular")
+(setq nano-font-size 10)
+
+(require 'nano-layout)
+(require 'nano-theme-light)
+(require 'nano-faces)
+(nano-faces)
+(require 'nano-theme)
+(nano-theme)
+
+(require 'nano-defaults)
+;; Nano header & mode lines (optional)
+(require 'nano-modeline)
+
+;; Nano key bindings modification (optional)
+(require 'nano-bindings)
+
+;; Welcome message (optional)
+(let ((inhibit-message t))
+ (message "Welcome to GNU Emacs / N Λ N O edition")
+ (message (format "Initialization time: %s" (emacs-init-time))))
+
+;; (require 'nano-base-colors)
+
+
+(require 'package)
+;(require 'use-package)
+;; Use https if enabled and add melpa.
+(let* ((no-ssl (and (memq system-type '(windows-nt ms-dos))
+ (not (gnutls-available-p))))
+ (proto (if no-ssl "http" "https")))
+ (add-to-list 'package-archives (cons "melpa" (concat proto "://melpa.org/packages/")) t)
+ (package-initialize))
+
+(use-package org-roam
+ :ensure t
+ :defer t
+ :init (setq org-roam-v2-ack t)
+ :custom
+ (org-roam-directory "~/OrgRoam")
+ :bind (("C-c n l" . org-roam-buffer-toggle)
+ ("C-c n f" . org-roam-node-find)
+ ("C-c n i" . org-roam-node-insert))
+ :config
+ (org-roam-setup))
+(provide 'custom-org-mode)
+;;; custom-org-mode.el ends here
diff --git a/emacs/custom.el b/emacs/custom.el
new file mode 100644
index 0000000..b4bd2b3
--- /dev/null
+++ b/emacs/custom.el
@@ -0,0 +1,116 @@
+(custom-set-variables
+ ;; custom-set-variables was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(ack-command "ack ")
+ '(ansi-color-names-vector
+ ["#ebdbb2" "#cc241d" "#98971a" "#d79921" "#458588" "#b16286" "#689d6a" "#3c3836"])
+ '(compilation-message-face 'default)
+ '(csv-separators '(";" "\11"))
+ '(custom-safe-themes
+ '("5014b68d3880d21a5539af6ef40c1e257e9045d224efb3b65bf0ae7ff2a5e17a" "4294aff6a80a0e683bf1ae776c2ae329f207c6a25c091941bc4025e4346161d1" "6c655326d9bb38d4be02d364d344bfa61b3c8fdabd1cf4b97dddc8c0b3047b47" "109ce4438776b240e7fef0f050f0ac3ff911218533c0fa524c36269f1b5d2676" "ba323a013c25b355eb9a0550541573d535831c557674c8d59b9ac6aa720c21d3" "76c646974f43b321a8fd460a0f5759f916654575da5927d3fd4195029c158018" "871b064b53235facde040f6bdfa28d03d9f4b966d8ce28fb1725313731a2bcc8" "046a2b81d13afddae309930ef85d458c4f5d278a69448e5a5261a5c78598e012" "ddb9bc949afc4ead71a8861e68ad364cd3c512890be51e23a34e4ba5a18b0ade" "6c79c891ffc3120b4dfcb8440e808f12d7593a71cbe933c6ecb70290712c5156" "1930427eae3d4d830a43fd79fbda76021138b929c243a4e8606cf4f0531ea17c" "3c8da990ce9e748a2735d5451192e124914cc0b93faf6e41ffbcdb20f773c0ca" "bcfeecf5f2ee0bbc64450f7c5155145d8d2c590b1310a898c505f48b4b5f4c75" "68b35e92f9daa37685218bd11aa5307140a0ec4c8fd17142a83457619e7b1240" "49887e6f0c666dfc10fad4c23c7a83a176cb296968648c02b85deec25bb11103" "e5a748cbefd483b74b183d7da4fca6228207a6bf9be9792dc85403a186724e1f" "20d3ce5f5cb95716edca608ef7bbc27d9f8d66c9a51200f7be3f08c107810f3e" "d445c7b530713eac282ecdeea07a8fa59692c83045bf84dd112dd738c7bcad1d" "a5270d86fac30303c5910be7403467662d7601b821af2ff0c4eb181153ebfc0a" "98ef36d4487bf5e816f89b1b1240d45755ec382c7029302f36ca6626faf44bbd" "b64a60e69617b4348d0402fad2f0d08a694301132e7ab243dab4d6a65c3bf948" "46c65f6d9031e2f55b919b1486952cddcc8e3ee081ade7eb2ffb6a68a804d30e" "2a7d6f6a46b1b8504b269029a7375597f208a5cdfa1ea125b09255a592bb326e" "74e2ed63173b47d6dc9a82a9a8a6a9048d89760df18bc7033c5f91ff4d083e37" "e16cd3e6093cf35e65dbac6c7649931936f32f56be34477cb7cbe1ee332c5b99" "0af4fc8329f73bd771df30015858813385461513e044df730fc805a49f5ece52" "cc626529cf94f8fd259ebd67e7e85af48b080fd8055f70cd7c4f1c0c86c91179" "84c2c93ce268699838b51eeeaaec46e064d5048e232b39113b73209be3ef6fd4" "c2efe6f5e2bd0bddfb2d6e26040545768939d2029f77e6b6a18d1ee0e0cb1033" "72cc2c6c5642b117034b99dcc3a33ff97a66593429c7f44cd21b995b17eebd4e" "b1a691bb67bd8bd85b76998caf2386c9a7b2ac98a116534071364ed6489b695d" "78e6be576f4a526d212d5f9a8798e5706990216e9be10174e3f3b015b8662e27" "d80952c58cf1b06d936b1392c38230b74ae1a2a6729594770762dc0779ac66b7" "fa49766f2acb82e0097e7512ae4a1d6f4af4d6f4655a48170d0a00bcb7183970" "3e374bb5eb46eb59dbd92578cae54b16de138bc2e8a31a2451bf6fdb0f3fd81b" "19a2c0b92a6aa1580f1be2deb7b8a8e3a4857b6c6ccf522d00547878837267e7" "2ff9ac386eac4dffd77a33e93b0c8236bb376c5a5df62e36d4bfa821d56e4e20" "72ed8b6bffe0bfa8d097810649fd57d2b598deef47c992920aef8b5d9599eefe" "83afe95f30785201eb9e189bf507b0f38076a436804c987c52830214ac025906" "52645403935dd6f8266c3a8f831949c1e79155324efdf709b5af0d078cd6c822" "83f4659ff482028561aed742320eaa491b1416c7c43181647f0c8ef256610dca" "63865ac3d0f7fe970be87f4690ed3c19be51632808f65e6fdd812e74f98b95fa" "d16a286583f7326bb1e3baf7d83df3643533cfa9ac6f0601d1b4a595ad2db523" "e103856e345842bf4334b3db8b773ad01153ce02a3d6655d7c6f5cdb9558c62c" "8d371c95370c5965746ccddd94fe96d7a2fbcdd67a77b3951db6fb11f68baf7d" "be5ebe527c28434cd4bdf33b0430a4eec557e59a63b632695a7ce7014c6713a7" "f87c245f58040e87eba4a7383c6fcf9ca7922e57f2cd71c366176d60efcf305a" "234c3805fb341b7ce2a9e8ce6d72dba9b81e9335422cfee838e128edfb8a9774" "578db0ce196a4c849aa995a0dd32d5fe85da59a1ec303614aa40a28bf9ad8b99" "59820d0ca7ba29984ab4d255f9fcfaa28041ad6ae4b6ae2ffb2ccfbfaec210e4" "5a00018936fa1df1cd9d54bee02c8a64eafac941453ab48394e2ec2c498b834a" "249e100de137f516d56bcf2e98c1e3f9e1e8a6dce50726c974fa6838fbfcec6b" "06ed754b259cb54c30c658502f843937ff19f8b53597ac28577ec33bb084fa52" "e266d44fa3b75406394b979a3addc9b7f202348099cfde69e74ee6432f781336" "e8567ee21a39c68dbf20e40d29a0f6c1c05681935a41e206f142ab83126153ca" "a131602c676b904a5509fff82649a639061bf948a5205327e0f5d1559e04f5ed" "c95813797eb70f520f9245b349ff087600e2bd211a681c7a5602d039c91a6428" "2ce76d65a813fae8cfee5c207f46f2a256bac69dacbb096051a7a8651aa252b0" "11cc65061e0a5410d6489af42f1d0f0478dbd181a9660f81a692ddc5f948bf34" "9cd57dd6d61cdf4f6aef3102c4cc2cfc04f5884d4f40b2c90a866c9b6267f2b3" "159b4110d7b6b71531b3e70a27b773bc3cb13c66e3a5ce001cac064939e46887" "fb2c27e7ad4a81c2f57bceeca0faeb1c84fb7a167c097b998e2a1ea314455fd6" "6d52e002613d477c3e65373f959525f3b10c850bf9f93013cefeb2059dc689f7" "d252b812c27336226a74ebc0960c1ccb7f95e58a0930e2bbe58b9516df5d82d5" "51e1ac68a9844a92b3402b30d3f9f568e15e2015812d4ee79819a489261f9d0a" "3c93094d214c034a89ed81a4bba720a23b090f38f7923a442c879c2bd4dcce5b" "799ceed53273d15b3539cc91b25d728399fe967f78f13ca21659cb7dcb23bd8c" "6a4ec7c23828609753b252d3fa543f153ddd0852a0f724ec31b5f579458c54f0" "d50da51d7dc41c7fc1ce9409a74fd7661540dc4bf54ef55148e59a7763318112" "d0a35d7f6d15d501525e2e134a7254096fc72ae42c0946458372bc7fd00a73ac" "73a183da135380d11ea344ccfe4e78dfe0a6ddcf09f59f050d373f7b4c397c19" "05b767a3f3a37ac46353fd88f194934d82eb6c3644c3b8da883752f57513e7aa" "7343e856679eef5ad722f026037c92e5c60fc9eed6f38ef86b4170b3e524fee3" "c8d99bb565b2412dd867f89eff95ac89ff33111680569db7436e5d6a8c912e64" "47f3e55e4e3d570d5513d4cc58047dc059bd6ab3d135c796c4ccbfb77d4eb88b" "0ce768d3ea6d809292d12b22a5ff6de65e24a8d527e4e0885cf87640f42dff7d" "1070069a4671554a2c00b8375485896c1aa8144f5b8d99b86845069351770ee9" "b7bf7b95fb796614f0b36a7c4906a93db75ad0c6146f336c7ed085f6fceef93d" "a55c6f55eacfa36389dffc8672420b80454db33b59843a1923f3e3054a4643ca" "e8483bc21cf667971eabdbb01203e3a471de1b59a4e532368b7a20f5665d686a" "45611797b789abf53e97c43b29c7f10dd6f18971e238e700bc885e702531053a" "347313c47366c3cb305fb63dff7df87426061d5529a86c215086fe8581228733" "2a0669753764cc15b818fc882d271fc30850d5a45220a499fb9d835846001b7c" "04a9d8ab1ba3288f88018d1a2ba84be4c21a3b3c0b479005ac2b2ee7d417caa3" "931ee45708e894d5233fc4a94ae0065c765c1a0aeb1bd8d9feee22f5622f44b4" "9dbd2c6f93cc1774c261f23042be8bf7decc8f6599c21189c04d7791231b2b79" "c01cd0485ce35cf0a19ab91146d2c2b6528ec60ad4c8ffec5b2b7cc4bc05bd80" "d9a28a009cda74d1d53b1fbd050f31af7a1a105aa2d53738e9aa2515908cac4c" "f00a605fb19cb258ad7e0d99c007f226f24d767d01bf31f3828ce6688cbdeb22" "6128465c3d56c2630732d98a3d1c2438c76a2f296f3c795ebda534d62bb8a0e3" "d516f1e3e5504c26b1123caa311476dc66d26d379539d12f9f4ed51f10629df3" "3c7a784b90f7abebb213869a21e84da462c26a1fda7e5bd0ffebf6ba12dbd041" "22c213e81a533c259127302ef1e0f2d1f332df83969a1f9cf6d5696cbe789543" "9b7d703afa15e320af9aa6b3e02bb1ebb8657c23043f7054357f86ce014b5461" "b8fe3d5d369cef3730db2b28af550f99311351f8a889d2c210565c572952fa5c" "b330e75c3717166db3a8a41eb180c705b46b97c584dffdb917b310f86025c811" "38ab78e4efd20f018e8e963beb2d8c18029219b8c911a0064d16a621310cd487" "bf3653578abaf51e8037c314a9aadf2f67dd9e853e0711b63fbea7a99fc8853b" "7f954d5bee47a27cc6cc83d1d6b80f7a32d82f744a725375d6e22b65758f9a5e" "df069ec238487ceab1cec64809a3c1dcef1393123ecdf430bdb7b94537ca2c6a" "8d68cd652ab405df5db91acc66be58307e008bfac3ddc4beef7d7f814d37026c" "43b78a08f245bc198dadf35b324f445472c92dda3f1b6d1746cefee9f2ade177" "d6c5b14073abc649dad816750ef1ac7d5defdf1630d4e9938e06c38ad547d6da" "06a2eef27703cd3c8b017c90d9025d766ade307971826362c487a5273e14cc5a" "92cfd42cedb42fdd3ea0d84d518825a94f29b30be20f65978dab7d7c8fa30c6a" "1240ba17198f53cac7d4c9c27267f8d497a745e5db5f10233b47ddb820fd271b" "207084af4dc6fd33c7cc8f2070ec5a7af0929cef54928e1af46a94597b9ba8b2" "9e2e4db695753d4846b84e3eb15aab79a04404852801f07f66b080a5d2b6e00f" "d7847e695e0a71f78536cac29f3971aecc794c626784660935267d4a2aabb187" "a701a8612a0105b657a3fc6d686a1afa43f6c26f9339cadc6a26570099f69f26" "c83615b3176138c1b6c646b2df6c87e0bfb497fdc8486a9b280beee9628d9299" "9f97708991e9b0ddc2d428e5bae87d97d8b6c6c09ef82cbfa26a797560de7cec" "eb57c351b0be290c10f71ae3280f319c697cead02eadd06d395f99809d122841" "671bf7cd1ba52017fb369a66dee4a66ae932c4c8264f51199d244a6ff12001c0" "42850fc05cf02fc37c45164a8d7006c762d3ebcd43409efe2c4456a8b89bdf47" "919fabfc5cb6165ce07b9d8668f78fe75fe8bd08566006bc87513c29b4f34ade" "2e023980b41219250a042f39d2d3fb4e686701686f7a7dae9bbb6f352ad37382" "0bfc1a9df8943554fa36c6ac38e6149c58a484273caddf5f78404c7b2edde196" "d84603447cb3b5291abfd7d03a0d79b156c240663687d19e911dde438af15eba" "1827e68476136b7002933452239abede12329c3d54fc27be01a1a2ab10c6a28b" "dbade2e946597b9cda3e61978b5fcc14fa3afa2d3c4391d477bdaeff8f5638c5" "801a567c87755fe65d0484cb2bded31a4c5bb24fd1fe0ed11e6c02254017acb2" "184b3a18e5d1ef9c8885ceb9402c3f67d656616d76bf91f709d1676407c7cf1d" "9b4ae6aa7581d529e20e5e503208316c5ef4c7005be49fdb06e5d07160b67adc" "171d1ae90e46978eb9c342be6658d937a83aaa45997b1d7af7657546cae5985b" "d2e0c53dbc47b35815315fae5f352afd2c56fa8e69752090990563200daae434" "b77a00d5be78f21e46c80ce450e5821bdc4368abf4ffe2b77c5a66de1b648f10" "57e3f215bef8784157991c4957965aa31bac935aca011b29d7d8e113a652b693" "0dd2666921bd4c651c7f8a724b3416e95228a13fca1aa27dc0022f4e023bf197" "b73a23e836b3122637563ad37ae8c7533121c2ac2c8f7c87b381dd7322714cd0" "d14f3df28603e9517eb8fb7518b662d653b25b26e83bd8e129acea042b774298" "1d89fcf0105dd8778e007239c481643cc5a695f2a029c9f30bd62c9d5df6418d" "47e6f8c23eaea064b89ed1361b5824ee4f9562a8c4a30774ee9ee69f9b9d4f69" "18cd5a0173772cdaee5522b79c444acbc85f9a06055ec54bb91491173bc90aaa" "4eb6fa2ee436e943b168a0cd8eab11afc0752aebb5d974bba2b2ddc8910fca8f" "6bdcff29f32f85a2d99f48377d6bfa362768e86189656f63adbf715ac5c1340b" "78c4238956c3000f977300c8a079a3a8a8d4d9fee2e68bad91123b58a4aa8588" "6b5c518d1c250a8ce17463b7e435e9e20faa84f3f7defba8b579d4f5925f60c1" "83e0376b5df8d6a3fbdfffb9fb0e8cf41a11799d9471293a810deb7586c131e6" "7661b762556018a44a29477b84757994d8386d6edee909409fabe0631952dad9" "d9646b131c4aa37f01f909fbdd5a9099389518eb68f25277ed19ba99adeb7279" "998975856274957564b0ab8f4219300bca12a0f553d41c1438bbca065f298a29" default))
+ '(eglot-events-buffer-size 0)
+ '(fci-rule-color "#3C3D37")
+ '(flycheck-flake8-maximum-line-length 120)
+ '(global-flycheck-mode t)
+ '(highlight-changes-colors '("#FD5FF0" "#AE81FF"))
+ '(highlight-tail-colors
+ '(("#3C3D37" . 0)
+ ("#679A01" . 20)
+ ("#4BBEAE" . 30)
+ ("#1DB4D0" . 50)
+ ("#9A8F21" . 60)
+ ("#A75B00" . 70)
+ ("#F309DF" . 85)
+ ("#3C3D37" . 100)))
+ '(hl-paren-background-colors '("#e8fce8" "#c1e7f8" "#f8e8e8"))
+ '(hl-paren-colors '("#40883f" "#0287c8" "#b85c57"))
+ '(magit-diff-use-overlays nil)
+ '(mindre-use-more-bold t)
+ '(mood-line-mode nil)
+ '(org-agenda-files
+ '("~/OrgRoam/agenda.org" "/home/work/OrgRoam/20230808170239-code_reviews.org" "/home/work/OrgRoam/20230808173230-tareas.org"))
+ '(org-jira-working-dir "~/OrgRoam/jira")
+ '(package-selected-packages
+ '(one-themes ob-restclient realgud realgud-ipdb pyimport magit-section humanoid-themes po-mode py-isort yaml-mode plan9-theme imenu-anywhere gruvbox-theme vterm dockerfile-mode jenkinsfile-mode monokai-theme mood-line pyvenv acme-theme org-plus-contrib flycheck exec-path-from-shell python-pytest magit restclient use-package))
+ '(pdf-view-midnight-colors '("#282828" . "#fbf1c7"))
+ '(pos-tip-background-color "#FFFACE")
+ '(pos-tip-foreground-color "#272822")
+ '(projectile-use-git-grep t)
+ '(python-pytest-executable "pytest")
+ '(safe-local-variable-values
+ '((python-shell-interpreter-args . "/home/work/Workspace/ceg-intranet/ceg/manage.py shell_plus")
+ (python-shell-interpreter-args . "")
+ (python-shell-interpreter . "/home/work/Workspace/ceg-intranet/conf/scripts/shell.sh")
+ (python-shell-interpreter-args "compose exec backoffice ./manage.py shell_plus --simple-prompt")
+ (python-shell-interpreter . "docker")
+ (python-pytest-executable . "docker compose exec backoffice pytest")
+ (pyvenv-activate concat
+ (projectile-project-root)
+ "venv")
+ (python-pytest-executable . "pytest")
+ (python-pytest-executable . "docker-compose exec backoffice pytest")
+ (flycheck-flake8rc . "/home/work/Workspace/ceg-intranet/ceg/.flake8")
+ (python-shell-interpreter-args . "/home/work/Workspace/ceg-intranet/ceg/manage.py shell_plus --plain")
+ (python-shell-interpreter . "/home/work/Workspace/ceg-intranet/venv/bin/python")
+ (flycheck-flake8rc . "/home/matiasl/Workspace/ceg-intranet/ceg/.flake8")
+ (python-shell-interpreter-args . "/home/matiasl/Workspace/ceg-intranet/ceg/manage.py shell_plus --plain")
+ (python-shell-interpreter . "/home/matiasl/Workspace/ceg-intranet/venv/bin/python")
+ (python-shell-interpreter-args . "/home/matiasl/Workspace/intranet/ceg/manage.py shell_plus --plain")
+ (python-shell-interpreter . "/home/matiasl/Workspace/intranet/venv/bin/python")))
+ '(sml/active-background-color "#98ece8")
+ '(sml/active-foreground-color "#424242")
+ '(sml/inactive-background-color "#4fa8a8")
+ '(sml/inactive-foreground-color "#424242")
+ '(vc-annotate-background nil)
+ '(vc-annotate-color-map
+ '((20 . "#F92672")
+ (40 . "#CF4F1F")
+ (60 . "#C26C0F")
+ (80 . "#E6DB74")
+ (100 . "#AB8C00")
+ (120 . "#A18F00")
+ (140 . "#989200")
+ (160 . "#8E9500")
+ (180 . "#A6E22E")
+ (200 . "#729A1E")
+ (220 . "#609C3C")
+ (240 . "#4E9D5B")
+ (260 . "#3C9F79")
+ (280 . "#A1EFE4")
+ (300 . "#299BA6")
+ (320 . "#2896B5")
+ (340 . "#2790C3")
+ (360 . "#66D9EF")))
+ '(vc-annotate-very-old-color nil)
+ '(warning-suppress-log-types
+ '(((python python-shell-completion-native-turn-on-maybe))
+ ((python python-shell-completion-native-turn-on-maybe))
+ ((python python-shell-completion-native-turn-on-maybe))
+ (comp)
+ (comp)))
+ '(warning-suppress-types
+ '(((python python-shell-completion-native-turn-on-maybe))
+ ((python python-shell-completion-native-turn-on-maybe))
+ (comp)
+ (comp)))
+ '(weechat-color-list
+ '(unspecified "#272822" "#3C3D37" "#F70057" "#F92672" "#86C30D" "#A6E22E" "#BEB244" "#E6DB74" "#40CAE4" "#66D9EF" "#FB35EA" "#FD5FF0" "#74DBCD" "#A1EFE4" "#F8F8F2" "#F8F8F0")))
+(custom-set-faces
+ ;; custom-set-faces was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(org-block ((t (:font "Fantasque Sans Mono" :height 110))))
+ '(org-code ((t (:font "Fantasque Sans Mono" :height 110))))
+ '(org-document-info ((t (:foreground "dark orange"))))
+ '(org-document-info-keyword ((t (:inherit (shadow) :font "Fantasque Sans Mono" :height 110))))
+ '(org-indent ((t (:inherit (org-hide) :font "Fantasque Sans Mono" :height 110))))
+ '(org-link ((t (:foreground "royal blue" :underline t))))
+ '(org-meta-line ((t (:inherit (font-lock-comment-face) :font "Fantasque Sans Mono" :height 110))))
+ '(org-property-value ((t (:font "Fantasque Sans Mono" :height 110))) t)
+ '(org-special-keyword ((t (:inherit (font-lock-comment-face) :font "Fantasque Sans Mono" :height 110))))
+ '(org-table ((t (:font "Fantasque Sans Mono" :height 110))))
+ '(org-tag ((t (:inherit (shadow) :font "Fantasque Sans Mono" :height 110 :weight bold :height 0.8))))
+ '(org-verbatim ((t (:inherit (shadow) :font "Fantasque Sans Mono" :height 110)))))
diff --git a/emacs/init.el b/emacs/init.el
new file mode 100644
index 0000000..ffd53f6
--- /dev/null
+++ b/emacs/init.el
@@ -0,0 +1,426 @@
+;;; package --- init.el
+;;; Comentary:
+
+;; A new init.el
+
+;;; Code:
+
+(with-eval-after-load 'package
+ (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t))
+
+;; Automatic reread from disk if the underlying file changes
+(setq auto-revert-interval 1)
+(setq auto-revert-check-vc-info t)
+(global-auto-revert-mode)
+
+;; Move thourgh windows with Ctrl-<arrow keys>
+(windmove-default-keybindings 'meta)
+
+;; Fix archaic defaults
+(setq sentence-end-double-space nil)
+
+;; Make right click do something sensible
+(when (display-graphic-p)
+ (context-menu-mode))
+
+
+;; Tramp - Faster than default scp
+(setq tramp-default-method "ssh")
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Interface enhancements/defaults
+;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Mode line information
+(setq line-number-mode t) ; Show current line in modeline
+(setq column-number-mode t) ; Show column as well
+
+(setq x-underline-at-descent-line nil) ; Prettier underlines
+(setq switch-to-buffer-obey-display-actions t) ; Make switching buffers more consistent
+
+(setq-default show-trailing-whitespace nil) ; By default, don't underline trailing spaces
+(setq-default indicate-buffer-boundaries nil) ; Show buffer top and bottom in the margin
+
+;; Misc. UI tweaks
+(blink-cursor-mode -1) ; Steady cursor
+(pixel-scroll-precision-mode) ; Smooth scrolling
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Tab-bar configuration
+;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Show the tab-bar as soon as tab-bar functions are invoked
+(setq tab-bar-show 0)
+
+;; Add the time to the tab-bar, if visible
+(add-to-list 'tab-bar-format 'tab-bar-format-align-right 'append)
+(add-to-list 'tab-bar-format 'tab-bar-format-global 'append)
+(setq display-time-format "%a %F %T")
+(setq display-time-interval 1)
+(display-time-mode)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Theme
+;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(use-package emacs
+ :config
+ (if (display-graphic-p)
+ (progn
+ (load-theme 'modus-operandi)
+ (set-face-attribute 'default nil :font "Fantasque Sans Mono" :height 110)
+ (set-face-attribute 'fixed-pitch nil :font "Input Mono" :height 100)
+ (set-face-attribute 'variable-pitch nil :font "IBM Plex Sans" :height 110)
+ (setq modus-themes-operandi-color-overrides
+ '((bg-main . "#fefcf4"))))
+ (load-theme 'gruvbox-dark-hard)))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Org
+;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(setq org-agenda-files (list "~/OrgRoam/agenda.org"
+ "/home/work/OrgRoam/20230808170239-code_reviews.org"
+ "/home/work/OrgRoam/20230808173230-tareas.org"))
+
+(use-package org
+ :hook ((org-mode . visual-line-mode) ; wrap lines at word breaks
+ (org-mode . flyspell-mode)) ; spell checking!
+
+ :bind (:map global-map
+ ("C-c l s" . org-store-link) ; Mnemonic: link → store
+ ("C-c l i" . org-insert-link-global) ; Mnemonic: link → insert
+ ("C-c a" . org-agenda))
+ :config
+ (require 'org-tempo) ; Abbrv support for code blocks
+ (add-to-list 'org-export-backends 'md)
+
+ ;; Make org-open-at-point follow file links in the same window
+ (setf (cdr (assoc 'file org-link-frame-setup)) 'find-file)
+
+ ;; Make exporting quotes better
+ (setq org-export-with-smart-quotes t)
+ (setq org-confirm-babel-evaluate nil) ; Dont prompt for evaluation
+ )
+(add-hook 'org-mode-hook (lambda ()
+ (auto-fill-mode)
+ (variable-pitch-mode)
+ (bug-reference-mode)
+ (olivetti-mode)
+ (olivetti-set-width 100)))
+(use-package org-roam
+ :ensure t
+ :defer t
+ :init (setq org-roam-v2-ack t)
+ :custom
+ (org-roam-directory "~/OrgRoam")
+ :bind (("C-c n l" . org-roam-buffer-toggle)
+ ("C-c n f" . org-roam-node-find)
+ ("C-c n i" . org-roam-node-insert))
+ :config
+ ;; (org-roam-setup) ;; One shot?
+ (org-roam-db-autosync-mode)
+ (setq org-roam-index-file "~/OrgRoam/index.org")
+ (add-to-list 'display-buffer-alist
+ '("\\*org-roam\\*"
+ (display-buffer-in-side-window)
+ (side . right)
+ (window-width . 0.4)
+ (window-height . fit-window-to-buffer))))
+
+(use-package org-jira
+ :config (setq jiralib-url "https://comprandoengrupo.atlassian.net"))
+
+(use-package org-modern
+ :ensure t
+ :init (global-org-modern-mode))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Minibuffer and completion
+;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Vertico: better vertical completion for minibuffer commands
+(use-package vertico
+ :ensure t
+ :init
+ ;; You'll want to make sure that e.g. fido-mode isn't enabled
+ (vertico-mode))
+
+;; Marginalia: annotations for minibuffer
+(use-package marginalia
+ :ensure t
+ :config
+ (marginalia-mode))
+
+(use-package corfu
+ :ensure t
+ :custom
+ (corfu-cycle t)
+ :bind
+ (:map corfu-map
+ ("SPC" . corfu-insert-separator))
+ :hook ((prog-mode . corfu-mode)
+ (shell-mode . corfu-mode)
+ (eshell-mode . corfu-mode))
+ :init (global-corfu-mode))
+
+;; Part of corfu
+(use-package corfu-popupinfo
+ :after corfu
+ :hook (corfu-mode . corfu-popupinfo-mode)
+ :custom
+ (corfu-popupinfo-delay '(0.25 . 0.1))
+ (corfu-popupinfo-hide nil)
+ :config
+ (corfu-popupinfo-mode))
+
+;; Make corfu popup come up in terminal overlay
+(use-package corfu-terminal
+ :if (not (display-graphic-p))
+ :ensure t
+ :config
+ (corfu-terminal-mode))
+
+;; Pretty icons for corfu
+(use-package kind-icon
+ :if (display-graphic-p)
+ :ensure t
+ :after corfu
+ :config
+ (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))
+
+;; Orderless: powerful completion style
+(use-package orderless
+ :ensure t
+ :config
+ (setq completion-styles '(orderless)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Packages
+;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Treesiter config
+
+(use-package emacs
+ :config
+ ;; Treesitter config
+
+ ;; Tell Emacs to prefer the treesitter mode
+ ;; You'll want to run the command `M-x treesit-install-language-grammar' before editing.
+ (setq major-mode-remap-alist
+ '(;(yaml-mode . yaml-ts-mode)
+ (bash-mode . bash-ts-mode)
+ (js2-mode . js-ts-mode)
+ (typescript-mode . typescript-ts-mode)
+ (json-mode . json-ts-mode)
+ (css-mode . css-ts-mode)
+ (python-mode . python-ts-mode)))
+ :hook
+ ;; Auto parenthesis matching
+ ((prog-mode . electric-pair-mode)))
+
+;; Eglot
+(use-package eglot
+ ;; no :ensure t here because it's built-in
+
+ ;; Configure hooks to automatically turn-on eglot for selected modes
+ ; :hook
+ ; (((python-mode ruby-mode elixir-mode) . eglot))
+
+ :custom
+ (eglot-send-changes-idle-time 0.1)
+
+ :config
+ (fset #'jsonrpc--log-event #'ignore) ; massive perf boost---don't log every event
+ ;; Sometimes you need to tell Eglot where to find the language server
+ ; (add-to-list 'eglot-server-programs
+ ; '(haskell-mode . ("haskell-language-server-wrapper" "--lsp")))
+ (add-to-list 'eglot-server-programs
+ '(python-ts-mode . ("pylsp" "--tcp" "--port" :autoport)))
+ )
+
+;; YAML
+(use-package yaml-mode :ensure t)
+
+;; JSON
+(use-package json-mode :ensure t)
+(add-hook 'js-json-mode-hook
+ (lambda ()
+ (define-key js-json-mode-map (kbd "<f5>") 'json-pretty-print-buffer)))
+
+;; Lisp
+(use-package slime :defer t :ensure t)
+(setq inferior-lisp-program "sbcl")
+
+;; Rest client
+(use-package restclient :defer t :ensure t)
+
+;; Magit
+(use-package magit
+ :ensure t
+ :bind (("s-g" . magit-status)
+ ("C-c g" . magit-status)))
+
+;; python-mode configuration
+
+(use-package pyvenv
+ :ensure t
+ :config
+ ;; Set correct Python interpreter
+ (setq pyvenv-post-activate-hooks
+ (list (lambda ()
+ (setq python-shell-interpreter (concat pyvenv-virtual-env "bin/python3")))))
+ (setq pyvenv-post-deactivate-hooks
+ (list (lambda ()
+ (setq python-shell-interpreter "python3")))))
+
+(use-package python-pytest
+ :defer t
+ :ensure t
+ :config
+ (transient-append-suffix
+ 'python-pytest-dispatch
+ "-v"
+ '("--db" "Create db" "--create-db")))
+
+(add-hook 'python-ts-mode-hook
+ (lambda ()
+ (define-key python-ts-mode-map (kbd "C-c p") 'python-pytest-dispatch)
+ (define-key python-ts-mode-map (kbd "C-c m p") 'ceg/pre-commit-run-current-file)))
+
+;; Load path from shell environment
+(use-package exec-path-from-shell :ensure t :defer t)
+
+;; sh-mode configuration
+(use-package flymake-shellcheck
+ :commands flymake-shellcheck-load
+ :init
+ (add-hook 'sh-mode-hook 'flymake-shellcheck-load))
+
+
+;; Moodline
+(use-package mood-line :ensure t)
+(mood-line-mode)
+
+;; Fix for flycheck with eglot
+;; https://gitlab.com/jessieh/mood-line/-/merge_requests/11
+(require 'cl-lib)
+
+(defun mood-line--checker-flymake-count-errors ()
+ "Return alist with count of all current flymake diagnostic reports.
+
+Counts will be returned in an alist as the cdr of the following keys:
+`'note-count' | All notes reported by checker
+`'error-count' | All errors reported by checker
+`'warning-count' | All warnings reported by checkero
+`'issue-count' | All errors and warnings reported by checker
+`'all-count' | Everything reported by checker"
+ (let ((error-count 0)
+ (warning-count 0)
+ (note-count 0))
+ (progn
+ (cl-loop
+ with warning-level = (warning-numeric-level :warning)
+ with note-level = (warning-numeric-level :debug)
+ for state being the hash-values of flymake--state
+ do (cl-loop
+ with diags = (flymake--state-diags state)
+ for diag in diags do
+ (let ((severity (flymake--lookup-type-property (flymake--diag-type diag) 'severity
+ (warning-numeric-level :error))))
+ (cond ((> severity warning-level) (cl-incf error-count))
+ ((> severity note-level) (cl-incf warning-count))
+ (t (cl-incf note-count)))))))
+ `((note-count . ,note-count)
+ (error-count . ,error-count)
+ (warning-count . ,warning-count)
+ (issue-count . ,(+ warning-count
+ error-count))
+ (all-count . ,(+ note-count
+ warning-count
+ error-count)))))
+
+;; IMenu everywhere
+(use-package imenu-anywhere
+ :ensure t
+ :bind (("C-." . imenu-anywhere)))
+
+;; Projectile
+(use-package projectile
+ :init
+ (setq projectile-use-git-grep t))
+(projectile-mode +1)
+(define-key projectile-mode-map (kbd "M-p") 'projectile-command-map)
+
+
+(use-package projectile-rails
+ :defer t :ensure t
+ :init (projectile-rails-global-mode))
+(define-key projectile-rails-mode-map (kbd "C-c r")
+ 'projectile-rails-command-map)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Custom functions
+;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun ceg/pre-commit-run-current-file ()
+ "Run pre-commit with the current file name"
+ (interactive)
+ (let ((full-command (concat "pre-commit run --file " buffer-file-name " | sed 's;^ceg/;;g'")))
+ (compile full-command)))
+
+(defun ceg/pre-commit-run ()
+ "Run pre-commit with the current file name"
+ (interactive)
+ (let ((full-command (concat "pre-commit run | sed 's;^ceg/;;g'")))
+ (compile full-command)))
+
+(add-hook 'python-mode (lambda ()
+ (local-set-key ("C-c o")
+ 'ceg/pre-commit-run)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Global keybindigns
+;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define-key global-map (kbd "RET") 'newline-and-indent)
+(global-set-key (kbd "C-x C-b") 'ibuffer)
+(global-set-key (kbd "C-;") 'completion-at-point)
+(global-set-key (kbd "C-x g") 'magit-status)
+(global-set-key (kbd "M-z") 'zap-up-to-char)
+(global-set-key (kbd "C-.") #'imenu-anywhere)
+(global-set-key (kbd "M-o") 'other-window)
+(custom-set-variables
+ ;; custom-set-variables was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(custom-safe-themes
+ '("919fabfc5cb6165ce07b9d8668f78fe75fe8bd08566006bc87513c29b4f34ade" "3770d0ae70172461ee0a02edcff71b7d480dc54066e8960d8de9367d12171efb" default))
+ '(safe-local-variable-values
+ '((python-pytest-executable . "pytest")
+ (python-shell-interpreter-args . "/home/work/Workspace/ceg-intranet/ceg/manage.py shell_plus --plain"))))
+(custom-set-faces
+ ;; custom-set-faces was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ )
diff --git a/emacs/libs/center-helm-buffer.el b/emacs/libs/center-helm-buffer.el
new file mode 100644
index 0000000..85f8438
--- /dev/null
+++ b/emacs/libs/center-helm-buffer.el
@@ -0,0 +1,55 @@
+;;; package --- Center the helm buffer to the emacs window
+;;; Commentary:
+
+;;; Code:
+
+(defun my-helm-display-frame-center (buffer &optional resume)
+ "Display `BUFFER' in a separate frame which centered in parent frame.
+
+I don't know what's RESUME."
+ (if (not (display-graphic-p))
+ ;; Fallback to default when frames are not usable.
+ (helm-default-display-buffer buffer)
+ (setq helm--buffer-in-new-frame-p t)
+ (let* ((parent (selected-frame))
+ (frame-pos (frame-position parent))
+ (parent-left (car frame-pos))
+ (parent-top (cdr frame-pos))
+ (width (/ (frame-width parent) 2))
+ (height (/ (frame-height parent) 3))
+ tab-bar-mode
+ (default-frame-alist
+ (if resume
+ (buffer-local-value 'helm--last-frame-parameters
+ (get-buffer buffer))
+ `((parent . ,parent)
+ (width . ,width)
+ (height . ,height)
+ (undecorated . ,helm-use-undecorated-frame-option)
+ (left-fringe . 0)
+ (right-fringe . 0)
+ (tool-bar-lines . 0)
+ (line-spacing . 0)
+ (desktop-dont-save . t)
+ (no-special-glyphs . t)
+ (inhibit-double-buffering . t)
+ (tool-bar-lines . 0)
+ (left . ,(+ parent-left (/ (* (frame-char-width parent) (frame-width parent)) 4)))
+ (top . ,(+ parent-top (/ (* (frame-char-width parent) (frame-height parent)) 2)))
+ (title . "Helm")
+ (vertical-scroll-bars . nil)
+ (menu-bar-lines . 0)
+ (fullscreen . nil)
+ (visible . ,(null helm-display-buffer-reuse-frame))
+ ;; (internal-border-width . ,(if IS-MAC 1 0))
+ )))
+ display-buffer-alist)
+ (set-face-background 'internal-border (face-foreground 'default))
+ (helm-display-buffer-popup-frame buffer default-frame-alist))
+ (helm-log-run-hook 'helm-window-configuration-hook)))
+
+(setq helm-display-function 'my-helm-display-frame-center)
+
+
+(provide 'center-helm-buffer)
+;;; center-helm-buffer.el ends here
diff --git a/emacs/libs/lambda-line.el b/emacs/libs/lambda-line.el
new file mode 100644
index 0000000..acbd660
--- /dev/null
+++ b/emacs/libs/lambda-line.el
@@ -0,0 +1,1825 @@
+;;; lambda-line.el --- A custom status line -*- lexical-binding: t -*-
+
+;; Author: Colin McLear
+;; Maintainer: Colin McLear
+;; Version: 0.2.0
+;; Package-Requires: ((emacs "27.1"))
+;; Homepage: https://github.com/Lambda-Emacs/lambda-line
+;; Keywords: mode-line faces
+
+;; This file is NOT part of GNU Emacs
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; lambda-line is a minimal, though opinionated, status-line (i.e. in Emacs the
+;; information display either in the mode-line and/or header-line) for use as
+;; either header or footer in a buffer. The structure of the status-line takes
+;; the following form: [ status | name (primary) tertiary | secondary ]
+
+;; Usage: M-x lambda-line-mode
+
+;;; Code:
+
+(require 'face-remap)
+(require 'cl-lib)
+(require 'all-the-icons)
+
+;;;; Group
+
+(defgroup lambda-line nil
+ "lambda-line group"
+ :group 'mode-line
+ :link '(url-link :tag "Homepage" "https://github.com/Lambda-Emacs/lambda-line"))
+
+;;;; Custom Variable Settings
+
+(defcustom lambda-line-window-width-limit 0.25
+ "The limit of the window width.
+If `window-width' is smaller than the limit, some information won't be
+displayed. It can be an integer or a float number. `nil' means no limit."
+ :type '(choice integer
+ float
+ (const :tag "Disable" nil))
+ :group 'lambda-line)
+
+(defcustom lambda-line-position 'bottom
+ "Default modeline position (top or bottom)"
+ :type '(choice
+ (const :tag "Nil" nil)
+ (const :tag "Top" top)
+ (const :tag "Bottom" bottom))
+ :group 'lambda-line)
+
+(defcustom lambda-line-prefix t
+ "Include a prefix icon to indicate buffer status in the status-line."
+ :type 'boolean
+ :group 'lambda-line)
+
+(defcustom lambda-line-prefix-padding t
+ "Include prefix padding."
+ :type 'boolean
+ :group 'lambda-line)
+
+(defcustom lambda-line-user-mode nil
+ "User supplied mode to be evaluated for modeline."
+ :type '(choice (const nil) function)
+ :group 'lambda-line)
+
+(defcustom lambda-line-abbrev nil
+ "If t then show abbreviated mode symbol in modeline.
+Default is nil. To change the values of the major-mode symbols
+see the value of `lambda-line-abbrev-alist'"
+ :group 'lambda-line
+ :type 'boolean)
+
+(defcustom lambda-line-git-diff-mode-line t
+ "If t then show diff lines in modeline."
+ :group 'lambda-line
+ :type 'boolean)
+
+(defcustom lambda-line-vc-symbol ""
+ "Symbol to use in buffers visiting files under version control"
+ :group 'lambda-line
+ :type 'string)
+
+;; Visual Bell
+(defcustom lambda-line-visual-bell t
+ "If t then use `lambda-line-visual-bell'."
+ :group 'lambda-line
+ :type 'boolean)
+
+;; Invert status faces
+;; This make lambda-line look more like nano-modeline
+(defcustom lambda-line-status-invert nil
+ "If t then invert the colors to get a box effect for the corner of the status line."
+ :group 'lambda-line
+ :type 'boolean)
+
+;; Mode line symbols
+(defcustom lambda-line-gui-ro-symbol " ⨂" ;; ⬤◯⨂
+ "Modeline gui read-only symbol."
+ :group 'lambda-line
+ :type 'string)
+
+(defcustom lambda-line-gui-mod-symbol " ⬤" ;; ⨀⬤
+ "Modeline gui modified symbol."
+ :group 'lambda-line
+ :type 'string)
+
+(defcustom lambda-line-gui-rw-symbol " ◯" ; λ ◉ ◎ ⬤◯
+ "Modeline gui read-write symbol."
+ :group 'lambda-line
+ :type 'string)
+
+(defcustom lambda-line-tty-ro-symbol " 𝛌 "
+ "Modeline tty read-only symbol."
+ :group 'lambda-line
+ :type 'string)
+
+(defcustom lambda-line-tty-mod-symbol " 𝛌 "
+ "Modeline tty read-only symbol."
+ :group 'lambda-line
+ :type 'string)
+
+(defcustom lambda-line-tty-rw-symbol " 𝛌 "
+ "Modeline tty read-write symbol."
+ :group 'lambda-line
+ :type 'string)
+
+(defcustom lambda-line-truncate-value 30
+ "Value of modeline truncate-length function."
+ :group 'lambda-line
+ :type 'integer)
+
+(defcustom lambda-line-hspace " "
+ "Space adjustment for right end of modeline."
+ :type 'string
+ :group 'lambda-line)
+
+(defcustom lambda-line-space-top +.35
+ "Space adjustment for top of status-line.
+Positive is upwards"
+ :type 'float
+ :group 'lambda-line)
+
+(defcustom lambda-line-space-bottom -.5
+ "Space adjustment for bottom of status-line.
+Negative is downwards."
+ :type 'float
+ :group 'lambda-line)
+
+(defcustom lambda-line-symbol-position .067
+ "Space adjustment for symbol in status-line.
+Negative is downwards."
+ :type 'float
+ :group 'lambda-line)
+
+(defcustom lambda-line-syntax t
+ "Show flycheck/flymake report in status-line."
+ :type 'boolean
+ :group 'lambda-line)
+
+(defcustom lambda-line-flycheck-label "Issues: "
+ "Show with flycheck/flymake issues count."
+ :type 'string
+ :group 'lambda-line)
+
+(defcustom lambda-line-icon-time nil
+ "When set to non-nil show the time as an icon clock.
+Time info is only shown `display-time-mode' is non-nil"
+ :type 'boolean
+ :group 'lambda-line)
+
+(defcustom lambda-line-time-day-and-date-format " %H:%M %Y-%m-%e "
+ "`format-time-string'."
+ :type 'string
+ :group 'lambda-line)
+
+(defcustom lambda-line-time-format " %H:%M "
+ "`format-time-string'."
+ :type 'string
+ :group 'lambda-line)
+
+(defcustom lambda-line-time-icon-format " %s"
+ "`format-time-string'."
+ :type 'string
+ :group 'lambda-line)
+
+(defcustom lambda-line-display-group-start "("
+ "Modeline display group start indicator."
+ :group 'lambda-line
+ :type 'string)
+
+(defcustom lambda-line-display-group-end ")"
+ "Modeline display group end indicator."
+ :group 'lambda-line
+ :type 'string)
+
+(defcustom lambda-line-mode-formats
+ '(;; with :mode-p first
+ (imenu-list-mode :mode-p lambda-line-imenu-list-mode-p
+ :format lambda-line-imenu-list-mode)
+ (org-capture-mode :mode-p lambda-line-org-capture-mode-p
+ :format lambda-line-org-capture-mode
+ :on-activate lambda-line-org-capture-activate
+ :on-deactivate lambda-line-org-capture-deactivate)
+ (prog-mode :mode-p lambda-line-prog-mode-p
+ :format lambda-line-prog-mode
+ :on-activate lambda-line-prog-activate
+ :on-deactivate lambda-line-prog-deactivate)
+ (mu4e-dashboard-mode :mode-p lambda-line-mu4e-dashboard-mode-p
+ :format lambda-line-mu4e-dashboard-mode)
+ (messages-mode :mode-p lambda-line-messages-mode-p
+ :format lambda-line-messages-mode)
+ (message-mode :mode-p lambda-line-message-mode-p
+ :format lambda-line-message-mode)
+ (term-mode :mode-p lambda-line-term-mode-p
+ :format lambda-line-term-mode)
+ (vterm-mode :mode-p lambda-line-vterm-mode-p
+ :format lambda-line-term-mode)
+ (eshell-mode :mode-p lambda-line-eshell-mode-p
+ :format lambda-line-eshell-mode)
+ (buffer-menu-mode :mode-p lambda-line-buffer-menu-mode-p
+ :format lambda-line-buffer-menu-mode
+ :on-activate lambda-line-buffer-menu-activate
+ :on-deactivate lambda-line-buffer-menu-deactivate)
+ (calendar-mode :mode-p lambda-line-calendar-mode-p
+ :format lambda-line-calendar-mode
+ :on-activate lambda-line-calendar-activate
+ :on-deactivate lambda-line-calendar-deactivate)
+ (completion-list-mode :mode-p lambda-line-completion-list-mode-p
+ :format lambda-line-completion-list-mode)
+ (deft-mode :mode-p lambda-line-deft-mode-p
+ :format lambda-line-deft-mode)
+ (doc-view-mode :mode-p lambda-line-doc-view-mode-p
+ :format lambda-line-doc-view-mode)
+ (elfeed-search-mode :mode-p lambda-line-elfeed-search-mode-p
+ :format lambda-line-elfeed-search-mode
+ :on-activate lambda-line-elfeed-search-activate
+ :on-deactivate lambda-line-elfeed-search-deactivate)
+ (elfeed-show-mode :mode-p lambda-line-elfeed-show-mode-p
+ :format lambda-line-elfeed-show-mode)
+ (elpher-mode :mode-p lambda-line-elpher-mode-p
+ :format lambda-line-elpher-mode
+ :on-activate lambda-line-elpher-activate)
+ (help-mode :mode-p lambda-line-help-mode-p
+ :format lambda-line-help-mode)
+ (helpful-mode :mode-p lambda-line-helpful-mode-p
+ :format lambda-line-help-mode)
+ (info-mode :mode-p lambda-line-info-mode-p
+ :format lambda-line-info-mode
+ :on-activate lambda-line-info-activate
+ :on-deactivate lambda-line-info-deactivate)
+ (magit-mode :mode-p lambda-line-magit-mode-p
+ :format lambda-line-magit-mode)
+ (mu4e-compose-mode :mode-p lambda-line-mu4e-compose-mode-p
+ :format lambda-line-mu4e-compose-mode)
+ (mu4e-headers-mode :mode-p lambda-line-mu4e-headers-mode-p
+ :format lambda-line-mu4e-headers-mode)
+ (mu4e-loading-mode :mode-p lambda-line-mu4e-loading-mode-p
+ :format lambda-line-mu4e-loading-mode)
+ (mu4e-main-mode :mode-p lambda-line-mu4e-main-mode-p
+ :format lambda-line-mu4e-main-mode)
+ (mu4e-view-mode :mode-p lambda-line-mu4e-view-mode-p
+ :format lambda-line-mu4e-view-mode)
+ (org-agenda-mode :mode-p lambda-line-org-agenda-mode-p
+ :format lambda-line-org-agenda-mode)
+
+ (org-clock-mode :mode-p lambda-line-org-clock-mode-p
+ :format lambda-line-org-clock-mode
+ :on-activate lambda-line-org-clock-activate
+ :on-deactivate lambda-line-org-clock-deactivate)
+ (pdf-view-mode :mode-p lambda-line-pdf-view-mode-p
+ :format lambda-line-pdf-view-mode)
+ (fundamental-mode :mode-p lambda-line-fundamental-mode-p
+ :format lambda-line-fundamental-mode)
+ (text-mode :mode-p lambda-line-text-mode-p
+ :format lambda-line-text-mode)
+
+ ;; hooks only go last
+ (ein-notebook-mode :on-activate lambda-line-ein-notebook-activate
+ :on-deactivate lambda-line-ein-notebook-deactivate)
+ (esh-mode :on-activate lambda-line-esh-activate
+ :on-deactivate lambda-line-esh-deactivate)
+ (ispell-mode :on-activate lambda-line-ispell-activate
+ :on-deactivate lambda-line-ispell-deactivate)
+ (mu4e-mode :on-activate lambda-line-mu4e-activate
+ :on-deactivate lambda-line-mu4e-deactivate))
+
+ "Modes to be evalued for modeline.
+KEY mode name, for reference only. Easier to do lookups and/or replacements.
+:MODE-P the function to check if :FORMAT needs to be used, first one wins.
+:ON-ACTIVATE and :ON-DEACTIVATE do hook magic on enabling/disabling the mode.
+"
+ :type '(alist :key-type symbol
+ :value-type (plist :key-type (choice (const :mode-p)
+ (const :format)
+ (const :on-activate)
+ (const :on-deactivate))
+ :value-type function))
+ :group 'lambda-line)
+
+(defcustom lambda-line-mode-format-activate-hook nil
+ "Add hooks on activation of the mode.
+This is for those modes that define their own status-line."
+ :type 'hook
+ :options '(turn-on-auto-fill flyspell-mode)
+ :group 'lambda-line)
+
+(defcustom lambda-line-mode-format-deactivate-hook nil
+ "Remove hooks on de-activation of the mode.
+This is for those modes that define their own status-line."
+ :type 'hook
+ :options '(turn-on-auto-fill flyspell-mode)
+ :group 'lambda-line)
+
+(defcustom lambda-line-default-mode-format 'lambda-line-default-mode
+ "Default mode to evaluate.
+This is if no match could be found in `lambda-lines-mode-formats'"
+ :type 'function
+ :group 'lambda-line)
+
+;;;; Faces
+;;;;; Line Faces
+
+(defface lambda-line-active
+ '((t (:inherit (mode-line))))
+ "Modeline face for active modeline."
+ :group 'lambda-line-active)
+
+(defface lambda-line-inactive
+ '((t (:inherit (mode-line-inactive))))
+ "Modeline face for inactive line."
+ :group 'lambda-line-inactive)
+
+(defface lambda-line-hspace-active
+ '((t (:invisible t :family "Monospace" :inherit (mode-line))))
+ "Face for vertical spacer in active line.")
+
+(defface lambda-line-hspace-inactive
+ '((t (:invisible t :family "Monospace" :inherit (mode-line-inactive))))
+ "Face for vertical spacer in inactive line.")
+
+(defface lambda-line-active-name
+ '((t (:inherit (mode-line))))
+ "Modeline face for active name element."
+ :group 'lambda-line-active)
+
+(defface lambda-line-inactive-name
+ '((t (:inherit (mode-line-inactive))))
+ "Modeline face for inactive name element."
+ :group 'lambda-line-inactive)
+
+(defface lambda-line-active-primary
+ '((t (:weight light :inherit (mode-line))))
+ "Modeline face for active primary element."
+ :group 'lambda-line-active)
+
+(defface lambda-line-inactive-primary
+ '((t (:inherit (mode-line-inactive))))
+ "Modeline face for inactive primary element."
+ :group 'lambda-line-inactive)
+
+(defface lambda-line-active-secondary
+ '((t (:inherit mode-line)))
+ "Modeline face for active secondary element."
+ :group 'lambda-line-active)
+
+(defface lambda-line-inactive-secondary
+ '((t (:inherit (mode-line-inactive))))
+ "Modeline face for inactive secondary element."
+ :group 'lambda-line-inactive)
+
+(defface lambda-line-active-tertiary
+ '((t (:inherit mode-line)))
+ "Modeline face for active tertiary element."
+ :group 'lambda-line-active)
+
+(defface lambda-line-inactive-tertiary
+ '((t (:inherit (mode-line-inactive))))
+ "Modeline face for inactive tertiary element."
+ :group 'lambda-line-inactive)
+
+
+;;;;; Status Bar Faces
+
+;; lambda-line uses a colored symbol to indicate the status of the buffer
+
+(defface lambda-line-active-status-RO
+ '((t (:inherit (mode-line) :foreground "yellow" (when lambda-line-status-invert :inverse-video t))))
+ "Modeline face for active READ-ONLY element."
+ :group 'lambda-line-active)
+
+(defface lambda-line-inactive-status-RO
+ '((t (:inherit (mode-line-inactive) :foreground "light gray" (when lambda-line-status-invert :inverse-video t))))
+ "Modeline face for inactive READ-ONLY element."
+ :group 'lambda-line-inactive)
+
+(defface lambda-line-active-status-RW
+ '((t (:inherit (mode-line) :foreground "green" (when lambda-line-status-invert :inverse-video t))))
+ "Modeline face for active READ-WRITE element."
+ :group 'lambda-line-active)
+
+(defface lambda-line-inactive-status-RW
+ '((t (:inherit (mode-line-inactive) :foreground "light gray" (when lambda-line-status-invert :inverse-video t))))
+ "Modeline face for inactive READ-WRITE element."
+ :group 'lambda-line-inactive)
+
+(defface lambda-line-active-status-MD
+ '((t (:inherit (mode-line) :foreground "red" (when lambda-line-status-invert :inverse-video t))))
+ "Modeline face for active MODIFIED element."
+ :group 'lambda-line-active)
+
+(defface lambda-line-inactive-status-MD
+ '((t (:inherit (mode-line-inactive) :foreground "light gray" (when lambda-line-status-invert :inverse-video t))))
+ "Modeline face for inactive MODIFIED element."
+ :group 'lambda-line-inactive)
+
+
+;;;;; Bell Faces
+
+(defface lambda-line-visual-bell '((t (:background "red3")))
+ "Face to use for the mode-line when `lambda-line-visual-bell-config' is used."
+ :group 'lambda-line)
+
+;;;; Setup Functions
+
+;;;;; Visual bell for mode line
+
+;; See https://github.com/hlissner/emacs-doom-themes for the basic idea
+
+(defun lambda-line-visual-bell-fn ()
+ "Blink the status-line red briefly. Set `ring-bell-function' to this to use it."
+ (let ((lambda-line--bell-cookie (if (eq lambda-line-position 'bottom)
+ (face-remap-add-relative 'mode-line 'lambda-line-visual-bell)
+ (face-remap-add-relative 'header-line 'lambda-line-visual-bell)))
+ (force-mode-line-update t))
+ (run-with-timer 0.15 nil
+ (lambda (cookie buf)
+ (with-current-buffer buf
+ (face-remap-remove-relative cookie)
+ (force-mode-line-update t)))
+ lambda-line--bell-cookie
+ (current-buffer))))
+
+(defun lambda-line-visual-bell-config ()
+ "Enable flashing the status-line on error."
+ (setq ring-bell-function #'lambda-line-visual-bell-fn
+ visible-bell t))
+
+;;;;; Abbreviate Major-Mode
+;; Source: https://www.masteringemacs.org/article/hiding-replacing-modeline-strings
+
+(defcustom lambda-line-abbrev-alist
+ `((dired-mode . "Dir")
+ (emacs-lisp-mode . "𝛌")
+ (fundamental-mode . "F")
+ (helpful-mode . "")
+ (help-mode . "")
+ (lisp-interaction-mode . "λΙ")
+ (markdown-mode . "MD")
+ (magit-mode . "MG")
+ (nxhtml-mode . "NX")
+ (prog-mode . "PR")
+ (python-mode . "PY")
+ (text-mode . "TX"))
+ "Alist for `lambda-line--abbrev'.
+
+When you add a new element to the alist, keep in mind that you
+must pass the correct minor/major mode symbol and a string you
+want to use in the modeline *as substitute for* the original."
+ :type '(alist
+ :key-type (symbol :tag "Major mode")
+ :value-type (string :tag "Abbreviation"))
+ :group 'lambda-line)
+
+(defun lambda-line--abbrev ()
+ (cl-loop for abbrev in lambda-line-abbrev-alist
+ do (let* ((mode (car abbrev))
+ (mode-str (cdr abbrev))
+ (old-mode-str (cdr (assq mode minor-mode-alist))))
+ (when old-mode-str
+ (setcar old-mode-str mode-str))
+ ;; major mode
+ (when (eq mode major-mode)
+ (setq mode-name mode-str)))))
+
+;; Set abbrev (default is nil)
+(when lambda-line-abbrev
+ (add-hook 'after-change-major-mode-hook #'lambda-line--abbrev))
+
+;;;;; Mode Name
+(defun lambda-line-user-mode-p ()
+ "Should the user supplied mode be called for modeline?"
+ lambda-line-user-mode)
+
+(defun lambda-line-mode-name ()
+ "Return current major mode name."
+ (format-mode-line mode-name))
+
+;;;;; String Truncate
+(defun lambda-line-truncate (str size &optional ellipsis)
+ "If STR is longer than SIZE, truncate it and add ELLIPSIS."
+
+ (let ((ellipsis (or ellipsis "…")))
+ (if (> (length str) size)
+ (format "%s%s" (substring str 0 (- size (length ellipsis))) ellipsis)
+ str)))
+
+;;;;; Branch display
+;; -------------------------------------------------------------------
+(defun lambda-line-project-name ()
+ "Return name of project without path."
+ (file-name-nondirectory (directory-file-name (if (vc-root-dir) (vc-root-dir) "-"))))
+
+(defun lambda-line-vc-project-branch ()
+ "Show project and branch name for file.
+Otherwise show '-'."
+ (let ((backend (vc-backend buffer-file-name)))
+ (concat
+ (if buffer-file-name
+ (if vc-mode
+ (let ((project-name (lambda-line-project-name)))
+ ;; Project name
+ (unless (string= "-" project-name)
+ (concat
+ ;; Divider
+ (propertize " •" 'face `(:inherit fringe))
+ (format " %s" project-name))))))
+
+ ;; Show branch
+ (if vc-mode
+ (concat
+ lambda-line-vc-symbol (substring-no-properties vc-mode ;   
+ (+ (if (eq backend 'Hg) 2 3) 2))) nil))))
+
+;;;;; Dir display
+;; From https://amitp.blogspot.com/2011/08/emacs-custom-mode-line.html
+(defun lambda-line-shorten-directory (dir max-length)
+ "Show up to `max-length' characters of a directory name `dir'."
+ (let ((path (reverse (split-string (abbreviate-file-name dir) "/")))
+ (output ""))
+ (when (and path (equal "" (car path)))
+ (setq path (cdr path)))
+ (while (and path (< (length output) (- max-length 4)))
+ (setq output (concat (car path) "/" output))
+ (setq path (cdr path)))
+ (when path
+ (setq output (concat "…/" output)))
+ output))
+
+;;;;; Git diff in modeline
+;; https://cocktailmake.github.io/posts/emacs-modeline-enhancement-for-git-diff/
+(when lambda-line-git-diff-mode-line
+ (defadvice vc-git-mode-line-string (after plus-minus (file) compile activate)
+ "Show the information of git diff in status-line"
+ (setq ad-return-value
+ (concat ad-return-value
+ (let ((plus-minus (vc-git--run-command-string
+ file "diff" "--numstat" "--")))
+ (if (and plus-minus
+ (string-match "^\\([0-9]+\\)\t\\([0-9]+\\)\t" plus-minus))
+ (concat
+ " "
+ (format "+%s" (match-string 1 plus-minus))
+ (format "-%s" (match-string 2 plus-minus)))
+ ""))))))
+
+;;;;; Git Parse Repo Status
+;; See https://kitchingroup.cheme.cmu.edu/blog/2014/09/19/A-git-status-Emacs-modeline/
+(defun lambda-line-git-parse-status ()
+ "Display the status of the repo."
+ (interactive)
+ (let ((U 0) ; untracked files
+ (M 0) ; modified files
+ (O 0) ; other files
+ (U-files "")
+ (M-files "")
+ (O-files ""))
+ (dolist (line (split-string
+ (shell-command-to-string "git status --porcelain")
+ "\n"))
+ (cond
+
+ ;; ignore empty line at end
+ ((string= "" line) nil)
+
+ ((string-match "^\\?\\?" line)
+ (setq U (+ 1 U))
+ (setq U-files (concat U-files "\n" line)))
+
+ ((string-match "^ M" line)
+ (setq M (+ 1 M))
+ (setq M-files (concat M-files "\n" line))
+ )))
+
+ ;; construct propertized string
+ (concat
+ (propertize
+ (format "M:%d" M)
+ 'face (if (> M 0)
+ 'error
+ 'success)
+ 'help-echo M-files)
+ (propertize "|" 'face 'magit-dimmed)
+ (propertize
+ (format "?:%d" U)
+ 'face (if (> U 0)
+ 'warning
+ 'success)
+ 'help-echo U-files))))
+
+;;;;; Flycheck/Flymake Segment
+(defvar-local lambda-line--flycheck-text nil)
+(defun lambda-line--update-flycheck-segment (&optional status)
+ "Update `lambda-line--flycheck-text' against the reported flycheck STATUS."
+ (setq lambda-line--flycheck-text
+ (pcase status
+ ('finished (if flycheck-current-errors
+ (let-alist (flycheck-count-errors flycheck-current-errors)
+ (let ((sum (+ (or .error 0) (or .warning 0))))
+ (propertize (concat lambda-line-flycheck-label
+ (number-to-string sum)
+ " ")
+ 'face (if .error
+ 'error
+ 'warning))))
+ (propertize "Good " 'face 'success)))
+ ('running (propertize "Checking " 'face 'info))
+ ('errored (propertize "Error " 'face 'error))
+ ('interrupted (propertize "Paused " 'face 'fringe))
+ ('no-checker ""))))
+
+(defun lambda-line-check-syntax ()
+ "Display syntax-checking information from flymake/flycheck in the mode-line (if available)."
+ (if (and (>= emacs-major-version 28)
+ (boundp 'flymake-mode)
+ flymake-mode)
+ (concat (format-mode-line flymake-mode-line-format) " ")
+ lambda-line--flycheck-text))
+
+;;;;; Display-time-mode
+(defun lambda-line-install-clockface-fonts ()
+ "Install ClockFace fonts on the local system.
+
+Thanks to the Doom Emacs project, for the basis of this
+cross-platform font dowload/install code."
+ (interactive)
+ (let ((on-mac (eq system-type 'darwin))
+ (on-linux (memq system-type '(gnu gnu/linux gnu/kfreebsd berkeley-unix)))
+ (on-windows (memq system-type '(cygwin windows-nt ms-dos)))
+ (name "ClockFace")
+ (url-format "https://ocodo.github.io/ClockFace-font/%s")
+ (fonts-list '("ClockFace-Regular.ttf"
+ "ClockFaceRect-Regular.ttf"
+ "ClockFaceSolid-Regular.ttf"
+ "ClockFaceRectSolid-Regular.ttf")))
+ (unless (yes-or-no-p
+ (format
+ "Download%sthe ClockFace fonts, continue?"
+ (if on-windows
+ " "
+ " and install ")))
+ (user-error "Aborted Download of ClockFace fonts"))
+ (let* ((font-dest
+ (cond (on-linux
+ (expand-file-name
+ "fonts/" (or (getenv "XDG_DATA_HOME")
+ "~/.local/share")))
+ (on-mac
+ (expand-file-name "~/Library/Fonts/"))))
+ (known-dest-p (stringp font-dest))
+ (font-dest (or font-dest (read-directory-name "Font installation directory: " "~/"))))
+ (unless (file-directory-p font-dest)
+ (mkdir font-dest t))
+ (dolist (font fonts-list)
+ (url-copy-file (format url-format font)
+ (expand-file-name font font-dest)
+ t))
+ (when known-dest-p
+ (message "Font downloaded, updating font cache... Using <fc-cache -f -v> ")
+ (shell-command-to-string "fc-cache -f -v"))
+ (if on-windows
+ (when (y-or-n-p "The %S font was downloaded, Windows users must install manually.\n\nOpen windows explorer?")
+ (call-process "explorer.exe" nil nil nil font-dest))
+ (message "Successfully %s %S fonts to %S!"
+ (if known-dest-p
+ "installed"
+ "downloaded")
+ name font-dest)))))
+
+(defun lambda-line-clockface-select-font ()
+ "Select clockface icon font."
+ (interactive)
+ (let ((font (completing-read
+ "Select clockface icon font: "
+ '("ClockFace"
+ "ClockFaceSolid"
+ "ClockFaceRect"
+ "ClockFaceRectSolid"))))
+ (lambda-line-clockface-update-fontset font)))
+
+(defun lambda-line-clockface-update-fontset (&optional font)
+ "Use ClockFace font for unicode #xF0000..F008F.
+Optionally use another clockface font."
+ (set-fontset-font
+ "fontset-default"
+ (cons (decode-char 'ucs #xF0000)
+ (decode-char 'ucs #xF008F))
+ (or font "ClockFace")))
+
+;; Usage example for testing
+;; - exal each one after font installation to test.
+;; (uses the complete font name now)
+;;
+;; [x] (lambda-line-clockface-update-fontset "ClockFace")
+;; [x] (lambda-line-clockface-update-fontset "ClockFaceRect")
+;; [x] (lambda-line-clockface-update-fontset "ClockFaceRectSolid")
+;; [x] (lambda-line-clockface-update-fontset "ClockFaceSolid")
+
+;; Need to add some note about Doom Emacs font-set modification for the user:
+;;
+;; E.g.
+;;
+;; Doom Emacs will reset fontset-default when fonts are resized
+;; (e.g. after `doom/increase-font-size' or `doom/decrease-font-size')
+;;
+;; So it's necessary to use `lambda-line-clockface-update-fontset' after such events have
+;; completed.
+;;
+;; (I haven't found a working solution, i.e. using the Doom hook `after-setting-font-hook' doesn't work.)
+
+(defun lambda-line-clockface-icons-unicode (hours minutes)
+ "Return ClockFace icon unicode for HOURS and MINUTES."
+ (let* ((minute (- minutes (% minutes 5)))
+ (offset (round (+ (* (% hours 12) 12) (* 12 (/ minute 60.0))))))
+ (+ offset #xF0000)))
+
+(defun lambda-line-time ()
+ "Display the time when `display-time-mode' is non-nil."
+ (when display-time-mode
+ (let* ((time-unicode
+ (cl-destructuring-bind (_ minute hour &rest n) (decode-time)
+ (lambda-line-clockface-icons-unicode hour minute))))
+ (concat
+ (unless lambda-line-icon-time
+ (if display-time-day-and-date
+ (propertize (format-time-string lambda-line-time-day-and-date-format))
+ (propertize (format-time-string lambda-line-time-format ) 'face `(:height 0.9))))
+ (propertize
+ (format lambda-line-time-icon-format (char-to-string time-unicode)
+ 'display '(raise 0)))))))
+
+;;;;; Status
+(defun lambda-line-status ()
+ "Return buffer status, one of 'read-only, 'modified or 'read-write."
+
+ (let ((read-only (when (not (or (derived-mode-p 'vterm-mode)
+ (derived-mode-p 'term-mode)
+ (derived-mode-p 'Info-mode)
+ (derived-mode-p 'help-mode)
+ (derived-mode-p 'helpful-mode)
+ (derived-mode-p 'elfeed-search)
+ (derived-mode-p 'elfeed-show)))
+ buffer-read-only))
+ (modified (and buffer-file-name (buffer-modified-p))))
+ (cond (modified 'modified)
+ (read-only 'read-only)
+ (t 'read-write))))
+
+;;;;; Compose Status-Line
+(defun lambda-line-compose (status name primary tertiary secondary)
+ "Compose a string with provided information.
+Each section is first defined, along with a measure of the width of the status-line.
+STATUS, NAME, PRIMARY, and SECONDARY are always displayed. TERTIARY is displayed only in some modes."
+ (let* ((window (get-buffer-window (current-buffer)))
+
+ (name-max-width (max 12
+ (- (window-body-width)
+ (round (* 0.8 (length primary)))
+ (length tertiary)
+ (length secondary))))
+
+ (name (if (and (stringp name) (> (length name) name-max-width))
+ (format "…%s" (substring name (- (length name) name-max-width -1)))
+ name))
+
+ (status (or status (lambda-line-status)))
+
+ (active (eq window lambda-line--selected-window))
+
+ (prefix (cond ((eq lambda-line-prefix nil) "")
+ (t
+ (cond ((derived-mode-p 'term-mode) " >_")
+ ((derived-mode-p 'vterm-mode) " >_")
+ ((derived-mode-p 'eshell-mode) " λ:")
+ ((derived-mode-p 'Info-mode) " ℹ")
+ ((derived-mode-p 'help-mode) " ")
+ ((derived-mode-p 'helpful-mode) " ")
+ ((eq status 'read-only)
+ (if (display-graphic-p) lambda-line-gui-ro-symbol
+ lambda-line-tty-ro-symbol))
+ ((eq status 'read-write) (if (display-graphic-p) lambda-line-gui-rw-symbol
+ lambda-line-tty-rw-symbol))
+ ((eq status 'modified) (if (display-graphic-p) lambda-line-gui-mod-symbol
+ lambda-line-tty-mod-symbol))
+ ((window-dedicated-p) (if (display-graphic-p) " ––" " --"))
+ ;; otherwise just use rw symbol
+ (t (if (display-graphic-p) lambda-line-gui-rw-symbol
+ lambda-line-tty-rw-symbol))))))
+
+ (face-modeline (if active
+ 'lambda-line-active
+ 'lambda-line-inactive))
+ (face-prefix (if (not prefix) face-modeline
+ (if active
+ (cond ((eq status 'read-only) 'lambda-line-active-status-RO)
+ ((eq status 'read-write) 'lambda-line-active-status-RW)
+ ((eq status 'modified) 'lambda-line-active-status-MD)
+ ((or (derived-mode-p 'term-mode)
+ (derived-mode-p 'vterm-mode)
+ (derived-mode-p 'eshell-mode))
+ 'lambda-line-active-status-MD)
+ ((or (derived-mode-p 'Info-mode)
+ (derived-mode-p 'help-mode)
+ (derived-mode-p 'helpful-mode))
+ 'lambda-line-active-status-RO)
+ (t 'lambda-line-active))
+ (cond ((eq status 'read-only) 'lambda-line-inactive-status-RO)
+ ((eq status 'read-write) 'lambda-line-inactive-status-RW)
+ ((eq status 'modified) 'lambda-line-inactive-status-MD)
+ ((or (derived-mode-p 'term-mode)
+ (derived-mode-p 'vterm-mode)
+ (derived-mode-p 'eshell-mode)
+ (derived-mode-p 'Info-mode)
+ (derived-mode-p 'help-mode)
+ (derived-mode-p 'helpful-mode))
+ 'lambda-line-inactive-status-RW)
+ (t 'lambda-line-inactive)))))
+ (face-name (if active
+ 'lambda-line-active-name
+ 'lambda-line-inactive-name))
+ (face-primary (if active
+ 'lambda-line-active-primary
+ 'lambda-line-inactive-primary))
+ (face-secondary (if active
+ 'lambda-line-active-secondary
+ 'lambda-line-inactive-secondary))
+ (face-tertiary (if active
+ 'lambda-line-active-tertiary
+ 'lambda-line-inactive-tertiary))
+ (left
+ ;; special face for special mode prefixes
+ (concat
+ (propertize prefix 'face face-prefix 'display `(raise ,lambda-line-symbol-position))
+ ;; this matters for inverse-video!
+ (propertize " " 'face face-prefix 'display `(raise ,lambda-line-space-top))
+
+ (when lambda-line-prefix-padding
+ (propertize " " 'face face-modeline))
+
+ (propertize name 'face face-name)
+
+ (propertize " " 'face (if active 'lambda-line-active
+ 'lambda-line-inactive)
+ 'display `(raise ,lambda-line-space-bottom))
+
+ (propertize primary 'face face-primary)))
+
+ (right (concat tertiary (propertize secondary 'face face-secondary) (propertize lambda-line-hspace 'face face-modeline)))
+
+ (right-len (length (format-mode-line right))))
+ (concat
+ left
+ (propertize " " 'face face-modeline 'display `(space :align-to (- right ,right-len)))
+ right)))
+
+;;;; Mode Functions
+;;;; Default display
+(defun lambda-line-default-mode ()
+ "Compose the default status line."
+ (let ((buffer-name (format-mode-line (if buffer-file-name
+ (file-name-nondirectory (buffer-file-name))
+ "%b")))
+ (mode-name (lambda-line-mode-name))
+ (branch (lambda-line-vc-project-branch))
+ (position (format-mode-line "%l:%c:%o")))
+ (lambda-line-compose (lambda-line-status)
+ (lambda-line-truncate buffer-name lambda-line-truncate-value)
+ (concat lambda-line-display-group-start
+ mode-name
+ (when branch
+ branch)
+ lambda-line-display-group-end)
+ ""
+ ;; Narrowed buffer
+ (concat (if (buffer-narrowed-p)
+ (concat
+ (propertize "⇥ " 'face `(:inherit lambda-line-inactive-secondary))
+ position " ")
+ position)
+ (lambda-line-time)))))
+
+;;;;; Prog Mode
+;; ---------------------------------------------------------------------
+(defun lambda-line-prog-mode-p ()
+ (derived-mode-p 'prog-mode))
+
+(defun lambda-line-prog-mode ()
+ (let ((buffer-name (format-mode-line (if buffer-file-name (file-name-nondirectory (buffer-file-name)) "%b")))
+ (mode-name (lambda-line-mode-name))
+ (branch (lambda-line-vc-project-branch))
+ (position (format-mode-line "%l:%c:%o")))
+ (lambda-line-compose (lambda-line-status)
+ (lambda-line-truncate buffer-name lambda-line-truncate-value)
+ (concat lambda-line-display-group-start mode-name
+ (when branch branch)
+ lambda-line-display-group-end)
+
+ (if lambda-line-syntax
+ (lambda-line-check-syntax) "")
+
+ (concat
+ ;; Narrowed buffer
+ (when (buffer-narrowed-p)
+ (propertize "⇥ " 'face `(:inherit lambda-line-inactive-secondary)))
+ (if lambda-line-syntax
+ (if (or (boundp 'flycheck-mode)
+ (boundp 'flymake-mode))
+ ;; (concat position lambda-line-hspace)
+ position)
+ position)
+
+ (lambda-line-time)))))
+
+(defun lambda-line-prog-activate ()
+ "Setup flycheck hooks."
+ (add-hook 'flycheck-status-changed-functions #'lambda-line--update-flycheck-segment)
+ (add-hook 'flycheck-mode-hook #'lambda-line--update-flycheck-segment)
+ (when lambda-line-git-diff-mode-line
+ (add-hook 'after-save-hook #'vc-refresh-state)))
+
+(defun lambda-line-prog-deactivate ()
+ "Remove flycheck hooks."
+ (remove-hook 'flycheck-status-changed-functions #'lambda-line--update-flycheck-segment)
+ (remove-hook 'flycheck-mode-hook #'lambda-line--update-flycheck-segment)
+ (when lambda-line-git-diff-mode-line
+ (remove-hook 'after-save-hook #'vc-refresh-state)))
+
+;;;;; Fundamental Mode
+
+(defun lambda-line-fundamental-mode-p ()
+ (derived-mode-p 'fundamental-mode))
+
+(defun lambda-line-fundamental-mode ()
+ (lambda-line-default-mode))
+
+;;;;; Text Mode
+
+(defun lambda-line-text-mode-p ()
+ (derived-mode-p 'text-mode))
+
+(defun lambda-line-text-mode ()
+ (lambda-line-default-mode))
+
+
+;;;;; Help (& Helpful) Mode
+(defun lambda-line-help-mode-p ()
+ (derived-mode-p 'help-mode))
+
+(defun lambda-line-helpful-mode-p ()
+ (derived-mode-p 'helpful-mode))
+
+(defun lambda-line-help-mode ()
+ (lambda-line-compose "HELP"
+ (format-mode-line "%b")
+ ""
+ ""
+ (format-mode-line "%l:%c:%o")))
+
+
+;;;;; Info Display
+;; ---------------------------------------------------------------------
+(defun lambda-line-info-breadcrumbs ()
+ (let ((nodes (Info-toc-nodes Info-current-file))
+ (cnode Info-current-node)
+ (node Info-current-node)
+ (crumbs ())
+ (depth Info-breadcrumbs-depth)
+ line)
+ (save-excursion
+ (while (> depth 0)
+ (setq node (nth 1 (assoc node nodes)))
+ (if node (push node crumbs))
+ (setq depth (1- depth)))
+ (setq crumbs (cons "Top" (if (member (pop crumbs) '(nil "Top"))
+ crumbs (cons nil crumbs))))
+ (forward-line 1)
+ (dolist (node crumbs)
+ (let ((text
+ (if (not (equal node "Top")) node
+ (format "%s"
+ (if (stringp Info-current-file)
+ (file-name-sans-extension
+ (file-name-nondirectory Info-current-file))
+ Info-current-file)))))
+ (setq line (concat line (if (null line) "" " > ")
+ (if (null node) "..." text)))))
+ (if (and cnode (not (equal cnode "Top")))
+ (setq line (concat line (if (null line) "" " > ") cnode)))
+ line)))
+
+(defun lambda-line-info-mode-p ()
+ (derived-mode-p 'Info-mode))
+
+(defun lambda-line-info-mode ()
+ (lambda-line-compose "INFO"
+ ""
+ (concat lambda-line-display-group-start
+ (lambda-line-info-breadcrumbs)
+ lambda-line-display-group-end)
+ ""
+ ""
+ ))
+
+(defun lambda-line-info-activate ()
+ (if (eq lambda-line-position 'top)
+ (setq Info-use-header-line nil)))
+
+(defun lambda-line-info-deactivate ()
+ (custom-reevaluate-setting 'Info-use-header-line))
+
+;;;; Term & Vterm
+;; ---------------------------------------------------------------------
+;; term
+(defun lambda-line-term-mode-p ()
+ (derived-mode-p 'term-mode))
+
+;; vterm
+(defun lambda-line-vterm-mode-p ()
+ (derived-mode-p 'vterm-mode))
+
+(defun lambda-line-term-mode ()
+ (lambda-line-compose " >_ "
+ "Terminal"
+ (concat lambda-line-display-group-start
+ (file-name-nondirectory shell-file-name)
+ lambda-line-display-group-end)
+ nil
+ (concat (lambda-line-shorten-directory default-directory 32)
+ (lambda-line-time))))
+
+
+;; ---------------------------------------------------------------------
+
+(defun lambda-line-get-ssh-host (_str)
+ (let ((split-defdir (split-string default-directory)))
+ (if (equal (length split-defdir) 1)
+ (car (split-string (shell-command-to-string "hostname") "\n"))
+ (cadr split-defdir))))
+
+(defun lambda-line-ssh-mode ()
+ (lambda-line-compose " >_ "
+ "Terminal"
+ (concat lambda-line-display-group-start
+ (lambda-line-get-ssh-host default-directory)
+ lambda-line-display-group-end)
+ nil
+ (concat (lambda-line-shorten-directory (car (last (split-string default-directory ":"))) 32)
+ (lambda-line-time))))
+
+;;;; Eshell
+;; ---------------------------------------------------------------------
+(defun lambda-line-eshell-mode-p ()
+ (derived-mode-p 'eshell-mode))
+
+(defun lambda-line-eshell-mode ()
+ (lambda-line-compose " >_ "
+ "Eshell"
+ (concat lambda-line-display-group-start
+ (buffer-name)
+ lambda-line-display-group-end)
+ ""
+ (concat (lambda-line-shorten-directory default-directory 32)
+ (lambda-line-time))))
+
+(defun lambda-line-esh-activate ()
+ (with-eval-after-load 'esh-mode
+ (setq eshell-status-in-mode-line nil)))
+
+(defun lambda-line-esh-deactivate ()
+ (custom-reevaluate-setting 'eshell-status-in-mode-line))
+
+;;;; Messages Buffer Mode
+;; ---------------------------------------------------------------------
+(defun lambda-line-messages-mode-p ()
+ (derived-mode-p 'messages-buffer-mode))
+
+(defun lambda-line-messages-mode ()
+ (lambda-line-compose (lambda-line-status)
+ "*Messages*"
+ ""
+ ""
+ (concat "" (lambda-line-time))))
+
+;;;; Message Mode
+;; ---------------------------------------------------------------------
+(defun lambda-line-message-mode-p ()
+ (derived-mode-p 'message-mode))
+
+(defun lambda-line-message-mode ()
+ (lambda-line-compose (lambda-line-status)
+ "Message" "(Draft)" nil (lambda-line-time)))
+
+;;;; Docview Mode
+;;---------------------------------------------------------------------
+(defun lambda-line-doc-view-mode-p ()
+ (derived-mode-p 'doc-view-mode))
+
+(defun lambda-line-doc-view-mode ()
+ (let ((buffer-name (format-mode-line "%b"))
+ (mode-name (lambda-line-mode-name))
+ (branch (lambda-line-vc-project-branch))
+ (page-number (concat
+ (number-to-string (doc-view-current-page)) "/"
+ (or (ignore-errors
+ (number-to-string (doc-view-last-page-number)))
+ "???"))))
+ (lambda-line-compose
+ (lambda-line-status)
+ buffer-name
+ (concat lambda-line-display-group-start mode-name
+ branch
+ lambda-line-display-group-end)
+ nil
+ (concat page-number
+ (lambda-line-time)))))
+
+;;;; PDF View Mode
+;; ---------------------------------------------------------------------
+(defun lambda-line-pdf-view-mode-p ()
+ (derived-mode-p 'pdf-view-mode))
+
+(with-eval-after-load 'pdf-tools
+ (require 'pdf-view))
+
+(defun lambda-line-pdf-view-mode ()
+ (let ((buffer-name (format-mode-line "%b"))
+ (mode-name (lambda-line-mode-name))
+ (branch (lambda-line-vc-project-branch))
+ (page-number (concat
+ (number-to-string (eval `(pdf-view-current-page))) "/"
+ (or (ignore-errors
+ (number-to-string (pdf-cache-number-of-pages)))
+ "???"))))
+ (lambda-line-compose (lambda-line-status)
+ buffer-name
+ (concat lambda-line-display-group-start mode-name
+ lambda-line-display-group-end)
+ ""
+ (concat page-number " " (lambda-line-time)))))
+
+;;;; MenuMode
+
+(defun lambda-line-buffer-menu-mode-p ()
+ (derived-mode-p 'buffer-menu-mode))
+
+(defun lambda-line-buffer-menu-mode ()
+ (let ((buffer-name "Buffer list")
+ (mode-name (lambda-line-mode-name))
+ (position (format-mode-line "%l:%c:%o")))
+
+ (lambda-line-compose (lambda-line-status)
+ buffer-name "" nil (concat position lambda-line-hspace (lambda-line-time)))))
+
+;;;; Imenu-List
+(defun lambda-line-imenu-list-mode-p ()
+ (derived-mode-p 'imenu-list-major-mode))
+
+(defun lambda-line-imenu-list-mode ()
+ (let (
+ ;; We take into account the case of narrowed buffers
+ (buffer-name (buffer-name imenu-list--displayed-buffer))
+ (branch (lambda-line-vc-project-branch))
+ (position (format-mode-line "%l:%c")))
+ (lambda-line-compose (lambda-line-status)
+ buffer-name
+ "(imenu list)"
+ ""
+ "")))
+;;;; Completion
+;; ---------------------------------------------------------------------
+(defun lambda-line-completion-list-mode-p ()
+ (derived-mode-p 'completion-list-mode))
+
+(defun lambda-line-completion-list-mode ()
+ (let ((buffer-name (format-mode-line "%b"))
+ (mode-name (lambda-line-mode-name))
+ (position (format-mode-line "%l:%c:%o")))
+
+ (lambda-line-compose (lambda-line-status)
+ buffer-name "" nil (concat position lambda-line-hspace))))
+
+;;;; Deft Mode
+
+(with-eval-after-load 'deft
+ (defun lambda-line--deft-print-header ()
+ (force-mode-line-update)
+ (widget-insert "\n")))
+
+(defun lambda-line-deft-mode-p ()
+ (derived-mode-p 'deft-mode))
+
+(defun lambda-line-deft-mode ()
+ (let ((prefix " DEFT ")
+ (primary "Search:")
+ (filter (if deft-filter-regexp
+ (deft-whole-filter-regexp) "<filter>"))
+ (matches (if deft-filter-regexp
+ (format "%d matches" (length deft-current-files))
+ (format "%d notes" (length deft-all-files)))))
+ (lambda-line-compose prefix primary filter nil matches)))
+
+;;;; Calendar Mode
+;; ---------------------------------------------------------------------
+(defun lambda-line-calendar-mode-p ()
+ (derived-mode-p 'calendar-mode))
+
+(defun lambda-line-calendar-mode () "")
+
+;; Calendar (no header, only overline)
+(with-eval-after-load 'calendar
+ (defun lambda-line-calendar-setup-header ()
+ (setq header-line-format "")
+ (face-remap-add-relative
+ 'header-line `(:overline ,(face-foreground 'default)
+ :height 0.5
+ :background ,(face-background 'default)))))
+
+(defun lambda-line-calendar-activate ()
+ (with-eval-after-load 'calendar
+ (add-hook 'calendar-initial-window-hook
+ #'lambda-line-calendar-setup-header)))
+
+(defun lambda-line-calendar-deactivate ()
+ (remove-hook 'calendar-initial-window-hook
+ #'lambda-line-calendar-setup-header))
+
+;;;; Org Capture
+;; ---------------------------------------------------------------------
+(defun lambda-line-org-capture-mode-p ()
+ (bound-and-true-p org-capture-mode))
+
+(defun lambda-line-org-capture-mode ()
+ (lambda-line-compose (lambda-line-status)
+ "Capture"
+ (concat lambda-line-display-group-start
+ (org-capture-get :description)
+ lambda-line-display-group-end)
+ nil
+ "Finish: C-c C-c, refile: C-c C-w, cancel: C-c C-k "))
+
+
+(defun lambda-line-org-capture-turn-off-header-line ()
+ (setq-local header-line-format (default-value 'header-line-format))
+ (message nil))
+
+(defun lambda-line-org-capture-activate ()
+ (with-eval-after-load 'org-capture
+ (add-hook 'org-capture-mode-hook
+ #'lambda-line-org-capture-turn-off-header-line)))
+
+(defun lambda-line-org-capture-deactivate ()
+ (remove-hook 'org-capture-mode-hook
+ #'lambda-line-org-capture-turn-off-header-line))
+
+
+;;;; Org Agenda
+;; ---------------------------------------------------------------------
+(defun lambda-line-org-agenda-mode-p ()
+ (derived-mode-p 'org-agenda-mode))
+
+(defun lambda-line-org-agenda-mode ()
+ (let ((lambda-line-icon-time t))
+ (lambda-line-compose (lambda-line-status)
+ "Agenda"
+ (concat lambda-line-display-group-start (format "%S" org-agenda-current-span) lambda-line-display-group-end)
+ ""
+ (concat (format-time-string "%A, %d %B %Y")
+ (lambda-line-time)
+ (format-time-string " %H:%M")))))
+
+;;;; Org Clock
+;; ---------------------------------------------------------------------
+(defun lambda-line-org-clock-mode-p ()
+ (and (boundp 'org-mode-line-string)
+ (stringp org-mode-line-string)))
+
+(defun lambda-line-org-clock-mode ()
+ (let ((buffer-name (format-mode-line "%b"))
+ (mode-name (lambda-line-mode-name))
+ (branch (lambda-line-vc-project-branch))
+ (position (format-mode-line "%l:%c:%o")))
+ (lambda-line-compose (lambda-line-status)
+ buffer-name
+ (concat lambda-line-display-group-start
+ mode-name
+ (when branch
+ branch)
+ lambda-line-display-group-end)
+ ""
+ (concat
+ ;; Narrowed buffer
+ (when (buffer-narrowed-p)
+ (propertize "⇥ " 'face `(:inherit lambda-line-inactive-secondary)))
+ org-mode-line-string
+ " "
+ nil
+ position
+ lambda-line-hspace))))
+
+(defun lambda-line-org-clock-out ()
+ (setq org-mode-line-string nil)
+ (force-mode-line-update))
+
+(defun lambda-line-org-clock-activate ()
+ (with-eval-after-load 'org-clock
+ (add-hook 'org-clock-out-hook #'lambda-line-org-clock-out)))
+
+(defun lambda-line-org-clock-deactivate ()
+ (remove-hook 'org-clock-out-hook
+ #'lambda-line-org-clock-out))
+
+;;;; Elfeed
+;; ---------------------------------------------------------------------
+(defun lambda-line-elfeed-search-mode-p ()
+ (derived-mode-p 'elfeed-search-mode))
+
+(defun lambda-line-elfeed-search-mode ()
+ (let* ((status "NEWS")
+ (no-database (zerop (elfeed-db-last-update)))
+ (update (> (elfeed-queue-count-total) 0))
+
+ (name (cond (no-database "No database")
+ (update "Update:")
+ (t "Search:")))
+ (primary (cond (no-database "")
+ (update
+ (let ((total (elfeed-queue-count-total))
+ (in-process (elfeed-queue-count-active)))
+ (format "%d jobs pending, %d active"
+ (- total in-process) in-process)))
+ (t (let* ((db-time (seconds-to-time (elfeed-db-last-update)))
+ (unread))
+ (cond (elfeed-search-filter-active "")
+ ((string-match-p "[^ ]" elfeed-search-filter)
+ elfeed-search-filter)
+ (""))))))
+ (secondary (concat
+ (cond
+ ((zerop (elfeed-db-last-update)) "")
+ ((> (elfeed-queue-count-total) 0) "")
+ (t (elfeed-search--count-unread)))
+ (lambda-line-time))))
+
+ (lambda-line-compose status name primary nil secondary)))
+
+;; Elfeed uses header-line, we need to tell it to use our own format
+(defun lambda-line-elfeed-setup-header ()
+ (setq header-line-format (default-value 'header-line-format)))
+
+(defun lambda-line-elfeed-search-activate ()
+ (with-eval-after-load 'elfeed
+ (if (eq lambda-line-position 'top)
+ (setq elfeed-search-header-function #'lambda-line-elfeed-setup-header))))
+
+(defun lambda-line-elfeed-search-deactivate ()
+ (if (boundp 'elfeed-search-header-function)
+ (setq elfeed-search-header-function #'elfeed-search--header)))
+
+;; ---------------------------------------------------------------------
+(defun lambda-line-elfeed-show-mode-p ()
+ (derived-mode-p 'elfeed-show-mode))
+
+(defun lambda-line-elfeed-show-mode ()
+ (let* ((title (elfeed-entry-title elfeed-show-entry))
+ (tags (elfeed-entry-tags elfeed-show-entry))
+ (tags-str (mapconcat #'symbol-name tags ", "))
+ (tag (if tags
+ (concat lambda-line-display-group-start
+ tags-str
+ lambda-line-display-group-end)
+ " "))
+ (date (seconds-to-time (elfeed-entry-date elfeed-show-entry)))
+ (feed (elfeed-entry-feed elfeed-show-entry))
+ (entry-author (elfeed-meta elfeed-show-entry :author))
+ (feed-title (if entry-author
+ (concat entry-author " (" (elfeed-feed-title feed) ")")
+ (elfeed-feed-title feed))))
+ (lambda-line-compose
+ ""
+ (lambda-line-truncate title 65)
+ tag
+ ""
+ (format-time-string "%Y-%m-%d %H:%M:%S" date))))
+
+
+;;;; Mu4e
+
+(defun lambda-line-mu4e-last-query ()
+ "Get the most recent mu4e query or nil if there is none."
+ (if (fboundp 'mu4e-last-query)
+ (mu4e-last-query)
+ mu4e~headers-last-query))
+
+(defun lambda-line-mu4e-context ()
+ "Return the current mu4e context as a non propertized string."
+ (if (> (length (mu4e-context-label)) 0)
+ (concat
+ lambda-line-display-group-start
+ (substring-no-properties (mu4e-context-label) 1 -1)
+ lambda-line-display-group-end)
+ "(none)"))
+
+(defun lambda-line-mu4e-server-props ()
+ "Encapsulates the call to the variable mu4e-/~server-props
+depending on the version of mu4e."
+ (if (version< mu4e-mu-version "1.6.0")
+ mu4e~server-props
+ mu4e--server-props))
+
+(defun lambda-line-mu4e-activate ()
+ (with-eval-after-load 'mu4e
+ (advice-add 'mu4e~header-line-format :override #'lambda-line)))
+
+(defun lambda-line-mu4e-deactivate ()
+ (advice-remove #'mu4e~header-line-format #'lambda-line))
+
+;; ---------------------------------------------------------------------
+(defun lambda-line-mu4e-dashboard-mode-p ()
+ (bound-and-true-p mu4e-dashboard-mode))
+
+(defun lambda-line-mu4e-dashboard-mode ()
+ (lambda-line-compose (lambda-line-status)
+ (format "%d messages"
+ (plist-get (lambda-line-mu4e-server-props) :doccount))
+ ""
+ ""
+ (lambda-line-time)))
+
+;; ---------------------------------------------------------------------
+(defun lambda-line-mu4e-loading-mode-p ()
+ (derived-mode-p 'mu4e-loading-mode))
+
+(defun lambda-line-mu4e-loading-mode ()
+ (lambda-line-compose (lambda-line-status)
+ (format-time-string "%A %d %B %Y, %H:%M ")
+ ""
+ "Loading..."
+ (lambda-line-mu4e-context)))
+
+;; ---------------------------------------------------------------------
+(defun lambda-line-mu4e-main-mode-p ()
+ (derived-mode-p 'mu4e-main-mode))
+
+(defun lambda-line-mu4e-main-mode ()
+ (lambda-line-compose (lambda-line-status)
+ (format-time-string "%A %d %B %Y, %H:%M ")
+ ""
+ ""
+ (lambda-line-mu4e-context)))
+
+;; ---------------------------------------------------------------------
+(defun lambda-line-mu4e-compose-mode-p ()
+ (derived-mode-p 'mu4e-compose-mode))
+
+(defun lambda-line-mu4e-compose-mode ()
+ (lambda-line-compose (lambda-line-status)
+ (format-mode-line "%b")
+ ""
+ ""
+ (format "[%s] "
+ (lambda-line-mu4e-quote
+ (mu4e-context-name (mu4e-context-current))))))
+
+;; ---------------------------------------------------------------------
+(defun lambda-line-mu4e-quote (str)
+ (if (version< mu4e-mu-version "1.8.0")
+ (mu4e~quote-for-modeline str)
+ (mu4e-quote-for-modeline str)))
+
+(defun lambda-line-mu4e-headers-mode-p ()
+ (derived-mode-p 'mu4e-headers-mode))
+
+(defun lambda-line-mu4e-headers-mode ()
+ (let ((mu4e-modeline-max-width 80))
+ (lambda-line-compose
+ (lambda-line-status)
+ "Search:"
+ (or (lambda-line-mu4e-quote
+ (lambda-line-mu4e-last-query)) "")
+ ""
+ (concat
+ (format "[%s] "
+ (lambda-line-mu4e-quote
+ (mu4e-context-name (mu4e-context-current))))
+ (or (lambda-line-time) "")))))
+
+;; ---------------------------------------------------------------------
+(defun lambda-line-mu4e-view-mode-p ()
+ (derived-mode-p 'mu4e-view-mode))
+
+(defun lambda-line-mu4e-view-mode ()
+ (let* ((msg (mu4e-message-at-point))
+ (subject (mu4e-message-field msg :subject))
+ (from (mu4e~headers-contact-str (mu4e-message-field msg :from)))
+ (date (mu4e-message-field msg :date)))
+ (lambda-line-compose (lambda-line-status)
+ (or from "")
+ (concat lambda-line-display-group-start
+ (lambda-line-truncate (or subject "") 50 "…")
+ lambda-line-display-group-end)
+ ""
+ (concat (or (format-time-string mu4e-headers-date-format date) "") " "))))
+
+(defun lambda-line-mu4e-activate ()
+ (with-eval-after-load 'mu4e
+ (advice-add 'mu4e~header-line-format :override #'lambda-line)))
+
+(defun lambda-line-mu4e-deactivate ()
+ (advice-remove #'mu4e~header-line-format #'lambda-line))
+
+;;;; Ein
+
+(defun lambda-line-ein-notebook-mode ()
+ (let ((buffer-name (format-mode-line "%b")))
+ (lambda-line-compose (if (ein:notebook-modified-p) "MD" "RW")
+ buffer-name
+ ""
+ ""
+ (concat
+ (ein:header-line)
+ (lambda-line-time)))))
+
+;; since the EIN library itself is constantly re-rendering the notebook, and thus
+;; re-setting the header-line-format, we cannot use the lambda-line function to set
+;; the header format in a notebook buffer. Fortunately, EIN exposes the
+;; ein:header-line-format variable for just this purpose.
+
+(defun lambda-line-ein-notebook-activate ()
+ (with-eval-after-load 'ein
+ (if (eq lambda-line-position 'top)
+ (setq ein:header-line-format '((:eval (lambda-line-ein-notebook-mode)))))))
+
+(defun lambda-line-ein-notebook-deactivate ()
+ (if (boundp 'ein:header-line-format)
+ (setq ein:header-line-format '(:eval (ein:header-line)))))
+
+
+;;;; Buffer Menu Mode
+;; ---------------------------------------------------------------------
+(defun lambda-line-buffer-menu-mode-p ()
+ (derived-mode-p 'buffer-menu-mode))
+
+(defun lambda-line-buffer-menu-mode ()
+ (let ((buffer-name "Buffer list")
+ (mode-name (lambda-line-mode-name))
+ (position (format-mode-line "%l:%c")))
+
+ (lambda-line-compose nil
+ buffer-name
+ ""
+ nil
+ (concat
+ position
+ (lambda-line-time)))))
+
+;;(defun buffer-menu-mode-header-line ()
+;; (face-remap-add-relative
+;; 'header-line `(:background ,(face-background 'nano-subtle))))
+;;(add-hook 'Buffer-menu-mode-hook
+;; #'buffer-menu-mode-header-line)
+
+(defun lambda-line-buffer-menu-activate ()
+ (if (eq lambda-line-position 'top)
+ (setq Buffer-menu-use-header-line nil)))
+
+(defun lambda-line-buffer-menu-deactivate ()
+ (custom-reevaluate-setting 'Buffer-menu-use-header-line))
+
+;;;; Elpher Mode
+;; ---------------------------------------------------------------------
+(defun lambda-line-elpher-mode-p ()
+ (derived-mode-p 'elpher-mode))
+
+(defun lambda-line-elpher-mode ()
+ (let* ((display-string (elpher-page-display-string elpher-current-page))
+ (sanitized-display-string (replace-regexp-in-string "%" "%%" display-string))
+ (address (elpher-page-address elpher-current-page))
+ (tls-string (if (and (not (elpher-address-about-p address))
+ (member (elpher-address-protocol address)
+ '("gophers" "gemini")))
+ "(TLS encryption)"
+ "")))
+ (lambda-line-compose nil
+ sanitized-display-string
+ tls-string
+ nil
+ (lambda-line-time))))
+
+(defun lambda-line-elpher-activate ()
+ (with-eval-after-load 'elpher
+ (setq elpher-use-header nil)))
+
+;;;; Ispell Mode
+;; ---------------------------------------------------------------------
+(defun lambda-line-enlarge-ispell-choices-buffer (buffer)
+ (when (string= (buffer-name buffer) "*Choices*")
+ (with-current-buffer buffer
+ ;; (enlarge-window +2)
+ (setq-local header-line-format nil)
+ (setq-local mode-line-format nil))))
+
+(defun lambda-line-ispell-activate ()
+ (with-eval-after-load 'ispell
+ (advice-add #'ispell-display-buffer :after
+ #'lambda-line-enlarge-ispell-choices-buffer)))
+
+(defun lambda-line-ispell-deactivate ()
+ (advice-remove #'ispell-display-buffer
+ #'lambda-line-enlarge-ispell-choices-buffer))
+
+;;;; Eldoc
+;; ---------------------------------------------------------------------
+;; `eldoc-minibuffer-message' changes `mode-line-format' but status-line when
+;; `lambda-line-position' is `top' fails to display info. Solution is to move
+;; eldoc messages to the minibuffer/echo area.
+(when (eq lambda-line-position 'top)
+ (setq eldoc-message-function #'message))
+
+;;;; Magit
+;; ---------------------------------------------------------------------
+(defun lambda-line-magit-mode-p ()
+ (derived-mode-p 'magit-mode))
+
+;; Add functions to parse repo every N seconds
+(defvar lambda-line-git-parse-last-update (float-time) "Last time we updated")
+(defvar lambda-line-git-parse-update-interval 15 "Minimum time between update in seconds")
+(defvar lambda-line-git-parse "" "Last value of the parse")
+
+(defun lambda-line-magit-mode ()
+ (let* ((buffer-name (format-mode-line
+ (if buffer-file-name
+ (file-name-nondirectory (buffer-file-name))
+ "%b")))
+ (mode-name (lambda-line-mode-name))
+ (project (file-name-nondirectory (directory-file-name (magit-toplevel))))
+ (branch (magit-get-current-branch))
+ (status (lambda-line-git-parse-status)))
+ (lambda-line-compose (lambda-line-status)
+ mode-name
+ (concat lambda-line-display-group-start
+ project
+ lambda-line-vc-symbol
+ branch
+ lambda-line-display-group-end)
+ status
+ "")))
+
+
+;;;; Setup Lambda-line
+;; ---------------------------------------------------------------------
+(defun lambda-line-face-clear (face)
+ "Clear FACE"
+ (set-face-attribute face nil
+ :foreground 'unspecified :background 'unspecified
+ :family 'unspecified :slant 'unspecified
+ :weight 'unspecified :height 'unspecified
+ :underline 'unspecified :overline 'unspecified
+ :box 'unspecified :inherit 'unspecified))
+
+;; ---------------------------------------------------------------------
+(defvar lambda-line--saved-mode-line-format nil)
+(defvar lambda-line--saved-header-line-format nil)
+(defvar lambda-line--selected-window nil)
+
+(defun lambda-line--update-selected-window ()
+ "Update selected window (before mode-line is active)"
+ (setq lambda-line--selected-window (selected-window)))
+
+(defun lambda-line ()
+ "Build and set the modeline."
+ (let* ((format
+ '((:eval
+ (funcall
+ (or (catch 'found
+ (dolist (elt lambda-line-mode-formats)
+ (let* ((config (cdr elt))
+ (mode-p (plist-get config :mode-p))
+ (format (plist-get config :format)))
+ (when mode-p
+ (when (funcall mode-p)
+ (throw 'found format))))))
+ lambda-line-default-mode-format))))))
+ (if (eq lambda-line-position 'top)
+ (progn
+ (setq header-line-format format)
+ (setq-default header-line-format format))
+ (progn
+ (setq mode-line-format format)
+ (setq-default mode-line-format format)))))
+
+(defun lambda-line-update-windows ()
+ "Hide the mode line depending on the presence of a window
+below or a buffer local variable 'no-mode-line'."
+ (dolist (window (window-list))
+ (with-selected-window window
+ (with-current-buffer (window-buffer window)
+ (if (or (not (boundp 'no-mode-line)) (not no-mode-line))
+ (setq mode-line-format
+ (cond ((one-window-p t) (list ""))
+ ((eq (window-in-direction 'below) (minibuffer-window)) (list ""))
+ ((not (window-in-direction 'below)) (list ""))
+ (t nil))))))))
+
+(defun lambda-line-mode--activate ()
+ "Activate lambda-line."
+
+ ;; Save current mode-line and header-line
+ (unless lambda-line--saved-mode-line-format
+ (setq lambda-line--saved-mode-line-format mode-line-format)
+ (setq lambda-line--saved-header-line-format header-line-format))
+
+ (dolist (elt lambda-line-mode-formats)
+ (let* ((config (cdr elt))
+ (fn (plist-get config :on-activate)))
+ (when fn (funcall fn))))
+
+ (run-hooks 'lambda-line-mode-format-activate-hook)
+
+ ;; Update selected window
+ (lambda-line--update-selected-window)
+ ;; (setq lambda-line--selected-window (selected-window))
+
+ (setq mode-line-format nil)
+ (setq-default mode-line-format nil)
+ (setq header-line-format nil)
+ (setq-default header-line-format nil)
+
+ (lambda-line)
+
+ ;; Use lambda-line-visual-bell when var is set to t
+ (when lambda-line-visual-bell
+ (lambda-line-visual-bell-config))
+
+ ;; This hooks is necessary to register selected window because when
+ ;; a modeline is evaluated, the corresponding window is always selected.
+ (add-hook 'post-command-hook #'lambda-line--update-selected-window)
+
+ ;; This hooks hide the modeline for windows having a window below them
+ ;; Disabled for the time being,
+ ;; -> see https://github.com/rougier/nano-modeline/issues/24
+ ;; (add-hook 'window-configuration-change-hook #'lambda-line-update-windows)
+
+ (force-mode-line-update t))
+
+;; Deactivate status-line
+(defun lambda-line-mode--deactivate ()
+ "Deactivate lambda-line and restore default mode-line."
+
+ (dolist (elt lambda-line-mode-formats)
+ (let* ((config (cdr elt))
+ (fn (plist-get config :on-deactivate)))
+ (when fn (funcall fn))))
+
+ (run-hooks 'lambda-line-mode-format-deactivate-hook)
+
+ (remove-hook 'post-command-hook
+ #'lambda-line--update-selected-window)
+ (remove-hook 'window-configuration-change-hook
+ #'lambda-line-update-windows)
+
+ ;; Deactivate lambda-line-visual-bell
+ (setq lambda-line-visual-bell nil)
+
+ (setq mode-line-format lambda-line--saved-mode-line-format)
+ (setq-default mode-line-format lambda-line--saved-mode-line-format)
+ (setq header-line-format lambda-line--saved-header-line-format)
+ (setq-default header-line-format lambda-line--saved-header-line-format))
+
+;;;; Lambda-line minor mode
+
+;; Store the default mode-line format
+(defvar lambda-line--default-mode-line mode-line-format)
+
+;;;###autoload
+(define-minor-mode lambda-line-mode
+ "Toggle lambda-line on or off."
+ :group 'lambda-line
+ :global t
+ :lighter nil
+
+ (if lambda-line-mode
+ (lambda-line-mode--activate)
+ (lambda-line-mode--deactivate))
+
+ ;; Run any registered hooks
+ (run-hooks 'lambda-line-mode-hook))
+
+;;; Provide:
+(provide 'lambda-line)
+
+;;; lambda-line.el ends here
diff --git a/emacs/libs/minad.el b/emacs/libs/minad.el
new file mode 100644
index 0000000..3b9ca4e
--- /dev/null
+++ b/emacs/libs/minad.el
@@ -0,0 +1,89 @@
+;;; package --- Summary
+
+;;; Commentary:
+
+;; This loads vertico, corfu, orderless, etc.
+;; All from https://github.com/minad
+
+
+;;; Code:
+
+(require 'package)
+
+(use-package corfu
+ :ensure t
+ :custom
+ (corfu-cycle t)
+ :hook ((prog-mode . corfu-mode)
+ (shell-mode . corfu-mode)
+ (eshell-mode . corfu-mode))
+ :init (global-corfu-mode))
+
+(use-package orderless
+ :ensure t
+ :init
+ ;; Configure a custom style dispatcher (see the Consult wiki)
+ (setq orderless-style-dispatchers nil
+ orderless-component-separator #'orderless-escapable-split-on-space)
+ (setq completion-styles '(orderless basic)
+ completion-category-defaults nil
+ completion-category-overrides '((file (styles basic partial-completion)))))
+
+(setq completion-styles '(orderless basic))
+
+
+;; Use dabbrev with Corfu!
+(use-package dabbrev
+ ;; Swap M-/ and C-M-/
+ :bind (("M-/" . dabbrev-expand)
+ ("C-M-/" . dabbrev-completion)))
+
+;; Enable richer annotations using the Marginalia package
+(use-package marginalia
+ :ensure t
+ ;; Either bind `marginalia-cycle` globally or only in the minibuffer
+ ;; :bind (("M-A" . marginalia-cycle)
+ ;; :map minibuffer-local-map
+ ;; ("M-A" . marginalia-cycle))
+
+ ;; The :init configuration is always executed (Not lazy!)
+ :init
+
+ ;; Must be in the :init section of use-package such that the mode gets
+ ;; enabled right away. Note that this forces loading the package.
+ (marginalia-mode))
+
+(use-package vertico
+ :ensure t
+ ;; Special recipe to load extensions conveniently
+ :straight (vertico :files (:defaults "extensions/*")
+ :includes (vertico-indexed
+ vertico-flat
+ vertico-grid
+ vertico-mouse
+ vertico-quick
+ vertico-buffer
+ vertico-repeat
+ vertico-reverse
+ vertico-directory
+ vertico-multiform
+ vertico-unobtrusive
+ ))
+ ;; :general
+ ;; (:keymaps 'vertico-map
+ ;; "<tab>" #'vertico-insert ; Choose selected candidate
+ ;; "<escape>" #'minibuffer-keyboard-quit ; Close minibuffer
+ ;; ;; NOTE 2022-02-05: Cycle through candidate groups
+ ;; "C-M-n" #'vertico-next-group
+ ;; "C-M-p" #'vertico-previous-group)
+ :custom
+ (vertico-count 12) ; Number of candidates to display
+ (vertico-resize t)
+ (vertico-cycle nil) ; Go from last to first candidate and first to last (cycle)?
+ :config
+ (vertico-mode)
+ (vertico-reverse-mode))
+
+(provide 'minad)
+
+;;; minad.el ends here
diff --git a/emacs/libs/nano-emacs b/emacs/libs/nano-emacs
new file mode 160000
+Subproject 185894da71aeab33e52a1bedcde6cea4b148436
diff --git a/emacs/libs/penumbra-theme.el b/emacs/libs/penumbra-theme.el
new file mode 100644
index 0000000..e8e6acf
--- /dev/null
+++ b/emacs/libs/penumbra-theme.el
@@ -0,0 +1,512 @@
+;;; penumbra-theme.el --- A color theme based on Acme & Sam from Plan 9 -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020 Ian Yi-En Pan
+
+;; Author: Ian Y.E. Pan
+;; URL: https://github.com/ianpan870102/acme-emacs-theme
+;; Version: 1.0.0
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; A color theme for Emacs based on Acme & Sam from Plan 9
+
+;;; Credits:
+;; This theme was modified from John Louis Del Rosario's plan9-theme.el
+
+;;; Code:
+
+(defgroup penumbra-theme nil
+ "Options for penumbra theme."
+ :group 'faces)
+
+(defcustom penumbra-theme-black-fg nil
+ "If non-nil, foreground will be pure black instead of the default dark grey."
+ :group 'penumbra-theme
+ :type 'boolean)
+
+(deftheme penumbra "A color theme based on Penumbra & Sam")
+
+;;; Color palette
+
+(let ((class '((class color) (min-colors 89)))
+ (bg "#FFF7ED") ; default bg
+ (bg-alt "#FFFDFB")
+ (bg-dark "#F2E6D4")
+ (fg (if penumbra-theme-black-fg "#000000" "#24272B")) ; default fg
+ (fg-alt "#B8B09A")
+ (fg-dark "#988D6D")
+ (fg-light "#CCCCB7")
+ (highlight "#E8EB98")
+ (highlight-alt "#E8EBC8")
+
+ ;; Standardized palette
+ (penumbra-cyan "#00B3C2")
+ (penumbra-cyan-light "#00C4D7")
+ (penumbra-red "#DF7F78")
+ (penumbra-red-light "#F58C81")
+ (penumbra-yellow "#9CA748")
+ (penumbra-yellow-light "#A9B852")
+ (penumbra-green "#50B584")
+ (penumbra-green-alt "#54C794")
+ (penumbra-green-light "#54C794")
+ (penumbra-blue "#61A3E6")
+ (penumbra-blue-light "#6EB2FD")
+ (penumbra-purple "#A48FE1")
+ (penumbra-purple-light "#B69CF6"))
+
+;;; Theme Faces
+ (custom-theme-set-faces
+ 'penumbra
+
+;;;; Built-in
+
+;;;;; basic coloring
+ `(button ((t (:underline t))))
+ `(link ((t (:foreground "#0066cc":weight normal))))
+ `(highlight ((t (:inherit link :underline t)))) ; link hover
+ `(link-visited ((t (:foreground ,penumbra-purple :underline t :weight normal))))
+ `(default ((t (:foreground ,fg :background ,bg))))
+ `(cursor ((t (:foreground ,bg :background ,fg))))
+ `(escape-glyph ((t (:foreground ,penumbra-cyan-light :bold nil))))
+ `(fringe ((t (:foreground ,fg :background ,bg))))
+ `(line-number ((t (:foreground ,fg :background ,bg-alt))))
+ `(line-number-current-line ((t (:foreground ,fg :background ,bg-alt))))
+ `(header-line ((t (:foreground ,fg :background ,penumbra-blue-light :box t))))
+ `(success ((t (:foreground ,penumbra-green :weight normal))))
+ `(warning ((t (:foreground ,penumbra-red :weight normal))))
+ `(error ((t (:foreground ,penumbra-red :bold t))))
+
+;;;;; compilation
+ `(compilation-column-face ((t (:foreground ,penumbra-yellow :background ,penumbra-yellow-light))))
+ `(compilation-column-number ((t (:foreground ,penumbra-yellow :background ,penumbra-yellow-light))))
+ `(compilation-error-face ((t (:foreground ,penumbra-red :weight normal :underline t))))
+ `(compilation-face ((t (:foreground ,fg))))
+ `(compilation-info-face ((t (:foreground ,penumbra-blue))))
+ `(compilation-info ((t (:foreground ,penumbra-blue :underline t))))
+ `(compilation-line-face ((t (:foreground ,penumbra-purple))))
+ `(compilation-line-number ((t (:foreground ,penumbra-yellow :background ,penumbra-yellow-light))))
+ `(compilation-message-face ((t (:foreground ,penumbra-blue))))
+ `(compilation-warning-face ((t (:foreground ,penumbra-yellow :weight normal :underline t))))
+ `(compilation-mode-line-exit ((t (:foreground ,penumbra-cyan :weight normal))))
+ `(compilation-mode-line-fail ((t (:foreground ,penumbra-red :weight normal))))
+ `(compilation-mode-line-run ((t (:foreground ,penumbra-purple :weight normal))))
+
+;;;;; grep
+ `(grep-context-face ((t (:foreground ,fg-alt))))
+ `(grep-error-face ((t (:foreground ,penumbra-red :weight normal :underline t))))
+ `(grep-hit-face ((t (:foreground ,penumbra-purple :weight normal))))
+ `(grep-match-face ((t (:foreground ,penumbra-cyan :weight normal))))
+ `(match ((t (:background ,penumbra-cyan :foreground ,penumbra-cyan-light))))
+
+;;;;; ag
+ `(ag-hit-face ((t (:foreground ,penumbra-green :weight normal))))
+ `(ag-match-face ((t (:foreground ,penumbra-cyan :background ,penumbra-cyan-light :weight normal))))
+
+;;;;; isearch
+ `(isearch ((t (:foreground ,fg :weight normal :background ,penumbra-cyan-light))))
+ `(isearch-fail ((t (:foreground ,fg :weight normal :background ,penumbra-red))))
+ `(lazy-highlight ((t (:foreground ,fg :weight normal :background ,penumbra-blue-light))))
+
+ `(menu ((t (:foreground ,bg :background ,fg))))
+ `(minibuffer-prompt ((t (:foreground ,fg :weight normal))))
+ `(region ((,class (:foreground ,fg :background ,highlight :extend nil))))
+ `(secondary-selection ((t (:background ,penumbra-green-light))))
+ `(trailing-whitespace ((t (:background ,penumbra-red-light))))
+ `(vertical-border ((t (:foreground ,penumbra-cyan))))
+
+;;;;; font lock
+ `(font-lock-builtin-face ((t (:foreground ,fg :weight normal))))
+ `(font-lock-function-name-face ((t (:foreground ,fg :weight normal))))
+ `(font-lock-string-face ((t (:foreground ,penumbra-red))))
+ `(font-lock-keyword-face ((t (:foreground ,penumbra-blue :weight bold)))) ; if, else, for, while, return...
+ `(font-lock-type-face ((t (:foreground ,fg :weight bold)))) ; int, float, string, void...
+ `(font-lock-constant-face ((t (:foreground ,fg :weight bold)))) ; NULL, nullptr, true, false...
+ `(font-lock-variable-name-face ((t (:foreground ,fg :weight normal))))
+ `(font-lock-comment-face ((t (:foreground ,penumbra-green :italic nil))))
+ `(font-lock-comment-delimiter-face ((t (:foreground ,penumbra-green :italic nil))))
+ `(font-lock-doc-face ((t (:foreground ,penumbra-yellow :italic nil))))
+ `(font-lock-negation-char-face ((t (:foreground ,penumbra-red :weight normal))))
+ `(font-lock-preprocessor-face ((t (:foreground ,penumbra-red :weight normal))))
+ `(font-lock-regexp-grouping-construct ((t (:foreground ,penumbra-purple :weight normal))))
+ `(font-lock-regexp-grouping-backslash ((t (:foreground ,penumbra-purple :weight normal))))
+ `(font-lock-warning-face ((t (:foreground ,penumbra-red :weight normal))))
+
+;;;;; table
+ `(table-cell ((t (:background ,bg-alt))))
+
+;;;;; ledger
+ `(ledger-font-directive-face ((t (:foreground ,penumbra-cyan))))
+ `(ledger-font-periodic-xact-face ((t (:inherit ledger-font-directive-face))))
+ `(ledger-font-posting-account-face ((t (:foreground ,penumbra-blue))))
+ `(ledger-font-posting-amount-face ((t (:foreground ,penumbra-red))))
+ `(ledger-font-posting-date-face ((t (:foreground ,penumbra-red :weight normal))))
+ `(ledger-font-payee-uncleared-face ((t (:foreground ,penumbra-purple))))
+ `(ledger-font-payee-cleared-face ((t (:foreground ,fg))))
+ `(ledger-font-payee-pending-face ((t (:foreground ,penumbra-yellow))))
+ `(ledger-font-xact-highlight-face ((t (:background ,bg-alt))))
+
+;;;; Third-party
+
+
+;;;;; anzu
+ `(anzu-mode-line ((t (:foreground ,penumbra-yellow :background ,penumbra-yellow-light :weight normal))))
+
+;;;;; clojure-mode
+ `(clojure-interop-method-face ((t (:inherit font-lock-function-name-face))))
+
+;;;;; clojure-test-mode
+ `(clojure-test-failure-face ((t (:foreground ,penumbra-red :weight normal :underline t))))
+ `(clojure-test-error-face ((t (:foreground ,penumbra-red :weight normal :underline t))))
+ `(clojure-test-success-face ((t (:foreground ,penumbra-green :weight normal :underline t))))
+
+;;;;; diff
+ `(diff-added ((,class (:foreground ,fg :background ,penumbra-green-light))
+ (t (:foreground ,fg :background ,penumbra-green-light))))
+ `(diff-changed ((t (:foreground ,penumbra-yellow))))
+ `(diff-context ((t (:foreground ,fg))))
+ `(diff-removed ((,class (:foreground ,fg :background ,penumbra-red-light))
+ (t (:foreground ,fg :background ,penumbra-red-light))))
+ `(diff-refine-added ((t :inherit diff-added :background ,penumbra-green-light :weight bold :underline t)))
+ `(diff-refine-change ((t :inherit diff-changed :weight normal)))
+ `(diff-refine-removed ((t :inherit diff-removed :background ,penumbra-red-light :weight bold :underline t)))
+ `(diff-header ((,class (:foreground ,fg :weight normal))
+ (t (:foreground ,penumbra-purple-light :weight normal))))
+ `(diff-file-header ((,class (:foreground ,fg :background ,penumbra-cyan-light :weight normal))
+ (t (:foreground ,fg :background ,penumbra-cyan-light :weight normal))))
+ `(diff-hunk-header ((,class (:foreground ,penumbra-green :weight normal))
+ (t (:foreground ,penumbra-green :weight normal))))
+;;;;; dired/dired+/dired-subtree
+ `(dired-directory ((t (:foreground ,penumbra-blue :weight bold))))
+ `(diredp-display-msg ((t (:foreground ,penumbra-blue))))
+ `(diredp-compressed-file-suffix ((t (:foreground ,penumbra-purple))))
+ `(diredp-date-time ((t (:foreground ,penumbra-green))))
+ `(diredp-deletion ((t (:foreground ,penumbra-red))))
+ `(diredp-deletion-file-name ((t (:foreground ,penumbra-red))))
+ `(diredp-dir-heading ((t (:foreground ,penumbra-blue :background ,penumbra-blue-light :weight bold))))
+ `(diredp-dir-priv ((t (:foreground ,penumbra-blue))))
+ `(diredp-exec-priv ((t (:foreground ,penumbra-yellow))))
+ `(diredp-executable-tag ((t (:foreground ,penumbra-yellow))))
+ `(diredp-file-name ((t (:foreground ,fg))))
+ `(diredp-file-suffix ((t (:foreground ,penumbra-yellow))))
+ `(diredp-flag-mark ((t (:foreground ,penumbra-cyan))))
+ `(diredp-flag-mark-line ((t (:foreground ,penumbra-cyan))))
+ `(diredp-ignored-file-name ((t (:foreground ,fg-light))))
+ `(diredp-link-priv ((t (:foreground ,penumbra-purple))))
+ `(diredp-mode-line-flagged ((t (:foreground ,penumbra-yellow))))
+ `(diredp-mode-line-marked ((t (:foreground ,penumbra-yellow))))
+ `(diredp-no-priv ((t (:foreground ,fg))))
+ `(diredp-number ((t (:foreground ,penumbra-blue))))
+ `(diredp-other-priv ((t (:foreground ,fg))))
+ `(diredp-rare-priv ((t (:foreground ,fg))))
+ `(diredp-read-priv ((t (:foreground ,fg))))
+ `(diredp-symlink ((t (:foreground ,fg :background ,penumbra-blue-light))))
+ `(diredp-write-priv ((t (:foreground ,fg))))
+ `(diredp-dir-name ((t (:foreground ,penumbra-blue :weight bold))))
+ `(dired-subtree-depth-1-face ((t (:background ,bg))))
+ `(dired-subtree-depth-2-face ((t (:background ,bg))))
+ `(dired-subtree-depth-3-face ((t (:background ,bg))))
+
+;;;;; elfeed
+ `(elfeed-search-date-face ((t (:foreground ,penumbra-blue))))
+ `(elfeed-search-title-face ((t (:foreground ,fg))))
+ `(elfeed-search-unread-title-face ((t (:foreground ,fg))))
+ `(elfeed-search-feed-face ((t (:foreground ,penumbra-green))))
+ `(elfeed-search-tag-face ((t (:foreground ,penumbra-red))))
+ `(elfeed-search-unread-count-face ((t (:foreground ,fg))))
+
+;;;;; erc
+ `(erc-default-face ((t (:foreground ,fg))))
+ `(erc-header-line ((t (:inherit header-line))))
+ `(erc-action-face ((t (:inherit erc-default-face))))
+ `(erc-bold-face ((t (:inherit erc-default-face :weight normal))))
+ `(erc-underline-face ((t (:underline t))))
+ `(erc-error-face ((t (:inherit font-lock-warning-face))))
+ `(erc-prompt-face ((t (:foreground ,penumbra-green :background ,penumbra-green-light :weight normal))))
+ `(erc-timestamp-face ((t (:foreground ,penumbra-green :background ,penumbra-green-light))))
+ `(erc-direct-msg-face ((t (:inherit erc-default))))
+ `(erc-notice-face ((t (:foreground ,fg-light))))
+ `(erc-highlight-face ((t (:background ,highlight))))
+ `(erc-input-face ((t (:foreground ,fg :background ,bg-alt))))
+ `(erc-current-nick-face ((t (:foreground ,fg :background ,penumbra-cyan-light :weight normal
+ :box (:line-width 1 :style released-button)))))
+ `(erc-nick-default-face ((t (:weight normal :background ,bg-alt))))
+ `(erc-my-nick-face ((t (:foreground ,fg :background ,penumbra-cyan-light :weight normal
+ :box (:line-width 1 :style released-button)))))
+ `(erc-nick-msg-face ((t (:inherit erc-default))))
+ `(erc-fool-face ((t (:inherit erc-default))))
+ `(erc-pal-face ((t (:foreground ,penumbra-purple :weight normal))))
+ `(erc-dangerous-host-face ((t (:inherit font-lock-warning-face))))
+ `(erc-keyword-face ((t (:foreground ,penumbra-yellow :weight normal))))
+
+ ;;;;; evil
+ `(evil-search-highlight-persist-highlight-face ((t (:inherit lazy-highlight))))
+
+;;;;; flx
+ `(flx-highlight-face ((t (:foreground ,penumbra-yellow :background ,penumbra-green-light
+ :weight normal :underline t))))
+
+;;;;; company
+ `(company-tooltip ((t (:background ,penumbra-blue-light))))
+ `(company-tooltip-selection ((t (:background ,penumbra-cyan-light))))
+ `(company-tooltip-common ((t (:foreground ,penumbra-blue :bold t))))
+ `(company-tooltip-annotation ((t (:foreground ,penumbra-yellow :italic t)))) ; parameter hints etc.
+ `(company-scrollbar-fg ((t (:background ,penumbra-cyan))))
+ `(company-scrollbar-bg ((t (:background ,penumbra-cyan-light))))
+ `(company-preview-common ((t (:foreground ,fg :background ,penumbra-cyan-light))))
+
+;;;;; highlight-symbol
+ `(highlight-symbol-face ((t (:background ,bg-alt))))
+
+;;;;; highlight-numbers
+ `(highlight-numbers-number ((t (:foreground ,penumbra-blue))))
+
+;;;;; highlight-operators
+ `(highlight-operators-face ((t (:foreground ,fg))))
+
+;;;;; hl-todo
+ `(hl-todo ((t (:inverse-video t))))
+
+;;;;; hl-line-mode
+ `(hl-line ((,class (:background ,bg-alt))))
+
+;;;;; hl-sexp
+ `(hl-sexp-face ((,class (:background ,bg-alt))))
+
+;;;;; ido-mode
+ `(ido-first-match ((t (:foreground ,fg :weight normal))))
+ `(ido-only-match ((t (:foreground ,fg :weight normal))))
+ `(ido-subdir ((t (:foreground ,penumbra-blue))))
+ `(ido-indicator ((t (:foreground ,penumbra-yellow))))
+
+;;;;; ido-vertical
+ `(ido-vertical-first-match-face ((t (:foreground ,fg :background ,penumbra-cyan-light :weight normal))))
+ `(ido-vertical-only-match-face ((t (:foreground ,penumbra-red :background ,penumbra-red-light :weight normal))))
+ `(ido-vertical-match-face ((t (:foreground ,fg :background ,penumbra-green-light
+ :weight normal :underline t))))
+
+;;;;; indent-guide
+ `(indent-guide-face ((t (:foreground ,highlight))))
+
+;;;;; ivy
+ `(ivy-current-match ((t (:background ,penumbra-blue-light :underline t :extend t))))
+ `(ivy-minibuffer-match-face-1 ((t (:background ,bg-alt))))
+ `(ivy-minibuffer-match-face-2 ((t (:background ,penumbra-cyan-light))))
+ `(ivy-minibuffer-match-face-3 ((t (:background ,penumbra-purple-light))))
+ `(ivy-minibuffer-match-face-3 ((t (:background ,penumbra-blue-light))))
+
+;;;;; js2-mode
+ `(js2-warning ((t (:underline ,penumbra-yellow))))
+ `(js2-error ((t (:foreground ,penumbra-red :weight normal))))
+ `(js2-jsdoc-tag ((t (:foreground ,penumbra-purple))))
+ `(js2-jsdoc-type ((t (:foreground ,penumbra-blue))))
+ `(js2-jsdoc-value ((t (:foreground ,penumbra-cyan))))
+ `(js2-function-param ((t (:foreground ,fg))))
+ `(js2-external-variable ((t (:foreground ,penumbra-cyan))))
+
+;;;;; linum-mode
+ `(linum ((t (:foreground ,fg-light))))
+
+;;;;; lsp-mode
+ `(lsp-face-highlight-textual ((t (:background ,bg-dark))))
+ `(lsp-face-highlight-read ((t (:background ,penumbra-purple-light))))
+ `(lsp-face-highlight-write ((t (:background ,penumbra-green-light))))
+
+;;;;; magit
+ `(magit-section-heading ((t (:foreground ,penumbra-cyan :background ,penumbra-blue-light
+ :weight normal :underline t))))
+ `(magit-section-highlight ((t (:background ,bg-alt))))
+ `(magit-section-heading-selection ((t (:background ,highlight))))
+ `(magit-filename ((t (:foreground ,fg))))
+ `(magit-hash ((t (:foreground ,penumbra-yellow :weight normal))))
+ `(magit-tag ((t (:foreground ,penumbra-purple :weight normal))))
+ `(magit-refname ((t (:foreground ,penumbra-purple :weight normal))))
+ `(magit-head ((t (:foreground ,penumbra-green :weight normal))))
+ `(magit-branch-local ((t (:foreground ,penumbra-blue :background ,penumbra-blue-light
+ :weight normal))))
+ `(magit-branch-remote ((t (:foreground ,penumbra-green :background ,penumbra-green-light
+ :weight normal))))
+ `(magit-branch-current ((t (:foreground ,penumbra-cyan :background ,penumbra-cyan-light
+ :weight normal
+ :box (:line-width 1 :color ,penumbra-cyan)))))
+ `(magit-diff-file-heading ((t (:foreground ,fg :weight normal))))
+ `(magit-diff-file-heading-highlight ((t (:background ,bg-alt))))
+ `(magit-diff-file-heading-selection ((t (:foreground ,penumbra-red :background ,highlight))))
+ `(magit-diff-hunk-heading ((t (:foreground ,penumbra-blue :background ,penumbra-blue-light :weight normal :underline t))))
+ `(magit-diff-hunk-heading-highlight ((t (:background ,penumbra-cyan-light))))
+ `(magit-diff-added ((t (:foreground ,penumbra-green :background ,penumbra-green-light))))
+ `(magit-diff-removed ((t (:foreground ,penumbra-red :background ,penumbra-red-light))))
+ `(magit-diff-context ((t (:foreground ,fg-dark :background nil))))
+ `(magit-diff-added-highlight ((t (:foreground ,penumbra-green :background ,penumbra-green-light))))
+ `(magit-diff-removed-highlight ((t (:foreground ,penumbra-red :background ,penumbra-red-light))))
+ `(magit-diff-context-highlight ((t (:foreground ,fg-dark :background ,bg-alt))))
+ `(magit-diffstat-added ((t (:foreground ,penumbra-green :background ,penumbra-green-light :weight normal))))
+ `(magit-diffstat-removed ((t (:foreground ,penumbra-red :background ,penumbra-red-light :weight normal))))
+ `(magit-log-author ((t (:foreground ,penumbra-blue :weight normal))))
+ `(magit-log-date ((t (:foreground ,penumbra-purple :weight normal))))
+ `(magit-log-graph ((t (:foreground ,penumbra-red :weight normal))))
+ `(magit-blame-heading ((t (:foreground ,fg-dark :background ,bg-alt))))
+
+;;;;; paren-face
+ `(parenthesis ((t (:foreground "#CCCCB7"))))
+
+;;;;; project-explorer
+ `(pe/file-face ((t (:foreground ,fg))))
+ `(pe/directory-face ((t (:foreground ,penumbra-blue :weight normal))))
+
+;;;;; rainbow-delimiters
+ `(rainbow-delimiters-depth-1-face ((t (:foreground ,penumbra-green))))
+ `(rainbow-delimiters-depth-2-face ((t (:foreground ,penumbra-blue))))
+ `(rainbow-delimiters-depth-3-face ((t (:foreground ,penumbra-red))))
+
+;;;;; show-paren
+ `(show-paren-mismatch ((t (:foreground ,penumbra-yellow :background ,penumbra-red :weight normal))))
+ `(show-paren-match ((t (:foreground ,fg :background ,penumbra-cyan-light :weight normal))))
+
+;;;;; mode-line/sml-mode-line
+ `(mode-line ((,class (:foreground ,fg :background ,penumbra-blue-light :box t))))
+ `(mode-line-inactive ((t (:foreground ,fg :background ,bg-dark :box t))))
+ `(mode-line-buffer-id ((t (:foreground ,fg :weight bold)))) ; associated buffer/file name
+ `(sml/global ((t (:foreground ,fg))))
+ `(sml/modes ((t (:foreground ,penumbra-green :background ,penumbra-green-light))))
+ `(sml/filename ((t (:foreground ,penumbra-red))))
+ `(sml/folder ((t (:foreground ,fg))))
+ `(sml/prefix ((t (:foreground ,fg))))
+ `(sml/read-only ((t (:foreground ,fg))))
+ `(sml/modified ((t (:foreground ,penumbra-red :weight normal))))
+ `(sml/outside-modified ((t (:background ,penumbra-red :foreground ,penumbra-red-light :weight normal))))
+ `(sml/line-number ((t (:foreground ,fg :weight normal))))
+ `(sml/col-number ((t (:foreground ,fg :weight normal))))
+ `(sml/vc ((t (:foreground ,fg :weight normal))))
+ `(sml/vc-edited ((t (:foreground ,penumbra-red :weight normal))))
+ `(sml/git ((t (:foreground ,fg :weight normal))))
+
+;;;;; sh
+ `(sh-heredoc-face ((t (:foreground ,penumbra-purple))))
+
+;;;;; web-mode
+ `(web-mode-builtin-face ((t (:inherit ,font-lock-builtin-face))))
+ `(web-mode-comment-face ((t (:inherit ,font-lock-comment-face))))
+ `(web-mode-constant-face ((t (:inherit ,font-lock-constant-face))))
+ `(web-mode-doctype-face ((t (:inherit ,font-lock-comment-face))))
+ `(web-mode-folded-face ((t (:underline t))))
+ `(web-mode-function-name-face ((t (:foreground ,fg :weight normal))))
+ `(web-mode-html-attr-name-face ((t (:foreground ,fg))))
+ `(web-mode-html-attr-value-face ((t (:inherit ,font-lock-string-face))))
+ `(web-mode-html-tag-face ((t (:foreground ,penumbra-blue))))
+ `(web-mode-keyword-face ((t (:inherit ,font-lock-keyword-face))))
+ `(web-mode-preprocessor-face ((t (:inherit ,font-lock-preprocessor-face))))
+ `(web-mode-string-face ((t (:inherit ,font-lock-string-face))))
+ `(web-mode-type-face ((t (:inherit ,font-lock-type-face))))
+ `(web-mode-variable-name-face ((t (:inherit ,font-lock-variable-name-face))))
+ `(web-mode-server-background-face ((t (:background ,penumbra-green-light))))
+ `(web-mode-server-comment-face ((t (:inherit web-mode-comment-face))))
+ `(web-mode-server-string-face ((t (:foreground ,penumbra-red))))
+ `(web-mode-symbol-face ((t (:inherit font-lock-constant-face))))
+ `(web-mode-warning-face ((t (:inherit font-lock-warning-face))))
+ `(web-mode-whitespaces-face ((t (:background ,penumbra-red-light))))
+ `(web-mode-block-face ((t (:background ,penumbra-green-light))))
+ `(web-mode-current-element-highlight-face ((t (:foreground ,fg :background ,penumbra-blue-light))))
+ `(web-mode-json-key-face ((,class (:inherit font-lock-string-face))))
+ `(web-mode-json-context-face ((,class (:inherit font-lock-string-face :bold t))))
+
+;;;;; which-func-mode
+ `(which-func ((t (:foreground ,penumbra-purple :background ,penumbra-purple-light))))
+
+;;;;; yascroll
+ `(yascroll:thumb-text-area ((t (:background ,highlight))))
+ `(yascroll:thumb-fringe ((t (:background ,bg :foreground ,bg
+ :box (:line-width 1 :style released-button)))))
+
+;;;;; Org
+ `(org-level-1 ((t (:background ,penumbra-blue-light :foreground ,penumbra-blue :weight bold :overline t))))
+ `(org-level-2 ((t (:background ,penumbra-blue-light :foreground ,penumbra-cyan :weight bold :overline t))))
+ `(org-level-3 ((t (:background ,penumbra-blue-light :foreground ,penumbra-blue :weight bold :overline t))))
+ `(org-level-4 ((t (:background ,penumbra-blue-light :foreground ,penumbra-cyan))))
+ `(org-level-5 ((t (:background ,penumbra-blue-light :foreground ,penumbra-blue))))
+ `(org-level-6 ((t (:background ,penumbra-blue-light :foreground ,penumbra-cyan))))
+ `(org-level-7 ((t (:background ,penumbra-blue-light :foreground ,penumbra-blue))))
+ `(org-level-8 ((t (:background ,penumbra-blue-light :foreground ,penumbra-cyan))))
+ `(org-document-title ((t (:height 1.2 :foreground ,penumbra-blue :weight bold :underline t)))) ; #TITLE
+ `(org-meta-line ((t (:foreground ,penumbra-green))))
+ `(org-document-info ((t (:foreground ,penumbra-cyan :weight normal))))
+ `(org-document-info-keyword ((t (:foreground ,penumbra-cyan))))
+ `(org-todo ((t (:foreground ,penumbra-yellow :background ,bg-alt :weight normal :box (:line-width 1 :style released-button)))))
+ `(org-done ((t (:foreground ,penumbra-green :background ,penumbra-green-light :weight normal :box (:style released-button)))))
+ `(org-date ((t (:foreground ,penumbra-purple))))
+ `(org-table ((t (:foreground ,penumbra-purple))))
+ `(org-formula ((t (:foreground ,penumbra-blue :background ,bg-alt))))
+ `(org-code ((t (:foreground ,penumbra-red :background ,bg-alt))))
+ `(org-verbatim ((t (:foreground ,fg :background ,bg-alt :underline t))))
+ `(org-special-keyword ((t (:foreground ,penumbra-cyan))))
+ `(org-agenda-date ((t (:foreground ,penumbra-cyan))))
+ `(org-agenda-structure ((t (:foreground ,penumbra-purple))))
+ `(org-block ((t (:foreground ,fg :background ,bg-alt :extend t))))
+ `(org-block-background ((t (:background ,bg-alt :extend t))))
+ `(org-block-begin-line ((t (:foreground ,fg-alt :background ,bg-dark :italic t :extend t))))
+ `(org-block-end-line ((t (:foreground ,fg-alt :background ,bg-dark :italic t :extend t))))
+
+;;;;; origami
+ `(origami-fold-replacement-face ((t (:foreground ,penumbra-red :background ,penumbra-red-light
+ :box (:line-width -1)))))
+
+;;;;; git-gutter
+ `(git-gutter:added ((t (:background ,penumbra-green-alt :foreground ,penumbra-green-alt :weight normal))))
+ `(git-gutter:deleted ((t (:background ,penumbra-red :foreground ,penumbra-red :weight normal))))
+ `(git-gutter:modified ((t (:background ,penumbra-yellow :foreground ,penumbra-yellow :weight normal))))
+ `(git-gutter-fr:added ((t (:background ,penumbra-green-alt :foreground ,penumbra-green-alt :weight normal))))
+ `(git-gutter-fr:deleted ((t (:background ,penumbra-red :foreground ,penumbra-red :weight normal))))
+ `(git-gutter-fr:modified ((t (:background ,penumbra-yellow :foreground ,penumbra-yellow :weight normal))))
+
+;;;;; diff-hl
+ `(diff-hl-insert ((t (:background ,penumbra-green-alt :foreground ,penumbra-green-alt))))
+ `(diff-hl-delete ((t (:background ,penumbra-red :foreground ,penumbra-red))))
+ `(diff-hl-change ((t (:background ,penumbra-yellow :foreground ,penumbra-yellow))))
+
+;;;;; mu4e, mail
+ `(mu4e-header-highlight-face ((t (:background ,highlight))))
+ `(mu4e-unread-face ((t (:foreground ,penumbra-blue :weight normal))))
+ `(mu4e-flagged-face ((t (:foreground ,penumbra-red :background ,penumbra-red-light :weight normal))))
+ `(mu4e-compose-separator-face ((t (:foreground ,penumbra-green))))
+ `(mu4e-header-value-face ((t (:foreground ,fg))))
+ `(message-header-name ((t (:foreground ,penumbra-purple :weight normal))))
+ `(message-header-to ((t (:foreground ,penumbra-blue))))
+ `(message-header-subject ((t (:foreground ,penumbra-blue))))
+ `(message-header-other ((t (:foreground ,penumbra-blue))))
+ `(message-cited-text ((t (:inherit font-lock-comment-face))))
+
+;;;;; term-mode (vterm too)
+ `(term ((,class (:foreground ,fg :background ,bg))))
+ `(term-color-black ((,class (:foreground ,fg :background ,fg))))
+ `(term-color-blue ((,class (:foreground ,penumbra-blue :background ,penumbra-blue))))
+ `(term-color-red ((,class (:foreground ,penumbra-red :background ,penumbra-red))))
+ `(term-color-green ((,class (:foreground ,penumbra-green :background ,penumbra-green))))
+ `(term-color-yellow ((,class (:foreground ,penumbra-yellow :background ,penumbra-yellow))))
+ `(term-color-magenta ((,class (:foreground ,penumbra-purple :background ,penumbra-purple))))
+ `(term-color-cyan ((,class (:foreground ,penumbra-cyan :background ,penumbra-cyan))))
+ `(term-color-white ((,class (:foreground ,fg :background ,fg))))
+
+;;;;; fill-column-indicator
+ `(fci-rule-color ((t (:foreground ,highlight-alt))))
+ `(fill-column-indicator ((t (:foreground ,highlight-alt))))))
+
+;;;###autoload
+(when (and (boundp 'custom-theme-load-path) load-file-name)
+ (add-to-list 'custom-theme-load-path
+ (file-name-as-directory (file-name-directory load-file-name))))
+
+(provide-theme 'penumbra)
+(provide 'penumbra-theme)
+
+;;; penumbra-theme.el ends here
diff --git a/emacs/libs/slime b/emacs/libs/slime
new file mode 160000
+Subproject 6ef28864d4a6b4d9390dbd0cac64f2a56582682
diff --git a/emacs/libs/utils.el b/emacs/libs/utils.el
new file mode 100644
index 0000000..df0c464
--- /dev/null
+++ b/emacs/libs/utils.el
@@ -0,0 +1,17 @@
+;;; utils.el --- Utility package
+;;; Commentary:
+;; None
+
+;;; Code:
+(require 'org-table)
+
+(defun csv-to-table (file)
+ "Turn a csv with ; separator in FILE to table."
+ (with-temp-buffer
+ (erase-buffer)
+ (insert-file-contents file nil 0 500)
+ (org-table-convert-region (point-min) (point-max) ";")
+ (buffer-string)))
+
+(provide 'utils)
+;;; utils.el ends here
diff --git a/emacs/my.el b/emacs/my.el
new file mode 100644
index 0000000..07ce9f8
--- /dev/null
+++ b/emacs/my.el
@@ -0,0 +1,12 @@
+(defun ceg/show-urls (what)
+ "Run show-urls and grep for WHAT."
+ (interactive "sUrl: ")
+ (shell-command (concat "python " ceg/manage-bin " show_urls --no-color | grep '" what "'")
+ (concat "*URL<" what ">")))
+
+(defun my/show-urls (what)
+ "Run show_urls and grep for WHAT."
+ (interactive "sUrl: ")
+ (let ((command (concat "python " ceg/manage-bin " show_urls --no-color | grep '" what "'"))
+ (buf (concat "*URL<" what ">")))
+ ))
diff --git a/emacs/nano.el b/emacs/nano.el
new file mode 100644
index 0000000..676fc21
--- /dev/null
+++ b/emacs/nano.el
@@ -0,0 +1,34 @@
+(require 'package)
+(let* ((no-ssl (and (memq system-type '(windows-nt ms-dos))
+ (not (gnutls-available-p))))
+ (proto (if no-ssl "http" "https")))
+ (add-to-list 'package-archives (cons "melpa" (concat proto "://melpa.org/packages/")) t)
+ (package-initialize))
+(add-to-list 'load-path "~/.emacs.d/libs/nano-emacs")
+;; OrgMode
+(add-hook 'org-mode-hook (lambda ()
+ (auto-fill-mode)
+ ;;(variable-pitch-mode)
+ (bug-reference-mode)))
+(setq org-edit-src-content-indentation 0)
+(use-package org-roam
+ :ensure t
+ :defer t
+ :init (setq org-roam-v2-ack t)
+ :custom
+ (org-roam-directory "~/OrgRoam")
+ :bind (("C-c n l" . org-roam-buffer-toggle)
+ ("C-c n f" . org-roam-node-find)
+ ("C-c n i" . org-roam-node-insert))
+ :config
+ (org-roam-setup))
+(use-package org-modern
+ :ensure t
+ :defer t
+ :init (global-org-modern-mode))
+(setq org-confirm-babel-evaluate nil)
+
+
+(setq nano-font-family-monospaced "Roboto Mono")
+
+(load "~/.emacs.d/libs/nano-emacs/nano.el")
diff --git a/emacs/projects b/emacs/projects
new file mode 100644
index 0000000..479d055
--- /dev/null
+++ b/emacs/projects
@@ -0,0 +1,2 @@
+;;; -*- lisp-data -*-
+(("/home/work/Workspace/ceg-intranet/ceg/"))
diff --git a/emacs/tramp b/emacs/tramp
new file mode 100644
index 0000000..f294780
--- /dev/null
+++ b/emacs/tramp
@@ -0,0 +1,37 @@
+;; -*- emacs-lisp -*- <23/08/14 09:34:55 ~/.emacs.d/tramp>
+;; Tramp connection history. Don't change this file.
+;; Run `M-x tramp-cleanup-all-connections' instead.
+
+(((tramp-file-name "cache" nil nil nil nil nil nil)
+ ("tramp-version" "2.6.0.29.1"))
+ ((tramp-file-name "sudo" "root" nil "wendy" nil nil nil)
+ ("null-device" "/dev/null")
+ ("uname" "Linux 6.4.9-arch1-1")
+ ("locale" "LC_ALL=en_US.utf8")
+ ("test" "test")
+ ("pipe-buf" 4096)
+ ("remote-shell" "/bin/sh")
+ ("~root" "/root")
+ ("perl-file-spec" t)
+ ("perl-cwd-realpath" t)
+ ("perl" "\\perl")
+ ("file-exists" "test -e")
+ ("case-insensitive" nil)
+ ("~" "/root")
+ ("readlink" "\\readlink")
+ ("stat" "env QUOTING_STYLE=locale \\stat")
+ ("id" "/usr/bin/id")
+ ("uid-integer" 0)
+ ("uid-string" "root")
+ ("gid-integer" 0)
+ ("gid-string" "root")
+ ("groups-integer"
+ (0))
+ ("groups-string"
+ ("root"))
+ ("bzr" nil)
+ ("git" "\\git")
+ ("hg" nil)
+ ("ln" "\\ln"))
+ ((tramp-file-name "sudo" "work" nil "wendy" nil nil nil)
+ nil))