diff options
Diffstat (limited to '.config/emacs/init.el')
-rw-r--r-- | .config/emacs/init.el | 767 |
1 files changed, 385 insertions, 382 deletions
diff --git a/.config/emacs/init.el b/.config/emacs/init.el index 35d15c9..87fcde8 100644 --- a/.config/emacs/init.el +++ b/.config/emacs/init.el @@ -44,8 +44,9 @@ ;; Font (custom-set-faces (if is-hermes '(default ((t (:inherit nil :height 130 :family "Fira Mono")))) - '(default ((t (:inherit nil :height 150 :family "Fira Mono"))))) - '(org-modern-symbol ((t (:inherit t :family "Iosevka Aile"))))) + '(default ((t (:inherit nil :height 160 :family "Fira Mono"))))) + '(org-modern-symbol ((t (:inherit t :family "Iosevka Aile")))) + '(variable-pitch ((t (:inherit t :family "Fira Mono" :height 130))))) ;; Autoinsert (auto-insert-mode 1) @@ -53,25 +54,119 @@ (setf auto-insert-alist '((python-mode . "python.template")) auto-insert-directory (locate-user-emacs-file "insert")) -;; Completions -(add-to-list 'completion-styles 'initials t) -(setf tab-always-indent 'complete) - -;; Search -(setf search-default-mode #'char-fold-to-regexp) ;; make it easier to search Greek chars - -;; xref -(setf xref-show-xrefs-function #'consult-xref - xref-show-definitions-function #'consult-xref) ;; Set and load custom.el (setf custom-file (locate-user-emacs-file "custom.el")) (load custom-file 'noerror) +;; Imenu ;; Enable use-package support for imenu +;; NOTE: Load this before use-package! (setf use-package-enable-imenu-support t) -(setf browse-url-browser-function 'eww ;; 'browse-url-generic +(require 'imenu) +(setf imenu-auto-rescan t + imenu-flatten 'prefix) + +(global-set-key (kbd "C-c m") 'imenu) + + +;;;; Completions & Minibuffer + +(use-package completion-preview + :ensure t + :config + (global-completion-preview-mode) + ;; Enable completion-preview in org-mode + (push 'org-self-insert-command completion-preview-commands)) + +(use-package icomplete + :ensure t + :config + (setf completion-styles '(basic flex) + completion-auto-select t ;; Show completion on first call + completion-auto-help 'visible ;; Display *Completions* upon first request + completions-format 'one-column ;; Use only one column + completions-sort 'historical ;; Order based on minibuffer history + completions-max-height 20 ;; Limit completions to 15 + completion-ignore-case t) + ;; Minibuffer completions + (fido-vertical-mode 1) + :bind (:map icomplete-fido-mode-map + ("TAB" . 'icomplete-force-complete))) + +;; Search +(setf search-default-mode #'char-fold-to-regexp) ;; make it easier to search Greek chars + +;; Registers & Misc nav +(setf register-use-preview t) + +(global-set-key (kbd "C-x r d") 'bookmark-delete) +(global-set-key (kbd "C-x C-b") 'switch-to-prev-buffer) +(global-set-key (kbd "C-x M-b") 'ibuffer) + +(defun switch-to-window-with-buffer (buffer-name) + "Switch to a window displaying a buffer named BUFFER-NAME, if it exists." + (let ((target-window nil)) + (walk-windows (lambda (w) + (when (string= (buffer-name (window-buffer w)) buffer-name) + (setq target-window w))) + nil t) + (if target-window + (select-window target-window) + (message "No window is displaying buffer '%s'" buffer-name)))) + +(defun thanos/occur (regexp &optional nlines region) + "Run `occur' and switch to *Occur* buffer." + (interactive (nconc (occur-read-primary-args) + (and (use-region-p) (list (region-bounds))))) + (let* ((start (and (caar region) (max (caar region) (point-min)))) + (end (and (cdar region) (min (cdar region) (point-max)))) + (in-region (or start end)) + (bufs (if (not in-region) (list (current-buffer)) + (let ((ol (make-overlay + (or start (point-min)) + (or end (point-max))))) + (overlay-put ol 'occur--orig-point (point)) + (list ol))))) + (occur-1 regexp nlines bufs)) + (switch-to-window-with-buffer "*Occur*") + (forward-line)) + +(defun thanos/close-window (buffer-name) + "Go to occurrence and quit the *Occur* window." + (let ((occur-window (get-buffer-window buffer-name))) + (when occur-window + (quit-window nil occur-window)))) + +(defun thanos/occur-mode-goto-occurrence-close-occur-window () + "Go to occurrence and quit the *Occur* window." + (interactive) + (occur-mode-goto-occurrence) + (thanos/close-window "*Occur*")) + +(defun thanos/compile-goto-error () + "Go to compile error & close *grep* buffer." + (interactive (list last-input-event)) + (compile-goto-error) + (thanos/close-window "*grep*")) + +(require 'grep) +(define-key occur-mode-map (kbd "RET") + 'thanos/occur-mode-goto-occurrence-close-occur-window) + +(define-key grep-mode-map (kbd "C-o") 'thanos/compile-goto-error) + +(defvar-keymap thanos/search-map + "g" #'grep-find + "l" #'lgrep + "f" #'find-name-dired + "o" #'thanos/occur + "C-o" #'occur) + +(global-set-key (kbd "C-c s") thanos/search-map) + +(setf browse-url-browser-function 'browse-url-generic browse-url-generic-program "icecat" backup-directory-alist '((".*" . "~/.Trash")) sentence-end-double-space t @@ -90,6 +185,14 @@ ("\\<\\(TODO\\):" 1 font-lock-warning-face t) ("\\<\\(NOTE\\):" 1 font-lock-warning-face t)))) +(setf tab-always-indent 'icomplete-force-complete) + +(use-package flyspell + :ensure t + :config + (setf ispell-alternate-dictionary + (expand-file-name "~/.hunspell.d/en_med.dic"))) + (use-package org :ensure t :config @@ -145,11 +248,26 @@ ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}"))) + + (push 'org-self-insert-command completion-preview-commands) :hook ((org-mode . (lambda () (display-line-numbers-mode -1) (flyspell-mode)))) :bind (:map org-mode-map (("C-c l" . org-store-link) ("C-c M-t" . org-todo) - ("C-c RET" . org-table-hline-and-move)))) + ("C-c RET" . org-table-hline-and-move) + ("C-M-i" . completion-at-point)))) +(use-package org-present + :hook ((org-present-mode . (lambda () + (org-present-big) + (org-display-inline-images) + (org-present-hide-cursor) + (org-present-read-only))) + (org-present-mode-quit . (lambda () + (org-present-small) + (org-remove-inline-images) + (org-present-show-cursor) + (org-present-read-write))))) +;; (completion-styles-alist ) ;; Export (defun thanos/org-html-remove-curly-braces (text backend info) @@ -161,7 +279,6 @@ (use-package emacs :ensure nil :config - (if is-zeus (display-battery-mode 0) (display-battery-mode 1)) @@ -304,118 +421,20 @@ (setf org-modern-table nil org-modern-todo nil org-modern-tag nil + org-modern-timestamp nil org-modern-star 'replace org-modern-list '((?+ . "•") - (?- . "•"))) + (?- . "•")) + org-modern-replace-stars "☧") :hook ((org-mode . org-modern-mode))) ;; Create notes directory for org-roam (unless (file-exists-p "~/Notes") (make-directory "~/Notes")) -(use-package org-roam - :vc t - :load-path "~/Dev/emacs-lisp/org-roam" - :defer t - :init - (define-prefix-command 'thanos/notes-map) - :config - (setf org-roam-directory "~/Notes" - org-roam-dailies-directory "daily/") - - (org-roam-db-autosync-enable) - - (setf org-roam-node-display-template - (concat "${title:50} "(propertize "${tags:50}" 'face 'org-tag))) - - (setf org-roam-db-node-include-function - (lambda () - (not (or (member "journal" (org-get-tags)) - (member "dailies" (org-get-tags)))))) - ;; Templates - (setf org-roam-capture-templates - '(("d" "default" plain - "%?" - :if-new - (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+startup: overview\n") - :unnarrowed t) - ("p" "MUS" plain "* Goals\n\n%?\n\n* Tasks\n\n** TODO Add initial tasks\n\n* Dates\n\n" - :if-new - (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+filetags: MUS") - :unnarrowed t)) - org-roam-dailies-capture-templates - '(("d" "default" entry - "* %?" - :target (file+head "%<%Y-%m-%d>.org" - "#+title: %<%Y-%m-%d>\n#+filetags: :journal:dailies:\n")) - ("j" "journal" plain - "* %?" - :target (file+head "%<%Y-%m-%d>.org" - "#+title: %<%Y-%m-%d>\n#+filetags: :journal:dailies:\n -* Daily Notes\n\n* Goals\n+ [] Πρωινὴ Προσευχή\n+ [] Ἑσπερινή Προσευχή\n\n* Extras")))) - - (defun org-roam-ref-add-book () - "Insert org-link from Library." - (interactive) - (let ((book - (format - "file:%s" - (read-file-name "Book: " (if is-zeus "/hdd/Library/" "~/Library/"))))) - book)) - - (defun org-roam-sync-notes () - "Sync org-oram notes" - (interactive) - (let ((git (executable-find "git")) - (default-directory org-roam-directory)) - (message "Synching org-roam notes %s" org-roam-directory) - (unless git - (error "Git not found, please install `git'")) - (unless (file-exists-p (expand-file-name ".git" gnosis-dir)) - (message "Creating git repository") - (vc-create-repo 'Git)) - (shell-command "git pull") - (shell-command (format "%s %s" git "add .")) - (shell-command (format "%s %s %s" git "commit -m" - (shell-quote-argument "Update org-roam notes"))) - (vc-git-push nil)) - (funcall 'org-roam-db-sync)) - :bind (("C-c n" . thanos/notes-map) - :map thanos/notes-map - ("t" . org-roam-buffer-toggle) - ("f" . org-roam-node-find) - ("i" . org-roam-node-insert) - ("d" . org-roam-dailies-goto-today) - ("D" . org-roam-dailies-goto-date) - :map org-mode-map - ("C-c C-." . org-roam-tag-add) - ("C-c i" . org-id-get-create))) - -(use-package org-roam-ui - :vc (:url "https://github.com/org-roam/org-roam-ui") - :after org-roam - :config - (setq org-roam-ui-sync-theme t - org-roam-ui-follow t - org-roam-ui-update-on-save t - org-roam-ui-open-on-start t)) - -(use-package org-present - :vc (:url "https://github.com/rlister/org-present") - :hook ((org-present-mode . (lambda () - (org-present-big) - (org-display-inline-images) - (org-present-hide-cursor) - (org-present-read-only))) - (org-present-mode-quit . (lambda () - (org-present-small) - (org-remove-inline-images) - (org-present-show-cursor) - (org-present-read-write))))) - (unless (or is-phone is-uranus) (use-package modus-themes - :vc (:url "https://github.com/protesilaos/modus-themes") + :ensure t :config (setf modus-themes-italic-constructs nil modus-themes-bold-constructs nil @@ -425,15 +444,14 @@ modus-themes-disable-other-themes t modus-themes-prompts '(italic) modus-themes-completions '((matches . (underline)) - (selection . (semibold italic text-also underline))) - modus-themes-org-blocks 'tinted-background) + (selection . (semibold italic text-also underline)))) ;; Palette overrides (setf modus-themes-common-palette-overrides '((fg-line-number-active cyan-intense) ;; (bg-main "#1d2021") ;;grubox-hard ;; (bg-main "#191919") ;; 1337 ;; (bg-main "#1d1f21") ;; tomorrow night - ;; (bg-main "#151515") ;; jazz + (bg-main "#151515") ;; jazz ;; (bg-main "#0C0C0C") ;; random black ;; (bg-main "#171717") ;; badger ;; (overline-heading-1 gold) @@ -446,15 +464,15 @@ (underline-err red-intense) (underline-warning yellow-faint) (underline-note cyan-faint) - ;; (string "#86B187") + (string olive) (border-mode-line-active unspecified) (border-mode-line-inactive unspecified) (bg-mode-line-active "#433F4f") ;; subtle lavender (bg-mode-line-inactive "#1D1D1D") - ;; set fg from badger theme + ;; Set fg from badger theme (fg-mode-line-active "#F6F3E8") (bg-hl-line bg-dim) - (cursor slate) + (cursor indigo) (prose-todo green-intense) (prose-done bg-term-white) (fg-prompt yellow-faint) @@ -463,138 +481,22 @@ (setf modus-themes-headings '((1 . (ultrabold 1.35)) (2 . (semibold 1.2)) - (agenda-date . (1.3)) + (agenda-date . (1.2)) (agenda-structure . (variable-pitch light 1.8)) (t . (1.15)))) ;; Load modus (load-theme 'modus-vivendi t))) -(use-package vertico - :ensure t - :config - (vertico-mode)) - -(use-package marginalia - :ensure t - :config - (marginalia-mode)) - -(use-package consult - :ensure t - :init (define-prefix-command 'thanos/search) - :bind (("C-x r d" . 'bookmark-delete) - ("C-x r C-r" . 'bookmark-rename) - ("C-x r C-j" . 'consult-register) - ("C-x r SPC" . 'consult-register-store) - ("C-x r b" . 'consult-bookmark) - ("C-c m" . 'consult-imenu) - ("C-x b" . 'consult-buffer) - ("C-x C-b" . 'switch-to-prev-buffer) - ("C-x M-b" . 'ibuffer) - ("M-y" . 'consult-yank-from-kill-ring) - ("C-M-s" . 'consult-line) - ("C-c s" . 'thanos/search) - :map thanos/search - ("f" . 'consult-find) - ("g" . 'consult-grep) - ("i" . 'consult-info) - ("l" . 'consult-locate) - ("b" . 'consult-buffer-other-window) - ("m" . 'consult-man) - :map project-prefix-map - ("b" . 'consult-project-buffer))) - (use-package which-key :ensure t :config (which-key-mode 1)) -(use-package elfeed - :defer t - :vc (:url "https://github.com/skeeto/elfeed") - :config - (setf elfeed-search-filter "@1-week-ago +unread -hackernoon" - browse-url-browser-function #'browse-url-default-browser - elfeed-db-directory "~/.config/elfeed") - ;; Feeds - (setf elfeed-feeds - '(("https://hackaday.com/blog/feed/" - hackaday linux) - ("https://thanosapollo.org/index.xml" - thanos) - ("http://wikileaks.org/feed" - wikileaks) - ("https://hackernoon.com/feed" - hackernoon) - ("https://torrentfreak.com/feed" - torrentfreak piracy) - ("https://www.science.org/action/showFeed?type=etoc&feed=rss&jc=sciimmunol" - science) - ("http://localhost/?action=display&bridge=CssSelectorBridge&home_page=https%3A%2F%2Fwww.medscape.com%2Findex%2Flist_13470_0&url_selector=a.title&url_pattern=viewarticle%2F.*&content_selector=div.article__main-content&content_cleanup=&title_cleanup=+-+Index&limit=&format=Atom" medscape med) - ("http://localhost/?action=display&bridge=CssSelectorBridge&home_page=https%3A%2F%2Fwww.tovima.gr%2Flatest-news%2F&url_selector=a.columns&url_pattern=&content_selector=div.main-content&content_cleanup=div.wrap-facebook%2Cdiv.googlenews&title_cleanup=&limit=&format=Atom" tovima greek news) - ("http://localhost/?action=display&bridge=CssSelectorBridge&home_page=https%3A%2F%2Fwww.estianews.gr%2Feidiseis-arthra%2F&url_selector=h3.entry-title&url_pattern=&content_selector=div.col-lg-8&content_cleanup=&title_cleanup=&limit=&format=Atom" estia greek news) - ("http://localhost/?action=display&bridge=CssSelectorBridge&home_page=https%3A%2F%2Fwww.estianews.gr%2Fkentriko-thema%2F&url_selector=h3.entry-title&url_pattern=&content_selector=div.col-md-8&content_cleanup=&title_cleanup=&limit=&format=Atom" estia greek kyrio) - ("http://localhost/?action=display&bridge=CssSelectorBridge&home_page=https%3A%2F%2Fwww.estianews.gr%2Fapopseis%2F&url_selector=h3.entry-title&url_pattern=&content_selector=div.col-lg-8&content_cleanup=&title_cleanup=&limit=&format=Atom" estia greek opinions) - ("http://localhost/?action=display&bridge=CssSelectorBridge&home_page=https%3A%2F%2Fwww.reuters.com%2Fbusiness%2Fhealthcare-pharmaceuticals%2F&url_selector=a.basic-card__title__37xHl&url_pattern=&content_selector=div.article-body__wrapper__3IxHM&content_cleanup=svg.link__new-tab-symbol__3T19s%2C+div.toolbar__container__3kIkw%2C+div.article-body__row__dFOPA+article-body__element__2p5pI&title_cleanup=&limit=&format=Atom" reuters med news) - ("http://localhost/?action=display&bridge=CssSelectorBridge&home_page=https%3A%2F%2Fwww.reuters.com%2Ftechnology%2Fcybersecurity%2F&url_selector=a.media-story-card__headline__tFMEu%2C+a.media-story-card__heading__eqhp9&url_pattern=&content_selector=article.article__container__2MUeZ&content_cleanup=div.info-content__toolbar__3AkHm%2C+svg.link__new-tab-symbol__3T19s%2C+div.article-body__row__dFOPA%2C+div.read-next-tablet-up__container__3MpHN%2C+div.author-bio__multiple-authors__5YGrG%2C+div.article__read-next__Kjxdw&title_cleanup=&limit=&format=Atom" reuters cybersec news) - ("https://annas-blog.org/ -rss.xml" anna piracy) - ("https://planet.emacslife.com/atom.xml" emacs emacslife) - ("https://localmonero.co/static/rss/the-monero-standard/feed.xml" monero) - ("https://devonzuegel.com/feed" devon) - ("https://www.addtoany.com/add_to/feed?linkurl=http%3A%2F%2Fwww.thelancet.com%2Frssfeed%2Flancet_online.xml&type=feed&linkname=The%20Lancet%20Online%20First&linknote=" lancet med) - ("https://www.propublica.org/feeds/propublica/main" probublica news) - ("http://tools.cdc.gov/podcasts/feed.asp?feedid=183" cdc med) - ("http://planet.lisp.org/rss20.xml" lisp planetlisp) - ("https://guix.gnu.org/feeds/blog.atom" guix) - ("https://protesilaos.com/master.xml" prot) - ("https://static.fsf.org/fsforg/rss/news.xml" gnu fsf) - ;; YouTube - ("https://www.youtube.com/feeds/videos.xml?channel_id=UCVls1GmFKf6WlTraIb_IaJg" - distrotube yt linux) - ("https://www.youtube.com/feeds/videos.xml?channel_id=UCld68syR8Wi-GY_n4CaoJGA" - brodie yt linux) - ("https://www.youtube.com/feeds/videos.xml?channel_id=UCAiiOTio8Yu69c3XnR7nQBQ" - systemcrafters yt linux) - ("https://www.youtube.com/feeds/videos.xml?channel_id=UC6QYFutt9cluQ3uSM963_KQ" - ninja yt med) - ("https://www.youtube.com/feeds/videos.xml?channel_id=UC1yNl2E66ZzKApQdRuTQ4tw" - sabine yt physics) - ("https://www.aartaka.me.eu.org/" - artyom blog lisp) - ("https://nyxt-browser.com/feed" - nyxt lisp))) - - (defun elfeed-mpv (&optional use-generic-p) - "Play video link with mpv." - (interactive "P") - (let ((entries (elfeed-search-selected))) - (cl-loop for entry in entries - do (elfeed-untag entry 'unread) - when (elfeed-entry-link entry) - do (start-process-shell-command "elfeed-video" nil (format "mpv \"%s\"" it))) - (mapc #'elfeed-search-update-entry entries) - (unless (use-region-p) (forward-line)))) - - :bind (("C-x f" . elfeed) - :map elfeed-search-mode-map - ("v" . 'elfeed-mpv) - ("U" . 'elfeed-update)) - :hook ((elfeed-searchacw-mode . (lambda () (display-line-numbers-mode 0))))) - ;; Python (add-to-list 'auto-mode-alist '("\\.py\\'" . python-ts-mode)) ;; Lisp -(use-package rainbow-delimiters - :vc (:url "https://github.com/Fanael/rainbow-delimiters") - :defer t - :hook ((emacs-lisp-mode . rainbow-delimiters-mode) - (lisp-mode . rainbow-delimiters-mode) - (clojure-mode . rainbow-delimiters-mode) - (scheme-mode . rainbow-delimiters-mode))) - (use-package sly :init (setf inferior-lisp-program "sbcl") :ensure t) @@ -648,38 +550,26 @@ rss.xml" anna piracy) "Edit current commit message" (interactive) (vc-checkin nil 'git nil nil nil "") - (vc-git-log-edit-toggle-amend))) + (vc-git-log-edit-toggle-amend)) -(use-package corfu - :ensure t - :config - (global-corfu-mode) - (corfu-popupinfo-mode) - (setf corfu-auto t - corfu-auto-delay 0.1 - corfu-auto-prefix 2 - corfu-cycle t - corfu-popupinfo-delay 0.3 - corfu-quit-at-boundary 'separator - corfu-quit-no-match t - corfu-preselect 'first - corfu-preview-current t - corfu-echo-mode t) - (setf indent-tabs-mode nil)) + (defun thanos/vc-git-branch () + "Select git branch" + (let ((branch (completing-read "Select branch: " (vc-git-branches) nil t))) + branch)) + + (defun vc-git-delete-branch () + "Select & delete git branch." + (interactive) + (let ((branch (thanos/vc-git-branch))) + (vc-git-command nil 0 nil "branch" "-D" branch) + (message "Branch `%s' deleted." branch))) + :bind (:map + vc-prefix-map + ("b d" . 'vc-git-delete-branch))) (when (or is-phone is-uranus) (use-package corfu-terminal)) -(use-package cape - ;; Press C-c p ? to for help. - :bind ("M-p" . cape-prefix-map) ;; Alternative keys: M-p, M-+, ... - :config - ;; (add-hook 'completion-at-point-functions #'cape-dabbrev) - (add-hook 'completion-at-point-functions #'cape-file) - ;; (add-hook 'completion-at-point-functions #'cape-elisp-block) - ;; (add-hook 'completion-at-point-functions #'cape-dict) - ) - (defun insert-brackets (&optional arg) "Insert ARG brackets." (interactive "P") @@ -688,14 +578,6 @@ rss.xml" anna piracy) (global-set-key (kbd "C-x M-[") 'insert-brackets) -(use-package orderless - :init (add-to-list 'completion-styles 'initials t) - :ensure t - :config - (setf completion-category-overrides '((file (style basic partial-completion))) - completion-styles '(orderless) - completion-cycle-threshold 2)) - (use-package pdf-tools :ensure nil :config @@ -712,41 +594,34 @@ rss.xml" anna piracy) :config (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))) -(use-package eshell-syntax-highlighting - :vc (:url "https://github.com/akreisher/eshell-syntax-highlighting") - :ensure t - :after eshell - :config - (eshell-syntax-highlighting-global-mode 1)) - -(use-package emojify - :ensure t - :hook (erc-mode . emojify-mode) - :commands emojify-mode) - -(use-package flycheck-package - :vc (:url "https://github.com/purcell/flycheck-package") - :ensure nil - :after flycheck) - (use-package flycheck :ensure t :config (setf flycheck-emacs-lisp-load-path 'inherit) - (global-flycheck-mode) - :hook ((emacs-lisp-mode . (lambda () (flycheck-mode) (flycheck-package-setup))))) + (global-flycheck-mode)) (use-package eat + :ensure t :config (setf eshell-visual-commands nil eat-term-name "xterm-256color") - :bind (("C-c v" . eat)) + :bind (("C-c V" . eat)) :hook ((eshell-mode . eat-eshell-mode) - (eshell-mode . eat-eshell-visual-command-mode))) + (eshell-mode . eat-eshell-visual-command-mode) + (eat-mode . (lambda () (visual-line-mode -1))))) (use-package shell - :defer t - :bind (("C-c V" . shell) + :ensure t + :config + (defun thanos/shell (n) + "Create or switch to a shell buffer." + (interactive "P") + (let* ((num (if n (prefix-numeric-value n) nil)) + (buf-name (if num + (format "*shell<%d>*" num) + "*shell*"))) + (shell buf-name))) + :bind (("C-c v" . thanos/shell) :map shell-mode-map ("C-l" . 'comint-clear-buffer)) :hook ((shell-mode . (lambda () (display-line-numbers-mode -1))))) @@ -769,50 +644,49 @@ rss.xml" anna piracy) (interactive) (eshell/clear-scrollback)) -(use-package eshell +(defun thanos/eshell-preview-insert () + (interactive) + (completion-preview-insert) + (delete-char -1)) + +(use-package esh-mode + :ensure nil :config - (setf eshell-highlight-prompt t) + (defun eshell/git-info () + "Return a string with Git information if in a Git repository, or nil otherwise." + (when (eq (call-process "git" nil nil nil "rev-parse" "--is-inside-work-tree") 0) + (let* ((branch (string-trim (shell-command-to-string "git rev-parse --abbrev-ref HEAD"))) + (dirty (not (string= "" (string-trim (shell-command-to-string "git status --porcelain"))))) + (branch-info (if (string= branch "HEAD") "" branch)) + (dirty-info (if dirty " ✎" " ✔"))) + (concat (propertize "⎇ " 'face 'modus-themes-fg-green-warmer) + (propertize branch-info 'face 'modus-themes-fg-magenta-warmer) + (propertize dirty-info 'face (if dirty 'modus-themes-fg-red 'modus-themes-fg-green)))))) + + (defun eshell-prompt-multiline () + "Eshell Git prompt inspired by spaceship-prompt." + (let ((separator (propertize " | " 'face 'font-lock-comment-face)) + (hr (propertize (concat "\n" (make-string (/ (window-total-width) 2) ?─) "\n") 'face 'font-lock-comment-face)) + (dir (propertize (format "%s" (abbreviate-file-name (eshell/pwd))) 'face 'modus-themes-fg-yellow-warmer)) + (git-info (eshell/git-info)) + (time (propertize (format-time-string "%H:%M:%S") 'face 'font-lock-comment-face)) + (sign (if (= (user-uid) 0) + (propertize "\n#" 'face 'modus-themes-fg-blue-intense) + (propertize "\nλ" 'face 'modus-themes-fg-red-warmer)))) + ;; Build prompt + (concat hr dir separator git-info separator time sign " "))) + + (setf eshell-prompt-function 'eshell-prompt-multiline + eshell-highlight-prompt nil) :bind (("C-c e" . eshell) :map eshell-mode-map - ("C-l" . 'thanos/eshell-clear)) + ("C-l" . 'thanos/eshell-clear) + ("<tab>" . 'thanos/eshell-preview-insert) + ("C-M-i" . 'completion-at-point)) :hook ((eshell-mode . (lambda () (thanos/set-eshell-aliases thanos/aliases) - (display-line-numbers-mode -1))))) - -(use-package eshell-git-prompt - :vc (:url "https://github.com/xuchunyang/eshell-git-prompt") - :ensure t - :config - (defun eshell-git-prompt-multiline () - "Eshell Git prompt inspired by spaceship-prompt." - (let (separator hr dir git git-dirty time sign command) - (setq separator (with-face " | " 'eshell-git-prompt-multiline-secondary-face)) - (setq hr (with-face (concat "\n" (make-string (/ (window-total-width) 2) ?─) "\n") 'eshell-git-prompt-multiline-secondary-face)) - (setq dir - (concat - (with-face "" 'eshell-git-prompt-directory-face) - (concat (abbreviate-file-name (eshell/pwd))))) - (setq git - (concat (with-face "⎇" 'eshell-git-prompt-exit-success-face) - (concat (eshell-git-prompt--branch-name)))) - (setq git-dirty - (when (eshell-git-prompt--branch-name) - (if (eshell-git-prompt--collect-status) - (with-face " ✎" 'eshell-git-prompt-modified-face) - (with-face " ✔" 'eshell-git-prompt-exit-success-face)))) - (setq time (with-face (format-time-string "%I:%M:%S %p") - 'eshell-git-prompt-multiline-secondary-face)) - (setq sign - (if (= (user-uid) 0) - (with-face "\n#" 'eshell-git-prompt-multiline-sign-face) - (with-face "\nλ" 'eshell-git-prompt-multiline-sign-face))) - (setq command (with-face " " 'eshell-git-prompt-multiline-command-face)) - - ;; Build prompt - (eshell-git-prompt---str-read-only - (concat hr dir separator git git-dirty separator time sign command)))) - - (eshell-git-prompt-use-theme 'multiline)) + (display-line-numbers-mode -1) + (eshell-cmpl-mode -1))))) ;; Password-store (use-package password-store @@ -852,27 +726,11 @@ rss.xml" anna piracy) :map erc-mode-map ("C-c RET" . 'erc-cmd-QUERY))) -(use-package transmission - :vc (:url "https://github.com/holomorph/transmission") - :defer t) - (use-package sudo-edit - :vc (:url "https://github.com/nflath/sudo-edit") :ensure t :config (setf sudo-edit-local-method "sudo")) -(use-package dabbrev - :defer t - :config - (setf dabbrev-ignored-buffer-regexps '("\\.\\(?:pdf\\|jpe?g\\|png\\)\\'"))) - -(use-package xref - :defer t - :config - (setf xref-show-xrefs-function #'consult-xref - xref-show-definitions-function #'consult-xref)) - ;; My packages (when (or is-zeus is-hermes) (use-package yeetube @@ -941,7 +799,6 @@ rss.xml" anna piracy) ("k" . 'yeetube-remove-saved-video))) (use-package gnosis - :vc t :load-path "~/Dev/emacs-lisp/gnosis" :ensure t :init (define-prefix-command 'thanos/gnosis-map) @@ -951,25 +808,166 @@ rss.xml" anna piracy) gnosis-image-width (and is-hermes 150) gnosis-image-height (and is-hermes 150)) (gnosis-modeline-mode) - (setf gnosis-custom-values '((:deck "Bulgarian" (:amnesia 0.55 :proto (0 1 3))) - (:deck "Unking" (:amnesia 0.45)) - (:tag "vocabulary" (:amnesia 0.65 :proto (0 1 3))))) - :bind (("C-M-r" . 'gnosis-dashboard) - ("C-c c" . 'gnosis-add-note))) + (setf gnosis-custom-values + '((:deck "Bulgarian" (:amnesia 0.55 :proto (0 1 3))) + (:deck "Unking" (:amnesia 0.45)) + (:tag "vocabulary" (:amnesia 0.65 :proto (0 1 3))))) + :bind (("C-c SPC" . 'thanos/gnosis-map) + :map thanos/gnosis-map + ("a" . 'gnosis-add-note) + ("d" . 'gnosis-dashboard))) ;; Sync gnosis on startup (gnosis-vc-pull) + (use-package org-gnosis + :load-path "~/Dev/emacs-lisp/org-gnosis" + :init + (define-prefix-command 'thanos/notes-map) + (define-prefix-command 'thanos/journal-map) + :config + (setf org-gnosis-dir "~/Notes" + org-gnosis-journal-templates + '(("Default" + "* Daily Notes\n\n* Goals\n+ [] Πρωινὴ Προσευχή\n+ [] Ἑσπερινή Προσευχή\n\n* Extras")) + org-gnosis-show-tags t) + + (defun thanos/org-open-at-point () + "Open Org link at point in the same window, if possible." + (interactive) + (let ((org-link-frame-setup '((file . find-file)))) + (org-open-at-point))) + + :bind (("C-c n" . thanos/notes-map) + ("C-c j" . thanos/journal-map) + :map thanos/notes-map + ("f" . org-gnosis-find) + ("i" . org-gnosis-insert) + ("t" . org-gnosis-find-by-tag) + :map thanos/journal-map + ("j" . org-gnosis-journal) + ("f" . org-gnosis-journal-find) + ("i" . org-gnosis-journal-insert) + :map org-mode-map + ("C-c C-." . org-gnosis-insert-tag) + ("C-c i" . org-id-get-create) + ("C-c C-o" . thanos/org-open-at-point))) + + (use-package org-gnosis-ui + :load-path "~/Dev/emacs-lisp/org-roam-ui/" + :after org-gnosis + :config + (setf org-gnosis-ui-custom-theme + '((bg . "#1e1e1e") + (bg-alt . "#282a36") + (fg . "#ffffff") + (fg-alt . "#c6daff") + (red . "#ff5f5f") + (orange . "#f1fa8c") + (yellow . "#efef00") + (green . "#44df44") + (cyan . "#00eff0") + (blue . "#338fff") + (violet . "#9099d9") ;; indigo + (magenta . "#ff66ff")))) + (use-package pcmpl-tailscale :vc t :load-path "~/Dev/emacs-lisp/pcmpl-tailscale" - :ensure nil)) + :ensure nil) -;; Emacs dev + (use-package greek-polytonic + :vc t + :ensure t + :load-path "~/Dev/emacs-lisp/greek-polytonic")) -(use-package package-lint + +(use-package elfeed + :defer t + :vc (:url "https://github.com/skeeto/elfeed") + :config + (setf elfeed-search-filter "@1-week-ago +unread" + browse-url-browser-function #'browse-url-default-browser + elfeed-db-directory "~/.config/elfeed") + ;; Feeds + (setf elfeed-feeds + '(("https://hackaday.com/blog/feed/" + hackaday linux) + ("https://thanosapollo.org/index.xml" + thanos) + ("http://wikileaks.org/feed" + wikileaks) + ("https://hackernoon.com/feed" + hackernoon) + ("https://torrentfreak.com/feed" + torrentfreak piracy) + ("https://www.science.org/action/showFeed?type=etoc&feed=rss&jc=sciimmunol" + science) + ("http://localhost/?action=display&bridge=CssSelectorBridge&home_page=https%3A%2F%2Fwww.medscape.com%2Findex%2Flist_13470_0&url_selector=a.title&url_pattern=viewarticle%2F.*&content_selector=div.article__main-content&content_cleanup=&title_cleanup=+-+Index&limit=&format=Atom" medscape med) + ("http://localhost/?action=display&bridge=CssSelectorBridge&home_page=https%3A%2F%2Fwww.tovima.gr%2Flatest-news%2F&url_selector=a.columns&url_pattern=&content_selector=div.main-content&content_cleanup=div.wrap-facebook%2Cdiv.googlenews&title_cleanup=&limit=&format=Atom" tovima greek news) + ("http://localhost/?action=display&bridge=CssSelectorBridge&home_page=https%3A%2F%2Fwww.estianews.gr%2Feidiseis-arthra%2F&url_selector=h3.entry-title&url_pattern=&content_selector=div.col-lg-8&content_cleanup=&title_cleanup=&limit=&format=Atom" estia greek news) + ("http://localhost/?action=display&bridge=CssSelectorBridge&home_page=https%3A%2F%2Fwww.estianews.gr%2Fkentriko-thema%2F&url_selector=h3.entry-title&url_pattern=&content_selector=div.col-md-8&content_cleanup=&title_cleanup=&limit=&format=Atom" estia greek kyrio) + ("http://localhost/?action=display&bridge=CssSelectorBridge&home_page=https%3A%2F%2Fwww.estianews.gr%2Fapopseis%2F&url_selector=h3.entry-title&url_pattern=&content_selector=div.col-lg-8&content_cleanup=&title_cleanup=&limit=&format=Atom" estia greek opinions) + ("http://localhost/?action=display&bridge=CssSelectorBridge&home_page=https%3A%2F%2Fwww.reuters.com%2Fbusiness%2Fhealthcare-pharmaceuticals%2F&url_selector=a.basic-card__title__37xHl&url_pattern=&content_selector=div.article-body__wrapper__3IxHM&content_cleanup=svg.link__new-tab-symbol__3T19s%2C+div.toolbar__container__3kIkw%2C+div.article-body__row__dFOPA+article-body__element__2p5pI&title_cleanup=&limit=&format=Atom" reuters med news) + ("http://localhost/?action=display&bridge=CssSelectorBridge&home_page=https%3A%2F%2Fwww.reuters.com%2Ftechnology%2Fcybersecurity%2F&url_selector=a.media-story-card__headline__tFMEu%2C+a.media-story-card__heading__eqhp9&url_pattern=&content_selector=article.article__container__2MUeZ&content_cleanup=div.info-content__toolbar__3AkHm%2C+svg.link__new-tab-symbol__3T19s%2C+div.article-body__row__dFOPA%2C+div.read-next-tablet-up__container__3MpHN%2C+div.author-bio__multiple-authors__5YGrG%2C+div.article__read-next__Kjxdw&title_cleanup=&limit=&format=Atom" reuters cybersec news) + ("https://annas-blog.org/ +rss.xml" anna piracy) + ("http://localhost/?action=display&bridge=CssSelectorBridge&home_page=https%3A%2F%2Fwww.ethnos.gr%2Ftag%2F842%2Fellhnotoyrkika&url_selector=a.single-title&url_pattern=&content_selector=div.content-section&content_cleanup=div.article-related-posts%2C+div.ReadMore%2C+script&title_cleanup=&limit=&format=Atom" greek ethnos ellinotourkika) + ("https://planet.emacslife.com/atom.xml" emacs emacslife) + ("https://localmonero.co/static/rss/the-monero-standard/feed.xml" monero) + ("https://devonzuegel.com/feed" devon) + ("https://www.addtoany.com/add_to/feed?linkurl=http%3A%2F%2Fwww.thelancet.com%2Frssfeed%2Flancet_online.xml&type=feed&linkname=The%20Lancet%20Online%20First&linknote=" lancet med) + ("https://www.propublica.org/feeds/propublica/main" probublica news) + ("http://tools.cdc.gov/podcasts/feed.asp?feedid=183" cdc med) + ("http://planet.lisp.org/rss20.xml" lisp planetlisp) + ("https://guix.gnu.org/feeds/blog.atom" guix) + ("https://protesilaos.com/master.xml" prot) + ("https://static.fsf.org/fsforg/rss/news.xml" gnu fsf) + ;; YouTube + ("https://www.youtube.com/feeds/videos.xml?channel_id=UCVls1GmFKf6WlTraIb_IaJg" + distrotube yt linux) + ("https://www.youtube.com/feeds/videos.xml?channel_id=UCld68syR8Wi-GY_n4CaoJGA" + brodie yt linux) + ("https://www.youtube.com/feeds/videos.xml?channel_id=UCAiiOTio8Yu69c3XnR7nQBQ" + systemcrafters yt linux) + ("https://www.youtube.com/feeds/videos.xml?channel_id=UC6QYFutt9cluQ3uSM963_KQ" + ninja yt med) + ("https://www.youtube.com/feeds/videos.xml?channel_id=UC1yNl2E66ZzKApQdRuTQ4tw" + sabine yt physics) + ("https://www.aartaka.me.eu.org/" + artyom blog lisp) + ("https://nyxt-browser.com/feed" + nyxt lisp))) + + (defun elfeed-mpv (&optional use-generic-p) + "Play video link with mpv." + (interactive "P") + (let ((entries (elfeed-search-selected))) + (cl-loop for entry in entries + do (elfeed-untag entry 'unread) + when (elfeed-entry-link entry) + do (start-process-shell-command "elfeed-video" nil (format "mpv \"%s\"" it))) + (mapc #'elfeed-search-update-entry entries) + (unless (use-region-p) (forward-line)))) + + :bind (("C-x f" . elfeed) + :map elfeed-search-mode-map + ("v" . 'elfeed-mpv) + ("U" . 'elfeed-update)) + :hook ((elfeed-searchacw-mode . (lambda () (display-line-numbers-mode 0))))) + +(use-package transmission + :vc (:url "https://github.com/holomorph/transmission") :defer t) +(use-package rainbow-delimiters + :vc (:url "https://github.com/Fanael/rainbow-delimiters") + :ensure t + :hook ((emacs-lisp-mode . rainbow-delimiters-mode) + (lisp-mode . rainbow-delimiters-mode) + (clojure-mode . rainbow-delimiters-mode) + (scheme-mode . rainbow-delimiters-mode))) + ;; AI tools (use-package gptel :ensure t @@ -977,7 +975,7 @@ rss.xml" anna piracy) (setf gptel-api-key (password-store-get-field "openai/[email protected]" "api") gptel-default-mode 'org-mode gptel-directives '((default . "You are a large language model living in Emacs and a helpful assistant. Respond concisely.") - (programming . "You are a large language model and a careful programmer. Provide code and only code as output without any additional text, prompt or note.") + (programming . "You are a large language model and an expert emacs lisp hacker. Provide code and only code as output without any additional text, prompt or note.") (epictetus . "You are Epictetus, the stoic philosopher from Nicopolis. Respond concisely as Epictetus.") (med . "You are a medical professor. Respond concisely to your student in bullet points.") (code-review . "You are an expert programmer within Emacs reviewing code. Respond concisely") @@ -989,7 +987,12 @@ rss.xml" anna piracy) :host (if is-zeus "localhost:11434" "zeus:11434") :stream t :models '("llama3.2:latest" "dolphin-phi" "dolphin-llama3:latest"))) - :bind (("C-c g" . 'gptel-send) + + (gptel-make-anthropic "Claude" + :stream t + :key (password-store-get "claude/api1")) + + :bind (("C-c G" . 'gptel-send) :map gptel-mode-map ("C-c h" . 'gptel-menu))) @@ -1070,27 +1073,27 @@ rss.xml" anna piracy) smtpmail-smtp-service 465 smtpmail-stream-type 'ssl message-send-mail-function 'smtpmail-send-it - message-signature "Thanos Apollo\nhttps://thanosapollo.org") + message-signature "Thanos Apollo ☧\nhttps://thanosapollo.org") ;; autosign messages (add-hook 'message-send-hook 'mml-secure-message-sign-pgpmime) + ;; (use-package yasnippet ;; :ensure nil ;; :config ;; (when is-zeus (add-to-list 'yas-snippet-dirs "~/Dev/guile/guix/etc/snippets/yas"))) (use-package emms - :defer t + :ensure t :init (define-prefix-command 'thanos/emms) :config (with-eval-after-load 'emms (emms-all) - (setq emms-source-file-default-directory "/hdd/Music" + (setf emms-source-file-default-directory "/hdd/Music" emms-info-asynchronously t emms-show-format "♪ %s" - emms-info-functions) - (emms-info-exiftool) + emms-player-list '(emms-player-mpv)) (add-to-list 'emms-info-functions 'emms-info-native)) (setf emms-player-mpv-parameters '("--quiet" "--really-quiet" "--no-audio-display" "--no-video")) @@ -1118,7 +1121,7 @@ rss.xml" anna piracy) (add-hook 'gnus-article-mode-hook #'bug-reference-mode) ;; Change the default when run as 'M-x debbugs-gnu'. - (setq debbugs-gnu-default-packages '("emacs")) + (setq debbugs-gnu-default-packages '("emacs" "guix")) ;; Show feature requests. (setq debbugs-gnu-default-severities @@ -1141,17 +1144,20 @@ rss.xml" anna piracy) (defun vm-run () - "Spawn Virtual Machine." + "Spawn Virtual Machine with UEFI support." (interactive) (let ((memory (format "%sG" (read-string "Memory(G): "))) - (cores (read-string "Cores: ")) - (image (read-file-name "Image: " vm-directory)) - (iso (if (y-or-n-p "Load iso? ") - (read-file-name "ISO: ") - nil))) + (cores (read-string "Cores: ")) + (image (read-file-name "Image: " vm-directory)) + (iso (if (y-or-n-p "Load iso? ") + (read-file-name "ISO: ") + nil)) + (ovmf-path (string-trim + (shell-command-to-string + "echo $(guix build ovmf-x86-64)/share/firmware/ovmf_x64.bin")))) (async-shell-command (format "qemu-system-x86_64 -enable-kvm -m %s -smp %s -hda %s -vga virtio -device virtio-serial-pci -netdev user,id=vmnic,hostfwd=tcp::2222-:22 -device e1000,netdev=vmnic %s" - memory cores image (if iso (concat "-cdrom " iso) ""))))) + memory cores image (if iso (concat "-cdrom " iso) ""))))) (use-package 0x0 :ensure nil) @@ -1225,7 +1231,8 @@ Create a temporary frame to execute BODY, which will then be deleted." "Set random wallpaper." (interactive) (let ((wallpapers (directory-files "~/wallpapers" nil "^[^.].*"))) - (thanos/wallpaper-set (format "%s%s" wallpapers-dir (nth (random (length wallpapers)) wallpapers))))) + (thanos/wallpaper-set + (format "%s%s" wallpapers-dir (nth (random (length wallpapers)) wallpapers))))) (defun thanos/wallpaper-select () "Set wallpaper." @@ -1345,10 +1352,6 @@ Create a temporary frame to execute BODY, which will then be deleted." (insert (format "%s" (+ i str))) (org-table-hline-and-move))) -(use-package greek-polytonic - :vc t - :load-path "~/Dev/emacs-lisp/greek-polytonic") - (require 'server) (unless (server-running-p) (server-start)) |