Personal emacs configuration.
Note that this document is the code, and can be tangled with `org-babel`.
This configuration heavily rely on `use-package`.
;; setup packages
(require 'package)
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
("melpa-stable" . "https://stable.melpa.org/packages/")
("gnu" . "http://elpa.gnu.org/packages/")
("org" . "http://orgmode.org/elpa/")))
(package-initialize)
(unless package-archive-contents
(package-refresh-contents))
(unless (package-installed-p 'use-package)
(package-install 'use-package))
Set always ensure packages
(setq use-package-always-ensure t)
Place to put local packages.
(let* ((path (expand-file-name "lisp" user-emacs-directory))
(local-pkgs (mapcar 'file-name-directory (directory-files-recursively path ".*\\.el"))))
(if (file-accessible-directory-p path)
(mapc (apply-partially 'add-to-list 'load-path) local-pkgs)
(make-directory path :parents)))
;; Add prompt indicator to `completing-read-multiple'.
If you whant to tangle all configs in different subdirectories you can enable this code snippets and specify the file under each org header.
Load all configs from subdirectories Subdir:
config/
: contains all configurations files
;; load all configs
(let ((config-directory (concat user-emacs-directory "config/")))
(cl-loop for file in (reverse (directory-files-recursively config-directory "\\.el$"))
do (condition-case ex
(load (file-name-sans-extension file)))))
(defun dmd/reload-init-file () ; Reload init file
"Reload init file"
(interactive)
(load-file "~/.emacs.d/init.el"))
; (defun dmd/roam-wiki-grep-keywords (&optional arguments)
; "Get all files with specified keywords"
; (interactive "sWiki Keywords:")
; (rgrep (concat "^#\+KEYWORDS:[\s- a-zA-Z0-9]*\\("
; (mapconcat 'identity (split-string arguments) "\\)\\|\\(") "\\)")
; "*.org" "~/documents/org/org-roam/wiki/" nil))
(defun dmd/roam-wiki-fuzzy-search (&optional initial)
"Fuzzy search in wiki"
(interactive "P")
(consult--grep "Wiki Serach" #'consult--grep-make-builder "~/documents/org/org-roam/wiki/" initial))
(defun dmd/generate-org-note-name ()
(setq my-org-note-name (read-string "Name: "))
(setq my-org-note-time (format-time-string "%Y-%m-%d"))
(expand-file-name (format "%s-%s.org" my-org-note-time my-org-note-name) "~/documents/org/docs/"))
;;; Stefan Monnier <foo at acm.org>. It is the opposite of fill-paragraph
(defun unfill-paragraph (&optional region)
"Takes a multi-line paragraph and makes it into a single line of text."
(interactive (progn (barf-if-buffer-read-only) '(t)))
(let ((fill-column (point-max))
;; This would override `fill-column' if it's an integer.
(emacs-lisp-docstring-fill-column t))
(fill-paragraph nil region)))
(use-package minibuffer
:ensure nil
:hook ((minibuffer-setup . cursor-intangible-mode))
:init (savehist-mode 1)
:custom ((enable-recursive-minibuffers t)
(history-length 25)
(read-extended-command-predicate
#'command-completion-default-include-p)
(minibuffer-prompt-properties
'(read-only t cursor-intangible t face minibuffer-prompt)))
:config
;; Display ~[CRM<separator>]~, e.g., [CRM,] if the separator is a comma.
(advice-add #'completing-read-multiple :filter-args
#'(lambda (args)
(cons (format "[CRM%s] %s"
(replace-regexp-in-string
"\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" ""
crm-separator)
(car args))
(cdr args)))))
(use-package files
:ensure nil
:custom ((backup-directory-alist '(("." . "~/.emacs.d/backup")))
(create-lockfiles nil "Do not use lock-files.")
(backup-by-copying t "Don't delink hardlinks")
(version-control t "Use version numbers on backups")
(delete-old-versions t "Automatically delete excess backups")
(kept-new-versions 20 "How many of the newest versions to keep")
(kept-old-versions 5 "How many of the old versions to keep")
(require-final-newline t "Ends file with a newline.")
(recentf-mode 1 "Rember recently edited files")
(save-place-mode 1 "Remember last place visited")
(enable-local-variables :safe)
(enable-local-eval :safe)
(custom-file (locate-user-emacs-file "custom-vars.el") "custom-vars file location"))
:init (load custom-file 'noerror 'nomessage))
Line numbers etc
(use-package display-line-numbers
:ensure t
:hook ((term-mode
org-mode
eww-mode
shell-mode
eshell-mode
minimap
vterm-mode
doc-view-mode
telega-chat-mode
telega-root-mode
erc-mode
elfeed-show-mode
elfeed-search-mode) . (lambda () (display-line-numbers-mode 0)))
:init (global-display-line-numbers-mode t)
:custom ((column-number-mode t)
(display-line-numbers 'relative)
(truncate-lines t)))
(use-package whitespace
:bind (("C-M-w" . whitespace-mode)))
This is the use package for all the core configurations of emacs
(use-package dired
:ensure nil
:bind (:map dired-mode-map
("RET" . dired-find-alternate-file)
("^" . (lambda () (interactive) (find-alternate-file "..")))))
(use-package emacs
:diminish (visual-line-mode abbrev-mode)
:bind (("C-<f12>" . dmd/reload-init-file) ; Reload .emacs file
("M-Q" . unfill-paragraph)
("C-x C-b" . ibuffer))
:custom ((inhibit-startup-message t "disable startup message")
(use-dialog-box nil "disable popup")
(scroll-bar-mode nil "disable visible scrollbar")
(tool-bar-mode nil "disable toolbar")
(tooltip-mode nil "disable tooltips")
(menu-bar-mode nil "disable menu bar")
(set-fringe-mode 10 "give some breathing room")
(global-auto-revert-mode 1) ; auto revert buffer
(global-auto-revert-non-file-buffers t "auto-revert-buffers")
(doc-view-resolution 300))
:config
<<defun-dmd-reload-init-file>>
<<defun-unfill-paragraph>>
(add-to-list 'global-auto-revert-ignore-modes 'Buffer-menu-mode) ;; do not revert buffer menu
;; (set-face-font 'default "-UKWN-Iosevka-normal-normal-normal-*-*-*-*-*-d-0-iso10646-1")
;; (set-face-attribute 'default nil nil :height 120) ; font settings
(defalias 'yes-or-no-p 'y-or-n-p) ; (yes/no)->(y/n
;; "Expert" commands
(put 'upcase-region 'disabled nil) ; C-x C-u
(put 'downcase-region 'disabled nil) ; C-x C-l
;; Make dired open in the same window when using RET or ^
(put 'dired-find-alternate-file 'disabled nil) ; disables warning
)
(use-package comment-dwim-2
:ensure t
:bind (("M-;" . comment-dwim-2))
)
(use-package visual-fill-column
:ensure t
:init
(global-visual-fill-column-mode t)
(global-visual-line-mode t)
:custom ((visual-fill-column-width 100)
(visual-fill-column-center-text nil))
)
(use-package ssh
:ensure t
:hook
(ssh-mode . (lambda ()
(setq ssh-directory-tracking-mode t)
(shell-dirtrack-mode t)
(setq dirtrackp nil))))
(use-package pinentry
:custom (epa-pinentry-mode 'loopback)
:config (require 'epa-file) ; file cryptography
:init (if (not (memq epa-file-handler file-name-handler-alist))
(epa-file-enable)
(pinentry-start)))
(use-package exec-path-from-shell
:ensure t
:config
(dolist (var '("SSH_AUTH_SOCK" "SSH_AGENT_PID" "GPG_AGENT_INFO" "LANG" "LC_CTYPE" "JAVA_HOME" "JDK_HOME"))
(add-to-list 'exec-path-from-shell-variables var))
(exec-path-from-shell-initialize))
(use-package all-the-icons
:ensure t)
Be sure to run once this command to load all the fonts
(all-the-icons-install-fonts)
(use-package magit
:ensure t
:demand t
:commands (magit-status magit-get-current-branch)
:custom
(magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)
:config
(setq magit-repository-directories '(("~/repos/" . 2))))
(use-package projectile
:ensure t
:init
(projectile-global-mode)
(setq projectile-enable-caching t)
:diminish projectile-mode
:config (projectile-mode)
:bind-keymap
("C-c p" . projectile-command-map)
:init
(when (file-directory-p "~/repos/")
(setq projectile-project-search-path '(("~/repos/"))))
(setq projectile-switch-project-action #'projectile-dired))
This package provides better helper functions and formatting
(use-package helpful
:ensure t
:bind (("C-h f" . helpful-callable)
("C-h v" . helpful-variable)
("C-h k" . helpful-key)
("C-h x" . helpful-command)
("C-c C-d" . helpful-at-point)
("C-h F" . helpful-function)))
(use-package savehist
:ensure t
:init (savehist-mode))
(use-package company
:diminish
:ensure t
:defer t
:custom
;; Search other buffers with the same modes for completion instead of
;; searching all other buffers.
(company-dabbrev-other-buffers t)
(company-dabbrev-code-other-buffers t)
;; M-<num> to select an option according to its number.
(company-show-numbers t)
;; Only 2 letters required for completion to activate.
(company-minimum-prefix-length 3)
;; Do not downcase completions by default.
(company-dabbrev-downcase nil)
;; Even if I write something with the wrong case,
;; provide the correct casing.
(company-dabbrev-ignore-case t)
;; company completion wait
(company-idle-delay 0.2)
;; No company-mode in shell & eshell
(company-global-modes '(not eshell-mode shell-mode))
;; Use company with text and programming modes.
:hook ((text-mode . company-mode)
(prog-mode . company-mode))
:init (global-company-mode))
(use-package which-key
:diminish
:ensure t
:init (which-key-mode))
Trim EOL whitespace
(use-package ws-butler
:diminish
:ensure t
:init (ws-butler-global-mode))
tree-sitter
is an Emacs binding for Tree-sitter, an incremental
parsing system. https://emacs-tree-sitter.github.io/
(use-package tree-sitter
:diminish
:ensure t
:hook ((python-mode
c-mode
c++-mode) . tree-sitter-hl-mode)
:init (global-tree-sitter-mode))
(use-package tree-sitter-langs
:ensure t)
;; :config
;; (tree-sitter-require 'rust)
(use-package ts-fold
:after ts-fold-indicators
:bind (("<backtab>" . ts-fold-toggle))
:load-path "~/.emacs.d/lisp/ts-fold"
:init (global-ts-fold-mode))
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode))
(use-package diminish)
(use-package yasnippet-snippets)
(use-package yasnippet
:diminish (yas-minor-mode)
:hook (prog-mode . yas-minor-mode-on))
(use-package emojify
:config
(when (member "Segoe UI Emoji" (font-family-list))
(set-fontset-font
t 'symbol (font-spec :family "Segoe UI Emoji") nil 'prepend))
(setq emojify-display-style 'unicode)
(setq emojify-emoji-styles '(unicode)))
;(bind-key* (kbd "C-c e") #'emojify-insert-emoji)) ; override binding in any mode
(setq dmd/youtube-dl-quality-list
'("bestvideo[height<=720]+bestaudio/best[height<=720]"
"bestvideo[height<=480]+bestaudio/best[height<=480]"
"bestvideo[height<=1080]+bestaudio/best[height<=1080]"))
(setq dmd/default-emms-player-mpv-parameters
'("--quiet" "--really-quiet" "--no-audio-display"))
(defun dmd/set-emms-mpd-youtube-quality (quality)
(interactive "P")
(unless quality
(setq quality (completing-read "Quality: " dmd/youtube-dl-quality-list nil t)))
(setq emms-player-mpv-parameters
`(,@dmd/default-emms-player-mpv-parameters ,(format "--ytdl-format=%s" quality))))
(dmd/set-emms-mpd-youtube-quality (car dmd/youtube-dl-quality-list))
(defun dmd/emms-cleanup-urls ()
(interactive)
(let ((keys-to-delete '()))
(maphash (lambda (key value)
(when (eq (cdr (assoc 'type value)) 'url)
(add-to-list 'keys-to-delete key)))
emms-cache-db)
(dolist (key keys-to-delete)
(remhash key emms-cache-db)))
(setq emms-cache-dirty t))
(use-package emms
:ensure t
:hook
(emms-playlist-cleared . emms-player-mpd-clear)
:init
(require 'emms-setup)
(emms-all)
(add-to-list 'emms-info-functions 'emms-info-mpd)
(add-to-list 'emms-player-list 'emms-player-mpd t)
(add-to-list 'emms-player-list 'emms-player-mpv t)
(emms-player-mpd-connect)
(define-emms-source elfeed (entry)
(let ((track (emms-track
'url (dmd/get-youtube-url (elfeed-entry-link entry)))))
(emms-track-set track 'info-title (elfeed-entry-title entry))
(emms-playlist-insert-track track)))
(emms-player-set emms-player-mpd
'regex (emms-player-simple-regexp
"m3u" "ogg" "flac" "mp3" "wav" "mod" "au" "aiff"))
(emms-player-set emms-player-mpv
'regex
(rx (or (: "https://"
(* nonl) "youtube.com" (* nonl))
(+ (? (or "https://" "http://"))
(* nonl)
(regexp (eval
(emms-player-simple-regexp
"mp4" "mov" "wmv" "webm" "flv" "avi" "mkv")))))))
:custom
(emms-source-file-default-directory (expand-file-name "~/media/music/"))
(emms-player-mpd-server-name "localhost")
(emms-player-mpd-server-port "6600")
(emms-player-mpd-music-directory "~/media/music")
)
(use-package elfeed
:commands (elfeed)
:custom
(elfeed-db-directory "~/.emacs.d/elfeed")
(elfeed-enclosure-default-dir (expand-file-name "~/downloads"))
:config
(advice-add #'elfeed-insert-html
:around
(lambda (fun &rest r)
(let ((shr-use-fonts nil))
(apply fun r))))
)
(use-package elfeed-org
:after (elfeed)
:init (elfeed-org)
:custom
(rmh-elfeed-org-files '("~/documents/org/elfeed.org"))
(rmh-elfeed-org-auto-ignore-invalid-feeds t)
)
(defun dmd/get-youtube-url (link)
(let ((watch-id (cadr
(assoc "watch?v"
(url-parse-query-string
(substring
(url-filename
(url-generic-parse-url link))
1))))))
(concat "https://www.youtube.com/watch?v=" watch-id)))
(defun dmd/elfeed-add-emms-youtube ()
(interactive)
(emms-add-elfeed elfeed-show-entry)
(elfeed-tag elfeed-show-entry 'watched)
(elfeed-show-refresh))
To export notes to different formats
(use-package pandoc
:ensure t)
(use-package zotero
:ensure t
:defer t
:commands (zotero-browser zotero-sync))
(defun org-renumber-environment (orig-func &rest args)
(let ((results '())
(counter -1)
(numberp))
(setq results (cl-loop for (begin . env) in
(org-element-map (org-element-parse-buffer) 'latex-environment
(lambda (env)
(cons
(org-element-property :begin env)
(org-element-property :value env))))
collect
(cond
((and (string-match "\\\\begin{equation}" env)
(not (string-match "\\\\tag{" env)))
(cl-incf counter)
(cons begin counter))
((string-match "\\\\begin{align}" env)
(prog2
(cl-incf counter)
(cons begin counter)
(with-temp-buffer
(insert env)
(goto-char (point-min))
;; \\ is used for a new line. Each one leads to a number
(cl-incf counter (count-matches "\\\\$"))
;; unless there are nonumbers.
(goto-char (point-min))
(cl-decf counter (count-matches "\\nonumber")))))
(t
(cons begin nil)))))
(when (setq numberp (cdr (assoc (point) results)))
(setf (car args)
(concat
(format "\\setcounter{equation}{%s}\n" numberp)
(car args)))))
(apply orig-func args))
(advice-add 'org-create-formula-image :around #'org-renumber-environment)
To remove the advice just run:
(advice-remove 'org-create-formula-image #'org-renumber-environment)
(use-package ob
:after org
:load-path "~/.emacs.d/lisp/ob-diagrams/"
:ensure nil
:custom ((ob-diagrams-cli "/usr/bin/diagrams")
(ob-diagrams-sm-cli "/usr/bin/smcat")
(ob-diagrams-erd-cli "/usr/bin/erd"))
:config
(require 'ob-diagrams)
(require 'ob-js)
(require 'ob-rust)
;(require 'ob-latex-as-png)
(org-babel-do-load-languages
'org-babel-load-languages
'((js . t)
(latex . t)
(emacs-lisp . t)
(python . t)
(C . t)
(shell . t)
(java . t)
(js . t)
(rust . t)
(mermaid . t)
(diagrams .t)
(plantuml . t)
(octave . t))))
Code Blocks snippets
(use-package org-tempo
:after org
:ensure nil
:config
(require 'org-tempo)
(add-to-list 'org-structure-template-alist '("sh" . "src shell"))
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
(add-to-list 'org-structure-template-alist '("py" . "src python"))
(add-to-list 'org-structure-template-alist '("src" . "src"))
(add-to-list 'org-structure-template-alist '("js" . "src js"))
(add-to-list 'org-structure-template-alist '("rs" . "src rust"))
(add-to-list 'org-structure-template-alist '("cs" . "src C"))
(add-to-list 'org-structure-template-alist '("latex" . "src latex"))
(add-to-list 'org-structure-template-alist '("cpp" . "src C++"))
(setq org-confirm-babel-evaluate nil)
(push '("conf-unix" . conf-unix) org-src-lang-modes))
(use-package citar
:diminish
:ensure t
:after org
:init
(setq org-cite-insert-processor 'citar
org-cite-follow-processor 'citar
org-cite-activate-processor 'citar)
(setq citar-bibliography '("~/documents/org/bibliography/bibliography.bib"))
(setq citar-notes-paths '("~/documents/org/bibliography")))
(use-package citar-embark
:diminish
:ensure t
:after citar embark
:init
(setq citar-at-point-function 'embark-act)
:config
(citar-embark-mode))
(use-package citeproc
:after org
:ensure t)
(use-package bibtex
:ensure t
:mode (("\\.bib\\'" . bibtex-mode)))
(use-package ox-publish
:after org
:ensure nil
:init (require 'ox-publish)
:custom (org-publish-project-alist
'(("org-wiki"
:base-directory "~/documents/org/org-roam/wiki"
:base-extension "org"
:publishing-directory "/srv/http/emacs-wiki"
:recursive t
:publishing-function org-html-publish-to-html
:headline-levels 4 ; Just the default for this project.
:auto-preamble t
)
("org-static"
:base-directory "~/documents/org/org-roam/wiki"
:base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf"
:publishing-directory "/srv/http/emacs-wiki"
:recursive t
:publishing-function org-publish-attachment
)
("wiki"
:components ("org-wiki" "org-static")))))
(org-capture-templates
`(("t" "Tasks / Notes")
("tt" "Task" entry (file+olp "~/documents/org/todo.org" "Inbox")
"* TODO %?\n %U\n %a\n %i" :empty-lines 1)
("n" "Notes")
("nn" "Quick note" entry (file+olp "~/documents/org/todo.org" "Notes")
"* %^{Note}%U - /%^{Topic}/\n" :kill-buffer t)
("nd" "Document" plain (file dmd/generate-org-note-name)
"%(format \"#+TITLE: %s\n#+STAMP: %s\n\" my-org-note-name my-org-note-time)")
("j" "Journal Entries")
("jj" "Journal" entry
(file+olp+datetree "~/documents/org/journal.org")
"\n* %<%I:%M %p> - Journal :journal:\n\n%?\n\n"
;; ,(dw/read-file-as-string "~/Notes/Templates/Daily.org")
:clock-in :clock-resume
:empty-lines 1)
("jm" "Meeting" entry
(file+olp+datetree "~/documents/org/journal.org")
"* %<%I:%M %p> - %a :meetings:\n\n%?\n\n"
:clock-in :clock-resume
:empty-lines 1)
("je" "Event" entry
(file+olp+datetree "~/documents/org/journal.org")
"* %<%I:%M %p> - %a :events:\n\n%?\n\n"
:clock-in :clock-resume
:empty-lines 1)))
(org-agenda-custom-commands
'(("r" "Resonance Cal" tags "Type={.}"
((org-agenda-files
(directory-files-recursively
"~/documents/org/refs/rez" "\\.org$"))
(org-overriding-columns-format
"%35Item %Type %Start %Fin %Rating")
(org-agenda-cmp-user-defined
(cmp-date-property-stamp "Start"))
(org-agenda-sorting-strategy
'(user-defined-down))
(org-agenda-overriding-header "C-u r to re-run Type={.}")
(org-agenda-mode-hook
(lambda ()
(visual-line-mode -1)
(setq truncate-lines 1)
(setq display-line-numbers-offset -1)
(display-line-numbers-mode 1)))
(org-agenda-view-columns-initially t)))
("u" "Super view"
((agenda ""
((org-agenda-span 1)
(org-super-agenda-groups
'((:name "Today"
:tag ("bday" "ann" "hols" "cal" "today")
:time-grid t
:todo ("WIP")
:deadline today
:scheduled today)
(:name "Overdue"
:deadline past)
(:name "Reschedule"
:scheduled past)
(:name "Perso"
:tag "perso")
(:name "Due Soon"
:deadline future
:scheduled future))
)))
(tags (concat "w" (format-time-string "%V"))
((org-agenda-overriding-header (concat "--\nToDos Week " (format-time-string "%V")))
(org-super-agenda-groups
'((:discard (:deadline t))
(:discard (:scheduled t))
(:discard (:todo ("DONE")))
(:name "Ticklers"
:tag "someday")
(:name "Perso"
:and (:tag "perso" :not (:tag "someday")))
(:name "UH"
:and (:tag "uh" :not (:tag "someday")))
;; (:name "Neo"
;; :and (:tag "neo" :not (:tag "someday")))
(:name "Ping"
:tag "crm")
))))
))
))
(defun cmp-date-property-stamp (prop)
"Compare two `org-mode' agenda entries, `A' and `B', by some date property.
If a is before b, return -1. If a is after b, return 1. If they
are equal return nil."
(lexical-let ((prop prop))
#'(lambda (a b)
(let* ((a-pos (get-text-property 0 'org-marker a))
(b-pos (get-text-property 0 'org-marker b))
(a-date (or (org-entry-get a-pos prop)
(format "<%s>" (org-read-date t nil "now"))))
(b-date (or (org-entry-get b-pos prop)
(format "<%s>" (org-read-date t nil "now"))))
(cmp (compare-strings a-date nil nil b-date nil nil))
)
(if (eq cmp t) nil (signum cmp))
))))
(use-package org
:diminish (org-indent-mode)
:bind
(("C-c y l" . embark-org-copy-link-target)
("C-c l" . org-store-link)
("C-c s" . org-roam-db-sync)
("C-c a" . org-agenda)
("C-c C-k" . magit-kill-this-buffer)
("C-c c" . org-capture)
("C-c x \\" . org-toggle-pretty-entities)
("C-c x l" . org-latex-preview)
("C-c x v" . org-toggle-inline-images)
("C-c '" . org-edit-src-code)
;; ("C-c x e" . counsel-org-entity)
("C-c x i" . org-id-get-create))
:hook
(org-mode . (lambda ()
(visual-line-mode t)
(visual-fill-column-mode t)
(org-indent-mode)
(variable-pitch-mode 0)
(auto-fill-mode 0)
(org-toggle-pretty-entities)
(org-toggle-inline-images)
(org-latex-preview)
))
:custom
((org-ellipsis "▾")
(org-support-shift-select t)
(org-hide-emphasis-markers t)
(org-hide-leading-stars t)
(org-return-follows-link t)
(org-special-ctrl-a/e t)
(org-cite-global-bibliography '("~/documents/org/bibliography/bibliography.bib"))
(org-cite-csl-styles-dir '("~/documents/org/templates/styles"))
(org-log-done 'time)
(org-log-into-drawer t)
(org-src-preserve-indentation t) ;; This will preserve indentation of blocks
(org-agenda-start-with-log-mode t)
(org-directory "~/documents/org/")
(org-agenda-files
'("~/documents/org/notes.org"
;; "~/documents/org/projects.org"
"~/documents/org/journal.org"
"~/documents/org/inbox.org"
"~/documents/org/org-gtd-tasks.org"))
(org-latex-inputenc-alist '(("utf8" . "utf8x")))
(org-image-actual-width nil)
(org-refile-targets '(("todo.org" :maxlevel . 1)))
(org-reverse-note-order t)
(org-default-note-file "~/documents/org/notes.org")
(org-habit-graph-column 60)
(org-todo-keywords
'((sequence
"TODO(t)" ; doing later
"NEXT(n)" ; doing now or soon
"|"
"DONE(d)" ; done
"CNCL(c@)"; canceled
)
(sequence
"WAIT(w)" ; waiting for some external change (event)
"HOLD(h)" ; waiting for some internal change (of mind)
"IDEA(i)" ; maybe someday
"|"
"NOTE(o@/!)" ; end state, just keep track of it
"STOP(s@/!)" ; stopped waiting, decided not to work on it
)))
;;'((sequence "TODO(t)" "NEXT" "DONE(d!)" "|" "CANCELED(c@)")))
;;'((sequence "TODO(t)" "NEXT" "|" "DONE(d!)" "CANCELED(c@)" "WAIT(w@/!)")))
(org-tag-alist
'((:startgroup); Put mutually exclusive tags here
(:endgroup)
("@errand" . ?E)
("@home" . ?H)
("@work" . ?W)
("note" . ?n)
("idea" . ?i)
("project" . ?p)
("noexport" . ?N)))
<<org-capture-templates>>
<<org-agenda-custom-commands>>
)
:config
<<org-note-gen-name>>
(require 'oc-csl)
(require 'oc-biblatex)
(require 'oc-natbib)
(require 'ol-bibtex)
(require 'org-habit)
(add-to-list 'org-modules 'org-habit)
(font-lock-add-keywords 'org-mode
'(("^ *\\([-]\\) "
0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "•")))
("^ *\\([+]\\) "
0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "‣")))))
(setq org-format-latex-options '(plist-put org-format-latex-options :scale 1.5 :width 1 :foreground "white" ))
;;(advice-add 'org-refile :after 'org-save-all-org-buffers)
)
(use-package ob-rust
:ensure t)
(use-package ob-mermaid
:ensure t
:config
(setq ob-mermaid-cli-path "/usr/bin/mmdc"))
(use-package plantuml-mode
:ensure t
:config
(setq org-plantuml-jar-path (expand-file-name "/opt/plantuml/plantuml.jar"))
(add-to-list 'org-src-lang-modes '("plantuml" . plantuml)))
(use-package org-super-agenda
:ensure t
:after org
:defer t
:init
(org-super-agenda-mode)
:config
(let ((org-super-agenda-groups
'((:auto-category t))))
;;(org-agenda-list) ;uncomment this to view agenda at startup
))
(use-package general
:ensure t)
(use-package origami
:ensure t
:hook (org-agenda-mode . origami-mode)
:general
(:keymaps 'org-super-agenda-header-map
"<tab>" #'origami-toggle-node))
(use-package org-bullets
:ensure t
:after org
:hook (org-mode . org-bullets-mode)
:custom
(org-bullets-bullet-list '("◉" "•" "◦" "⋅")))
(org-roam-capture-templates
'(("d" "default" plain "%?"
:target (file+head "${slug}.org"
"#+TITLE: ${title}\n")
:unnarrowed t)
("r" "bibliography reference" plain "%?"
:target
(file+head "references/${citekey}.org" "#+TITLE: ${title}\n")
:unnarrowed t)
("s" "secret" entry "* %<%R%z>:%?"
:target (file+head "%<%Y-%m-%d>.org.gpg"
":PROPERTIES:\n:ROAM_EXCLUDE: t\n:END:\n,#+TITLE: %<%Y-%m-%d>"))
("w" "wiki" plain "* ${title}\n%?\n* Bibliography:\n#+PRINT_BIBLIOGRAPHY:\n* Variables :noexport:\n\nbibliography:~/documents/org/bibliography/bibliography.bib"
:if-new (file+head "wiki/${slug}.org"
"#+SETUPFILE: ~/documents/org/templates/heading.org\n#+TITLE: ${title}\n#+DESCRIPTION:\n#+KEYWORDS:")
:unnarrowed t)
("R" "Rez" plain "%?"
:target (file+head "~/documents/org/refs/rez/${slug}.org"
"#+TITLE: ${title}\n#+CREATED: %u\n#+MODIFIED:\n* ${title}\n:PROPERTIES:\n:START:\n:TYPE:\n:FIN:\n:KILLED:\n:RATING:\n:DIGESTED:\n:CREATOR:\n:URL:\n:END:\n** Actions\n** Key Ideas\n** Review\n* Quotes\n* Notes")
:unnarrowed t)
("e" "Exp" plain "%?"
:target (file+head "~/documents/org/areas/exps/${slug}.org"
":PROPERTIES:\n:START:\n:TYPE: Exp\n:FIN:\n:ASSESS: %<%Y-%m-%d %d %H:%m:%S %z>\n:QUESTION:\n:STATUS:\n:OUTCOME:\n:END:\n#+TITLE: ${title}\n#+CREATED: %u\n#+MODIFIED:\n* ${title}\n* Actions\n* Hypothesis\n* Treatment\n* Notes\n* Outcome\n* Contraindications\n")
:unnarrowed t)
("b" "Blog" plain "%?"
:target (file+head "~/documents/org/areas/blog/%<%Y-%m-%d>-${slug}.md"
"---\nid: %<%Y-%m-%d>-${slug}\nlayout: post\ntitle: \n'${title}'\npermalink: '/${slug}'\ndate: \n%<%Y-%m-%d>-Thh:mm:ss+02:00\nlocation: Ao Nang\ntags: []\ndescription: 'Clever description of contents.'\ndraft: true\n---
"):unnarrowed t)
))
(org-roam-dailies-capture-templates
'(("s" "secret" entry "* %<%R%z>:%?"
:target (file+head "%<%Y-%m-%d>.org.gpg"
":PROPERTIES:\n:ROAM_EXCLUDE: t\n:END:\n,#+TITLE: %<%Y-%m-%d>"))
("d" "default" entry "* %<%R%z>:%?"
:target (file+head "%<%Y-%m-%d>.org"
"#+TITLE: %<%Y-%m-%d %a>\n#+CREATED: %<%Y-%m-%d %a>\n#+MODIFIED:\n* Daily\nIntent\n** Todos\n* Perso\n** [[Morning Pages]]\n[[file:~/documents/org/journal/journal-%<%Y>.org.gpg::*\n%<%Y-%m\n%d %a>][%<%Y-%m-%d %a>]]\n** Meta\n- Where: ???\n- Weather: ???\n-\nMusic: ???\n- Sleep: 7h?\n- Weight: ???\n- Energy: L/M/H\n-\nEffective: L/M/H\n- Mood:\n*** [[Exercise]]\n*** [[TIL]]\n*** [[Highlights ]]\n*** [[Lowlights]]\n*** Eats\n- Breakie: ???\n- Lunch: ???\n- Dinner: ???\n*** [[Gratitude/Savoured]]\n1.\n2.\n3."))
("W" "Weekly" plain "%?"
:target (file+head "~/documents/org/logs/%<%Y-%W>.org"
"#+TITLE: %<%Y-%W>\n#+CREATED: %u\n#+MODIFIED:\n*\nIntents\nWeek Goal: -\n**\nWorkout\n|-----+-----+-----+-----+-----\n-----+-----|\n| Mon | Tue | Wed | Thu | Fri |\nSat | Sun |\n|-----+-----+-----+-----+-----+-----+-----|\n| | | | | | | |\n|-----+-----+-----+-----+-----+-----+-----|\n* Commits\n** Priorities\n1.\n2.\n3.\n**\nRemainders -\nContacts - Meets\n-\n-\n-\n** Foods\n|-------+--------|\n| *Lunch* |\n*Dinner* |\n|-------+--------|\n| m - | m\n- |\n| t - | t - |\n| w - | w\n- |\n| f - | f - |\n| s - | s\n- |\n| s - | s - |\n|-------+--------|\n*** Groceries\n**\nRecords\n+ Watched:\n+ Played:\n+ Read:\n** Create\n** Learn\n**\nReview, Plan, Prune\n* Weekly Review\n** Score: XX/XX ~ XX%\n** How'd it go?\n** Pluses\n1.\n2.\n3.\n** Minuses\n1.\n2.\n3.\n** Next\n1.\n2.\n3."):unnarrowed t)
))
(use-package org-roam
:after org
:ensure t
:hook (org-roam . org-roam-db-autosync-mode)
:bind (("C-c n t" . org-roam-dailies-capture-today)
("C-c n l" . org-roam-buffer-toggle)
;; ("C-c n f" . org-roam-node-find) ; see consult-org-roam-file-find
("C-c n i" . org-roam-node-insert)
("C-c w s" . dmd/roam-wiki-fuzzy-search)
;; ("C-c w k" . dmd/roam-wiki-grep-keywords)
:map org-mode-map
("C-M-i" . completion-at-point)
("C-c n a" . org-roam-alias-add))
:bind-keymap ("C-c n d" . org-roam-dailies-map)
:custom (
<<org-roam-capture-templates>>
<<org-roam-dailies-capture-templates>>
(org-roam-directory "~/documents/org/org-roam")
(org-roam-dailies-directory "journal/")
(find-file-visit-truename t))
:config
<<org-wiki-grep-keywords>>
(require 'org-roam-dailies)
(require 'org-roam-export)
(require 'org-roam-graph))
(use-package org-roam-ui
:ensure t)
(use-package org-ref
:config
(setq org-latex-pdf-process (list "latexmk -shell-escape -bibtex -f -pdf %f")))
(use-package org-ql
:after org)
(setq org-agenda-files
(mapcar 'file-truename
(file-expand-wildcards "~/documents/org/*.org")))
;; Save the corresponding buffers
(defun gtd-save-org-buffers ()
"Save `org-agenda-files' buffers without user confirmation.
See also `org-save-all-org-buffers'"
(interactive)
(message "Saving org-agenda-files buffers...")
(save-some-buffers t (lambda ()
(when (member (buffer-file-name) org-agenda-files)
t)))
(message "Saving org-agenda-files buffers... done"))
;; Add it after refile
(advice-add 'org-refile :after
(lambda (&rest _)
(gtd-save-org-buffers)))
(use-package org-edna
:diminish)
(setq org-gtd-update-ack "3.0.0")
(use-package org-gtd
:after org
:demand t
:ensure t
:custom
(org-gtd-directory "~/documents/org")
(org-edna-use-inheritance t)
(org-gtd-organize-hooks '(org-gtd-set-area-of-focus org-set-tags-command))
:config
(org-edna-mode)
:bind
(("C-c d c" . org-gtd-capture)
("C-c d e" . org-gtd-engage)
("C-c d p" . org-gtd-process-inbox)
:map org-gtd-clarify-map
("C-c c" . org-gtd-organize)))
Org integration for pandoc
(use-package ox-pandoc
:ensure t)
(use-package org-download
:init (require 'org-download)
:hook (dired-mode . org-download-enable))
(use-package consult-org-roam
:diminish
: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)
(consult-orgroam-buffer)
: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 f" . 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))
(use-package org-mind-map
:init
(require 'ox-org)
:ensure t
;; Uncomment the below if 'ensure-system-packages` is installed
;;:ensure-system-package (gvgen . graphviz)
:config
(setq org-mind-map-engine "dot") ; Default. Directed Graph
(setq org-mind-map-include-text t)
;; (setq org-mind-map-engine "neato") ; Undirected Spring Graph
;; (setq org-mind-map-engine "twopi") ; Radial Layout
;; (setq org-mind-map-engine "fdp") ; Undirected Spring Force-Directed
;; (setq org-mind-map-engine "sfdp") ; Multiscale version of fdp for the layout of large graphs
;; (setq org-mind-map-engine "twopi") ; Radial layouts
;; (setq org-mind-map-engine "circo") ; Circular Layout
)
(use-package vertico
:ensure t
:init
;; (setq vertico-count 5) ;; Number of candidates
(vertico-mode))
(use-package orderless
:ensure t
:init (icomplete-mode)
:custom
;; Configure a custom style dispatcher (see the Consult wiki)
(completion-styles '(orderless basic))
(completion-category-overrides '((file (styles basic partial-completion))))
(setq completion-ignore-case 't)
;; Configure a custom style dispatcher (see the Consult wiki)
(setq orderless-style-dispatchers '(+orderless-consult-dispatch orderless-affix-dispatch)
orderless-component-separator #'orderless-escapable-split-on-space)
(setq completion-styles '(orderless basic)
completion-category-defaults nil
completion-category-overrides '((file (styles partial-completion)))))
(use-package marginalia
:ensure t
:init (marginalia-mode)
:bind (:map minibuffer-local-map
("M-A" . marginalia-cycle)))
(use-package consult
:diminish
:ensure t
:bind
(;; C-c bindings in `mode-specific-map'
("C-c M-x" . consult-mode-command)
("C-c h" . consult-history)
("C-c k" . consult-kmacro)
("C-c m" . consult-man)
("C-c i" . consult-info)
([remap Info-search] . consult-info)
;; C-x bindings in `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
;; M-g bindings in `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 in `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 k" . consult-keep-lines)
("M-s u" . consult-focus-lines)
;; Isearch integration
("M-s e" . consult-isearch-history)
:map consult-narrow-map
("?" . consult-narrow-help) ; make narrowing help available in the minibuffer.
: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
:hook (completion-list-mode . consult-preview-at-point-mode)
:custom ((consult-narrow-key "C-+" "configure the narrowing key. "C-+""))
:init
;; Register formatting. Improves 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)
;; 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)
:config
;; 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 '(:debounce 0.4 any))
;; By default `consult-project-function' uses `project-root' from project.el.
;; Optionally configure a different project root function.
;;;; 1. project.el (the default)
;;(setq consult-project-function #'consult--default-project--function)
;;;; 4. projectile.el (projectile-project-root)
(autoload 'projectile-project-root "projectile")
(setq consult-project-function (lambda (_) (projectile-project-root))))
(use-package embark
:diminish (eldoc-mode)
: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
;; Show the Embark target at point via Eldoc. You may adjust the Eldoc
;; strategy, if you want to see the documentation from multiple providers.
(add-hook 'eldoc-documentation-functions #'embark-eldoc-first-target)
:config
;; replace the key help with a completing-read interface
(setq prefix-help-command #'embark-prefix-help-command)
(setq eldoc-documentation-strategy #'eldoc-documentation-compose-eagerly)
;; 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)))))
(use-package embark-consult
:ensure t
:hook (embark-collect-mode . consult-preview-at-point-mode))
(use-package eglot
:diminish
:ensure t
:hook ((prog-mode . eglot-ensure))
)
(use-package csharp-mode
:ensure t)
(use-package rustic
:ensure t)
(use-package haskell-mode
:ensure t)
(use-package php-mode
:ensure t
:mode ((("\\.php$"
"\\.inc$") . php-mode)))
(use-package phps-mode
:after flycheck
:ensure t
:mode ("\\.php\\'" "\\.phtml\\'")
:config
(phps-mode-flycheck-setup)
(setq phps-mode-async-process t)
(setq phps-mode-async-process-using-async-el t))
(use-package json-mode
:mode ((("\\.json$") . jsoyn-mode)))
(use-package dotenv-mode
:mode ("\\.env\\..*\\'" . dotenv-mode))
(use-package shader-mode
:ensure t
:mode ("\\.vert\\'" "\\.frag\\'"))
(use-package vterm
:commands vterm
:custom ((term-prompt-regexp "^[^#$%>\n]*[#$%>] *")
(vterm-max-scrollback 1024)))
(use-package eterm-256color
:hook (term-mode . eterm-256color-mode))
(use-package term
:hook (term-mode . (lambda () (setq mode-line-format nil)))
:custom ((explicit-shell-file-name "bash")
(term-prompt-regexp "^[^#$%>\n]*[#$%>] *") ;; default prompt
))
(use-package shell
:hook (shell-mode . (lambda () (setq-local comint-process-echoes t)))
:custom ((explicit-shell-file-name "/usr/bin/zsh")
(shell-file-name "zsh")
(explicit-zsh-args '("--login" "--interactive"))))
(use-package term-toggle
:load-path "~/.emacs.d/lisp/emacs-term-toggle"
:bind (("M-<tab>" . term-toggle-ansi)
("M-<iso-lefttab>" . term-toggle-eshell)))
(use-package doom-themes
:ensure t
;; :init (load-theme 'doom-one t)
:config
;; Global settings (defaults)
(setq doom-themes-enable-bold t ; if nil, bold is universally disabled
doom-themes-enable-italic t) ; if nil, italics is universally disabled
;; Enable flashing mode-line on errors
;(doom-themes-visual-bell-config)
;; Enable custom neotree theme (all-the-icons must be installed!)
;; (doom-themes-neotree-config)
;; or for treemacs users
;; (setq doom-themes-treemacs-theme "doom-atom") ; use "doom-colors" for less minimal icon theme
;; (doom-themes-treemacs-config)
;;Corrects (and improves) org-mode's native fontification.
(doom-themes-org-config))
(use-package doom-modeline
:init (doom-modeline-mode))
If for some reason you want to use evil, just tangle this code block
https://evil.readthedocs.io/en/latest/
(use-package evil
:init (evil-mode 1)
:custom ((evil-undo-system 'undo-redo)
(evil-want-fine-undo t)
;;(evil-auto-indent nil)
(evil-want-keybinding nil) ; use evil-collection
)
:config (fset 'evil-visual-update-x-selection 'ignore))
(use-package evil-org
:after org
:hook (org-mode . (lambda () evil-org-mode))
:config
(require 'evil-org-agenda)
(evil-org-agenda-set-keys))
(use-package evil-collection
:after evil
:ensure t
:custom (evil-collection-setup-minibuffer t)
:init (evil-collection-init))
(use-package telega
:custom
((telega-notifications-mode t)
(telega-root-show-avatars t)
(telega-chat-show-avatars t)
(telega-use-images t))
:config
(bind-key* (kbd "C-c t") telega-prefix-map))
(use-package erc
:custom (erc-server "irc.libera.chat"
erc-nick "username"
erc-user-full-name "Full Name"
erc-track-shorten-start 8
erc-kill-buffer-on-part t
erc-auto-query 'bury))