#+TITLE: Doom Emacs Configuration #+AUTHOR: Amr Gharbeia * early-init.el :PROPERTIES: :header-args: :tangle ~/.config/emacs/early-init.el :END: #+begin_src emacs-lisp (setq package-enable-at-startup nil) ;;Run Emacs as a server (require 'server) (unless (server-running-p) (server-start)) (defvar server-max-buffers 100) #+end_src * init.el :PROPERTIES: :header-args: :tangle ~/.config/emacs/init.el :END: #+begin_src emacs-lisp (doom! :input ;; Disable some input methods as I do not use them -chinese -cyrillic -japanese -korean -latin -multilang -persian -thai :completion company ;;helm ivy :ui doom ;;doom-dashboard ;;doom-quit ;;(emoji +unicode) hl-todo hydra ;; indent-guides ;; ligatures menu minimap modeline nav-flash neotree ophints (popup +defaults) tabs treemacs workspaces zen :editor ;; (evil +everywhere) file-templates fold (format +onsave) ;;god ;;lispy multiple-cursors ;;objed snippets ;;word-wrap :emacs dired electric ibuffer undo vc :term ;;eshell shell ;;term ;;vterm :checkers syntax ;;spell :tools ;;ansi-colors ;;debugger ;;direnv docker editorconfig ;;ein ;;eval lookup lsp magit make pass rgb taskrunner ;;terraform tmux ;;tree-sitter :os (:if IS-MAC macos) ;;tty ;;unicode :lang ;;agda ;;assembly ;;cc ;;clojure ;;common-lisp ;;coq ;;crystal ;;csharp ;;data ;;dart ;;elixir ;;elm emacs-lisp ;;erlang ;;ess ;;fsharp ;;fennel ;;fontend ;;gleam ;;go ;;graphql ;;haskell ;;hy ;;idris ;;java ;;javascript ;;julia ;;kotlin ;;latex ;;lean ;;lua ;;markdown ;;nim ;;nix ;;ocaml ;;purescript ;;plantuml ;;powershell ;;prolog ;;python ;;racket ;;raku ;;ruby ;;rust ;;scala ;;scheme ;;sh ;;sql ;;swift ;;terraform ;;web :email ;;(mu4e +org) ;;notmuch ;;smtp :app calendar ;;chat ;;irc ;;rss :config ;;default (org +roam2 +capture) ;;pdf ;;email ;;snippets ;; +smartparens +private/my-config secrets ) #+end_src * packages.el :PROPERTIES: :header-args: :tangle ~/.config/emacs/packages.el :END: #+begin_src emacs-lisp (package! flycheck) (package! org-modern) (package! org-super-agenda) (package! org-gtd) (package! org-roam) (package! sqlite3) (package! nov) (package! pass) (package! auth-source) (package! beancount :recipe (:host github :repo "beancount/beancount-mode")) (package! calibredb) (package! docker) (package! chemtable) (package! bash-completion) (package! org-noter) (package! org-noter-pdftools) (package! ellama) #+end_src * config.el :PROPERTIES: :header-args: :tangle ~/.config/emacs/config.el :END: #+begin_src emacs-lisp ;;; Package --- Summary ;;; Commentary: ;;; Code: ;; -*- lexical-binding: t; -*- ;; Front Matter (defvar custom-file (expand-file-name "custom.el" user-emacs-directory)) (when (file-exists-p custom-file) (load custom-file)) (defvar inhibit-startup-message t) (savehist-mode) (subword-mode) (defvar sentence-end-double-space nil) (add-hook 'server-done-hook (lambda () (delete-frame))) (desktop-save-mode t) (use-package! flycheck :init (global-flycheck-mode) :diminish (flycheck-mode . "") :config (add-hook 'after-init-hook #'global-flycheck-mode) (setq flycheck-emacs-lisp-load-path 'inherit) (setq flycheck-emacs-lisp-load-path (concat user-emacs-directory "straight/build"))) (use-package! org :config (defvar org-outline-path-complete-in-steps nil) (defvar org-pretty-entities t) ; Improve org mode looks (defvar org-hide-emphasis-markers t) ; Hide emphasis markup (defvar org-num-mode nil) (defvar org-startup-folded 'shw2levels) (defvar org-pretty-entities t) ; Improve org mode looks (defvar org-hide-emphasis-markers t) ; Hide emphasis markup (defvar org-num-mode nil) (defvar org-list-demote-modify-bullet t) (defvar org-src-fontify-natively t) (defvar org-src-tab-acts-natively t) (defvar org-startup-with-inline-images t) (defvar org-image-actual-width '300) (defvar org-deadline-warning-days 7) (defvar org-agenda-skip-additional-timestamps-same-entry t) (defvar org-agenda-span 'fortnight) (defvar org-todo-keywords '( (sequence "TODO(t)" "NEXT(n)" "|" "DONE(d!)") (sequence "WAIT(w@/!)" "|" "CNCL(c@)") )) (defvar org-todo-keyword-faces '( ("TODO" :foreground "red" :weight bold) ("NEXT" :foreground "red" :weight bold) ("WAIT" :foreground "yellow" :weight bold) ("DONE" :foreground "green" :weight bold) ("CNCL" :foreground "blue" :weight bold) )) (defvar org-enforce-todo-dependencies t) (defvar org-tags-exclude-from-inheritance '( "crypt" "!private" )) (defvar org-log-into-drawer "LOGBOOK") (defvar org-clock-into-drawer t) (defvar org-habit-graph-column 80) (defvar org-habit-show-habits-only-for-today nil) (defvar org-refile-targets '((nil :maxlevel . 9) (org-agenda-files :maxlevel . 9))) (defvar org-outline-path-complete-in-steps nil) (defvar org-refile-allow-creating-parent-nodes 'confirm) (defvar org-babel-do-load-languages 'org-babel-load-languages '((shell . t))) :bind (("C-c l" . org-store-link) ("C-c a" . org-agenda) ("C-c c" . org-capture) :map org-mode-map)) (defun org-summary-todo (n-done n-not-done) "Switch entry to 'DONE' when all subentries are done, to 'TODO' otherwise. Uses N-DONE and N-NOT-DONE" (let (org-log-done org-log-states) ; turn off logging (org-todo (if (= n-not-done 0) "DONE" "TODO") ) ) ) (add-hook 'org-after-todo-statistics-hook #'org-summary-todo) (use-package! org-modern :config ;; Choose some fonts (set-face-attribute 'default nil :family "sans-serif") (set-face-attribute 'variable-pitch nil :family "sans-serif") (set-face-attribute 'org-modern-symbol nil :family "Iosevka") ;; Edit settings (defvar org-auto-align-tags nil) (defvar org-tags-column 0) (defvar org-catch-invisible-edits 'show-and-error) (defvar org-special-ctrl-a/e t) (defvar org-insert-heading-respect-content t) ;; Org styling, hide markup etc. (defvar org-hide-emphasis-markers t) (defvar org-pretty-entities t) ;; Agenda styling (defvar org-agenda-tags-column 0) (defvar org-agenda-block-separator ?─) (defvar org-agenda-time-grid '((daily today require-timed) (800 1000 1200 1400 1600 1800 2000) " ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄")) (defvar org-agenda-current-time-string "◀── now ─────────────────────────────────────────────────") ;; Ellipsis styling (defvar org-ellipsis "…") (set-face-attribute 'org-ellipsis nil :inherit 'default :box nil) (global-org-modern-mode)) (use-package! org-super-agenda) (use-package! org-gtd :after org :config ;; Keeping these two settings on instead of enabling (org-gtd-mode) until this issue is resolved https://github.com/Trevoke/org-gtd.el/issues/198 (setq org-edna-use-inheritance t) (org-edna-mode) ;; (org-gtd-mode) :bind ( ("C-c d c" . org-gtd-capture) ("C-c d e" . org-gtd-engage) ("C-c d p" . org-gtd-process-inbox) :map org-gtd-clarify-map ("C-c c" . org-gtd-organize))) (use-package! org-roam :after org :config (org-roam-db-autosync-enable) (require 'org-roam-dailies) :bind ( ("C-c n f" . org-roam-node-find) ("C-c n g" . org-roam-graph) ("C-c n r" . org-roam-node-random) ("C-c n h" . org-roam-node-convert-headline) ("C-c n i" . org-roam-node-insert) ("C-c n o" . org-id-get-create) ("C-c n t" . org-roam-tag-add) ("C-c n a" . org-roam-alias-add) ("C-c n l" . org-roam-buffer-display-dedicated) )) (defun my/org-convert-orgzly-to-org-protocol () "Reformat Orgzly bookmark at point to org-protocol bookmark." (interactive) (when (org-at-heading-p) (let ((headline (nth 4 (org-heading-components)))) ;; Find and store the link. Delete the link line. (search-forward-regexp "^https?://\\S-*" nil t) (let ((link (match-string 0))) (beginning-of-line) (kill-line) ;; Delete any trailing blank spaces (org-back-to-heading) (end-of-line) (when (not (org-on-heading-p)) (delete-char 1) ) ;; Set new headline (goto-char (org-entry-beginning-position)) (org-edit-headline (format "[[%s][%s]]" link headline)) ;; Set new properties (org-set-property "TITLE" headline) (org-set-property "URI" link) (message "Reformatted Orgzly bookmark at point to org-protocol bookmark") ) ) ) ) (use-package! calibredb :config (setq calibredb-format-all-the-icons t) (setq calibredb-format-icons-in-terminal t) ;; Forcefully reset the variable after loading calibredb (defvar calibredb-root-dir (concat (getenv "HOME") "/library/books")) (defvar calibredb-db-dir (expand-file-name "metadata.db" calibredb-root-dir)) ; (defvar calibredb-library-alist (concat (getenv "HOME") "/library/books")) ;; (defvar calibredb-search-page-max-rows 1000) (defvar calibredb-id-width 6) (defvar calibredb-title-width 100) (defvar calibredb-format-width 0) (defvar calibredb-date-width 0) (defvar calibredb-author-width 20) (defvar calibredb-comment-width 0) (defvar calibredb-tag-width 0) (defvar calibredb-show-mode-map (let ((map (make-sparse-keymap))) (define-key map "?" #'calibredb-entry-dispatch) (define-key map "o" #'calibredb-find-file) (define-key map "O" #'calibredb-find-file-other-frame) (define-key map "V" #'calibredb-open-file-with-default-tool) (define-key map "s" #'calibredb-set-metadata-dispatch) (define-key map "e" #'calibredb-export-dispatch) (define-key map "q" #'calibredb-entry-quit) (define-key map "y" #'calibredb-yank-dispatch) (define-key map "," #'calibredb-quick-look) (define-key map "." #'calibredb-dired-open) (define-key map "\M-/" #'calibredb-rga) (define-key map "\M-t" #'calibredb-set-metadata--tags) (define-key map "\M-a" #'calibredb-set-metadata--author_sort) (define-key map "\M-A" #'calibredb-set-metadata--authors) (define-key map "\M-T" #'calibredb-set-metadata--title) (define-key map "\M-c" #'calibredb-set-metadata--comments) map) "Keymap for `calibredb-show-mode'.") (defvar calibredb-search-mode-map (let ((map (make-sparse-keymap))) (define-key map [mouse-3] #'calibredb-search-mouse) (define-key map (kbd "") #'calibredb-find-file) (define-key map "?" #'calibredb-dispatch) (define-key map "a" #'calibredb-add) (define-key map "A" #'calibredb-add-dir) (define-key map "c" #'calibredb-clone) (define-key map "d" #'calibredb-remove) (define-key map "D" #'calibredb-remove-marked-items) (define-key map "j" #'calibredb-next-entry) (define-key map "k" #'calibredb-previous-entry) (define-key map "l" #'calibredb-virtual-library-list) (define-key map "L" #'calibredb-library-list) (define-key map "n" #'calibredb-virtual-library-next) (define-key map "N" #'calibredb-library-next) (define-key map "p" #'calibredb-virtual-library-previous) (define-key map "P" #'calibredb-library-previous) (define-key map "s" #'calibredb-set-metadata-dispatch) (define-key map "S" #'calibredb-switch-library) (define-key map "o" #'calibredb-find-file) (define-key map "O" #'calibredb-find-file-other-frame) (define-key map "v" #'calibredb-view) (define-key map "V" #'calibredb-open-file-with-default-tool) (define-key map "," #'calibredb-quick-look) (define-key map "." #'calibredb-dired-open) (define-key map "y" #'calibredb-yank-dispatch) (define-key map "b" #'calibredb-catalog-bib-dispatch) (define-key map "e" #'calibredb-export-dispatch) (define-key map "r" #'calibredb-search-refresh-and-clear-filter) (define-key map "R" #'calibredb-search-clear-filter) (define-key map "q" #'calibredb-search-quit) (define-key map "m" #'calibredb-mark-and-forward) (define-key map "f" #'calibredb-toggle-favorite-at-point) (define-key map "x" #'calibredb-toggle-archive-at-point) (define-key map "h" #'calibredb-toggle-highlight-at-point) (define-key map "u" #'calibredb-unmark-and-forward) (define-key map "i" #'calibredb-edit-annotation) (define-key map (kbd "") #'calibredb-unmark-and-backward) (define-key map (kbd "") #'calibredb-toggle-view) (define-key map (kbd "TAB") #'calibredb-toggle-view-at-point) (define-key map "\M-n" #'calibredb-show-next-entry) (define-key map "\M-p" #'calibredb-show-previous-entry) (define-key map "/" #'calibredb-search-live-filter) (define-key map "\M-t" #'calibredb-set-metadata--tags) (define-key map "\M-a" #'calibredb-set-metadata--author_sort) (define-key map "\M-A" #'calibredb-set-metadata--authors) (define-key map "\M-T" #'calibredb-set-metadata--title) (define-key map "\M-c" #'calibredb-set-metadata--comments) map) "Keymap for `calibredb-search-mode'.") ) (use-package! org-noter) (use-package! org-noter-pdftools :after org-noter :config ;; Add a function to ensure precise note is inserted (defun org-noter-pdftools-insert-precise-note (&optional toggle-no-questions) (interactive "P") (org-noter--with-valid-session (let ((org-noter-insert-note-no-questions (if toggle-no-questions (not org-noter-insert-note-no-questions) org-noter-insert-note-no-questions)) (org-pdftools-use-isearch-link t) (org-pdftools-use-freepointer-annot t)) (org-noter-insert-note (org-noter--get-precise-info))))) ;; fix https://github.com/weirdNox/org-noter/pull/93/commits/f8349ae7575e599f375de1be6be2d0d5de4e6cbf (defun org-noter-set-start-location (&optional arg) "When opening a session with this document, go to the current location. With a prefix ARG, remove start location." (interactive "P") (org-noter--with-valid-session (let ((inhibit-read-only t) (ast (org-noter--parse-root)) (location (org-noter--doc-approx-location (when (called-interactively-p 'any) 'interactive)))) (with-current-buffer (org-noter--session-notes-buffer session) (org-with-wide-buffer (goto-char (org-element-property :begin ast)) (if arg (org-entry-delete nil org-noter-property-note-location) (org-entry-put nil org-noter-property-note-location (org-noter--pretty-print-location location)))))))) (with-eval-after-load 'pdf-annot (add-hook 'pdf-annot-activate-handler-functions #'org-noter-pdftools-jump-to-note))) (use-package! nov :config (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))) (use-package! pass) (use-package! auth-source :config (auth-source-pass-enable)) (use-package! bash-completion :config (require 'bash-completion) (bash-completion-setup) (defvar shell-dynamic-complete-functions t) ) (use-package! docker :bind ("C-c d" . docker)) (use-package! chemtable) (use-package! ellama :ensure t :bind ("C-c e" . ellama) ;; send last message in chat buffer with C-c C-c :hook (org-ctrl-c-ctrl-c-final . ellama-chat-send-last-message) :init (setopt ellama-auto-scroll t) :config ;; show ellama context in header line in all buffers (ellama-context-header-line-global-mode +1) ;; show ellama session id in header line in all buffers (ellama-session-header-line-global-mode +1)) (use-package! eww :config (add-hook 'eww-mode-hook 'visual-line-mode)) (use-package! beancount :config (add-to-list 'auto-mode-alist '("\\.beancount\\'" . beancount-mode)) (add-hook 'beancount-mode-hook #'outline-minor-mode) (define-key beancount-mode-map (kbd "C-c C-n") #'outline-next-visible-heading) (define-key beancount-mode-map (kbd "C-c C-p") #'outline-previous-visible-heading) (add-hook 'beancount-mode-hook #'flymake-bean-check-enable)) (use-package! flyspell :config (setq ispell-program-name "hunspell" ispell-default-dictionary "en_US" ) :diminish (flyspell-mode . "φ") :hook (text-mode . flyspell-mode) :bind ( ("M-" . flyspell-buffer) ("" . flyspell-word) ("C-;" . flyspell-auto-correct-previous-word) ) ) (defun my/fill-or-unfill-paragraph (&optional unfill region) "Fill paragraph (or REGION). With the prefix argument UNFILL, fill it instead." (interactive (progn (barf-if-buffer-read-only) (list (if current-prefix-arg 'fill) t))) (let ((fill-column (if unfill fill-column (point-max)))) (fill-paragraph nil region))) (bind-key "M-q" 'my/fill-or-unfill-paragraph) (defun my/fill-or-unfill-all-paragraphs (&optional unfill) "Fill or unfill all paragraphs in the current buffer. With the prefix argument UNFILL, fill them instead." (interactive (list (if current-prefix-arg 'fill))) (let ((fill-column (if unfill fill-column (point-max)))) (save-excursion (goto-char (point-min)) (while (not (eobp)) (fill-paragraph nil t) (forward-paragraph))))) (bind-key "M-Q" 'my/fill-or-unfill-all-paragraphs) (remove-hook 'text-mode-hook #'turn-on-auto-fill) (add-hook 'text-mode-hook 'turn-on-visual-line-mode) ;;; Package --- Summary ;;; Commentary: ;;; Code: ;; -*- lexical-binding: t; -*- ;; Front Matter (defvar custom-file (expand-file-name "custom.el" user-emacs-directory)) (when (file-exists-p custom-file) (load custom-file)) (defvar inhibit-startup-message t) (savehist-mode) (subword-mode) (defvar sentence-end-double-space nil) (add-hook 'server-done-hook (lambda () (delete-frame))) (desktop-save-mode t) (use-package! flycheck :init (global-flycheck-mode) :diminish (flycheck-mode . "") :config (add-hook 'after-init-hook #'global-flycheck-mode) (setq flycheck-emacs-lisp-load-path 'inherit) (setq flycheck-emacs-lisp-load-path (concat user-emacs-directory "straight/build"))) (use-package! org :config (defvar org-outline-path-complete-in-steps nil) (defvar org-pretty-entities t) ; Improve org mode looks (defvar org-hide-emphasis-markers t) ; Hide emphasis markup (defvar org-num-mode nil) (defvar org-startup-folded 'shw2levels) (defvar org-pretty-entities t) ; Improve org mode looks (defvar org-hide-emphasis-markers t) ; Hide emphasis markup (defvar org-num-mode nil) (defvar org-list-demote-modify-bullet t) (defvar org-src-fontify-natively t) (defvar org-src-tab-acts-natively t) (defvar org-startup-with-inline-images t) (defvar org-image-actual-width '300) (defvar org-deadline-warning-days 7) (defvar org-agenda-skip-additional-timestamps-same-entry t) (defvar org-agenda-span 'fortnight) (defvar org-todo-keywords '( (sequence "TODO(t)" "NEXT(n)" "|" "DONE(d!)") (sequence "WAIT(w@/!)" "|" "CNCL(c@)") )) (defvar org-todo-keyword-faces '( ("TODO" :foreground "red" :weight bold) ("NEXT" :foreground "red" :weight bold) ("WAIT" :foreground "yellow" :weight bold) ("DONE" :foreground "green" :weight bold) ("CNCL" :foreground "blue" :weight bold) )) (defvar org-enforce-todo-dependencies t) (defvar org-tags-exclude-from-inheritance '( "crypt" "!private" )) (defvar org-log-into-drawer "LOGBOOK") (defvar org-clock-into-drawer t) (defvar org-habit-graph-column 80) (defvar org-habit-show-habits-only-for-today nil) (defvar org-refile-targets '((nil :maxlevel . 9) (org-agenda-files :maxlevel . 9))) (defvar org-outline-path-complete-in-steps nil) (defvar org-refile-allow-creating-parent-nodes 'confirm) (defvar org-babel-do-load-languages 'org-babel-load-languages '((shell . t))) :bind (("C-c l" . org-store-link) ("C-c a" . org-agenda) ("C-c c" . org-capture) :map org-mode-map)) (defun org-summary-todo (n-done n-not-done) "Switch entry to 'DONE' when all subentries are done, to 'TODO' otherwise. Uses N-DONE and N-NOT-DONE" (let (org-log-done org-log-states) ; turn off logging (org-todo (if (= n-not-done 0) "DONE" "TODO") ) ) ) (add-hook 'org-after-todo-statistics-hook #'org-summary-todo) (use-package! org-modern :config ;; Choose some fonts (set-face-attribute 'default nil :family "sans-serif") (set-face-attribute 'variable-pitch nil :family "sans-serif") (set-face-attribute 'org-modern-symbol nil :family "Iosevka") ;; Edit settings (defvar org-auto-align-tags nil) (defvar org-tags-column 0) (defvar org-catch-invisible-edits 'show-and-error) (defvar org-special-ctrl-a/e t) (defvar org-insert-heading-respect-content t) ;; Org styling, hide markup etc. (defvar org-hide-emphasis-markers t) (defvar org-pretty-entities t) ;; Agenda styling (defvar org-agenda-tags-column 0) (defvar org-agenda-block-separator ?─) (defvar org-agenda-time-grid '((daily today require-timed) (800 1000 1200 1400 1600 1800 2000) " ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄")) (defvar org-agenda-current-time-string "◀── now ─────────────────────────────────────────────────") ;; Ellipsis styling (defvar org-ellipsis "…") (set-face-attribute 'org-ellipsis nil :inherit 'default :box nil) (global-org-modern-mode)) (use-package! org-super-agenda) (use-package! org-gtd :after org :config ;; Keeping these two settings on instead of enabling (org-gtd-mode) until this issue is resolved https://github.com/Trevoke/org-gtd.el/issues/198 (setq org-edna-use-inheritance t) (org-edna-mode) ;; (org-gtd-mode) :bind ( ("C-c d c" . org-gtd-capture) ("C-c d e" . org-gtd-engage) ("C-c d p" . org-gtd-process-inbox) :map org-gtd-clarify-map ("C-c c" . org-gtd-organize))) (use-package! org-roam :after org :config (org-roam-db-autosync-enable) (require 'org-roam-dailies) :bind ( ("C-c n f" . org-roam-node-find) ("C-c n g" . org-roam-graph) ("C-c n r" . org-roam-node-random) ("C-c n h" . org-roam-node-convert-headline) ("C-c n i" . org-roam-node-insert) ("C-c n o" . org-id-get-create) ("C-c n t" . org-roam-tag-add) ("C-c n a" . org-roam-alias-add) ("C-c n l" . org-roam-buffer-display-dedicated) )) (defun my/org-convert-orgzly-to-org-protocol () "Reformat Orgzly bookmark at point to org-protocol bookmark." (interactive) (when (org-at-heading-p) (let ((headline (nth 4 (org-heading-components)))) ;; Find and store the link. Delete the link line. (search-forward-regexp "^https?://\\S-*" nil t) (let ((link (match-string 0))) (beginning-of-line) (kill-line) ;; Delete any trailing blank spaces (org-back-to-heading) (end-of-line) (when (not (org-on-heading-p)) (delete-char 1) ) ;; Set new headline (goto-char (org-entry-beginning-position)) (org-edit-headline (format "[[%s][%s]]" link headline)) ;; Set new properties (org-set-property "TITLE" headline) (org-set-property "URI" link) (message "Reformatted Orgzly bookmark at point to org-protocol bookmark") ) ) ) ) (use-package! calibredb :config (setq calibredb-format-all-the-icons t) (setq calibredb-format-icons-in-terminal t) ;; Forcefully reset the variable after loading calibredb (defvar calibredb-root-dir (concat (getenv "HOME") "/library/books")) (defvar calibredb-db-dir (expand-file-name "metadata.db" calibredb-root-dir)) ; (defvar calibredb-library-alist (concat (getenv "HOME") "/library/books")) ;; (defvar calibredb-search-page-max-rows 1000) (defvar calibredb-id-width 6) (defvar calibredb-title-width 100) (defvar calibredb-format-width 0) (defvar calibredb-date-width 0) (defvar calibredb-author-width 20) (defvar calibredb-comment-width 0) (defvar calibredb-tag-width 0) (defvar calibredb-show-mode-map (let ((map (make-sparse-keymap))) (define-key map "?" #'calibredb-entry-dispatch) (define-key map "o" #'calibredb-find-file) (define-key map "O" #'calibredb-find-file-other-frame) (define-key map "V" #'calibredb-open-file-with-default-tool) (define-key map "s" #'calibredb-set-metadata-dispatch) (define-key map "e" #'calibredb-export-dispatch) (define-key map "q" #'calibredb-entry-quit) (define-key map "y" #'calibredb-yank-dispatch) (define-key map "," #'calibredb-quick-look) (define-key map "." #'calibredb-dired-open) (define-key map "\M-/" #'calibredb-rga) (define-key map "\M-t" #'calibredb-set-metadata--tags) (define-key map "\M-a" #'calibredb-set-metadata--author_sort) (define-key map "\M-A" #'calibredb-set-metadata--authors) (define-key map "\M-T" #'calibredb-set-metadata--title) (define-key map "\M-c" #'calibredb-set-metadata--comments) map) "Keymap for `calibredb-show-mode'.") (defvar calibredb-search-mode-map (let ((map (make-sparse-keymap))) (define-key map [mouse-3] #'calibredb-search-mouse) (define-key map (kbd "") #'calibredb-find-file) (define-key map "?" #'calibredb-dispatch) (define-key map "a" #'calibredb-add) (define-key map "A" #'calibredb-add-dir) (define-key map "c" #'calibredb-clone) (define-key map "d" #'calibredb-remove) (define-key map "D" #'calibredb-remove-marked-items) (define-key map "j" #'calibredb-next-entry) (define-key map "k" #'calibredb-previous-entry) (define-key map "l" #'calibredb-virtual-library-list) (define-key map "L" #'calibredb-library-list) (define-key map "n" #'calibredb-virtual-library-next) (define-key map "N" #'calibredb-library-next) (define-key map "p" #'calibredb-virtual-library-previous) (define-key map "P" #'calibredb-library-previous) (define-key map "s" #'calibredb-set-metadata-dispatch) (define-key map "S" #'calibredb-switch-library) (define-key map "o" #'calibredb-find-file) (define-key map "O" #'calibredb-find-file-other-frame) (define-key map "v" #'calibredb-view) (define-key map "V" #'calibredb-open-file-with-default-tool) (define-key map "," #'calibredb-quick-look) (define-key map "." #'calibredb-dired-open) (define-key map "y" #'calibredb-yank-dispatch) (define-key map "b" #'calibredb-catalog-bib-dispatch) (define-key map "e" #'calibredb-export-dispatch) (define-key map "r" #'calibredb-search-refresh-and-clear-filter) (define-key map "R" #'calibredb-search-clear-filter) (define-key map "q" #'calibredb-search-quit) (define-key map "m" #'calibredb-mark-and-forward) (define-key map "f" #'calibredb-toggle-favorite-at-point) (define-key map "x" #'calibredb-toggle-archive-at-point) (define-key map "h" #'calibredb-toggle-highlight-at-point) (define-key map "u" #'calibredb-unmark-and-forward) (define-key map "i" #'calibredb-edit-annotation) (define-key map (kbd "") #'calibredb-unmark-and-backward) (define-key map (kbd "") #'calibredb-toggle-view) (define-key map (kbd "TAB") #'calibredb-toggle-view-at-point) (define-key map "\M-n" #'calibredb-show-next-entry) (define-key map "\M-p" #'calibredb-show-previous-entry) (define-key map "/" #'calibredb-search-live-filter) (define-key map "\M-t" #'calibredb-set-metadata--tags) (define-key map "\M-a" #'calibredb-set-metadata--author_sort) (define-key map "\M-A" #'calibredb-set-metadata--authors) (define-key map "\M-T" #'calibredb-set-metadata--title) (define-key map "\M-c" #'calibredb-set-metadata--comments) map) "Keymap for `calibredb-search-mode'.") ) (use-package! org-noter) (use-package! org-noter-pdftools :after org-noter :config ;; Add a function to ensure precise note is inserted (defun org-noter-pdftools-insert-precise-note (&optional toggle-no-questions) (interactive "P") (org-noter--with-valid-session (let ((org-noter-insert-note-no-questions (if toggle-no-questions (not org-noter-insert-note-no-questions) org-noter-insert-note-no-questions)) (org-pdftools-use-isearch-link t) (org-pdftools-use-freepointer-annot t)) (org-noter-insert-note (org-noter--get-precise-info))))) ;; fix https://github.com/weirdNox/org-noter/pull/93/commits/f8349ae7575e599f375de1be6be2d0d5de4e6cbf (defun org-noter-set-start-location (&optional arg) "When opening a session with this document, go to the current location. With a prefix ARG, remove start location." (interactive "P") (org-noter--with-valid-session (let ((inhibit-read-only t) (ast (org-noter--parse-root)) (location (org-noter--doc-approx-location (when (called-interactively-p 'any) 'interactive)))) (with-current-buffer (org-noter--session-notes-buffer session) (org-with-wide-buffer (goto-char (org-element-property :begin ast)) (if arg (org-entry-delete nil org-noter-property-note-location) (org-entry-put nil org-noter-property-note-location (org-noter--pretty-print-location location)))))))) (with-eval-after-load 'pdf-annot (add-hook 'pdf-annot-activate-handler-functions #'org-noter-pdftools-jump-to-note))) (use-package! nov :config (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))) (use-package! pass) (use-package! auth-source :config (auth-source-pass-enable)) (use-package! bash-completion :config (require 'bash-completion) (bash-completion-setup) (defvar shell-dynamic-complete-functions t) ) (use-package! docker :bind ("C-c d" . docker)) (use-package! chemtable) (use-package! ellama :ensure t :bind ("C-c e" . ellama) ;; send last message in chat buffer with C-c C-c :hook (org-ctrl-c-ctrl-c-final . ellama-chat-send-last-message) :init (setopt ellama-auto-scroll t) :config ;; show ellama context in header line in all buffers (ellama-context-header-line-global-mode +1) ;; show ellama session id in header line in all buffers (ellama-session-header-line-global-mode +1)) (use-package! eww :config (add-hook 'eww-mode-hook 'visual-line-mode)) (use-package! beancount :config (add-to-list 'auto-mode-alist '("\\.beancount\\'" . beancount-mode)) (add-hook 'beancount-mode-hook #'outline-minor-mode) (define-key beancount-mode-map (kbd "C-c C-n") #'outline-next-visible-heading) (define-key beancount-mode-map (kbd "C-c C-p") #'outline-previous-visible-heading) (add-hook 'beancount-mode-hook #'flymake-bean-check-enable)) (use-package! flyspell :config (setq ispell-program-name "hunspell" ispell-default-dictionary "en_US" ) :diminish (flyspell-mode . "φ") :hook (text-mode . flyspell-mode) :bind ( ("M-" . flyspell-buffer) ("" . flyspell-word) ("C-;" . flyspell-auto-correct-previous-word) ) ) (defun my/fill-or-unfill-paragraph (&optional unfill region) "Fill paragraph (or REGION). With the prefix argument UNFILL, fill it instead." (interactive (progn (barf-if-buffer-read-only) (list (if current-prefix-arg 'fill) t))) (let ((fill-column (if unfill fill-column (point-max)))) (fill-paragraph nil region))) (bind-key "M-q" 'my/fill-or-unfill-paragraph) (defun my/fill-or-unfill-all-paragraphs (&optional unfill) "Fill or unfill all paragraphs in the current buffer. With the prefix argument UNFILL, fill them instead." (interactive (list (if current-prefix-arg 'fill))) (let ((fill-column (if unfill fill-column (point-max)))) (save-excursion (goto-char (point-min)) (while (not (eobp)) (fill-paragraph nil t) (forward-paragraph))))) (bind-key "M-Q" 'my/fill-or-unfill-all-paragraphs) (remove-hook 'text-mode-hook #'turn-on-auto-fill) (add-hook 'text-mode-hook 'turn-on-visual-line-mode) #+end_src * custom.el :PROPERTIES: :header-args: :tangle ~/.config/emacs/custom.el :END: #+begin_src emacs-lisp ;; To enable an installed theme, just copy the relevant lines below into your ;; ~/.doom.d/config.el file. (custom-set-variables '(user-full-name "Amr Gharbeia") '(email-address "amr@gharbeia.net") '(calendar-location-name "Washington, DC") '(calendar-latitude 39.0) '(calendar-time-zone -300) '(calendar-longitude -77.1) '(calendar-standard-time-zone-name "EST") '(calendar-daylight-time-zone-name "EDT") '(my-laptop-p (equal (system-name) "lilitop")) '(my-server-p (and (equal (system-name) "localhost") (equal user-login-name "root"))) '(my-phone-p (not (null (getenv "ANDROID_ROOT"))) "If non-nil, GNU Emacs is running on Termux.") '(when my-phone-p (defvar gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")) '(global-auto-revert-mode) ; simplifies syncing '(org-directory (concat (getenv "HOME") "/org/")) '(org-default-notes-file (concat org-directory "/inbox.org")) '(org-attach-id-dir (concat org-directory "/library")) '(org-noter-notes-search-path (list (concat org-directory "/library/books"))) '(org-noter-default-notes-file-names '("books.org")) '(org-agenda-files (list (concat org-directory "/inbox.org") (concat org-directory "/org-gtd-tasks.org") )) '(org-gtd-directory org-directory) '(org-gtd-organize-hooks '(org-gtd-set-area-of-focus org-set-tags-command)) '(org-gtd-areas-of-focus '("Atoms" "Bits" "Cells" "Flags" "Business" "Wealth" "Learning" "Skills" "Privacy" "Archive" "Library" "Writing" "Health" "Home" "Family" "Social" "Egypt" )) '(org-gtd-clarify-show-horizons 'right) ) '(org-capture-templates '(("p" "Protocol" entry (file "inbox.org") "* %^{Title}\nSource: %u, %c\n #+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n\n%?") ("L" "Protocol Link" entry (file "inbox.org") "* %? [[%:link][%:description]]\n:PROPERTIES:\n:TITLE: %:description\n:URI: %:link\n:CREATED: %U\n:END:" :prepend nil :empty-lines 1 :created t :kill-buffer t))) '(org-protocol-default-template-key "L") '(org-roam-capture-templates '(("L" "link" plain (function org-roam--capture-get-point) "%?" :file-name "web/%<%Y-%m-%dT%H%M%S>.org" :head "#+TITLE: ${title}\n#+CREATED: %<%Y-%m-%dT%H%M%S>" :immediate-finish t :unnarrowed t) ("h" "hugo post" plain "%?" :target (file+head "posts/${slug}.org" "#+TITLE: ${title}\n#+DATE: %U\n#+HUGO_BASE_DIR: ~/gharbeia.net\n#+HUGO_SECTION: ./posts\n#+HUGO_AUTO_SET_LASTMOD: t\n#+HUGO_TAGS: article\n#+HUGO_DRAFT: true\n") :immediate-finish t :unnarrowed t) ("p" "person" plain "%?" :if-new (file+head "people/${slug}.org" "#+TITLE: ${title}") :immediate-finish t :unnarrowed t))) '(org-roam-dailies-capture-templates '(("d" "daily" plain "" :target ("file+heaed %<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n\n") :immediate-finish t))) (custom-set-faces '(default ((t (:inherit default :height 120)))) '(org-level-1 ((t (:height 1.5)))) '(org-level-2 ((t (:height 1.3)))) '(org-level-3 ((t (:height 1.2)))) '(org-level-4 ((t (:height 1.1)))) '(org-level-5 ((t (:height 1.05)))) '(org-level-6 ((t (:height 1.0)))) '(org-link ((t (:underline t)))) '(org-todo ((t (:foreground "red" :weight bold))))) '(ellama-providers '((("ollama" . (make-llm-ollama :chat-model "gemma3:latest" :embedding-model "gemma3:latest" :default-chat-non-standard-params '(("num_ctx" . 8192))))) . nil) (nil . nil) (nil . nil) (("openai" . (make-llm-openai :key (auth-source-pass-get "api-key" "www/openai.com/amr@gharbeia.net") :chat-model "gpt-4o" :embedding-model "text-embedding-3-large")) . nil) (nil . nil) (("google" . (make-llm-google :key (auth-source-pass-get "gemini-api-key" "www/google.com/amr.gharbeia") :chat-model "latest" :embedding-model "text-embedding-004")) . nil) (("groq" . (make-llm-openai-compatible :url "https://api.groq.com/openai/v1" :key (auth-source-pass-get "api-key" "www/console.groq.com/groq@amr.gharbeia.net") :chat-model "llama3-70b-8192" :embedding-model "llama3-70b-8192")) . nil)) '(ellama-provider "ollama") #+end_src * private/config.el :PROPERTIES: :header-args: :tangle ~/.config/emacs/private/config.el :END: