#+PROPERTY: header-args :tangle "/home/yaqub/.emacs.d/init.el"* Initial Setup** Niceties#+begin_src emacs-lisp(setq ring-bell-function 'ignore)(setq inhibit-startup-message t)(setq initial-buffer-choice t)#+end_src** Backup to saves instead of leaving temporary files in .#+begin_src emacs-lisp(setq backup-directory-alist `(("." . "~/.saves")))(setq backup-by-copying t)#+end_src** Initialise use-package#+begin_src emacs-lisp(require 'package)(setq package-archives '(("melpa" . "https://melpa.org/packages/")("org" . "https://orgmode.org/elpa/")("gnu" . "https://elpa.gnu.org/packages/")))(package-initialize);; Bootstrap use-package if not installed(unless (package-installed-p 'use-package)(package-refresh-contents)(package-install 'use-package));; Ensure packages are installed automatically(setq use-package-always-ensure t)#+end_src* Appearance** Fonts#+begin_src emacs-lisp;; Set the default font for Latin, Greek, and Cyrillic(set-face-attribute 'default nil:family "SF Mono Terminal Regular":height 160) ;; Adjust height as needed(set-face-attribute 'fixed-pitch nil:family (face-attribute 'default :family):height (face-attribute 'default :height):weight (face-attribute 'default :weight))(set-face-attribute 'fixed-pitch-serif nil:family (face-attribute 'default :family):height (face-attribute 'default :height):weight (face-attribute 'default :weight));; Set the font for CJK characters to Source Han Serif with double width(dolist (charset '(kana han cjk-misc bopomofo))(set-fontset-font t charset(font-spec :family "Source Han Serif" :height 0.85)nil 'append));; Fallback to Andale Mono for any Unicode characters not covered by the above(set-fontset-font t 'unicode(font-spec :family "Andale Mono")nil 'append)#+end_src** Mac env. specific settings#+begin_src emacs-lisp(menu-bar-mode 1)(toggle-scroll-bar -1)(tool-bar-mode -1)(add-to-list 'default-frame-alist '(ns-transparent-titlebar . t))(add-to-list 'default-frame-alist '(ns-appearance . dark))#+end_src** Theming and modeline#+begin_src emacs-lisp(use-package bliss-theme:ensure t:config(load-theme 'bliss t))(use-package minions:ensure t:config(setq minions-mode-line-lighter "多")(setq minions-mode-line-delimiters '("" . ""))(minions-mode 1))#+end_src* QoL Packages#+begin_src emacs-lisp(use-package bind-key:ensure t)(use-package olivetti:ensure t)(use-package vertico:ensure t:init(vertico-mode)(setq vertico-cycle t)) ;; Cycle through options like ivy;; Vertico for better minibuffer completion (replaces ivy)(use-package vertico:ensure t:init(vertico-mode)(setq vertico-cycle t)) ;; Cycle through options like ivy;; Marginalia for annotations (docstrings, keybindings, etc.)(use-package marginalia:ensure t:init(marginalia-mode));; Consult for enhanced M-x, buffer switching, and more (replaces counsel)(use-package consult:ensure t:demand t:bind(("C-s" . consult-line) ;; Replaces swiper("C-x b" . consult-buffer) ;; Replaces counsel-switch-buffer("C-M-j" . consult-buffer) ;; Buffer switch (ivy-like behavior):map minibuffer-local-map("C-r" . consult-history))) ;; Replaces counsel-minibuffer-history;; Orderless for fuzzy matching (replaces ivy's fuzzy searching)(use-package orderless:ensure t:init(setq completion-styles '(orderless basic)orderless-matching-styles '(orderless-literalorderless-regexporderless-flex)));; Evil Mode (Vi-like keybindings)(use-package evil:ensure t:init(setq evil-want-integration tevil-want-keybinding nil)(evil-mode 1));; Evil-collection for better integration with Emacs commands(use-package evil-collection:ensure t:after evil:config(evil-collection-init))(use-package evil-org:ensure t:after org:hook (org-mode . (lambda () evil-org-mode)):config(require 'evil-org-agenda)(evil-org-agenda-set-keys));; Replace buffer switcher with consult-buffer in Evil ex-mode(evil-ex-define-cmd "b" 'consult-buffer);; Which-key for displaying available keybindings(use-package which-key:ensure t:init(which-key-mode));; Persist minibuffer history(use-package savehist:ensure t:init(savehist-mode));; Embark for acting on minibuffer selections(use-package embark:ensure t:bind(("C-." . embark-act) ;; Trigger actions on selected candidates):init(setq embark-prompter 'embark-keymap-prompter));; Embark-consult for seamless integration(use-package embark-consult:ensure t:after (embark consult):hook(embark-collect-mode . consult-preview-at-point-mode))(add-hook 'prog-mode-hook 'display-line-numbers-mode);; Define a function to clean up whitespace in the buffer(defun yaqub/cleanup-buffer-whitespace ()"Clean up whitespace in the buffer, including converting tabs to spaces."(interactive)(whitespace-cleanup));; Define a function to set the key binding in programming modes(defun yaqub/set-cleanup-whitespace-key ()(local-set-key (kbd "C-c w") 'yaqub/cleanup-buffer-whitespace));; Add the key binding function to the prog-mode-hook(add-hook 'prog-mode-hook 'yaqub/set-cleanup-whitespace-key)#+end_src** Modeline appearance#+begin_src emacs-lisp;; Set all modeline text to orange(set-face-attribute 'mode-line nil:foreground "orange":background (face-attribute 'mode-line :background):weight 'normal)(set-face-attribute 'mode-line-inactive nil:foreground "orange":background (face-attribute 'mode-line-inactive :background):weight 'normal);; Set modeline buffer ID to Microgramma(set-face-attribute 'mode-line-buffer-id nil:family "MicrogrammaDMedExt":weight 'normal)#+end_src#+RESULTS:** Evil undo tree#+begin_src emacs-lisp(use-package undo-tree:ensure t:config(global-undo-tree-mode)(evil-set-undo-system 'undo-tree))#+end_src* Coding** Enable line numbers in prog-mode#+begin_src emacs-lisp(add-hook 'prog-mode-hook 'display-line-numbers-mode)#+end_src** Enable whitespace cleanup in prog-mode#+begin_src emacs-lisp;; Define a function to clean up whitespace in the buffer(defun yaqub/cleanup-buffer-whitespace ()"Clean up whitespace in the buffer, including converting tabs to spaces."(interactive)(whitespace-cleanup));; Define a function to set the key binding in programming modes(defun yaqub/set-cleanup-whitespace-key ()(local-set-key (kbd "C-c w") 'yaqub/cleanup-buffer-whitespace));; Add the key binding function to the prog-mode-hook(add-hook 'prog-mode-hook 'yaqub/set-cleanup-whitespace-key)#+end_src** Setup YasnippetYasnippet is a template system for Emacs.#+begin_src emacs-lisp(use-package yasnippet:ensure t:init(yas-global-mode 1))#+end_src** Enable dired-sidebar#+begin_src emacs-lisp(use-package dired-sidebar:bind (("C-x C-n" . dired-sidebar-toggle-sidebar)):ensure t:commands (dired-sidebar-toggle-sidebar):init(add-hook 'dired-sidebar-mode-hook(lambda ()(unless (file-remote-p default-directory)(auto-revert-mode)))):config(push 'toggle-window-split dired-sidebar-toggle-hidden-commands)(push 'rotate-windows dired-sidebar-toggle-hidden-commands)(setq dired-sidebar-subtree-line-prefix "__")(setq dired-sidebar-theme 'vscode)(setq dired-sidebar-use-term-integration t)(setq dired-sidebar-use-custom-font t))#+end_src** Setup Company-modeCompany mode is a text completion framework.#+begin_src emacs-lisp(use-package company:ensure t:init(global-company-mode))#+end_src*** Setup Company-boxCompany-box is a frontend for company-mode, it provides a dropdown menu interface for completions.#+begin_src emacs-lisp(use-package company-box:ensure t:hook (company-mode . company-box-mode))#+end_src** Setup Editorconfig#+begin_src emacs-lisp(use-package editorconfig:ensure t:config(editorconfig-mode 1))#+end_src** MagitMagit is an interface to the version control system Git, implemented as an Emacs package. It aspires to be a complete Git porcelain.#+begin_src emacs-lisp(use-package magit:ensure t:bind (("C-x g" . magit-status)))#+end_src** Auto-install treesit grammars#+begin_src emacs-lisp(use-package treesit-auto:ensure t:config(setq treesit-auto-install 'prompt) ; Automatically install grammars(global-treesit-auto-mode))#+end_src** Smart Parens#+begin_src emacs-lisp(use-package smartparens:ensure smartparens ;; install the package:hook (prog-mode text-mode markdown-mode) ;; add `smartparens-mode` to these hooks:config;; load default config(require 'smartparens-config))#+end_src* Writing** Global bibliography variables#+begin_src emacs-lisp(setq yaqub/global-bibliography '("~/Zotero/References.bib")yaqub/global-library-path '("~/Zotero")yaqub/global-notes-path "~/Orgfiles/roam/")#+end_src** Setup OrgHere, we separate the org setup into its own function for clarity.#+begin_src emacs-lisp(use-package org:ensure t:custom(org-hide-emphasis-markers t)(org-startup-indented t)(org-startup-with-inline-images t):config;; Enable olivetti on all org buffers(add-hook 'org-mode-hook 'olivetti-mode);; add keybindings for org-mark-ring-goto at C-c C-<left> and C-c C-<right>(define-key org-mode-map (kbd "C-c <left>") 'org-mark-ring-goto)(define-key org-mode-map (kbd "C-c <right>") 'org-mark-ring-goto);; add keybindings for org-mark-ring-push at C-c C-<up> and C-c C-<down>(define-key org-mode-map (kbd "C-c <up>") 'org-mark-ring-push)(define-key org-mode-map (kbd "C-c <down>") 'org-mark-ring-push))#+end_src*** Org-roamVery important.#+begin_src emacs-lisp(use-package org-roam:ensure t:custom(org-roam-directory "~/Orgfiles/roam"):bind (("C-c n f" . org-roam-node-find)("C-c n i" . org-roam-node-insert)("C-c n g" . org-roam-graph)("C-c n c" . org-roam-capture)("C-c n d" . org-roam-dailies-goto-today)("C-c n D" . org-roam-dailies-goto-date)))#+end_src*** Making sure org links open in the same window#+begin_src emacs-lisp(setq org-link-frame-setup '((file . find-file)))#+end_srcWhen org-roam is enabled, make org-attach always attach to the /file/, not the /heading/.#+begin_src emacs-lisp(defun yaqub/org-attach-use-file-id ()"Use the top-level :ID: property for attachments unless overridden by :ATTACH_INDIVIDUALLY:."(save-excursion(goto-char (point-min))(let ((file-id (org-entry-get (point) "ID" t))(attach-individual (org-entry-get (point-min) "ATTACH_INDIVIDUALLY")))(if (and file-id (not attach-individual))(setq-local org-attach-id-dir (concat (file-name-as-directory org-attach-directory) file-id))))))(add-hook 'org-mode-hook 'yaqub/org-attach-use-file-id)(defun yaqub/org-attach-individually ()"Add :ATTACH_INDIVIDUALLY: property to the current heading."(interactive)(org-set-property "ATTACH_INDIVIDUALLY" "t")(message ":ATTACH_INDIVIDUALLY: property added."))(defun yaqub/org-attach-file-to-file-id ()"Attach a file to the top-level ID if present, regardless of cursor position."(interactive)(save-excursion(goto-char (point-min))(let ((file-id (org-entry-get (point) "ID" t)))(if file-id(setq-local org-attach-id-dir (concat (file-name-as-directory org-attach-directory) file-id)))))(save-excursion(goto-char (point-min))(org-attach)));; Bind this to the usual attachment keybinding (C-c c-a)(with-eval-after-load 'org(define-key org-mode-map (kbd "C-c c-a") #'yaqub/org-attach-file-to-file-id))#+end_src** Setup LaTeX*** Set up AucTeX#+begin_src emacs-lisp(use-package auctex:ensure t:mode ("\\.tex\\'" . LaTeX-mode):config(setq TeX-auto-save t)(setq TeX-parse-self t)(setq-default TeX-master nil)(add-hook 'LaTeX-mode-hook 'visual-line-mode)(add-hook 'LaTeX-mode-hook 'flyspell-mode)(add-hook 'LaTeX-mode-hook 'LaTeX-math-mode)(add-hook 'LaTeX-mode-hook 'turn-on-reftex)(setq reftex-plug-into-AUCTeX t)(setq TeX-PDF-mode t);; Use Biber with AUCTeX(setq TeX-command-BibTeX "Biber"))#+end_src* Reading** Setup elfeed*** Elfeed#+begin_src emacs-lisp(use-package elfeed:ensure t)#+end_src*** TODO Elfeed Org*** TODO Elfeed Youtube* Anki Integration#+begin_src emacs-lisp(use-package anki-editor:ensure t:config(global-set-key (kbd "C-c a a") 'anki-editor-insert-note)(global-set-key (kbd "C-c a c") 'anki-editor-cloze-region)(global-set-key (kbd "C-c a p") 'anki-editor-push-notes))#+end_src* Mentor Torrent Client#+begin_src emacs-lisp(use-package mentor:ensure t:after evil:config(setq mentor-rtorrent-external-rpc "~/.rtorrent-rpc.socket")(evil-set-initial-state 'mentor-mode 'emacs))#+end_src* Minibuffer Shortcuts#+begin_src emacs-lisp;; the command "eval-init" evaluates init.el(defun eval-init ()(interactive)(load-file "~/.emacs.d/init.el"));; the command "home" opens home orgfile(defun home ()(interactive)(find-file "/media/storage/Orgfiles/roam/home.org"));; the command "todo" opens todo orgfile(defun todo ()(interactive)(find-file "/media/storage/Orgfiles/roam/todo.org"));; the command "yaqubmacs" opens dired at ~/Development/yaqubmacs(defun yaqubmacs ()(interactive)(dired "/media/storage/Development/yaqubmacs"))#+END_SRC* Safe local varsUnsafe, but convenient#+begin_src emacs-lisp(setq enable-local-variables :all)#+end_src