Emacs init file

General settings

Package, package archive

;; Added by Package.el.  This must come before configurations of
;; installed packages.  Don't delete this line.  If you don't want it,
;; just comment it out by adding a semicolon to the start of the line.
;; You may delete these explanatory comments.
(require 'package)
(setq package-enable-at-startup nil)
(add-to-list 'package-archives
             '("stable" . "https://melpa.org/packages/") t)
(add-to-list 'package-archives
             '("org" . "https://orgmode.org/elpa/") t)
(add-to-list 'package-archives
             '("nongnu" . "https://elpa.nongnu.org/nongnu/") t)
;; (add-to-list 'package-archives
;;           '("gnu" . "https://elpa.gnu.org/packages/") t)

(package-initialize)

(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

Language, Line formatting, frame/window formatting, splash screen etc

;; Language setting
(setq system-time-locale "nl_NL.utf8")
;; To disable the toolbar completely, turn off ‘tool-bar-mode’. Add
;; the following to your InitFile, for GnuEmacs:
(tool-bar-mode -1)
;; Fold long lines
(toggle-truncate-lines 0)
;; mouse scrolling
(mouse-wheel-mode t)
;; Show line-number and column-number in the mode line
(line-number-mode 1)
(column-number-mode 1)
;; highlight current line
(global-hl-line-mode 1)
(set-face-background 'hl-line "#ededed")
(set-face-foreground 'highlight nil)

;; no help screen
(setq inhibit-startup-message t)

;; no splash screen
(setq inhibit-splash-screen t)

;; Use the Printing Package
(require 'printing)
(pr-update-menus)

(put 'downcase-region 'disabled nil)
(put 'upcase-region 'disabled nil)
(put 'scroll-left 'disabled nil)
 ;; Change "yes or no" to "y or n"
 (fset 'yes-or-no-p 'y-or-n-p)

Where are the config files?

Assuming that you install packages in ~/.emacs.d/lisp/ and that some of the installed packages are single libraries while others are placed inside their own sub-directories you need to combine the steps from above.

(let ((default-directory "~/.emacs.d/lisp/"))
  (normal-top-level-add-to-load-path '("."))
  (normal-top-level-add-subdirs-to-load-path))

;; Do not clutter up my dirs with ~ files
(setq backup-directory-alist '(("." . "~/doc/backups")))

;; Non-nil means a single space does not end a sentence.
(setq sentence-end-double-space nil)

Flyspell

(defun fd-switch-dictionary()
      (interactive)
      (let* ((dic ispell-current-dictionary)
         (change (if (string= dic "dutch") "english" "dutch")))
        (ispell-change-dictionary change)
        (message "Dictionary switched from %s to %s" dic change)
        ))

Tramp

(require 'tramp)
;; Tramp default mode
(setq tramp-default-method "ssh")
(add-to-list 'tramp-remote-path "/usr/local/perl/bin")

Windmove

;; Move around windows using Shift-arrow-keys
(use-package windmove
  :ensure t
  :config
  (windmove-default-keybindings 'super)
  (setq windmove-wrap-around t))

Which-key

(use-package which-key
  :ensure t
  :config (which-key-mode))

Magit

(autoload 'magit-status "magit" nil t)
(setq magit-save-some-buffers nil)
(add-hook 'before-save-hook 'delete-trailing-whitespace)

Helm

(require 'helm)
(require 'helm-ag)
(defun helm-find-files-prompt-dir ()
  (interactive)
  ;; Search for files using helm and find but prompt for root search
  ;; dir
  (helm-find 1)
  )

(use-package swiper-helm
  :ensure t
  :bind (("C-s" . swiper-helm)
         ("s-s" . swiper-helm-at-point)
         :map isearch-mode-map
         ("s-s" . swiper-helm-from-isearch))
  :config
  (defun swiper-helm-at-point ()
    "Custom function to pick up a thing at a point for
    swiper-helm If a selected region exists, it will be searched
    for by swiper If there is a symbol at the current point, its
    textual representation is searched. If there is no symbol,
    empty search box is started."
    (interactive)
    (swiper (selection-or-thing-at-point))))

(defun selection-or-thing-at-point ()
  (cond
   ;; If there is selection use it
   ((and transient-mark-mode
         mark-active
         (not (eq (mark) (point))))
    (let ((mark-saved (mark))
          (point-saved (point)))
      (deactivate-mark)
      (buffer-substring-no-properties mark-saved point-saved)))
   ;; Otherwise, use symbol at point or empty
   (t (format "%s"
              (or (thing-at-point 'symbol)
                  "")))))

Associate external programs with file formats

'(helm-external-programs-associations '(("jpg" . "ristretto")
                                        ("jpeg" . "ristretto")
                                        ("png" . "ristretto")
                                        ("pdf" . "evince")
                                        ("doc" . "libreoffice")
                                        ("docx" . "libreoffice")
                                        ("xlsx" . "libreoffice")
                                        ("xls" . "libreoffice")
                                        ("odt" . "libreoffice")))

Keybindings

(global-set-key (kbd "C-x f") 'helm-find-files-prompt-dir)
(global-set-key (kbd "C-x C-g") 'helm-ag)
(global-set-key (kbd "C-x b") 'helm-buffers-list)
(global-set-key (kbd "C-x r b") 'helm-bookmarks)
(global-set-key (kbd "M-y") 'helm-show-kill-ring)
(global-set-key (kbd "C-x C-f") 'helm-find-files)

(when (executable-find "curl")
   (setq helm-google-suggest-use-curl-p t))

(setq helm-split-window-in-side-p           t ; open helm buffer inside current window, not occupy whole other window
       helm-move-to-line-cycle-in-source     t ; move to end or beginning of source when reaching top or bottom of source.
       helm-ff-search-library-in-sexp        t ; search for library in `require' and `declare-function' sexp.
       helm-scroll-amount                    8 ; scroll 8 lines other window using M-<next>/M-<prior>
       helm-ff-file-name-history-use-recentf t
       helm-echo-input-in-header-line t)

(helm-mode 1)

Projectile

https://github.com/bbatsov/helm-projectile

(require 'projectile)
(require 'helm-projectile)
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
(projectile-mode +1)
(setq projectile-completion-system 'helm)
(helm-projectile-on)
(setq projectile-enable-caching t)

Show location of file in frame title

(setq frame-title-format
      '("" invocation-name ": "
        (:eval
         (if buffer-file-name
             (abbreviate-file-name buffer-file-name)
           "%b"))))

Eww

;; configure eww to use pdf-view-mode (from pdf-tools) for PDFs instead of DocView
(defvar tv/prefer-pdf-tools (fboundp 'pdf-view-mode))
(defun tv/start-pdf-tools-if-pdf ()
  (when (and tv/prefer-pdf-tools
             (eq doc-view-doc-type 'pdf))
    (pdf-view-mode)))

(add-hook 'doc-view-mode-hook 'tv/start-pdf-tools-if-pdf)

LaTeX/AUCTeX configuration

LaTeX

 (add-to-list 'auto-mode-alist '("\\.tex$" . LaTeX-mode))

 ;; To compile documents to PDF by default
 (setq TeX-PDF-mode t)

 ;; Query for master file.
 (setq-default TeX-master t)

 ;; Activate folding mode
 (add-hook `TeX-mode-hook (lambda ()
                          (TeX-fold-mode 1)))

 ;;Instead of editing the texmf.cnf file you can just add
 ;;-file-line-error option to your TeX processor.
 (setq LaTeX-command-style
     '(("" "%(PDF)%(latex) -file-line-error %S%(PDFout)")))

 ;; LaTeX-math-mode is the default
 (add-hook 'LaTeX-mode-hook 'LaTeX-math-mode)

 ;; spellcheck in LaTex mode
 (add-hook `LaTeX-mode-hook `flyspell-mode)
 (add-hook `TeX-mode-hook `flyspell-mode)
 (add-hook `bibtex-mode-hook `flyspell-mode)

 ;; TeX Directory
 (setq tex-directory "/usr/local/texlive/2022/bin/x86_64-linux/")

 ;; TeX and Evince interaction
 (setq TeX-view-program-list '(("Evince" "evince --page-index=%(outpage) %o")))
 (setq TeX-view-program-selection '((output-pdf "Evince")))
 (add-hook 'LaTeX-mode-hook 'TeX-source-correlate-mode)

;;  Change utf8 to latex charactercteres
;; http://www.emacswiki.org/emacs/LaTeX Volkan YAZICI

 (defvar tr-utf8-to-latex-string-translation-alist
   '(
   ("á" . "\\\'a") ("Á" . "\\\'A")
   ("à" . "\\\`a") ("À" . "\\\`A")
   ("ä" . "\\\"a") ("Ä" . "\\\"A")
   ("é" . "\\\'e") ("É" . "\\\'E")
   ("ë" . "\\\"e") ("Ë" . "\\\"E")
   ("í" . "\\\'{\\i}") ("Í" . "\\\'{\\i}")
   ("ó" . "\\\'o") ("Ó" . "\\\'O")
   ("ú" . "\\\'u") ("Á" . "\\\'u")
   ("ü" . "\\\"u") ("Ü" . "\\\"U")
   ("ñ" . "\\\~n") ("Ñ" . "\\\~Ñ")
   ("¿" . "?\'")
   ("¡" . "!\'")
   ("ß" . "{\\\ss}")
   ("ç" . "\\c{c}")  ("Ç" . "\\c{C}")
   ("ğ" . "\\u{g}")  ("Ğ" . "\\u{g}")
   ("İ" . "\\.{I}")
   ("ö" . "\\\"{o}") ("Ö" . "\\\"{O}")
   ("ş" . "\\c{s}")  ("Ş" . "\\c{S}")
   ))

 (defun latex-change-non-ascii-to-ascii ()
   "replaces non ascii characters to latex ascii characters"
   (interactive)
   (save-excursion
   (dolist (spec tr-utf8-to-latex-string-translation-alist)
     (goto-char (point-min))
     (message " cambiando %s" spec)
     (replace-string (car spec) (cdr spec) nil ))))

 (defun latex-change-ascii-to-non-ascii ()
   "replaces non ascii characters to latex ascii characters"
   (interactive)
   (save-excursion
   (dolist (spec tr-utf8-to-latex-string-translation-alist)
     (goto-char (point-min))
     (message " cambiando %s" spec)
     (replace-string (cdr spec) (car spec) nil ))))

 (unless (fboundp 'easy-menu-add-item)
   (defun easy-menu-add-item (map path item &optional before)))

 (add-hook 'LaTeX-mode-hook
         '(lambda ()
            (easy-menu-add-item nil '("LaTeX") ["á -> \\\'a" latex-change-non-ascii-to-ascii
                                                :help "Change non ascii to latex characters"]
                                "Delete Font")
            (easy-menu-add-item nil '("LaTeX") ["\\\'a -> á" latex-change-ascii-to-non-ascii
                                                :help "Change  ascii to non ascii"]
                                "Delete Font")
            ))

AUCTeX/REFTeX

(load "auctex.el" nil t t)
(load "preview-latex.el" nil t t)
;; (load "preview-latex.el" nil t t)

;;Do not ask about saving all the time
(setq TeX-save-query nil)

;; Activate RefTeX
(autoload 'reftex-mode "reftex" "RefTeX Minor Mode" t)
(autoload 'turn-on-reftex "reftex" "RefTeX Minor Mode" nil)
(add-hook 'LaTeX-mode-hook 'turn-on-reftex) ; with AUCTeX LaTeX mode
(setq reftex-enable-partial-scans t)
(setq reftex-save-parse-info t)
(setq reftex-use-multiple-selection-buffers t)
(setq reftex-plug-into-AUCTeX t)
(setq bib-cite-use-reftex-view-crossref t)
(global-auto-revert-mode t) ;; This mode makes sure that any changes
;; on disk are noticed immediately by
;; emacs.
;; AUCTeX depends heavily on being able to extract information from
;; the buffers by parsing them. Since parsing the buffer can be
;; somewhat;; slow, the parsing is initially disabled. You are
;; encouraged to enable them by adding the following lines to your
;; .emacs’ file.
(setq TeX-parse-self t) ; Enable parse on load.
(setq TeX-auto-save t) ; Enable parse on save.
(setq reftex-cite-format 'natbib) ; Set reference style to natbib

Math commands

(defun LaTeX-math-mathbb (char dollar)
  "Insert a {\\mathbb CHAR}.  If DOLLAR is non-nil, put $'s around it.
If `TeX-electric-math' is non-nil wrap that symbols around the
char."
  (interactive "*c\nP")
  (if dollar (insert (or (car TeX-electric-math) "$")))
  (if (member "latex2e" (TeX-style-list))
      (insert "\\mathbb{" (char-to-string char) "}")
    (insert "{\\mathbb " (char-to-string char) "}"))
  (if dollar (insert (or (cdr TeX-electric-math) "$"))))

(defun LaTeX-math-mathfrak (char dollar)
  "Insert a {\\mathfrak CHAR}.  If DOLLAR is non-nil, put $'s around it.
If `TeX-electric-math' is non-nil wrap that symbols around the
char."
  (interactive "*c\nP")
  (if dollar (insert (or (car TeX-electric-math) "$")))
  (if (member "latex2e" (TeX-style-list))
      (insert "\\mathfrak{" (char-to-string char) "}")
    (insert "{\\mathfrak " (char-to-string char) "}"))
  (if dollar (insert (or (cdr TeX-electric-math) "$"))))

Syntax highlighting for programming languages, etc

Lisp

(global-font-lock-mode t)
(show-paren-mode 1)
(add-hook 'lisp-mode-hook '(lambda ()
                             (local-set-key (kbd "RET") 'newline-and-indent)))

PROLOG

(autoload 'prolog-mode "prolog" "Major mode for editing Prolog programs." t)
(setq prolog-system 'swi)
(setq auto-mode-alist (append '(("\\.pl$" . prolog-mode)
                                ("\\.pro$" . prolog-mode)
                                ("\\.m$" . mercury-mode))
                              auto-mode-alist))

Apache config

(require 'apache-mode)

Markdown

(use-package markdown-mode
  :ensure t
  :commands (markdown-mode gfm-mode)
  :mode (("README\\.md\\'" . gfm-mode)
         ("\\.md\\'" . markdown-mode)
         ("\\.markdown\\'" . markdown-mode))
  :init (setq markdown-command "multimarkdown"))

Webmode (html / css / php)

(use-package web-mode
    :ensure t
    :config
    (add-to-list 'auto-mode-alist '("\\.html$" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.php\\'" . web-mode))
    (setq web-mode-engines-alist '(("php" . "\\.html\\'")))
    (setq web-mode-ac-sources-alist
          '(("css" . (ac-source-css-property))
            ("html" . (ac-source-words-in-buffer ac-source-abbrev))))
    (setq web-mode-enable-auto-closing t)
    (setq web-mode-enable-auto-quoting t))

YAML

(require 'yaml-mode)
   (add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode))

;; Unlike python-mode, this mode follows the Emacs convention of not
;; binding the ENTER key to `newline-and-indent'.  To get this
;; behavior, add the key definition to `yaml-mode-hook':

(add-hook 'yaml-mode-hook
  '(lambda ()
     (define-key yaml-mode-map "\C-m" 'newline-and-indent)))

Keybindings

(global-set-key (kbd "<f5>") 'mu4e-update-mail-and-index)
(global-set-key (kbd "<f6>") 'org-msg-mode)
(global-set-key (kbd "<f9>") 'undo)
(global-set-key (kbd "<f10>") 'org-capture)
(global-set-key (kbd "<f11>") 'emojify-mode)
(global-set-key (kbd "<f12>") 'helm-mode)
(global-set-key (kbd "C-c k") 'kill-buffer-and-window)
(global-set-key (kbd "C-c 0") 'eww)
(global-set-key (kbd "C-c m") 'mu4e)
(global-set-key (kbd "C-c 1") 'string-insert-rectangle)
(global-set-key (kbd "C-c 2") 'print-date-timestamp-nl)
(global-set-key (kbd "C-c 3") 'print-date-timestamp-en)
(global-set-key (kbd "C-c 4") 'print-time)
(global-set-key (kbd "C-c 5") 'helm-org-rifle)
(global-set-key (kbd "C-c 6") 'helm-org-rifle-current-buffer)
(global-set-key (kbd "C-c 7") 'helm-org-rifle-occur)
(global-set-key (kbd "C-c 8") 'helm-org-rifle-occur-current-buffer)
(global-set-key (kbd "C-c h o") 'helm-occur)
(global-set-key (kbd "C-h SPC") 'helm-all-mark-rings)
(global-set-key (kbd "C-x g") 'magit-status)
(global-set-key (kbd "C-x M-g") 'magit-dispatch)
(global-set-key (kbd "C-x C-b") 'ibuffer)
(global-set-key (kbd "C-x m") 'execute-extended-command)
(global-set-key (kbd "M-x") 'helm-M-x)
(global-set-key (kbd "C-x M") 'message-mail)
(global-set-key (kbd "<print>") 'delete-window)
(global-set-key (kbd "<Scroll_Lock>") 'org-caldav-sync)
(global-set-key (kbd "C-c S") 'helm-mu-contacts)
(global-set-key (kbd "C-c s")
                (lambda()(interactive)(switch-to-buffer "*scratch*")))
(global-set-key (kbd "C-c 9")
                (lambda()(interactive)(switch-to-buffer "*mu4e-headers*")))
(global-set-key (kbd "s-a")
                (lambda()(interactive)(switch-to-buffer "*Org Agenda*")))
(global-set-key (kbd "C-c F") 'my-spellcheck-buffer)

We remap Alt-Tab as it is used by our window manager.

(global-set-key (kbd "C-c i") (kbd "M-TAB"))

Custom functions

(defun my-spellcheck-buffer ()
  "Spellcheck current buffer. Repeating the command will check
for Dutch and English alternatively."
  (interactive)
  (flyspell-mode)
  (fd-switch-dictionary)
  (flyspell-buffer))

(defun print-time ()
  "Print the current system time"
  (interactive)
  (insert
   (shell-command-to-string "date +\"%H:%M\"")
   ))

(defun print-date-timestamp-nl ()
  "Print a current timestamp using NL locale"
  (interactive)
  (insert
   (shell-command-to-string "echo -n $(LC_TIME=nl_NL.utf8 date +\"%A, %d %B %Y, %H:%M\")")
   ))

(defun print-date-timestamp-en ()
  "Print a current timestamp using NL locale"
  (interactive)
  (insert
   (shell-command-to-string "echo -n $(date +\"%A, %d %B %Y, %H:%M\")")
   ))

;; Kills all open-buffers
(defun close-all-buffers ()
  (interactive)
    (mapc 'kill-buffer (buffer-list)))

Org mode

Helm bibtex

https://github.com/tmalsburg/helm-bibtex Dependency of org-ref

https://stackoverflow.com/questions/72682258/citeproc-error-after-updating-to-debian-buster-void-variable-bibtex-completion

(autoload 'helm-bibtex "helm-bibtex" "" t)
(setq bibtex-completion-display-formats '((t . "${author:36} ${title:*} ${year:4} ${=has-pdf=:1}${=has-note=:1} ${=type=:7}")))

Packages

(require 'calendar)
(require 'org)
(require 'org-agenda)
(require 'org-protocol)
(require 'org-capture)
(require 'org-ref)
(require 'org-ref-helm)
(require 'org-id)
(require 'org-ref-wos)
(require 'org-ref-scopus)
(require 'org-ref-pubmed)
(require 'org-bookmark-heading)
(require 'doi-utils)
(require 'helm-org-rifle)
(require 'ox)
(require 'ox-publish)
(require 'ox-html)
(require 'ox-beamer)
(require 'ox-icalendar)
(require 'ox-latex)
(require 'htmlize)

General settings

;; tells emacs to automatically revert (reload) any org-mode file that
;; changes on disk while the buffer is open
(add-hook 'org-mode-hook 'auto-revert-mode)

;; (add-to-list 'load-path "/usr/share/emacs24/site-lisp")
(add-to-list 'auto-mode-alist '("\\.org\\'" . org-mode))

;; By default, org-refile will show you only the top-level headings
;; of the current file. Let’s configure it to show you headings from
;; all your agenda files.
(setq org-refile-targets '((org-agenda-files . (:maxlevel . 8))))

(global-set-key (kbd "C-c l") 'org-store-link)
(global-set-key (kbd "C-c a") 'org-agenda)

Take advantage of the screen width.

(setq org-agenda-tags-column -100)

Do not include \hypersetup in my LaTeX exports

(setq org-latex-with-hyperref nil)

Open directories in dired.

(add-to-list 'org-file-apps '(directory . emacs))

Hide Emphasis markers

(setq org-hide-emphasis-markers t)

Org no longer indents by default. Shame!

(setq org-adapt-indentation t)

Keywords

(setq org-todo-keywords
      '((sequence "Todo(t)" "Scheduled(s@/i)" "In-Progress(i@/!)" "Check(c@/!)" "Waiting(W@/!)" "|" "Done(d@)" "Cancelled(C@)")
        (sequence "Task(T)" "Assigned(S@/!)" "Check(c@/!)" "Returned(R@/!)" "Waiting(W@/!)" "|" "Done(d@)" "Cancelled(C@)")
        (sequence "Actie(a@/i!)" "|" "Done(d@)")
        (sequence "Action(A@/i!)" "|" "Done(d@)")
        (sequence "Today(y@/i!)" "|" "Done(d@)")
        (sequence "Toezegging(Z@/i!)" "|" "Done(d@)")
        (sequence "Besluit(B)" "|")
        (sequence "Decision(D)" "|")))

(setq org-todo-keyword-faces
      '(("Todo" . (org-warning :box t))
        ("Task" . (org-warning :box t))
        ("Today" . (:foreground "white" :box t))
        ("Actie" . (:foreground "DarkOrange" :box t))
        ("Action" . (:foreground "DarkOrange" :box t))
        ("Toezegging" . (:foreground "gold" :box t))
        ("Besluit" . (:foreground "SpringGreen" :box t))
        ("Decision" . (:foreground "SpringGreen" :box t))
        ("Issue" . (:foreground "NavajoWhite3" :box t))
        ("Waiting" . (:foreground "DarkOrange" :box t))
        ("Returned" . (:foreground "DarkOrange" :box t))
        ("Scheduled" . (:foreground "khaki1" :box t))
        ("Check" . (:foreground "DeepSkyBlue" :box t))
        ;; ("Description" . (:foreground "NavajoWhite3" :box t))
        ;; ("Analysis" . (:foreground "NavajoWhite3" :box t))
        ;; ("Conclusion" . (:foreground "NavajoWhite3" :box t))
        ("Task" . (:foreground "DarkOrange"))
        ("In-Progress" . (:foreground "SpringGreen" :slant italic :box t))
        ("Assigned" . (:foreground "SpringGreen" :slant italic :box t))
        ("Done" . (:foreground "grey" :weight bold :box t))
        ("Cancelled" . (:foreground "grey" :weight bold))
        ))

Org settings

(setq org-log-into-drawer t)
(setq org-log-done 'time)
(setq org-directory "~/doc/org")
(setq org-agenda-include-diary nil)
(setq org-agenda-restore-windows-after-quit t)
(setq org-icalendar-combined-agenda-file "~/doc/org/org_combined.ics")
(setq org-attach-auto-tag "attachments")
(setq org-startup-folded t)

(eval-after-load "org"
  '(define-key org-mode-map (kbd "C-c t") 'org-insert-todo-heading))
(eval-after-load "org"
  '(define-key org-mode-map (kbd "C-c n") 'org-meta-return))
(eval-after-load "org"
  '(define-key org-mode-map (kbd "C-c r") 'org-insert-heading-respect-content))

(setq org-default-notes-file "~/doc/org/tasks.org")

(unless (boundp 'org-latex-classes)
  (setq org-latex-classes nil))
(add-to-list 'org-latex-classes
             '("article" "\\documentclass{article}"
               ("\\section{%s}" . "\\section*{%s}")
               ("\\subsection{%s}" . "\\subsection*{%s}")
               ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
               ("\\paragraph{%s}" . "\\paragraph*{%s}")
               ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))

(setq org-html-validation-link nil)

(add-to-list 'org-export-filter-timestamp-functions
             #'endless/filter-timestamp)
(defun endless/filter-timestamp (trans back _comm)
  "Remove <> around time-stamps."
  (pcase back
    ((or `jekyll `html)
     (replace-regexp-in-string "&[lg]t;" "" trans))
    (`latex
     (replace-regexp-in-string "[<>]" "" trans))))

(setq-default org-display-custom-times t)
    ;;; Before you ask: No, removing the <> here doesn't work.
(setq org-time-stamp-custom-formats
      '("<%d %b %Y>" . "<%d/%m/%y %a %H:%M>"))

Org apps

;; PDF Handling
(use-package pdf-tools
  :ensure t)
(delete '("\\.pdf\\'" . default) org-file-apps)

(add-to-list 'org-file-apps '("\\.pdf\\'" . org-pdfview-open))

Searching

When we search our org files we want our archive to be included in the search.

(setq org-agenda-text-search-extra-files '(agenda-archives))

org-babel

(setq org-confirm-babel-evaluate nil
      org-src-fontify-natively t
      org-src-tab-acts-natively t)

(org-babel-do-load-languages
 'org-babel-load-languages
 '((emacs-lisp . t)
   (prolog     . t)
   (shell      . t)
   (org   . t)
   (sql   . t)
   (latex      . t)
   (python     . t)
   (awk   . t)
   (ruby       . t)
   (R          . t)
   (ledger        . t)
   (ditaa      . t)))

Automatic tangle on save

As per this manual we configure a hook that automatically runs org-babel-tangle upon saving any org-mode buffer.

;; (org-mode . (lambda () (add-hook 'after-save-hook 'org-babel-tangle
;;                               'run-at-end 'only-in-org-mode)))
;;
;; An error is given:
;;
;; Debugger entered--Lisp error: (void-variable lambda)
;;   (org-mode lambda nil (add-hook (quote after-save-hook) (quote org-babel-tangle) (quote run-at-end) (quote only-in-org-mode)))
;;   eval((org-mode lambda nil (add-hook (quote after-save-hook) (quote org-babel-tangle) (quote run-at-end) (quote only-in-org-mode))) nil)
;;   elisp--eval-last-sexp(nil)
;;   eval-last-sexp(nil)
;;   funcall-interactively(eval-last-sexp nil)
;;   call-interactively(eval-last-sexp nil nil)
;;   command-execute(eval-last-sexp)

org-attach

org-attach-method

We want files to move when attached to prevent a cluttered file system with different versions of files.

(setq org-attach-method "mv")

Attach from Dired

Add the following lines to the Emacs init file to have C-c C-x a attach files in Dired buffers.

(add-hook 'dired-mode-hook
          (lambda ()
            (define-key dired-mode-map
              (kbd "C-c C-x a")
              #'org-attach-dired-to-subtree)))

The following code shows how to bind the previous command with a specific attachment method.

(add-hook 'dired-mode-hook
          (lambda ()
            (define-key dired-mode-map (kbd "C-c C-x c")
              (lambda ()
                (interactive)
                (let ((org-attach-method 'mv))
                  (call-interactively #'org-attach-dired-to-subtree))))))

Inheritance

(setq org-attach-use-inheritance t)

org-mutt interaction

This redefines the link type "mailto" to be able to handle e-mail messages in org-mode. This will call the function org-id-open-mail-in-mutt, which in turn calls a bash script.

(defun org-id-open-mail-in-mutt (id)
  "Tell screen to open new window and open mutt on assigned message"
  (interactive "MPath or Message-ID: ")
  (shell-command
   (format "%s %s"
           (substitute-in-file-name "$HOME/dot/bin/mutt-open-find-email.sh") id)))

(org-add-link-type "mailto" 'org-id-open-mail-in-mutt)

Export

LaTeX

I'll provide my own packages, thank you very much

(setq org-latex-default-packages-alist nil)

Publishing

Blog sitemap function definitions
(setq org-export-global-macros
      '(("timestamp" . "@@html:<span class=\"timestamp\">[$1]</span>@@")))

(defun my-blog-format-entry (entry style project)
  "Format ENTRY in org-publish PROJECT Sitemap format ENTRY ENTRY STYLE format that includes date."
  (let ((filename (org-publish-find-title entry project)))
    (if (= (length filename) 0)
        (format "*%s*" entry)
      (format "{{{timestamp(%s)}}} [[file:%s][%s]]"
              (format-time-string "%Y-%m-%d"
                                  (org-publish-find-date entry project))
              entry
              filename))))

(defun my-blog-html-postamble (options)
  (concat "<hr>"
          (format "<p class=\"date\">Modified: %s</p>" (format-time-string "%Y-%m-%d %H:%M:%S %Z"))
          (format "<p>%s</p>" (plist-get options ':creator))))
MathJax CDN

The defaults use an old MathJax version

(setf org-html-mathjax-options
      '((path "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML")
        (scale "100")
        (align "lect")
        (indent "10em")
        (mathml nil))
      )
(setf org-html-mathjax-template
      "<script type=\"text/javascript\" src=\"%PATH\"></script>")

Calendar format setting

;;As of GnuEmacs 23 the following code will make CalendarMode use the
;;European style of dates in the diary and display:
(add-hook 'calendar-load-hook
              (lambda ()
                (calendar-set-date-style 'european)))

Mu4e

General settings

(add-to-list 'load-path "/usr/share/emacs/site-lisp/mu4e")
(require 'mu4e)
(require 'mu4e-speedbar)
(setq mail-user-agent #'mu4e-user-agent)
(setq message-mail-user-agent t)
(set-variable 'read-mail-command 'mu4e)

;;store link to message if in header view, not to header query
(setq org-mu4e-link-query-in-headers-mode nil)

(setq mu4e-headers-fields
      '( (:human-date    .  20)
         (:flags         .   6)
         (:maildir       .  20)
         (:from-or-to    .  25)
         (:subject       .  nil)
         ))

;; (with-eval-after-load 'mu4e
;;   (define-key mu4e-view-mode-map (kbd "d") 'mu4e-headers-mark-for-delete))
;; (with-eval-after-load 'mu4e
;;     (define-key mu4e-view-mode-map (kbd "D") 'mu4e-headers-mark-for-trash))

(setq mu4e-headers-thread-child-prefix '("├>" . "├─➤ ")
      mu4e-headers-thread-last-child-prefix '("└>" . "└─➤ ")
      mu4e-headers-thread-orphan-prefix '("┬>" . "┬─➤ ")
      mu4e-headers-thread-single-orphan-prefix '("─>" . "──➤ ")
      ;; The following two should have the same width.
      mu4e-headers-thread-connection-prefix '("│" . "│ ")
      mu4e-headers-thread-blank-prefix '(" " . " "))

;;(setq mu4e-user-agent-string nil)
(setq mail-user-agent 'mu4e-user-agent)
(set-variable 'read-mail-command 'mu4e)
(setq mu4e-compose-complete-only-after "1995-01-01")
(setq mu4e-compose-complete-only-personal nil)
(setq mu4e-compose-context-policy nil)
(setq mu4e-compose-format-flowed t)
(setq mu4e-compose-dont-reply-to-self t)
(setq mu4e-confirm-quit nil)

(setq mu4e-headers-date-format "%Y-%m-%d %H:%M")
(setq mu4e-view-show-addresses t)
(setq mu4e-view-show-images t)
(setq shr-color-visible-luminance-min 60)
(setq shr-width 70)

(setq mu4e-headers-results-limit 50000)

(setq mu4e-change-filenames-when-moving t)

(setq message-citation-line-format "%N wrote on %Y-%m-%d %T:\n")
(setq mu4e-date-format-long "%F %T")
(setq mu4e-view-date-format "%F %T")
(setq message-citation-line-function (quote message-insert-formatted-citation-line))
(setq message-cite-style (quote message-cite-style-thunderbird))
(setq message-kill-buffer-on-exit t)
(setq mouse-buffer-menu-mode-mult 20)

;; It is possible to attach files to mu4e messages using dired (See
;; (emacs)Dired), using the following steps (based on a post on the
;; mu-discuss mailing list by Stephen Eglen).
(add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode)
(setq mu4e-attachment-dir "/home/peter/Desktop/")

;; show images
(setq mu4e-show-images t)

(setq mu4e-use-fancy-chars nil)

;; use imagemagick, if available
(when (fboundp 'imagemagick-register-types)
  (imagemagick-register-types))

(setq mu4e-html2text-command "w3m -T text/html"
      mu4e-update-interval 120
      mu4e-headers-auto-update t
      mu4e-compose-signature-auto-include nil)
(setq message-signature-file "~/dot/signature.txt")

(setq mail-personal-alias-file (expand-file-name "/home/peter/.emacs.d/mail-aliases"))

Helm-mu

(require 'helm-mu)
(define-key mu4e-search-minor-mode-map "s" 'helm-mu)
(setq helm-mu-always-use-default-search-string t)

Colors

https://github.com/Alexander-Miller/mu4e-column-faces

(use-package mu4e-column-faces
  :after mu4e
  :config (mu4e-column-faces-mode))

Keybindings

(define-key mu4e-headers-mode-map (kbd "d") 'mu4e-headers-mark-for-delete)
(define-key mu4e-headers-mode-map (kbd "D") 'mu4e-headers-mark-for-trash)
(define-key mu4e-headers-mode-map (kbd "<tab>") 'mu4e-next-unread)
(define-key mu4e-headers-mode-map (kbd ";") 'mu4e-context-switch)
(define-key mu4e-headers-mode-map (kbd "C-c S") 'helm-mu-contacts)
;;(define-key mu4e-view-mode-map (kbd "<f12>") 'helm-mode)
(define-key mu4e-view-mode-map (kbd "d") 'mu4e-view-mark-for-delete)
(define-key mu4e-headers-mode-map (kbd "<f8>") 'my-mu4e-cycle-context)
(define-key mu4e-compose-mode-map (kbd "C-c e") 'emojify-insert-emoji)

Hooks

(add-hook 'mu4e-compose-pre-hook
          (defun set-mu4e-sent-folder ()
            "Set the mu4e-sent-folder to custom function when a composing message"
            (when t
              (setq mu4e-sent-folder 'my-mu4e-sent-folder-function))))

(add-hook 'mu4e-compose-mode-hook
          (lambda ()
            (local-set-key (kbd "<f8>") 'my-mu4e-cycle-context)
            ))

Sending

(setq sendmail-program "/usr/bin/msmtp"
      send-mail-function 'smtpmail-send-it
      message-sendmail-f-is-evil t
      message-sendmail-extra-arguments '("--read-envelope-from")
      message-send-mail-function 'message-send-mail-with-sendmail)

We want to be prompted for an FCC location before sending.

(defun my-mu4e-sent-folder-function (msg)
  "Set the sent folder for the current message."
  (cond
   (t (mu4e-ask-maildir-check-exists "Save message to maildir: "))))

(setq mu4e-sent-folder 'my-mu4e-sent-folder-function)

org-mu4e interaction

(define-key mu4e-headers-mode-map (kbd "C-c c") 'mu4e-org-store-and-capture)
(define-key mu4e-view-mode-map    (kbd "C-c c") 'mu4e-org-store-and-capture)

Attachments

Dump all attachments to dir

This code defines a new function called mu4e-action-download-all-attachments that takes a message object as its argument. It prompts the user to choose a directory to save the attachments to, and then loops over all attachments of the message, saving each attachment to the specified directory.

The add-to-list function is used to add the new action to the mu4e actions menu. The first argument specifies the list to add the action to (mu4e-headers-actions), the second argument is a cons cell that defines the name of the action and the function to execute when the action is selected, and the third argument (t) specifies that the action should be added to the beginning of the list.

(defun mu4e-action-download-all-attachments (msg)
  "Download all attachments of the given message to the specified directory."
  (let ((directory (read-directory-name "Save attachments to directory: ")))
    (dolist (att (mu4e-message-field msg :attachments))
      (let ((filename (car att))
            (content (cadr att)))
        (with-temp-file (expand-file-name filename directory)
          (insert content))))))
(add-to-list 'mu4e-headers-actions
             '("download all attachments" . mu4e-action-download-all-attachments) t)

                                        ;(load "~/.emacs.d/lisp/mu4e-view-save-all-attachments.el")
                                        ;(define-key mu4e-view-mode-map ">" 'mu4e-view-save-all-attachments)

Delete attachments

GPG

(setq mu4e-decryption-policy t)

Desktop settings

Mutt/mail settings

Define hooks for mail mode

(setq auto-mode-alist (append '(("/tmp/mutt.*" . mail-mode)) auto-mode-alist))
(defun my-mail-mode-hook ()
  (auto-fill-mode 1)
  (abbrev-mode 1)
  (local-set-key "\C-Xk" 'server-edit))
(add-hook 'mail-mode-hook 'my-mail-mode-hook)
(defun my-mail-before-save-hook ()
  (when (eq major-mode 'mail-mode)
    (flyspell-mode)
    (fd-switch-dictionary)
    (flyspell-buffer)))

(add-hook 'before-save-hook #'my-mail-before-save-hook)
;; config for
(require 'mutt-mode)

Function to open new mutt instance in screen

(defun screen-new-mutt-window ()
       "Tell screen to open new window and open neomutt"
       (interactive)
       (shell-command "screen -X -S my_screen_session screen mutt -R"))

Bind the function to a key.

(global-set-key (kbd "C-c M") 'screen-new-mutt-window)

Color multiple levels

(add-hook 'mail-mode-hook
          (lambda ()
            (font-lock-add-keywords nil
                                    '(("^[ \t]*>[ \t]*>[ \t]*>.*$"
                                       (0 'org-level-2))
                                      ("^[ \t]*>[ \t]*>.*$"
                                       (0 'org-level-1))))))

Mail quote prefix

(setq mail-yank-prefix "> ")

Solarized

https://github.com/bbatsov/solarized-emacs

;; make the fringe stand out from the background
(setq solarized-distinct-fringe-background t)

;; Don't change the font for some headings and titles
(setq solarized-use-variable-pitch nil)

;; make the modeline high contrast
(setq solarized-high-contrast-mode-line t)

;; Use less bolding
(setq solarized-use-less-bold t)

;; Use more italics
(setq solarized-use-more-italic t)

;; Use less colors for indicators such as git:gutter, flycheck and similar
(setq solarized-emphasize-indicators nil)

;; Don't change size of org-mode headlines (but keep other size-changes)
(setq solarized-scale-org-headlines nil)

;; Avoid all font-size changes
(setq solarized-height-minus-1 1.0)
(setq solarized-height-plus-1 1.0)
(setq solarized-height-plus-2 1.0)
(setq solarized-height-plus-3 1.0)
(setq solarized-height-plus-4 1.0)
;; Colors by Solarized
(add-to-list 'custom-theme-load-path "~/.emacs.d/themes")
(use-package solarized-theme
:ensure t
:config (load-theme 'solarized-dark t))

Load desktop packages

https://www.emacswiki.org/emacs/BookmarkPlus

(add-to-list 'load-path "~/.emacs.d/lisp/bookmark+/")
(require 'bookmark+)

https://www.emacswiki.org/emacs/DiredPlus

;(require 'dired+)                      ;

https://www.gnu.org/software/emacs/manual/html_node/dired-x/

(require 'dired-x)

https://github.com/vedang/pdf-tools

(pdf-tools-install)

GPG

(setq epg-gpg-program "gpg2")

Custom set variables

(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(LaTeX-math-list
   (quote
    ((78 "neg"
         ("Misc Symbol")
         nil)
     ("=" "models"
      ("Relational")
      nil)
     ("'" LaTeX-math-mathbb "Mathbb-whatever" nil)
     ("," LaTeX-math-mathfrak "Mathfrak-whatever" nil)
     ("v 0" "varnothing"
      ("AMS" "Misc")
      8709)
     ("v d" "diam"
      ("AMS" "Misc")
      nil)
     ("v b" "Box"
      ("AMS" "Misc")
      nil)
     ("o" "not"
      ("AMS" "Misc")
      nil))))
 '(TeX-command-list
   (quote
    (("TeX" "%(PDF)%(tex) %`%S%(PDFout)%(mode)%' %t" TeX-run-TeX nil
      (plain-tex-mode texinfo-mode ams-tex-mode)
      :help "Run plain TeX")
     ("LaTeX" "%`%l%(mode)%' %t" TeX-run-TeX nil
      (latex-mode doctex-mode)
      :help "Run LaTeX")
     ("Makeinfo" "makeinfo %t" TeX-run-compile nil
      (texinfo-mode)
      :help "Run Makeinfo with Info output")
     ("Makeinfo HTML" "makeinfo --html %t" TeX-run-compile nil
      (texinfo-mode)
      :help "Run Makeinfo with HTML output")
     ("AmSTeX" "%(PDF)amstex %`%S%(PDFout)%(mode)%' %t" TeX-run-TeX nil
      (ams-tex-mode)
      :help "Run AMSTeX")
     ("ConTeXt" "texexec --once --texutil %(execopts)%t" TeX-run-TeX nil
      (context-mode)
      :help "Run ConTeXt once")
     ("ConTeXt Full" "texexec %(execopts)%t" TeX-run-TeX nil
      (context-mode)
      :help "Run ConTeXt until completion")
     ("BibTeX" "bibtex %s" TeX-run-BibTeX nil t :help "Run BibTeX")
     ("Biber" "biber %s" TeX-run-Biber nil t :help "Run Biber")
     ("View" "%V" TeX-run-discard-or-function t t :help "Run Viewer")
     ("Print" "%p" TeX-run-command t t :help "Print the file")
     ("Queue" "%q" TeX-run-background nil t :help "View the printer queue" :visible TeX-queue-command)
     ("File" "%(o?)dvips %d -o %f " TeX-run-command t t :help "Generate PostScript file")
     ("Index" "makeindex %s" TeX-run-command nil t :help "Create index file")
     ("Check" "lacheck %s" TeX-run-compile nil
      (latex-mode)
      :help "Check LaTeX file for correctness")
     ("Spell" "(TeX-ispell-document \"\")" TeX-run-function nil t :help "Spell-check the document")
     ("Clean" "TeX-clean" TeX-run-function nil t :help "Delete generated intermediate files")
     ("Clean All" "(TeX-clean t)" TeX-run-function nil t :help "Delete generated intermediate and output files")
     ("Other" "" TeX-run-command t t :help "Run an arbitrary command")
     ("compile-hfs" "compile_hfs" TeX-run-command nil t))))
 '(TeX-source-correlate-method (quote synctex))
 '(TeX-source-correlate-mode t)
 '(TeX-source-correlate-start-server t)
 '(TeX-view-program-list (quote (("Evince" "evince --page-index=%(outpage) %o"))))
 '(ansi-color-names-vector
   ["#073642" "#dc322f" "#859900" "#b58900" "#268bd2" "#d33682" "#2aa198" "#657b83"])
 '(column-number-mode t)
 '(custom-safe-themes
   (quote
    ("2809bcb77ad21312897b541134981282dc455ccd7c14d74cc333b6e549b824f3" "7f1d414afda803f3244c6fb4c2c64bea44dac040ed3731ec9d75275b9e831fe5" "d91ef4e714f05fff2070da7ca452980999f5361209e679ee988e3c432df24347" "0598c6a29e13e7112cfbc2f523e31927ab7dce56ebb2016b567e1eff6dc1fd4f" "1e7e097ec8cb1f8c3a912d7e1e0331caeed49fef6cff220be63bd2a6ba4cc365" "fc5fcb6f1f1c1bc01305694c59a1a861b008c534cae8d0e48e4d5e81ad718bc6" default)))
 '(default-input-method "chinese-sw")
 '(mingus-stream-alist
   (quote
    (("Radio Rota" . "http://streamer.radiorota.cz:8000/rota64.ogg")
     ("BBC Radio 3"
      . "http://bbcmedia.ic.llnwd.net/stream/bbcmedia_radio3_mf_p"))))
 '(org-modules
   (quote
    (ol-bbdb ol-bibtex ol-docview ol-gnus ol-info ol-irc ol-mhe ol-rmail ol-w3m)))
 '(package-selected-packages
   (quote
    (markdown-mode emojify ox-hugo org-download helm-org-rifle yaml-mode mingus mutt-mode php-mode flycheck which-key web-mode direx dired-k minimap magit use-package tablist swiper solarized-theme projectile popup pkg-info org-caldav ivy helm-projectile helm-core helm-ag helm epl counsel bind-key)))
 '(safe-local-variable-values
   (quote
    ((eval add-hook
           (quote after-save-hook)
           (lambda nil
             (org-babel-tangle))
           nil t))))
 '(show-paren-mode t)
 '(tool-bar-mode nil)
 '(vc-annotate-background nil)
 '(vc-annotate-background-mode nil)
 '(vc-annotate-color-map
   (quote
    ((20 . "#dc322f")
     (40 . "#c8805d801780")
     (60 . "#bec073400bc0")
     (80 . "#b58900")
     (100 . "#a5008e550000")
     (120 . "#9d0091000000")
     (140 . "#950093aa0000")
     (160 . "#8d0096550000")
     (180 . "#859900")
     (200 . "#66aa9baa32aa")
     (220 . "#57809d004c00")
     (240 . "#48559e556555")
     (260 . "#392a9faa7eaa")
     (280 . "#2aa198")
     (300 . "#28669833af33")
     (320 . "#279993ccbacc")
     (340 . "#26cc8f66c666")
     (360 . "#268bd2"))))
 '(vc-annotate-very-old-color nil)
 '(warning-suppress-types '((emacs) (emacs)))
 '(xterm-color-names
   ["#073642" "#dc322f" "#859900" "#b58900" "#268bd2" "#d33682" "#2aa198" "#eee8d5"])
 '(xterm-color-names-bright
   ["#002b36" "#cb4b16" "#586e75" "#657b83" "#839496" "#6c71c4" "#93a1a1" "#fdf6e3"]))
;; (custom-set-faces
;;  ;; custom-set-faces was added by Custom.
;;  ;; If you edit it by hand, you could mess it up, so be careful.
;;  ;; Your init file should contain only one such instance.
;;  ;; If there is more than one, they won't work right.
;;  '(default ((t (:family "Inconsolata" :foundry "CYRE" :slant normal :weight normal :height 120 :width normal)))))
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 )

Modified: 2024-02-18 15:55:45 CET

Emacs 29.2 (Org mode 9.6.15)