From 0f873d646031971dd37824181b65ce457576749e Mon Sep 17 00:00:00 2001 From: Matias Linares Date: Mon, 25 Sep 2023 09:33:17 -0300 Subject: Add emacs configuration --- emacs/custom-org-mode.el | 58 ++ emacs/custom.el | 116 +++ emacs/init.el | 426 +++++++++ emacs/libs/center-helm-buffer.el | 55 ++ emacs/libs/lambda-line.el | 1825 ++++++++++++++++++++++++++++++++++++++ emacs/libs/minad.el | 89 ++ emacs/libs/nano-emacs | 1 + emacs/libs/penumbra-theme.el | 512 +++++++++++ emacs/libs/slime | 1 + emacs/libs/utils.el | 17 + emacs/my.el | 12 + emacs/nano.el | 34 + emacs/projects | 2 + emacs/tramp | 37 + 14 files changed, 3185 insertions(+) create mode 100644 emacs/custom-org-mode.el create mode 100644 emacs/custom.el create mode 100644 emacs/init.el create mode 100644 emacs/libs/center-helm-buffer.el create mode 100644 emacs/libs/lambda-line.el create mode 100644 emacs/libs/minad.el create mode 160000 emacs/libs/nano-emacs create mode 100644 emacs/libs/penumbra-theme.el create mode 160000 emacs/libs/slime create mode 100644 emacs/libs/utils.el create mode 100644 emacs/my.el create mode 100644 emacs/nano.el create mode 100644 emacs/projects create mode 100644 emacs/tramp (limited to 'emacs') 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- +(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 "") '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 . + +;;; 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 ") + (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) "")) + (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 + ;; "" #'vertico-insert ; Choose selected candidate + ;; "" #'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 index 0000000..185894d --- /dev/null +++ b/emacs/libs/nano-emacs @@ -0,0 +1 @@ +Subproject commit 185894da71aeab33e52a1bedcde6cea4b148436c 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 . + +;;; 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 index 0000000..6ef2886 --- /dev/null +++ b/emacs/libs/slime @@ -0,0 +1 @@ +Subproject commit 6ef28864d4a6b4d9390dbd0cac64f2a56582682d 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)) -- cgit v1.2.3-70-g09d2