#+title: Emacs Configuration #+property: header-args:elisp :mkdirp yes :results silent :padline no #+property: header-args:elisp+ :tangle "~/.config/emacs/init.el" * General ** Early Init Ensure dark background on startup. #+begin_src elisp :tangle "~/.config/emacs/early-init.el" (setq default-frame-alist '((background-color . "#000000") (ns-appearance . dark) (ns-transparent-titlebar . t))) #+end_src ** MELPA https://melpa.org Add and enable the MELPA repository for more available packages. #+begin_src elisp (require 'package) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) (package-initialize) #+end_src ** Settings Quality of life settings. #+begin_src elisp (setq-default help-window-select t delete-by-moving-to-trash t sentence-end-double-space nil confirm-kill-emacs 'yes-or-no-p scroll-conservatively 101 cursor-in-non-selected-windows nil) #+end_src ** Startup Screen Disable default startup screen. #+begin_src elisp (setq-default inhibit-startup-screen t) #+end_src ** Interface GUI bars. #+begin_src elisp (tool-bar-mode -1) (menu-bar-mode -1) (scroll-bar-mode -1) #+end_src Right-click context menu. #+begin_src elisp (context-menu-mode -1) #+end_src Vertical minibuffer. #+begin_src elisp (fido-vertical-mode) #+end_src ** Behaviour :PROPERTIES: :ID: 8818a835-08ef-47f8-bcbf-83dd210725a0 :END: Automatically move cursor point on window split. #+begin_src elisp (advice-add 'split-window-below :after (lambda (&rest r) (other-window 1))) (advice-add 'split-window-right :after (lambda (&rest r) (other-window 1))) #+end_src Add advice to enable ~query-replace~ to search the whole buffer or region if selected, as the original default behaviour would only begin to replace from the cursor point position. #+begin_src elisp (defun +advice-goto-top-no-region (func &rest args) "Move point to top of buffer when no region applying ARGS to FUNC." (save-excursion (when (not (use-region-p)) (goto-char (point-min))) (apply func args))) (advice-add 'query-replace :around #'+advice-goto-top-no-region) (advice-add 'query-replace-regexp :around #'+advice-goto-top-no-region) #+end_src Eshell display settings. #+begin_src elisp (cl-pushnew '("\\*e?shell\\*" (display-buffer-in-side-window) (side . bottom) (slot . -1) (window-height . 0.5)) display-buffer-alist) #+end_src Calendar display settings. #+begin_src elisp (cl-pushnew '("Calendar" (display-buffer-in-side-window) (side . bottom) (slot . 1) (window-height . 0.25)) display-buffer-alist) #+end_src #+begin_src elisp (cl-pushnew '("\\*Org Agenda\\*" display-buffer-in-side-window (side . right) (window-width . 0.5)) display-buffer-alist) #+end_src ** Editor Tab behaviour settings. #+begin_src elisp (setq-default tab-width 4 tab-always-indent 'complete backward-delete-char-untabify-method 'hungry indent-tabs-mode nil) #+end_src Replace selected region when yanking text. #+begin_src elisp (delete-selection-mode) #+end_src Auto update buffer on any file changes. #+begin_src elisp (global-auto-revert-mode) #+end_src Automatically remove trailing whitespace on file-save. #+begin_src elisp (add-hook 'before-save-hook #'whitespace-cleanup) #+end_src Increase default column width. #+begin_src elisp (setq-default fill-column 80) #+end_src Set whitespace column length and symbols. #+begin_src elisp (with-eval-after-load 'whitespace (setq-default whitespace-line-column fill-column whitespace-display-mappings '((space-mark ?\s [?·] [?.]) (newline-mark ?\n [?↴ ?\n]) (tab-mark ?\t [?➔ ?\t] [?\\ ?\t])))) #+end_src Enable pairing brackets and add additional bracket pairs. #+begin_src elisp (electric-pair-mode) (with-eval-after-load "elec-pair" (cl-pushnew '(?\{ . ?\}) electric-pair-pairs)) #+end_src Fix elisp prop indentation. #+begin_src elisp (setq-default lisp-indent-function 'common-lisp-indent-function) #+end_src ** Theme Enable theme. #+begin_src elisp (load-theme 'modus-vivendi) (set-face-attribute 'fringe nil :background 'unspecified) #+end_src Fix fringe background colour. #+begin_src elisp (add-hook 'modus-themes-after-load-theme-hook (lambda () "Hide fringe background on theme toggle." (set-face-attribute 'fringe nil :background 'unspecified))) #+end_src ** Font Font settings. #+begin_src elisp (set-face-attribute 'default nil :family "Hack" :height 100) #+end_src ** Tab-bar Open scratch window on new tab. #+begin_src elisp (with-eval-after-load 'tab-bar (setq-default tab-bar-new-tab-choice #'get-scratch-buffer-create)) #+end_src ** Modeline Enable column number in modeline. #+begin_src elisp (column-number-mode) #+end_src ** Completion Enable completions previews. #+begin_src elisp (add-hook 'prog-mode-hook #'completion-preview-mode) #+end_src Set completion keybindings. #+begin_src elisp (with-eval-after-load 'completion-preview (let ((map completion-preview-active-mode-map)) (keymap-set map "M-n" #'completion-preview-next-candidate) (keymap-set map "M-p" #'completion-preview-prev-candidate))) #+end_src ** Which-key Enable which-key that displays a pop-up window of posisble keybindings sequences. #+begin_src elisp (which-key-mode) #+end_src ** Winner-mode Enable winner-mode. #+begin_src elisp (winner-mode) #+end_src Set winner mode keybindings. #+begin_src elisp (with-eval-after-load 'winner (keymap-set winner-mode-map "C-<" #'winner-undo) (keymap-set winner-mode-map "C->" #'winner-redo)) #+end_src ** History *** Minibuffer History Enable saving minibuffer history. #+begin_src elisp :noweb yes (savehist-mode) (with-eval-after-load 'savehist <>) #+end_src Automatically save history on exit. #+begin_example elisp :tangle no :noweb-ref savehist-settings (add-hook 'kill-emacs-hook #'savehist-save) #+end_example Ensure savehist file is loaded. #+begin_src elisp :tangle no :noweb-ref savehist-settings (unless savehist-loaded (load-file savehist-file)) #+end_src Add addtional variable lists to save. #+begin_src elisp :tangle no :noweb-ref savehist-settings (dolist (var '(command-history register-alist mark-ring kill-ring search-ring regexp-search-ring)) (cl-pushnew var savehist-additional-variables)) #+end_src *** Recent Files Enable saving history of recent opened files. #+begin_src elisp :noweb yes (recentf-mode) #+end_src Recentf settings. #+begin_src elisp (setq-default recentf-max-saved-items 50 recentf-auto-cleanup 'never) #+end_src Save recent files and cleanup file list on exit. #+begin_src elisp (add-hook 'kill-emacs-hook #'recentf-cleanup) (add-hook 'kill-emacs-hook #'recentf-save-list) #+end_src Disallow duplicates in history. #+begin_src elisp (setq-default history-delete-duplicates t) #+end_src *** Cursor Point Position Enable saving cursor point positions. #+begin_src elisp :noweb yes (save-place-mode) (with-eval-after-load 'saveplace <>) #+end_src Save place settings. #+begin_src elisp :tangle no :noweb-ref saveplace-settings (setq-default save-place-abbreviate-file-names t save-place-limit 800) #+end_src *** Bookmarks Don't display bookmark icon in fringe. #+begin_src elisp (with-eval-after-load 'bookmark (setq-default bookmark-fringe-mark nil)) #+end_src Disable auto-bookmarking org-mode files. #+begin_src elisp (with-eval-after-load 'org (setq-default org-bookmark-names-plist nil)) #+end_src ** Spell Checking Set dictionary. #+begin_src elisp (setq-default ispell-dictionary "british") #+end_src Enable spell checking. #+begin_src elisp (add-hook 'text-mode-hook #'flyspell-mode) (add-hook 'prog-mode-hook #'flyspell-prog-mode) #+end_src Add add word to dictionary function. #+begin_src elisp (defun +flyspell-add-word-to-dictionary () "Save word at point to personal dictionary." (interactive) (when-let ((loc (point)) (word (flyspell-get-word))) (when (yes-or-no-p (format "Add '%s' to dictionary?" (car word))) (flyspell-do-correct 'save nil (car word) loc (cadr word) (caddr word) loc) (save-buffer) (revert-buffer-quick) (message "Added '%s' to personal dictionary" (car word))))) #+end_src Set custom spell checking keybindings. #+begin_src elisp (setq-default flyspell-mode-map (make-sparse-keymap)) (with-eval-after-load 'flyspell (keymap-set flyspell-mode-map "C-x c c" #'flyspell-auto-correct-word) (keymap-set flyspell-mode-map "C-x c u" #'flyspell-auto-correct-previous-word) (keymap-set flyspell-mode-map "C-x c l" #'flyspell-check-previous-highlighted-word) (keymap-set flyspell-mode-map "C-x c n" #'flyspell-goto-next-error) (keymap-set flyspell-mode-map "C-x c b" #'flyspell-buffer) (keymap-set flyspell-mode-map "C-x c d" #'ispell-change-dictionary) (keymap-set flyspell-mode-map "C-x c i" #'+flyspell-add-word-to-dictionary)) #+end_src ** Dired #+begin_src elisp :noweb yes (with-eval-after-load 'dired <>) #+end_src Dired settings. #+begin_src elisp :tangle no :noweb-ref dired-settings (setq-default dired-guess-shell-alist-user '(("\\.pdf$" "zathura")) dired-listing-switched "-AFhlv --group-directories-first") #+end_src Hide dot-files when using ~dired-omit-mode~. #+begin_src elisp :tangle no :noweb-ref dired-settings (setq-default dired-omit-files "\\`[.].*\\'") #+end_src Auto enable omit mode on Dired startup. #+begin_src elisp :tangle no :noweb-ref dired-settings (add-hook 'dired-mode-hook (lambda () (dired-omit-mode) (toggle-truncate-lines 1))) #+end_src Add shred function. #+begin_src elisp :tangle no :noweb-ref dired-settings (if (executable-find "shred") (defun +dired-shred-file () "Shred marked files or a file at point in Dired." (interactive) (mapc (lambda (file) "Run the shred shell command on FILE." (if (file-regular-p file) (when (yes-or-no-p (format "Shred %s?" file)) (shell-command (format "shred -u \"%s\"" file))) (error "Aborting shred procedure; \"%s\" is not a file!" file))) (dired-get-marked-files))) (error "Shred command not found!")) #+end_src Add additional dired keybindings. #+begin_src elisp :tangle no :noweb-ref dired-settings (keymap-set dired-mode-map "b" #'dired-up-directory) (keymap-set dired-mode-map "z" #'+dired-shred-file) #+end_src Allow changing file permissions when in a writable dired buffer. #+begin_src elisp :tangle no :noweb-ref dired-settings (with-eval-after-load 'wdired (setq-default wdired-allow-to-change-permissions t)) #+end_src ** Search & Replace Case-sensitive search by default and show match count in minibuffer. #+begin_src elisp (with-eval-after-load 'isearch (setq-default case-fold-search nil isearch-lazy-count t)) #+end_src ** Org #+begin_src elisp :noweb yes (with-eval-after-load 'org <> <> <> <>) #+end_src #+begin_src elisp :noweb yes (with-eval-after-load 'org-keys <>) #+end_src #+begin_src elisp :noweb yes (with-eval-after-load 'org-agenda <>) #+end_src *** Org Settings :PROPERTIES: :header-args:elisp: :tangle no :noweb-ref org-settings :results none :END: Org directory location. #+begin_src elisp (require 'xdg) (setq-default org-directory (expand-file-name "org" (xdg-user-dir "DOCUMENTS"))) #+end_src Hide emphasis markers and set ellipse symbol. #+begin_src elisp (setq-default org-ellipsis "⤵" org-hide-emphasis-markers t) #+end_src Enable checkbox dependency checking. #+begin_src elisp (setq-default org-enforce-todo-dependencies t org-enforce-todo-checkbox-dependencies t org-checkbox-hierarchical-statistics nil) #+end_src Set org column format. #+begin_src elisp (setq-default org-columns-default-format "%70ITEM %TODO %10CLOCKSUM %16DEADLINE") #+end_src Enable notes for various actions. #+begin_src elisp (setq-default org-log-done 'time org-log-reschedule 'note org-log-redeadline 'note org-log-into-drawer t org-log-note-clock-out t) #+end_src Prioritise attribute tags for image width. #+begin_src elisp (setq-default org-image-actual-width nil) #+end_src Add advice to prompt for confirmation before commenting or cutting a subtree. #+begin_src elisp (advice-add 'org-cut-subtree :before-while (lambda (&rest _) "Prompts for confirmation before cutting subtree." (let ((heading (org-entry-get nil "ITEM"))) (y-or-n-p (format "Cut \"%s\" subtree?" heading))))) (advice-add 'org-toggle-comment :before-while (lambda (&rest _) "Prompt for confirmation before commenting a subtree." (let ((heading (org-entry-get nil "ITEM"))) (y-or-n-p (format "Toggle comment on \"%s\" subtree?" heading))))) #+end_src Use custom IDs for links. #+begin_src elisp (with-eval-after-load 'org-id (setq-default org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id)) #+end_src Style org headings. #+begin_src elisp (set-face-attribute 'org-level-1 nil :height 1.3) (set-face-attribute 'org-level-2 nil :height 1.2) (set-face-attribute 'org-level-3 nil :height 1.1) #+end_src *** Org To-dos & Tags :PROPERTIES: :header-args:elisp: :tangle no :noweb-ref org-todo-tag-settings :END: Set to-do key words and selection type. #+begin_src elisp (setq-default org-use-fast-todo-selection 'expert org-todo-keywords '((sequence "IDLE(i)" "TODO(t)" "LIVE(l)" "WAIT(w@/!)" "|" "AXED(a@)" "DONE(d)"))) #+end_src Style keywords. #+begin_src elisp (set-face-attribute 'org-todo nil :weight 'bold :slant 'italic) (setq-default org-todo-keyword-faces '(("IDLE" . "grey") ("TODO" . "RoyalBlue1") ("LIVE" . "goldenrod2") ("WAIT" . "linen") ("DONE" . "SeaGreen3") ("AXED" . "OrangeRed2"))) #+end_src Add no-export tag. #+begin_src elisp (with-eval-after-load 'ox (cl-pushnew "NOEXPORT" org-export-exclude-tags)) #+end_src Set tag list. #+begin_src elisp (setq-default org-tag-alist '(;; Built-in Actions ("ARCHIVE") ("NOEXPORT") ("ignore") ;; General definitions ("blog") ("crypt") ("emacs") ("mail") ("note") ("web") ;; Code (:startgroup) ("code") (:grouptags) ("bash") ("c") ("cpp") ("css") ("elisp") ("html") (:endgroup) ;; Text (:startgroup) ("text") (:grouptags) ("article") ("book") ("man") ("pdf") ("txt") ("doc") (:endgroup) ;; Audio (:startgroup) ("audio") (:grouptags) ("audbook") ("music") ("podcast") (:endgroup) ;; Video (:startgroup) ("video") (:grouptags) ("movie") ("yt") (:endgroup))) #+end_src *** Org Speed Command Keys :PROPERTIES: :header-args:elisp: :tangle no :noweb-ref org-speed-command-settings :END: Enable org speed commands. #+begin_src elisp (setq-default org-use-speed-commands t) #+end_src Alternative comment key =;= added to be consistent with ~org-toggle-comment~ (=C-c ;=). #+begin_src elisp (dolist (key '(("P" . org-set-property) ("$" . org-archive-subtree-default-with-confirmation) ("q" . org-set-tags-command) ("]" . org-shiftright) ("[" . org-shiftleft) (";" . org-toggle-comment) ("z" . org-add-note) ("y" . org-copy-subtree))) (cl-pushnew key org-speed-commands)) #+end_src Add ='= shortcut key to edit source blocks, which is consistent with ~org-edit-special~ (=C-c '=). #+begin_src elisp (cl-pushnew '("'" . org-edit-src-code) org-babel-key-bindings) #+end_src *** Org Babel :PROPERTIES: :header-args:elisp: :tangle no :noweb-ref org-babel-settings :END: Add new structure template shortcuts when inserting a block. #+begin_src elisp (cl-pushnew '("se" . "src elisp") org-structure-template-alist) #+end_src Add advice to automatically open an edit buffer when inserting a structure template. #+begin_src elisp (advice-add 'org-insert-structure-template :after (lambda (&rest r) "Edit an Org block after insertion." (call-interactively 'org-edit-special))) #+end_src Enable supported org babel languages. #+begin_src elisp (org-babel-do-load-languages 'org-babel-load-languages '((emacs-lisp . t) (shell . t) (C . t) (plantuml . t))) #+end_src Redisplay images when executing an org block. #+begin_src elisp (with-eval-after-load 'ob-core (add-hook 'org-babel-after-execute-hook (lambda () "Redisplay Org inline images." (when org-inline-image-overlays (org-redisplay-inline-images))))) #+end_src *** Org Export :PROPERTIES: :header-args:elisp: :tangle no :noweb-ref org-export-settings :results none :END: Use SVG LaTeX previews. #+begin_src elisp (setq-default org-preview-latex-default-process 'dvisvgm) (setq-default org-format-latex-options '(:foreground default :background "Transparent" :scale 0.5 :html-foreground "Black" :html-background "Transparent" :html-scale 1 :matchers ("begin" "$1" "$" "$$" "\\(" "\\["))) (with-eval-after-load 'ox-html (setq-default org-html-with-latex 'dvisvgm)) #+end_src Set [[https://ctan.org/pkg/hyperref][hyperref]] LaTeX settings. #+begin_src elisp (with-eval-after-load 'ox-latex (setq-default org-latex-hyperref-template "\\hypersetup{ pdfauthor={%a}, pdftitle={%t}, pdfkeywords={%k}, pdfsubject={%d}, pdfcreator={%c}, pdflang={%L}, linktoc=all, colorlinks=true, urlcolor=blue, citecolor=blue, linkcolor=blue } ") ) #+end_src Add =doc= LaTeX class. #+begin_src elisp (with-eval-after-load 'ox-latex (cl-pushnew '("doc" " % Document Type \\documentclass[11pt]{article} % Geometry \\usepackage[a4paper,margin=1in]{geometry} % Paraskip \\usepackage{parskip} \\setlength{\\parindent}{0em} \\setlength{\\parskip}{1em} % Line height \\renewcommand{\\baselinestretch}{1.2} % Fancyhdr (header/footer) \\usepackage{fancyhdr} \\pagestyle{fancy} \\fancyhead[LH,LH]{\\scriptsize\\leftmark} \\fancyhead[RH,RH]{\\scriptsize\\rightmark} \\fancyfoot[CF]{\\thepage} \\fancyfootoffset{\\pagewidth} \\renewcommand{\\headrulewidth}{0.5pt} % top line thickness \\renewcommand{\\footrulewidth}{0.5pt} % bottom line thickness \\renewcommand{\\headruleskip}{10pt} % top line padding \\renewcommand{\\footruleskip}{10pt} % bottom line padding " ("\\section{%s}" . "\\section*{%s}") ("\\subsection{%s}" . "\\subsection*{%s}") ("\\subsubsection{%s}" . "\\subsubsection*{%s}") ("\\paragraph{%s}" . "\\paragraph*{%s}") ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) org-latex-classes) ) #+end_src *** Org Habit #+begin_src elisp (with-eval-after-load "org-habit" (setq-default org-habit-today-glyph ?T org-habit-completed-glyph ?+)) #+end_src *** Org Agenda :PROPERTIES: :header-args:elisp: :tangle no :noweb-ref org-agenda-settings :results none :END: Match encrypted org files for agenda. #+begin_src elisp (setq-default org-agenda-file-regexp "^[^.#].+\\.org\\(?:\\.gpg\\)?$") #+end_src Set agenda directory location and add files to agenda. #+begin_src elisp (let ((dir (expand-file-name "agenda/" org-directory))) (if (file-exists-p dir) (setq-default org-agenda-files (directory-files-recursively dir org-agenda-file-regexp)) (warn "Org-agenda directory '%s' not found" dir))) #+end_src Set agenda header formats. #+begin_src elisp (setq-default org-agenda-prefix-format '((agenda . "%?2i%-5c%?t%s\s") (todo . "%?2i%-5c") (tags . "⬜ %?2i%-5c") (search . "%?2i%-5c")) org-agenda-deadline-leaders '("!" "In %2d d.:" "[!%2dx]") org-agenda-scheduled-leaders '("+" "[+%2dx]") org-agenda-format-date "%F %A") #+end_src Set bulk actions and marker. #+begin_src elisp (setq-default org-agenda-bulk-custom-functions '((?k org-agenda-kill)) org-agenda-bulk-mark-char "☑️") #+end_src Set priority faces. #+begin_src elisp (setq-default org-priority-faces '((?A . (:foreground "red" :slant italic)) (?B . (:foreground "cadetblue" :slant italic)) (?C . (:foreground "goldenrod" :slant italic)))) #+end_src Set face for to-dos in agenda view. #+begin_src elisp (set-face-attribute 'org-agenda-dimmed-todo-face nil :weight 'bold :inherit nil :background 'unspecified) #+end_src Set sorting strategy. #+begin_src elisp (setq-default org-agenda-sorting-strategy '((agenda deadline-up time-up habit-down priority-up category-up) (todo todo-state-down deadline-up scheduled-up priority-down category-keep) (tags todo-state-down priority-down category-keep) (search category-keep))) #+end_src Set time grid. #+begin_src elisp (setq-default org-agenda-time-grid '((daily today require-timed) (0000 0100 0200 0300 0400 0500 0600 0700 0800 0900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300) "⏰" "——————————————————————————————")) #+end_src **** Org Agenda Commands Command to view to personal planner. #+begin_src elisp (cl-pushnew '("=" "Day Planner: Personal" ((agenda "" ((org-agenda-overriding-header "PERSONAL AGENDA:") (org-agenda-span 'day) (org-agenda-include-deadlines nil) (org-agenda-show-all-dates nil))) (agenda "" ((org-agenda-overriding-header "\nPERSONAL DEADLINES:") (org-agenda-span 'day) (org-agenda-format-date "%F %A") (org-agenda-entry-types '(:deadline)) (org-agenda-skip-deadline-if-done t))) (tags-todo "-goal/TODO|LIVE" ((org-agenda-overriding-header "\nPERSONAL TASKS")))) ((org-habit-show-habits nil) (org-agenda-include-diary nil) (org-agenda-use-time-grid nil) (org-agenda-block-separator nil) (org-agenda-category-filter-preset '("-Work")))) org-agenda-custom-commands) #+end_src Command to view work planner. #+begin_src elisp (cl-pushnew '("-" "Day Planner: Work" ((agenda "" ((org-agenda-overriding-header "WORK AGENDA:") (org-agenda-start-day "monday") (org-agenda-span 5) (org-agenda-include-deadlines nil) (org-agenda-show-all-dates nil) (org-habit-show-habits nil))) (agenda "" ((org-agenda-overriding-header "\nWORK DEADLINES:") (org-agenda-span 'day) (org-agenda-time-grid nil) (org-agenda-format-date "%F %A") (org-agenda-entry-types '(:deadline)) (org-agenda-skip-deadline-if-done t))) (alltodo "" ((org-agenda-overriding-header "\nWORK TASKS:")))) ((org-agenda-block-separator nil) (org-agenda-category-filter-preset '("+Work")))) org-agenda-custom-commands) #+end_src Command to view all personal tasks. #+begin_src elisp (cl-pushnew '("l" "All Personal Tasks" tags-todo "-goal-milestone" ((org-agenda-overriding-header "PERSONAL TASKS:") (org-agenda-category-filter-preset '("-Work")))) org-agenda-custom-commands) #+end_src Command to view all work tasks. #+begin_src elisp (cl-pushnew '("k" "All Work Related Tasks" todo "" ((org-agenda-overriding-header "WORK TASKS:") (org-agenda-category-filter-preset '("+Work")))) org-agenda-custom-commands) #+end_src Command to organise idle tasks. #+begin_src elisp (cl-pushnew '("o" "Organise Tasks" todo "IDLE" ((org-agenda-overriding-header "TASKS TO ORGANISE:"))) org-agenda-custom-commands) #+end_src Command to view tasks that require archiving. #+begin_src elisp (cl-pushnew '("$" "Tasks to Archive" tags "CLOSED<=\"<-3m>\"+CATEGORY={Task}/DONE|AXED" ((org-agenda-show-inherited-tags nil) (org-agenda-todo-list-sublevels nil) (org-agenda-search-view-max-outline-level 1) (org-agenda-overriding-header "PERSONAL TASKS TO ARCHIVE"))) org-agenda-custom-commands) #+end_src Command to view habits. #+begin_src elisp (cl-pushnew '("h" "Habits" tags-todo "STYLE=\"habit\"" ((org-agenda-overriding-header "HABITS:"))) org-agenda-custom-commands) #+end_src Command to view projects. #+begin_src elisp (cl-pushnew '("p" "Projects" ((tags-todo "+proj|+goal|+milestone" ((org-agenda-overriding-header "PROJECTS:"))) (tags-todo "-proj-goal-milestone" ((org-agenda-overriding-header "\nPROJECT TASKS:")))) ((org-agenda-prefix-format "⬜ %?2i%-5c%?t%?s%(+org-agenda-breadcrumb)") (org-agenda-compact-blocks t) ;; (org-agenda-category-filter-preset +project-categories) (org-agenda-sorting-strategy '(category-up deadline-up time-up priority-down effort-up)))) org-agenda-custom-commands) #+end_src Command to view clock report. #+begin_src elisp (cl-pushnew '("c" "Clock Review" agenda "" ((org-agenda-span 'day) (org-agenda-prefix-format " %-5c | %t | %s | ") (org-agenda-archives-mode t) (org-agenda-use-time-grid nil) (org-agenda-start-with-log-mode 'clockcheck) (org-agenda-start-with-clockreport-mode t) (org-agenda-clock-consistency-checks '(:min-duration 0 :max-gap 5 :inherit 'warning :default-face ((:background 'unspecified) (:family "monospace")))))) org-agenda-custom-commands) #+end_src Command to review the week. #+begin_src elisp (cl-pushnew '("r" "Review: Week" agenda "" ((org-agenda-overriding-header (format "WEEK %s REVIEW" (format-time-string "%U" (current-time)))) (org-habit-show-habits nil) (org-agenda-span 'week) (org-agenda-include-diary nil) (org-agenda-show-all-dates t) (org-agenda-clockreport-mode t))) org-agenda-custom-commands) #+end_src Command to review the month. #+begin_src elisp (cl-pushnew '("R" "Review: Month" agenda "" ((org-agenda-overriding-header (format "%s REVIEW" (upcase (format-time-string "%B" (current-time))))) (org-habit-show-habits nil) (org-agenda-span 'month) (org-agenda-include-diary nil) (org-agenda-show-all-dates t) (org-agenda-start-with-clockreport-mode t))) org-agenda-custom-commands) #+end_src Command to review the weekend. #+begin_src elisp (cl-pushnew '("w" "Review: Weekend" agenda "" ((org-agenda-overriding-header "WEEKEND REVIEW") (org-agenda-span 2) (org-agenda-start-day "saturday"))) org-agenda-custom-commands) #+end_src *** Org Clock-table Define a custom clocktable formatter function for ~+org-clocktable-format~. #+begin_src elisp (with-eval-after-load 'org-clock (defun +org-clocktable-format (&rest args) "A cleaner Org clocktable format." (apply #'org-clocktable-write-default args) (save-excursion ;; Rename headline (search-forward "Headline") (backward-kill-sexp) (insert "Tasks") (org-table-align) ;; Capitalise row (beginning-of-line) (setq this-command-keys-shift-translated t) (call-interactively 'end-of-line) (call-interactively 'capitalize-dwim) (deactivate-mark) ;; Remove cookies (org-mark-element) (while (re-search-forward "\\[[0-9]+\\(?:/[0-9]\\|%\\)\\] " nil t) (replace-match "")) (org-table-align) (exchange-point-and-mark t) ;; Move total time row to the end of the table (kill-whole-line) (condition-case nil (while t (org-table-move-row-down)) (error nil)) (org-table-insert-hline t)))) #+end_src Set default clocktable parameters. #+begin_src elisp :tangle no :noweb-ref org-agenda-settings (setq-default org-agenda-clockreport-parameter-plist '(:link t :fileskip0 t :hidefiles t :formatter +org-clocktable-format)) #+end_src *** Org Capture #+begin_src elisp :noweb yes (with-eval-after-load 'org-capture <> <>) #+end_src **** Capture Templates Task template. #+begin_src elisp :tangle no :noweb-ref capture-task-template "* IDLE %^{Task} %^G" #+end_src Event template. #+begin_src elisp :tangle no :noweb-ref capture-event-template "* %^{Event} SCHEDULED: %^T" #+end_src Note template. #+begin_src elisp :tangle no :noweb-ref capture-note-template "* %^{Note} %^G" #+end_src Meeting template. #+begin_src elisp :tangle no :noweb-ref capture-meeting-template "* TODO Meeting with: *%\\1* at *%\\2* :meeting: SCHEDULED: %^T" #+end_src Goal setting template. #+begin_src elisp :tangle no :noweb-ref capture-goal-template "* [/] %^{Goal Title} :goal: DEADLINE: %^{When do you expect this goal to be completed?}t :SMART: :SPECIFIC: %^{What SPECIFICALLY is the goal?} :MEASURABLE: %^{What RESULTS will determine the completion of the goal?} :ACTIONABLE: %^{What ACTIONS will you take to accomplish this goal?} :RELEVANT: %^{Why is it IMPORTANT to accomplish this goal?} :TIMELY: Due by =DEADLINE= :END:" #+end_src Daily review template. #+begin_src elisp :tangle no :noweb-ref capture-weekly-review-template "%? ,,#+BEGIN: clocktable :scope agenda-with-archives :block %t ,,#+END:" #+end_src Weekly review template. #+begin_src elisp :tangle no :noweb-ref capture-weekly-review-template "%? ,,#+BEGIN: clocktable :scope agenda-with-archives :block %<%Y>-W%<%V> ,,#+END:" #+end_src Monthly review template. #+begin_src elisp :tangle no :noweb-ref capture-monthly-review-template "%? ,,#+BEGIN: clocktable :scope agenda-with-archives :block %<%Y-%m> ,,#+END:" #+end_src **** Capture Template Quick Keys :PROPERTIES: :header-args:elisp: :tangle no :noweb-ref org-capture-quick-keys :noweb yes :noweb-prefix no :END: Capture a quick task. #+begin_src elisp :noweb yes (cl-pushnew '("c" "Quick Task (personal)" entry (file "agenda/tasks.org") <> :prepend t :empty-lines-after 1 :immediate-finish t) org-capture-templates) #+end_src Capture event. #+begin_src elisp (cl-pushnew '("v" "Event" entry (file "agenda/events.org") <> :prepend t :empty-lines-after 1 :immediate-finish t) org-capture-templates) #+end_src Captured to last clocked file. #+begin_src elisp (cl-pushnew '("l" "Clocked File" item (clock) nil) org-capture-templates) #+end_src **** Capture Template Personal Keys :PROPERTIES: :header-args:elisp: :tangle no :noweb-ref org-capture-personal-keys :noweb yes :noweb-prefix no :END: Personal capture templates. #+begin_src elisp (cl-pushnew '("p" "personal...") org-capture-templates) (cl-pushnew '("pt" "Task" entry (file "agenda/tasks.org") <> :prepend t :empty-lines-after 1 :immediate-finish t) org-capture-templates) (cl-pushnew '("pT" "Detailed Task" entry (file "agenda/tasks.org") <> :prepend t :empty-lines-after 1) org-capture-templates) (cl-pushnew '("pp" "Plan Today" checkitem (file+olp+datetree "agenda/planner.org") nil :empty-lines-after 1 :jump-to-captured t) org-capture-templates) (cl-pushnew '("pn" "Note" entry (file "notes/notes.org") <> :empty-lines-after 1) org-capture-templates) (cl-pushnew '("pe" "Meeting" entry (file "agenda/tasks.org") <> :prepend t :empty-lines-after 1) org-capture-templates) #+end_src Review captures. #+begin_src elisp (cl-pushnew '("pr" "Review") org-capture-templates) (cl-pushnew '("prd" "Daily Review" plain (file+olp+datetree "agenda/planner.org" "Reviews" "Daily") <> :time-prompt t :empty-lines-after 1) org-capture-templates) (cl-pushnew '("prw" "Weekly Review" plain (file+olp+datetree "agenda/planner.org" "Reviews" "Weekly") <> :time-prompt t :tree-type week :jump-to-captured t :empty-lines-after 1) org-capture-templates) (cl-pushnew '("prm" "Monthly Review" plain (file+olp+datetree "agenda/planner.org" "Reviews" "Monthly") <> :time-prompt t :tree-type month :jump-to-captured t :empty-lines-after 1) org-capture-templates) #+end_src *** Org Encryption Enable org-crypt module. #+begin_src elisp (with-eval-after-load 'org (cl-pushnew 'org-crypt org-modules)) #+end_src Use symmetrical keys for encryption/decryption. #+begin_src elisp (with-eval-after-load 'org-crypt (setq-default org-crypt-key nil)) #+end_src Redirect pinentry queries to Emacs to query passphrases through the minibuffer. #+begin_src elisp (with-eval-after-load 'epg-config (setq-default epg-pinentry-mode 'loopback)) #+end_src Encrypt file on save. #+begin_src elisp (with-eval-after-load 'org-crypt (setq-default org-crypt-disable-auto-save 'encrypt) (org-crypt-use-before-save-magic)) #+end_src *** Org Refile Display filename on refile target and enable instant completion. #+begin_src elisp (with-eval-after-load 'org-refile (setq-default org-refile-use-outline-path 'file org-outline-path-complete-in-steps nil)) #+end_src Increase refile depth for current buffer and agenda files. #+begin_src elisp (with-eval-after-load 'org-refile (cl-pushnew '(nil :maxlevel . 9) org-refile-targets) (cl-pushnew '(org-agenda-files :maxlevel . 9) org-refile-targets)) #+end_src ** Error Checking Enable flymake for programming modes. #+begin_src elisp (add-hook 'prog-mode-hook #'flymake-mode) #+end_src Set flymake keybindings. #+begin_src elisp (with-eval-after-load 'flymake (keymap-set flymake-mode-map "M-# #" #'flymake-show-buffer-diagnostics) (keymap-set flymake-mode-map "M-# M-#" #'flymake-show-project-diagnostics) (keymap-set flymake-mode-map "M-# M-]" #'flymake-goto-next-error) (keymap-set flymake-mode-map "M-# M-[" #'flymake-goto-prev-error)) #+end_src ** Compilation Set make command and scroll output. #+begin_src elisp (with-eval-after-load 'compile (setq-default compile-command "make" compilation-scroll-output t)) #+end_src Auto-close compilation buffer when there are no errors or warnings. #+begin_src elisp (with-eval-after-load 'compile (add-hook 'compilation-finish-functions (lambda (buffer string) "Bury a compilation buffer if succeeded without warnings " (require 'winner) (when (and (buffer-live-p buffer) (string-match "compilation" (buffer-name buffer)) (string-match "finished" string) (eq 0 compilation-num-warnings-found) (eq 0 compilation-num-errors-found)) (run-with-timer 1 nil (lambda () (winner-undo) (message "Compilation successful"))))))) #+end_src ** Shell Make shell prompt and output read-only. #+begin_src elisp (with-eval-after-load 'shell (setq-default comint-prompt-read-only t) (advice-add 'comint-output-filter :after (lambda (&rest r) "Set last process output read-only." (add-text-properties comint-last-output-start (line-end-position 0) '(read-only t rear-nonsticky (inhibit-line-move-field-capture)))))) #+end_src ** Eshell Set the eshell welcome message. #+begin_src elisp (with-eval-after-load 'em-banner (setq-default eshell-banner-message "")) #+end_src Set the prompt for eshell. #+begin_src elisp :noweb yes (with-eval-after-load 'em-prompt <>) #+end_src *** Eshell Prompt :PROPERTIES: :header-args:elisp: :tangle no :noweb-ref eshell-prompt :results none :ID: 531f8b73-c91a-449d-a13b-2bddc8fe13c7 :END: Prompt faces. #+begin_src elisp (defface +eshell-user '((t :foreground "DodgerBlue" :weight bold)) "The face used to highlight $USER." :group 'eshell-prompt) (defface +eshell-host '((t :foreground "indianred" :weight bold)) "The face used to highlight $HOSTNAME." :group 'eshell-prompt) (defface +eshell-dir '((t :foreground "goldenrod" :weight bold)) "The face used to highlight $PWD." :group 'eshell-prompt) (defface +eshell-branch '((t :foreground "MediumSeaGreen" :weight bold)) "The face used to highlight the Git branch." :group 'eshell-prompt) (set-face-attribute 'eshell-prompt nil :inherit 'default) #+end_src Prompt functions. #+begin_src elisp (require 'vc-git) (defun +eshell-git-branch () "Get the Git branch for the current working directory." (vc-git--symbolic-ref (eshell/pwd))) (defun +eshell-dir (&optional limit) "Get full directory path or restrict to current folder if LIMIT." (if limit (file-name-nondirectory (abbreviate-file-name (eshell/pwd))) (abbreviate-file-name (eshell/pwd)))) (defun +eshell-prompt-layout (user dir host branch) "Return a prompt layout using USER, DIR, HOST, & BRANCH." (propertize (concat "[" user "@" host " in " dir (when branch (concat " on " branch)) "] "))) (defun +eshell-prompt-function () "Custom eshell prompt function." (let ((branch (+eshell-git-branch))) (+eshell-prompt-layout (propertize (eshell-user-name) 'face '+eshell-user) (propertize (+eshell-dir t) 'face '+eshell-dir) (propertize (system-name) 'face '+eshell-host) (when branch (propertize branch 'face '+eshell-branch))))) #+end_src Prompt settings. #+begin_src elisp (setq-default eshell-highlight-prompt nil eshell-prompt-function #'+eshell-prompt-function) #+end_src ** Diff-mode Rebind diff-mode's ~diff-goto-source~ keybinding (due to conflict with =M-o=). Add version control next action shortcut in diff-mode buffer. #+begin_src elisp (with-eval-after-load 'diff-mode (keymap-set diff-mode-map "M-j" #'diff-goto-source) (keymap-set diff-mode-map "v" #'vc-next-action)) #+end_src ** Eglot Configure eglot. #+begin_src elisp (with-eval-after-load 'eglot (keymap-set eglot-mode-map "C-c e a" #'eglot-code-actions) (keymap-set eglot-mode-map "C-c e e" #'eglot-code-actions) (keymap-set eglot-mode-map "C-c e f" #'eglot-format) (keymap-set eglot-mode-map "C-c e r" #'eglot-rename)) #+end_src Enable eglot for certain modes. #+begin_src elisp (add-hook 'c-mode-hook #'eglot-ensure) (add-hook 'c++-mode-hook #'eglot-ensure) #+end_src * Global Keybindings Unlock previously unusable keybinding. #+begin_src elisp (define-key input-decode-map [?\C-\[] (kbd "")) #+end_src To prevent other packages overriding any custom global keybinding, all custom global keybinding are stored in a global minor mode. #+begin_src elisp (define-minor-mode +global-keys "Minor to store my custom global keybindings." :global t :lighter " +GKEYS" :keymap (make-sparse-keymap)) (+global-keys) #+end_src File actions. #+begin_src elisp (keymap-set +global-keys-map "C-x x R" #'rename-visited-file) (keymap-set +global-keys-map "C-x x D" #'delete-file) (keymap-set +global-keys-map "C-x M-f" #'recentf) #+end_src Window actions. #+begin_src elisp (keymap-set +global-keys-map "M-o" #'other-window) (keymap-set +global-keys-map "M-O" #'window-swap-states) (keymap-set +global-keys-map "M-V" #'scroll-other-window-down) (keymap-set +global-keys-map "C-S-V" #'scroll-other-window) (keymap-set +global-keys-map "C-M-<" #'beginning-of-buffer-other-window) (keymap-set +global-keys-map "C-M->" #'end-of-buffer-other-window) #+end_src Buffer actions. #+begin_src elisp (keymap-set +global-keys-map "C-M--" #'kill-this-buffer) (keymap-set +global-keys-map "C-M-0" #'kill-buffer-and-window) (keymap-set +global-keys-map "C-M-]" #'next-buffer) (keymap-set +global-keys-map "C-x M-b" #'bs-show) (keymap-set +global-keys-map "C-x M-i" #'ibuffer) (keymap-set +global-keys-map "M-ESC" #'previous-buffer) ; C-M-[ translates to M-ESC (keymap-set +global-keys-map "M-_" #'bury-buffer) (keymap-set +global-keys-map "M-*" #'unbury-buffer) #+end_src Set meta-key quick actions to mirror =C-x DIGIT= bindings, therefore reducing the need for additional keypresses. These bindings override their corresponding numerical argument, however these can be can be alternatively called with =C-u DIGIT= or =C-DIGIT=. #+begin_src elisp (keymap-set +global-keys-map "M-0" #'delete-window) (keymap-set +global-keys-map "M-1" #'delete-other-windows) (keymap-set +global-keys-map "M-2" (lambda () "Switch to scratch buffer on split." (interactive) (split-window-below) (scratch-buffer))) (keymap-set +global-keys-map "M-3" (lambda () "Switch to scratch buffer on split." (interactive) (split-window-right) (scratch-buffer))) (keymap-set +global-keys-map "M-4" #'ctl-x-4-prefix) (keymap-set +global-keys-map "M-5" #'ctl-x-5-prefix) (keymap-set +global-keys-map "M-6" (keymap-global-lookup "C-x 6")) (keymap-set +global-keys-map "M-7" (keymap-global-lookup "C-x 7")) (keymap-set +global-keys-map "M-8" (keymap-global-lookup "C-x 8")) (keymap-set +global-keys-map "M-9" (keymap-global-lookup "C-x 9")) #+end_src Tab actions. #+begin_src elisp (keymap-set +global-keys-map "C-x C-" #'tab-new) (keymap-set +global-keys-map "C-x C-" #'tab-close) (keymap-set +global-keys-map "C-x t l" #'tab-list) (keymap-set +global-keys-map "C-x t " #'toggle-frame-tab-bar) #+end_src Improve region text manipulation. #+begin_src elisp (keymap-set +global-keys-map "M-c" #'capitalize-dwim) (keymap-set +global-keys-map "M-l" #'downcase-dwim) (keymap-set +global-keys-map "M-u" #'upcase-dwim) (keymap-set +global-keys-map "M-U" #'upcase-char) #+end_src Help actions. #+begin_src elisp (keymap-set +global-keys-map "C-h M" #'describe-keymap) (keymap-set +global-keys-map "C-h j" #'describe-char) (keymap-set +global-keys-map "C-h y" (lambda () "Open the Directory node for info on major topics." (interactive) (require 'info) (Info-find-node "dir" "top"))) #+end_src Display modes. #+begin_src elisp (keymap-set +global-keys-map "C-x #" #'calendar) (keymap-set +global-keys-map "C-x x SPC" #'whitespace-mode) (keymap-set +global-keys-map "C-x x c" #'display-fill-column-indicator-mode) (keymap-set +global-keys-map "C-x x h" #'hl-line-mode) (keymap-set +global-keys-map "C-x x l" #'display-line-numbers-mode) (keymap-set +global-keys-map "C-x x o" #'overwrite-mode) (keymap-set +global-keys-map "C-x x s" #'prettify-symbols-mode) (keymap-set +global-keys-map "C-x x v" #'visual-line-mode) #+end_src Org functions. #+begin_src elisp (keymap-set +global-keys-map "C-c a" #'org-agenda) (keymap-set +global-keys-map "C-c c" #'org-capture) (keymap-set +global-keys-map "C-c l" #'org-store-link) (keymap-set +global-keys-map "C-c C-x ," #'org-timer-pause-or-continue) (keymap-set +global-keys-map "C-c C-x ." #'org-timer) (keymap-set +global-keys-map "C-c C-x 0" #'org-timer-start) (keymap-set +global-keys-map "C-c C-x ;" #'org-timer-set-timer) (keymap-set +global-keys-map "C-c C-x _" #'org-timer-stop) #+end_src Other =C-c= commands. #+begin_src elisp (keymap-set +global-keys-map "C-c t" #'modus-themes-toggle) (keymap-set +global-keys-map "C-c e" #'eshell) (keymap-set +global-keys-map "C-c s" #'window-toggle-side-windows) (keymap-set +global-keys-map "C-`" #'window-toggle-side-windows) #+end_src Repeat action. #+begin_src elisp (keymap-set +global-keys-map "C-." #'repeat) #+end_src * EXTENSIONS #+begin_src elisp (add-to-list 'load-path "~/shared/modally/") (require 'modally) (modally-mode) #+end_src * Extra Packages ** Use package #+begin_src elisp (setq-default use-package-always-ensure t) #+end_src ** Vundo https://github.com/casouri/vundo Vundo (visual undo) displays the undo history as a tree and lets you move in the tree to go back to previous buffer states. #+begin_src elisp (use-package vundo :bind ("C-x C-/" . vundo)) #+end_src ** Vertico https://github.com/minad/vertico Vertico provides a performant and minimalistic vertical completion UI based on the default completion system. #+begin_src elisp (use-package vertico :config ;; Disable previously used vertical mode (fido-vertical-mode -1) (fido-mode -1) ;; Enable vertico mode (vertico-mode)) #+end_src ** Corfu https://github.com/minad/corfu Corfu enhances in-buffer completion with a small completion popup. The current candidates are shown in a popup below or above the point, and can be selected by moving up and down. #+begin_src elisp (use-package corfu :custom (corfu-count 5) (corfu-auto t) :config ;; Remove previous completion preview method (remove-hook 'prog-mode-hook #'completion-preview-mode) ;; Enable corfu mode (global-corfu-mode)) #+end_src ** Marginalia https://github.com/minad/marginalia This package provides marginalia-mode which adds marginalia to the minibuffer completions. #+begin_src elisp (use-package marginalia :ensure t :bind (:map minibuffer-local-map ("C-M-i" . marginalia-cycle)) :init (marginalia-mode)) #+end_src ** Consult https://github.com/minad/consult Consult provides search and navigation commands based on the Emacs completion function completing-read. #+begin_src elisp ;; Example configuration for Consult (use-package consult ;; Replace bindings. Lazily loaded by `use-package'. :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 t b" . consult-buffer-other-tab) ;; orig. switch-to-buffer-other-tab ("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 r" . consult-grep-match) ("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 ("C-c j" . consult-outline) ("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) ;; Alternative: consult-fd ("M-s c" . 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 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 ;; Org mode :map org-mode-map ("C-c j" . consult-org-heading) ("C-c C-j" . consult-org-heading)) ;; 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 ;; Tweak the register preview for `consult-register-load', ;; `consult-register-store' and the built-in commands. This improves the ;; register formatting, adds thin separator lines, register sorting and hides ;; the window mode line. (advice-add #'register-preview :override #'consult-register-window) (setq register-preview-delay 0.5) ;; 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 "C-.") ;; 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-man ;; 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 "M-." ;; :preview-key '(:debounce 0.4 any)) ;; Optionally configure the narrowing key. ;; Both < and C-+ work reasonably well. (setq consult-narrow-key "<") ;; "C-+" ;; Optionally make narrowing help available in the minibuffer. ;; You may want to use `embark-prefix-help-command' or which-key instead. ;; (keymap-set consult-narrow-map (concat consult-narrow-key " ?") #'consult-narrow-help) ) #+end_src ** Orderless https://github.com/oantolin/orderless Emacs completion style that matches multiple regexps in any order. #+begin_src elisp (use-package orderless :custom (completion-styles '(orderless basic)) (completion-category-overrides '((file (styles partial-completion))))) #+end_src ** Devdocs https://github.com/astoff/devdocs.el Devdocs is a documentation viewer for Emacs similar to the built-in Info browser, but geared towards documentation distributed by the DevDocs website. #+begin_src elisp (use-package devdocs :bind ("C-c d" . devdocs-lookup) :hook ((c-mode . (lambda () (setq-local devdocs-current-docs '("c")))) (c++-mode . (lambda () (setq-local devdocs-current-docs '("cpp")))))) #+end_src ** Dired Sidebar [[https://github.com/jojojames/dired-sidebar]] Sidebar for Emacs leveraging Dired. #+begin_src elisp (use-package dired-sidebar :commands (dired-sidebar-toggle-sidebar) :bind ("C-c o" . dired-sidebar-toggle-sidebar)) #+end_src ** Kind Icons https://github.com/jdtsmith/kind-icon Completion kind text/icon prefix labelling for emacs in-region completion. #+begin_src elisp (use-package kind-icon :ensure t :after corfu :custom (kind-icon-blend-background t) (kind-icon-default-face 'corfu-default) ; only needed with blend-background :config (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter)) #+end_src ** Diff-hl #+begin_src elisp (use-package diff-hl :custom (diff-hl-margin-symbols-alist '((insert . "+") (delete . "-") (change . "~") (unknown . "?") (ignored . "i"))) :custom-face (diff-hl-margin-insert ((t (:inherit nil :weight bold :background "unspecified-bg" :foreground "green")))) (diff-hl-margin-change ((t (:inherit nil :weight bold :background "unspecified-bg" :foreground "goldenrod")))) (diff-hl-margin-delete ((t (:inherit nil :weight bold :background "unspecified-bg" :foreground "red")))) :config (global-diff-hl-mode) (diff-hl-margin-mode) (diff-hl-flydiff-mode) :hook (dired-mode . diff-hl-dired-mode)) #+end_src ** Expand Region https://codeberg.org/codeblake/emacs#headline-102 Emacs extension to increase selected region by semantic units. #+begin_src elisp (use-package expand-region :bind ("C-=" . er/expand-region)) #+end_src