[emacs] drop after! and use with-eval-after-load
[~bandali/configs] / init.org
index b5f0618..61af647 100644 (file)
--- a/init.org
+++ b/init.org
@@ -54,6 +54,13 @@ make build
 - [[#header][Header]]
 - [[#initial-setup][Initial setup]]
 - [[#core][Core]]
 - [[#header][Header]]
 - [[#initial-setup][Initial setup]]
 - [[#core][Core]]
+- [[#borg-essentials][Borg's =layer/essentials=]]
+- [[#editing][Editing]]
+- [[#syntax-spell-checking][Syntax and spell checking]]
+- [[#programming-modes][Programming modes]]
+- [[#emacs-enhancements][Emacs enhancements]]
+- [[#email][Email]]
+- [[#blogging][Blogging]]
 - [[#post-initialization][Post initialization]]
 - [[#footer][Footer]]
 
 - [[#post-initialization][Post initialization]]
 - [[#footer][Footer]]
 
@@ -440,39 +447,6 @@ buffers and/or modes.
 
 ** Useful utilities
 
 
 ** Useful utilities
 
-#+begin_src emacs-lisp
-(defun amin-enlist (exp)
-  "Return EXP wrapped in a list, or as-is if already a list."
-(if (listp exp) exp (list exp)))
-
-; from https://github.com/hlissner/doom-emacs/commit/589108fdb270f24a98ba6209f6955fe41530b3ef
-(defmacro after! (features &rest body)
-  "A smart wrapper around `with-eval-after-load'. Supresses warnings during
-compilation."
-  (declare (indent defun) (debug t))
-  (list (if (or (not (bound-and-true-p byte-compile-current-file))
-                (dolist (next (amin-enlist features))
-                  (if (symbolp next)
-                      (require next nil :no-error)
-                    (load next :no-message :no-error))))
-            #'progn
-          #'with-no-warnings)
-        (cond ((symbolp features)
-               `(eval-after-load ',features '(progn ,@body)))
-              ((and (consp features)
-                    (memq (car features) '(:or :any)))
-               `(progn
-                  ,@(cl-loop for next in (cdr features)
-                             collect `(after! ,next ,@body))))
-              ((and (consp features)
-                    (memq (car features) '(:and :all)))
-               (dolist (next (cdr features))
-                 (setq body `(after! ,next ,@body)))
-               body)
-              ((listp features)
-               `(after! (:all ,@features) ,@body)))))
-#+end_src
-
 Convenience macro for =setq='ing multiple variables to the same value:
 
 #+begin_src emacs-lisp
 Convenience macro for =setq='ing multiple variables to the same value:
 
 #+begin_src emacs-lisp
@@ -646,18 +620,30 @@ Enable =winner-mode=.
 (winner-mode 1)
 #+end_src
 
 (winner-mode 1)
 #+end_src
 
-*** Close =*compilation*= on success
+*** Don’t display =*compilation*= on success
+
+Based on https://stackoverflow.com/a/17788551, with changes to use
+=cl-letf= instead of the now obsolete =flet=.
 
 #+begin_src emacs-lisp
 
 #+begin_src emacs-lisp
-(setq compilation-exit-message-function
-      (lambda (status code msg)
-        "Close the compilation window if successful."
-        ;; if M-x compile exits with 0
-         (when (and (eq status 'exit) (zerop code))
-           (bury-buffer)
-           (delete-window (get-buffer-window (get-buffer "*compilation*"))))
-         ;; return the result of compilation-exit-message-function
-         (cons msg code)))
+(with-eval-after-load 'compile
+  (defun amin--compilation-finish-function (buffer outstr)
+    (unless (string-match "finished" outstr)
+      (switch-to-buffer-other-window buffer))
+    t)
+
+  (setq compilation-finish-functions #'amin--compilation-finish-function)
+
+  (require 'cl-macs)
+
+  (defadvice compilation-start
+      (around inhibit-display
+              (command &optional mode name-function highlight-regexp))
+    (if (not (string-match "^\\(find\\|grep\\)" command))
+        (cl-letf (((symbol-function 'display-buffer) #'ignore))
+          (save-window-excursion ad-do-it))
+      ad-do-it))
+  (ad-activate 'compilation-start))
 #+end_src
 
 *** Search for non-ASCII characters
 #+end_src
 
 *** Search for non-ASCII characters
@@ -673,6 +659,12 @@ for this.
 ;; (setq replace-char-fold t)
 #+end_src
 
 ;; (setq replace-char-fold t)
 #+end_src
 
+*** Cursor shape
+
+#+begin_src emacs-lisp
+(setq-default cursor-type 'bar)
+#+end_src
+
 ** Bindings
 
 #+begin_src emacs-lisp
 ** Bindings
 
 #+begin_src emacs-lisp
@@ -742,6 +734,9 @@ In short, my favourite way of life.
         org-edit-src-content-indentation 0
         org-email-link-description-format "Email %c: %s" ; %.30s
         org-highlight-latex-and-related '(entities)
         org-edit-src-content-indentation 0
         org-email-link-description-format "Email %c: %s" ; %.30s
         org-highlight-latex-and-related '(entities)
+        org-use-speed-commands t
+        org-startup-folded 'content
+        org-catch-invisible-edits 'show-and-error
         org-log-done 'time)
   (add-to-list 'org-structure-template-alist '("L" . "src emacs-lisp") t)
   (font-lock-add-keywords
         org-log-done 'time)
   (add-to-list 'org-structure-template-alist '("L" . "src emacs-lisp") t)
   (font-lock-add-keywords
@@ -794,7 +789,7 @@ d/async-babel-tangle]] which uses [[https://github.com/jwiegley/emacs-async][asy
 file.
 
 #+begin_src emacs-lisp
 file.
 
 #+begin_src emacs-lisp
-(after! org
+(with-eval-after-load 'org
   (defvar amin-show-async-tangle-results nil
     "Keep *emacs* async buffers around for later inspection.")
 
   (defvar amin-show-async-tangle-results nil
     "Keep *emacs* async buffers around for later inspection.")
 
@@ -810,7 +805,8 @@ file.
     (let* ((file-tangle-start-time (current-time))
            (file (buffer-file-name))
            (file-nodir (file-name-nondirectory file))
     (let* ((file-tangle-start-time (current-time))
            (file (buffer-file-name))
            (file-nodir (file-name-nondirectory file))
-           (async-quiet-switch "-q"))
+           ;; (async-quiet-switch "-q")
+           )
       (async-start
        `(lambda ()
           (require 'org)
       (async-start
        `(lambda ()
           (require 'org)
@@ -897,8 +893,9 @@ There's no way I could top that, so I won't attempt to.
 
 #+begin_src emacs-lisp
 (use-package swiper
 
 #+begin_src emacs-lisp
 (use-package swiper
-  :bind (("C-s" . swiper)
-         ("C-r" . swiper)))
+  :bind (("C-s"   . swiper)
+         ("C-r"   . swiper)
+         ("C-S-s" . isearch-forward)))
 #+end_src
 
 **** Counsel
 #+end_src
 
 **** Counsel
@@ -924,6 +921,7 @@ There's no way I could top that, so I won't attempt to.
 (use-package eshell
   :defer 1
   :commands eshell
 (use-package eshell
   :defer 1
   :commands eshell
+  :bind ("C-c a s e" . eshell)
   :config
   (eval-when-compile (defvar eshell-prompt-regexp))
   (defun amin/eshell-quit-or-delete-char (arg)
   :config
   (eval-when-compile (defvar eshell-prompt-regexp))
   (defun amin/eshell-quit-or-delete-char (arg)
@@ -940,7 +938,7 @@ There's no way I could top that, so I won't attempt to.
 
   (defun amin|eshell-setup ()
     (make-local-variable 'company-idle-delay)
 
   (defun amin|eshell-setup ()
     (make-local-variable 'company-idle-delay)
-    (setq company-idle-delay nil)
+    (defvar company-idle-delay nil)
     (bind-keys :map eshell-mode-map
                ("C-d"   . amin/eshell-quit-or-delete-char)
                ("C-S-l" . amin/eshell-clear)
     (bind-keys :map eshell-mode-map
                ("C-d"   . amin/eshell-quit-or-delete-char)
                ("C-S-l" . amin/eshell-clear)
@@ -979,6 +977,13 @@ There's no way I could top that, so I won't attempt to.
    '(("default"
       ("dired" (mode . dired-mode))
       ("org"   (mode . org-mode))
    '(("default"
       ("dired" (mode . dired-mode))
       ("org"   (mode . org-mode))
+      ("gnus"
+       (or
+        (mode . gnus-group-mode)
+        (mode . gnus-summary-mode)
+        (mode . gnus-article-mode)
+        ;; not really, but...
+        (mode . message-mode)))
       ("web"
        (or
         (mode . web-mode)
       ("web"
        (or
         (mode . web-mode)
@@ -988,20 +993,21 @@ There's no way I could top that, so I won't attempt to.
       ("shell"
        (or
         (mode . eshell-mode)
       ("shell"
        (or
         (mode . eshell-mode)
-        (mode . shell-mode)))
-      ("notmuch" (name . "\*notmuch\*"))
+        (mode . shell-mode)
+        (mode . term-mode)))
       ("programming"
        (or
         (mode . python-mode)
       ("programming"
        (or
         (mode . python-mode)
+        (mode . c-mode)
         (mode . c++-mode)
         (mode . c++-mode)
-        (mode . emacs-lisp-mode)))
+        (mode . emacs-lisp-mode)
+        (mode . scheme-mode)
+        (mode . haskell-mode)
+        (mode . lean-mode)))
       ("emacs"
        (or
         (name . "^\\*scratch\\*$")
       ("emacs"
        (or
         (name . "^\\*scratch\\*$")
-        (name . "^\\*Messages\\*$")))
-      ("slack"
-       (or
-        (name . "^\\*Slack*"))))))
+        (name . "^\\*Messages\\*$"))))))
   (ibuffer-formats
    '((mark modified read-only locked " "
            (name 18 18 :left :elide)
   (ibuffer-formats
    '((mark modified read-only locked " "
            (name 18 18 :left :elide)
@@ -1039,6 +1045,9 @@ There's no way I could top that, so I won't attempt to.
 #+end_src
 
 * Borg's =layer/essentials=
 #+end_src
 
 * Borg's =layer/essentials=
+:PROPERTIES:
+:CUSTOM_ID: borg-essentials
+:END:
 
 TODO: break this giant source block down into individual org sections.
 
 
 TODO: break this giant source block down into individual org sections.
 
@@ -1121,6 +1130,9 @@ TODO: break this giant source block down into individual org sections.
 #+end_src
 
 * Editing
 #+end_src
 
 * Editing
+:PROPERTIES:
+:CUSTOM_ID: editing
+:END:
 
 ** Company
 
 
 ** Company
 
@@ -1142,6 +1154,9 @@ TODO: break this giant source block down into individual org sections.
 #+end_src
 
 * Syntax and spell checking
 #+end_src
 
 * Syntax and spell checking
+:PROPERTIES:
+:CUSTOM_ID: syntax-spell-checking
+:END:
 
 #+begin_src emacs-lisp
 (use-package flycheck
 
 #+begin_src emacs-lisp
 (use-package flycheck
@@ -1184,7 +1199,11 @@ TODO: break this giant source block down into individual org sections.
   (advice-add #'ispell-parse-output :filter-args
               #'endless/replace-quote))
 #+end_src
   (advice-add #'ispell-parse-output :filter-args
               #'endless/replace-quote))
 #+end_src
+
 * Programming modes
 * Programming modes
+:PROPERTIES:
+:CUSTOM_ID: programming-modes
+:END:
 
 ** [[http://alloytools.org][Alloy]] (with [[https://github.com/dwwmmn/alloy-mode][alloy-mode]])
 
 
 ** [[http://alloytools.org][Alloy]] (with [[https://github.com/dwwmmn/alloy-mode][alloy-mode]])
 
@@ -1553,7 +1572,10 @@ treemacs
   :load-path "lib/guix/elisp")
 #+end_src
 
   :load-path "lib/guix/elisp")
 #+end_src
 
-* Emacs Enhancements
+* Emacs enhancements
+:PROPERTIES:
+:CUSTOM_ID: emacs-enhancements
+:END:
 
 ** [[https://github.com/justbur/emacs-which-key][which-key]]
 
 
 ** [[https://github.com/justbur/emacs-which-key][which-key]]
 
@@ -1653,7 +1675,8 @@ Emacs package that displays available keybindings in popup
        (advice-add 'magit-checkout
                    :after #'my-projectile-invalidate-cache)
        (advice-add 'magit-branch-and-checkout
        (advice-add 'magit-checkout
                    :after #'my-projectile-invalidate-cache)
        (advice-add 'magit-branch-and-checkout
-                   :after #'my-projectile-invalidate-cache))))
+                   :after #'my-projectile-invalidate-cache)))
+  :custom (projectile-completion-system 'ivy))
 #+end_src
 
 ** [[https://github.com/Wilfred/helpful][helpful]]
 #+end_src
 
 ** [[https://github.com/Wilfred/helpful][helpful]]
@@ -1669,53 +1692,6 @@ Emacs package that displays available keybindings in popup
    ("C-S-h p" . helpful-at-point)))
 #+end_src
 
    ("C-S-h p" . helpful-at-point)))
 #+end_src
 
-** [[https://github.com/knu/shell-toggle.el][shell-toggle]]
-
-#+begin_src emacs-lisp
-(use-package shell-toggle
-  :after eshell
-  :bind ("C-c a s e" . amin/shell-toggle)
-  :config
-  (defun amin/shell-toggle (make-cd)
-    "Toggle between the shell buffer and whatever buffer you are editing.
-With a prefix argument MAKE-CD also insert a \"cd DIR\" command
-into the shell, where DIR is the directory of the current buffer.
-
-When called in the shell buffer returns you to the buffer you were editing
-before calling this the first time.
-
-Options: `shell-toggle-goto-eob'"
-    (interactive "P")
-    ;; Try to decide on one of three possibilities:
-    ;; If not in shell-buffer, switch to it.
-    ;; If in shell-buffer, return to state before going to the shell-buffer
-    (if (eq (current-buffer) shell-toggle-shell-buffer)
-        (shell-toggle-buffer-return-from-shell)
-      (progn
-        (shell-toggle-buffer-goto-shell make-cd)
-        (if shell-toggle-full-screen-window-only (delete-other-windows)))))
-
-  ;; override to split horizontally instead
-  (defun shell-toggle-buffer-switch-to-other-window ()
-    "Switch to other window.
-If the current window is the only window in the current frame,
-create a new window and switch to it.
-
-\(This is less intrusive to the current window configuration than
-`switch-buffer-other-window')"
-    (let ((this-window (selected-window)))
-      (other-window 1)
-      ;; If we did not switch window then we only have one window and need to
-      ;; create a new one.
-      (if (eq this-window (selected-window))
-             (progn
-               (split-window-horizontally)
-            (other-window 1)))))
-
-  :custom
-  (shell-toggle-launch-shell 'shell-toggle-eshell))
-#+end_src
-
 ** [[https://github.com/EricCrosson/unkillable-scratch][unkillable-scratch]]
 
 Make =*scratch*= and =*Messages*= unkillable.
 ** [[https://github.com/EricCrosson/unkillable-scratch][unkillable-scratch]]
 
 Make =*scratch*= and =*Messages*= unkillable.
@@ -1768,42 +1744,6 @@ Make =*scratch*= and =*Messages*= unkillable.
 
 Also see [[https://www.emacswiki.org/emacs/rebox2][rebox2]].
 
 
 Also see [[https://www.emacswiki.org/emacs/rebox2][rebox2]].
 
-** COMMENT [[https://github.com/DarthFennec/highlight-indent-guides][highlight-indent-guides]]
-
-#+begin_src emacs-lisp
-(use-package highlight-indent-guides
-  :defer 3
-  :hook ((prog-mode . highlight-indent-guides-mode)
-         ;; (org-mode  . highlight-indent-guides-mode)
-         )
-  :config
-  (setq highlight-indent-guides-character ?\|)
-  (setq highlight-indent-guides-auto-enabled nil)
-  (setq highlight-indent-guides-method 'character)
-  (setq highlight-indent-guides-responsive 'top)
-  (set-face-foreground 'highlight-indent-guides-character-face "gainsboro")
-  (set-face-foreground 'highlight-indent-guides-top-character-face "grey40")) ; grey13 is nice too
-#+end_src
-
-** pdf-tools
-
-#+begin_src emacs-lisp
-(use-package pdf-tools
-  :defer t
-  :magic ("%PDF" . pdf-view-mode)
-  :config
-  (setq pdf-view-resize-factor 1.05)
-  (pdf-tools-install)
-  :bind
-  (:map pdf-view-mode-map
-        ("C-s" . isearch-forward)
-        ("C-r" . isearch-backward)
-        ("j"   . pdf-view-next-line-or-next-page)
-        ("k"   . pdf-view-previous-line-or-previous-page)
-        ("h"   . image-backward-hscroll)
-        ("l"   . image-forward-hscroll)))
-#+end_src
-
 ** typo.el
 
 #+begin_src emacs-lisp
 ** typo.el
 
 #+begin_src emacs-lisp
@@ -1854,71 +1794,6 @@ Also see [[https://www.emacswiki.org/emacs/rebox2][rebox2]].
         ""))))
 #+end_src
 
         ""))))
 #+end_src
 
-** COMMENT slack
-
-Hopefully temporary.
-
-#+begin_src emacs-lisp
-(use-package slack
-  :commands (slack-start)
-  :init
-  (eval-when-compile                    ; silence the byte-compiler
-    (defvar url-http-data nil)
-    (defvar url-http-extra-headers nil)
-    (defvar url-http-method nil)
-    (defvar url-callback-function nil)
-    (defvar url-callback-arguments nil)
-    (defvar oauth--token-data nil))
-  (setq slack-buffer-emojify t
-        slack-prefer-current-team t)
-  :config
-  (slack-register-team
-   :name "uw-apv"
-   :default t
-   :client-id uw-apv-client-id
-   :client-secret uw-apv-client-secret
-   :token uw-apv-token
-   :subscribed-channels '(general)
-   :full-and-display-names t)
-  (slack-register-team
-   :name "watform"
-   :default nil
-   :client-id watform-client-id
-   :client-secret watform-client-secret
-   :token watform-token
-   :subscribed-channels '(general)
-   :full-and-display-names t)
-  (add-to-list 'swiper-font-lock-exclude 'slack-message-buffer-mode t)
-  (setq lui-time-stamp-format "[%Y-%m-%d %H:%M:%S]"
-        lui-time-stamp-only-when-changed-p t
-        lui-time-stamp-position 'right)
-  :bind
-  (("C-c s s" . slack-start)
-   ("C-c s u" . slack-select-unread-rooms)
-   ("C-c s b" . slack-select-rooms)
-   ("C-c s t" . slack-change-current-team)
-   ("C-c s c" . slack-ws-close)
-   :map slack-mode-map
-   ("M-p"     . slack-buffer-goto-prev-message)
-   ("M-n"     . slack-buffer-goto-next-message)
-   ("C-c e"   . slack-message-edit)
-   ("C-c k"   . slack-message-delete)
-   ("C-c C-k" . slack-channel-leave)
-   ("C-c r a" . slack-message-add-reaction)
-   ("C-c r r" . slack-message-remove-reaction)
-   ("C-c r s" . slack-message-show-reaction-users)
-   ("C-c p l" . slack-room-pins-list)
-   ("C-c p a" . slack-message-pins-add)
-   ("C-c p r" . slack-message-pins-remove)
-   ("@"       . slack-message-embed-mention)
-   ("#"       . slack-message-embed-channel)))
-
-(use-package alert
-  :commands (alert)
-  :init
-  (setq alert-default-style 'notifier))
-#+end_src
-
 ** [[https://github.com/peterwvj/eshell-up][eshell-up]]
 
 #+begin_src emacs-lisp
 ** [[https://github.com/peterwvj/eshell-up][eshell-up]]
 
 #+begin_src emacs-lisp
@@ -1931,9 +1806,12 @@ Hopefully temporary.
 #+begin_src emacs-lisp
 (use-package multi-term
   :defer 1
 #+begin_src emacs-lisp
 (use-package multi-term
   :defer 1
-  :bind (("C-c C-j"     . term-line-mode)
-         ("C-c a s m m" . multi-term)
-         ("C-c a s m p" . multi-term-dedicated-toggle))
+  :bind (("C-c a s m m" . multi-term)
+         ("C-c a s m p" . multi-term-dedicated-toggle)
+         :map term-mode-map
+         ("C-c C-j" . term-char-mode)
+         :map term-raw-map
+         ("C-c C-j" . term-line-mode))
   :config
   (setq multi-term-program "/bin/screen"
         ;; TODO: add separate bindings for connecting to existing
   :config
   (setq multi-term-program "/bin/screen"
         ;; TODO: add separate bindings for connecting to existing
@@ -1967,11 +1845,21 @@ Hopefully temporary.
   (global-page-break-lines-mode))
 #+end_src
 
   (global-page-break-lines-mode))
 #+end_src
 
+** expand-region
+
+#+begin_src emacs-lisp
+(use-package expand-region
+  :bind ("C-=" . er/expand-region))
+#+end_src
+
 * Email
 * Email
+:PROPERTIES:
+:CUSTOM_ID: email
+:END:
 
 #+begin_src emacs-lisp
 (defvar amin-maildir (expand-file-name "~/mail/"))
 
 #+begin_src emacs-lisp
 (defvar amin-maildir (expand-file-name "~/mail/"))
-(after! recentf
+(with-eval-after-load 'recentf
   (add-to-list 'recentf-exclude amin-maildir))
 #+end_src
 
   (add-to-list 'recentf-exclude amin-maildir))
 #+end_src
 
@@ -2145,7 +2033,7 @@ Hopefully temporary.
   ;; (message-header-cc      ((t (:foreground "#333" :weight normal))))
   )
 
   ;; (message-header-cc      ((t (:foreground "#333" :weight normal))))
   )
 
-(after! mml-sec
+(with-eval-after-load 'mml-sec
   (setq mml-secure-openpgp-encrypt-to-self t
         mml-secure-openpgp-sign-with-sender t))
 #+end_src
   (setq mml-secure-openpgp-encrypt-to-self t
         mml-secure-openpgp-sign-with-sender t))
 #+end_src
@@ -2174,37 +2062,56 @@ Convenient footnotes in =message-mode=.
         footnote-style     'unicode))
 #+end_src
 
         footnote-style     'unicode))
 #+end_src
 
-** bbdb
+** ebdb
 
 
-Manually install bbdb (=lisp/bbdb= copied from an ELPA-based setup),
-because installing it from source on Emacs 27 using the following
-submodule configuration for some reason doesn’t work and results in
-very strange errors when using any of the functions.
+#+begin_src emacs-lisp
+(use-package ebdb
+  :defer 1
+  :bind (:map gnus-group-mode-map ("e" . ebdb))
+  :config
+  (setq ebdb-sources (no-littering-expand-var-file-name "ebdb"))
+  (with-eval-after-load 'swiper
+    (add-to-list 'swiper-font-lock-exclude 'ebdb-mode t)))
 
 
-#+begin_src conf :tangle no
-[submodule "bbdb"]
-       path = lib/bbdb
-       url = https://git.savannah.nongnu.org/git/bbdb.git
-       load-path = lisp
-       info-path = doc
-       build-step = ./autogen.sh
-       build-step = ./configure
-       build-step = make
-       build-step = make install
-#+end_src
+(use-package ebdb-com
+  :after ebdb)
 
 
-I tried using =borg-elpa= instead of doing it like this, but it added
-2 seconds to my startup time, which is unacceptable to me.
+;; (use-package ebdb-complete
+;;   :after ebdb
+;;   :config
+;;   (ebdb-complete-enable))
 
 
-#+begin_src emacs-lisp
-(use-package bbdb
-  :load-path "lisp/bbdb"
-  :init
-  (load (expand-file-name "lisp/bbdb/bbdb-autoloads.el" user-emacs-directory))
-  ;; (bbdb-mua-auto-update-init 'message)
-  (setq bbdb-mua-auto-update-p 'query
-        bbdb-complete-mail nil)
-  (bbdb-initialize 'gnus 'message))
+(use-package company-ebdb
+  :after (:all company message)
+  :config
+  (defun company-ebdb--post-complete (_) nil)
+  :hook
+  (message-mode . (lambda ()
+                    (add-to-list (make-local-variable 'company-backends)
+                                 'company-ebdb))))
+
+(use-package ebdb-gnus
+  :after ebdb
+  :custom
+  (ebdb-gnus-window-configuration
+   '(article
+     (vertical 1.0
+               (summary 0.25 point)
+               (horizontal 1.0
+                           (article 1.0)
+                           (ebdb-gnus 0.3))))))
+
+(use-package ebdb-mua
+  :after ebdb
+  ;; :custom (ebdb-mua-pop-up nil)
+  )
+
+;; (use-package ebdb-message
+;;   :after ebdb)
+
+
+;; (use-package ebdb-vcard
+;;   :after ebdb)
 #+end_src
 
 ** COMMENT message-x
 #+end_src
 
 ** COMMENT message-x
@@ -2235,6 +2142,9 @@ I tried using =borg-elpa= instead of doing it like this, but it added
 #+end_src
 
 * Blogging
 #+end_src
 
 * Blogging
+:PROPERTIES:
+:CUSTOM_ID: blogging
+:END:
 
 ** [[https://ox-hugo.scripter.co][ox-hugo]]
 
 
 ** [[https://ox-hugo.scripter.co][ox-hugo]]