From 5896fdd4d91e83a5d0cd5ba54ae96ebb4eaec0e7 Mon Sep 17 00:00:00 2001 From: Thanos Apollo Date: Tue, 23 Jan 2024 04:39:37 +0200 Subject: emacs: Rewrite with use-package --- .emacs.d/init.el | 775 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 762 insertions(+), 13 deletions(-) diff --git a/.emacs.d/init.el b/.emacs.d/init.el index b40a7b0..1ea9b24 100644 --- a/.emacs.d/init.el +++ b/.emacs.d/init.el @@ -50,19 +50,768 @@ (setf disabled-command-function nil ;; Enable all commands url-privacy-level 'high) ;; Privacy level -(require 'thanos-packages) ;; List packages and install them -(require 'thanos-shells) ;; vterm, eshell, eat configuration -(require 'thanos-aesthetics) ;; minibuffer and theming configuration -(require 'thanos-org) ;; org-roam, agenda, theming etc -(require 'thanos-pass) ;; password-store -(require 'thanos-commands) ;; Misc commands to manage vm's and others -(require 'thanos-books) ;; pdf-tools, nov-mode -(require 'thanos-chat) ;; telega, erc, ement -(require 'thanos-tools) ;; Completions, programming lang specific customization, chatgpt etc. -(require 'thanos-dired) ;; Dired theming and custom functions +(defun thanos/imenu-use-package () + "Add `use-package' to imenu." + (add-to-list 'imenu-generic-expression + `(,(propertize "Package " 'face 'font-lock-keyword-face) + "\\(^\\s-*(use-package +\\)\\(\\_<.+\\_>\\)" 2))) + +(add-hook 'emacs-lisp-mode-hook #'thanos/imenu-use-package) + +(setf consult-imenu-config + '((emacs-lisp-mode :toplevel "Functions" + :types ((?f "Functions" font-lock-function-name-face) + (?m "Macros" font-lock-function-name-face) + (?p "Packages" font-lock-constant-face) + (?t "Types" font-lock-type-face) + (?v "Variables" font-lock-variable-name-face) + (?p "Package:" font-lock-keyword-face))))) + +;; Set and load custom.el +(setf custom-file (locate-user-emacs-file "custom.el")) +(load custom-file 'noerror) + +;; Install straight.el + +(defvar bootstrap-version) + +(let ((bootstrap-file + (expand-file-name + "straight/repos/straight.el/bootstrap.el" + (or (bound-and-true-p straight-base-dir) + user-emacs-directory))) + (bootstrap-version 7)) + (unless (file-exists-p bootstrap-file) + (with-current-buffer + (url-retrieve-synchronously + "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el" + 'silent 'inhibit-cookies) + (goto-char (point-max)) + (eval-print-last-sexp))) + (load bootstrap-file nil 'nomessage)) + +(setq package-enable-at-startup nil) + +(require 'straight) + +(setf straight-use-package-by-default t) + +(setf straight-recipe-overrides + '((transmission :type git :host nil :repo "git@thanosapollo.org:/var/git/transmission") + (yeetube :type git :host nil :repo "git@thanosapollo.org:/var/git/yeetube"))) + +(defvar thanos/custom-packages + '((yeetube :local-repo "~/Dev/emacs-lisp/yeetube") + (gnosis :local-repo "~/Dev/emacs-lisp/gnosis") + (copilot :host github :repo "zerolfx/copilot.el" :files ("dist" "*.el"))) + "Custom package recipes.") + +(defun theme-invisible-dividers (_theme) + "Make window dividers for THEME invisible." + (let ((bg (face-background 'default))) + (custom-set-faces + `(fringe ((t :background ,bg :foreground ,bg))) + `(window-divider ((t :background ,bg :foreground ,bg))) + `(window-divider-first-pixel ((t :background ,bg :foreground ,bg))) + `(window-divider-last-pixel ((t :background ,bg :foreground ,bg)))))) + +(add-hook 'enable-theme-functions #'theme-invisible-dividers) + +;;;; Theming ;;;; + +(setf inhibit-startup-message t + initial-scratch-message nil) + +(blink-cursor-mode -1) +(menu-bar--visual-line-mode-enable) +(global-visual-line-mode 1) + +(setf visible-bell t) + +(column-number-mode) +(global-display-line-numbers-mode 1) +(menu-bar--display-line-numbers-mode-relative) + +;; Transparency +(add-to-list 'default-frame-alist '(alpha-background . 90)) + +(when (equal is-phone nil) + (scroll-bar-mode -1) + (set-fringe-mode 10)) + +(tool-bar-mode -1) +(tooltip-mode -1) +(menu-bar-mode -1) +(global-hl-line-mode) + +(use-package modus-themes + :straight t + :config + (setf modus-themes-italic-constructs t + modus-themes-bold-constructs nil + modus-themes-mixed-fonts nil + modus-themes-variable-pitch-ui nil + modus-themes-custom-auto-reload t + modus-themes-disable-other-themes t + modus-themes-prompts '(italic bold) + modus-themes-completions '((matches . (extrabold)) + (selection . (semibold italic text-also underline))) + modus-themes-org-blocks 'tinted-background) + ;; Palette overrides + (setf modus-themes-common-palette-overrides + '((fg-line-number-inactive "gray40") + (fg-line-number-active cyan-intense) + (bg-main "#171717") + ;; (overline-heading-1 gold) + (fg-heading-1 red-warmer) + ;; (bg-heading-1 bg-blue-nuanced) + (bg-line-number-inactive unspecified) + (bg-line-number-active unspecified) + (bg-paren-match bg-magenta-intense) + (underline-paren-match fg-main) + (underline-err red-intense) + (underline-warning yellow-faint) + (underline-note cyan-faint) + (string "#86B187") + (border-mode-line-active unspecified) + (border-mode-line-inactive unspecified) + (bg-mode-line-active "#2f2f2f") + (bg-mode-line-inactive "1D1D1D") + ;; set fg from badger theme + (fg-mode-line-active "#F6F3E8") + (bg-hl-line bg-dim) + (cursor slate) + (fg-prompt yellow-faint) + ,@modus-themes-preset-overrides-intense)) + ;; Headings + (setf modus-themes-headings + '((1 . (ultrabold 1.35)) + (2 . (semibold 1.2)) + (agenda-date . (1.3)) + (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 nerd-icons-completion + :ensure t + :config + (nerd-icons-completion-marginalia-setup) + (nerd-icons-completion-mode)) + +(use-package marginalia + :defer t + :hook (marginalia-mode . nerd-icons-completion-mode) + :config + (marginalia-mode)) + +(use-package nerd-icons-ibuffer + :defer t + :hook ((ibuffer-mod))) + +(use-package consult + :defer t + :bind (("C-x b" . 'consult-buffer) + ("C-c m" . 'consult-imenu))) + +(use-package org + :defer t + :config + (setf org-directory "~/org/" + org-agenda-files '("~/org/agenda.org") + org-default-notes-file (expand-file-name "notes.org" org-directory) + org-ellipsis " ▼ " + org-log-done 'time + org-hide-emphasis-markers nil ;;change to t to hide emphasis markers + org-table-convert-region-max-lines 20000 + org-log-done 'time + org-todo-keywords '((sequence "TODO(t)" "SEMINAR(s)" "LECTURE(l)" "DONE(d)"))) + + (defadvice org-edit-src-code (around set-buffer-file-name activate compile) + (let ((file-name (buffer-file-name))) + ad-do-it + (setf buffer-file-name file-name))) + + (org-babel-do-load-languages + 'org-babel-load-languages + '((emacs-lisp . t) + (python . t))) + + (setf org-structure-template-alist + '(("e" . "src emacs-lisp") + ("p" . "src python") + ("l" . "src lisp") + ("b" . "src bash") + ("q" . "QUOTE"))) + :hook ((org-mode . org-auto-tangle-mode) + (org-mode . (lambda () (display-line-numbers-mode -1))))) + +(defun org-insert-book () + "Insert org-link from ~/Library for book." + (interactive) + (let* ((book-path (read-file-name "Book: " "~/Library/"))) + (org-insert-link nil book-path (file-name-base book-path)))) + +(use-package org-modern + :ensure t + :config + (global-org-modern-mode) + (setf org-modern-table nil) + (setf org-modern-todo nil)) + +;; Create notes directory for org-roam +(unless (file-exists-p "~/Notes") + (make-directory "~/Notes")) + +(use-package org-roam + :defer t + :init + (define-prefix-command 'thanos/notes-map) + :config + (setf org-roam-directory "~/Notes") + (org-roam-db-autosync-enable) + + (setf org-roam-node-display-template + (concat "${title:50} "(propertize "${tags:30}" 'face 'org-tag))) + + (setf org-roam-db-node-include-function + (lambda () + (not (or (member "journal" (org-get-tags)) + (member "memorize" (org-get-tags)))))) + ;; Templaes + (setf org-roam-capture-templates + '(("d" "default" plain + "%?" + :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n") + :unnarrowed t) + ("l" "programming language" plain + "* Characteristics\n\n- Family: %?\n- Inspired by: \n\n* Reference:\n\n" + :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\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))) + :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) + :map org-mode-map + ("C-c C-." . org-roam-tag-add) + ("C-c i" . org-id-get-create))) + +(use-package which-key + :defer t + :config + (which-key-mode 1)) + +(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)))) + +(use-package elfeed + :defer t + :config + (setf elfeed-search-filter "@1-week-ago +unread" + browse-url-browser-function #'browse-url-default-browser) + ;; Feeds + (setf elfeed-feeds + '(("https://hackaday.com/blog/feed/" + hackaday linux) + ("https://protesilaos.com/news.xml" + protesilaos) + ("https://protesilaos.com/codelog.xml" + proetesilaos) + ("https://guix.gnu.org/feeds/blog.atom" + gnu guix) + ("https://thanosapollo.com/posts/index.xml" + thanos) + ("http://nullprogram.com/feed/" + emacs linux) + ("https://drewdevault.com/blog/index.xml" + sourcehut drewdevault) + ("https://archlinux.org/feeds/news/" + ArchLinux Latest) + ("http://wikileaks.org/feed" + wikileaks) + ("https://hackernoon.com/feed" + hackernoon) + ("https://sachachua.com/blog/feed/" + sacha emacs) + ("https://bits.debian.org/feeds/feed.rss" + debian linux) + ("https://torrentfreak.com/feed" + torrentfreak piracy) + ("https://wp.medscape.com/cx/rssfeeds/2700.xml" + med medscape) + ("https://www.science.org/action/showFeed?type=etoc&feed=rss&jc=sciimmunol" + science) + ("https://www.who.int/rss-feeds/news-english.xml" + who medicine) + ("https://annas-blog.org/rss.xml" + anna piracy) + ("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 medicine) + ("https://www.addtoany.com/add_to/feed?linkurl=http%3A%2F%2Fwww.thelancet.com%2Frssfeed%2Flanhae_online.xml&type=feed&linkname=The%20Lancet%20Haematology%20Online%20First&linknote=" + lancet haematology medicine) + ("https://totsipaki.net/ikiwiki/nparafe/%CE%9C%CF%80%CE%BB%CE%BF%CE%B3%CE%BA/index.rss" + nikos fsf))) + :bind (("C-c a f" . elfeed) + :map elfeed-search-mode-map + ("v" . 'elfeed-mpv) + ("U" . 'elfeed-update))) + +(use-package elfeed-goodies + :defer t + :config + (setf elfeed-goodies/entry-pane-size 0.55) + (elfeed-goodies/setup)) + +(use-package python-mode + :defer t + :config + (add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode))) + +(use-package emms + :defer t + :config + (with-eval-after-load 'emms + (emms-all) + (setq emms-source-file-default-directory "~/Music" + emms-info-asynchronously t + emms-show-format "♪ %s") + (emms-default-players)) + (setf emms-player-mpv-parameters nil) + :bind (:map emms-playlist-mode-map + (("A" . 'emms-add-directory-tree)))) + +(use-package rainbow-delimiters + :defer t + :init (add-hook 'emacs-lisp-mode-hook 'prettify-symbols-mode) + :hook ((emacs-lisp-mode . rainbow-delimiters-mode) + (lisp-mode . rainbow-delimiters-mode) + (scheme-mode . rainbow-delimiters-mode))) + +(use-package helpful + :defer t + :bind (("C-h f" . 'helpful-callable) + ("C-h v" . 'helpful-variable) + ("C-h k" . 'helpful-key) + ("C-h x" . 'helpful-command) + ("C-h ." . 'helpful-at-point) + ("C-h F" . 'helpful-function))) + +(use-package password-store + :defer t) + +(use-package ox-hugo + :defer t) + +(use-package json-mode + :defer t + :config + (add-to-list 'auto-mode-alist '("\\.json'" . json-mode))) + +(defun project-magit () + "Run magit-status in the current project's root." + (interactive) + (magit-status-setup-buffer (project-root (project-current t)))) + +(use-package magit + :defer t + :config + (setf magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1) + :bind (:map project-prefix-map + ("g" . 'project-magit))) + +(use-package corfu + :ensure t + :init (define-prefix-command 'thanos/search) + :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) + :bind (("C-x r d" . 'bookmark-delete) + ("C-x r C-r" . 'bookmark-rename) + ("C-x r ." . 'consult-register) + ("C-x r s" . 'consult-register-store) + ("C-x r b" . 'consult-bookmark) + ("M-y" . 'consult-yank-from-kill-ring) + ("C-s" . 'thanos/search) + :map thanos/search + ("f" . 'isearch-forward) + ("b" . 'isearch-backward) + ("s" . 'consult-line) + ("C-f" . 'consult-find) + ("C-g" . 'consult-grep) + ("C-i" . 'consult-info) + ("C-l" . 'consult-locate) + :map project-prefix-map + ("b" . 'consult-project-buffer))) + +(defun insert-brackets (&optional arg) + "Insert ARG brackets." + (interactive "P") + (insert-pair arg ?\[ ?\])) + +(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 + :defer t + :config + (pdf-tools-install) + (add-to-list 'auto-mode-alist '("\\.pdf\\'" . 'pdf-view-mode)) + :hook ((pdf-view-mode . 'pdf-isearch-minor-mode) + (pdf-view-mode . 'pdf-view-midnight-minor-mode))) + +(use-package markdown-mode + :defer t + :config + (setq markdown-header-scaling t + markdown-command "multimarkdown") + (add-to-list 'auto-mode-alist '("\\.md\\'" . gfm-mode))) + +(use-package eat + :defer t) + +(use-package org-auto-tangle + :defer t) + +(use-package sly + :init (setf inferior-lisp-program "sbcl") + :defer) + +(use-package eat + :defer t) + +(use-package nov + :defer t + :config + (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))) + +(use-package eshell-syntax-highlighting + :defer t) + +(use-package emojify + :defer t + :config + (global-emojify-mode) + (global-emojify-mode-line-mode)) + +(use-package flycheck + :defer t + :config + (setf flycheck-emacs-lisp-load-path 'inherit) + :hook ((org-src-mode . (lambda () (flycheck-disable-checker 'emacs-lisp-checkdoc))))) + +;; Shells +(use-package vterm + :defer t + :bind (("C-c v" . vterm) + :map vterm-mode-map + ("M-&" . 'async-shell-command)) + :hook ((vterm-mode . (lambda () (display-line-numbers-mode -1))))) + +(defvar thanos/aliases + '((g . magit) + (gl . magit-log) + (gc . magit-clone) + (d . dired) + (o . find-file) + (oo . find-file-other-window) + (ll . (lambda () (eshell/ls '-lha))) + (eshell/clear . eshell/clear-scrollback))) + +(defun thanos/set-eshell-aliases (aliases) + "Set ALIASES as eshell aliases." + (mapc (lambda (alias) + (defalias (car alias) (cdr alias))) + aliases)) + +(use-package eshell + :config + (setf eshell-highlight-prompt t) + (eshell-syntax-highlighting-global-mode 1) + :bind (("C-c e" . eshell)) + :hook ((eshell-mode . (lambda () + (hl-line-mode 'toggle) + (thanos/set-eshell-aliases thanos/aliases) + (display-line-numbers-mode -1))))) + +(use-package eshell-git-prompt + :ensure t + :config + (eshell-git-prompt-use-theme 'multiline)) + +;; Chat +(use-package telega + :defer t + :hook ((telega-root-mode . (lambda () emojify-mode + (display-line-numbers-mode -1))) + (telega-chat-mode . emojify-mode))) + +(use-package erc + :defer t + :config + (setf erc-modules + '(sasl netsplit fill button match track completion readonly + networks ring autojoin noncommands irccontrols move-to-prompt stamp + menu list))) + +(defun erc-libera () + "Login to liberachat with erc." + (interactive) + (erc-tls :server "irc.libera.chat" :port 6697 + :nick "thanosapollo" + :user "thanosapollo" + :password (password-store-get "liberachat/thanos_apollo"))) + +(use-package transmission + :defer t + :straight (transmission :type git :host nil :repo "git@thanosapollo.org:/var/git/transmission")) + +(use-package nerd-icons-dired + :defer t + :hook ((dired-mode . nerd-icons-dired-mode))) + +(use-package sudo-edit + :defer t + :config + (setf sudo-edit-local-method "doas")) + +(use-package jinx + :defer t + :bind (:map jinx-mode-map + (("M-'" . jinx-correct))) + :hook ((org-mode . jinx-mode))) + +(defun dired-watch-video () + "Watch play file with mpv." + (interactive) + (call-process-shell-command + (format "mpv \"%s\"" (dired-get-filename)) nil 0)) + +(defun dired-set-wallpaper () + "Set NAME as wallpaper using feh." + (interactive) + (call-process-shell-command + (format "feh --bg-scale %s" (dired-get-filename)) nil 0)) + +(defun dired-delete-files-except () + "Delete all files inside directory except match." + (interactive) + (let* ((directory (read-directory-name "Select directory: ")) + (files (directory-files directory t)) + (except-match (read-string "Except the ones that have: "))) + (dolist (file files) + (unless (or (string= "." (substring file -1)) + (string= ".." (substring file -2)) + (string-match except-match file)) + (dired-delete-file file t))))) + +(defun dired-delete-file-match () + "Delete all files inside directory except match." + (interactive) + (let* ((directory (read-directory-name "Select directory: ")) + (files (directory-files directory t)) + (match (read-string "Delete files that match: "))) + (dolist (file files) + (when (string-match-p match file) + (dired-delete-file file t))))) + +(defun dired-rename-capitalize-file () + "Capitalize the base name of the file at point in a Dired buffer." + (interactive) + (let* ((file (dired-get-file-for-visit)) + (new-file (capitalize (file-name-nondirectory file)))) + (if (string-prefix-p "." file) + (message "Skipping file starting with '.'") + (progn + (rename-file file (concat (file-name-directory file) new-file)) + (revert-buffer) + (message "Renamed %s to %s" file new-file))))) + +(use-package term + :bind (("C-c t" . term) + :map term-mode-map + ("M-p" . term-send-up) + ("M-n" . term-send-down) + :map term-raw-map + ("M-o" . other-window) + ("M-p" . term-send-up) + ("M-n" . term-send-down))) + + +(use-package emacs + :ensure t + :init + (require 'dired) + :bind (("C-x C-b" . 'ibuffer) + ("M-." . 'xref-find-definitions) + ("C-c L" . 'display-line-numbers) + :map dired-mode-map + (("b" . 'dired-up-directory) + ("v" . 'dired-watch-video) + ("z" . 'wdired-change-to-wdired-mode) + ("C-c w" . 'dired-set-wallpaper) + ("C-c d" . 'dired-delete-files-except))) + :config + (custom-set-faces + (if is-hermes '(default ((t (:inherit nil :height 120 :family "Jetbrains Mono")))) + '(default ((t (:inherit nil :height 130 :family "Jetbrains Mono")))))) + ;; Don't display battery-mode on desktop + (if is-zeus + (display-battery-mode 0) + (display-battery-mode 1)) + (savehist-mode) + (save-place-mode 1) + (recentf-mode 1) + (electric-pair-mode 1) + ;; Autoinsert + (auto-insert-mode 1) + (define-auto-insert + '("\\.sh\\'" . "Bash skeleton") + '("Description:" + "#!/bin/bash\n\n")) + (add-to-list 'completion-styles 'initials t) + (setf tab-always-indent 'complete) + ;; tramp + (setf tramp-default-method "ssh") + ;; xref + (setf xref-show-xrefs-function #'consult-xref + xref-show-definitions-function #'consult-xref) + ;; dabbrev + :hook ((ibuffer-mode . 'nerd-icons-ibuffer-mode) + (shell-script-mode . 'auto-insert))) + +(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)) + +;; (use-package tramp +;; :ensure t +;; :init (setf tramp-default-method "ssh")) + +;; My packages +(use-package yeetube + :straight (yeetube :local-repo "~/Dev/emacs-lisp/yeetube")) + +(use-package gnosis + :straight (gnosis :local-repo "~/Dev/emacs-lisp/gnosis") + :init (define-prefix-command 'thanos/gnosis-map) + :bind (("C-r" . 'thanos/gnosis-map) + :map thanos/gnosis-map + ("r" . 'gnosis-review) + ("a" . 'gnosis-add-note))) + +;; AI tools +(use-package gptel + :defer t + :config + (setf gptel-api-key (password-store-get "chatgpt/api")) + :bind (:map gptel-mode-map + ("C-c h" . 'gptel-menu))) + +(use-package copilot + :straight (copilot :host github :repo "zerolfx/copilot.el" :files ("dist" "*.el")) + :bind (:map copilot-mode-map + ("M-TAB" . 'copilot-accept-completion-by-line) + ("C-M-n" . 'copilot-next-completion) + ("C-M-p" . 'copilot-previous-completion))) + + +;; Password-store + +(defun thanos/pass-launcher () + "Launch Emacs as a front-end for pass." + (interactive) + (unwind-protect + (with-selected-frame + (make-frame '((name . "thanos/pass-launcher") + (fullscreen . 0) + (undecorated . t) + (minibuffer . only) + (width . 70) + (height . 15))) + (let* ((choice (completing-read "Choose an action: " + '("AUTO" "COPY PASS" "COPY USERNAME" "EDIT" "GENERATE"))) + (action (pcase choice + ("AUTO" #'(lambda (entry) (let ((user (password-store-get-field entry "user")) (pass (password-store-get entry))) + (start-process-shell-command + "xdotool" nil + (format "sleep 0.3 && xdotool getactivewindow type '%s' && xdotool getactivewindow key Tab && xdotool getactivewindow type '%s'" + (if user user 'thanosapollo) pass))))) + ("COPY PASS" #'password-store-copy) + ("COPY USERNAME" #'(lambda (entry) (password-store-copy-field entry "user"))) + ("EDIT" #'password-store-edit) + ("GENERATE" #'password-store-generate)))) + (funcall action (completing-read "Search: " (password-store-list))) + (delete-frame))))) + +(defun smtp-get-pass () + "Get password for smtp." + (interactive) + (password-store-copy-field "fastmail.com/thanosapollo@fastmail.com" "smtp")) + + +(use-package password-store + :init (define-prefix-command 'thanos/pass) + :ensure t + :config + (setf password-store-password-length (+ 20 (random 20))) + :bind (("C-c p" . 'thanos/pass) + :map thanos/pass + ("i" . 'password-store-insert) + ("e" . 'password-store-edit) + ("g" . 'password-store-generate) + ("c" . 'password-store-copy) + ("s" . 'smtp-get-pass))) + +(use-package mu4e-alert + :ensure t + :config + (mu4e-alert-enable-mode-line-display)) + + +(require 'thanos-commands) ;; Misc commands (require 'thanos-mu4e) ;; Email client -(require 'thanos-multimedia) ;; emms, yeetube -(require 'thanos-elfeed) ;; RSS -(require 'thanos-ai) ;; AI tools ;;; init.el ends here -- cgit v1.2.3