It is inspired by:
- https://github.com/caiohcs/my-emacs/
- https://github.com/jchaffin/.emacs.d
- http://pragmaticemacs.com
- https://protesilaos.com/dotemacs
- https://vincent.demeester.fr/articles/my_organizational_workflow.html
- https://gitlab.com/howardabrams/spacemacs.d/blob/master/elisp/boxes.el
- http://doc.norang.ca/org-mode.html
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 edit
;;; 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)
Follow PARA method with org-roam:
- Project: Short-term efforts
- Area: Long-term responsibilities
- Resource: interests
- Archive: Inactive items
(defconst org-directory "~/org/"
"org-mode directory, where most of the org-mode file lives")
(defconst org-roam-directory (expand-file-name "roam" org-directory)
"Org-roam base directory")
(defconst org-projects-dir (expand-file-name "projects" org-roam-directory)
"Primary tasks directory.")
(defconst org-inbox-file (expand-file-name "Inbox.org" org-roam-directory)
"New stuff collected in this file.")
(defconst org-icalendar-file (expand-file-name "calendar.org" org-roam-directory)
"Synchronize with office calendar")
(defconst org-people-file (expand-file-name "people.org" org-roam-directory)
"org-contacts for colleagues")
(defconst org-home-dir (expand-file-name "home" org-roam-directory)
"Home/personal roam directory")
(defconst org-home-projects-dir (expand-file-name "projects" org-home-dir)
"Home projects directory")
(defconst org-friends-file (expand-file-name "friends.org" org-home-dir)
"org-contacts for friends")
(defconst org-area-dir (expand-file-name "area" org-roam-directory)
"Primary Area directory.")
(defconst org-references-dir (expand-file-name "references" org-roam-directory)
"Primary Area directory.")
(defconst org-roam-bibfile (expand-file-name "zotero.bib" org-roam-directory)
"Main bibfile")
(defconst org-archive-dir (expand-file-name "archive" org-roam-directory)
"Directory of shareable, technical notes.")
(defconst org-completed-dir (expand-file-name "projects" org-archive-dir)
"Directory of completed project files.")
(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)
(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))
(use-package apheleia
:config
(apheleia-global-mode +1))
(use-package clang-format)
(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"))))
)
https://github.com/jacktasia/dumb-jump
(use-package dumb-jump
:custom
(dump-jump-force-searcher 'rg)
(xref-show-definitions-function #'xref-show-definitions-completing-read)
:config
(add-hook 'xref-backend-functions #'dumb-jump-xref-activate)
)
(use-package cmake-mode
:mode ("CMakeLists.txt'" "\\.cmake\\'"))
(use-package cmake-font-lock
:after (cmake-mode)
:hook (cmake-mode . cmake-font-lock-activate))
(use-package meson-mode
:mode ("meson.build'" "meson_options.txt'"))
(use-package magit
:bind (("C-x g" . magit-status)))
(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))
(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..
(use-package python-black
:demand t
:after python
:hook (python-mode . python-black-on-save-mode))
(use-package yaml-mode
:init (setq yapfify-executable "yapf3")
:mode ("\\.yml\\'" . yaml-mode))
(use-package docker
:bind ("C-c d" . docker))
(use-package dockerfile-mode
:mode ("Dockerfile\\'" "\\.dockerfile$"))
Needs pandoc
(use-package markdown-mode
:delight "μ "
:mode ("\\.markdown\\'" "\\.md\\'")
:custom (markdown-command "/usr/bin/pandoc"))
(use-package rst
:delight "rst"
:mode (("\\.rst$" . rst-mode)
("\\.rest$" . rst-mode)))
(use-package sphinx-mode
:after rst)
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))
(use-package fish-mode
:mode ("\\.fish\\'"))
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
:defer t
: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\\'")
)
(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)
(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\\'"))
(use-package project)
(use-package twilight-bright-theme
:config
(load-theme 'twilight-bright t))
(use-package olivetti
:diminish
:config
(setq olivetti-body-width 0.7)
(setq olivetti-minimum-body-width 80)
(setq olivetti-recall-visual-line-mode-entry-state t))
(use-package which-key
:commands which-key-mode)
(use-package visual-regexp-steroids
:commands vr/replace)
(use-package casual
:after (dired agenda)
:config
(require 'casual-dired)
(require 'casual-agenda)
:bind (
:map dired-mode-map
("C-o" . #'casual-dired-tmenu)
("s" . #'casual-dired-sort-by-tmenu)
:map org-agenda-mode-map
("C-o" . #'casual-agenda-tmenu)
("M-J" . #'org-agenda-clock-goto)))
(use-package multiple-cursors
:bind (("C-C m c" . mc/edit-lines)))
https://github.com/gonewest818/dimmer.el
(use-package dimmer
:custom
(dimmer-adjustment-mode :background)
(dimmer-fraction 0.1)
(dimmer-configure-company-box)
(dimmer-configure-which-key)
(dimmer-configure-magit)
:config
(dimmer-mode))
Note:
dimmer-adjustment-mode
is set to :background
to avoid a Wrong type argument: stringp, reset
with emacs 29, see gonewest818/dimmer.el#69
(use-package dired
:ensure nil
:config
(when (string= system-type "darwin")
(setq dired-use-ls-dired nil)))
(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))
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
: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
:after org-roam
:defer t
: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))
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
: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
:hook
(embark-collect-mode . consult-preview-at-point-mode))
;; 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))))))
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)
)
(use-package indent-tools
:bind (("C-C >" .'indent-tools-hydra/body)))
(use-package editorconfig
:defer 0.3
:config (editorconfig-mode 1))
(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)
)
;; (use-package dap-mode
;; :disabled)
;; (use-package dap-LANGUAGE) to load the dap adapter for your language
(use-package flycheck
:init (global-flycheck-mode))
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)))
(use-package org
:mode (("\\.org$" . org-mode)
("\\.org.draft$" . org-mode))
:config
(setq org-latex-logfiles-extensions
'("acn" "ind" "ilg" "ist" "glo" "tex" "synctex.gz"))
:custom
(require 'org-inlinetask)
;;;;;;; Files
;; setup archive directory in current folder
;;;;;;; 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-list-allow-alphabetical t)
(org-hide-emphasis-markers 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")))
("C-c l" . org-store-link)
("C-c r" . org-refile)
;; Skeletons
(:map org-mode-map
("C-c C-x h" . org-toggle-link-display)
("C-c C-s" . org-schedule))
)
)
(with-eval-after-load 'org
(setq org-use-speed-commands t
org-special-ctrl-a/e t
org-special-ctrl-k t
org-todo-keywords '((sequence "TODO(t)" "NEXT(n)" "INPROGRESS(p)" "|" "DONE(d!)" "CANCELED(c@/!)")
(sequence "WAITING(w@/!)" "SOMEDAY(s)" "|" "CANCELED(c@/!)" "MEETING(m)")
(sequence "IDEA(i)" "|" "CANCELED(c@/!)"))
org-todo-state-tags-triggers '(("CANCELLED" ("CANCELLED" . t))
("WAITING" ("WAITING" . t))
(done ("WAITING"))
("TODO" ("WAITING") ("CANCELLED"))
("NEXT" ("WAITING") ("CANCELLED"))
("DONE" ("WAITING") ("CANCELLED")))
org-use-tag-inheritance t
org-tag-alist '(("Research") ("Collab") ("Teaching") ("Codesign")
("Kokkos") ("C++") ("Rust") ("Arcane")
("docs") ("code") ("review")
(:startgroup . nil)
("#home" . ?h) ("#work" . ?w)
(:endgroup . nil)
(:startgroup . nil)
("#link" . ?i) ("#read" . ?r) ("#project" . ?p)
(:endgroup . nil))
org-log-done 'time
org-log-redeadline 'time
org-log-reschedule 'time
org-log-into-drawer t
org-enforce-todo-dependencies t
org-refile-allow-creating-parent-nodes 'confirm
org-columns-default-format "%80ITEM(Task) %TODO %3PRIORITY %10Effort(Effort){:} %10CLOCKSUM"
org-fontify-whole-heading-line t
org-pretty-entities t
org-ellipsis " ⤵"
org-archive-location (concat org-completed-dir "/%s::datetree/")
org-use-property-inheritance t
org-priority 67
org-priority-faces '((?A . "#ff2600")
(?B . "#ff5900")
(?C . "#ff9200")
(?D . "#747474"))
org-global-properties (quote (("EFFORT_ALL" . "0:15 0:30 0:45 1:00 2:00 3:00 4:00 5:00 6:00 0:00")
("STYLE_ALL" . "habit")))
org-blank-before-new-entry '((heading . t)
(plain-list-item . nil)))
)
(use-package org-super-agenda
:after org
:custom
(org-agenda-include-diary t)
(org-agenda-custom-commands
'(("z" "Zall"
((agenda "" ((org-agenda-span 'day)
(org-super-agenda-groups
'((:name "Today"
:time-grid t
:date today
:todo "TODAY"
:scheduled today
:order 1)))))
(alltodo "" ((org-agenda-overriding-header "")
(org-super-agenda-groups
'((:name "Next to do"
:todo "NEXT"
:order 1)
(:name "Important"
:tag "Important"
:priority "A"
:order 6)
(:name "Due Today"
:deadline today
:order 2)
(:name "Due Soon"
:deadline future
:order 8)
(:name "Overdue"
:deadline past
:order 7)
(:name "Projects"
:tag "Project"
:order 14)
(:name "Waiting"
:todo "WAITING"
:order 20)))))))
("g" "Grouped by project"
((agenda "" ((org-agenda-span 'week)
(org-super-agenda-groups
'((:auto-group t)))))))
("b" "Best"
((agenda "" ((org-agenda-span 'week)
(org-super-agenda-groups
'((:log t) ; Automatically named "Log"
(:name "Schedule"
:time-grid t)
(:name "Today"
:scheduled today)
(:habit t)
(:name "Due today"
:deadline today)
(:name "Overdue"
:deadline past)
(:name "Due soon"
:deadline future)
(:name "Unimportant"
:todo ("SOMEDAY" "MAYBE" "CHECK" "TO-READ" "TO-WATCH")
:order 100)
(:name "Waiting..."
:todo "WAITING"
:order 98)
(:name "Scheduled earlier"
:scheduled past)))))))))
:config
(setq org-agenda-files (cons org-projects-dir '()))
(if (file-exists-p org-inbox-file)
(add-to-list 'org-agenda-files org-inbox-file))
(if (file-exists-p org-icalendar-file)
(add-to-list 'org-agenda-files org-icalendar-file))
(if (file-directory-p org-home-projects-dir)
(add-to-list 'org-agenda-files org-home-projects-dir))
(org-super-agenda-mode))
https://www.reddit.com/r/emacs/comments/8toivy/tip_how_to_manage_your_contacts_with_orgcontacts/
(use-package org-contacts
:after org
:config
(if (file-exists-p org-friends-file)
(add-to-list 'org-contacts-files org-friends-file))
(if (file-exists-p org-people-file)
(add-to-list 'org-contacts-files org-people-file))
)
(use-package calendar
:custom
(diary-file (expand-file-name "diary" user-emacs-directory))
(calendar-mark-holidays-flag t)
(calendar-mark-diary-entries-flag t)
(calendar-date-style 'iso))
French holidays, from https://irfu.cea.fr/Pisp/vianney.lebouteiller/emacs.html
;;French holidays
(setq french-holiday
'((holiday-fixed 1 1 "Jour de l'an")
(holiday-fixed 5 8 "Victoire 45")
(holiday-fixed 7 14 "Fête nationale")
(holiday-fixed 8 15 "Assomption")
(holiday-fixed 11 1 "Toussaint")
(holiday-fixed 11 11 "Armistice 18")
(holiday-easter-etc 1 "Lundi de Pâques")
(holiday-easter-etc 39 "Ascension")
(holiday-easter-etc 50 "Lundi de Pentecôte")
(holiday-fixed 1 6 "Épiphanie")
(holiday-fixed 2 2 "Chandeleur")
(holiday-fixed 2 14 "Saint Valentin")
(holiday-fixed 5 1 "Fête du travail")
(holiday-fixed 5 8 "Commémoration de la capitulation de l'Allemagne en 1945")
(holiday-fixed 6 21 "Fête de la musique")
(holiday-fixed 11 2 "Commémoration des fidèles défunts")
(holiday-fixed 12 25 "Noël")
;; fêtes à date variable
(holiday-easter-etc 0 "Pâques")
(holiday-easter-etc 49 "Pentecôte")
(holiday-easter-etc -47 "Mardi gras")
(holiday-float 6 0 3 "Fête des pères") ;; troisième dimanche de juin
;; Fête des mères
(holiday-sexp
'(if (equal
;; Pentecôte
(holiday-easter-etc 49)
;; Dernier dimanche de mai
(holiday-float 5 0 -1 nil))
;; -> Premier dimanche de juin si coïncidence
(car (car (holiday-float 6 0 1 nil)))
;; -> Dernier dimanche de mai sinon
(car (car (holiday-float 5 0 -1 nil))))
"Fête des mères")))
(setq calendar-holidays (append french-holiday)
calendar-mark-diary-entries-flag nil) ;calendar-mark-holidays-flag t
(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)
(org-babel-do-load-languages 'org-babel-load-languages
'(
(C . t)
(ditaa . t)
(emacs-lisp . t)
(latex . t)
(plantuml . t)
(python . t)
(shell . t)
))
(setq org-ditaa-jar-path "/usr/bin/ditaa")
)
(with-eval-after-load 'ox-latex
(require 'ox-beamer)
(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")
(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))
(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")))
)
Store org-links from magit
:
M-x org-link-store # From a magit buffer
M-x org-insert-link # In the org file
This package is quite slow to load, force defer.
(use-package orgit
:after org magit
:defer t)
(use-package orgit-forge
:after org forge)
(use-package org-modern
:after org
:defer t
:custom
;; Choose some fonts
(set-face-attribute 'default nil :family "JuliaMono")
(set-face-attribute 'variable-pitch nil :family "JuliaMono Aile")
(set-face-attribute 'org-modern-symbol nil :family "JuliaMono")
;; :if window-system
:hook (org-mode . org-modern-mode))
For a nice org-mode outline.
(use-package org-sidebar
:after org
:defer t)
Useful for org-collector
(use-package org-contrib
:after org
:custom
(require 'org-collector))
(use-package mermaid-mode
:defer t)
(use-package ob-mermaid
:after org
:defer t
:config
(setq ob-mermaid-cli-path "~/opt/node_modules/.bin/mmdc"))
(use-package gnuplot
:defer t)
(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)))
)
(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))))
(use-package citar
:if (file-exists-p org-roam-bibfile)
: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 (list org-roam-bibfile))
(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
:if (file-exists-p org-roam-bibfile)
:custom
(citar-org-roam-subdir "resource/references")
:config
(citar-org-roam-mode))
For zettelkasten
notes.
Requires:
sqlite3
graphviz
fordot
From https://systemcrafters.net/build-a-second-brain-in-emacs/capturing-notes-efficiently/
(use-package org-roam
:after org
:if (file-directory-p org-roam-directory)
:init
(setq org-roam-v2-ack t)
:custom
(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 "* ${title}%?\n:PROPERTIES:\n:POSITION:\n:EMAIL:\n:ID: %(shell-command-to-string \"uuidgen\")\n:END:"
:if-new (file+head "people.org"
"#+title: Contacts\n#+date: %U\n#+filetags: :people:\n# -*- mode: Org; org-use-property-inheritance: (\"Company\") -*-\n* To Sort")
:unnarrowed t)
("w" "Work project" plain "* Goals\n\n%?\n\n* Tasks\n\n** TODO Add initial tasks\n\n* Dates\n\n"
:if-new (file+head "projects/%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+category: ${title}\n#+filetags: :Project:\n")
:unnarrowed t)
("i" "inbox" plain "* %?\n:PROPERTIES:\n:CREATED:%U\n:END:\n\n%i\n\nFrom: %a"
:if-new (file+head "Inbox.org" "#+title: Inbox\n")
:immediate-finish t)
("f" "friend" entry "* ${title}%?\n:PROPERTIES:\n:BIRTHDAY: %^{YYYY-MM-DD}t\n:NICKNAME:\n:GROUP:\n:EMAIL:\n:ADDRESS:\n:END:"
:target (file+head "home/friends.org"
"#+title: Friends and Family\n#+date: %U\n#+filetags: :people:#home:\n")
:unnarrowed t)
("h" "home" plain "%?"
:if-new (file+head "home/%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+date: %U\n")
:unnarrowed t)
("P" "Home project" plain "* Goals\n\n%?\n\n* Tasks\n\n** TODO Add initial tasks\n\n* Dates\n\n"
:if-new (file+head "home/projects/${slug}.org" "#+title: ${title}\n#+category: ${title}\n#+filetags: :Project:#home:\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 t" . (lambda () "Populate inbox"
(interactive)
(org-roam-capture nil "i")))
("C-c n T" . org-roam-dailies-capture-today)
("C-c n d" . org-roam-dailies-goto-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 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))))
)
(use-package org-roam-ui
:after org-roam
;; normally we'd recommend hooking orui after org-roam, but since org-roam does not have
;; a hookable mode anymore, you're advised to pick something yourself
;; if you don't care about startup time, use
;; :hook (after-init . org-roam-ui-mode)
:config
(setq org-roam-ui-sync-theme t
org-roam-ui-follow t
org-roam-ui-update-on-save t
org-roam-ui-open-on-start t))
copy and paste with style
(use-package org-rich-yank
:after org
:ensure t
:demand t
:bind (:map org-mode-map
("C-M-y" . org-rich-yank)))
Follow http://www.mkbehr.com/posts/a-research-workflow-with-zotero-and-org-mode/
;; (use-package org-noter)
(use-package zotxt)
- https://github.com/sshaw/copy-as-format
- ediff and ediff-keep
- magit-todos
- https://orgmode.org/worg/org-contrib/org-contacts.html
- org-inlinetask
- org-ql
- https://github.com/nobiot/org-remark
- https://github.com/unhammer/org-rich-yank
- https://orgmode.org/worg/org-contrib/gsoc2012/student-projects/org-sync/tutorial/index.html
- https://github.com/nobiot/org-transclusion
- orgit-forge
- ox-md
- org-config
- https://github.com/jacktasia/dumb-jump
- https://github.com/charignon/github-review
- https://github.com/wandersoncferreira/code-review