Files
memex/9_system/doom.org

31 KiB

Doom Emacs Configuration

DONE early-init.el

:PROPERTIES: :header-args: :tangle no

:END:

This ~/.config/emacs/early-init.el conflicts with Doom's default

  (setq package-enable-at-startup nil)

  ;;Run Emacs as a server
  (require 'server)
  (unless (server-running-p) (server-start))
  (defvar server-max-buffers 100)

init.el

:PROPERTIES: :header-args: :tangle ~/.config/doom/init.el: END:

  ;;; init.el -*- lexical-binding: t; -*-

  ;; This file controls what Doom modules are enabled and what order they load
  ;; in. Remember to run 'doom sync' after modifying it!

  ;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's
  ;;      documentation. There you'll find a link to Doom's Module Index where all
  ;;      of our modules are listed, including what flags they support.

  ;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or
  ;;      'C-c c k' for non-vim users) to view its documentation. This works on
  ;;      flags as well (those symbols that start with a plus).
  ;;
  ;;      Alternatively, press 'gd' (or 'C-c c d') on a module to browse its
  ;;      directory (for easy access to its source code).

  (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 +protocol)
   ;;pdf
   ;;email
   ;;snippets
   ;; +smartparens
   +private/my-config
   secrets
      )

packages.el

  ;; -*- no-byte-compile: t; -*-
  ;;; $DOOMDIR/packages.el

  ;; To install a package with Doom you must declare them here and run 'doom sync'
  ;; on the command line, then restart Emacs for the changes to take effect -- or


  ;; To install SOME-PACKAGE from MELPA, ELPA or emacsmirror:
  ;; (package! some-package)

  ;; To install a package directly from a remote git repo, you must specify a
  ;; `:recipe'. You'll find documentation on what `:recipe' accepts here:
  ;; https://github.com/radian-software/straight.el#the-recipe-format
  ;; (package! another-package
  ;;   :recipe (:host github :repo "username/repo"))

  ;; If the package you are trying to install does not contain a PACKAGENAME.el
  ;; file, or is located in a subdirectory of the repo, you'll need to specify
  ;; `:files' in the `:recipe':
  ;; (package! this-package
  ;;   :recipe (:host github :repo "username/repo"
  ;;            :files ("some-file.el" "src/lisp/*.el")))

  ;; If you'd like to disable a package included with Doom, you can do so here
  ;; with the `:disable' property:
  ;; (package! builtin-package :disable t)

  ;; You can override the recipe of a built in package without having to specify
  ;; all the properties for `:recipe'. These will inherit the rest of its recipe
  ;; from Doom or MELPA/ELPA/Emacsmirror:
  ;; (package! builtin-package :recipe (:nonrecursive t))
  ;; (package! builtin-package-2 :recipe (:repo "myfork/package"))

  ;; Specify a `:branch' to install a package from a particular branch or tag.
  ;; This is required for some packages whose default branch isn't 'master' (which
  ;; our package manager can't deal with; see radian-software/straight.el#279)
  ;; (package! builtin-package :recipe (:branch "develop"))

  ;; Use `:pin' to specify a particular commit to install.
  ;; (package! builtin-package :pin "1a2b3c4d5e")


  ;; Doom's packages are pinned to a specific commit and updated from release to
  ;; release. The `unpin!' macro allows you to unpin single packages...
  ;; (unpin! pinned-package)
  ;; ...or multiple packages
  ;; (unpin! pinned-package another-pinned-package)
  ;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
  ;; (unpin! t)


  (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)

config.el

  ;;; Package --- Summary
    ;;; Commentary:
    ;;; Code:

    ;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-

  ;; Place your private configuration here! Remember, you do not need to run 'doom
  ;; sync' after modifying this file!


  ;; Some functionality uses this to identify you, e.g. GPG configuration, email
  ;; clients, file templates and snippets. It is optional.
  ;; (setq user-full-name "John Doe"
  ;;       user-mail-address "john@doe.com")

  ;; Doom exposes five (optional) variables for controlling fonts in Doom:
  ;;
  ;; - `doom-font' -- the primary font to use
  ;; - `doom-variable-pitch-font' -- a non-monospace font (where applicable)
  ;; - `doom-big-font' -- used for `doom-big-font-mode'; use this for
  ;;   presentations or streaming.
  ;; - `doom-symbol-font' -- for symbols
  ;; - `doom-serif-font' -- for the `fixed-pitch-serif' face
  ;;
  ;; See 'C-h v doom-font' for documentation and more examples of what they
  ;; accept. For example:
  ;;
  ;;(setq doom-font (font-spec :family "Fira Code" :size 12 :weight 'semi-light)
  ;;      doom-variable-pitch-font (font-spec :family "Fira Sans" :size 13))
  ;;
  ;; If you or Emacs can't find your font, use 'M-x describe-font' to look them
  ;; up, `M-x eval-region' to execute elisp code, and 'M-x doom/reload-font' to
  ;; refresh your font settings. If Emacs still can't find your font, it likely
  ;; wasn't installed correctly. Font issues are rarely Doom issues!

  ;; There are two ways to load a theme. Both assume the theme is installed and
  ;; available. You can either set `doom-theme' or manually load a theme with the
  ;; `load-theme' function. This is the default:
  (setq doom-theme 'doom-one)

  ;; This determines the style of line numbers in effect. If set to `nil', line
  ;; numbers are disabled. For relative line numbers, set this to `relative'.
  (setq display-line-numbers-type t)

  ;; If you use `org' and don't want your org files in the default location below,
  ;; change `org-directory'. It must be set before org loads!
  (setq org-directory "~/org/")


  ;; Whenever you reconfigure a package, make sure to wrap your config in an
  ;; `after!' block, otherwise Doom's defaults may override your settings. E.g.
  ;;
  ;;   (after! PACKAGE
  ;;     (setq x y))
  ;;
  ;; The exceptions to this rule:
  ;;
  ;;   - Setting file/directory variables (like `org-directory')
  ;;   - Setting variables which explicitly tell you to set them before their
  ;;     package is loaded (see 'C-h v VARIABLE' to look up their documentation).
  ;;   - Setting doom variables (which start with 'doom-' or '+').
  ;;
  ;; Here are some additional functions/macros that will help you configure Doom.
  ;;
  ;; - `load!' for loading external *.el files relative to this one
  ;; - `use-package!' for configuring packages
  ;; - `after!' for running code after a package has loaded
  ;; - `add-load-path!' for adding directories to the `load-path', relative to
  ;;   this file. Emacs searches the `load-path' when you load packages with
  ;;   `require' or `use-package'.
  ;; - `map!' for binding new keys
  ;;
  ;; To get information about any of these functions/macros, move the cursor over
  ;; the highlighted symbol at press 'K' (non-evil users must press 'C-c c k').
  ;; This will open documentation for it, including demos of how they are used.
  ;; Alternatively, use `C-h o' to look up a symbol (functions, variables, faces,
  ;; etc).
  ;;
  ;; You can also try 'gd' (or 'C-c c d') to jump to their definition and see how
  ;; they are implemented.
  (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)

  (defvar user-full-name "Amr Gharbeia")
  (defvar email-address "amr@gharbeia.net")
  (defvar calendar-location-name "Washington, DC")
  (defvar calendar-latitude 39.0)
  (defvar calendar-time-zone -300)
  (defvar calendar-longitude -77.1)
  (defvar calendar-standard-time-zone-name "EST")
  (defvar calendar-daylight-time-zone-name "EDT")

  (defvar my-laptop-p (equal (system-name) "lilitop"))
  (defvar my-server-p (and (equal (system-name) "localhost") (equal user-login-name "root")))
  (defvar 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

  (defvar org-default-notes-file (concat org-directory "inbox.org"))
  (defvar org-attach-id-dir (concat org-directory "library"))
  (defvar org-noter-notes-search-path (list (concat org-directory "library/books")))
  (defvar org-noter-default-notes-file-names '("books.org"))
  (defvar org-agenda-files (list
                            (concat org-directory "inbox.org")
                            (concat org-directory "org-gtd-tasks.org")
                            ))
  (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)
  (require 'org-protocol)
  (defvar org-protocol-default-directory org-directory)
  (defvar org-capture-templates
    `(
      ("p" "Protocol" entry (file (expand-file-name "inbox.org" org-directory))
       "* %^{Title}\nSource: %u, %c\n #+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n\n%?")

      ("L" "Protocol Link" entry (file (expand-file-name "inbox.org" org-directory))
       "* %? [[%: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)
      ))

  (defvar org-protocol-default-template-key "L")
  (use-package! org-roam
    :after org
    :config
    (org-roam-db-autosync-enable)
    (setq org-roam-directory org-directory)
    (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)
            ))
  (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)))
  (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 "<RET>") #'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 "<DEL>") #'calibredb-unmark-and-backward)
        (define-key map (kbd "<backtab>") #'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! 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! flyspell
    :config
    (setq ispell-program-name "hunspell"
          ispell-default-dictionary "en_US"
          )
    :diminish (flyspell-mode . "φ")
    :hook (text-mode . flyspell-mode)
    :bind (
           ("M-<f7>" . flyspell-buffer)
           ("<f7>" . 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)

  ;; To enable an installed theme, just copy the relevant lines below into your
  ;; ~/.doom.d/config.el file.
  (defvar org-gtd-directory org-directory)
  (defvar org-gtd-organize-hooks '(org-gtd-set-area-of-focus
                                   org-set-tags-command))
  (defvar org-gtd-areas-of-focus '("Atoms"
                                   "Bits"
                                   "Cells"
                                   "Flags"
                                   "Business"
                                   "Wealth"
                                   "Learning"
                                   "Skills"
                                   "Privacy"
                                   "Archive"
                                   "Library"
                                   "Writing"
                                   "Health"
                                   "Home"
                                   "Family"
                                   "Social"
                                   "Egypt"
                                   ))
  (defvar org-gtd-clarify-show-horizons 'right)
  (defvar 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)))

  (defvar 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)))))
  (defvar ellama-providers
    '(  ;; <--- Start of the SINGLE quoted list for the variable's value
      (("ollama" make-llm-ollama
        :chat-model "gemma3:latest"
        :embedding-model "gemma3:latest"
        :default-chat-non-standard-params '(("num_ctx" . 8192))))

      ;; Remove the `(nil)` entries, as they are not valid provider configurations.
      ;; You had several (nil) entries in your snippet. If they were intentional
      ;; for some reason (which is highly unlikely for ellama-providers),
      ;; you'd need to confirm ellama's documentation on what they represent.
      ;; Assuming they are unintended:

      (("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"))

      (("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"))

      (("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"))) ;; <--- End of the SINGLE quoted list

    ;; You can optionally add a docstring:
    ;; "A list of Ellama providers and their configurations."
    )

  (defvar ellama-provider "ollama")