#+TITLE: Emacs Configuration
#+PROPERTY: header-args :tangle ../.emacs.d/init.el
#+auto_tangle: t
#+STARTUP: overview
* System information
Check the ~$HOSTNAME~, if it's one of my devices running GuixSD.
#+begin_src emacs-lisp
(defvar is-zeus (equal (system-name) "zeus"))
(defvar is-hephaestus (equal (system-name) "hephaestus"))
#+end_src
Setup default browser as ~mullvad-browser~
#+begin_src emacs-lisp
(setq browse-url-browser-function 'browse-url-generic
browse-url-generic-program "mullvad-browser")
#+end_src
* Setting up Packages
** Setup for GuixSD machines
#+begin_src emacs-lisp
;; When guix t, load emacs packages
(when (or is-zeus
is-hephaestus
(add-to-list 'load-path "~/.guix-profile/share/emacs/site-lisp")
(guix-emacs-autoload-packages)))
(with-eval-after-load 'geiser-guile
(add-to-list 'geiser-guile-load-path "~/dotfiles/.config/guix"))
;; Personal Information
(setq user-full-name "Thanos Apollo"
user-mail-address "public@thanosapollo.com")
(setq copyright-names-regexp
(format "%s <%s>" user-full-name user-mail-address))
#+end_src
** Define and install packages
*** List of required packages
Request the following packages:
#+begin_src emacs-lisp
(defconst my-package-list '(org-snooze
all-the-icons
all-the-icons-dired
all-the-icons-ivy-rich
dap-mode
toc-org
emojify
general
doom-themes
doom-modeline
counsel
which-key
ivy
ivy-rich
helpful
password-store
org
org-modern
visual-fill-column
rainbow-delimiters
flycheck
lsp-mode
lsp-ui
json-mode
rjsx-mode
typescript-mode
python-mode
pyvenv
company
company-box
magit
elfeed
elfeed-goodies
paredit
corfu
monkeytype
sudo-edit
exwm
exwm-mff
;; exwm-firefox-core
consult
alsamixer
simple-httpd
circe
eshell-syntax-highlighting
; pdf-tools
org-superstar
mastodon
dashboard
org-auto-tangle))
#+end_src
*** Installation & activation
Set our ~package-archives~, and install our packages
#+begin_src emacs-lisp
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
("org" . "https://orgmode.org/elpa/")
("elpa" . "https://elpa.gnu.org/packages/")
("jcs-elpa" . "https://jcs-emacs.github.io/jcs-elpa/packages/")))
(package-initialize)
(unless package-archive-contents
(package-refresh-contents))
(defvar my-missing-packages '()
"List populated at each startup.
Contains the list of packages that need to be installed.")
(dolist (p my-package-list)
(when (not (package-installed-p p))
(add-to-list 'my-missing-packages p)))
(when my-missing-packages
(message "Emacs is now refreshing its package database...")
(package-refresh-contents)
;; Install the missing packages
(dolist (p my-missing-packages)
(message "Installing `%s' .." p)
(package-install p))
(setq my-missing-packages '()))
(unless (package-installed-p 'use-package)
(package-install 'use-package))
;; set and load custom.el
(setq custom-file (concat user-emacs-directory "custom.el"))
(load custom-file 'noerror)
#+end_src
* UI Settings
** Basic UI
Fonts and basic appearance settings
#+begin_src emacs-lisp
(setq inhibit-startup-message nil)
;; Transparency
(set-frame-parameter (selected-frame) 'alpha '(90 95))
(add-to-list 'default-frame-alist '(alpha 90 90))
(add-hook 'dired-mode-hook 'all-the-icons-dired-mode)
(when is-hephaestus
(display-battery-mode 1))
(scroll-bar-mode -1)
(tool-bar-mode -1)
(tooltip-mode -1)
(set-fringe-mode 10)
(menu-bar-mode -1)
(which-key-mode 1)
(blink-cursor-mode -1)
(menu-bar--visual-line-mode-enable)
(global-visual-line-mode 1)
(require 'emojify)
(global-emojify-mode 1)
(setq visible-bell t)
(column-number-mode)
(global-display-line-numbers-mode 0)
(menu-bar--display-line-numbers-mode-relative)
;;Disable line numbers for some modes
(dolist (mode '(pdf-view-mode-hook
org-mode-hook
term-mode-hook
shell-mode-hook
eshell-mode-hook
vterm-mode-hook
elfeed))
(add-hook mode (lambda () (display-line-numbers-mode 0))))
(defvar apollo/default-font-size 140)
(when (equal (system-name) "hermes")
(setq apollo/default-font-size 110))
(set-face-attribute 'default nil
:font "JetBrains Mono"
:height apollo/default-font-size)
(set-face-attribute 'fixed-pitch nil
:font "JetBrains Mono"
:height apollo/default-font-size)
(set-face-attribute 'variable-pitch nil
:font "JetBrains Mono"
:height apollo/default-font-size
:weight 'regular)
#+end_src
** Dashboard
#+begin_src emacs-lisp
(require 'dashboard)
(require 'all-the-icons)
(dashboard-setup-startup-hook)
(setq dashboard-items '((recents . 5)
(bookmarks . 5)))
(setq initial-buffer-choice (lambda () (get-buffer-create "*dashboard*"))
dashboard-item-names '(("Recent Files:" . "Recent Files:")
("Bookmarks:" . "Study:")))
;; Set the banner
(setq dashboard-startup-banner "~/dotfiles/pictures/medicine/plague-doctor-s.png")
;; Set the title
(setq dashboard-banner-logo-title "Is that a flying flower?")
;; (setq dashboard-init-info "Bring me your sick and wounded!")
(setq dashboard-set-init-info t
dashboard-center-content t
dashboard-set-navigator t
dashboard-set-heading-icons t
dashboard-set-file-icons t
dashboard-show-shortcuts nil
dashboard-set-footer t
dashboard-footer-messages '("Welcome to the Church Of Emacs")
dashboard-footer-icon (all-the-icons-octicon "broadcast"
:height 1.15
:v-adjust -0.05
:face 'font-lock-keyword-face))
#+end_src
** Theme & modeline
#+begin_src emacs-lisp
(load-theme 'doom-ayu-dark t)
(doom-modeline-mode 1)
(setq doom-modeline-height 35)
#+end_src
** Ivy
#+begin_src emacs-lisp
(use-package ivy
:diminish
:bind (("C-s" . swiper)
:map ivy-minibuffer-map
("TAB" . ivy-alt-done)
("C-l" . ivy-alt-done)
("C-j" . ivy-next-line)
("C-k" . ivy-previous-line)
:map ivy-switch-buffer-map
("C-k" . ivy-previous-line)
("C-l" . ivy-done)
("C-d" . ivy-switch-buffer-kill)
:map ivy-reverse-i-search-map
("C-k" . ivy-previous-line)
("C-d" . ivy-reverse-i-search-kill))
:config
(ivy-mode 1)
(setq ivy-use-selectable-prompt t))
(ivy-rich-mode 1)
(all-the-icons-ivy-rich-mode 1)
#+end_src
** Helpful
#+begin_src emacs-lisp
(use-package helpful
:custom
(counsel-describe-function-function #'helpful-callable)
(counsel-describe-variable-function #'helpful-variable)
:bind
([remap describe-function] . counsel-describe-function)
([remap describe-command] . helpful-command)
([remap describe-variable] . counsel-describe-variable)
([remap describe-key] . helpful-key))
#+end_src
* Dired
** Keys
#+begin_src emacs-lisp
(define-key dired-mode-map "b" 'dired-up-directory)
#+end_src
** All-the-icons.el
#+begin_src emacs-lisp
;;; all-the-icons-dired.el --- Shows icons for each file in dired mode -*- lexical-binding: t; -*-
;;; Code:
(require 'cl-lib)
(require 'dired)
(require 'all-the-icons)
(defface all-the-icons-dired-dir-face
'((((background dark)) :foreground "white")
(((background light)) :foreground "black"))
"Face for the directory icon"
:group 'all-the-icons-faces)
(defcustom all-the-icons-dired-v-adjust 0.01
"The default vertical adjustment of the icon in the dired buffer."
:group 'all-the-icons
:type 'number)
(defvar all-the-icons-dired-mode)
(defun all-the-icons-dired--add-overlay (pos string)
"Add overlay to display STRING at POS."
(let ((ov (make-overlay (1- pos) pos)))
(overlay-put ov 'all-the-icons-dired-overlay t)
(overlay-put ov 'after-string string)))
(defun all-the-icons-dired--overlays-in (beg end)
"Get all all-the-icons-dired overlays between BEG to END."
(cl-remove-if-not
(lambda (ov)
(overlay-get ov 'all-the-icons-dired-overlay))
(overlays-in beg end)))
(defun all-the-icons-dired--overlays-at (pos)
"Get all-the-icons-dired overlays at POS."
(apply #'all-the-icons-dired--overlays-in `(,pos ,pos)))
(defun all-the-icons-dired--remove-all-overlays ()
"Remove all `all-the-icons-dired' overlays."
(save-restriction
(widen)
(mapc #'delete-overlay
(all-the-icons-dired--overlays-in (point-min) (point-max)))))
(defun all-the-icons-dired--refresh ()
"Display the icons of files in a dired buffer."
(all-the-icons-dired--remove-all-overlays)
(save-excursion
(goto-char (point-min))
(while (not (eobp))
(when (dired-move-to-filename nil)
(let ((file (dired-get-filename 'relative 'noerror)))
(when file
(let ((icon (if (file-directory-p file)
(all-the-icons-icon-for-dir file
:face 'all-the-icons-dired-dir-face
:v-adjust all-the-icons-dired-v-adjust)
(all-the-icons-icon-for-file file :v-adjust all-the-icons-dired-v-adjust))))
(if (member file '("." ".."))
(all-the-icons-dired--add-overlay (point) " \t")
(all-the-icons-dired--add-overlay (point) (concat icon "\t")))))))
(forward-line 1))))
(defun all-the-icons-dired--refresh-advice (fn &rest args)
"Advice function for FN with ARGS."
(apply fn args)
(when all-the-icons-dired-mode
(all-the-icons-dired--refresh)))
(defun all-the-icons-dired--setup ()
"Setup `all-the-icons-dired'."
(when (derived-mode-p 'dired-mode)
(setq-local tab-width 1)
(advice-add 'dired-readin :around #'all-the-icons-dired--refresh-advice)
(advice-add 'dired-revert :around #'all-the-icons-dired--refresh-advice)
(advice-add 'dired-internal-do-deletions :around #'all-the-icons-dired--refresh-advice)
(advice-add 'dired-insert-subdir :around #'all-the-icons-dired--refresh-advice)
(advice-add 'dired-do-kill-lines :around #'all-the-icons-dired--refresh-advice)
(with-eval-after-load 'dired-narrow
(advice-add 'dired-narrow--internal :around #'all-the-icons-dired--refresh-advice))
(all-the-icons-dired--refresh)))
(defun all-the-icons-dired--teardown ()
"Functions used as advice when redisplaying buffer."
(advice-remove 'dired-readin #'all-the-icons-dired--refresh-advice)
(advice-remove 'dired-revert #'all-the-icons-dired--refresh-advice)
(advice-remove 'dired-internal-do-deletions #'all-the-icons-dired--refresh-advice)
(advice-remove 'dired-narrow--internal #'all-the-icons-dired--refresh-advice)
(advice-remove 'dired-insert-subdir #'all-the-icons-dired--refresh-advice)
(advice-remove 'dired-do-kill-lines #'all-the-icons-dired--refresh-advice)
(all-the-icons-dired--remove-all-overlays))
;;;###autoload
(define-minor-mode all-the-icons-dired-mode
"Display all-the-icons icon for each files in a dired buffer."
:lighter " all-the-icons-dired-mode"
(when (and (derived-mode-p 'dired-mode) (display-graphic-p))
(if all-the-icons-dired-mode
(all-the-icons-dired--setup)
(all-the-icons-dired--teardown))))
#+end_src
Hook with ~dired-mode~
#+begin_src emacs-lisp
(add-hook 'dired-mode-hook 'all-the-icons-dired-mode)
#+end_src
* Terminals
** Vterm
#+begin_src emacs-lisp
(use-package vterm
:ensure nil)
(use-package multi-vterm
:ensure nil
:config
(setq multi-vterm-dedicated-window-height 25))
#+end_src
** Eshell
#+begin_src emacs-lisp
(use-package eshell
:ensure nil
:bind (("C-c e" . 'eshell))
:config
(defvar eshell-path-env (getenv "~/.local/bin")))
(defun with-face (str &rest face-plist)
(propertize str 'face face-plist))
(defun apollo-eshell-prompt ()
(let ((winter-blue "#3F3B6C")
(white-summer "#E5E5CB")
(green-night "#03C988")
(orange-summer "#FFB100")
(green-summer "#A3BB98")
(summer-sea "#2192FF")
(black "#000000"))
(concat
(with-face (concat "[" user-login-name) :foreground orange-summer :background black)
(with-face "@" :foreground orange-summer :background black)
(with-face (concat system-name "]\n") :foreground orange-summer :background black)
(with-face (concat "|" (eshell/pwd) ) :foreground "#F0E9D2" :background winter-blue)
(with-face (format-time-string " | %H:%M" (current-time)) :background winter-blue :foreground "#888")
(with-face "\n -> "))))
;; (setq eshell-prompt-function 'apollo-eshell-prompt)
;; (setq eshell-highlight-prompt t)
#+end_src
* Custom
** Random functions
#+begin_src emacs-lisp
(defun apollo/html-boostrap-boilerplate ()
"Insert html boilerplate with boostrap link."
(interactive)
(insert
"
My Title
Starting point
" ))
(defun apollo/center-buffer ()
"Centers/Uncenters selected buffer"
(interactive)
(if visual-fill-column-center-text
(setq visual-fill-column-center-text nil)
(setq visual-fill-column-center-text t))
(visual-fill-column-mode 1)
(message "General's task completed!"))
(defun apollo/rofi-switch-window ()
"Navigate X11 buffers using rofi."
(interactive)
(start-process-shell-command
"rofi" nil "rofi -show window"))
(defun apollo/run-in-background (command)
"Run COMMAND in the background."
(let ((command-parts (split-string command "[ ]+")))
(apply #'call-process `(,(car command-parts) nil 0 nil ,@(cdr command-parts)))))
(defun rofi ()
"Run Rofi."
(interactive)
(apollo/run-in-background "rofi -show drun"))
(defun apollo/volume-increase ()
"Increase Volume."
(interactive)
(start-process-shell-command
"amixer" nil "amixer sset Master 5%+"))
(defun apollo/volume-decrease ()
"Decrease Volume."
(interactive)
(start-process-shell-command
"amixer" nil "amixer sset Master 5%-"))
(defun apollo/restore-wallpaper ()
"Set NAME as wallpaper."
(interactive)
(start-process-shell-command
"feh" nil "feh --bg-scale ~/dotfiles/wallpaper.png"))
(defun apollo/emacs-keys ()
"Swap caps with ctrl."
(interactive)
(start-process-shell-command
"setxkbmap" nil "setxkbmap us -option ctrl:swapcaps"))
(defun apollo/greek-keyboard ()
"Swap caps with ctrl."
(interactive)
(start-process-shell-command
"setxkbmap" nil "setxkbmap gr"))
(defun apollo/exwm-update-class ()
(exwm-workspace-rename-buffer exwm-class-name))
(defun eshell-new()
"Open a new instance of eshell."
(interactive)
(eshell 'N))
(defun make-mini-geiser ()
(interactive)
(split-window-below 60)
(geiser nil))
(defun start-polybar ()
"Check which system is running, start polybar accordingly."
(interactive)
(if (string= (system-name) "fsociety")
(start-process-shell-command
"polybar" nil "polybar main & polybar second")
(start-process-shell-command
"polybar" nil "polybar main")))
(defun create-keimenografos ()
"create a scratch buffer"
(interactive)
(switch-to-buffer (get-buffer-create "*Keimenografos*"))
(text-mode))
#+end_src
** Key-bindings
#+begin_src emacs-lisp
(global-set-key (kbd "") 'keyboard-escape-quit)
(global-set-key (kbd "s-=") 'text-scale-increase)
(global-set-key (kbd "s--") 'text-scale-decrease)
(global-set-key (kbd "C-k") 'copy-region-as-kill)
;; Pass
(global-set-key (kbd "C-c p i") 'password-store-insert)
(global-set-key (kbd "C-c p e") 'password-store-edit)
(define-prefix-command 'thanos/applications-map)
(define-key thanos/applications-map (kbd "q") 'chatgpt-query)
(define-key thanos/applications-map (kbd "m") 'mu4e)
(define-key thanos/applications-map (kbd "t") 'counsel-load-theme)
(define-key thanos/applications-map (kbd "f") 'elfeed)
(global-set-key (kbd "C-c a") 'thanos/applications-map)
(define-prefix-command 'Morfi)
(define-key thanos/applications-map (kbd "c") 'Morfi)
(define-key Morfi (kbd "t") 'create-keimenografos)
(defvar thanos/vterm-map (make-sparse-keymap))
(define-prefix-command 'thanos/vterm-map)
(define-key global-map (kbd "C-c v") 'thanos/vterm-map)
(define-key thanos/vterm-map (kbd "n") 'multi-vterm-next)
(define-key thanos/vterm-map (kbd "p") 'multi-vterm-prev)
(define-key thanos/vterm-map (kbd "d") 'multi-vterm-dedicated-open)
(define-key thanos/vterm-map (kbd "o") 'multi-vterm)
#+end_src
*** General
#+begin_src emacs-lisp
;; my general's leader key!
(defconst general-key "C-c g")
(general-create-definer general-does
:prefix general-key)
;; Basic functions
(general-define-key
"C-d" 'kill-region
"C-k" 'copy-region-as-kill
"C-x 9" 'make-mini-buffer
"C-c l e" 'apollo/emacs-keys
;;Change keyboard layouts/language
"C-c l g" 'apollo/greek-keyboard
"C-κ" 'apollo/emacs-keys
"C-x C-b" 'ibuffer)
;; My Generals does:
(general-does
"t" 'counsel-load-theme
"l" 'display-line-numbers-mode
"v" 'multi-vterm
"e" 'eshell
"i" 'circe
"c" 'apollo/center-buffer
"m" 'mu4e
"f" 'elfeed
"C-t" 'telega
"g" 'guix)
;;pdf-tools
(general-define-key
:keymaps 'pdf-view-mode-map
"C-c d" 'pdf-view-midnight-minor-mode
"C-s" 'isearch-forward
"C-o" 'pdf-isearch-occur)
;;vterm
(general-does
:keymaps 'vterm-mode-map
"n" 'multi-vterm-next
"o" 'multi-vterm
"p" 'multi-vterm-prev)
(general-does
:keymaps 'eshell-mode-map
"n" 'eshell-new)
(general-does
:keymaps 'org-mode-map
"3" 'org-insert-image-size-300)
#+end_src
** ChatGPT
#+begin_src emacs-lisp
(setq openai-key (password-store-get "chatgpt/api2"))
#+end_src
* Org-mode Configuration
** org-make-toc
#+begin_src emacs-lisp
(add-hook 'org-mode-hook 'org-make-toc-mode)
#+end_src
** Themes
*** Dracula
#+begin_src emacs-lisp
(defun apollo/org-theme-dracula ()
"Enable Dracula theme for Org headers."
(interactive)
(dolist
(face
'((org-level-1 1.7 "#8be9fd" extra-bold)
(org-level-2 1.6 "#bd93f9" extra-bold)
(org-level-3 1.5 "#50fa7b" bold)
(org-level-4 1.4 "#ff79c6" semi-bold)
(org-level-5 1.3 "#9aedfe" normal)
(org-level-6 1.2 "#caa9fa" normal)
(org-level-7 1.1 "#5af78e" normal)
(org-level-8 1.0 "#ff92d0" normal)))
(set-face-attribute (nth 0 face) nil
:font "JetBrains Mono"
:weight (nth 3 face)
:height (nth 1 face)
:foreground (nth 2 face)))
(set-face-attribute 'org-table nil
:font "JetBrains Mono"
:weight 'normal
:height 1.0
:foreground "#bfafdf"))
#+end_src
*** Darkone
#+begin_src emacs-lisp
(defun apollo/org-theme-darkone ()
"Enable Darkone theme for Org headers."
(interactive)
(dolist
(face
'((org-level-1 1.70 "#51afef" bold)
(org-level-2 1.55 "#7FBCD2" bold)
(org-level-3 1.40 "#da8548" bold)
(org-level-4 1.20 "#da8548" semi-bold)
(org-level-5 1.20 "#5699af" normal)
(org-level-6 1.20 "#a9a1e1" normal)
(org-level-7 1.10 "#46d9ff" normal)
(org-level-8 1.00 "#ff6c6b" normal)))
(set-face-attribute (nth 0 face) nil
:font "Jetbrains Mono"
:weight (nth 3 face)
:height (nth 1 face)
:foreground (nth 2 face)))
(set-face-attribute 'org-table nil
:font "Jetbrains Mono"
:weight 'normal
:height 1.0
:foreground "#A66CFF"))
#+end_src
*** Gruvbox
#+begin_src emacs-lisp
(defun apollo/org-theme-gruvbox ()
"Enable Darkone theme for Org headers."
(interactive)
(dolist
(face
'((org-level-1 1.70 "#fb4934" bold)
(org-level-2 1.55 "#98971a" bold)
(org-level-3 1.40 "#458588" bold)
(org-level-4 1.20 "#b16286" semi-bold)
(org-level-5 1.20 "#689d6a" normal)
(org-level-6 1.20 "#d3869b" normal)
(org-level-7 1.10 "#8ec07c" normal)
(org-level-8 1.00 "#ebdbb2" normal)))
(set-face-attribute (nth 0 face) nil
:font "Jetbrains Mono"
:weight (nth 3 face)
:height (nth 1 face)
:foreground (nth 2 face)))
(set-face-attribute 'org-table nil
:font "Jetbrains Mono"
:weight 'normal
:height 1.0
:foreground "#A66CFF"))
#+end_src
*** Org Modern
#+begin_src emacs-lisp
(modify-all-frames-parameters
'((right-divider-width . 5)
(internal-border-width . 5)))
(dolist (face '(window-divider
window-divider-first-pixel
window-divider-last-pixel))
(face-spec-reset-face face)
(set-face-foreground face (face-attribute 'default :background)))
(set-face-background 'fringe (face-attribute 'default :background))
(setq
;; Edit settings
org-auto-align-tags nil
org-tags-column 0
org-catch-invisible-edits 'show-and-error
org-special-ctrl-a/e t
org-insert-heading-respect-content t
;; Org styling, hide markup etc.
org-hide-emphasis-markers t
org-pretty-entities t
;; Agenda styling
org-agenda-tags-column 0
org-agenda-block-separator ?─
org-agenda-time-grid
'((daily today require-timed)
(800 1000 1200 1400 1600 1800 2000)
" ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄")
org-agenda-current-time-string
"⭠ now ─────────────────────────────────────────────────")
(global-org-modern-mode)
#+end_src
** Settings
#+begin_src emacs-lisp
(require 'ox-md nil t)
(setq 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-agenda-start-log-mode t
org-log-done 'time
org-log-into-drawer t
org-indent-mode t
org-todo-keywords ;; This overwrites the default Doom org-todo-keywords
'((sequence
"TODO(t)" ;; A task that is ready to be tackled
"BLOG(b)" ;; Blog writing assignments
"GYM(g)" ;; Things to accomplish at the gym
"WAIT(w)" ;; Something is holding up this task
"|" ;; The pipe necessary to separate "active" states and "inactive" states
"DONE(d)" ;; Task has been completed
"CANCELLED(c)" ))
org-superstar-headline-bullets-list '("◉" "●" "○" "●" "○" "●" "◆")
org-superstar-itembullet-alist '((?+ . ?➤) (?- . ?✦))) ;; changes +/- symbols in item lists)
;; Hooks
(add-hook 'org-mode-hook 'apollo/org-theme-gruvbox)
(add-hook 'org-mode-hook 'flyspell-mode)
(add-hook 'org-mode-hook 'toc-org-mode)
#+end_src
** Babel
#+begin_src emacs-lisp
(defadvice org-edit-src-code (around set-buffer-file-name activate compile)
(let ((file-name (buffer-file-name))) ;; (1)
ad-do-it ;; (2)
(setq buffer-file-name file-name))) ;; (3)
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(python . t)))
(add-to-list 'org-structure-template-alist '("ex" . "SRC EXAMPLE"))
(add-to-list 'org-structure-template-alist '("b" . "src bash"))
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
(add-to-list 'org-structure-template-alist '("py" . "src python"))
(add-to-list 'org-structure-template-alist '("li" . "src lisp"))
;;Auto tangle
(add-hook 'org-mode-hook 'org-auto-tangle-mode)
#+end_src
* Markdown
** Theme
#+begin_src emacs-lisp
(defun apollo/markdown-theme ()
(interactive)
(dolist
(face
'(markdown-header-face-1 :height 2.0))))
#+end_src
** Settings
#+begin_src emacs-lisp
(setq markdown-header-scaling t)
(use-package markdown-mode
:ensure t
:mode (".md" . gfm-mode)
:init (setq markdown-command "multimarkdown"))
#+end_src
* Programming
** Essentials
#+begin_src emacs-lisp
(electric-pair-mode 1)
(global-flycheck-mode)
(use-package company
:after lsp-mode
:hook (lsp-mode . company-mode)
:bind (:map company-active-map
("" . company-complete-selection))
(:map lsp-mode-map
("" . company-indent-or-complete-common))
:custom
(company-minimum-prefix-length 1)
(company-idle-delay 0.0))
(use-package dap-mode
:custom
(lsp-enable-dap-auto-configure nil)
:config
(dap-ui-mode 1))
(use-package company-box
:hook (company-mode . company-box-mode))
#+end_src
*** Magit
#+begin_src emacs-lisp
(use-package magit
:custom
(magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1))
#+end_src
** Emacs lisp
#+begin_src emacs-lisp
(setq tab-always-indent 'complete)
(add-to-list 'completion-styles 'initials t)
(add-hook 'emacs-lisp-mode-hook #'rainbow-delimiters-mode)
(add-hook 'scheme-mode-hook #'rainbow-delimiters-mode)
#+end_src
** LSP-Mode
#+begin_src emacs-lisp
(defun apollo/lsp-mode-setup ()
(setq lsp-headerline-breadcrumb-segments '(path-up-to-project file symbols))
(lsp-headerline-breadcrumb-mode))
(use-package lsp-mode
:commands (lsp lsp-deferred)
:hook (lsp-mode . apollo/lsp-mode-setup)
:init
(setq lsp-keymap-prefix "C-c l") ;; Or 'C-l', 's-l'
:config
(lsp-enable-which-key-integration t)
(setq lsp-pyls-server-command "~/.local/bin/pylsp"))
(use-package lsp-ui
:hook (lsp-mode . lsp-ui-mode)
:custom
(lsp-ui-doc-position 'bottom))
#+end_src
** Python
#+begin_src emacs-lisp
(use-package python-mode
:ensure t
:mode ".py"
:hook (python-mode . lsp-deferred)
:custom
(dap-python-debugger 'debugpy)
:config
(require 'dap-python))
(use-package pyvenv
:config
(pyvenv-mode 1))
#+end_src
** JSON
#+begin_src emacs-lisp
(use-package json-mode
:mode ".json"
:hook (json-mode . lsp-deferred))
#+end_src
** Javascript
#+begin_src emacs-lisp
(use-package rjsx-mode
:mode ".js"
:hook (rjsx-mode . lsp-deferred)
:config
(defadvice js-jsx-indent-line (after js-jsx-indent-line-after-hack activate)
"Workaround sgml-mode and follow airbnb component style."
(save-excursion
(beginning-of-line)
(if (looking-at-p "^ +\/?> *$")
(delete-char sgml-basic-offset)))))
#+end_src
* Elfeed
** Feeds
#+begin_src emacs-lisp
(require 'elfeed)
(require 'elfeed-goodies)
(setq elfeed-feeds (quote
(
("https://hackaday.com/blog/feed/"
hackaday linux)
("https://thanosapollo.com/public/feed.xml"
me)
("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 me)
("https://rss.nytimes.com/services/xml/rss/nyt/Science.xml"
NYT science news)
("https://rss.nytimes.com/services/xml/rss/nyt/Health.xml"
NYT med news)
("https://rss.nytimes.com/services/xml/rss/nyt/World.xml"
NYT world news)
("https://rss.nytimes.com/services/xml/rss/nyt/US.xml"
NYT us news)
("https://www.addtoany.com/add_to/feed?linkurl=http%3A%2F%2Fwww.thelancet.com%2Frssfeed%2Flancet_current.xml&type=feed&linkname=The%20Lancet%20Current%20Issue&linknote="
lancet med)
("http://nullprogram.com/feed/"
emacs linux)
("https://drewdevault.com/blog/index.xml"
sourcehut drewdevault)
("https://spacepub.space/feeds/videos.xml?videoChannelId=2"
drewdevault youtube)
("https://www.youtube.com/feeds/videos.xml?channel_id=UCVls1GmFKf6WlTraIb_IaJg"
video dt)
("https://www.youtube.com/feeds/videos.xml?channel_id=UC7YOGHUfC1Tb6E4pudI9STA"
video mental)
("https://www.youtube.com/feeds/videos.xml?channel_id=UCAiiOTio8Yu69c3XnR7nQBQ"
video daviwil)
("https://videos.lukesmith.xyz/feeds/videos.atom?sort=-publishedAt&isLocal=true"
video luke)
("https://www.youtube.com/feeds/videos.xml?channel_id=UCrc2iv2-G1FZ3VscM3zu2jg"
video zoogirl)
("https://www.youtube.com/feeds/videos.xml?channel_id=UC0uTPqBCFIpZxlz_Lv1tk_g"
video prot)
("https://www.youtube.com/feeds/videos.xml?channel_id=UCq6VFHwMzcMXbuKyG7SQYIg"
video moist)
("https://www.youtube.com/feeds/videos.xml?channel_id=UC05XpvbHZUQOfA6xk4dlmcw"
video djware)
("https://archlinux.org/feeds/news/"
ArchLinux Latest))))
#+end_src
** Settings & Keys
#+begin_src emacs-lisp
(defun elfeed-v-mpv (url)
"Watch a video from URL in MPV"
(async-shell-command (format "mpv \"%s\"" url)))
(defun elfeed-view-mpv (&optional use-generic-p)
"Youtube-feed link"
(interactive "P")
(let ((entries (elfeed-search-selected)))
(cl-loop for entry in entries
do (elfeed-untag entry 'unread)
when (elfeed-entry-link entry)
do (elfeed-v-mpv it))
(mapc #'elfeed-search-update-entry entries)
(unless (use-region-p) (forward-line))))
(define-key elfeed-search-mode-map (kbd "v") 'elfeed-view-mpv)
(define-key elfeed-search-mode-map (kbd "U") 'elfeed-update)
(setq elfeed-goodies/entry-pane-size 0.65)
(elfeed-goodies/setup)
#+end_src
* PDF
#+begin_src emacs-lisp
;;Add pdf-isearch-minor-mode hook, otherwise isearch will be buggy
;;Darkmode hook, cause I don't want color or light in my life, I'm a vampire.
(add-hook 'pdf-view-mode-hook 'pdf-isearch-minor-mode)
(add-hook 'pdf-view-mode-hook 'pdf-view-midnight-minor-mode)
(add-to-list 'auto-mode-alist '("\\.pdf\\'" . pdf-view-mode))
#+end_src
* mu4e | Email Configuration
#+begin_src emacs-lisp
;; Check if we have mu4e available
;; if t load mu4e settings
(when (require 'mu4e nil 'noerror)
(setq mu4e-update-interval (* 10 60))
(setq mu4e-get-mail-command "mbsync -a")
(setq mu4e-maildir-list "~/Mail/Inbox")
(defun set-mu4e-context (context-name full-name mail-address signature server)
"Return a mu4e context named CONTEXT-NAME with :match-func matching
folder name CONTEXT-NAME in Maildir. The context's `user-mail-address',
`user-full-name' and `mu4e-compose-signature'`smtpmail-smpt-server' is set to MAIL-ADDRESS
FULL-NAME SIGNATURE and SERVER respectively.
Special folders are set to context specific folders."
(let ((dir-name (concat "/" context-name)))
(make-mu4e-context
:name context-name
;; we match based on the maildir of the message
:match-func
`(lambda (msg)
(when msg
(string-match-p
,(concat "^" dir-name)
(mu4e-message-field msg :maildir))))
:vars
`((user-mail-address . ,mail-address)
(user-full-name . ,full-name)
(mu4e-sent-folder . ,(concat dir-name "/Sent"))
(mu4e-drafts-folder . ,(concat dir-name "/Drafts"))
(mu4e-trash-folder . ,(concat dir-name "/Trash"))
(mu4e-trash-folder . ,(concat dir-name "/Starred"))
(mu4e-refile-folder . ,(concat dir-name "/Archive"))
(smtpmail-smtp-service . ,465)
(smtpmail-smtp-server . ,server)
(mu4e-compose-signature . ,signature)))))
;;Fixing duplicate UID errors when using mbsync and mu4e
(setq mu4e-change-filenames-when-moving t)
(setq mu4e-maildir-shortcuts
'(("/Fastmail/Inbox" . ?i)
("/Fastmail/Sent" . ?s)
))
(setq mu4e-contexts
`(, (set-mu4e-context
"Fastmail" "Thanos Apollo"
"public@thanosapollo.com" "Thanos\nhttps://thanosapollo.com"
"smtp.fastmail.com")))
;; (setq smtpmail-smtp-service 465
;; smtpmail-stream-type 'ssl
;; smtpmail-smtp-server "smtp.fastmail.com")
(setq message-send-mail-function 'smtpmail-send-it
smtpmail-stream-type 'ssl))
#+end_src
* EXWM
EXWM configuration is tangled with ~.exwm~
+ In GuixSD ~emacs-exwm~ package will look for ~~/.exwm~
#+begin_src emacs-lisp :tangle ../.exwm.el
(defun apollo/exwm-init-hook ()
"Do this upon start."
(if (string= (system-name) "fsociety") ;; Check if it's my desktop, otherwise display battery
(display-battery-mode 0)
(display-battery-mode 1))
(setq display-time-day-and-date t)
(display-time-mode 1)
(exwm-firefox-holyK-mode 1)
;;Launch apps that will run in the background
;; (apollo/run-in-background "blueman-applet")
(apollo/run-in-background "picom")
;; (apollo/run-in-background "nm-applet")
(apollo/emacs-keys)
(apollo/restore-wallpaper)
)
(defun apollo/exwm-update-class ()
(exwm-workspace-rename-buffer exwm-class-name))
(setq exwm-workspace-number 6)
;; When window "class" updates, use it to set the buffer name
(add-hook 'exwm-update-class-hook #'apollo/exwm-update-class)
;;When EXWM starts up, run this hook
(add-hook 'exwm-init-hook #'apollo/exwm-init-hook)
(start-process-shell-command
"xrandr" nil "xrandr --output DisplayPort-0 --primary --mode 2560x1440 --pos 1930x0 --rotate normal --output DisplayPort-1 --off --output DisplayPort-2 --off --output HDMI-A-0 --mode 1920x1080 --pos 0x0 --rotate normal")
;; Set the screen resolution
(require 'exwm-randr)
(setq exwm-randr-workspace-monitor-plist '(0 "DP-1" 2 "HDMI-A-0"))
(add-hook 'exwm-randr-screen-change-hook
(lambda ()
(start-process-shell-command
"xrandr" nil "xrandr --output DisplayPort-2 --primary --mode 2560x1440 --pos 1920x0 --rotate normal --output HDMI-A-0 --mode 1920x1080 --pos 0x0 --rotate normal" )))
(exwm-randr-enable)
;; Load the system tray before exwm-init
(require 'exwm-systemtray)
(exwm-systemtray-enable)
;; These keys should always pass through to Emacs
(setq exwm-input-prefix-keys
'(?\C-x
?\C-u
?\C-h
?\C-w
?\M-x
?\M-`
?\M-&
?\M-:
?\s-d
?\C-\M-j ;; Buffer list
?\C-\
?\C-k
?\C-y
?\C-n
?\C-p
?\C-f
?\C-b
?\C-s
?\M-f
?\M-b
?\M-<
?\M->))
;; Ctrl+Q will enable the next key to be sent directly
(define-key exwm-mode-map [?\C-q] 'exwm-input-send-next-key)
;; Set up global key bindings. These always work, no matter the input state!
;; Keep in mind that changing this list after EXWM initializes has no effect.
(setq exwm-input-global-keys
`(
([?\s-r] . exwm-reset)
;; ;; Launch applications via shell command
;; ([?\s-&] . (lambda (command)
;; (interactive (list (read-shell-command "$ ")))
;; (start-process-shell-command command nil command)))
;; Switch workspace
([?\s-e] . exwm-workspace-switch)
([?\s-`] . (lambda () (interactive) (exwm-workspace-switch-create 0)))
([?\s-2] . (lambda () (interactive) (exwm-workspace-switch-create 1)))
([?\s-3] . (lambda () (interactive) (exwm-workspace-switch-create 2)))
([?\s-4] . (lambda () (interactive) (exwm-workspace-switch-create 3)))
([?\s-5] . (lambda () (interactive) (exwm-workspace-switch-create 4)))
,@(mapcar (lambda (i)
`(,(kbd (format "s-%d" i)) .
(lambda ()
(interactive)
(exwm-workspace-switch-create ,i))))
(number-sequence 0 9))))
(defun exwm-enlarge-horizontally-50 ()
(interactive)
(exwm-layout-enlarge-window-horizontally 50))
(defun exwm-shrink-horizontally-50 ()
"Shrink window horizontally by 10"
(interactive)
(exwm-layout-shrink-window-horizontally 50))
(defun exwm-shrink-vertically-50 ()
"Shrink window by 50."
(interactive)
(exwm-layout-shrink-window 50))
(defun exwm-enlarge-vertically-50 ()
"Enlarge window by 50."
(interactive)
(exwm-layout-enlarge-window 50))
(exwm-input-set-key (kbd "C-c d") 'dmenu)
(exwm-input-set-key (kbd "s-") 'rofi)
(exwm-input-set-key (kbd "s-Q") 'kill-emacs)
(exwm-input-set-key (kbd "") 'apollo/volume-increase)
(exwm-input-set-key (kbd "") 'apollo/volume-decrease)
(exwm-input-set-key (kbd "s-0") 'apollo/emacs-keys)
(exwm-input-set-key (kbd "s-9") 'apollo/greek-keyboard)
(exwm-input-set-key (kbd "C-c C-") 'exwm-shrink-horizontally-50)
(exwm-input-set-key (kbd "C-c C-") 'exwm-enlarge-horizontally-50)
(exwm-input-set-key (kbd "C-c C-") 'exwm-shrink-vertically-50)
(exwm-input-set-key (kbd "C-c C-") 'exwm-enlarge-vertically-50)
(exwm-input-set-key (kbd "C-c C-e") 'exwm-layout-toggle-fullscreen)
(exwm-enable)
#+end_src