UP | HOME
Kristian Alexander P

Kristian Alexander

Free Software Enthusiast | GNU Emacs User

Emacs Configuration

Published on Feb 20, 2022 by Kristian Alexander P.

This configuration was inspired by the rational-emacs configuration from the systemcrafters series. So instead of blindly copying every snippets of Emacs configuration I’ve found on the internet, I’m taking the lighter approach and try to only use what is necessary.

With that in mind, I’m breaking down this configuration into separate pluggable files that can be included on demand. But the general goal is to only use what’s already built-in to Emacs as much as possible. Just like many other dotfiles I’ve used so far, this configuration will be generated from a single org-mode file (the one you’re reading right now).

By default this will creates an emacs directory insinde ~/.config or wherever the ${XDG_CONFIG_HOME} is set. If you’re using chemacs, or if you want to use the standard ~/.emacs.d directory, modify the :tangle directive inside each heading’s :PROPERTIES:.

To easily toggle the additional packages, create a config-user.el file inside user-emacs-directory, usually ~/.config/emacs. This file also generate ~/.config/emacs/config-user.el.example:

Example config-user.el

header-args: :tangle (expand-file-name "config-user.el.example" user-emacs-directory)

Commented header

;;; config-user.el --- Emacs configuration file -*- lexical-binding: t mode: emacs-lisp -*-
;;; Commentary:
;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
;; for details.
;;; Code:

And set variables for various packages.

(setq user-full-name "Kristian Alexander P"
      user-mail-address "alexforsale@yahoo.com")
