Skip to content

cedricchevalier19/dotemacs

Repository files navigation

My Emacs configuration

My Emacs configuration

It is inspired by:

Preconfiguration

Header

lexical-binding is Necessary for some lambdas used to configure org-roam.

;; -*- lexical-binding: t -*-
;;; My emacs configuration
;;; Commentary:
;;; Generated from readme.org
;;; Do not editorial

;;; Code:

Package management

;;; Code:
(require 'package)
(add-to-list 'package-archives '("gnu"   . "https://elpa.gnu.org/packages/"))
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
(package-initialize)

(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))
(eval-and-compile
  (require 'use-package)
  (setq use-package-always-ensure t
        use-package-expand-minimally t))
(use-package bind-key)

Customization

(defvar cc/roam-dir "~/org/roam")
(defvar cc/bibfiles '("~/org/roam/zotero.bib"))

Startup profiling

(use-package esup
  :ensure t)
(use-package benchmark-init
  :ensure t
  :config
  ;; To disable collection of benchmark data after init is done.
  (add-hook 'after-init-hook 'benchmark-init/deactivate))

Generic

(use-package no-littering
  :demand t
  :commands (no-littering-expand-etc-file-name)
  :init
  (require 'recentf)

  (setq no-littering-etc-directory (expand-file-name "etc" user-emacs-directory))
  (setq no-littering-var-directory (expand-file-name "var" user-emacs-directory))
  ;; exclude from recentf
  (add-to-list 'recentf-exclude no-littering-var-directory)
  (add-to-list 'recentf-exclude no-littering-etc-directory)
  ;; store auto save files in the var directory.
  :config
  (setq auto-save-file-name-transforms
        `((".*" ,(no-littering-expand-var-file-name "auto-save/") t))))

(customize-set-variable 'load-prefer-newer t) ;; load newer bytecode
;;;; auto compile
(use-package auto-compile
  :demand t
  :init
  (auto-compile-on-load-mode))

(use-package diminish
  :defer t)

Programming

Formatting

(use-package apheleia
:config
(apheleia-global-mode +1))
** Documentation
(use-package devdocs
  :bind (("C-h D" . devdocs-lookup))
  :hook
  (cmake-mode . (lambda () (setq-local devdocs-current-docs '("cmake~3.24"))))
  (sh-mode . (lambda () (setq-local devdocs-current-docs '("bash"))))
  )

CMake

Edit

(use-package cmake-mode
  :mode ("CMakeLists.txt'" "\\.cmake\\'"))

(use-package cmake-font-lock
  :after (cmake-mode)
  :hook (cmake-mode . cmake-font-lock-activate))

Develop

Meson

(use-package meson-mode
  :mode ("meson.build'" "meson_options.txt'"))

Git

Magit

(use-package magit
  :bind (("C-x g" . magit-status)))

Current modifications

(use-package diff-hl
  :after vc
  :config
  (setq diff-hl-draw-borders nil)
  (setq diff-hl-side 'left)
  :hook (after-init-hook . global-diff-hl-mode))

gitlab support

Forge

(use-package forge
  :after magit
  ;;  :config (setq auth-sources '("~/.authinfo"))
  )

From https://magit.vc/manual/ghub/Storing-a-Token.html#Storing-a-Token

git config --global github.user USERNAME

The variable auth-sources controls how and where Auth-Source keeps its secrets. The default value is a list of three files: (“~/.authinfo” “~/.authinfo.gpg” “~/.netrc”), but to avoid confusion you should make sure that only one of these files exists and then you should also adjust the value of the variable to only ever use that file, for example:

(setq auth-sources ‘(“~/.authinfo”))

In ~/.authinfo secrets are stored in plain text. If you don’t want that, then you should use the encrypted ~/.authinfo.gpg instead:

(setq auth-sources ‘(“~/.authinfo.gpg”))

Auth-Source also supports storing secrets in various external key-chains. See (auth)Top for more information.

The default Auth-Source backends only support storing three values per entry; the “machine”, the “login” and the “password”. Because Ghub uses separate tokens for each package, it has to squeeze four values into those three slots, and it does that by using “USERNAME^PACKAGE” as the “login”.

Assuming your Github username is “ziggy”, the package is named “forge”, and you want to access Github.com, an entry in one of the three mentioned files would then look like this:

machine api.github.com login ziggy^forge password 012345abcdef…

Assuming your Gitlab username is “ziggy”, the package is named “forge”, and you want to access Gitlab.com, an entry in one of the three mentioned files would then look like this:

machine gitlab.com/api/v4 login ziggy^forge password 012345abcdef..

Gitlab ci

LUA

(use-package lua-mode)

Python

(use-package python-black
  :demand t
  :after python
  :hook (python-mode . python-black-on-save-mode))

Yaml

(use-package yaml-mode
  :init (setq yapfify-executable "yapf3")
  :mode ("\\.yml\\'" . yaml-mode))

Docker

(use-package docker
  :bind ("C-c d" . docker))

(use-package dockerfile-mode
  :mode ("Dockerfile\\'" "\\.dockerfile$"))

Golang

(use-package go-mode
  :config
  (use-package go-eldoc
    :after (go-mode)
    :hook (go-mode . go-eldoc-setup))
  :mode ("\\.go$"))

Markdown

Needs pandoc

(use-package markdown-mode
  :delight "μ "
  :mode ("\\.markdown\\'" "\\.md\\'")
  :custom (markdown-command "/usr/bin/pandoc"))

RST

plain

(use-package rst
  :delight "rst"
  :mode (("\\.rst$" . rst-mode)
         ("\\.rest$" . rst-mode)))

sphinx

(use-package sphinx-mode
  :after rst)

Shell scripts

Exec rights

The snippet below ensures that the execution right is automatically granted to save a shell script file that begins with a #! shebang:

(use-package sh-script
  :ensure nil
  :hook (after-save . executable-make-buffer-file-executable-if-script-p))

Fish support

(use-package fish-mode
  :mode ("\\.fish\\'"))

Rust

rust-analyser must be installed before (https://rust-analyzer.github.io/manual.html#installation)

rustup component add rust-analyzer

From https://www.bytedude.com/setting-up-rust-support-in-emacs/

(use-package rustic
  :config
  (setq
   ;; eglot seems to be the best option right now.
   rustic-lsp-client 'eglot
   rustic-format-on-save nil
   ;; Prevent automatic syntax checking, which was causing lags and stutters.
   eglot-send-changes-idle-time (* 60 60)
   rustic-analyzer-command '("~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rust-analyzer")
   )
  ;; Disable the annoying doc popups in the minibuffer.
  (add-hook 'eglot-managed-mode-hook (lambda () (eldoc-mode -1)))
  ;;:mode ("\\.rs\\'" "Cargo.toml\\'")
  )

Parentheses

(use-package smartparens
  :diminish smartparens-mode
  :config
  (smartparens-global-mode)
  ;; (sp-local-pair 'org-mode "*" "*")
  ;; (sp-local-pair 'org-mode "_" "_")
  )

(use-package highlight-parentheses
  :diminish highlight-parentheses-mode
  :config (global-highlight-parentheses-mode))

(defvar show-paren-delay 0)
(show-paren-mode t)

Pantuml

(use-package plantuml-mode
  :config
  (setq org-plantuml-jar-path
        (expand-file-name "/usr/share/plantuml/plantuml.jar"))
  (setq plantuml-default-exec-mode 'jar)
  :mode ("\\.plantuml\\'"))

Project

(use-package project
  :ensure t)

Interface

Theme

(use-package leuven-theme
  :ensure t
  :config
  (load-theme 'leuven t))

Better display for text

(use-package olivetti
  :ensure
  :diminish
  :config
  (setq olivetti-body-width 0.7)
  (setq olivetti-minimum-body-width 80)
  (setq olivetti-recall-visual-line-mode-entry-state t))

Which-key

(use-package which-key
  :commands which-key-mode)

Regular expressions

(use-package visual-regexp-steroids
  :commands vr/replace)

Hydra

(use-package hydra)

Multiple-cursors

(use-package multiple-cursors
  :bind (("C-C m c" . mc/edit-lines)))

Dashboard

(use-package all-the-icons
  :if (display-graphic-p))

(use-package dashboard
  :after all-the-icons
  :init
  (dashboard-setup-startup-hook)
  :config
  ;; Dashboard requirements.
  (use-package page-break-lines)
  (use-package all-the-icons)
  ;; Dashboard configuration.
  (setq dashboard-banner-logo-title "Welcome to Emacs")
  (setq dashboard-startup-banner 'logo)
  (setq dashboard-items '((recents   . 5)
                          (agenda    . 5)))
  (setq dashboard-set-init-info t)
  (setq dashboard-set-heading-icons t)
  (setq dashboard-set-file-icons t)

  ;; adds a clock
  (defun dashboard-insert-custom (list-size)
    (defun string-centralized (str)
      (let* ((indent
              (concat "%"
                      (number-to-string
                       (/ (- (window-body-width) (string-width str)) 2))
                      "s"))
             (str (concat indent str indent)))
        (format str " " " ")))

    (insert (propertize (string-centralized (format-time-string "%a %d %b %Y" (current-time))) 'font-lock-face '('bold :foreground "#6c4c7b")))
    (newline)
    (insert (propertize (string-centralized (format-time-string "%H:%M" (current-time))) 'font-lock-face '('bold :foreground "#6c4c7b"))))

  (add-to-list 'dashboard-item-generators  '(custom . dashboard-insert-custom))
  (add-to-list 'dashboard-items '(custom) t)

  (defun test-dashboard () (setq *my-timer* (run-at-time "20 sec" nil #'(lambda ()
                                                                          (when *my-timer*
                                                                            (cancel-timer *my-timer*)
                                                                            (setq *my-timer* nil))
                                                                          (when (string=
                                                                                 (buffer-name (window-buffer))
                                                                                 "*dashboard*")
                                                                            (dashboard-refresh-buffer))))))
  (add-hook 'dashboard-mode-hook #'test-dashboard))

Features

Consult

https://github.com/minad/consult

;; Example configuration for Consult
(use-package consult
  ;; Replace bindings. Lazily loaded due by `use-package'.
  :bind (;; C-c bindings (mode-specific-map)
         ("C-c h" . consult-history)
         ("C-c m" . consult-mode-command)
         ("C-c k" . consult-kmacro)
         ;; C-x bindings (ctl-x-map)
         ("C-x M-:" . consult-complex-command)     ;; orig. repeat-complex-command
         ("C-x b" . consult-buffer)                ;; orig. switch-to-buffer
         ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
         ("C-x 5 b" . consult-buffer-other-frame)  ;; orig. switch-to-buffer-other-frame
         ("C-x r b" . consult-bookmark)            ;; orig. bookmark-jump
         ("C-x p b" . consult-project-buffer)      ;; orig. project-switch-to-buffer
         ;; Custom M-# bindings for fast register access
         ("M-#" . consult-register-load)
         ("M-'" . consult-register-store)          ;; orig. abbrev-prefix-mark (unrelated)
         ("C-M-#" . consult-register)
         ;; Other custom bindings
         ("M-y" . consult-yank-pop)                ;; orig. yank-pop
         ("<help> a" . consult-apropos)            ;; orig. apropos-command
         ;; M-g bindings (goto-map)
         ("M-g e" . consult-compile-error)
         ("M-g f" . consult-flymake)               ;; Alternative: consult-flycheck
         ("M-g g" . consult-goto-line)             ;; orig. goto-line
         ("M-g M-g" . consult-goto-line)           ;; orig. goto-line
         ("M-g o" . consult-outline)               ;; Alternative: consult-org-heading
         ("M-g m" . consult-mark)
         ("M-g k" . consult-global-mark)
         ("M-g i" . consult-imenu)
         ("M-g I" . consult-imenu-multi)
         ;; M-s bindings (search-map)
         ("M-s d" . consult-find)
         ("M-s D" . consult-locate)
         ("M-s g" . consult-grep)
         ("M-s G" . consult-git-grep)
         ("M-s r" . consult-ripgrep)
         ("M-s l" . consult-line)
         ("M-s L" . consult-line-multi)
         ("M-s m" . consult-multi-occur)
         ("M-s k" . consult-keep-lines)
         ("M-s u" . consult-focus-lines)
         ;; Isearch integration
         ("M-s e" . consult-isearch-history)
         :map isearch-mode-map
         ("M-e" . consult-isearch-history)         ;; orig. isearch-edit-string
         ("M-s e" . consult-isearch-history)       ;; orig. isearch-edit-string
         ("M-s l" . consult-line)                  ;; needed by consult-line to detect isearch
         ("M-s L" . consult-line-multi)            ;; needed by consult-line to detect isearch
         ;; Minibuffer history
         :map minibuffer-local-map
         ("M-s" . consult-history)                 ;; orig. next-matching-history-element
         ("M-r" . consult-history))                ;; orig. previous-matching-history-element

  ;; Enable automatic preview at point in the *Completions* buffer. This is
  ;; relevant when you use the default completion UI.
  :hook (completion-list-mode . consult-preview-at-point-mode)

  ;; The :init configuration is always executed (Not lazy)
  :init

  ;; Optionally configure the register formatting. This improves the register
  ;; preview for `consult-register', `consult-register-load',
  ;; `consult-register-store' and the Emacs built-ins.
  (setq register-preview-delay 0.5
        register-preview-function #'consult-register-format)

  ;; Optionally tweak the register preview window.
  ;; This adds thin lines, sorting and hides the mode line of the window.
  (advice-add #'register-preview :override #'consult-register-window)

  ;; Use Consult to select xref locations with preview
  (setq xref-show-xrefs-function #'consult-xref
        xref-show-definitions-function #'consult-xref)

  ;; Configure other variables and modes in the :config section,
  ;; after lazily loading the package.
  :config

  ;; Optionally configure preview. The default value
  ;; is 'any, such that any key triggers the preview.
  ;; (setq consult-preview-key 'any)
  ;; (setq consult-preview-key (kbd "M-."))
  ;; (setq consult-preview-key (list (kbd "<S-down>") (kbd "<S-up>")))
  ;; For some commands and buffer sources it is useful to configure the
  ;; :preview-key on a per-command basis using the `consult-customize' macro.
  (consult-customize
   consult-theme :preview-key '(:debounce 0.2 any)
   consult-ripgrep consult-git-grep consult-grep
   consult-bookmark consult-recent-file consult-xref
   consult--source-bookmark consult--source-file-register
   consult--source-recent-file consult--source-project-recent-file
   ;; :preview-key (kbd "M-.")
   :preview-key '(:debounce 0.4 any))

  ;; Optionally configure the narrowing key.
  ;; Both < and C-+ work reasonably well.
  (setq consult-narrow-key "<") ;; (kbd "C-+")

  ;; Optionally make narrowing help available in the minibuffer.
  ;; You may want to use `embark-prefix-help-command' or which-key instead.
  ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help)

  ;; By default `consult-project-function' uses `project-root' from project.el.
  ;; Optionally configure a different project root function.
  ;; There are multiple reasonable alternatives to chose from.
  ;;;; 1. project.el (the default)
  ;; (setq consult-project-function #'consult--default-project--function)
  ;;;; 2. projectile.el (projectile-project-root)
  ;; (autoload 'projectile-project-root "projectile")
  ;; (setq consult-project-function (lambda (_) (projectile-project-root)))
  ;;;; 3. vc.el (vc-root-dir)
  ;; (setq consult-project-function (lambda (_) (vc-root-dir)))
  ;;;; 4. locate-dominating-file
  ;; (setq consult-project-function (lambda (_) (locate-dominating-file "." ".git")))
  )

(use-package consult-dir
  :ensure t
  :bind (("C-x C-d" . consult-dir)
         :map minibuffer-local-completion-map
         ("C-x C-d" . consult-dir)
         ("C-x C-j" . consult-dir-jump-file)
         :map selectrum-minibuffer-map
         ("C-x C-d" . consult-dir)
         ("C-x C-j" . consult-dir-jump-file)))

(use-package consult-eglot)

(use-package consult-org-roam
  :ensure t
  :after org-roam
  :init
  (require 'consult-org-roam)
  ;; Activate the minor mode
  (consult-org-roam-mode 1)
  :custom
  ;; Use `ripgrep' for searching with `consult-org-roam-search'
  (consult-org-roam-grep-func #'consult-ripgrep)
  ;; Configure a custom narrow key for `consult-buffer'
  (consult-org-roam-buffer-narrow-key ?r)
  ;; Display org-roam buffers right after non-org-roam buffers
  ;; in consult-buffer (and not down at the bottom)
  (consult-org-roam-buffer-after-buffers t)
  :config
  ;; Eventually suppress previewing for certain functions
  (consult-customize
   consult-org-roam-forward-links
   :preview-key (kbd "M-."))
  :bind
  ;; Define some convenient keybindings as an addition
  ("C-c n e" . consult-org-roam-file-find)
  ("C-c n b" . consult-org-roam-backlinks)
  ("C-c n l" . consult-org-roam-forward-links)
  ("C-c n r" . consult-org-roam-search))

Marginalia

https://github.com/minad/marginalia

;; Enable rich annotations using the Marginalia package
(use-package marginalia
  ;; Either bind `marginalia-cycle' globally or only in the minibuffer
  :bind (("M-A" . marginalia-cycle)
         :map minibuffer-local-map
         ("M-A" . marginalia-cycle))

  ;; The :init configuration is always executed (Not lazy!)
  :init

  ;; Must be in the :init section of use-package such that the mode gets
  ;; enabled right away. Note that this forces loading the package.
  (marginalia-mode))

(use-package embark
  :ensure t

  :bind
  (("C-." . embark-act)         ;; pick some comfortable binding
   ("C-;" . embark-dwim)        ;; good alternative: M-.
   ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'

  :init

  ;; Optionally replace the key help with a completing-read interface
  (setq prefix-help-command #'embark-prefix-help-command)

  :config

  ;; Hide the mode line of the Embark live/completions buffers
  (add-to-list 'display-buffer-alist
               '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
                 nil
                 (window-parameters (mode-line-format . none)))))

;; Consult users will also want the embark-consult package.
(use-package embark-consult
  :ensure t ; only need to install it, embark loads it after consult if found
  :hook
  (embark-collect-mode . consult-preview-at-point-mode))

Vertigo

;; Enable vertico
(use-package vertico
  :init
  (vertico-mode)

  ;; Different scroll margin
  ;; (setq vertico-scroll-margin 0)

  ;; Show more candidates
  ;; (setq vertico-count 20)

  ;; Grow and shrink the Vertico minibuffer
  ;; (setq vertico-resize t)

  ;; Optionally enable cycling for `vertico-next' and `vertico-previous'.
  ;; (setq vertico-cycle t)
  )

;; Persist history over Emacs restarts. Vertico sorts by history position.
(use-package savehist
  :init
  (savehist-mode))

;; A few more useful configurations...
(use-package emacs
  :init
  ;; Add prompt indicator to `completing-read-multiple'.
  ;; We display [CRM<separator>], e.g., [CRM,] if the separator is a comma.
  (defun crm-indicator (args)
    (cons (format "[CRM%s] %s"
                  (replace-regexp-in-string
                   "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" ""
                   crm-separator)
                  (car args))
          (cdr args)))
  (advice-add #'completing-read-multiple :filter-args #'crm-indicator)

  ;; Do not allow the cursor in the minibuffer prompt
  (setq minibuffer-prompt-properties
        '(read-only t cursor-intangible t face minibuffer-prompt))
  (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)

  ;; Emacs 28: Hide commands in M-x which do not work in the current mode.
  ;; Vertico commands are hidden in normal buffers.
  ;; (setq read-extended-command-predicate
  ;;       #'command-completion-default-include-p)

  ;; Enable recursive minibuffers
  (setq enable-recursive-minibuffers t))

;; Optionally use the `orderless' completion style.
(use-package orderless
  :init
  ;; Configure a custom style dispatcher (see the Consult wiki)
  ;; (setq orderless-style-dispatchers '(+orderless-dispatch)
  ;;       orderless-component-separator #'orderless-escapable-split-on-space)
  (setq completion-styles '(orderless flex)
        completion-category-defaults nil
        completion-category-overrides '((file (styles partial-completion)) (eglot (styles . (orderless flex))))))

Dired

Use built-in dired with =dired-hacks=

Completion

corfu is used

(use-package corfu
  ;; Optional customizations
  :custom
  (corfu-cycle t)                ;; Enable cycling for `corfu-next/previous'
  (corfu-auto t)                 ;; Enable auto completion
  ;; (corfu-separator ?\s)          ;; Orderless field separator
  ;; (corfu-quit-at-boundary nil)   ;; Never quit at completion boundary
  ;; (corfu-quit-no-match nil)      ;; Never quit, even if there is no match
  ;; (corfu-preview-current nil)    ;; Disable current candidate preview
  ;; (corfu-preselect-first nil)    ;; Disable candidate preselection
  ;; (corfu-on-exact-match nil)     ;; Configure handling of exact matches
  ;; (corfu-scroll-margin 5)        ;; Use scroll margin

  ;; Enable Corfu only for certain modes.
  ;; :hook ((prog-mode . corfu-mode)
  ;;        (shell-mode . corfu-mode)
  ;;        (eshell-mode . corfu-mode))

  :bind (:map corfu-map
              ("C-j" . corfu-next)
              ("C-k" . corfu-previous)
              ("TAB" . corfu-insert)
              ("RET" . nil))

  ;; Recommended: Enable Corfu globally.
  ;; This is recommended since Dabbrev can be used globally (M-/).
  ;; See also `corfu-excluded-modes'.
  :init
  (global-corfu-mode)
  (global-set-key (kbd "M-i") #'completion-at-point)
  )

Indent

Indent

(use-package indent-tools
  :bind (("C-C >" .'indent-tools-hydra/body)))

editor config

(use-package editorconfig
  :defer 0.3
  :config (editorconfig-mode 1))

highlight

(use-package highlight-indent-guides
  :defer 0.3
  :hook (prog-mode . highlight-indent-guides-mode)
  :custom (highlight-indent-guides-method 'character))

eglot

Core

(use-package eglot
  :init
  (setq exec-path (append '("~/opt/lsp-tools/bin") exec-path))
  ;; Option 1: Specify explicitly to use Orderless for Eglot
  (setq completion-category-overrides '((eglot (styles orderless))))
  :config
  (add-hook 'c-mode-hook 'eglot-ensure)
  (add-hook 'c++-mode-hook 'eglot-ensure)
  (setq completion-category-defaults nil)
  )

debugger

;; (use-package dap-mode
;;   :disabled)
;; (use-package dap-LANGUAGE) to load the dap adapter for your language

Flycheck

(use-package flycheck
  :init (global-flycheck-mode))

Jinx

https://github.com/minad/jinx

Jinx a just-in-time spell-checker. It requires enchant.

On mac:

brew install enchant
(use-package jinx
  :hook (emacs-startup . global-jinx-mode)
  :custom
  (add-to-list 'vertico-multiform-categories
               '(jinx grid (vertico-grid-annotate . 20)))
  (vertico-multiform-mode 1)
  :bind (("M-$" . jinx-correct)
         ("C-M-$" . jinx-languages)))

Custom

(setq-default
 auto-save-list-file-name  (expand-file-name "local/auto-save-list"
                                             user-emacs-directory)
 custom-file  (expand-file-name "local/custom.el"
                                user-emacs-directory))
(when (file-exists-p custom-file)
  (load custom-file t))

Search

Fuzzy

(use-package fzf)

ripgrep

(use-package deadgrep)

Snippets

(use-package yasnippet
  :disabled
  :config
  (add-to-list 'yas-snippet-dirs (expand-file-name "snippets"
                                                   user-emacs-directory))
  (yas-global-mode 1))

And some preconfigured snippets:

(use-package yasnippet-snippets
  :disabled)

Undo

(use-package vundo
  :config
  (setq vundo-glyph-alist vundo-unicode-symbols)
  )

Org

Main config

(use-package org
  :config

  (setq org-latex-logfiles-extensions
        '("acn" "ind" "ilg" "ist" "glo" "tex" "synctex.gz"))

  :custom
  ;;;;;;; Files
  (org-directory (file-truename "~/org/"))
  ;; setup archive directory in current folder
  (org-archive-location "archive/%s_archive::")
  (org-agenda-files (list "inbox.org"))
  (org-capture-templates
   `(("i" "Inbox" entry  (file "inbox.org")
      ,(concat "* TODO %?\n"
               "/Entered on/ %U"))))
  ;;;;;;; Org source
  (org-ctrl-k-protect-subtree 'error)
  (org-startup-indented t)
  (org-catch-invisible-edits 'smart)
  ;;;;;;; Structure and Appearance
  (org-display-remote-inline-images 'cache)
  (org-insert-heading-respect-content t)
  (org-ellipsis "")
  (org-list-allow-alphabetical t)
  (org-hide-emphasis-markers t)
  (org-hidden-keywords '(author title date))
  (org-pretty-entities t)
  (org-use-sub-superscripts '{})
  (org-use-speed-commands t)
  (org-yank-folded-subtrees t)
  (org-yank-adjusted-subtrees t)
  (org-blank-before-new-entry
   '((heading . auto)
     (plain-list-item . auto)))

  :bind
  (("C-c a" . org-agenda)
   ("C-c c" . org-capture)
   ("C-c b" . org-switchb)
   ("C-c i" . (lambda () "Open inbox capture window"
                (interactive)
                (org-capture nil "i")))
   (:map org-mode-map
         ("C-c C-x h" . org-toggle-link-display)
         ("C-c C-s" . org-schedule))
   )
  )

Org-babel

(with-eval-after-load 'org
  (setq org-confirm-babel-evaluate nil)
  (setq org-src-fontify-natively t)
  (setq org-src-preserve-indentation t)
  (setq org-src-persistent-message nil)
  (setq org-src-window-setup 'current-window)

  (add-to-list 'org-src-lang-modes '("plantuml" . plantuml))
  (defadvice org-babel-execute-src-block (around load-language nil activate)
    "Load language if needed"
    (let ((language (org-element-property :language (org-element-at-point))))
      (unless (cdr (assoc (intern language) org-babel-load-languages))
        (add-to-list 'org-babel-load-languages (cons (intern language) t))
        (org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages))
      ad-do-it))
  (org-babel-do-load-languages 'org-babel-load-languages
                               '(
                                 (C . t)
                                 (ditaa . t)
                                 (emacs-lisp . t)
                                 (gnuplot . t)
                                 (latex . t)
                                 (plantuml . t)
                                 (python . t)
                                 (shell . t)
                                 ))
  (setq org-ditaa-jar-path "/usr/bin/ditaa")
  )

Org-Latex

(with-eval-after-load 'ox-latex
  (setq org-latex-hyperref-template nil)
  (setq org-latex-listings 'minted)
  (setq org-latex-minted-options
	'(("mathescape" "true")
	  ("escapeinside" "@@")
	  ("breaklines" "true")
	  ("fontsize" "\\tiny")))
  (setq org-latex-compiler "xelatex")
  (defcustom org-latex-minted-from-org-p 't
    "If non-nil, then included minted in `org-latex-packages-alist'
      and get options from `org-latex-minted-options'."
    :type 'boolean
    :group 'org-export-latex
    :version "26.1"
    :package-version '(Org . "9.0"))

  (defun org-latex-toggle-minted-from-org ()
    "Toggle `org-latex-minted-from-org-p'."
    (interactive)
    (cl-flet ((nominted (pkg) (not (string= (cadr pkg) "minted"))))
      (if (not org-latex-minted-from-org-p)
          (setq org-latex-packages-alist
                (append org-latex-packages-alist '(("newfloat" "minted"))))
        (setq org-latex-packages-alist (seq-filter #'nominted org-latex-packages-alist)))
      (setq org-latex-minted-from-org-p (not org-latex-minted-from-org-p))
      (message "org minted %s" (if org-latex-minted-from-org-p
                                   "enabled" "disabled"))))
  ;; Latex process
  (setq oxl-process-bibtex
        '("latexmk -pdflatex='pdflatex -interaction=nonstopmode -shell-escape' -synctex=1 -pdf -bibtex -f %f"))

  (setq oxl-process-biber
        '("latexmk -pdflatex='pdflatex -interaction=nonstopmode -shell-escape' -synctex=1 -pdf -biber -f %f"))

  (setq oxl-process-xelatex
        '("latexmk -pdf -shell-escape -xelatex -f %f"))

  (setq oxl-process-lualatex
        '("latexmk -pdf -synctex=1 -shell-escape -lualatex -f %f"))

  (defcustom org-latex-pdf-engines
    '(("lualatex" . oxl-process-lualatex)
      ("xelatex" . oxl-process-xelatex)
      ("pdflatex" . (oxl-process-bibtex oxl-process-biber)))
    "A list of LaTeX commands available to run when
      `org-latex-export-to-pdf' is invoked."
    :type '(choice (cons string symbol) (cons string (repeat symbol)))
    :group 'org-export-latex
    :version "26.1")

  (defvar org-latex-pdf-process-hook nil
    "Hook to run after setting pdf process.")

  (defun org-latex-pdf-process-set (compiler)
    (interactive
     (list (completing-read "Compiler: " org-latex-pdf-engines)))
    (if (member compiler org-latex-compilers)
        (let ((process (cdr (assoc compiler org-latex-pdf-engines))))
          (setq org-latex-pdf-process (symbol-value
                                       (if (listp process)
                                           (intern (completing-read "Process:" process))
                                         process))
                org-latex-compiler compiler)
          (run-hooks org-latex-pdf-process-hook))
      (error "%s not in `org-latex-compilers'" compiler)))
  (setq org-latex-logfiles-extensions
        (append org-latex-logfiles-extensions
                '("acn" "ind" "ilg" "ist" "glo" "tex" "synctex.gz")))
  )

(with-eval-after-load 'ox
  (org-latex-pdf-process-set org-latex-compiler))

mermaid

(use-package mermaid-mode)
(use-package ob-mermaid
  :after org
  :defer t
  :config
  (setq ob-mermaid-cli-path "~/opt/node_modules/.bin/mmdc"))

gnuplot

(use-package gnuplot
  :defer t)

latex

(use-package latex
  :ensure auctex
  :mode
  ("\\.tex\\'" . latex-mode)
  :bind
  (:map LaTeX-mode-map
        ("C-c C-r" . reftex-query-replace-document)
        ("C-c C-g" . reftex-grep-document))
  :config
  (setq-default TeX-master nil ; by each new file AUCTEX will ask for a master fie.
                TeX-PDF-mode t
                TeX-engine 'xetex)     ; optional

  (setq TeX-auto-save t
        TeX-save-query nil       ; don't prompt for saving the .tex file
        TeX-parse-self t
        TeX-show-compilation nil  ; if `t`, automatically shows compilation log
        LaTeX-babel-hyphen nil  ; Disable language-specific hyphen insertion.
        )
  (add-hook 'LaTeX-mode-hook 'reftex-mode)
  ;; Add standard Sweave file extensions to the list of files recognized  by AuCTeX.
  (add-hook 'TeX-mode-hook (lambda () (reftex-isearch-minor-mode)))
  )

Pandoc

(use-package ox-pandoc
  :disabled
  :after (:all ox)
  :custom
  (org-pandoc-options '((standalone . t)))
  :demand t
  :config
  (defun ox-pandoc--pdf-engine ()
    "Set the default latex pdf engine to the one set by `org-latex-pdf-process'. "
    (let ((syms (mapcar (lambda (x) (if (listp x) (if (listp (cdr x)) (cadr x) (cdr x)))) org-latex-pdf-engines))
          (pred (lambda (sym) (eq (symbol-value sym) org-latex-pdf-process)))
          (prefix "oxl-process-"))
      (cadr (split-string (symbol-name (car (seq-filter pred syms))) prefix))))

  (setq org-pandoc-options-for-beamer-pdf
        `((pdf-engine . ,(ox-pandoc--pdf-engine)))
        org-pandoc-options-for-latex-pdf
        `((pdf-engine . ,(ox-pandoc--pdf-engine))))

  (defun org-pandoc-pdf-engine-set (compiler)
    "Set the latex pdf engine for `org-pandoc-export-to-latex-pdf'."
    (interactive
     (list (completing-read "Compiler: " org-latex-compilers)))
    (setq org-pandoc-options-for-beamer-pdf
          `((pdf-engine . ,compiler))
          org-pandoc-options-for-latex-pdf
          `((pdf-engine . ,compiler))))
  ;; Open MS .doc?x files with system viewer.
  (when (symbolp 'org-file-apps)
    (add-to-list 'org-file-apps '("\\.docx?\\'" . system))))

ref

(use-package citar
  :no-require
  :bind (("C-c n o" . citar-open)
         ("C-c r" . citar-insert-citation)
         :map minibuffer-local-map
         ("M-b" . citar-insert-preset))
  :custom
  (org-cite-global-bibliography cc/bibfiles)
  (org-cite-insert-processor 'citar)
  (org-cite-follow-processor 'citar)
  (org-cite-activate-processor 'citar)
  (org-cite-csl-styles-dir
   (expand-file-name "~/Zotero/styles/"))
  (citar-bibliography org-cite-global-bibliography))

(use-package citar-embark
  :after citar embark
  :no-require
  :config (citar-embark-mode))

(use-package citar-org-roam
  :after citar org-roam
  :no-require
  :custom
  (citar-org-roam-subdir "references")
  :config (citar-org-roam-mode))

Roam

For zettelkasten notes.

Requires:

  • sqlite3
  • graphviz for dot

From https://systemcrafters.net/build-a-second-brain-in-emacs/capturing-notes-efficiently/

(use-package org-roam
  :ensure t
  :demand t  ;; Ensure org-roam is loaded by default
  :init
  (setq org-roam-v2-ack t)
  :custom
  (org-roam-directory cc/roam-dir)
  (org-roam-completion-everywhere t)
  (org-roam-capture-templates
   '(
     ("d" "default" plain "%?"
      :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+date: %U\n")
      :unnarrowed t)
     ("p" "person" plain "%?"
      :target (file+head "people/%<%Y%m%d%H%M%S>-${slug}.org"
					; I name these files after the persons work alias,
					; then put their full name under "ROAM_ALIASES"
                         ":PROPERTIES:\n:ROAM_ALIASES: \"${fullname}\"\n:END:\n#+title: ${title}\n#+date: %U\n")
      :unnarrowed t)
     ))
  :bind (("C-c n l" . org-roam-buffer-toggle)
         ("C-c n f" . org-roam-node-find)
         ("C-c n i" . org-roam-node-insert)
         ("C-c n I" . org-roam-node-insert-immediate)
         ("C-c n p" . my/org-roam-find-project)
         ("C-c n t" . my/org-roam-capture-task)
         ("C-c n b" . my/org-roam-capture-inbox)
	 ("C-c n T" . org-roam-dailies-capture-today)
	 ("C-c n d" . org-roam-dailies-find-today)
         :map org-mode-map
         ("C-M-i" . completion-at-point)
         :map org-roam-dailies-map
         ("Y" . org-roam-dailies-capture-yesterday)
         ("T" . org-roam-dailies-capture-tomorrow))
  :bind-keymap
  ("C-c n d" . org-roam-dailies-map)
  :config
  (require 'org-roam-dailies) ;; Ensure the keymap is available
  (org-roam-db-autosync-mode))

(defun org-roam-node-insert-immediate (arg &rest args)
  (interactive "P")
  (let ((args (push arg args))
        (org-roam-capture-templates (list (append (car org-roam-capture-templates)
                                                  '(:immediate-finish t)))))
    (apply #'org-roam-node-insert args)))

(defun my/org-roam-filter-by-tag (tag-name)
  (lambda (node)
    (member tag-name (org-roam-node-tags node))))

(defun my/org-roam-list-notes-by-tag (tag-name)
  (mapcar #'org-roam-node-file
          (seq-filter
           (my/org-roam-filter-by-tag tag-name)
           (org-roam-node-list))))

(defun my/org-roam-refresh-agenda-list ()
  (interactive)
  (setq org-agenda-files (my/org-roam-list-notes-by-tag "Project")))

;; Build the agenda list the first time for the session
(my/org-roam-refresh-agenda-list)

(defun my/org-roam-project-finalize-hook ()
  "Adds the captured project file to `org-agenda-files' if the
capture was not aborted."
  ;; Remove the hook since it was added temporarily
  (remove-hook 'org-capture-after-finalize-hook #'my/org-roam-project-finalize-hook)

  ;; Add project file to the agenda list if the capture was confirmed
  (unless org-note-abort
    (with-current-buffer (org-capture-get :buffer)
      (add-to-list 'org-agenda-files (buffer-file-name)))))

(defun my/org-roam-find-project ()
  (interactive)
  ;; Add the project file to the agenda after capture is finished
  (add-hook 'org-capture-after-finalize-hook #'my/org-roam-project-finalize-hook)

  ;; Select a project file to open, creating it if necessary
  (org-roam-node-find
   nil
   nil
   (my/org-roam-filter-by-tag "Project")
   :templates
   '(("p" "project" plain "* Goals\n\n%?\n\n* Tasks\n\n** TODO Add initial tasks\n\n* Dates\n\n"
      :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+category: ${title}\n#+filetags: Project")
      :unnarrowed t))))

(defun my/org-roam-capture-inbox ()
  (interactive)
  (org-roam-capture- :node (org-roam-node-create)
                     :templates '(("i" "inbox" plain "* %?"
                                   :if-new (file+head "Inbox.org" "#+title: Inbox\n")))))

(defun my/org-roam-capture-task ()
  (interactive)
  ;; Add the project file to the agenda after capture is finished
  (add-hook 'org-capture-after-finalize-hook #'my/org-roam-project-finalize-hook)

  ;; Capture the new task, creating the project file if necessary
  (org-roam-capture- :node (org-roam-node-read
                            nil
                            (my/org-roam-filter-by-tag "Project"))
                     :templates '(("p" "project" plain "** TODO %?"
                                   :if-new (file+head+olp "%<%Y%m%d%H%M%S>-${slug}.org"
                                                          "#+title: ${title}\n#+category: ${title}\n#+filetags: Project"
                                                          ("Tasks"))))))

(defun my/org-roam-copy-todo-to-today ()
  (interactive)
  (let ((org-refile-keep t) ;; Set this to nil to delete the original!
        (org-roam-dailies-capture-templates
         '(("t" "tasks" entry "%?"
            :if-new (file+head+olp "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n" ("Tasks")))))
        (org-after-refile-insert-hook #'save-buffer)
        today-file
        pos)
    (save-window-excursion
      (org-roam-dailies--capture (current-time) t)
      (setq today-file (buffer-file-name))
      (setq pos (point)))

    ;; Only refile if the target file is different than the current file
    (unless (equal (file-truename today-file)
                   (file-truename (buffer-file-name)))
      (org-refile nil nil (list "Tasks" today-file nil pos)))))

(add-to-list 'org-after-todo-state-change-hook
             (lambda ()
               (when (equal org-state "DONE")
                 (my/org-roam-copy-todo-to-today))))

Zotero

Follow http://www.mkbehr.com/posts/a-research-workflow-with-zotero-and-org-mode/

;; (use-package org-noter)
(use-package zotxt)

French

Releases

No releases published

Packages

No packages published