(customize-set-variable 'org-directory (expand-file-name "Documents/google-drive/org/" (getenv "HOME")))
(customize-set-variable '+org-archives-file (expand-file-name "archives.org" org-directory))
(customize-set-variable '+org-capture-todo-file (expand-file-name "todo.org" org-directory))
(customize-set-variable '+org-capture-links-file (expand-file-name "links.org" org-directory))
(customize-set-variable '+org-capture-notes-file (expand-file-name "notes.org" org-directory))
(customize-set-variable '+org-capture-habits-file (expand-file-name "habits.org" org-directory))
(customize-set-variable '+org-capture-projects-file (expand-file-name "projects.org" org-directory))
(customize-set-variable 'org-agenda-files (list org-directory))
(customize-set-variable '+emms-music-dir "~/Music")
(customize-set-variable '+config-doom-theme 'doom-solarized-dark)
(customize-set-variable '+config-standard-theme 'wombat)
(customize-set-variable '+mail-directory "~/.mail")

UI Packages

;; UI Additional packages
;; (require 'config-all-the-icons)
;; (require 'config-doom-modelines)
;; (require 'config-doom-themes)
;; (when (display-graphic-p)
;;   (require 'config-theme-magic))
(require 'config-helpful)
(require 'config-which-key)
;; (require 'config-ace-window)
;; (require 'config-perspective)
;; (unless (or (featurep 'exwm)
;;             (string= "exwm" (getenv "DESKTOP_SESSION")))
;;   (require 'config-centaur-tabs)) ; doesn't look good in workspaces
;; (require 'config-rainbow-mode)
;; (require 'config-rainbow-delimiters)
;; (require 'config-hl-todo)
(require 'config-diminish)
;; (require 'config-dashboard)
;; (require 'config-alert)
;; (require 'config-smartparens)
;; (require 'config-treemacs)
;; (require 'config-vertico-posframe)

Editing packages

;; Editing Additional packages
;; (require 'config-multiple-cursors)
;; (require 'config-yasnippet)
;; (require 'config-geiser)
;; (require 'config-yaml-mode)
;; (require 'config-toml-mode)
;; (require 'config-nix-mode)
;; (require 'config-markdown-mode)
;; (require 'config-rust-mode)
;; (require 'config-visual-regexp)
;; (require 'config-undo-fu)
;; (require 'config-block-nav)
;; (require 'config-ansible)
;; (require 'config-jinja2-mode)
;; (require 'config-hydra)
;; (require 'config-general)
;; (require 'config-evil)
;; (require 'config-aggressive-indent-mode)

Org packages

;; Org Additional packages
;; (require 'config-org-roam)
;; (require 'config-org-elfeed)
;; (require 'config-org-gcal)
;; (+config/org-gcal-setup-sync)
(require 'config-org-journal)

IDE packages

;; IDE Additional packages
;; (require 'config-flycheck)
;; (require 'config-projectile)
;; (require 'config-lsp-mode)
;; (require 'config-git-gutter)

Email packages

;; Email Additional packages
;; (require 'config-notmuch)
;; (require 'config-gnus-alias)
;; (customize-set-variable '+config/mail-fetch-program "mbsync")

Various additional packages

;; Shell Additional packages
;; (require 'config-vterm)

Completion packages

;; Completion packages
;; (require 'config-vertico)
;; (require 'config-orderless)
;; (require 'config-marginalia)
;; (require 'config-consult)
;; (require 'config-embark)
;; (require 'config-corfu)
;; (require 'config-cape)
;; (require 'config-dabbrev)

Tools packages

;; Misc tools packages
;; (require 'config-pass)
(require 'config-magit)
(require 'config-git-modes)
;;(require 'config-slime)
;;(require 'config-sly) ; a better repl than slime
;;(require 'config-paredit)
;; (require 'config-telega)
;; (require 'config-emms)
;;(+config/emms-set-mpd) ; when using mpd
;; (require 'config-w3m)
;; (require 'config-pdf-tools)
;; (require 'config-gist)
;; (require 'config-ripgrep)
;; (require 'config-restart-emacs)
;; (require 'config-hugo)

Theme

(defun +config/load-theme (theme)
  "Load THEME after new frame.
Also for the current frame"
  (progn
    (load-theme theme t)
    (add-hook 'after-make-frame-functions
              (lambda (frame)
                (select-frame frame)
                (when (display-graphic-p frame)
                  (load-theme theme t))))))

(cond ((and (featurep 'config-doom-themes)
            (featurep 'consult)
            (display-graphic-p))
       (+config/load-theme +config-doom-theme))
      (t
       (+config/load-theme +config-standard-theme)))

Footer

(provide 'config-user)
;;; config-user.el ends here

config.org

header-args: :tangle (expand-file-name "config.el" user-emacs-directory) :mkdirp t

Set lexical-binding for this file.

;;; config.el --- Base Emacs configuration file -*- lexical-binding: t -*-
;;; Commentary:
;; This file is auto-generated from `config.org'
;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
;;; Code:

early-init.el

header-args: :tangle (expand-file-name "early-init.el" user-emacs-directory)
;;; early-init.el --- Customization before normal init -*- lexical-binding: t -*-
;;; Commentary:
;; This file is auto-generated from `config.org'
;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
;;; Code:

This file is loaded before the package system and GUI is initialized.

Set +emacs-data-dir variables.

(defvar +emacs-data-dir
  (if (getenv "XDG_DATA_HOME")
      (expand-file-name "emacs" (getenv "XDG_DATA_HOME"))
    (expand-file-name ".local/share/emacs" (getenv "HOME")))
  "Location for Emacs data files.")

This will set the variable =+emacs-data-dir to ~/.local/share/emacs.

Increase the GC threshold for faster startup

The default is 800 kilobytes, measured in bytes.

(setq gc-cons-threshold (* 50 1000 1000))

Prefer loading newest compiled .el files

(customize-set-variable 'load-prefer-newer noninteractive)

Native compilation settings.

(when (featurep 'native-compile)
  ;; Silence compiler warnings as they can be pretty disruptive
  (setq native-comp-async-report-warnings-errors nil)

  ;; Make native compilation happens asynchronously
  (setq native-comp-deferred-compilation t)

  ;; Set the right directory to store the native compilation cache
  (add-to-list 'native-comp-eln-load-path (expand-file-name "eln-cache/" +emacs-data-dir)))

Don’t use package.el, we’ll use straight.el instead

(setq package-enable-at-startup nil)

Remove some unneeded UI elements.

(setq inhibit-startup-message t)
(push '(tool-bar-lines . 0) default-frame-alist)
(push '(menu-bar-lines . 0) default-frame-alist)
(push '(vertical-scroll-bars) default-frame-alist)
(push '(background-color . "#232635") default-frame-alist)
(push '(foreground-color . "#FCFCFA") default-frame-alist)
(push '(mouse-color . "white") default-frame-alist)

This also sets the initial minimal theme to avoid having the vanilla theme.

Make the initial buffer load faster by setting its mode to fundamental-mode.

(customize-set-variable 'initial-major-mode 'fundamental-mode)

Set location for straight-base-dir, must be set before straight.el initialized.

(customize-set-variable 'straight-base-dir +emacs-data-dir)

Adds footer since this is the end of the file early-init.el

(provide 'early-init)
;;; early-init.el ends here

init.el

header-args: :tangle (expand-file-name "init.el" user-emacs-directory)
;;; init.el --- Main Emacs configuration file -*- lexical-binding: t -*-
;;; Commentary:
;; This file is auto-generated from `config.org'
;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
;;; Code:

The Emacs initialization file.

Add the modules folder to the load path.

(add-to-list 'load-path (expand-file-name "modules/" user-emacs-directory))

User site-lisp directory

(defvar +site-lisp-dir
  (expand-file-name "site-lisp" user-emacs-directory)
  "Location of user site-lisp directory")
(add-to-list 'load-path +site-lisp-dir)

;; create the directory
(unless (file-directory-p +site-lisp-dir)
  (make-directory +site-lisp-dir))

Set default coding system.

(set-default-coding-systems 'utf-8)

Increase large file warning size to around 100MB.

(customize-set-variable 'large-file-warning-threshold 100000000)

Bootstrap straight.el

;; redefine `+emacs-data-dir', it seems in Emacs 27
;; variables defined in early-init.el doesn't carry-over here.
(unless (boundp '+emacs-data-dir)
  (defvar +emacs-data-dir
    (if (getenv "XDG_DATA_HOME")
        (expand-file-name "emacs" (getenv "XDG_DATA_HOME"))
      (expand-file-name ".local/share/emacs" (getenv "HOME")))
    "Location for Emacs data files."))
(unless (file-directory-p +emacs-data-dir)
  (make-directory +emacs-data-dir :parents))
(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" +emacs-data-dir))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))
;; run org immediately
(straight-use-package 'org)

This is a modification from the original snippets, so it needs to be evaluated regularly to merge any updates.

Separate custom-file, and load it if exists.

(setq-default custom-file (expand-file-name "custom.el" +emacs-data-dir))
(when (file-exists-p custom-file)
  (load custom-file))

This file is usually modified if you made changes using the customize function (e.g. M-x customize).

In order to have emacs use this file as its init file, first we have to convert this file from org-mode into the usual emacs-lisp file.

(defvar +my-emacs-config-file (expand-file-name "config.org" user-emacs-directory)
  "My Emacs `org-mode' configuration file.")

(when (file-exists-p +my-emacs-config-file)
  (org-babel-load-file +my-emacs-config-file))

This is important, this org-mode file needs to also resides in the user-emacs-directory, this variable is dynamically set depending on where your init.el file. So if you already have that file inside ~/.config/emacs before Emacs started, that’s where the user-emacs-directory (only if it not detect an ~/.emacs.d directory, so remove that directory first if you want to use ~/.config/emacs).

Also, any codes inside this file will automatically evaluated by Emacs. So you don’t have to manually require it.

loads config-defaults, which doesn’t require any foreign packages.

(require 'config-defaults)

This is the core tweaks. Any codes inside this file (config-defaults.el) should not depends on any other files or modules except the ones bundled with Emacs.

per-user configuration file, not maintained by git, so I can have different setup for my desktop and laptop.

(when (file-exists-p (expand-file-name "config-user.el" user-emacs-directory))
  (customize-set-variable 'vc-follow-symlinks t)
  (load (expand-file-name "config-user.el" user-emacs-directory)))

If there’s any modules or other files needed, this is where to place it.

start server

(require 'server)
(unless (server-running-p) (server-start))

Adds footer since this is the end of the file init.el

(provide 'init)
;;; init.el ends here

Variables

header-args: :tangle (expand-file-name "modules/config-defaults-variables.el" user-emacs-directory) :mkdirp t
;;; config-defaults-variables.el --- Summary -*- lexical-binding: t -*-
;;; Commentary:
;; This file is auto-generated from `config.org'
;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
;;; Code:

This tangles into ~/.config/emacs/modules/config-defaults-variables.el

Determine running OS

(cond ((string-match ".*/sh" (getenv "SHELL"))
       (when (file-exists-p
              (expand-file-name ".shrc" (getenv "HOME")))
         (shell-command ". ~/.shrc" nil nil)))
      ((string-match ".*/csh" (getenv "SHELL"))
       (when (file-exists-p
              (expand-file-name ".cshrc" (getenv "HOME")))
         (shell-command "source ~/.cshrc")))
      ((string-match ".*/tcsh" (getenv "SHELL"))
       (when (file-exists-p
              (expand-file-name ".tcshrc" (getenv "HOME")))
         (shell-command "source ~/.tcshrc")))
      ((string-match ".*/bash" (getenv "SHELL"))
       (when (file-exists-p
              (expand-file-name ".bashrc" (getenv "HOME")))
         (shell-command "source ~/.bashrc")))
      ((string-match ".*/zsh" (getenv "SHELL"))
       (when (file-exists-p
              (expand-file-name ".zhrc" (getenv "HOME")))
         (shell-command "source ~/.zshrc"))))

This is needed for EXWM inside guixSD.

guix

(setq +config/is-guix-system (and (eq system-type 'gnu/linux)
                                  (string= (getenv "GUIX_LOCPATH") "/run/current-system/locale")))

DE/WM

exwm

(setq +config/exwm-enabled
      (or (string= (getenv "DESKTOP_SESSION") "exwm")
          (featurep 'exwm)))

XDG Directories

;; set XDG_PICTURES_DIR
(unless (getenv "XDG_PICTURES_DIR")
  (setenv "XDG_PICTURES_DIR" (expand-file-name "Pictures" (getenv "HOME"))))
;; set XDG_MUSIC_DIR
(unless (getenv "XDG_MUSIC_DIR")
  (setenv "XDG_MUSIC_DIR" (expand-file-name "Music" (getenv "HOME"))))
;; set XDG_DOWNLOAD_DIR
(unless (getenv "XDG_DOWNLOAD_DIR")
  (setenv "XDG_DOWLNOAD_DIR" (expand-file-name "Downloads" (getenv "HOME"))))

emms music directory

(defvar +emms-music-dir (getenv "XDG_MUSIC_DIR")
  "Location for `emms' music directory.")

backups and autosave files

The first thing to do is set the directories for backups and autosave, most people turn off these settings, but I sometimes need them, not inside the user-emacs-directory though, because I’d like to have few lines in my .gitignore.

(defvar +emacs-backup-directory
  (if (getenv "XDG_DATA_HOME")
      (expand-file-name "emacs/backups" (getenv "XDG_DATA_HOME"))
    (expand-file-name ".local/share/emacs/backups" (getenv "HOME")))
  "Location of Emacs backup files.")
(unless backup-directory-alist
  (setq backup-directory-alist `(("." . ,+emacs-backup-directory))))
(unless (file-directory-p +emacs-backup-directory)
  (make-directory +emacs-backup-directory :parents))
(setq backup-by-copying t)
(setq auto-save-list-file-prefix (expand-file-name "auto-saves/sessions/" +emacs-backup-directory))
(setq auto-save-file-name-transform
      `((".*" ,(expand-file-name "auto-saves/" +emacs-backup-directory) t)))

other builtin data file

(setq filesets-menu-cache-file (expand-file-name "filesets-menu-cache.el" +emacs-data-dir))
(setq gamegrid-user-score-file-directory (expand-file-name "gamegrid-user-score/" +emacs-data-dir))
(setq kkc-init-file-name (expand-file-name "kkc-init.el" +emacs-data-dir))
(setq multisession-directory (expand-file-name "multisession/" +emacs-data-dir))
(setq project-list-file (expand-file-name "project-list.el" +emacs-data-dir))
(setq quickurl-url-file (expand-file-name "quickurl-url.el" +emacs-data-dir))
(setq rcirc-log-directory (expand-file-name "rcirc-log/" +emacs-data-dir))
(setq srecode-map-save-file (expand-file-name "srecode-map.el" +emacs-data-dir))
(setq semanticdb-default-save-directory (expand-file-name "semantic/" +emacs-data-dir))
(setq shared-game-score-directory (expand-file-name "shared-game-score/" +emacs-data-dir))
(setq timeclock-file (expand-file-name "timeclock" +emacs-data-dir))
(setq type-break-file-name (expand-file-name "type-break.el" +emacs-data-dir))

theme

(defvar +config-doom-theme nil
  "User doom theme")
(defvar +config-standard-theme nil
  "User builtin theme")

directory-empty-p

This function only available for Emacs version 28+, make it available also for earlier version.

(when (version< emacs-version "28" ;>
                )
  (defun directory-empty-p (file-name)
    "Check if a directory contains any other files then dot-files"
    (when (file-directory-p file-name)
      (null (directory-files file-name nil
                             directory-files-no-dot-files-regexp t)))))

mail-fetch-program

(defvar +config/mail-fetch-program nil
  "Mail fetcher to use.

Choices are offlineimap or mbsync.")

mail-directory

(defvar +mail-directory nil
  "User mail directory.")

footer

(provide 'config-defaults-variables)
;;; config-defaults-variables.el ends here

modules

With this modular design, I can include per files configuration only.

defaults

header-args: :tangle (expand-file-name "modules/config-defaults.el" user-emacs-directory)
;;; config-defaults.el --- Summary -*- lexical-binding: t -*-
;;; Commentary:
;; This file is auto-generated from `config.org'
;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
;;; Code:

Other defaults modules

(require 'config-defaults-org)
(require 'config-defaults-ui)
(require 'config-defaults-editings)
(require 'config-defaults-completion)
(require 'config-defaults-various)
(require 'config-defaults-ide)
(require 'config-defaults-email)
(require 'config-defaults-shell)
(require 'config-defaults-tools)
(require 'config-defaults-keybindings)

end of config-defaults.el

(provide 'config-defaults)
;;; config-defaults.el ends here

Default UI

header-args: :tangle (expand-file-name "modules/config-defaults-ui.el" user-emacs-directory) :mkdirp t
;;; config-defaults-ui.el --- Summary -*- lexical-binding: t -*-
;;; Commentary:
;; This file is auto-generated from `config.org'
;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
;;; Code:

Default fonts

Got this from emacsredux:

(cond
 ((find-font (font-spec :name "Source Code Pro"))
  (set-frame-font "Source Code Pro-10"))
 ((find-font (font-spec :name "Fira Code"))
  (set-frame-font "Fire Code-10"))
 ((find-font (font-spec :name "DejaVu Sans Mono"))
  (set-frame-font "DejaVu Sans Mono-10"))
 ((find-font (font-spec :name "Ubuntu Mono"))
  (set-frame-font "Ubuntu Mono-12")))

Load theme

(unless custom-enabled-themes
 (load-theme 'manoj-dark t))

Revert Dired and other buffers

(setq auto-revert-verbose t
      auto-revert-use-notify nil
      auto-revert-stop-on-user-input nil
      revert-without-query (list "."))
(customize-set-variable 'global-auto-revert-non-file-buffers t)

Revert buffers when the underlying file has changed

(global-auto-revert-mode 1)

Make scrolling less stuttered

(setq auto-window-vscroll nil)
(customize-set-variable 'fast-but-imprecise-scrolling t)
(customize-set-variable 'scroll-conservatively 101)
(customize-set-variable 'scroll-margin 0)
(customize-set-variable 'scroll-preserve-screen-position t)

enable visual-line-mode

(visual-line-mode 1)

move point to help window

(setq help-window-select t)

always maximize frame

(set-frame-parameter (selected-frame) 'fullscreen 'maximized)
(add-to-list 'default-frame-alist '(fullscreen . maximized))

don’t truncate lines

(setq truncate-lines 'nil)
(setq truncate-partial-width-windows nil)

Lines should be 80 characters wide

(setq fill-column 80)

Show empty lines after buffer end

(set-default 'indicate-empty-lines t)

don’t confirm when following symlink files

(setq vc-follow-symlinks t)

Enable recursive minibuffers

(setq enable-recursive-minibuffers t)

Always require final newline

(setq require-final-newline t)

uniquify

(require 'uniquify)
(setq uniquify-buffer-name-style 'forward)

Offer to create parent directories if they do not exists, from iqbalansari.github.io

(defun +my-create-non-existent-directory ()
  (let ((parent-directory (file-name-directory buffer-file-name)))
    (when (and (not (file-exists-p parent-directory))
               (y-or-n-p (format "Directory `%s' does not exist! Create it?" parent-directory)))
      (make-directory parent-directory t))))

(add-to-list 'find-file-not-found-functions '+my-create-non-existent-directory)

line numbering for some modes

      (column-number-mode)

      ;; Enable line numbers for some modes
      (dolist (mode '(text-mode-hook
                      prog-mode-hook
                      conf-mode-hook))
        (add-hook mode (lambda () (display-line-numbers-mode 1))))

      ;; Override some modes which derive from the above
      (dolist (mode '(org-mode-hook))
        (add-hook mode (lambda () (display-line-numbers-mode 0))))
(setq-default display-line-numbers-width 3)
(setq-default display-line-numbers-widen t)

add visual pulse when changing focus, like beacon but built-in, from karthinks.com.

(defun +pulse-line (&rest _)
  "Pulse the current line."
  (pulse-momentary-highlight-one-line (point)))

(dolist (command '(scroll-up-command scroll-down-command
                                     recenter-top-bottom other-window))
  (advice-add command :after #'+pulse-line))

loop animated image

(setq image-animate-loop t)

eldoc

(add-hook 'emacs-lisp-mode-hook 'eldoc-mode)
(add-hook 'lisp-interaction-mode-hook 'eldoc-mode)
(add-hook 'ielm-mode-hook 'eldoc-mode)
(add-hook 'prog-mode-hook 'eldoc-mode)

enable line numbering for some mode automatically.

(column-number-mode)

;; Enable line numbers for some modes
(dolist (mode '(text-mode-hook
                prog-mode-hook
                conf-mode-hook))
  (add-hook mode (lambda () (display-line-numbers-mode 1))))

;; Override some modes which derive from the above
(dolist (mode '(org-mode-hook))
  (add-hook mode (lambda () (display-line-numbers-mode 0))))

indentation

(customize-set-variable 'standard-indent 2)
(customize-set-variable 'smie-indent-basic 2)
(customize-set-variable 'sh-indent-for-do 2)
(customize-set-variable 'sh-indent-for-done 0)
(customize-set-variable 'sh-indent-for-fi 0)
(customize-set-variable 'sh-indent-for-else 0)
(customize-set-variable 'sh-indent-for-then 2)
(customize-set-variable 'sh-indent-after-do 2)
(customize-set-variable 'sh-indent-after-done 2)
(customize-set-variable 'notmuch-hello-indent 2)
(customize-set-variable 'org-list-indent-offset 2)
(paragraph-indent-minor-mode 1)

Additional Packages

  • all-the-icons
    header-args: :tangle (expand-file-name "modules/config-all-the-icons.el" user-emacs-directory)
    
    • header
      ;;; config-all-the-icons.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (when (display-graphic-p)
          (straight-use-package 'all-the-icons)))
      
    • Footer
      (provide 'config-all-the-icons)
      ;;; config-all-the-icons.el ends here
      
  • doom-modeline
    header-args: :tangle (expand-file-name "modules/config-doom-modelines.el" user-emacs-directory)
    
    • header
      ;;; config-doom-modelines.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'doom-modeline))
      
    • variables
      (customize-set-variable 'doom-modeline-height 15)
      (customize-set-variable 'doom-modeline-bar-width 6)
      (customize-set-variable 'doom-modeline-minor-modes t)
      (customize-set-variable 'doom-modeline-buffer-file-name-style 'truncate-except-project)
      
    • hooks
      (add-hook 'after-init-hook 'doom-modeline-init)
      ;;(add-hook 'doom-modeline-mode-hook 'size-indication-mode-hook)
      ;;(add-hook 'doom-modeline-mode-hook 'column-number-mode-hook)
      
    • set icon when in daemon mode
      (when (daemonp)
        (setq doom-modeline-icon t))
      
    • Footer
      (provide 'config-doom-modelines)
      ;;; config-doom-modelines.el ends here
      
  • doom-themes
    header-args: :tangle (expand-file-name "modules/config-doom-themes.el" user-emacs-directory)
    
    • header
      ;;; config-doom-themes.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'doom-themes))
      
    • variables
      (setq doom-themes-enable-bold t    ; if nil, bold is universally disabled
            doom-themes-enable-italic t) ; if nil, italics is universally disabled
      
    • config
      ;; 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)
      
    • Footer
      (provide 'config-doom-themes)
      ;;; config-doom-themes.el ends here
      
  • theme-magic
    header-args: :tangle (expand-file-name "modules/config-theme-magic.el" user-emacs-directory)
    
    • header
      ;;; config-theme-magic.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'theme-magic))
      (when (executable-find "wal")
        (require 'theme-magic)
        (theme-magic-export-theme-mode))
      
    • Footer
      (provide 'config-theme-magic)
      ;;; config-theme-magic.el ends here
      
  • helpful
    header-args: :tangle (expand-file-name "modules/config-helpful.el" user-emacs-directory)
    
    • header
      ;;; config-helpful.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'elisp-demos)
        (straight-use-package 'helpful))
      
    • keybinding
      (require 'helpful)
      (define-key helpful-mode-map [remap revert-buffer] #'helpful-update)
      (global-set-key [remap describe-command] #'helpful-command)
      (global-set-key [remap describe-function] #'helpful-callable)
      (global-set-key [remap describe-key] #'helpful-key)
      (global-set-key [remap describe-symbol] #'helpful-symbol)
      (global-set-key [remap describe-variable] #'helpful-variable)
      (global-set-key (kbd "C-h F") #'helpful-function)
      (global-set-key (kbd "C-h K") #'describe-keymap)
      
    • elisp-demos
      (require 'elisp-demos)
      (advice-add 'helpful-update :after #'elisp-demos-advice-helpful-update)
      
    • Footer
      (provide 'config-helpful)
      ;;; config-helpful.el ends here
      
  • which-key
    header-args: :tangle (expand-file-name "modules/config-which-key.el" user-emacs-directory)
    
    • header
      ;;; config-which-key.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'which-key))
      
    • config
      (require 'which-key)
      (which-key-mode)
      (which-key-setup-side-window-right-bottom)
      
    • Footer
      (provide 'config-which-key)
      ;;; config-which-key.el ends here
      
  • ace-window
    header-args: :tangle (expand-file-name "modules/config-ace-window.el" user-emacs-directory)
    
    • header
      ;;; config-ace-window.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables nil t)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'ace-window))
      
    • variables
      (customize-set-variable 'aw-scope 'frame)
      (customize-set-variable 'aw-dispatch-always nil)
      (customize-set-variable 'aw-minibuffer-flag t)
      (customize-set-variable 'aw-keys '(?q ?w ?e ?r ?t ?a ?s ?d ?f))
      (defvar aw-dispatch-alist
        '((?x aw-delete-window "Delete Window")
          (?m aw-swap-window "Swap Windows")
          (?M aw-move-window "Move Window")
          (?c aw-copy-window "Copy Window")
          (?j aw-switch-buffer-in-window "Select Buffer")
          (?n aw-flip-window)
          (?u aw-switch-buffer-other-window "Switch Buffer Other Window")
          (?c aw-split-window-fair "Split Fair Window")
          (?v aw-split-window-vert "Split Vert Window")
          (?b aw-split-window-horz "Split Horz Window")
          (?o delete-other-windows "Delete Other Windows")
          (?? aw-show-dispatch-help))
        "List of actions for `aw-dispatch-default'.")
      
    • config
      (require 'ace-window nil t)
      (set-face-attribute
       'aw-leading-char-face nil
       :foreground "deep sky blue"
       :weight 'bold
       :height 3.0)
      
      (set-face-attribute
       'aw-mode-line-face nil
       :inherit 'mode-line-buffer-id
       :foreground "lawn green")
      
      (ace-window-display-mode t)
      
    • keybinding
      (global-set-key [remap other-window] 'ace-window)
      
      • general

        Since the +config/leader-def is defined only when evil is loaded, evaluate this after evil.

        (with-eval-after-load 'config-general
          (progn
            (require 'general)
            (+config/leader-def
             :states '(normal visual)
             "w0" 'ace-delete-window
             "wd" 'delete-window
             "ww" 'ace-window)))
        
    • Footer
      (provide 'config-ace-window)
      ;;; config-ace-window.el ends here
      
  • perpective
    header-args: :tangle (expand-file-name "modules/config-perspective.el" user-emacs-directory)
    
    • header
      ;;; config-perspective.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'perspective))
      
    • variables
      (setq persp-initial-frame-name "Main")
      (setq persp-state-default-file (expand-file-name "statesave" +emacs-data-dir))
      (customize-set-variable 'persp-mode-prefix-key (kbd "C-c b"))
      
    • config
      (unless (equal persp-mode t)
        (persp-mode))
      
    • keybinding
      (with-eval-after-load 'perspective
        (global-set-key [remap switch-to-buffer] #'persp-switch-to-buffer*)
        (define-key persp-mode-map (kbd "C-c b TAB") 'persp-switch-last))
      
      • general
        (with-eval-after-load 'config-general
          (progn
            (require 'general)
            (+config/leader-def
              :states '(normal visual)
              "TAB" (general-simulate-key "C-c b"
                      :name +perspective-prefix
                      :which-key "Perspective prefix"))))
        
    • hooks
      (unless +config/exwm-enabled
        (add-hook 'emacs-startup-hook (lambda () (persp-state-load persp-state-default-file)))
        (add-hook 'kill-emacs-hook #'persp-state-save))
      
    • Footer
      (provide 'config-perspective)
      ;;; config-perspective.el ends here
      
  • centaur-tabs
    header-args: :tangle (expand-file-name "modules/config-centaur-tabs.el" user-emacs-directory)
    
    • header
      ;;; config-centaur-tabs.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (straight-use-package 'centaur-tabs)
      
    • hook
      (add-hook 'dashboard-mode-hook #'centaur-tabs-local-mode)
      (add-hook 'term-mode-hook #'centaur-tabs-local-mode)
      (add-hook 'calendar-mode-hook #'centaur-tabs-local-mode)
      (add-hook 'org-agenda-mode-hook #'centaur-tabs-local-mode)
      (add-hook 'helpful-mode-hook #'centaur-tabs-local-mode)
      
    • variables
      (setq centaur-tabs-style "rounded"
            centaur-tabs-set-icons t
            centaur-tabs-set-bar 'under
            x-underline-at-descent-line t
            centaur-tabs-gray-out-icons 'buffer
            centaur-tabs-close-button "✕"
            centaur-tabs-set-modified-marker "•"
            centaur-tabs-cycle-scope 'tabs)
      
    • config
      (centaur-tabs-mode t)
      
    • keybinding
      (global-set-key (kbd "C-c t p") 'centaur-tabs-backward)
      (global-set-key (kbd "C-c t C-p") 'centaur-tabs-backward)
      (global-set-key (kbd "C-c t n") 'centaur-tabs-forward)
      (global-set-key (kbd "C-c t C-n") 'centaur-tabs-forward)
      (global-set-key (kbd "C-c t M-p") 'centaur-tabs-backward-group)
      (global-set-key (kbd "C-c t M-n") 'centaur-tabs-forward-group)
      (global-set-key (kbd "C-c t g") 'centaur-tabs-consult-switch-group)
      
    • functions
      ;; buffer groups
      (defun centaur-tabs-buffer-groups ()
        "`centaur-tabs-buffer-groups' control buffers' group rules.
      
         Group centaur-tabs with mode if buffer is derived from
        `eshell-mode' `emacs-lisp-mode' `dired-mode' `org-mode' `magit-mode'.
         All buffer name start with * will group to \"Emacs\".
         Other buffer group by `centaur-tabs-get-group-name' with project name."
        (list
         (cond
          ((memq major-mode '(telega-root-mode
                              telega-chat-mode
                              telega-image-mode
                              telega-webpage-mode
                              telega-edit-file-mode))
           "Telega")
          ((memq major-mode '(notmuch-show-mode
                              notmuch-tree-mode
                              notmuch-hello-mode
                              notmuch-search-mode
                              notmuch-message-mode))
           "Notmuch")
          ((memq major-mode '(erc-mode
                              erc-list-menu-mode
                              erc-track-minor-mode))
           "ERC")
          ((memq major-mode '(emms-mark-mode
                              emms-lyrics-mode
                              emms-browser-mode
                              emms-playlist-mode
                              emms-show-all-mode
                              emms-tag-editor-mode
                              emms-metaplaylist-mode
                              emms-volume-minor-mode
                              emms-browser-search-mode))
           "Emms")
          ((memq major-mode '(elfeed-show-mode
                              elfeed-search-mode))
           "Elfeed")
          ((memq major-mode '(vterm-mode
                              shell-mode
                              term-mode))
           "Term")
          ((or (string-equal "*" (substring (buffer-name) 0 1))
               (memq major-mode '(magit-process-mode
                                  magit-status-mode
                                  magit-diff-mode
                                  magit-log-mode
                                  magit-file-mode
                                  magit-blob-mode
                                  magit-blame-mode
                                  )))
           "Emacs")
          ((derived-mode-p 'prog-mode)
           "Editing")
          ((derived-mode-p 'dired-mode)
           "Dired")
          ((memq major-mode '(helpful-mode
                              help-mode))
           "Help")
          ((memq major-mode '(org-mode
                              org-agenda-clockreport-mode
                              org-src-mode
                              org-agenda-mode
                              org-beamer-mode
                              org-indent-mode
                              org-bullets-mode
                              org-cdlatex-mode
                              org-agenda-log-mode
                              diary-mode))
           "OrgMode")
          (t
           (centaur-tabs-get-group-name (current-buffer))))))
      (setq centaur-tabs--buffer-show-groups t)
      
    • consult integration
      (defun centaur-tabs-consult-switch-group ()
        "Display a list of current buffer groups using Consult."
        (interactive)
        (when (featurep 'consult)
          (require 'consult)
          (centaur-tabs-switch-group
           (consult--read
            (centaur-tabs-get-groups)
            :prompt "Centaur Tabs Groups:"))))
      
    • Footer
      (provide 'config-centaur-tabs)
      ;;; config-centaur-tabs.el ends here
      
  • rainbow-mode
    header-args: :tangle (expand-file-name "modules/config-rainbow-mode.el" user-emacs-directory)
    
    • header
      ;;; config-rainbow-mode.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'rainbow-mode))
      (require 'rainbow-mode)
      
    • hook
      (add-hook 'css-mode-hook #'rainbow-mode)
      
    • function

      From emacs stackexchange:

      ;; turn off word colors
      (defun +rainbow-turn-off-words ()
        "Turn off word colors in rainbow-mode."
        (interactive)
        (font-lock-remove-keywords
         nil
         `(,@rainbow-x-colors-font-lock-keywords
           ,@rainbow-latex-rgb-colors-font-lock-keywords
           ,@rainbow-r-colors-font-lock-keywords
           ,@rainbow-html-colors-font-lock-keywords
           ,@rainbow-html-rgb-colors-font-lock-keywords)))
      ;; turn off hexadecimal colors
      (defun +rainbow-turn-off-hexadecimal ()
        "Turn off hexadecimal colors in rainbow-mode."
        (interactive)
        (font-lock-remove-keywords
         nil
         `(,@rainbow-hexadecimal-colors-font-lock-keywords)))
      ;; TODO: set toggling and keybindings
      
    • Footer
      (provide 'config-rainbow-mode)
      ;;; config-rainbow-mode.el ends here
      
  • rainbow-delimiters
    header-args: :tangle (expand-file-name "modules/config-rainbow-delimiters.el" user-emacs-directory)
    
    • header
      ;;; config-rainbow-delimiters.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'rainbow-delimiters))
      (require 'rainbow-delimiters)
      
    • hook
      (add-hook 'prog-mode-hook 'rainbow-delimiters-mode)
      (add-hook 'org-mode-hook 'rainbow-delimiters-mode)
      
    • Footer
      (provide 'config-rainbow-delimiters)
      ;;; config-rainbow-delimiters.el ends here
      
  • hl-todo
    header-args: :tangle (expand-file-name "modules/config-hl-todo.el" user-emacs-directory)
    
    • header
      ;;; config-hl-todo.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (straight-use-package 'hl-todo)
      (require 'hl-todo)
      
    • config
      (global-hl-todo-mode)
      ;;(add-hook 'prog-mode-hook hl-todo-mode-hook)
      ;;(add-hook 'yaml-mode-hook hl-todo-mode-hook)
      
    • Footer
      (provide 'config-hl-todo)
      ;;; config-hl-todo.el ends here
      
  • diminish
    header-args: :tangle (expand-file-name "modules/config-diminish.el" user-emacs-directory)
    
    • header
      ;;; config-diminish.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'diminish))
      (require 'diminish)
      
    • config
      (progn
        (with-eval-after-load 'rainbow-mode
          (diminish 'rainbow-mode))
        (diminish 'text-scale-mode)
        (with-eval-after-load 'eldoc
          (diminish 'eldoc-mode))
        (with-eval-after-load 'subword
          (diminish 'subword-mode))
        (with-eval-after-load 'flycheck
          (diminish 'flycheck-mode))
        (with-eval-after-load 'projectile
          (diminish 'projectile-mode))
        (with-eval-after-load 'yasnippet
          (diminish 'yas-global-mode)
          (diminish 'yas-extra-mode)
          (diminish 'yas-minor-mode))
        (with-eval-after-load 'which-key
          (diminish 'which-key-mode))
        (with-eval-after-load 'desktop-environment
          (diminish 'desktop-environment-mode))
        (with-eval-after-load 'paredit
          (diminish 'paredit-mode))
        (with-eval-after-load 'theme-magic
          (diminish 'theme-magic-export-theme-mode))
        (with-eval-after-load 'git-gutter
          (diminish 'git-gutter-mode))
        (with-eval-after-load 'smartparens
          (diminish 'smartparens-mode))
        (with-eval-after-load 'evil-collection-unimpaired
          (diminish 'evil-collection-unimpaired-mode)))
      
    • Footer
      (provide 'config-diminish)
      ;;; config-diminish.el ends here
      
  • dashboard
    header-args: :tangle (expand-file-name "modules/config-dashboard.el" user-emacs-directory)
    
    • header
      ;;; config-dashboard.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'dashboard))
      (require 'dashboard)
      
    • config
      (dashboard-setup-startup-hook)
      
    • variables
      ;;(setq initial-buffer-choice (lambda () (get-buffer "*dashboard*")))
      (setq dashboard-center-content t)
      (setq dashboard-items '((recents  . 5)
                              (bookmarks . 5)
                              (projects . 5)
                              (agenda . 5)
                              (registers . 5)))
      (setq dashboard-set-heading-icons t)
      (setq dashboard-set-file-icons t)
      (setq dashboard-set-navigator t)
      (setq dashboard-set-init-info t)
      (setq dashboard-week-agenda t)
      (setq dashboard-items-default-length 40)
      (if (featurep 'projectile)
          (setq dashboard-projects-backend 'projectile)
        (setq dashboard-projects-backend 'project-el))
      
    • Footer
      (provide 'config-dashboard)
      ;;; config-dashboard.el ends here
      
  • alert
    header-args: :tangle (expand-file-name "modules/config-alert.el" user-emacs-directory)
    
    • header
      ;;; config-alert.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'alert))
      
    • variable
      (customize-set-variable 'alert-default-style #'notifications)
      
    • Footer
      (provide 'config-alert)
      ;;; config-alert.el ends here
      
  • smartparens
    header-args: :tangle (expand-file-name "modules/config-smartparens.el" user-emacs-directory)
    
    • header
      ;;; config-smartparens.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'smartparens))
      
    • config
      ;; disable `electric-pair-mode'
      ;; (electric-pair-mode 0)
      (smartparens-global-mode 1)
      (require 'smartparens-config)
      (setq sp-highlight-pair-overlay nil
            sp-highlight-wrap-overlay nil
            sp-highlight-wrap-tag-overlay nil)
      ;; Silence some harmless but annoying echo-area spam
      (dolist (key '(:unmatched-expression :no-matching-tag))
        (setf (alist-get key sp-message-alist) nil))
      (sp-local-pair '(minibuffer-mode minibuffer-inactive-mode) "'" nil :actions nil)
      (sp-local-pair '(minibuffer-mode minibuffer-inactive-mode) "`" nil :actions nil)
      (sp-local-pair '(emacs-lisp-mode lisp-mode scheme-mode) "'" nil :actions nil)
      (add-hook 'minibuffer-setup-hook 'turn-on-smartparens-strict-mode)
      
    • custom org-mode-hook
      (defun +config/sp-mode-org-hook ()
        (when (org-in-src-block-p)
          (sp-local-pair 'org-mode "'" nil :actions nil)))
      (add-hook 'org-mode-hook '+config/sp-mode-org-hook)
      
    • Footer
      (provide 'config-smartparens)
      ;;; config-smartparens.el ends here
      
  • treemacs
    header-args: :tangle (expand-file-name "modules/config-treemacs.el" user-emacs-directory)
    
    • header
      ;;; config-treemacs.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (straight-use-package 'treemacs)
      (straight-use-package 'treemacs-projectile)
      (straight-use-package 'treemacs-magit)
      (straight-use-package 'treemacs-icons-dired)
      (straight-use-package 'treemacs-perspective)
      (straight-use-package 'treemacs-all-the-icons)
      (straight-use-package 'project)
      
    • Variables
      (customize-set-variable 'treemacs-persist-file (expand-file-name ".treemacs-persist" +emacs-data-dir))
      
    • Functions
      (require 'ace-window)
      (defun +config/treemacs-back-and-forth ()
        (interactive)
        (if (treemacs-is-treemacs-window-selected?)
            (ace-flip-window)
          (treemacs-select-window)))
      
    • Keybinding

      To switch from a normal window to a treemacs window add C-u before the keybinding (C-u C-x o).

      (global-set-key (kbd "C-x M-SPC") 'treemacs)
      
      • general
        (with-eval-after-load 'config-general
          (progn
            (require 'general)
            (+config/leader-def
             :states '(normal visual)
             "t" '(:ignore t :which-key "Terminal/Treemacs prefix")
             "t SPC" 'treemacs)))
        
    • Misc
      ;; projectile
      (with-eval-after-load 'projectile
        (require 'treemacs-projectile))
      ;; dired
      (add-hook 'dired-mode-hook #'treemacs-icons-dired-enable-once)
      ;; magit
      (with-eval-after-load 'magit
        (require 'treemacs-magit))
      ;; perspective
      (with-eval-after-load 'perspective
        (progn
          (require 'treemacs-perspective)
          (treemacs-set-scope-type 'Perspectives)))
      ;; theme
      (with-eval-after-load 'treemacs
        (progn
          (treemacs-load-theme 'doom-atom)
          (treemacs-indent-guide-mode 1)))
      
    • Footer
      (provide 'config-treemacs)
      ;;; config-treemacs.el ends here
      
  • vertico-posframe
    header-args: :tangle (expand-file-name "modules/config-vertico-posframe.el" user-emacs-directory)
    
    • header
      ;;; config-vertico-posframe.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (with-eval-after-load 'vertico
        (straight-use-package 'vertico-posframe))
      
    • config
      (with-eval-after-load 'vertico
        (require 'vertico-posframe)
        (vertico-posframe-mode 1))
      (when (featurep 'corfu)
        (setq corfu-preview-current nil
              corfu-echo-documentation nil))
      
    • Footer
      (provide 'config-vertico-posframe)
      ;;; config-vertico-posframe.el ends here
      

Footer

(provide 'config-defaults-ui)
;;; config-defaults-ui.el ends here

Default Editings

header-args: :tangle (expand-file-name "modules/config-defaults-editings.el" user-emacs-directory)
;;; config-defaults-editings.el --- Summary -*- lexical-binding: t -*-
;;; Commentary:
;; This file is auto-generated from `config.org'
;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
;;; Code:
(require 'config-defaults-variables)

Escape cancels all

(global-set-key (kbd "<escape>") 'keyboard-escape-quit)

Enable show-paren-mode

(show-paren-mode)

Don’t blink on matching parenthesis

(setq blink-matching-paren nil)

Don’t stretch the cursor

(setq x-stretch-cursor nil)

Free up fringes

(setq indicate-buffer-boundaries nil
      indicate-empty-lines nil)

Don’t use gui dialog boxes

(setq use-dialog-box nil)

Disable tooltip

(when (bound-and-true-p tooltip-mode)
  (tooltip-mode -1))
(setq x-gtk-use-system-tooltips nil)

Enable electric-pair-mode

(electric-pair-mode 1)

enable electric-indent-mode

(electric-indent-mode 1)

custom hook for org-mode src-code-block

(defun +config/electric-indent-org-hook ()
  (when (org-in-src-block-p) (electric-indent-mode 0)))
(add-hook 'org-mode-hook '+config/electric-indent-org-hook)

disable auto pairing for < >

(add-function :before-until electric-pair-inhibit-predicate
              (lambda (c) (eq c ?<   ;; >
                              )))

Use spaces instead of tabs

(setq-default indent-tabs-mode nil
              tab-width 2
              tab-always-indent nil)
(setq tabify-regexp "^\t* [ \t]+")

Use “y” and “n” to confirm/negate prompt instead of “yes” and “no”.

(advice-add #'yes-or-no-p :override #'y-or-n-p)
(setq y-or-n-p-use-read-key t)

Keep the cursor out of the read-only portions of the minibuffer

(setq minibuffer-prompt-properties '(read-only t intangible t cursor-intangible t face minibuffer-prompt))
(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)

Don’t save duplicates in kill-ring

(customize-set-variable 'kill-do-not-save-duplicates t)

Better support for files with long lines.

(setq-default bidi-paragraph-direction 'left-to-right)
(setq-default bidi-inhibit-bpa t)
(global-so-long-mode 1)

Make shebang (#!) file executable when saved.

(add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p)

Remove text in active region if inserting text.

(delete-selection-mode 1)

Mouse middle-click yanks where the point is, not where the mouse is.

(setq mouse-yank-at-point t)

Delete trailing whitespace on save.

(add-hook 'before-save-hook 'delete-trailing-whitespace)

Enable whitespace-mode

(unless (or (eq major-mode 'fundamental-mode)
            (bound-and-true-p global-whitespace-mode)
            (null buffer-file-name))
  (require 'whitespace)
  (setq whitespace-line-column nil
        whitespace-style
        '(face indentation tabs tab-mark spaces space-mark newline newline-mark
               trailing lines-tail)
        whitespace-display-mappings
        '((tab-mark ?\t [?› ?\t])
          (newline-mark ?\n [?¬ ?\n])
          (space-mark ?\  [?·] [?.]))))

Easily navigate sillycased words.

(global-subword-mode 1)

Apropos commands will search more extensively.

(require 'apropos)
(setq apropos-do-all t)

Turn on recentf-mode

(add-hook 'after-init-hook #'recentf-mode)
(setq recentf-save-file (expand-file-name "recentf" +emacs-data-dir))
(setq recentf-max-saved-items 100) ;; just 20 is too recent

Enable savehist-mode for an command history

(savehist-mode 1)
(setq history-length 1000)
(setq savehist-file (expand-file-name "history" +emacs-backup-directory))
(setq savehist-additional-variables
      '(kill-ring
        search-ring
        register-alist
        mark-ring
        global-mark-ring
        regexp-search-ring))
(setq savehist-save-minibuffer-history t
      savehist-autosave-interval nil)

Enable save-place-mode

(setq save-place-mode 1)
(setq save-place-file (expand-file-name "save-place.el" +emacs-data-dir))

abbrev-mode

(setq abbrev-file-name (expand-file-name "abbrev_defs" +emacs-data-dir))

comint

(eval-after-load 'comint
  (setq comint-prompt-read-only t
        comint-buffer-maximum-size 2048))

ediff

(eval-after-load 'ediff
  (setq ediff-diff-options "-w"
        ediff-split-window-function #'split-window-horizontally
        ediff-window-setup-function #'ediff-setup-windows-plain))

hl-line

From doom.

(defvar global-hl-line-modes
  '(prog-mode text-mode conf-mode special-mode
              org-agenda-mode dired-mode)
  "What modes to enable `hl-line-mode' in.")

(define-globalized-minor-mode global-hl-line-mode hl-line-mode
  (lambda ()
    (and (cond (hl-line-mode nil)
               ((null global-hl-line-modes) nil)
               ((eq global-hl-line-modes t))
               ((eq (car global-hl-line-modes) 'not)
                (not (derived-mode-p global-hl-line-modes)))
               ((apply #'derived-mode-p global-hl-line-modes)))
         (hl-line-mode +1))))

paren

(eval-after-load 'paren
  (setq show-paren-delay 0.1
        show-paren-highlight-openparen t
        show-paren-when-point-inside-paren t
        show-paren-when-point-in-periphery t))

auto-insert mode

  • auto-insert-directory
    (setq auto-insert-directory (expand-file-name "auto-insert/" +emacs-data-dir))
    
  • TODO auto-insert-alist
    • State “TODO” from [2022-03-22 Tue 16:45]

Move files to trash when deleting.

(setq delete-by-moving-to-trash t)

unbind <menu> key and <execute> key

(global-set-key (kbd "<menu>") 'nil)
(global-set-key (kbd "<execute>") 'nil)

Additional Packages

  • multiple-cursors
    header-args: :tangle (expand-file-name "modules/config-multiple-cursors.el" user-emacs-directory)
    
    • header
      ;;; config-multiple-cursors.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'multiple-cursors))
      
    • variable
      (setq mc/list-file (expand-file-name ".mc-lists.el" +emacs-data-dir))
      (global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)
      (global-set-key (kbd "C-c M->") 'mc/mark-next-like-this)
      (global-set-key (kbd "C-c M-<") 'mc/mark-previous-like-this)
      (global-set-key (kbd "C-c M-a") 'mc/mark-all-like-this)
      
    • Footer
      (provide 'config-multiple-cursors)
      ;;; config-multiple-cursors.el ends here
      
  • yasnippet
    header-args: :tangle (expand-file-name "modules/config-yasnippet.el" user-emacs-directory)
    
    • header
      ;;; config-yasnippet.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'yasnippet)
        (straight-use-package 'yasnippet-snippets))
      
    • variable
      (setq yas-snippet-dir `(,(expand-file-name "yasnippet/snippets/" +emacs-data-dir)))
      (eval-after-load 'yasnippet
        (make-directory (expand-file-name "yasnippet/snippets/" +emacs-data-dir) :parents))
      (yas-global-mode 1)
      
    • keybinding
      (global-set-key (kbd "C-c y i") 'yas-insert-snippet)
      (global-set-key (kbd "C-c y d") 'yas-describe-tables)
      
    • consult integration
      (when (featurep 'consult)
        (straight-use-package 'consult-yasnippet))
      
    • Footer
      (provide 'config-yasnippet)
      ;;; config-yasnippet.el ends here
      
  • geiser
    header-args: :tangle (expand-file-name "modules/config-geiser.el" user-emacs-directory)
    
    • header
      ;;; config-geiser.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'geiser)
        (straight-use-package 'geiser-guile)
        (straight-use-package 'geiser-racket))
      
    • config
      (eval-after-load 'geiser
        `(make-directory ,(expand-file-name "geiser/" +emacs-data-dir) t))
      (setq geiser-repl-history-filename     (expand-file-name "geiser/repl-history" +emacs-data-dir))
      (require 'geiser-impl)
      (add-to-list 'geiser-implementations-alist '((regexp "\\.scm$") guile))
      
    • Footer
      (provide 'config-geiser)
      ;;; config-geiser.el ends here
      
  • yaml-mode
    header-args: :tangle (expand-file-name "modules/config-yaml-mode.el" user-emacs-directory)
    
    • header
      ;;; config-yaml-mode.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'yaml-mode))
      (require 'yaml-mode)
      
    • hook
      (add-to-list 'auto-mode-alist '("'\\.yaml\\'" . yaml-mode))
      (add-to-list 'auto-mode-alist '("'\\.yml\\'" . yaml-mode))
      (add-hook 'yaml-mode-hook
                #'(lambda ()
                    (define-key yaml-mode-map "\C-m" 'newline-and-indent)))
      
    • Footer
      (provide 'config-yaml-mode)
      ;;; config-yaml-mode.el ends here
      
  • toml-mode
    header-args: :tangle (expand-file-name "modules/config-toml-mode.el" user-emacs-directory)
    
    • header
      ;;; config-toml-mode.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'toml-mode))
      
    • config
      (add-to-list 'auto-mode-alist '("'\\.toml\\'" . toml-mode))
      
    • Footer
      (provide 'config-toml-mode)
      ;;; config-toml-mode.el ends here
      
  • nix-mode
    header-args: :tangle (expand-file-name "modules/config-nix-mode.el" user-emacs-directory)
    
    • header
      ;;; config-nix-mode.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'nix-mode))
      
    • config
      (add-to-list 'auto-mode-alist '("\\.nix\\'" . nix-mode))
      
    • Footer
      (provide 'config-nix-mode)
      ;;; config-nix-mode.el ends here
      
  • toml-mode
    header-args: :tangle (expand-file-name "modules/config-toml-mode.el" user-emacs-directory)
    
    • header
      ;;; config-toml-mode.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'toml-mode))
      
    • config
      (add-to-list 'auto-mode-alist '("'\\.toml\\'" . toml-mode))
      
    • Footer
      (provide 'config-toml-mode)
      ;;; config-toml-mode.el ends here
      
  • nginx-mode
    header-args: :tangle (expand-file-name "modules/config-nginx-mode.el" user-emacs-directory)
    
    • header
      ;;; config-nginx-mode.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'nginx-mode))
      
    • config
      (require 'nginx-mode)
      (add-to-list 'auto-mode-alist '("/nginx/sites-\\(?:available\\|enabled\\)/" . nginx-mode))
      
    • Footer
      (provide 'config-nginx-mode)
      ;;; config-nginx-mode.el ends here
      
  • markdown-mode
    header-args: :tangle (expand-file-name "modules/config-markdown-mode.el" user-emacs-directory)
    
    • header
      ;;; config-markdown-mode.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'markdown-mode))
      
    • config
      (autoload 'markdown-mode "markdown-mode"
        "Major mode for editing Markdown files" t)
      (add-to-list 'auto-mode-alist
                   '("\\.\\(?:md\\|markdown\\|mkd\\|mdown\\|mkdn\\|mdwn\\)\\'" . markdown-mode))
      
      (autoload 'gfm-mode "markdown-mode"
        "Major mode for editing GitHub Flavored Markdown files" t)
      (add-to-list 'auto-mode-alist '("README\\.md\\'" . gfm-mode))
      
    • Footer
      (provide 'config-markdown-mode)
      ;;; config-markdown-mode.el ends here
      
  • visual-regexp
    header-args: :tangle (expand-file-name "modules/config-visual-regexp.el" user-emacs-directory)
    
    • header
      ;;; config-visual-regexp.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'visual-regexp))
      
    • config
      (require 'visual-regexp)
      
    • keybinding
      (define-key global-map (kbd "C-c R") 'vr/replace)
      (define-key global-map (kbd "C-c q") 'vr/query-replace)
      ;; if you use multiple-cursors, this is for you:
      
    • multiple-cursors integration
      (when (featurep 'config-multiple-cursors)
        (define-key global-map (kbd "C-c M-m") 'vr/mc-mark))
      
    • Footer
      (provide 'config-visual-regexp)
      ;;; config-visual-regexp.el ends here
      
  • undo-fu
    header-args: :tangle (expand-file-name "modules/config-undo-fu.el" user-emacs-directory)
    
    • header
      ;;; config-undo-fu.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'undo-fu)
        (straight-use-package 'undo-fu-session))
      
    • config
      (require 'undo-fu)
      (setq undo-limit 400000
            undo-strong-limit 3000000
            undo-outer-limit 48000000)
      (setq undo-fu-session-directory (expand-file-name "undo-fu-session/" +emacs-data-dir))
      
    • keybinding
      (global-unset-key (kbd "C-z")) ; previously `suspend-frame'
      (unless (featurep' evil)
        (global-set-key (kbd "C-z") 'undo-fu-only-undo)
        (global-set-key (kbd "C-S-z") 'undo-fu-only-redo))
      (setq undo-fu-session-incompatible-files '("\\.gpg$" "/COMMIT_EDITMSG\\'" "/git-rebase-todo\\'"))
      (global-undo-fu-session-mode)
      
    • evil integration
      (with-eval-after-load 'evil
        (customize-set-variable 'evil-undo-system 'undo-fu))
      
    • Footer
      (provide 'config-undo-fu)
      ;;; config-undo-fu.el ends here
      
  • block-nav
    header-args: :tangle (expand-file-name "modules/config-block-nav.el" user-emacs-directory)
    
    ;;; config-block-nav.el --- Summary -*- lexical-binding: t -*-
    ;;; Commentary:
    ;; This file is auto-generated from `config.org'
    ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
    ;;; Code:
    
    • package
      (straight-use-package 'block-nav)
      
    • variables
      (setf block-nav-move-skip-shallower t
            block-nav-center-after-scroll t)
      
    • keybindings
      • hydra
        (when (featurep 'hydra)
          (defhydra hydra-block-nav (global-map "C-c b"
                                     :pre (linum-mode 1)
                                     :post (linum-mode -1))
            "block-nav"
            ("M-p" block-nav-previous-indentation-level "previous indent")
            ("M-n" block-nav-next-indentation-level "next indent")
            ("p" block-nav-previous-block "previous block")
            ("n" block-nav-next-block "next block")))
        
    • Footer
      (provide 'config-block-nav)
      ;;; config-block-nav.el ends here
      
  • rust-mode
    header-args: :tangle (expand-file-name "modules/config-rust-mode.el" user-emacs-directory)
    
    • header
      ;;; config-rust-mode.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'rust-mode))
      
    • config
      (require 'rust-mode)
      (add-hook 'rust-mode-hook
                (lambda () (prettify-symbols-mode)))
      (add-hook 'rust-mode-hook
                (lambda () (setq indent-tabs-mode nil)))
      (add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-mode))
      
    • Footer
      (provide 'config-rust-mode)
      ;;; config-rust-mode.el ends here
      
  • ansible
    header-args: :tangle (expand-file-name "modules/config-ansible.el" user-emacs-directory)
    
    • header
      ;;; config-ansible.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (straight-use-package 'ansible)
      (straight-use-package 'ansible-doc)
      
    • config
      (require 'ansible)
      (add-hook 'yaml-mode-hook #'(lambda () (ansible 1)))
      (add-hook 'ansible-hook 'ansible-auto-decrypt-encrypt)
      (setq ansible-section-face 'font-lock-variable-name-face
            ansible-task-label-face 'font-lock-doc-face)
      ;; set keybinding in yaml-mode since I usually set secrets in variable file
      (define-key yaml-mode-map (kbd "C-c a d") 'ansible-decrypt-buffer)
      (define-key yaml-mode-map (kbd "C-c a e") 'ansible-encrypt-buffer)
      
    • Footer
      (provide 'config-ansible)
      ;;; config-ansible.el ends here
      
  • jinja2-mode
    header-args: :tangle (expand-file-name "modules/config-jinja2-mode.el" user-emacs-directory)
    
    • header
      ;;; config-jinja2-mode.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (straight-use-package 'jinja2-mode)
      
    • config
      (setq jinja2-enable-indent-on-save nil)
      (add-to-list 'auto-mode-alist '("'\\.j2$\\'" . jinja2-mode))
      
    • Footer
      (provide 'config-jinja2-mode)
      ;;; config-jinja2-mode.el ends here
      
  • hydra
    header-args: :tangle (expand-file-name "modules/config-hydra.el" user-emacs-directory)
    
    • header
      ;;; config-hydra.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (straight-use-package 'hydra)
      (require 'hydra)
      
    • hydra remapping
      • yank
        (cond ((featurep 'consult)
               (defhydra hydra-yank-pop ()
                 "yank"
                 ("C-y" yank nil)
                 ("M-y" yank-pop nil)
                 ("y" (yank-pop 1) "next")
                 ("Y" (yank-pop -1) "prev")
                 ("l" consult-yank-from-kill-ring "list" :color blue)))
              ((featurep 'helm)
               (defhydra hydra-yank-pop ()
                 "yank"
                 ("C-y" yank nil)
                 ("M-y" yank-pop nil)
                 ("y" (yank-pop 1) "next")
                 ("Y" (yank-pop -1) "prev")
                 ("l" helm-show-kill-ring "list" :color blue)))
              (t
               (defhydra hydra-yank-pop ()
                 "yank"
                 ("C-y" yank nil)
                 ("M-y" yank-pop nil)
                 ("y" (yank-pop 1) "next")
                 ("Y" (yank-pop -1) "prev"))))
        (global-set-key [remap yank-pop] #'hydra-yank-pop/yank-pop)
        (global-set-key [remap yank] #'hydra-yank-pop/yank)
        
      • TODO movement
        • Note taken on [2022-06-08 Wed 02:22]
          Find a way to avoid conflict
        • State “TODO” from [2022-06-08 Wed 02:22]

        This conflict with minibuffer

        (global-set-key
         (kbd "C-n")
         (defhydra hydra-move
           (:body-pre (next-line))
           "move"
           ("n" next-line)
           ("p" previous-line)
           ("f" forward-char)
           ("b" backward-char)
           ("a" beginning-of-line)
           ("e" move-end-of-line)
           ("v" scroll-up-command)
           ;; Converting M-v to V here by analogy.
           ("V" scroll-down-command)
           ("l" recenter-top-bottom)))
        
    • Footer
      (provide 'config-hydra)
      ;;; config-hydra.el ends here
      
  • general
    header-args: :tangle (expand-file-name "modules/config-general.el" user-emacs-directory)
    
    • header
      ;;; config-general.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (straight-use-package 'general)
      (require 'general)
      (require 'which-key)
      (when (featurep 'config-projectile)
        (require 'projectile))
      
    • variables
      (defconst +general-leader "SPC")
      (defconst +general-local-leader "C-c SPC")
      

      For frequently used prefix keys, the user can create a custom definer with a default :prefix, using a variable is not necessary, but it may be useful if you want to experiment with different prefix keys and aren’t using general-create-definer.

      #+begin_src emacs-lisp
        (general-create-definer +config/leader-def
          ;; :prefix my-leader
          ;; or without a variable
          :prefix "C-c")
      #+end_src
      

      Then we can use +config/leader-def in

      • Global keybinding

        #+begin_src emacs-lisp
          (+config/leader-def
           "a" 'org-agenda
           "b" 'counsel-bookmark
           "c" 'org-capture)
        #+end_src
        
      • Local keybinding

        #+begin_src emacs-lisp
          (+config/leader-def
           :keymaps 'clojure-mode-map
           ;; bind "C-c C-l"
           "C-l" 'cider-load-file
           "C-z" 'cider-switch-to-repl-buffer)
          ;; `general-create-definer' creates wrappers around `general-def', so
          ;; `define-key'-like syntax is also supported
          (+config/leader-def clojure-mode-map
                         "C-l" 'cider-load-file
                         "C-z" 'cider-switch-to-repl-buffer)
        #+end_src
        
    • general definer
      (require 'general)
      (when (featurep 'evil)
        (general-evil-setup t))
      (general-create-definer +config/leader-def
        :prefix +general-leader)
      (when (featurep 'evil)
        (general-create-definer +config/local-leader-def
          :prefix +general-local-leader))
      
    • Set title for which-key
      (+config/leader-def
        :states '(normal visual)
        "" '(nil :which-key "+config/leader-def root")
        "SPC" 'execute-extended-command
        ":" 'eval-expression
        "b" '(:ignore t :which-key "Buffers Prefix")
        "f" '(:ignore t :which-key "Files Prefix")
        "F" '(:ignore t :which-key "Frames Prefix")
        "g" '(:ignore t :which-key ("G-key" . "Git Prefix"))
        "m" '(:ignore t :which-key "Mail Prefix")
        "o" '(:ignore t :which-key "Org-mode Prefix")
        "s" '(:ignore t :which-key "Search prefix")
        "t" '(:ignore t :which-key "Terminal prefix")
        "w" '(:ignore t :which-key "Window Prefix")
        "/" '(:ignore t :which-key "Navigation Prefix"))
      
    • keybindings
      • help
        (general-define-key
         :states '(normal visual)
         :prefix +general-leader
         "h" (general-simulate-key "C-h"
               :name +general-simulates-C-h
               :docstring "Simulate C-h in normal and visual state with SPC-h."
               :which-key "Simulate C-h"))
        
      • files
        (+config/leader-def
          :states '(normal visual)
          "ff" 'find-file
          "fw" 'write-file)
        
      • buffers
        (+config/leader-def
          :states '(normal visual)
          "bb" 'switch-to-buffer
          "br" 'rename-buffer
          "bd" 'kill-current-buffer
          "bi" 'ibuffer
          "bk" 'kill-buffer
          "br" 'revert-buffer
          "bs" 'save-buffer
          "bS" 'save-some-buffers
          "b[" 'previous-buffer
          "b]" 'next-buffer)
        
      • window
        • builtin functions.
          (+config/leader-def
            :states '(normal visual)
            "w1" 'delete-other-windows
            "wo" 'delete-other-windows
            "w=" 'balance-windows
            "w+" 'maximize-window
            "w-" 'minimize-window)
          
          (general-define-key
           :keymaps '(normal visual)
           :prefix +general-leader
           "w^" '(enlarge-window :properties (:repeat t))
           "w{" '(shrink-window-horizontally :properties (:repeat t))
           "w}" '(enlarge-window-horizontally :properties (:repeat t)))
          
        • only bind this when evil not loaded
          (unless (featurep 'evil)
            (+config/leader-def
              :states '(normal visual)
              "ws" 'split-window-right
              "wv" 'split-window-below))
          
        • search
          • builtin
            (+config/leader-def
              :states '(normal visual)
              "sg" 'grep-find
              "si" 'imenu)
            
        • frames
          (+config/leader-def
            :states '(normal visual)
            "Fd" 'delete-frame
            "Ff" 'make-frame
            "fo" 'other-frame)
          
        • navigation
          • builtin
            • registers
              (+config/leader-def
                :states '(normal visual)
                "/r" '(:ignore t :which-key "Register prefix")
                "/r SPC" 'point-to-register
                "/r +" 'increment-register
                "/r f" 'frameset-to-register
                "/r n" 'number-to-register
                "/r i" 'insert-register
                "/r s" 'copy-to-register
                "/r j" 'jump-to-register)
              
            • bookmark
              (+config/leader-def
                :states '(normal visual)
                "/b" '(:ignore t :which-key "Bookmark prefix")
                "/bb" 'bookmark-jump
                "/bm" 'bookmark-set)
              
    • Footer
      (provide 'config-general)
      ;;; config-general.el ends here
      
  • evil
    header-args: :tangle (expand-file-name "modules/config-evil.el" user-emacs-directory)
    
    • header
      ;;; config-evil.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (straight-use-package 'evil)
      (straight-use-package 'evil-collection)
      
    • variables
      • move cursor beyond end of line

        This is what I’ve grown accustomed in Emacs.

        (customize-set-variable 'evil-move-beyond-eol t)
        (customize-set-variable 'evil-split-window-below t)
        (customize-set-variable 'evil-vsplit-window-right t)
        (customize-set-variable 'evil-start-of-line t)
        (customize-set-variable 'evil-want-keybinding nil)
        (customize-set-variable 'evil-want-integration t)
        
    • hooks
      (add-hook 'with-editor-mode-hook 'evil-insert-state)
      
    • dependencies
      (require 'config-undo-fu)
      (require 'evil)
      (evil-mode 1)
      (when (require 'evil-collection nil t)
        (evil-collection-init))
      
    • keybinding
      • general
        • window
          (with-eval-after-load 'general
            (+config/leader-def
              :states '(normal visual)
              "wW" 'evil-window-prev ; C-w W
              "wh" 'evil-window-left ; C-w h
              "wH" 'evil-window-top-left ; C-w C-t
              "wl" 'evil-window-right ; C-w l
              "wL" 'evil-window-bottom-right ; C-w C-b
              "wj" 'evil-window-down ; C-w j
              "wk" 'evil-window-up ; C-w k
              "wR" 'evil-window-rotate-upwards ; C-w R
              "wr" 'evil-window-rotate-downwards ; C-w r
              "ws" 'evil-window-split ; C-w r
              "wv" 'evil-window-vsplit ; C-w r
              "wv" 'evil-window-vsplit ; C-w r
              ))
          
        • buffer
          (with-eval-after-load 'general
            (+config/leader-def
              :states '(normal visual)
              "bo" 'evil-buffer))
          
        • avoid conflict with ace-window
          (unless (featurep 'ace-window)
            (+config/leader-def
              :states '(normal visual)
              "w0" 'evil-window-delete ; C-w C-c
              "wd" 'evil-window-delete ; C-w C-c
              "ww" 'evil-window-next ; C-w C-w
              ))
          
    • Footer
      (provide 'config-evil)
      ;;; config-evil.el ends here
      
  • aggressive-indent-mode
    header-args: :tangle (expand-file-name "modules/config-aggressive-indent-mode.el" user-emacs-directory)
    
    • header
      ;;; config-aggressive-indent-mode.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (straight-use-package 'aggressive-indent)
      (require 'aggressive-indent)
      
    • config
      (add-hook 'emacs-lisp-mode-hook #'aggressive-indent-mode)
      (add-hook 'css-mode-hook #'aggressive-indent-mode)
      
    • Footer
      (provide 'config-aggressive-indent-mode)
      ;;; config-aggressive-indent-mode.el ends here
      

Footer

(provide 'config-defaults-editings)
;;; config-defaults-editings.el ends here

Default Org Configurations

header-args: :tangle (expand-file-name "modules/config-defaults-org.el" user-emacs-directory)
;;; config-defaults-org.el --- Summary -*- lexical-binding: t -*-
;;; Commentary:
;; This file is auto-generated from `config.org'
;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
;;; Code:
(require 'config-defaults-variables)
(require 'org)

This file stores the common org-mode configuration.

load org-contrib

(when (featurep 'straight)
  (unless +config/is-guix-system
    (straight-use-package 'org-contrib)))

Sets the default directories

(progn
  `(make-directory ,(expand-file-name "org/" +emacs-data-dir) t)
  (setq org-clock-persist-file (expand-file-name "org/clock-persist.el" +emacs-data-dir))
  (setq org-id-locations-file (expand-file-name "org/id-locations.el" +emacs-data-dir))
  (setq org-persist-directory (expand-file-name "org/persist/" +emacs-data-dir))
  (unless (file-directory-p org-persist-directory)
    (make-directory org-persist-directory :parents))
  (setq org-publish-timestamp-directory  (expand-file-name "org/timestamps/" +emacs-data-dir))
  (setq org-generic-id-locations-file (expand-file-name ".org-generic-id-locations" +emacs-data-dir)))

org-structure-template-alist

This is an alist of keys and block types.

(require 'org-tempo)
(add-to-list 'org-modules 'org-tempo t)
(add-to-list 'org-structure-template-alist '("sh" . "src sh"))
(add-to-list 'org-structure-template-alist '("lisp" . "src lisp"))
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
(add-to-list 'org-structure-template-alist '("sc" . "src scheme"))
(add-to-list 'org-structure-template-alist '("ts" . "src typescript"))
(add-to-list 'org-structure-template-alist '("py" . "src python"))
(add-to-list 'org-structure-template-alist '("go" . "src go"))
(add-to-list 'org-structure-template-alist '("yaml" . "src yaml"))
(add-to-list 'org-structure-template-alist '("json" . "src json"))

Startup variables

(setq org-startup-truncated nil
      org-startup-indented nil
      org-startup-align-all-tables t
      org-startup-with-inline-images t
      org-startup-with-latex-preview t
      org-hide-block-startup t)

sound and notifications

(setq org-clock-sound t)
(setq org-show-notification-handler "notify-send")

hide leading stars

(setq org-hide-leading-stars t)

adapt indentation

(setq org-adapt-indentation t)
(require 'org-indent)
(org-indent-mode 1)

org-priorities

(setq org-highest-priority ?A
      org-lowest-priority ?C
      org-default-priority ?C)
(setq org-priority-faces '((?A . (:foreground "#dc322f" :weight bold))
                           (?B . (:foreground "#fdf6e3"))
                           (?C . (:foreground "#859900"))))

org-protocol

(require 'org-protocol)

fontify

(setq org-fontify-quote-and-verse-blocks t
      org-fontify-todo-headline t)

footnote

(setq org-footnote-auto-adjust t)

invisible edits

(setq org-catch-invisible-edits 'smart)

don’t hide emphasis-marker

It’s kinda ugly but makes editing easy.

(setq org-hide-emphasis-markers nil)

images

(setq org-image-actual-width nil)

links

Set to relative path

(setq org-link-file-path-type 'relative)

org-directory

(unless (boundp 'org-directory)
  (customize-set-variable 'org-directory (expand-file-name "Documents/org/" (getenv "HOME"))))

org-agenda

(require 'org-agenda)
(setq org-agenda-files (list org-directory)
      org-agenda-span 'day
      org-agenda-window-setup (quote current-window)
      org-agenda-skip-deadline-prewarning-if-scheduled 'pre-scheduled
      org-agenda-include-diary t
      org-clock-persist 'history)

org-capture

(defvar +org-capture-todo-file "todo.org"
  "Default target for todo entries.
              Relative to `org-directory', unless it is absolute.")

(defun +org-capture-todo-file ()
  "Expand `+org-capture-todo-file' from `org-directory'.
              If it is an absolute path return `+org-capture-todo-file' verbatim."
  (expand-file-name +org-capture-todo-file org-directory))

(defvar +org-capture-notes-file "notes.org"
  "Default target for storing notes.
Used as a fall back file for org-capture.el, for templates that do not specify a
target file. Is relative to `org-directory', unless it is absolute.")

(defun +org-capture-notes-file ()
  "Expand `+org-capture-notes-file' from `org-directory'.
If it is an absolute path return `+org-capture-notes-file' verbatim."
  (defvar +org-capture-notes-file org-directory))

(defvar +org-capture-links-file "links.org"
  "Default target for storing timestamped journal entries.
Is relative to `org-directory', unless it is absolute.")

(defun +org-capture-links-file ()
  "Expand `+org-capture-links-file' from `org-directory'.
If it is an absolute path return `+org-capture-links-file' verbatim."
  (expand-file-name +org-capture-links-file org-directory))

(defvar +org-capture-habits-file "habits.org"
  "Default target for storing repeated entries.
Is relative to `org-directory', unless it is absolute.")

(defun +org-capture-habits-file ()
  "Expand `+org-capture-habits-file' from `org-directory'.
If it is an absolute path return `+org-capture-habits-file' verbatim."
  (expand-file-name +org-capture-habits-file org-directory))

(defvar +org-capture-projects-file "projects.org"
  "Default target for storing project entries.
Is relative to `org-directory', unless it is absolute.")

(defun +org-capture-projects-file ()
  "Expand `+org-capture-projects-file' from `org-directory'.
If it is an absolute path return `+org-capture-projects-file' verbatim."
  (expand-file-name +org-capture-projects-file org-directory))

(require 'org-capture)
(setq org-default-notes-file +org-capture-notes-file)

org-archive

(defvar +org-archives-file "archives.org"
  "Default target for storing archived entries.
Is relative to `org-directory', unless it is absolute.")

(defun +org-archives-file ()
  "Expand `+org-archives-file' from `org-directory'.
If it is an absolute path return `+org-archives-file' verbatim."
  (expand-file-name +org-archives-file org-directory))

Sets the defaults directories

(setq org-default-notes-file
      (expand-file-name +org-capture-notes-file org-directory)
      +org-capture-links-file
      (expand-file-name +org-capture-links-file org-directory)
      +org-capture-projects-file
      (expand-file-name +org-capture-projects-file org-directory)
      +org-capture-habits-file
      (expand-file-name +org-capture-habits-file org-directory))

Logging

(setq org-log-done 'time
      org-log-refile 'time
      org-log-redeadline 'time
      org-log-note-clock-out t
      org-log-into-drawer t
      org-log-note-headings '((done . "CLOSING NOTE %t")
                              (state . "State %-12s from %-12S %t")
                              (note . "Note taken on %t")
                              (reschedule . "Rescheduled from %S on %t")
                              (delschedule . "Not scheduled, was %S on %t")
                              (redeadline . "New deadline from %S on %t")
                              (deldeadline . "Removed deadline, was %S on %t")
                              (refile . "Refiled on %t")
                              (clock-out . "")))

habits

(add-to-list 'org-modules 'org-habit t)
(setq org-habit-preceeding-days 7)
(setq org-habit-following-days 3)
(setq org-habit-graph-column 80)
(setq org-habit-show-habits-only-for-today nil)
(setq org-treat-insert-todo-heading-as-state-change t)

Todos and tags

(setq org-todo-keywords
      '((sequence "TODO(t!)"
                  "PROG(p@/!)"
                  "WAITING(w@/!)"
                  "NEXT(n@/!)"
                  "MAYBE(m!)"
                  "|"
                  "DONE(d!)"
                  "CANCELLED(c@/!)")))

(setq org-todo-keyword-faces
      '(("TODO" . (:foreground "#dc322f" :weight bold))
        ("PROG" . (:foreground "#b58900"))
        ("WAITING" . (:foreground "#859900"))
        ("DONE" . (:foreground "#2aa198"))
        ("MAYBE" . (:foreground "#FF2AFC"))
        ("CANCELLED" . (:foreground "#657b83"))))
(setq org-complete-tags-always-offer-all-agenda-tags nil)

Attach

(setq org-attach-directory (expand-file-name "data" org-directory))
(setq org-attach-dir-relative t)
(setq org-attach-archive-delete 'query)
(add-hook 'dired-mode-hook
          (lambda ()
            (define-key dired-mode-map
              (kbd "C-c C-x a")
              #'org-attach-dired-to-subtree)))

Global keybindings

(global-set-key (kbd "C-c l") 'org-store-link)
(global-set-key (kbd "C-c a") 'org-agenda)
(global-set-key (kbd "C-c c") 'org-capture)
  • general
    (with-eval-after-load 'config-general
      (progn
        (require 'general)
        (+config/leader-def
          :states '(normal visual)
          "ol" '(:ignore t :which-key "Links prefix")
          "oa" '(:ignore t :which-key "Agenda prefix")
          "oly" 'org-store-link
          "olp" 'org-insert-link
          "oa" 'org-agenda
          "x" 'org-capture)))
    

babel

see here for available languages.

(org-babel-do-load-languages
 'org-babel-load-languages
 '((emacs-lisp . t)
   (awk . t)
   (C . t)
   (css . t)
   (calc . t)
   (screen . t)
   (dot . t )
   (haskell . t)
   (java . t)
   (js . t)
   (latex . t)
   (lisp . t)
   (lua . t)
   (org . t)
   (perl . t)
   (python .t)
   (ruby . t)
   (shell . t)
   (sed . t)
   (scheme . t)
   (sql . t)
   (sqlite . t)))

org-agenda

(require 'org-agenda)
(setq org-agenda-span 'day)
(setq org-agenda-window-setup (quote current-window))
(setq org-agenda-skip-deadlines-if-done t)
(setq org-agenda-skip-deadline-prewarning-if-scheduled 'pre-scheduled)
(setq org-agenda-custom-commands
      `(("d" "Dashboard"
         ((agenda "" ((org-deadline-warning-days 3)))
          (tags-todo "+habit+TODO=\"TODO\"" ((org-agenda-overriding-header "Routine")))
          (tags-todo "{project*}-TODO=\"DONE\"-TODO=\"SOMEDAY\"-TODO=\"LEARN\""
                     ((org-agenda-overriding-header "Projects:")))
          (tags-todo "+followup" ((org-agenda-overriding-header "Needs Follow Up")))
          (tags "+TODO=\"NEXT\"+learning+" ((org-agenda-overriding-header "Learning:")))
          (alltodo ""
                   ((org-agenda-overriding-header "Inbox")))
          (tags-todo "TODO=\"TODO\"-project-reading-errands-video"
                     ((org-agenda-skip-function '(org-agenda-skip-if nil '(timestamp)))
                      (org-agenda-skip-function
                       `(org-agenda-skip-entry-if
                         'notregexp ,(format "\\[#%s\\]" (char-to-string org-priority-highest))))
                      (org-agenda-prefix-format "%-6e ")
                      (org-agenda-max-entries nil)
                      (org-agenda-overriding-header "Unscheduled TODO entries: ")
                      (org-agenda-sorting-strategy '(priority-down effort-up tag-up category-keep))))))))
(setq org-agenda-include-diary t)
(setq org-clock-persist 'history)
(org-clock-persistence-insinuate)
(setq org-global-properties '(("Effort_ALL". "0 0:10 0:20 0:30 1:00 2:00 3:00 4:00 6:00 8:00")))
(setq org-columns-default-format '"%38ITEM(Details) %TAGS(Context) %7TODO(To Do) %5Effort(Time){:} %6CLOCKSUM(Clock)")

refile and archive

(setq org-refile-targets
      '((org-agenda-files :maxlevel . 9)))
(setq org-refile-use-cache t)
(setq org-refile-use-outline-path 'file)
(setq org-outline-path-complete-in-steps nil)
(setq org-refile-allow-creating-parent-nodes 'confirm)
(setq org-archive-location (concat +org-archives-file "::datetree/* Archived Tasks"))
(advice-add 'org-refile :after 'org-save-all-org-buffers)

stuck-projects

(setq org-stuck-projects
      '("+project/-MAYBE-DONE-SOMEDAY" ("TODO" "NEXT") nil ""))

This is a list of four items:

  1. A tags/todo/property matcher string that is used to identify a project. See the manual for a description of tag and property searches. The entire tree below a headline matched by this is considered one project.
  2. A list of TODO keywords identifying non-stuck projects. If the project subtree contains any headline with one of these todo keywords, the project is considered to be not stuck. If you specify “*” as a keyword, any TODO keyword will mark the project unstuck.
  3. A list of tags identifying non-stuck projects. If the project subtree contains any headline with one of these tags, the project is considered to be not stuck. If you specify “*” as a tag, any tag will mark the project unstuck. Note that this is about the explicit presence of a tag somewhere in the subtree, inherited tags do not count here. If inherited tags make a project not stuck, use “-TAG” in the tags part of the matcher under (1.) above.
  4. An arbitrary regular expression matching non-stuck projects.

move bookmark file to +emacs-data-dir

(setq bookmark-file (concat +emacs-data-dir "/bookmarks"))

capture-templates

(setq org-capture-templates
      '(("t" "Personal (t)Tasks")
        ("tt" "(t)todo" entry
         (file+headline +org-capture-todo-file "Inbox")
         "** TODO [#A] %? %^G:followup:\n:PROPERTIES:\n:Via: %a\n:Note:\n:END:\n:LOGBOOK:\n- State \"TODO\"\tfrom\t\"\"\t%U\n:END:"
         :empty-line 1
         :clock-in t
         :clock-resume t
         :jump-to-captured t)
        ("ts" "(p)In Progress Tasks" entry
         (file+headline +org-capture-todo-file "Inbox")
         "** PROG [#B] %? %^G:followup:\n:PROPERTIES:\n:Via: %a\n:Note:\n:END:\n:LOGBOOK:\n- State \"PROG\"\tfrom\t\"\"\t%U\n:END:"
         :empty-line 1
         :clock-in t
         :clock-resume t
         :jump-to-captured t)
        ("tn" "(n)Notes" entry
         (file+headline +org-capture-notes-file "Notes")
         "** %? %^G\n:PROPERTIES:\n:Via: %a\n:Note:\n:END:\n"
         :empty-line 1
         :jump-to-captured t)
        ("te" "(e)Next" entry
         (file+headline +org-capture-todo-file "Inbox")
         "** NEXT %^G\n:PROPERTIES:\n:Via: %a\n:Note:\n:END:\n"
         :empty-line 1
         :jump-to-captured t)
        ("ti" "(I)Ideas" entry
         (file+headline +org-capture-notes-file "Ideas")
         "** MAYBE %^G\n:PROPERTIES:\n:Via: %a\n:Note:\n:END:\n"
         :empty-line 1
         :jump-to-captured t)
        ("th" "(h)Habit" entry
         (file+headline +org-capture-habits-file "Recurring")
         "** TODO [#C] %? %^G:habit:\n SCHEDULED: %^t\n:PROPERTIES:\n:Style: habit\n:Note:\n:END:\n:LOGBOOK:\n- State \"TODO\"\tfrom \"\"\t%U\n:END:"
         :empty-line 1
         :jump-to-captured t)
        ("td" "(d)Done" entry
         (file+headline +org-capture-notes-file "Inbox")
         "** DONE %?\nCLOSED: %U\n:PROPERTIES:\n:Via: %a\n:Note:\n:END:\n:LOGBOOK:\n- State \"DONE\"\tfrom \"\"\t%U\n:END:"
         :empty-lines 1
         :jump-to-captured t)
        ("p" "Project")
        ("pt" "Project (t)todo" entry
         (file+headline +org-capture-projects-file "Inbox")
         "** TODO [#A] %? %^G:project:\n:PROPERTIES:\n:Via: %a\n:Note:\n:END:\n:LOGBOOK:\n- State \"TODO\"\tfrom \"\"\t%U\n:END:"
         :empty-line 1
         :clock-in t
         :clock-resume t
         :jump-to-captured t)
        ("pe" "project (e)Next" entry
         (file+headline +org-capture-projects-file "Inbox")
         "** NEXT %^G:project:\n:PROPERTIES:\n:Via: %a\n:Note:\n:END:\n:LOGBOOK:\n:END:"
         :empty-line 1
         :clock-in t
         :clock-resume t
         :jump-to-captured t)
        ("pn" "project (n)Note" entry
         (file+headline +org-capture-projects-file "Notes")
         "** %? %^G:project:\n:PROPERTIES:\n:Via: %a\n:Note:\n:END:\n:LOGBOOK:\n:END:"
         :empty-line 1
         :clock-in t
         :clock-resume t
         :jump-to-captured t)
        ("pi" "project ()Ideas" entry
         (file+headline +org-capture-projects-file "Ideas")
         "** MAYBE %^G:project:\n:PROPERTIES:\n:Via: %a\n:Note:\n:END:\n:LOGBOOK:\n:END:"
         :empty-line 1
         :clock-in t
         :clock-resume t
         :jump-to-captured t)
        ("o" "org-protocol")
        ("ot" "org-protocol TODO(t)"
         entry (file+headline +org-capture-todo-file "Inbox")
         "** TODO %?\n:PROPERTIES:\n:Via: %a\n:Note:\n:END:\n:LOGBOOK:\n- State \"TODO\"\tfrom \"\"\t%U\n:END:"
         :empty-lines 1
         :jump-to-captured t)
        ("ol" "org-protocol Links(l)"
         entry (file+headline +org-capture-links-file "Links")
         "** %a %^G:website:\n\n%U\n\n%:initial %?"
         :jump-to-capture t)
        ("j" "Journal")
        ("jt" "Journal Today" plain (function +org-journal-find-location)
         "** %(format-time-string org-journal-time-format)%^{Title}\n%i%?"
         :jump-to-captured t
         :immediate-finish t)
        ("js" "Scheduled Journal" plain (function +org-journal-date-location)
         "** TODO %?\n <%(princ +org-journal--date-location-scheduled-time)>\n"
         :jump-to-captured t)
        )
      org-capture-default-templates "tt")
(add-hook 'org-capture-prepare-finalize-hook 'org-id-store-link)

Settings up org-protocol

  • create a desktop application

    On linux and some other unix OS this is achieved by creating a .desktop file in ~/.local/share/applications/ folder. Here it’s ~/.local/share/applications/org-protocol.desktop.

    [Desktop Entry]
    Name=Org-Protocol
    Exec=emacsclient %u
    Icon=emacs-icon
    Type=Application
    Terminal=false
    MimeType=x-scheme-handler/org-protocol
    

    Then associate it with the org-protocol:// link

    [ $(command -v xdg-mime) ] && xdg-mime default org-protocol.desktop x-scheme-handler/org-protocol
    

Inherit properties

Set org-properties to also apply to their sublevels.

(customize-set-variable 'org-use-property-inheritance t)

Additional org packages

This will be stored in each individual files.

  • org-roam
    header-args: :tangle (expand-file-name "modules/config-org-roam.el" user-emacs-directory)
    
    • header
      ;;; config-org-roam.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'org-roam)
        (straight-use-package 'org-roam-ui)
        (when (featurep 'consult)
          (straight-use-package '(consult-org-roam :type git
                                                   :host github
                                                   :repo "jgru/consult-org-roam"))))
      
    • for freebsd

      Need to install emacsql package from pkg.

      (when (and (string= "berkeley-unix" system-type)
                 (executable-find "emacsql-sqlite"))
        (straight-use-package '(emacsql :type built-in))
        (straight-use-package '(emacsql-sqlite :type built-in))
        (require 'emacsql)
        (require 'emacsql-sqlite)
        (setq emacsql-data-root
              (concat "/usr/local/share/emacs/"
                      emacs-version
                      "/site-lisp/emacsql/"))
        (setq emacsql-sqlite-data-root emacsql-data-root)
        (setq emacsql-sqlite-executable "/usr/local/bin/emacsql-sqlite"))
      
    • config
      (customize-set-variable 'org-roam-db-location (expand-file-name "org-roam.db" +emacs-data-dir))
      (add-hook 'org-roam-backlinks-mode 'turn-on-visual-line-mode)
      (setq org-roam-directory
            (file-name-as-directory
             (file-truename
              (expand-file-name "roam" org-directory)))
            org-roam-completion-everywhere t
            org-roam-mode-section-functions
            #'(org-roam-backlinks-section
               org-roam-reflinks-section))
      (unless (file-directory-p org-roam-directory)
        (make-directory org-roam-directory :parents))
      (org-roam-db-autosync-mode)
      
    • roam-daily
      (require 'org-roam-dailies)
      (setq org-roam-dailies-directory
            (file-name-as-directory
             (file-truename
              (expand-file-name "daily" org-roam-directory))))
      
    • org-roam-graph
      (require 'org-roam-graph)
      
    • roam-ui
      (setq org-roam-node-display-template
            (concat "${title:*} "
                    (propertize "${tags:10}" 'face 'org-tag)))
      
      (add-to-list 'display-buffer-alist
                   '("\\*org-roam\\*"
                     (display-buffer-in-side-window)
                     (side . right)
                     (slot . 0)
                     (window-width . 0.33)
                     (window-parameters . ((no-other-window . t)
                                           (no-delete-other-windows . t)))))
      (unless +config/is-guix-system
        (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))
      (require 'server)
      (unless (server-running-p)
        (server-start))
      (require 'org-protocol)
      (require 'org-roam-protocol)
      (setq org-roam-capture-templates
            (quote (("r" "reference" plain "%?"
                     :if-new (file+head "reference/${title}.org" "#+title: ${title}\n")
                     :immediate-finish t
                     :unnarrowed t)
                    ("a" "article" plain "%?"
                     :if-new (file+head "articles/${title}.org" "#+title: ${title}\n#+filetags: :article:\n")
                     :immediate-finish t
                     :unnarrowed t)
                    ("d" "default" plain
                     "* ${title}\n%?" :if-new
                     (file+head "%<%Y%m%d%H%M%S>-${slug}.org"
                                "#+title: ${title}\n#+filetags:\n#+date: %<%Y-%m-%d>\n\n")
                     :unnarrowed t)
                    )))
      (setq org-roam-capture-ref-templates
            (quote (("r" "ref" plain
                     "%?"
                     :if-new (file+head
                              "%(format-time-string \"%Y-%m-%d--%H-%M-%SZ--${slug}.org\" (current-time) t)"
                              "#+title: ${title}\n#+filetags:\n#+date: %<%Y-%m-%d>\n\n")
                     :unnarrowed t :jump-to-captured t))))
      (setq org-roam-dailies-capture-templates
            (quote (("d" "Default" plain
                     "%?"
                     :if-new (file+head
                              "%(format-time-string \"%Y-%m-%d--journal.org\" (current-time) t)"
                              "#+title: Journal %<%Y-%m-%d>\n#+date: %<%Y-%m-%d>\n#+journal: private journal\n\n\n")
                     :unnarrowed t))))
      
    • consult-integration
      (when (featurep 'consult)
        (require 'consult-org-roam)
        (consult-org-roam-mode 1))
      
    • Keybindings
      (global-set-key (kbd "C-c r i") 'org-roam-node-insert)
      (global-set-key (kbd "C-c r f") 'org-roam-node-find)
      (global-set-key (kbd "C-c r c") 'org-roam-capture)
      (global-set-key (kbd "C-c r b") 'org-roam-buffer-toggle)
      (global-set-key (kbd "C-c r B") 'org-roam-buffer-display-dedicated)
      (global-set-key (kbd "C-c r s") 'org-roam-db-sync)
      (when (featurep 'consult-org-roam)
        (global-set-key (kbd "C-c r e") 'consult-org-roam-file-find)
        (global-set-key (kbd "C-c r x") 'consult-org-roam-backlinks)
        (global-set-key (kbd "C-c r S") 'consult-org-roam-search))
      
      • general
        (with-eval-after-load 'config-general
          (progn
            (require 'general)
            (+config/leader-def
              :states '(normal visual)
              "or" '(:ignore t :which-key "Roam prefix")
              "ori" 'org-roam-node-insert
              "orf" 'org-roam-node-find
              "orc" 'org-roam-capture
              "orb" 'org-roam-buffer-toggle
              "orB" 'org-roam-buffer-display-dedicated
              "ors" 'org-roam-db-sync)))
        (with-eval-after-load 'consult-org-roam
          (progn
            (require 'general)
            (+config/leader-def
              :states '(normal visual)
              "ore" 'consult-org-roam-file-find
              "orx" 'consult-org-roam-backlinks
              "orS" 'consult-org-roam-search)))
        
    • Footer
      (provide 'config-org-roam)
      ;;; config-org-roam.el ends here
      
  • org-elfeed
    header-args: :tangle (expand-file-name "modules/config-org-elfeed.el" user-emacs-directory)
    
    • header
      ;;; config-org-elfeed.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'elfeed)
        (straight-use-package 'elfeed-org))
      
    • config
      (require 'elfeed)
      (setq rmh-elfeed-org-files (list (concat org-directory "/elfeed.org")))
      (eval-after-load 'elfeed
        `(make-directory ,(expand-file-name "elfeed/" +emacs-data-dir) t))
      (setq elfeed-db-directory (expand-file-name "elfeed/db/" +emacs-data-dir))
      (setq elfeed-enclosure-default-dir (expand-file-name "elfeed/enclosures/" +emacs-data-dir))
      (setq elfeed-score-score-file (expand-file-name "elfeed/score/score.el" +emacs-data-dir))
      (elfeed-org)
      
    • elfeed notification
      (defvar +config/elfeed-update-complete-hook nil
        "Functions called with no arguments when `elfeed-update' is finished.")
      
      (defvar +config/elfeed-updates-in-progress 0
        "Number of feed updates in-progress.")
      
      (defvar +config/elfeed-search-update-filter nil
        "The filter when `elfeed-update' is called.")
      
      (defun +config/elfeed-update-complete-hook (&rest ignore)
        "When update queue is empty, run `+config/elfeed-update-complete-hook' functions."
        (when (= 0 +config/elfeed-updates-in-progress)
          (run-hooks '+config/elfeed-update-complete-hook)))
      
      (add-hook 'elfeed-update-hooks #'+config/elfeed-update-complete-hook)
      
      (defun +config/elfeed-update-message-completed (&rest _ignore)
        (message "Feeds updated")
        (notifications-notify :title "Elfeed" :body "Feeds updated."))
      
      (add-hook '+config/elfeed-update-complete-hook #'+config/elfeed-update-message-completed)
      
      (defun +config/elfeed-search-update-restore-filter (&rest ignore)
        "Restore filter after feeds update."
        (when +config/elfeed-search-update-filter
          (elfeed-search-set-filter +config/elfeed-search-update-filter)
          (setq +config/elfeed-search-update-filter nil)))
      
      (add-hook '+config/elfeed-update-complete-hook #'+config/elfeed-search-update-restore-filter)
      
      (defun +config/elfeed-search-update-save-filter (&rest ignore)
        "Save and change the filter while updating."
        (setq +config/elfeed-search-update-filter elfeed-search-filter)
        (setq elfeed-search-filter "#0"))
      
      ;; NOTE: It would be better if this hook were run before starting the feed updates, but in
      ;; `elfeed-update', it happens afterward.
      (add-hook 'elfeed-update-init-hooks #'+config/elfeed-search-update-save-filter)
      
      (defun +config/elfeed-update-counter-inc (&rest ignore)
        (cl-incf +config/elfeed-updates-in-progress))
      
      (advice-add #'elfeed-update-feed :before #'+config/elfeed-update-counter-inc)
      
      (defun +config/elfeed-update-counter-dec (&rest ignore)
        (cl-decf +config/elfeed-updates-in-progress)
        (when (< +config/elfeed-updates-in-progress 0 ; >
                 )
          ;; Just in case
          (setq +config/elfeed-updates-in-progress 0)))
      
      (add-hook 'elfeed-update-hooks #'+config/elfeed-update-counter-dec)
      
    • Keybinding
      (global-set-key (kbd "C-c e e") 'elfeed)
      (global-set-key (kbd "C-c e u") 'elfeed-update)
      (global-set-key (kbd "C-c e U") 'elfeed-update-feed)
      
      • general
        (with-eval-after-load 'config-general
          (progn
            (require 'general)
            (+config/leader-def
              :states '(normal visual)
              "e" '(:ignore t :which-key "Elfeed prefix")
              "ee" 'elfeed
              "eu" 'elfeed-update
              "eU" 'elfeed-update-feed)))
        
    • Footer
      (provide 'config-org-elfeed)
      ;;; config-org-elfeed.el ends here
      
  • org-gcal
    header-args: :tangle (expand-file-name "modules/config-org-gcal.el" user-emacs-directory)
    
    • header
      ;;; config-org-gcal.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (straight-use-package 'org-gcal)
      
    • config
      (defun +config/org-gcal-setup-sync (&optional dir id secret)
        "Setup gcal with optional args DIR, ID and SECRET."
        ;; require
        (require 'config-pass)
        (require 'org-gcal)
        (if dir
            (setq org-gcal-dir dir)
          (setq org-gcal-dir (expand-file-name "org/gcal/" +emacs-data-dir)))
        (if id
            (setq org-gcal-client-id id)
          (setq org-gcal-client-id (password-store-get "console.cloud.google.com/gcal/id")))
        (if secret
            (setq org-gcal-client-secret secret)
          (setq org-gcal-client-secret (password-store-get "console.cloud.google.com/gcal/secret"))))
      
    • Keybinding
      (global-set-key (kbd "C-c g s") 'org-gcal-sync)
      (global-set-key (kbd "C-c g f") 'org-gcal-fetch)
      
      • general
        (with-eval-after-load 'config-general
          (progn
            (require 'general)
            (+config/leader-def
              :states '(normal visual)
              "og" '(:ignore t :which-key "Org-Gcal prefix")
              "ogs" 'org-gcal-sync
              "ogf" 'org-gcal-fetch)))
        
    • Footer
      (provide 'config-org-gcal)
      ;;; config-org-gcal.el ends here
      
  • org-journal
    header-args: :tangle (expand-file-name "modules/config-org-journal.el" user-emacs-directory)
    
    • header
      ;;; config-org-journal.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'org-journal))
      
    • config
      (setq org-journal-dir (expand-file-name "journal" org-directory)
            org-journal-enable-agenda-integration t
            org-journale-enable-cache t
            org-journal-follow-mode t
            org-journal-prefix-key "C-c j")
      
      (defun +org-journal-find-location ()
        "Open today's journal, but specify a non-nil prefix argument in order to
        inhibit inserting the heading; org-capture will insert the heading."
        (org-journal-new-entry t)
        (unless (eq org-journal-file-type 'daily)
          (org-narrow-to-subtree))
        (goto-char (point-max)))
      
      (defvar +org-journal--date-location-scheduled-time nil)
      
      (defun +org-journal-date-location (&optional scheduled-time)
        (let ((scheduled-time (or scheduled-time (org-read-date nil nil nil "Date:"))))
          (setq +org-journal--date-location-scheduled-time scheduled-time)
          (org-journal-new-entry t (org-time-string-to-time scheduled-time))
          (unless (eq org-journal-file-type 'daily)
            (org-narrow-to-subtree))
          (goto-char (point-max))))
      
      (defun +org-journal-save-entry-and-exit()
        "Simple convenience function.
           Saves the buffer of the current day's entry and kills the window
           Similar to org-capture like behavior"
        (interactive)
        (save-buffer)
        (kill-buffer-and-window))
      
      (require 'org-journal)
      ;; this messes up org-clock
      ;;(define-key org-journal-mode-map (kbd "C-x C-s") '+org-journal-save-entry-and-exit)
      
    • Footer
      (provide 'config-org-journal)
      ;;; config-org-gcal.el ends here
      

Footer

(provide 'config-defaults-org)
;;; config-defaults-org.el ends here

Default IDE

header-args: :tangle (expand-file-name "modules/config-defaults-ide.el" user-emacs-directory)
;;; config-defaults-ide.el --- Summary -*- lexical-binding: t -*-
;;; Commentary:
;; This file is auto-generated from `config.org'
;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
;;; Code:
(require 'config-defaults-variables)

Additional Package

  • flycheck
    header-args: :tangle (expand-file-name "modules/config-flycheck.el" user-emacs-directory)
    
    • header
      ;;; config-flycheck.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'flycheck))
      
    • consult integration
      (when (featurep 'consult)
        (straight-use-package 'consult-flycheck))
      (global-flycheck-mode)
      (when (featurep 'consult)
        (require 'consult-flycheck)
        (with-eval-after-load 'config-general
          (progn
            (require 'general)
            (+config/leader-def
              :states '(normal visual)
              "/ff" 'consult-flycheck))))
      
    • Footer
      (provide 'config-flycheck)
      ;;; config-flycheck.el ends here
      
  • projectile
    header-args: :tangle (expand-file-name "modules/config-projectile.el" user-emacs-directory)
    
    • header
      ;;; config-projectile.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • config
      (straight-use-package 'projectile)
      (customize-set-variable 'projectile-cache-file (expand-file-name "projectile.cache" +emacs-data-dir))
      (customize-set-variable 'projectile-known-projects-file (expand-file-name "projectile-bookmarks.eld" +emacs-data-dir))
      (projectile-mode +1)
      (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
      (when (featurep 'consult)
        (straight-use-package '(consult-projectile :type git
                                                   :host gitlab
                                                   :repo "OlMon/consult-projectile"
                                                   :branch "master")))
      
      • general
        (with-eval-after-load 'config-general
          (progn
            (require 'general)
            (+config/leader-def
              :states '(normal visual)
              "p" (general-simulate-key "C-c p"
                     :name +projectile-prefix
                     :which-key "Projectile prefix"))))
        
    • Footer
      (provide 'config-projectile)
      ;;; config-projectile.el ends here
      
  • lsp-mode
    header-args: :tangle (expand-file-name "modules/config-lsp-mode.el" user-emacs-directory)
    
    • header
      ;;; config-lsp-mode.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'lsp-mode)
        (straight-use-package 'lsp-ui)
        (when (featurep 'consult)
          (straight-use-package 'consult-lsp)))
      
    • config
      (setq lsp-keymap-prefix "C-c L")
      (customize-set-variable 'lsp-completion-provider :none)
      (customize-set-variable 'lsp-toml-cache-path (expand-file-name ".cache/lsp-toml" +emacs-data-dir))
      (customize-set-variable 'lsp-clojure-workspace-cache-dir (expand-file-name ".cache/lsp-toml" +emacs-data-dir))
      (defun +config/lsp-mode-setup-completion ()
        (setf (alist-get 'styles (alist-get 'lsp-capf completion-category-defaults))
              '(orderless))) ;; Configure flex
      (require 'lsp-mode)
      
    • hook
      (add-hook 'c-mode-hook #'lsp-deferred)
      (add-hook 'c++-mode-hook #'lsp-deferred)
      (add-hook 'shell-mode-hook #'lsp-deferred)
      (add-hook 'yaml-mode-hook #'lsp-deferred)
      (customize-set-variable 'lsp-yaml-schema-store-local-db (expand-file-name ".cache/lsp/lsp-yaml-schemas.json" +emacs-data-dir))
      (add-hook 'rust-mode-hook #'lsp-deferred)
      (add-hook 'toml-mode-hook #'lsp-deferred)
      (add-hook 'python-mode-hook #'lsp-deferred)
      (add-hook 'nix-mode-hook #'lsp-deferred)
      (add-hook 'nginx-mode-hook #'lsp-deferred)
      (add-hook 'markdown-mode-hook #'lsp-deferred)
      (add-hook 'lsp-mode-hook #'lsp-enable-which-key-integration)
      (add-hook 'lsp-completion-mode-hook #'+config/lsp-mode-setup-completion)
      
      (when (featurep 'consult)
        (straight-use-package 'consult-lsp)
        (define-key lsp-mode-map [remap xref-find-apropos] #'consult-lsp-symbols))
      
    • python deps

      lsp server.

      pip install 'python-lsp-server[all]'
      
    • extra deps
      • pyls-flake8
        pip install pyls-flake8
        
      • pyls-mypy
        pip install pyls-mypy
        
      • pyls-isort
        pip install pyls-isort
        
      • python-lsp-black
        pip install python-lsp-black
        
      • pyls-memestra
        pip install pyls-memestra
        
      • pylsp-rope
        pip install pylsp-rope
        
    • Footer
      (provide 'config-lsp-mode)
      ;;; config-lsp-mode.el ends here
      
  • git-gutter
    header-args: :tangle (expand-file-name "modules/config-git-gutter.el" user-emacs-directory)
    
    • header
      ;;; config-git-gutter.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      ;; (straight-use-package 'git-gutter)
      (straight-use-package 'git-gutter-fringe)
      
    • variables
      (require 'git-gutter-fringe)
      
      ;; this is from doom
      (defvar +vc-gutter-in-remote-files nil
        "If non-nil, enable the vc gutter in remote files (e.g. open through TRAMP).")
      
    • hooks
      (add-hook 'find-file-hook
                (defun +vc-gutter-init-maybe-h ()
                  "Enable `git-gutter-mode' in the current buffer.
           If the buffer doesn't represent an existing file, `git-gutter-mode's activation
           is deferred until the file is saved. Respects `git-gutter:disabled-modes'."
                  (let ((file-name (buffer-file-name (buffer-base-buffer))))
                    (cond
                     ((and (file-remote-p (or file-name default-directory))
                           (not +vc-gutter-in-remote-files)))
                     ;; If not a valid file, wait until it is written/saved to activate
                     ;; git-gutter.
                     ((not (and file-name (vc-backend file-name)))
                      (add-hook 'after-save-hook #'+vc-gutter-init-maybe-h nil 'local))
                     ;; Allow git-gutter or git-gutter-fringe to activate based on the type
                     ;; of frame we're in. This allows git-gutter to work for silly geese
                     ;; who open both tty and gui frames from the daemon.
                     ((if (and (display-graphic-p)
                               (require 'git-gutter-fringe nil t))
                          (setq-local git-gutter:init-function      #'git-gutter-fr:init
                                      git-gutter:view-diff-function #'git-gutter-fr:view-diff-infos
                                      git-gutter:clear-function     #'git-gutter-fr:clear
                                      git-gutter:window-width -1)
                        (setq-local git-gutter:init-function      'nil
                                    git-gutter:view-diff-function #'git-gutter:view-diff-infos
                                    git-gutter:clear-function     #'git-gutter:clear-diff-infos
                                    git-gutter:window-width 1))
                      (unless (memq major-mode git-gutter:disabled-modes)
                        (git-gutter-mode +1)
                        (remove-hook 'after-save-hook #'+vc-gutter-init-maybe-h 'local)))))))
      (setq git-gutter:disabled-modes '(fundamental-mode image-mode pdf-view-mode))
      (add-hook 'focus-in-hook #'git-gutter:update-all-windows)
      
    • avoid collision with flycheck
      ;; avoid collision with flycheck
      (when (featurep 'flycheck)
        (setq flycheck-indication-mode 'right-fringe))
      
    • custom functions
      (unless (featurep 'evil)
        (defun +git-gutter:next-hunk ()
          (interactive)
          (git-gutter:next-hunk 1)
          (set-temporary-overlay-map
           (let ((map (make-sparse-keymap)))
             (define-key map (kbd "C-n") (git-gutter:next-hunk 1))
             map)))
        (defun +git-gutter:previous-hunk ()
          (interactive)
          (git-gutter:previous-hunk 1)
          (set-temporary-overlay-map
           (let ((map (make-sparse-keymap)))
             (define-key map (kbd "C-p") (git-gutter:previous-hunk 1))
             map))))
      
    • keybinding
      • hydra
        (when (featurep 'hydra)
          (defhydra hydra-git-gutter (global-map
                                      "C-c g")
            "
        git-gutter^
        "
            ("p" git-gutter:previous-hunk "previous hunk")
            ("n" git-gutter:next-hunk "next hunk")
            ("P" git-gutter:popup-hunk "pop hunk")
            ("s" git-gutter:stage-hunk "stage hunk")
            ("r" git-gutter:revert-hunk "revert hunk")
            ("u" git-gutter:update-all-windows "update all windows")))
        
      • general
        (when (featurep 'general)
          (+config/leader-def
            :states '(normal visual)
            "gs" 'git-gutter:stage-hunk
            "gr" 'git-gutter:revert-hunk
            "gu" 'git-gutter:stage-hunk)
          (when (featurep 'evil)
            (general-define-key
              :keymaps '(normal visual)
              :prefix +general-leader
              :repeat t
              :jump t
              "gk" 'git-gutter:previous-hunk
              "gj" 'git-gutter:next-hunk)))
        
    • Footer
      (provide 'config-git-gutter)
      ;;; config-lsp-mode.el ends here
      

Footer

(provide 'config-defaults-ide)
;;; config-defaults-ide.el ends here

Default Email

header-args: :tangle (expand-file-name "modules/config-defaults-email.el" user-emacs-directory)
;;; config-defaults-email.el --- Summary -*- lexical-binding: t -*-
;;; Commentary:
;; This file is auto-generated from `config.org'
;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
;;; Code:
(require 'config-defaults-variables)

message-directory

(customize-set-variable 'message-directory +mail-directory)

message-auto-save-directory

(setq message-auto-save-directory (expand-file-name "mail/auto-save" +emacs-data-dir))
(unless (file-directory-p message-auto-save-directory)
  (make-directory message-auto-save-directory :parents))

sign outgoing mail by default

(add-hook 'message-setup-hook 'mml-secure-message-sign-pgpmime)

msmtp

(setq send-mail-function 'sendmail-send-it
      mail-specify-envelope-from t
      message-sendmail-envelope-from 'header
      mail-envelope-from 'header)
(when (executable-find "msmtp")
  (require 'sendmail)
  (customize-set-variable 'sendmail-program (executable-find "msmtp")))

Additional Packages

  • notmuch
    header-args: :tangle (expand-file-name "modules/config-notmuch.el" user-emacs-directory)
    
    • header
      ;;; config-notmuch.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      
    • package
      (straight-use-package 'notmuch)
      (straight-use-package 'ol-notmuch)
      
    • config
      (customize-set-variable 'notmuch-init-file (expand-file-name "notmuch-config" +emacs-data-dir))
      (customize-set-variable 'notmuch-search-oldest-first nil)
      (if (executable-find "gpg2")
          (customize-set-variable 'notmuch-crypto-gpg-program "gpg2")
        (customize-set-variable 'notmuch-crypto-gpg-program "gpg"))
      (global-set-key (kbd "C-c M") 'notmuch) ;; conflict with consult
      (when (featurep 'consult)
        (straight-use-package 'consult-notmuch)
        (require 'consult-notmuch))
      (unless (featurep 'transient)
        (straight-use-package 'transient))
      (require 'transient)
      (require 'notmuch)
      (with-eval-after-load 'config-general
        (progn
          (require 'general)
          (+config/leader-def
            :states '(normal visual)
            "mm" 'notmuch)))
      

      This is the default saved-searches, for reference.

      (setq notmuch-saved-searches
            '((:name "inbox" :query "tag:inbox" :key "i")
              (:name "unread" :query "tag:unread" :key "u")
              (:name "flagged" :query "tag:flagged" :key "f") ;starred in gmail
              (:name "sent" :query "tag:sent" :key "t")
              (:name "drafts" :query "tag:draft" :key "d")
              (:name "all mail" :query "*" :key "a")))
      

      Since I’ve used afew to modify tags based on the accounts maildir directories

      (setq notmuch-saved-searches
            '((:name "Today"
                     :query "date:today AND NOT tag:spam AND NOT tag:bulk"
                     :key "T"
                     :search-type 'tree
                     :sort-order 'newest-first)
              (:name "This Week"
                     :query "date:weeks AND NOT tag:spam AND NOT tag:bulk"
                     :key "W"
                     :search-type 'tree
                     :sort-order 'newest-first)
              (:name "This Month"
                     :query "date:months AND NOT tag:spam AND NOT tag:bulk"
                     :key "M"
                     :search-type 'tree
                     :sort-order 'newest-first)
              (:name "flagged"
                     :query "tag:flagged AND NOT tag:spam AND NOT tag:bulk"
                     :key "f"
                     :search-type 'tree
                     :sort-order 'newest-first)
              (:name "inbox" :query "tag:inbox" :key "i")
              (:name "unread" :query "tag:unread" :key "u")
              (:name "spam" :query "tag:spam")
              (:name "gmail/inbox" :query "tag:gmail/inbox")
              (:name "gmail/sent" :query "tag:gmail/sent")
              (:name "gmail/draft" :query "tag:gmail/draft")
              (:name "gmail/archive" :query "tag:gmail/archive")
              (:name "gmail/spam" :query "tag:gmail/spam")
              (:name "yahoo/inbox" :query "tag:yahoo/inbox")
              (:name "yahoo/sent" :query "tag:yahoo/sent")
              (:name "yahoo/draft" :query "tag:yahoo/draft")
              (:name "yahoo/archive" :query "tag:yahoo/archive")
              (:name "yahoo/spam" :query "tag:yahoo/spam")
              (:name "hotmail/inbox" :query "tag:hotmail/inbox")
              (:name "hotmail/sent" :query "tag:hotmail/sent")
              (:name "hotmail/draft" :query "tag:hotmail/draft")
              (:name "hotmail/archive" :query "tag:hotmail/archive")
              (:name "hotmail/spam" :query "tag:hotmail/spam")
              (:name "ymail/inbox" :query "tag:ymail/inbox")
              (:name "ymail/sent" :query "tag:ymail/sent")
              (:name "ymail/draft" :query "tag:ymail/draft")
              (:name "ymail/archive" :query "tag:ymail/archive")
              (:name "ymail/spam" :query "tag:ymail/spam")))
      

      +my/offlineimap-poll function

      (defun +my/offlineimap-poll (&optional args)
        "Poll offlineimap with ARGS if provided."
        (setq-local output-buffer "*offlineimap*"
                    error-buffer "*offlineimap-error*"
                    command "offlineimap")
        (if args
            (async-shell-command (mapconcat #'identity `(,command ,@args) " ") output-buffer error-buffer))
        (async-shell-command (mapconcat #'identity `(,command ,@args) " ") output-buffer error-buffer))
      

      +my/interactive-offlineimap-poll

      (defun +my/interactive-offlineimap-poll (&optional args)
        "Runs offlineimap interactively.
      Should be run with transient."
        (interactive
         (list (transient-args '+my/offlineimap-transient)))
        (let ((command "offlineimap")
              (output-buffer "*offlineimap*")
              (error-buffer "*offlineimap-error*"))
          (if args
              (async-shell-command (mapconcat #'identity `(,command ,@args) " ") output-buffer error-buffer)
            (async-shell-command (mapconcat #'identity `(,command ,@args) " ") output-buffer error-buffer))))
      

      +my/offlineimap-transient

      (require 'transient)
      
      (transient-define-prefix +my/offlineimap-transient ()
        "Offlineimap transient account chooser"
        :man-page "offlineimap"
        :incompatible '(("-a gmail" "-a yahoo" "-a ymail" "-a hotmail"))
        ["Account"
         ("g" "Gmail" "-a gmail")
         ("y" "Yahoo" "-a yahoo")
         ("Y" "Ymail" "-a ymail")
         ("h" "Hotmail" "-a hotmail")]
        ["Options"
         ("-d" "dry-run" "--dry-run")
         ("-i" "info" "--info")
         ("-1" "single-thread" "-1")
         ("-s" "syslog" "-s")
         ("-q" "quick" "-q")]
        ["Actions"
         ("p" "poll offlineimap" +my/interactive-offlineimap-poll)])
      
      (when (executable-find "offlineimap")
        (define-key notmuch-common-keymap [remap notmuch-poll-and-refresh-this-buffer] #'+my/offlineimap-transient))
      
    • mbsync
      (defun +my/mbsync-poll ()
        (interactive)
        (async-shell-command "notmuch new" "*notmuch-poll*" "*notmuch-poll-error*"))
      (when (executable-find "mbsync")
        (define-key notmuch-common-keymap [remap notmuch-poll-and-refresh-this-buffer] #'+my/mbsync-poll))
      
    • Footer
      (provide 'config-notmuch)
      ;;; config-notmuch.el ends here
      
  • gnus-alias
    header-args: :tangle (expand-file-name "modules/config-gnus-alias.el" user-emacs-directory)
    
    ;;; config-gnus-alias.el --- Summary -*- lexical-binding: t -*-
    ;;; Commentary:
    ;; This file is auto-generated from `config.org'
    ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
    ;;; Code:
    
    (straight-use-package 'gnus-alias)
    (add-hook 'message-setup-hook
              (lambda ()
                (gnus-alias-determine-identity)
                (define-key message-mode-map (kbd "C-c f")
                  (lambda ()
                    (interactive)
                    (message-remove-header "Fcc")
                    (message-remove-header "Organization")
                    (gnus-alias-select-identity)
                    (when (featurep 'notmuch)
                      (notmuch-fcc-header-setup))))))
    
    • Footer
      (provide 'config-gnus-alias)
      ;;; config-gnus-alias.el ends here
      

Footer

(provide 'config-defaults-email)
;;; config-defaults-email.el ends here

Default Shell

header-args: :tangle (expand-file-name "modules/config-defaults-shell.el" user-emacs-directory)
;;; config-defaults-shell.el --- Summary -*- lexical-binding: t -*-
;;; Commentary:
;; This file is auto-generated from `config.org'
;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
;;; Code:
(require 'config-defaults-variables)

xterm-set-window-title

(customize-set-variable 'xterm-set-window-title t)

Eshell

  • Eshell and emacs-server

    From emacswiki. If using chemacs, to actually run this outside emacs, use: emacsclient -a "" -s <chemacs-profile> -c -e '(+server-eshell)'

    (require 'cl-lib)
    (defun +server-eshell ()
      "Command to be called by emacs-client to start a new shell.
    
    A new eshell will be created.  When the frame is closed,
    the buffer is deleted or the shell exits, then hooks will take
    care that the other actions happen. For example, when the frame
    is closed, then the buffer will be deleted and the client disconnected.
    Also creates a local binding of `C-x #' to kill the buffer."
      (lexical-let ((buf (eshell t))
                    (client (first server-clients))
                    (frame (selected-frame)))
                   (labels ((close (&optional arg)
                                   (when (not (boundp '+cve/recurse))
                                     (let ((+cve/recurse t))
                                       (delete-frame frame)
                                       (kill-buffer buf)
                                       (server-delete-client client)))))
                           (add-hook 'eshell-exit-hook #'close t t)
                           (add-hook 'delete-frame-functions #'close t t))
                   (local-set-key (kbd "C-x #") (lambda () (interactive) (kill-buffer buf)))
                   (delete-other-windows)
                   nil))
    
  • Set current directory in prompt.
    (setq eshell-prompt-function
          (lambda nil
            (concat
             (eshell/pwd)
             " $ ")))
    
  • keybinding
    (global-set-key (kbd "C-c t e") 'eshell)
    
    • general
      (with-eval-after-load 'config-general
        (progn
          (require 'general)
          (+config/leader-def
            :states '(normal visual)
            "te" 'eshell)))
      

Additional Packages

  • vterm
    header-args: :tangle (expand-file-name "modules/config-vterm.el" user-emacs-directory)
    
    ;;; config-vterm.el --- Summary -*- lexical-binding: t -*-
    ;;; Commentary:
    ;; This file is auto-generated from `config.org'
    ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
    ;;; Code:
    (require 'config-defaults-variables)
    
    (unless +config/is-guix-system
      (straight-use-package 'vterm))
    (require 'vterm)
    (global-set-key (kbd "C-c t t") 'vterm)
    (setq vterm-max-scrollback 5000)
    (add-hook 'vterm-mode-hook (lambda () (setq confirm-kill-processes nil
                                                hscroll-margin 0)))
    
    • general
      (with-eval-after-load 'config-general
        (progn
          (require 'general)
          (+config/leader-def
            :states '(normal visual)
            "tt" 'vterm)))
      
    • Footer
      (provide 'config-vterm)
      ;;; config-vterm.el ends here
      

Footer

(provide 'config-defaults-shell)
;;; config-defaults-shell.el ends here

Default Completion

header-args: :tangle (expand-file-name "modules/config-defaults-completion.el" user-emacs-directory)
;;; config-defaults-completion.el --- Summary -*- lexical-binding: t -*-
;;; Commentary:
;; This file is auto-generated from `config.org'
;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
;;; Code:
(require 'config-defaults-variables)

Additional Packages

  • vertico
    header-args: :tangle (expand-file-name "modules/config-vertico.el" user-emacs-directory)
    
    • header
      ;;; config-vertico.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (straight-use-package '(vertico :files (:defaults "extensions/*")
                                      :includes (vertico-indexed
                                                 vertico-flat
                                                 vertico-grid
                                                 vertico-mouse
                                                 vertico-quick
                                                 vertico-buffer
                                                 vertico-repeat
                                                 vertico-reverse
                                                 vertico-directory
                                                 vertico-multiform
                                                 vertico-unobtrusive
                                                 )))
      
    • config
      (defun crm-indicator (args)
        (cons (concat "[CRM] " (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)
      (setq tab-always-indent 'complete)
      (customize-set-variable 'vertico-cycle t)
      
      (require 'vertico)
      (vertico-mode)
      
    • completion-in-region
      ;; Use `consult-completion-in-region' if Vertico is enabled.
      ;; Otherwise use the default `completion--in-region' function.
      (setq completion-in-region-function
            (lambda (&rest args)
              (apply (if vertico-mode
                         #'consult-completion-in-region
                       #'completion--in-region)
                     args)))
      
    • menubar
      ;; tmm-menubar
      (global-set-key [f10] #'tmm-menubar)
      (advice-add #'tmm-add-prompt :after #'minibuffer-hide-completions)
      
    • ffap-menu
      ;; ffap-menu
      (advice-add #'ffap-menu-ask :around (lambda (&rest args)
                                            (cl-letf (((symbol-function #'minibuffer-completion-help)
                                                       #'ignore))
                                              (apply args))))
      
    • prefix
      ;; prefix
      (advice-add #'vertico--format-candidate :around
                  (lambda (orig cand prefix suffix index _start)
                    (setq cand (funcall orig cand prefix suffix index _start))
                    (concat
                     (if (= vertico--index index)
                         (propertize "» " 'face 'vertico-current)
                       "  ")
                     cand)))
      ;; don't let vertico resize the minibuffer
      (setq vertico-resize nil)
      ;; increase the number of candidates to show
      (setq vertico-count 15)
      
    • vertico-multiform
      (require 'vertico-multiform)
      (setq vertico-multiform-commands
            '((consult-imenu buffer indexed)
              (consult-imenu-multi buffer indexed)))
      
      (setq vertico-multiform-categories
            '((symbol (vertico-sort-function . vertico-sort-alpha))
              (file (vertico-sort-function . sort-directories-first))))
      
      (setq vertico-multiform-categories
            '((buffer flat (vertico-cycle . t))))
      
      (defun sort-directories-first (files)
        (setq files (vertico-sort-history-length-alpha files))
        (nconc (seq-filter (lambda (x) (string-suffix-p "/" x)) files)
               (seq-remove (lambda (x) (string-suffix-p "/" x)) files)))
      
    • vertico-repeat
      (global-set-key (kbd "<C-S-iso-lefttab>") #'vertico-repeat)
      (add-hook 'minibuffer-setup-hook #'vertico-repeat-save)
      
    • vertico-directory
      (require 'vertico-directory)
      (add-hook 'rfn-eshadow-update-overlay-hook #'vertico-directory-tidy)
      (add-hook 'minibuffer-setup-hook #'vertico-repeat-save)
      (define-key vertico-map (kbd "DEL") 'vertico-directory-delete-char)
      ;;(define-key vertico-map (kbd "M-DEL") 'vertico-directory-delete-char)
      
    • Footer
      (provide 'config-vertico)
      ;;; config-vertico.el ends here
      
  • orderless
    header-args: :tangle (expand-file-name "modules/config-orderless.el" user-emacs-directory)
    
    • header
      ;;; config-orderless.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'orderless))
      (require 'orderless)
      
    • config
      (setq completion-styles '(basic partial-completion orderless)
            completion-category-defaults nil
            completion-category-overrides '((file (styles basic partial-completion))))
      
    • Footer
      (provide 'config-orderless)
      ;;; config-orderless.el ends here
      
  • marginalia
    header-args: :tangle (expand-file-name "modules/config-marginalia.el" user-emacs-directory)
    
    • header
      ;;; config-marginalia.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'marginalia)
        (when (featurep 'config-all-the-icons)
          (straight-use-package 'all-the-icons-completion)))
      (require 'marginalia)
      
    • keybind
      (define-key minibuffer-local-map (kbd "M-A") 'marginalia-cycle)
      (marginalia-mode 1)
      
    • all-the-icons integration
      (when (featurep 'config-all-the-icons)
        (all-the-icons-completion-mode)
        (add-hook 'marginalia-mode-hook #'all-the-icons-completion-marginalia-setup))
      
    • Footer
      (provide 'config-marginalia)
      ;;; config-marginalia.el ends here
      
  • consult
    header-args: :tangle (expand-file-name "modules/config-consult.el" user-emacs-directory)
    
    • header
      ;;; config-consult.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'consult)
        (straight-use-package 'consult-dir))
      
    • hooks
      (require 'consult)
      (add-hook 'completion-list-mode-hook #'consult-preview-at-point-mode)
      (advice-add #'register-preview :override #'consult-register-window)
      ;;(advice-add #'completing-read-multiple :override #'consult-completing-read-multiple)
      
    • variable
      (setq register-preview-delay 0.5
            register-preview-function #'consult-register-format)
      (setq xref-show-xrefs-function #'consult-xref
            xref-show-definitions-function #'consult-xref)
      (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-recent-file
       consult--source-project-recent-file
       :preview-key (kbd "M-."))
      (setq consult-narrow-key "<") ;; (kbd "C-+")
      ;; remap
      
    • keybindings
      • global remap
        (global-set-key [remap apropos-command] #'consult-apropos)
        (global-set-key [remap bookmark-jump] #'consult-bookmark)
        (global-set-key [remap goto-line] #'consult-goto-line)
        (global-set-key [remap imenu] #'consult-imenu)
        (global-set-key [remap locate] #'consult-locate)
        (global-set-key [remap load-theme] #'consult-theme)
        (global-set-key [remap man] #'consult-man)
        (global-set-key [remap recentf-open-files] #'consult-recent-file)
        (global-set-key [remap repeat-complex-command] #'consult-complex-command)
        (global-set-key [remap project-switch-to-buffer] #'consult-project-buffer)
        (global-set-key [remap switch-to-buffer] #'consult-buffer)
        (global-set-key [remap switch-to-buffer-other-window] #'consult-buffer-other-window)
        (global-set-key [remap switch-to-buffer-other-frame] #'consult-buffer-other-frame)
        (global-set-key [remap yank-pop] #'consult-yank-pop)
        
      • isearch-mode-map
        (define-key isearch-mode-map [remap isearch-edit-string] #'consult-isearch-history)
        ;; Isearch integration
        (global-set-key (kbd "M-s e") 'consult-isearch-history)
        (define-key isearch-mode-map (kbd "M-s l") #'consult-line) ;; needed by consult-line to detect isearch
        (define-key isearch-mode-map (kbd "M-s L") #'consult-line-multi) ;; needed by consult-line to detect isearch
        
      • global
        (global-set-key (kbd "C-c h") 'consult-history)
        (global-set-key (kbd "C-c m") 'consult-mode-command)
        (global-set-key (kbd "C-c k") 'consult-kmacro)
        ;; Custom M-# bindings for fast register access
        (global-set-key (kbd "M-#") 'consult-register-load)
        (global-set-key (kbd "M-'") 'consult-register-store)          ;; orig. abbrev-prefix-mark (unrelated)
        (global-set-key (kbd "C-M-#") 'consult-register)
        ;; M-g bindings (goto-map)
        (global-set-key (kbd "M-g e") 'consult-compile-error)
        (global-set-key (kbd "M-g o") 'consult-outline)               ;; Alternative: consult-org-heading
        ;;(global-set-key (kbd "M-g m") 'consult-mark) ;;conflict with telega
        (global-set-key (kbd "M-g k") 'consult-global-mark)
        ;;(global-set-key (kbd "M-g i") 'consult-imenu) ;; conflict with telega
        (global-set-key (kbd "M-g I") 'consult-imenu-multi)
        ;; M-s bindings (search-map)
        (global-set-key (kbd "M-s d") 'consult-find)
        (global-set-key (kbd "M-s D") 'consult-locate)
        (global-set-key (kbd "M-s g") 'consult-grep)
        (global-set-key (kbd "M-s G") 'consult-git-grep)
        (global-set-key (kbd "M-s r") 'consult-ripgrep)
        (global-set-key (kbd "M-s l") 'consult-line)
        (global-set-key (kbd "M-s L") 'consult-line-multi)
        (global-set-key (kbd "M-s m") 'consult-multi-occur)
        (global-set-key (kbd "M-s k") 'consult-keep-lines)
        (global-set-key (kbd "M-s u") 'consult-focus-lines)
        
      • flymake/flycheck integration
        (when (featurep 'flymake)
          (global-set-key (kbd "M-g f") 'consult-flymake))               ;; Alternative: consult-flycheck
        (when (featurep 'flycheck)
          (global-set-key (kbd "M-g f") 'consult-flycheck))
        
      • consult-dir
        (global-set-key [remap list-directory] #'consult-dir)
        (cond ((featurep 'vertico)
               (define-key vertico-map (kbd "C-x C-d") 'consult-dir)
               (define-key vertico-map (kbd "C-x C-j") 'consult-dir-jump-file))
              ((featurep 'selectrum)
               (define-key selectrum-minibuffer--map (kbd "C-x C-d") 'consult-dir)
               (define-key selectrum-minibuffer-map (kbd "C-x C-j") 'consult-dir-jump-file)))
        (define-key minibuffer-local-completion-map (kbd "C-x C-d") 'consult-dir)
        (define-key minibuffer-local-completion-map (kbd "C-x C-j") 'consult-dir-jump-file)
        
      • project
        (cond
         ((featurep 'projectile)
          (autoload 'projectile-project-root "projectile")
          (setq consult-project-root-function #'projectile-project-root))
         ((featurep 'project)
          (setq consult-project-root-function #'consult--project-root-default-function))
         ((featurep 'vc)
          (setq consult-project-root-function #'vc-root-dir)))
        
      • general
        • consult-register
          (with-eval-after-load 'config-general
            (progn
              (require 'general)
              (+config/leader-def
                :states '(normal visual)
                "/ry" 'consult-register-store
                "/rp" 'consult-register-load
                "/rr" 'consult-register)))
          
        • consult-bookmark
          (with-eval-after-load 'config-general
            (progn
              (require 'general)
              (+config/leader-def
                :states '(normal visual)
                "/bl" 'consult-bookmark)))
          
        • consult-recent-file
          (with-eval-after-load 'config-general
            (progn
              (require 'general)
              (+config/leader-def
                :states '(normal visual)
                "fF" 'consult-recent-file)))
          
        • consult-buffer
          (with-eval-after-load 'config-general
            (progn
              (require 'general)
              (+config/leader-def
                :states '(normal visual)
                "bb" 'consult-buffer)))
          
        • consult-imenu
          (with-eval-after-load 'config-general
            (progn
              (require 'general)
              (+config/leader-def
                :states '(normal visual)
                "si" 'consult-imenu
                "sI" 'consult-imenu-multi)))
          
        • consult-line
          (with-eval-after-load 'config-general
            (progn
              (require 'general)
              (+config/leader-def
                :states '(normal visual)
                "/l" 'consult-line
                "/L" 'consult-line-multi)))
          
        • consult-outline
          (with-eval-after-load 'config-general
            (progn
              (require 'general)
              (+config/leader-def
                :states '(normal visual)
                "/o" 'consult-outline)))
          
        • consult-global-mark
          (with-eval-after-load 'config-general
            (progn
              (require 'general)
              (+config/leader-def
                :states '(normal visual)
                "/bg" 'consult-global-mark)))
          
        • consult-find
          (with-eval-after-load 'config-general
            (progn
              (require 'general)
              (+config/leader-def
                :states '(normal visual)
                "sf" 'consult-find)))
          
        • consult-locate
          (with-eval-after-load 'config-general
            (progn
              (require 'general)
              (+config/leader-def
                :states '(normal visual)
                "sl" 'consult-locate)))
          
        • consult-grep
          (with-eval-after-load 'config-general
            (progn
              (require 'general)
              (+config/leader-def
                :states '(normal visual)
                "sg" 'consult-grep)))
          
        • consult-git-grep
          (with-eval-after-load 'config-general
            (progn
              (require 'general)
              (+config/leader-def
                :states '(normal visual)
                "sG" 'consult-git-grep)))
          
        • consult-ripgrep
          (with-eval-after-load 'config-general
            (progn
              (require 'general)
              (+config/leader-def
                :states '(normal visual)
                "sr" 'consult-ripgrep)))
          
        • consult-multi-occur
          (with-eval-after-load 'config-general
            (progn
              (require 'general)
              (+config/leader-def
                :states '(normal visual)
                "sm" 'consult-multi-occur)))
          
    • Footer
      (provide 'config-consult)
      ;;; config-consult.el ends here
      
  • embark
    header-args: :tangle (expand-file-name "modules/config-embark.el" user-emacs-directory)
    
    • header
      ;;; config-embark.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'embark))
      (when (featurep 'consult)
        (straight-use-package 'embark-consult))
      (require 'embark)
      
    • keybind
      (global-set-key [remap describe-bindings] #'embark-bindings)
      (global-set-key (kbd "C-c C-.") 'embark-act)
      
    • config
      (setq prefix-help-command #'embark-prefix-help-command)
      (add-to-list 'display-buffer-alist
                   '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
                     nil
                     (window-parameters (mode-line-format . none))))
      
    • consult integration
      (when (featurep 'consult)
        (require 'embark-consult)
        (add-hook 'embark-collect-mode-hook #'consult-preview-at-point-mode))
      
    • which-key integration
      (when (featurep 'which-key)
        (setq which-key-use-C-h-commands nil
              prefix-help-command #'embark-prefix-help-command))
      
    • Footer
      (provide 'config-embark)
      ;;; config-embark.el ends here
      
  • corfu
    header-args: :tangle (expand-file-name "modules/config-corfu.el" user-emacs-directory)
    
    • header
      ;;; config-corfu.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package '(corfu :files (:defaults "extensions/*")
                                      :includes (corfu-history
                                                 corfu-indexed
                                                 corfu-info
                                                 corfu-quick))))
      (require 'corfu)
      
    • variable
      ;;(customize-set-variable 'corfu-cycle t)
      (customize-set-variable 'corfu-auto t)
      ;;(customize-set-variable 'corfu-preselect-first t)
      (customize-set-variable 'corfu-quit-no-match 'separator)
      ;;(customize-set-variable 'corfu-separator ?\s)
      (setq completion-cycle-threshold 3
            tab-always-indent 'complete)
      
      (defun +corfu-enable-in-minibuffer ()
        "Enable Corfu in the minibuffer if `completion-at-point' is bound."
        (when (where-is-internal #'completion-at-point (list (current-local-map)))
          ;; (setq-local corfu-auto nil) Enable/disable auto completion
          (corfu-mode 1)))
      (add-hook 'minibuffer-setup-hook #'+corfu-enable-in-minibuffer)
      
      (add-hook 'eshell-mode-hook
                (lambda ()
                  (setq-local corfu-auto nil)
                  (corfu-mode)))
      
    • keybind
      (define-key corfu-map (kbd "TAB") 'corfu-next)
      (define-key corfu-map (kbd "S-TAB") 'corfu-previous)
      
      (defun +corfu-beginning-of-prompt ()
        "Move to beginning of completion input."
        (interactive)
        (corfu--goto -1)
        (goto-char (car completion-in-region--data)))
      
      (defun +corfu-end-of-prompt ()
        "Move to end of completion input."
        (interactive)
        (corfu--goto -1)
        (goto-char (cadr completion-in-region--data)))
      
      (define-key corfu-map [remap move-beginning-of-line] #'+corfu-beginning-of-prompt)
      (define-key corfu-map [remap move-end-of-line] #'+corfu-end-of-prompt)
      
      (global-corfu-mode)
      
    • all-the-icons integration
      (when (featurep' config-all-the-icons)
        (straight-use-package 'kind-icon)
        (require 'kind-icon)
        (customize-set-variable 'kind-icon-default-face 'corfu-default)
        (add-hook 'my-completion-ui-mode-hook
                  (lambda ()
                    (setq completion-in-region-function
                          (kind-icon-enhance-completion
                           completion-in-region-function)))))
      
    • corfu-doc
      (straight-use-package '(corfu-doc
                              :type git
                              :host github
                              :repo "galeo/corfu-doc"))
      (add-hook 'corfu-mode-hook #'corfu-doc-mode)
      (require 'corfu-history)
      (add-to-list 'savehist-additional-variables 'corfu-history)
      
    • Footer
      (provide 'config-corfu)
      ;;; config-corfu.el ends here
      
  • cape
    header-args: :tangle (expand-file-name "modules/config-cape.el" user-emacs-directory)
    
    • header
      ;;; config-cape.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (straight-use-package 'cape)
      
    • init
      (require 'cape)
      (add-to-list 'completion-at-point-functions #'cape-file)
      (add-to-list 'completion-at-point-functions #'cape-dabbrev)
      ;; (add-to-list 'completion-at-point-functions #'cape-history)
      ;; (add-to-list 'completion-at-point-functions #'cape-keyword)
      ;; (add-to-list 'completion-at-point-functions #'cape-tex)
      ;; (add-to-list 'completion-at-point-functions #'cape-sgml)
      ;; (add-to-list 'completion-at-point-functions #'cape-rfc1345)
      ;; (add-to-list 'completion-at-point-functions #'cape-abbrev)
      ;; (add-to-list 'completion-at-point-functions #'cape-ispell)
      ;; (add-to-list 'completion-at-point-functions #'cape-dict)
      ;; (add-to-list 'completion-at-point-functions #'cape-symbol)
      ;; (add-to-list 'completion-at-point-functions #'cape-line)
      
    • keybinding
      (global-set-key (kbd "C-S-c p C-<return>") 'completion-at-point)
      (global-set-key (kbd "C-S-c p t") 'complete-tag)
      (global-set-key (kbd "C-S-c p d") 'cape-dabbrev)
      (global-set-key (kbd "C-S-c p h") 'cape-history)
      (global-set-key (kbd "C-S-c p f") 'cape-file)
      (global-set-key (kbd "C-S-c p k") 'cape-keyword)
      (global-set-key (kbd "C-S-c p s") 'cape-symbol)
      (global-set-key (kbd "C-S-c p a") 'cape-abbrev)
      (global-set-key (kbd "C-S-c p i") 'cape-ispell)
      (global-set-key (kbd "C-S-c p l") 'cape-line)
      (global-set-key (kbd "C-S-c p w") 'cape-dict)
      (global-set-key (kbd "C-S-c p \\") 'cape-tex)
      (global-set-key (kbd "C-S-c p _") 'cape-tex)
      (global-set-key (kbd "C-S-c p ^") 'cape-tex)
      (global-set-key (kbd "C-S-c p &") 'cape-sgml)
      (global-set-key (kbd "C-S-c p r") 'cape-rfc1345)
      
    • Footer
      (provide 'config-cape)
      ;;; config-cape.el ends here
      
  • dabbrev
    header-args: :tangle (expand-file-name "modules/config-dabbrev.el" user-emacs-directory)
    
    • header
      ;;; config-dabbrev.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (straight-use-package 'dabbrev)
      
    • config
      (require 'dabbrev)
      (global-set-key (kbd "M-/") 'dabbrev-completion)
      (global-set-key (kbd "C-M-/") 'dabbrev-expand)
      (customize-set-variable 'dabbrev-ignored-buffer-regexps '("\\.\\(?:pdf\\|jpe?g\\|png\\)\\'"))
      
    • Footer
      (provide 'config-dabbrev)
      ;;; config-dabbrev.el ends here
      

Footer

(provide 'config-defaults-completion)
;;; config-defaults-completion.el ends here

Default Tools

header-args: :tangle (expand-file-name "modules/config-defaults-tools.el" user-emacs-directory)

header

;; config-defaults-tools.el --- Summary -*- lexical-binding: t -*-
;; Commentary:
;; This file is auto-generated from `config.org'
;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
;; Code:
(require 'config-defaults-variables)

quicklisp

;; quicklisp
(if (file-directory-p
     (expand-file-name
      ".ros/lisp/quicklisp"
      (getenv "HOME")))
    (defvar +quicklisp-path
      (expand-file-name
       ".ros/lisp/quicklisp"
       (getenv "HOME")))
  (when (file-directory-p
         (expand-file-name
          ".local/share/quicklisp"
          (getenv "HOME")))
    (defvar +quicklisp-path
      (expand-file-name
       ".local/share/quicklisp"
       (getenv "HOME")))))

ros

(cond ((and (executable-find "ros")
            (file-exists-p
             (expand-file-name
              ".roswell/helper.el"
              (getenv "HOME"))))
       (progn
         (load
          (expand-file-name
           ".roswell/helper.el"
           (getenv "HOME")))
         (setq inferior-lisp-program "ros -Q -l ~/.sbclrc run")))
      ((executable-find "sbcl")
       (setq inferior-lisp-program "sbcl")))
;; (setq max-lisp-eval-depth 32000
;;       max-specpdl-size 32000)

erc

  • auto connect based on server
    (customize-set-variable 'erc-nick user-login-name)
    (customize-set-variable 'erc-user-full-name user-full-name)
    
    (require 'config-pass)
    (defun +erc/libera ()
      (erc-tls :server "irc.libera.chat"
               :port "7070"))
    
    (add-hook 'erc-after-connect
              `(lambda (SERVER NICK)
                 (cond
                  ((string-match "irc\\.libera\\.chat" SERVER)
                   (erc-message "PRIVMSG" (concat "NickServ identify " (password-store-get "irc.libera.chat/alexforsale")))))))
    
  • autojoin
    (require 'erc)
    (require 'erc-join)
    
    (setq erc-autojoin-timing 'ident)
    (erc-autojoin-mode 1)
    (setq erc-autojoin-channels-alist
          '(("Libera.Chat" "#emacs" "#emacs-beginners" "gnus" "#archlinux"
             "archlinux-offtopic" "guix" "gentoo" )))
    ;;(erc-tls :server "irc.libera.chat" :port 7070 :nick user-login-name :password (password-store-get "irc.libera.chat/alexforsale"))
    (setq erc-rename-buffers t)
    (setq erc-interpret-mirc-color t)
    (setq erc-kill-buffer-on-part t)
    (setq erc-kill-queries-on-quit t)
    (setq erc-kill-server-buffer-on-quit t)
    (require 'erc-services)
    (setq erc-nickserv-identify-mode 'both)
    (erc-services-mode 1)
    
  • only notify when nick or keywords mentioned.
    (setq erc-current-nick-highlight-type 'nick)
    (setq erc-keywords '("\\berc[-a-z]*\\b" "\\bemms[-a-z]*\\b"))
    
    (setq erc-track-exclude-types '("JOIN" "PART" "QUIT" "NICK" "MODE"))
    (setq erc-track-use-faces t)
    (setq erc-track-faces-priority-list
          '(erc-current-nick-face erc-keyword-face))
    (setq erc-track-priority-faces-only 'all)
    

Additional Packages

  • password-store
    header-args: :tangle (expand-file-name "modules/config-pass.el" user-emacs-directory)
    
    • header
      ;;; config-defaults-tools.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'pass)
        (straight-use-package 'password-store)
        (straight-use-package 'password-store-otp))
      
    • config
      (setq password-store-password-length 12)
      (auth-source-pass-enable)
      
    • Footer
      (provide 'config-pass)
      ;;; config-pass.el ends here
      
  • magit
    header-args: :tangle (expand-file-name "modules/config-magit.el" user-emacs-directory)
    
    • header
      ;;; config-magit.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'magit)
        (straight-use-package 'diff-hl))
      
    • config
      (customize-set-variable 'transient-levels-file (expand-file-name "transient/levels.el" +emacs-data-dir))
      (customize-set-variable 'transient-values-file (expand-file-name "transient/values.el" +emacs-data-dir))
      (customize-set-variable 'transient-history-file (expand-file-name "transient/history.el" +emacs-data-dir))
      (require 'magit)
      (require 'diff-hl)
      (transient-append-suffix 'magit-log "a"
        '("w" "Wip" magit-wip-log-current))
      (transient-append-suffix 'magit-log "-A"
        '("-m" "Omit merge commits" "--no-merges"))
      (setq magit-log-arguments '("-n100" "--graph" "--decorate"))
      (add-hook 'magit-pre-refresh-hook #'diff-hl-magit-pre-refresh)
      (add-hook 'magit-post-refresh-hook #'diff-hl-magit-post-refresh)
      (add-hook 'magit-mode-hook #'hl-line-mode)
      
    • Add keybinding if missing
      (unless (key-binding (kbd "C-x g"))
        (if (featurep 'evil)
            (+config/leader-def
              :states '(normal visual)
              "gg" 'magit-status)
          (global-set-key (kbd "C-x g") 'magit-status)))
      
    • Footer
      (provide 'config-magit)
      ;;; config-magit.el ends here
      
  • git-modes
    header-args: :tangle (expand-file-name "modules/config-git-modes.el" user-emacs-directory)
    
    • header
      ;;; config-git-modes.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (straight-use-package 'git-modes)
      
    • config
      (add-to-list 'auto-mode-alist
                   (cons "/.dockerignore\\'" 'gitignore-mode)
                   (cons "/.griveignore\\'" 'gitignore-mode))
      
    • Footer
      (provide 'config-git-modes)
      ;;; config-git-modes.el ends here
      
  • slime
    header-args: :tangle (expand-file-name "modules/config-slime.el" user-emacs-directory)
    
    • header
      ;;; config-slime.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'slime))
      (require 'slime)
      
    • config
      (when (file-exists-p (expand-file-name "slime-helper.el" +quicklisp-path))
        (load (expand-file-name "slime-helper.el" +quicklisp-path))
        (slime-setup '(slime-fancy)))
      (defun slime-description-fontify ()
        "Fontify sections of SLIME Description."
        (with-current-buffer "*SLIME Description*"
          (highlight-regexp
           (concat "^Function:\\|"
                   "^Macro-function:\\|"
                   "^Its associated name.+?) is\\|"
                   "^The .+'s arguments are:\\|"
                   "^Function documentation:$\\|"
                   "^Its.+\\(is\\|are\\):\\|"
                   "^On.+it was compiled from:$")
           'hi-green-b)))
      
      (defadvice slime-show-description (after slime-description-fontify activate)
        "Fontify sections of SLIME Description."
        (slime-description-fontify))
      
    • Footer
      (provide 'config-slime)
      ;;; config-slime.el ends here
      
  • sly
    header-args: :tangle (expand-file-name "modules/config-sly.el" user-emacs-directory)
    
    • header
      ;;; config-sly.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'sly))
      (require 'sly-autoloads)
      
    • config
      ;; (add-hook 'emacs-lisp-mode-hook #'sly-mode)
      ;; (add-hook 'eval-expression-minibuffer-setup-hook #'sly--mode)
      ;; (add-hook 'ielm-mode-hook #'sly-mode)
      ;; (add-hook 'lisp-mode-hook #'sly-mode)
      ;; (add-hook 'sly-editing-mode #'sly-mode)
      ;; (add-hook 'sly-mode #'sly-mode)
      ;; (add-hook 'lisp-interaction-mode-hook #'sly-mode)
      ;; (add-hook 'scheme-mode-hook #'sly-mode)
      ;; (add-hook 'comint-mode-hook #'sly-mode)
      (add-hook 'sly-mode-hook
                (lambda ()
                  (unless (sly-connected-p)
                    (save-excursion (sly)))))
      (setq sly-contribs '(sly-fancy
                           sly-fontifying-fu
                           sly-profiler
                           sly-retro
                           sly-scratch))
      
    • Footer
      (provide 'config-sly)
      ;;; config-sly.el ends here
      
  • paredit
    header-args: :tangle (expand-file-name "modules/config-paredit.el" user-emacs-directory)
    
    • header
      ;;; config-paredit.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'paredit))
      (require 'paredit)
      
    • config
      (add-hook 'emacs-lisp-mode-hook #'enable-paredit-mode)
      (add-hook 'eval-expression-minibuffer-setup-hook #'enable-paredit-mode)
      (add-hook 'ielm-mode-hook #'enable-paredit-mode)
      (add-hook 'lisp-mode-hook #'enable-paredit-mode)
      (add-hook 'sly-editing-mode #'enable-paredit-mode)
      (add-hook 'sly-mode #'enable-paredit-mode)
      (add-hook 'lisp-interaction-mode-hook #'enable-paredit-mode)
      (add-hook 'scheme-mode-hook #'enable-paredit-mode)
      (require 'eldoc)
      (eldoc-add-command
       'paredit-backward-delete
       'paredit-close-round)
      (add-hook 'slime-repl-mode-hook (lambda () (paredit-mode +1)))
      ;; Stop SLIME's REPL from grabbing DEL,
      (defun override-slime-repl-bindings-with-paredit ()
        (define-key slime-repl-mode-map
          (read-kbd-macro paredit-backward-delete-key) nil))
      (add-hook 'slime-repl-mode-hook 'override-slime-repl-bindings-with-paredit)
      
    • Footer
      (provide 'config-paredit)
      ;;; config-paredit.el ends here
      
  • telega
    header-args: :tangle (expand-file-name "modules/config-telega.el" user-emacs-directory)
    
    • header
      ;;; config-telega.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      (require 'config-all-the-icons)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'telega))
      
    • config
      (unless +config/is-guix-system
        (customize-set-variable 'telega-server-libs-prefix "/usr"))
      (when (string= "berkeley-unix" system-type)
        (customize-set-variable 'telega-server-libs-prefix "/usr/local"))
      (customize-set-variable 'telega-directory (expand-file-name "telega/" +emacs-data-dir))
      (customize-set-variable 'telega-options-plist '(:online t :is-location-visible t))
      (customize-set-variable 'telega-my-location '(:latitude -6.241586 :longitude 106.992416))
      (customize-set-variable 'telega-use-image t)
      (customize-set-variable 'telega-voip-allow-p2p t)
      (customize-set-variable 'telega-appindicator-use-label t)
      (customize-set-variable 'telega-active-locations-show-avatars t)
      (customize-set-variable 'telega-appindicator-icon-colors
                              '((offline "#ffffff" "#000000" nil)
                                (online "#ffffff" "#000000" "#00ff00")
                                (connecting "gray" "white" "white")))
      
      (add-hook 'telega-load-hook 'telega-notifications-mode)
      ;; not needed with notification
      ;;(add-hook 'telega-load-hook 'telega-mode-line-mode)
      (add-hook 'telega-load-hook 'telega-appindicator-mode)
      (add-hook 'telega-open-file-hook 'telega-edit-file-mode)
      (add-hook 'telega-load-hook 'telega-my-location-mode)
      ;; needs better keybind
      (add-hook 'telega-load-hook
                (lambda ()
                  (define-key global-map (kbd "C-c t T") telega-prefix-map)))
      (require 'telega)
      ;; contrib packages
      ;; org-mode links
      (require 'ol-telega)
      (customize-set-variable 'telega-status-history-logs-dir (expand-file-name "telega/history/" +emacs-data-dir))
      (require 'telega-status-history)
      (add-hook 'telega-load-hook 'global-telega-url-shorten-mode)
      (require 'telega-url-shorten)
      (customize-set-variable 'telega-url-shorten-use-images t)
      (straight-use-package 'language-detection)
      (require 'language-detection)
      (require 'telega-mnz)
      (add-hook 'telega-load-hook 'global-telega-mnz-mode)
      (require 'telega-transient)
      (telega-transient-mode 1)
      (require 'telega-dashboard)
      (add-to-list 'dashboard-items '(telega-chats . 5))
      ;;(require 'telega-stories)
      ;;(telega-stories-mode 1)
      ;;(define-key telega-root-mode-map (kbd "v e") 'telega-view-emacs-stories)
      ;;(add-to-list 'dashboard-items '(telega-stories . 5))
      
    • Footer
      (provide 'config-telega)
      ;;; config-telega.el ends here
      
  • emms
    header-args: :tangle (expand-file-name "modules/config-emms.el" user-emacs-directory)
    
    • header
      ;;; config-emms.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'emms)
        (straight-use-package 'lyrics-fetcher)
        (straight-use-package 'org-emms))
      
    • config
      (customize-set-variable 'emms-directory (expand-file-name "emms" +emacs-data-dir))
      (customize-set-variable 'emms-player-mpv-update-metadata t)
      
      (add-hook 'emms-player-started-hook 'emms-show)
      (require 'emms-setup)
      (require 'emms-history)
      (require 'emms-source-file)
      (require 'emms-source-playlist)
      ;;(require 'emms-librefm-scrobbler)
      (require 'emms-lyrics)
      (require 'config-pass)
      (emms-all)
      (emms-default-players)
      (emms-cache-enable)
      
      ;; history
      (emms-history-load)
      (setq emms-source-file-default-directory +emms-music-dir
            emms-lyrics-dir (expand-file-name ".lyrics/" +emms-music-dir)
            emms-lyrics-display-buffer t
            emms-random-playlist t
            emms-repeat-playlist t
            emms-browser-covers #'emms-browser-cache-thumbnail-async
            emms-source-playlist-default-format 'm3u
            emms-playlist-mode-center-when-go t
            emms-playlist-default-major-mode 'emms-playlist-mode
            emms-show-format "NP: %s"
            emms-playlist-buffer-name "*Music*"
            emms-player-mpv-environment '("PULSnE_PROP_media.role=music")
            emms-player-mpv-parameters '("--quiet" "--really-quiet" "--no-audio-display" "--force-window=no" "--vo=null"))
      ;;(setq emms-librefm-scrobbler-username (user-login-name))
      ;;(setq emms-librefm-scrobbler-password (password-store-get (concat "libre.fm/" (user-login-name))))
      
      ;;(when emms-librefm-scrobbler-password
      ;;  (emms-librefm-scrobbler-enable))
      
      (when (not (directory-name-p emms-lyrics-dir))
        (make-directory emms-lyrics-dir :parents))
      
    • Lyrics-fetcher
      ;; lyrics-fetcher
      (setq lyrics-fetcher-lyrics-folder emms-lyrics-dir)
      (lyrics-fetcher-use-backend 'neteasecloud)
      
    • Setup player based on executables.
      (setq emms-player-list nil)
      (when (executable-find "vlc")
        (add-to-list 'emms-player-list 'emms-player-vlc)
        (add-to-list 'emms-player-list 'emms-player-vlc-playlist))
      (when (executable-find "mpeg123")
        (add-to-list 'emms-player-list 'emms-player-mpg321))
      (when (executable-find "mplayer")
        (add-to-list 'emms-player-list 'emms-player-mplayer)
        (add-to-list 'emms-player-list 'emms-player-mplayer-playlist))
      (when (executable-find "mpv")
        (add-to-list 'emms-player-list 'emms-player-mpv))
      (when (executable-find "xine")
        (add-to-list 'emms-player-list 'emms-player-xine))
      (when (executable-find "mikmod")
        (add-to-list 'emms-player-list 'emms-player-mikmod))
      
    • emms-player-mpd
      (defun +config/emms-set-mpd (&optional name port passwd)
        "Set `emms' to use mpd, use arguments NAME, PORT and PASSWD."
        (interactive)
        (require 'emms-player-mpd)
        (if name
            (setq emms-player-mpd-server-name name)
          (setq emms-player-mpd-server-name "localhost"))
        (if port
            (setq emms-player-mpd-server-port port)
          (setq emms-player-mpd-server-port "6600"))
        (if passwd
            (setq emms-player-mpd-server-password passwd))
        (add-to-list 'emms-info-functions 'emms-info-mpd)
        (add-to-list 'emms-player-list 'emms-player-mpd)
        (require 'emms-volume)
        (setq emms-volume-change-function 'emms-volume-mpd-change))
      
    • notification
      (defvar notify-method 'nil
        "Method for sending notifications.")
      
      ;; choose D-Bus to disseminate messages, if it is running.
      (cond
       ;; test to see if D-Bus notifications are available
       ((if (and (require 'dbus nil t)
                 (dbus-ping :session "org.freedesktop.Notifications"))
            (progn
              (setq notify-method 'notify-via-dbus-notifications)
              (require 'notifications))))
       ;; could use the message system otherwise
       (t (setq notify-method 'notify-via-message)))
      
      (defun notify-via-notifications (title msg icon)
        "Send notification with TITLE, MSG via `D-Bus'."
        (notifications-notify
         :title title
         :body msg
         :app-icon icon
         :urgency 'low))
      
      (defun notify-via-messages (title msg)
        "Send notification with TITLE, MSG to message."
        (message "APPOINTMENT: %s" msg))
      
      (defun emms-notifications-dbus (track-name)
        "Share track name via `D-Bus'."
        (let ((icon "/usr/share/icons/gnome/24x24/categories/applications-multimedia.png"))
          (notify-via-notifications "EMMS is now playing:" track-name icon)))
      
      (defun emms-notifications-message (track-name)
        "Share track name via Emacs minibuffer."
        (message "EMMS is now playing: %s" track-name))
      
      (setq emms-player-next-function 'emms-notify-and-next)
      
      (defun emms-notify-and-next ()
        "Send a notification of track and start next."
        (emms-next-noerror)
        (let ((track-name (emms-track-description (emms-playlist-current-selected-track))))
          (cond
           ((eq notify-method 'notify-via-dbus-notifications)
            (emms-notifications-dbus track-name))
           (t (emms-notifications-message track-name)))))
      
    • Footer
      (provide 'config-emms)
      ;;; config-emms.el ends here
      
  • w3m
    header-args: :tangle (expand-file-name "modules/config-w3m.el" user-emacs-directory)
    
    • header
      ;;; config-w3m.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'w3m))
      
    • config
      (when (executable-find "w3m")
        (require 'w3m)
        (require 'w3m-bookmark)
        ;;(setq browse-url-browser-function 'w3m-goto-url-new-session)
        (setq w3m-home-page "http://www.google.com")
        (setq w3m-use-cookies t)
        (setq w3m-use-header-line-title t)
        (setq w3m-cookie-accept-bad-cookies t)
        (setq w3m-view-this-url-new-session-in-background t)
        (setq w3m-new-session-in-background t)
        (setq w3m-session-time-format "%Y-%m-%d %A %H:%M")
        (setq w3m-favicon-use-cache-file t)
        (setq w3m-show-graphic-icons-in-mode-line t)
        (setq w3m-keep-arrived-urls 50000)
        (setq w3m-keep-cache-size 1000)
        (setq w3m-edit-function (quote find-file-other-window))
        (setq w3m-session-automatic-save t)
        (setq w3m-session-deleted-save nil)
        (setq w3m-default-display-inline-images nil)
        (setq w3m-toggle-inline-images-permanently t)
        (setq w3m-enable-google-feeling-lucky nil)
        (setq w3m-use-filter t)
        (setq w3m-filter-google-separator "")
        (setq w3m-fb-mode t)
        (setq w3m-session-load-crashed-sessions t)
        (setq w3m-bookmark-file-coding-system 'utf-8)
        (setq w3m-file-coding-system 'utf-8)
        (setq w3m-file-name-coding-system 'utf-8)
        (setq w3m-coding-system 'utf-8)
        (setq w3m-default-coding-system 'utf-8)
        (w3m-fb-mode 1))
      
    • directories
      (setq w3m-default-save-directory (getenv "XDG_DOWNLOAD_DIR"))
      (setq w3m-bookmark-file (expand-file-name "w3m/bookmarks.html" +emacs-data-dir))
      (setq w3m-cookie-file (expand-file-name "w3m/cookies" +emacs-data-dir))
      (setq w3m-session-file (expand-file-name "w3m/sessions" +emacs-data-dir))
      
    • Footer
      (provide 'config-w3m)
      ;;; config-w3m.el ends here
      
  • pdf-tools
    header-args: :tangle (expand-file-name "modules/config-pdf-tools.el" user-emacs-directory)
    
    • header
      ;;; config-pdf-tools.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (unless +config/is-guix-system
        (straight-use-package 'pdf-tools)
        (pdf-loader-install))
      
    • Footer
      (provide 'config-pdf-tools)
      ;;; config-pdf-tools.el ends here
      
  • gist
    header-args: :tangle (expand-file-name "modules/config-gist.el" user-emacs-directory)
    
    • header
      ;;; config-gist.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (straight-use-package 'gist)
      
    • Footer
      (provide 'config-gist)
      ;;; config-gist.el ends here
      
  • ripgrep
    header-args: :tangle (expand-file-name "modules/config-ripgrep.el" user-emacs-directory)
    
    • header
      ;;; config-ripgrep.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (straight-use-package 'ripgrep)
      
    • Footer
      (provide 'config-ripgrep)
      ;;; config-ripgrep.el ends here
      
  • restart-emacs
    header-args: :tangle (expand-file-name "modules/config-restart-emacs.el" user-emacs-directory)
    
    • header
      ;;; config-restart-emacs.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (straight-use-package 'restart-emacs)
      
    • Footer
      (provide 'config-restart-emacs)
      ;;; config-restart-emacs.el ends here
      
  • hugo
    header-args: :tangle (expand-file-name "modules/config-hugo.el" user-emacs-directory)
    
    • header
      ;;; config-hugo.el --- Summary -*- lexical-binding: t -*-
      ;;; Commentary:
      ;; This file is auto-generated from `config.org'
      ;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
      ;;; Code:
      (require 'config-defaults-variables)
      
    • package
      (straight-use-package 'ox-hugo)
      
    • variables
      (defvar +config/blog-dir (expand-file-name "blog" org-directory)
        "Blog directory, relative to `org-directory'.")
      (defvar +config/ox-hugo-en-file (expand-file-name "content-org/posts.en.org" +config/blog-dir)
        "Blog file for `hugo'.")
      (defvar +config/ox-hugo-id-file (expand-file-name "content-org/posts.id.org" +config/blog-dir)
        "Blog file for `hugo'.")
      (defvar +config/ox-hugo-heading "Blog Ideas"
        "Heading for org-capture inside `+config/ox-hugo-file'.")
      
    • config
      (require 'ox)
      (require 'ox-hugo)
      
    • capture template
      ;; Populates only the EXPORT_FILE_NAME property in the inserted heading.
      (with-eval-after-load 'org-capture
        (defun org-hugo-new-subtree-post-capture-template ()
          "Returns `org-capture' template string for new Hugo post.
                                                                      See `org-capture-templates' for more information."
          (let* ((title (read-from-minibuffer "Post Title: ")) ;Prompt to enter the post title
                 (fname (org-hugo-slug title)))
            (mapconcat #'identity
                       `(
                         ,(concat "* TODO " title)
                         ":PROPERTIES:"
                         ,(concat ":EXPORT_FILE_NAME: " fname)
                         ":END:"
                         "%?\n")          ;Place the cursor here finally
                       "\n")))
      
        (setq org-capture-templates
              (append org-capture-templates
                      `(("h" "(h)ugo")
                        ("he"  "Hugo (e)nglish post"               ;`org-capture' binding + h
                         entry
                         ;; It is assumed that below file is present in `org-directory'
                         ;; and that it has a "Blog Ideas" heading. It can even be a
                         ;; symlink pointing to the actual location of all-posts.org!
                         (file+olp ,+config/ox-hugo-en-file ,+config/ox-hugo-heading)
                         (function org-hugo-new-subtree-post-capture-template))
                        ("hi"  "Hugo (i)ndonesian post"               ;`org-capture' binding + h
                         entry
                         ;; It is assumed that below file is present in `org-directory'
                         ;; and that it has a "Blog Ideas" heading. It can even be a
                         ;; symlink pointing to the actual location of all-posts.org!
                         (file+olp ,+config/ox-hugo-id-file ,+config/ox-hugo-heading)
                         (function org-hugo-new-subtree-post-capture-template))))))
      
    • start hugo server function
      (defun +config/start-hugo-server (args)
        "Start hugo server in `+config/blog-dir'."
        (interactive (list (transient-args '+config/transient-hugo-server)))
        (if (not (executable-find "hugo"))
            (message "hugo executable not found")
          (let ((default-directory +config/blog-dir)
                (command "hugo server"))
            (async-shell-command (mapconcat #'identity `(,command ,@args) " ") "*hugo*" "*hugo-error*"))))
      
    • transient define
      (require 'transient)
      (transient-define-prefix +config/transient-hugo-server ()
        "Run hugo server with `transient'."
        :man-page "hugo-server"
        ["Options"
         ("-D" "Build drafts" "--buildDrafts")
         ("-E" "Build expired" "--buildExpired")
         ("-F" "Build future" "--buildFuture")
         ("d" "Debug" "--debug")
         ("B" "Disable build errors on browser" "--disableBrowserError")
         ("c" "Clean destination dir" "--cleanDestinationDir")
         ("e" "Enable Git info" "--enableGitInfo")
         ("F" "enable full re-renders on changes" "--disableFastRender")
         ("f" "Force sync static files" "--forceSyncStatic")
         ("g" "enable to run some cleanup tasks" "--gc")
         ("m" "Minify any supported output format" "--minify")
         ("C" "No chmod" "--noChmod")
         ("T" "Don't sync modification time of files" "--noTimes")
         ("I" "Print missing translation" "--printI18nWarnings")
         ("M" "Print memory usage" "--printMemoryUsage")
         ("P" "Print warning on duplicate target path" "--printPathWarnings")
         ("q" "Quiet" "--quiet")
         ("v" "Verbose" "--verbose")
         ("w" "Watch filesystem for changes" "--watch")]
        ["Action"
         ("s" "hugo server" +config/start-hugo-server)])
      
    • general keybinding
      (with-eval-after-load 'general
        (+config/leader-def
          :states '(normal visual)
          "H" '(:ignore t :whick-key "Hugo prefix")
          "Hs" '+config/transient-hugo-server))
      
    • Footer
      (provide 'config-hugo)
      ;;; config-hugo.el ends here
      

Footer

(provide 'config-defaults-tools)
;;; config-defaults-tools.el ends here

Various other defaults

header-args: :tangle (expand-file-name "modules/config-defaults-various.el" user-emacs-directory)
;;; config-defaults-editings.el --- Summary -*- lexical-binding: t -*-
;;; Commentary:
;; This file is auto-generated from `config.org'
;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
;;; Code:

desktop-save-mode

(eval-after-load 'desktop
  `(make-directory ,(expand-file-name "desktop/" +emacs-data-dir) t))
(setq desktop-dirname (expand-file-name "desktop/" +emacs-data-dir))
(setq desktop-path (list desktop-dirname))

Browser

(setq browse-url-generic-program "xdg-open")

calendar and diary

(require 'calendar)
(setq diary-file "~/Documents/google-drive/Notes/diary")
(add-hook 'diary-list-entries-hook 'diary-sort-entries t)
(setq calendar-intermonth-spacing 1)

calc file

(setq calc-settings-file (expand-file-name "calc-settings.el" +emacs-data-dir))

ecomplete database

(setq ecomplete-database-file (expand-file-name "ecomplete-database.el" +emacs-data-dir))

ede cache file

(setq ede-project-placeholder-cache-file (expand-file-name "ede-projects.el" +emacs-data-dir))

erc

(eval-after-load 'erc
  `(make-directory ,(expand-file-name "erc/dcc/" +emacs-data-dir) t))
(setq erc-dcc-get-default-directory    (expand-file-name "erc/dcc/" +emacs-data-dir))
(setq erc-log-channels-directory       (expand-file-name "erc/log-channels/" +emacs-data-dir))

eshell

(eval-after-load 'eshell
  `(make-directory ,(expand-file-name "eshell/" +emacs-data-dir) t))
(setq eshell-aliases-file              (expand-file-name "eshell/aliases" +emacs-data-dir))
(setq eshell-directory-name            (expand-file-name "eshell/" +emacs-data-dir))

eudc

(setq eudc-options-file (expand-file-name "eudc-options.el" +emacs-data-dir))

eww

(with-eval-after-load 'eww
  `(make-directory ,(expand-file-name "eww/" +emacs-data-dir) t)
  (setq eww-bookmarks-directory (expand-file-name "eww/" +emacs-data-dir)))

gnus

(with-eval-after-load 'gnus
  `(make-directory ,(expand-file-name "gnus/dribble/" +emacs-data-dir) t)
  (setq gnus-dribble-directory (expand-file-name "gnus/dribble/" +emacs-data-dir))
  (setq gnus-init-file (expand-file-name "gnus/init.el" +emacs-data-dir)))

ido

(eval-after-load 'ido
  (setq ido-save-directory-list-file (expand-file-name "ido-save-directory-list.el" +emacs-data-dir)))

dired

(with-eval-after-load 'dired
  (setq image-dired-db-file (expand-file-name "image-dired/db.el" +emacs-data-dir))
  (setq image-dired-dir (expand-file-name "image-dired/" +emacs-data-dir))
  (setq image-dired-gallery-dir (expand-file-name "image-dired/gallery/" +emacs-data-dir))
  (setq image-dired-temp-image-file (expand-file-name "image-dired/temp-image" +emacs-data-dir))
  (setq image-dired-temp-rotate-image-file (expand-file-name "image-dired/temp-rotate-image" +emacs-data-dir)))
(add-hook 'dired-load-hook
          (function (lambda () (load "dired-x"))))

newsticker

(with-eval-after-load 'newsticker
  `(make-directory ,(expand-file-name "newsticker/" +emacs-data-dir) t)
  (setq newsticker-cache-filename (expand-file-name "newsticker/cache.el" +emacs-data-dir))
  (setq newsticker-dir (expand-file-name "newsticker/data/" +emacs-data-dir)))

nsm

(eval-after-load 'nsm
  (setq nsm-settings-file (expand-file-name "nsm-settings.el" +emacs-data-dir)))

tramp

(setq tramp-auto-save-directory (expand-file-name "tramp/auto-save/" +emacs-data-dir))
(setq tramp-persistency-file-name (expand-file-name "tramp/persistency.el" +emacs-data-dir))
(setq remote-file-name-inhibit-cache 60
      tramp-completion-reread-directory-timeout 60
      tramp-verbose 1
      vc-ignore-dir-regexp (format "%s\\|%s\\|%s"
                                   vc-ignore-dir-regexp
                                   tramp-file-name-regexp
                                   "[/\\\\]node_modules"))

shadowfile

(with-eval-after-load 'shadowfile
  `(make-directory ,(expand-file-name "shadow/" +emacs-data-dir) t)
  (setq shadow-info-file (expand-file-name "shadow/info.el" +emacs-data-dir))
  (setq shadow-todo-file (expand-file-name "shadow/todo.el" +emacs-data-dir)))

url

(with-eval-after-load 'url
  (setq url-cache-directory (expand-file-name "url/cache/" +emacs-data-dir))
  (setq url-configuration-directory (expand-file-name "url/" +emacs-data-dir))
  (setq url-cookie-file (expand-file-name "url/cookies.el" +emacs-data-dir))
  (setq url-history-file (expand-file-name "url/history.el" +emacs-data-dir)))

remember

(with-eval-after-load 'remember
  (setq remember-data-file (expand-file-name "remember/data" +emacs-data-dir))
  (setq remember-data-directory (expand-file-name "remember/data.d/" +emacs-data-dir)))

epg

(if (executable-find "gpg2")
    (customize-set-variable 'epg-gpg-program "gpg2")
  (customize-set-variable 'epg-gpg-program "gpg"))

Footer

(provide 'config-defaults-various)
;;; config-defaults-various.el ends here

Defaults keybindings

header-args: :tangle (expand-file-name "modules/config-defaults-keybindings.el" user-emacs-directory)
;;; config-defaults-keybindings.el --- Summary -*- lexical-binding: t -*-
;;; Commentary:
;; This file is auto-generated from `config.org'
;; See `https://java281.dynv6.net/~alexforsale/posts/Emacs-Configuration.html'
;;; Code:

recentf

Previously unbound

(global-set-key (kbd "C-x M-f") 'recentf-open-files)

Footer

(provide 'config-defaults-keybindings)
;;; config-defaults-keybindings.el ends here

site-lisp

set footer for config.el

header-args: :tangle (expand-file-name "config.el" user-emacs-directory)
(require 'config-defaults)
(provide 'config)
;;; config.el ends here