The noweb-ref
headers, such as the one below, are adapted from Melioratus’s answer here.
This way, I can maintain some semblance of a literate config.
#+begin_src emacs-lisp :noweb-ref no :tangle (meq/tangle-path)
<<early-init.el>>
#+end_src
Start off by specifying the user-emacs-directory
:
;;; $EMACSDIR/early-init.el -*- lexical-binding: t; -*- no-byte-compile: t -*-
(defvar user-emacs-directory (file-name-directory (or load-file-name buffer-file-name)))
If I ever need it, this will give me the initial directory I was in; the code is adapted from Stefan’s answer here:
(setq meq/var/initial-directory default-directory)
Advise message
to not show messages about creating autoloads and Library is file
, then remove it after initialization:
(defun meq/message (func &rest args) (interactive)
(let* ((*message (apply #'format args)))
;; NOTE: THE SPACE BEFORE `CREATING' IS MEANT TO BE THERE!
(unless (or (string-prefix-p " Creating" *message)
(string-prefix-p "Configuring" *message)
(string-prefix-p "Loading" *message)
(string-prefix-p "Library is file" *message))
(apply func args))))
(advice-add #'message :around #'meq/message)
(add-hook 'after-init-hook #'(lambda nil (interactive) (advice-remove #'message #'meq/message)))
Define preliminary versions of meq/item-in-cla, meq/get-next-in-cla, and meq/*two-items-in-cla:
(defun meq/*item-in-cla (item) (unwind-protect (member item command-line-args) (delete item command-line-args)))
(defun meq/*get-next-in-cla (item)
(let* ((index (seq-position command-line-args item))
(value (when index (nth (1+ index) command-line-args))))
(when value (unwind-protect value (delete value command-line-args)))))
(defun meq/*two-items-in-list (item) (unwind-protect (when (member item command-line-args) (meq/*get-next-in-cla item)) (delete item command-line-args)))
Check if we’re bootstrapping the system, and whether we want reinstall the packages:
(defvar meq/var/bootstrap (meq/*item-in-cla "--bootstrap"))
(defvar meq/var/force-bootstrap (meq/*item-in-cla "--force-bootstrap"))
This sets up various system-related variables, all fairly descriptive on their own:
(defvar meq/var/windows (member system-type '(windows-nt ms-dos)))
(defvar meq/var/slash (if meq/var/windows "\\" "/"))
(defvar meq/var/phone (ignore-errors (string-match-p (regexp-quote "Android") (shell-command-to-string "uname -a"))))
(defvar meq/var/wsl (ignore-errors (string-match-p (regexp-quote "microsoft-standard-WSL") (shell-command-to-string "uname -a"))))
(defvar meq/var/nixos (ignore-errors (string-match-p (regexp-quote "nixos") (shell-command-to-string "uname -a"))))
Are we borg?
(defvar meq/var/we-are-borg (or (getenv "WEAREBORG") (meq/*item-in-cla "--we-are-borg")))
Disable ~package.el~ on startup:
(setq package-enable-at-startup nil)
Methods of package management, including:
(setq meq/var/package-manager (if meq/var/we-are-borg "borg" "nix"))
(load (concat user-emacs-directory "siluam/"
(pcase meq/var/package-manager
("package" "package-config.el")
("straight" "straight-config.el")
("quelpa" "quelpa.el")
("borg" "borg-cube.el")
(_ "nix-config.el"))))
Avoid stale *.elc
files using this answer, by Malabarba:
(setq load-prefer-newer t)
Set up startup optimization packages, including ~packed~, ~auto-compile~, ~no-littering~, and ~gcmh~:
(mapc #'(lambda (pkg) (interactive)
(let* ((pkg-name (symbol-name pkg)))
(when meq/var/we-are-borg (ignore-errors (borg-activate pkg-name)))
(unless (require pkg nil t)
(pcase meq/var/package-manager
("package" (progn (add-to-list 'package-selected-packages pkg) (package-install pkg)))
("straight" (straight-use-package pkg))
("quelpa" (quelpa pkg))
("borg" (borg-assimilate pkg-name (borg-get pkg-name "url")))))
(require pkg))) '(auto-compile no-littering gcmh))
(auto-compile-on-load-mode)
(auto-compile-on-save-mode)
(gcmh-mode 1)
Enable auto-revert
modes to automagically update modified files on disk, from here:
(global-auto-revert-mode t) (auto-revert-mode t)
(setq global-auto-revert-non-file-buffers t
auto-revert-verbose nil
Don’t notify us about auto-reversion, from this answer by jdc:
auto-revert-use-notify nil)
We Are Org
:
(require 'org-loaddefs)
Create a version of borg’s git call function to call any shell command:
(defun meq/call (program buffer-name &rest args)
(let ((process-connection-type nil)
(buffer (generate-new-buffer buffer-name)))
(with-current-buffer buffer
(pop-to-buffer buffer)
(if (eq (apply #'call-process program nil buffer nil args) 0)
(unwind-protect (format "\n\n%s\n\n" (buffer-string)) (kill-buffer buffer))
(error "%s: %s:\n\n%s" program args (buffer-string))))))
Then create a shell tangle function based on the above:
(defun meq/call-tangle (file) (meq/call "org-tangle" "*literally-configuring*" file))
Modify ~org-babel-load-file~ to use the above function instead:
(defun meq/org-babel-load-file-advice (file &optional compile)
"Load Emacs Lisp source code blocks in the Org FILE.
This function exports the source code using `org-babel-tangle'
and then loads the resulting file using `load-file'. With
optional prefix argument COMPILE, the tangled Emacs Lisp file is
byte-compiled before it is loaded."
(interactive "fFile to load: \nP")
(let ((tangled-file (concat (file-name-sans-extension file) ".el")))
;; Tangle only if the Org file is newer than the Elisp file.
(unless (org-file-newer-than-p
tangled-file
(file-attribute-modification-time
(file-attributes (file-truename file))))
(meq/call-tangle file))
(if compile
(progn
(byte-compile-file tangled-file)
(load tangled-file)
(message "Compiled and loaded %s" tangled-file))
(load-file tangled-file)
(message "Loaded %s" tangled-file))))
(advice-add #'org-babel-load-file :override #'meq/org-babel-load-file-advice)
Then finally create the function to [re]load the primary early-init in this README and load it for the first time:
(defun meq/reload-early-init nil (interactive) (org-babel-load-file (concat user-emacs-directory "README.org") t))
(meq/reload-early-init)
Remove --
from scripts:
(when (string= (car (last command-line-args)) "--") (delete "--" command-line-args))
Startup optimizations from Henrik Lissner’s Doom Emacs’ ~early-init.el~:
Emacs 27.1 introduced early-init.el, which is run before init.el, before package and UI initialization happens, and before site files are loaded.
A big contributor to startup times is garbage collection. We up the gc threshold to temporarily prevent it from running, then reset it later by enabling `gcmh-mode’. Not resetting it will cause stuttering/freezes.
(setq gc-cons-threshold most-positive-fixnum)
And for the file-name-handler-alist
:
(setq meq/var/file-name-handler-alist file-name-handler-alist)
(unless (or (daemonp) noninteractive)
`file-name-handler-alist’ is consulted on each `require’, `load’ and various path/io functions. You get a minor speed up by unsetting this. Some warning, however: this could cause problems on builds of Emacs where its site lisp files aren’t byte-compiled and we’re forced to load the *.el.gz files (e.g. on Alpine).
(setq-default file-name-handler-alist nil)
…but restore `file-name-handler-alist’ later, because it is needed for handling encrypted or compressed files, among other things.
(defun meq/reset-file-handler-alist-h ()
(setq file-name-handler-alist
Merge instead of overwrite because there may have bene changes to `file-name-handler-alist’ since startup we want to preserve.
(delete-dups (append file-name-handler-alist
meq/var/file-name-handler-alist))))
(add-hook 'emacs-startup-hook #'meq/reset-file-handler-alist-h 101))
The next few bits are adapted from here, with a few quotes from myself and others scattered here and there, such as this bit about ~gc-cons-percentage~:
… There’s also gc-cons-percentage which performs a gc if the amount of new memory used as a percentage of the total has increased by a certain amount. If you set gc-cons-threshold to a large number that effectively puts gc-cons-percentage into the driving seat. The default gc-cons-threshold is 400000 bytes, not 800000. …
(defvar meq/var/gc-cons-percentage gc-cons-percentage)
(add-hook 'after-init-hook
(lambda ()
(setq gc-cons-percentage meq/var/gc-cons-percentage)
(defun meq/gc-on-lose-focus ()
(unless (frame-focus-state)
(garbage-collect)))
(if (boundp 'after-focus-change-function)
(add-function :after after-focus-change-function #'meq/gc-on-lose-focus))))
(setq-default gc-cons-percentage 0.6)
(setq-default auto-window-vscroll nil
frame-inhibit-implied-resize t
inhibit-compacting-font-caches t)
(fset 'yes-or-no-p 'y-or-n-p)
(fset 'view-hello-file 'ignore)
(fset 'display-startup-echo-area-message 'ignore)
(put 'narrow-to-region 'disabled nil)
(put 'up-case-rgion 'disabled nil)
(put 'downcase-region 'disabled nil)
(put 'erase-buffer 'disabled nil)
(push '(ns-transparent-titlebar . t) default-frame-alist)
(push '(ns-appearance . nil) default-frame-alist)
(push '(internal-border . 0) default-frame-alist)
(push '(menu-bar-lines . 0) default-frame-alist)
(push '(tool-bar-lines . 0) default-frame-alist)
(push '(vertical-scroll-bars . 0) default-frame-alist)
(push '(left-fringe . 0) default-frame-alist)
(push '(right-fringe . 0) default-frame-alist)
Byte-compile the library directories and add them to the load-path now; the following bits are adapted from NickD’s answer here, and from this section of the Emacs Wiki.
(let* ((default-directory (concat user-emacs-directory "siluam")))
(normal-top-level-add-to-load-path '("."))
(normal-top-level-add-subdirs-to-load-path))
These are two settings I like for native compilation
, adapted from here:
Silence compiler warnings as they can be pretty disruptive
(ignore-errors
(setq native-comp-async-report-warnings-errors nil)
Set the right directory to store the native comp cache
(add-to-list 'native-comp-eln-load-path (meq/ued-local "eln-cache/")))
Finally activate my function library:
(require 'meq)
As adapted from ebpa’s answer here:
(setq custom-file (meq/ued "custom.el"))
(meq/cl custom-file)
(setq auto-save-list-file-prefix user-emacs-directory)
(byte-recompile-directory (meq/ued "themes") nil)
(add-to-list 'custom-theme-load-path (meq/ued "themes"))
(setq custom-safe-themes t)
By the way, I get most of my themes from themer.dev.
use-package with John Wiegley:
(with-no-warnings
(setq use-package-verbose t)
(setq use-package-enable-imenu-support t))
(require 'use-package)
Search the command-line-args
list for the --always-demand
argument and set use-package-always-demand
accordingly,
then delete the argument from the list; also set the variable if Emacs is running as a daemon.
(setq use-package-always-demand (or (meq/item-in-cla "--always-demand") (daemonp)))
Quoted from Use-Package’s Loading packages in sequence:
NOTE: pay attention if you set use-package-always-defer to t, and also use the :after keyword, as you will need to specify how the declared package is to be loaded: e.g., by some :bind. If you’re not using one of the mechanisms that registers autoloads, such as :bind or :hook, and your package manager does not provide autoloads, it’s possible that without adding :defer 2 to those declarations, your package will never be loaded.
Quoted from Use-Package’s Notes about lazy loading:
In almost all cases you don’t need to manually specify :defer t. This is implied whenever :bind or :mode or :interpreter is used. Typically, you only need to specify :defer if you know for a fact that some other package will do something to cause your package to load at the appropriate time, and thus you would like to defer loading even though use-package isn’t creating any autoloads for you. You can override package deferral with the :demand keyword. Thus, even if you use :bind, using :demand will force loading to occur immediately and not establish an autoload for the bound key.
Quoted from Use-Package’s Modes and interpreters:
Similar to :bind, you can use :mode and :interpreter to establish a deferred binding within the auto-mode-alist and interpreter-mode-alist variables. … If you aren’t using :commands, :bind, :bind*, :bind-keymap, :bind-keymap*, :mode, :interpreter, or :hook (all of which imply :defer; see the docstring for use-package for a brief description of each), you can still defer loading with the :defer keyword…
Quoted from Use-Package’s Magic handlers:
Similar to :mode and :interpreter, you can also use :magic and :magic-fallback to cause certain function to be run if the beginning of a file matches a given regular expression. … This registers an autoloaded command for pdf-view-mode, defers loading of pdf-tools, and runs pdf-view-mode if the beginning of a buffer matches the string “%PDF”.
Quoted from RYO-Modal’s Use-package keyword:
Ryo-modal also provides a use-package keyword: :ryo, which is similar to :bind in that it implies :defer t and create autoloads for the bound commands. The keyword is followed by one or more key-binding commands, using the same syntax as used by ryo-modal-keys…
Quoted from General’s Use-package Keywords:
:general is similar to :bind in that it implies :defer t whenever there are bound commands that can be autoloaded (e.g. it will not imply :defer t if the only bound command is to a lambda, for example). Whenever autoloadable commands are bound, use-package will create autoloads for them (though this is usually not necessary).
Quoted from General’s :ghook Keyword:
:ghook is intended to be used to add a package’s minor mode enabling function to a user-specified hook, so that when hook is run, the package will be loaded and the mode enabled. This means that :ghook will usually imply :defer t. While it does not always imply :defer t, it will add any non-lambda functions to :commands (this is the same behavior as :hook). Though this is usually unnecessary (the commands probably already have autoloads), it will in turn imply :defer t.
Quoted from General’s :gfhook Keyword:
Unlike :ghook, :gfhook never adds functions to :commands and therefore never implies :defer t. This is because the functions specified are ones that should be run when turning on (or toggling) the mode(s) the package provides. The specified functions are external to the package, could be called elsewhere, and therefore should not trigger the package to load.
Also see this comment.
Note that I assume that chords also defer and create autoloads.
And in my experience… Not a good idea; much too confusing. Use the arguments here to decide whether to use this or :defer <n>
instead.
(setq use-package-always-defer (meq/item-in-cla "--always-defer"))
This sets up use-package-extras by yours truely:
(use-package use-package-extras :demand t
;; :config (meq/up use-package-ensure-system-package)
)
And then leaf.el by Naoya Yamashita:
(meq/up leaf
:init (defmacro meq/leaf (&rest args) `(leaf ,@args :require ,(cl-getf args :require t)))
:upnsd-postconfig (leaf-keywords :demand t))
This sets up hydra by Oleh Krehel, as well as its use-package
keywords:
(meq/up hydra
:custom (hydra-hint-display-type 'lv)
:bind (:map hydra-base-map ("~" . hydra--universal-argument))
This bit sets up the following:
- janus by yours truely
- use-package-hydra by to1ne
- use-package-deino by yours truely
- deino, forked from
hydra by Oleh Krehel
:use-package-preconfig (use-package-hydra)
:upnsd-preconfig (janus)
:upnsd-postconfig (deino :custom (deino-hint-display-type 'lv)) (use-package-deino))
Here is the configuration for alloy, forked from general.el by Fox Kiester:
(meq/upnsd alloy
This sets up the following:
- lode by yours truely! :D
- prime by yours truely! :D
- command-log-mode by Le Wang
- use-package-chords by justin talbott
:use-package-preconfig (command-log-mode)
;; Important: https://github.com/noctuid/general.el/issues/53#issuecomment-307262154
(use-package-chords)
I don’t like having to unbind keys before reassigning them:
:config (alloy-auto-unbind-keys)
This binds some fundamental keys to the following keymaps:
(defvar demon-run '(global override
aiern-insert-state-map
aiern-normal-state-map
aiern-god-state-map
evil-insert-state-map
evil-normal-state-map
evil-god-state-map))
(alloy-def :keymaps demon-run
;; Adapted From:
;; Answer: https://stackoverflow.com/a/4557027/10827766
;; User: https://stackoverflow.com/users/387076/gilles-so-stop-being-evil
"\eOA" [up]
"\e[A" [up]
"\eOB" [down]
"\e[B" [down]
"\eOD" [left]
"\e[D" [left]
"\eOC" [right]
"\e[C" [right]
"M-x" 'meq/M-x
(alloy-chord "jj") 'universal-argument
(naked "<tab>") 'org-cycle
(naked "backtab") 'org-shifttab
:keymaps 'universal-argument-map (alloy-chord "jj") 'universal-argument-more)
And finally, this allows alloy
to assume kbd
is being used, or in this case, naked:
:custom (alloy-implicit-naked t))
Set up prime by yours truely:
(meq/upnsd prime)
This sets up my package uru, which activates deinos
based on the current major-mode, as mentioned in magic medusa hydra, by Andy Drop:
(meq/upnsd uru
:prime ("u u" uru "uru") ("u m" minoru "minoru")
:primer ("u" "uru")
:primed ("u" "
^Uru ^| ^^Minoru | Etc
--------^^+------------^^+-------------^^
_u_ : uru | _m_ : minoru | _DEL_ : primus
^^^^ | _`_ : exit
"))
The incredible emacs-which-key by the incredible Justin Burkett:
(meq/up which-key :deino (deino/which-key (:color blue :columns 4) "w"
("`" nil "cancel")
("a" cosmoem-any-popup-showing-p "any popup showing")
("h" meq/which-key--hide-popup "hide-popup")
("s" meq/which-key--show-popup "show-popup")
("r" meq/which-key--refresh-popup "refresh-popup")
("t" meq/toggle-which-key "toggle")
("l" meq/which-key-show-top-level "meq/toplevel")
("L" which-key-show-top-level "toplevel"))
:gsetq
(which-key-enable-extended-define-key t)
(which-key-idle-delay 0.1)
(which-key-idle-secondary-delay nil)
(which-key-allow-evil-operators t)
;; NOTE: This will cause the which-key maps for the operator states to show up,
;; breaking functionality such as `d 13 <arrow-down>', etc.
;; (which-key-show-operator-state-maps t)
;; TODO: Choose a fun one!
(which-key-separator " × ")
;; (which-key-separator " |-> ")
(which-key-popup-type 'side-window)
(which-key-side-window-location '(right bottom left top))
;; If this percentage is too small, the keybindings frame will appear at the bottom
(which-key-side-window-max-width 0.5)
(which-key-side-window-max-height 0.25))
Meet the cosmoem named Nebby, forked from hercules.el by jjzmajic:
(meq/upnsd cosmoem
:prime (", m" map-of-infinity/body "map-of-infinity")
:primer ("," "Deinos / Hydras / Functions")
:primed ("," "
^Map of Infinity
^^-------------------
_m_ : Map of Infinity
")
:which-key-change-ryo ("," "damascus")
This sets up a few things to create a deino
of cosmoem
maps, adapted from here
and here:
:gsetq (meq/var/all-keymaps-map nil)
(meq/var/alamode-aiern-was-on (member "aiern" meq/var/ignored-modal-prefixes))
(meq/var/alamode-evil-was-on (member "evil" meq/var/ignored-modal-prefixes))
:config/defun* (meq/toggle-inner (mode prefix mode-on map &optional use-cosmoem force) (interactive)
(meq/disable-all-modal-modes nil (not mode-on))
(if mode-on
(when force (meq/which-key--show-popup map force))
(funcall mode 1)
(when (featurep 'which-key)
(if use-cosmoem
(ignore-errors (funcall (meq/inconcat "meq/" prefix "-cosmoem-show")))
(meq/which-key-show-top-level map)))))
(meq/execute-with-current-bindings-inner (mode prefix mode-on map &optional use-cosmoem called-interactively)
(interactive "d")
(unless mode-on
(letrec ((caller this-command)
(buffer (current-buffer))
(cleanup
(lambda ()
;; Perform cleanup in original buffer even if the command
;; switched buffers.
(if (buffer-live-p buffer)
(with-current-buffer buffer
(unwind-protect
(progn
(setq overriding-terminal-local-map meq/var/alamode-backup-terminal-local-map)
(funcall mode -1)
(when meq/var/alamode-aiern-was-on (aiern-mode 1))
(when meq/var/alamode-evil-was-on (evil-mode 1))
(meq/which-key-show-top-level))
(remove-hook 'post-command-hook post-hook)))
(remove-hook 'post-command-hook post-hook))))
(kill-transient-map (lambda nil (interactive)
(set-transient-map map 'meq/god-prefix-command-p cleanup)))
(post-hook (lambda nil (unless (and
(eq this-command caller)
;; If we've entered the minibuffer, this implies
;; a non-prefix command was run, even if
;; `this-command' has not changed. For example,
;; `execute-extended-command' behaves this way.
(not (window-minibuffer-p)))
(funcall kill-transient-map)))))
(add-hook 'post-command-hook post-hook)
;; Pass the current prefix argument along to the next command.
(setq prefix-arg current-prefix-arg)
;; Technically we don't need to activate %p mode since the
;; transient keymap is already in place, but it's useful to provide
;; a mode line lighter and run any hook functions the user has set
;; up. This could be made configurable in the future.
(funcall mode 1)
(when (featurep 'which-key) (meq/which-key-show-top-level map))
(setq meq/var/alamode-backup-terminal-local-map overriding-terminal-local-map)
(setq deino-enabled-temporarily t
overriding-terminal-local-map (symbol-value map))
(when (string= prefix "god")
(when (meq/fbatp aiern-mode) (setq meq/var/alamode-aiern-was-on t) (aiern-mode -1))
(when (meq/fbatp evil-mode) (setq meq/var/alamode-evil-was-on t) (evil-mode -1)))
(message (format "Switched to %s mode for the next command ..." prefix)))))
This deino
leads to a bunch of other useful deinos
, as well as a few useful functions:
:deino (map-of-infinity nil ", m"
("`" nil "cancel")
("w" deino/which-key/body "which-key")
("h" deino/cosmoem/body "cosmoem")
("d" meq/disable-all-modal-modes "disable all modal modes" :color blue)
("t" toggles/body "toggles")
("k" all-keymaps/body "all keymaps"))
The deino
for this package:
(deino/cosmoem (:color blue) ", c"
("`" nil "cancel")
("h" cosmoem-hide-all-modal-modes "hide all modal modes"))
A deino
for all my modal-mode toggles:
(toggles (:color blue) ", t" ("`" nil "cancel"))
A deino
for all my modal-mode keymaps:
(all-keymaps (:color blue) ", k" ("`" nil "cancel")))
Finally, sorrow, forked from ryo-modal by Erik Sjöstrand:
(meq/upnsd sorrow :primer ("t" "toggles")
Here is the setup for the deino
of cosmoem
maps referred to in the cosmoem use-package
definition:
:config
<<8eae8e4e-adf4-45cc-ae3f-ac61384d6b75(map="sorrow-mode-map", mode="sorrow-mode", prefix="sorrow", short="s", package="sorrow")>>
;; From: https://github.com/shadowrylander/sorrow#which-key-integration
(push '((nil . "sorrow:.*:") . (nil . "")) which-key-replacement-alist))
Unless I’m on Windows or a DOS-based OS, I’ll need to make sure every executable available on my $PATH
can be found by Emacs as well, using
exec-path-from-shell by Steve Purcell:
(unless (meq/windows-p)
(meq/up exec-path-from-shell
:gsetq
(exec-path-from-shell-check-startup-files nil)
(exec-path-from-shell-variables '("PATH" "MANPATH" "CACHE_HOME" "FPATH" "PYENV_ROOT"))
(exec-path-from-shell-arguments '("-l"))
:config
(exec-path-from-shell-initialize)))
Set up undo-fu and undo-fu-session:
(meq/up undo-fu :deino (deino-undo nil "u"
("u" undo-fu-only-undo "undo")
("r" undo-fu-only-redo "redo")
("R" undo-fu-only-redo-all "redo all"))
:upnsd-postconfig
(undo-fu-session
:gsetq
(undo-fu-session-directory (meq/ued-local "undo-fu-session"))
(undo-fu-session-incompatible-files '("/COMMIT_EDITMSG\\'" "/git-rebase-todo\\'"))
:hook (after-init . global-undo-fu-session-mode)))
Set up lode by yours truely:
(meq/upnsd lode)
Set up meta by yours truely:
(meq/upnsd meta)
aiern is my version of evil; this first bit of config will enable aiern
on initialization and add it to the list of ignored modal-modes,
such that it isn’t disabled by meq/disable-all-modal-modes
:
(meq/upnsd aiern
:gsetq (aiern-undo-system 'undo-fu aiern-move-beyond-eol t)
:hook (after-init . (lambda nil (interactive) (meq/add-to-ignored-modal-modes aiern (setq state (list aiern-default-state)))))
Both evil
and aiern
require emacs-bind-map, by Justin Burkett:
:use-package-preconfig (bind-map)
More aiern, courtesy of this, this, and this:
:upnsd-postconfig (aiern-aiernhide-state)
The :meta-aiern
keyword, from my very own meta package, creates a hydra out of the keymaps passed to it,
in this case the keymaps being aiern-normal-state-map
and aiern-insert-state-map
:
:meta-aiern (aiern-normal-state-map) (aiern-insert-state-map)
;; :demon
;; ((alloy-chord "") 'meq/toggle-aiern-ex-cosmoem)
;; TODO
;; ((alloy-chord "''") 'aiern-ex)
:config
;; TODO: How do I create a keymap `aiern-ex-keymap' out of the `aiern-ex-commands' alist?
;; (cosmoem-def :show-funs #'meq/aiern-ex-cosmoem-show
;; :hide-funs #'meq/aiern-ex-cosmoem-hide
;; :toggle-funs #'meq/aiern-ex-cosmoem-toggle
;; :keymap 'aiern-ex-keymap
;; ;; :transient t
;; )
;; (defun meq/aiern-ex-cosmoem-toggle nil (interactive))
;; (defun meq/aiern-ex-show-top-level nil (interactive)
;; (meq/which-key-show-top-level 'aiern-ex-keymap))
;; (defun meq/toggle-aiern-ex (ua) (interactive "p")
;; (if (= ua 4)
;; (funcall 'meq/toggle-inner 'aiern-mode "aiern-ex" (meq/fbatp aiern-mode) 'aiern-ex-keymap nil t)
;; (funcall 'meq/toggle-inner 'aiern-mode "aiern-ex" (meq/fbatp aiern-mode) 'aiern-ex-keymap)))
;; (defun meq/toggle-aiern-ex-cosmoem (ua) (interactive "p")
;; (if (= ua 4)
;; (funcall 'meq/toggle-inner 'aiern-mode "aiern-ex" (meq/fbatp aiern-mode) 'aiern-ex-keymap t t)
;; (funcall 'meq/toggle-inner 'aiern-mode "aiern-ex" (meq/fbatp aiern-mode) 'aiern-ex-keymap t)))
Here is the setup for the deino
of cosmoem
maps referred to in the cosmoem use-package
definition:
<<8eae8e4e-adf4-45cc-ae3f-ac61384d6b75(map="aiern-normal-state-map", mode="aiern-mode", prefix="aiern", short="a", package="aiern")>>
And here are the aiern
bindings set in the sorrow
modal-mode:
:sorrow ("l" :deino
'(aiern-exits (:color blue) "e"
;; From: https://github.com/emacs-evil/evil/blob/master/evil-maps.el#L449
"A deino for getting the fuck outta' here!"
("`" nil "cancel")
("l" aiern-save-and-quit ":wq")
("p" aiern-quit ":q")
("o" aiern-write ":w")
("O" aiern-write-all ":wa")
Deprecated; kept for documentation purposes:
("q" (funcall (alloy-simulate-key ":q! <RET>")) ":q!"))
("q" (aiern-quit t) ":q!"))
:name "aiern exits"))
I use Cartograph by Connary Fagen, Inc., but I got it cheaper here; the second site often has sales on fonts.
(meq/up all-the-icons :config
(ignore-errors
(set-face-attribute 'default nil :font "Cartograph CF Extra Bold-12")
(set-face-attribute 'mode-line nil :font "Cartograph CF Extra Bold-12")
(set-face-attribute 'mode-line-inactive nil :font "Cartograph CF Extra Bold-12")))
This binds ctrl-tab
and ctrl-shift-tab
to buffer-cycling motions:
(alloy-def :keymaps demon-run "C-tab" 'next-buffer "C-<iso-lefttab>" 'previous-buffer)
And this is mostly adapted from here:
(sorrow-key "b" :deino '(deino-buffer (:color red :columns 3) "b"
"
Buffers :
"
("`" nil "cancel")
("<right>" next-buffer "next")
("n" next-buffer "next")
("b" ivy-switch-buffer "switch" :color blue)
("B" ibuffer "ibuffer" :color blue)
("<left>" previous-buffer "prev")
("p" previous-buffer "prev")
("C-b" buffer-menu "buffer menu" :color blue)
("N" evil-buffer-new "new" :color blue)
("d" kill-this-buffer "delete")
;; don't come back to previous buffer after delete
("D" (progn (kill-this-buffer) (next-buffer)) "Delete")
("S" save-buffer "save")
("s" deino-window/body "window" :color blue)))
From the swiper package by Oleh Krehel:
(meq/up ivy :sorrow ("x" :deino '(deino-execute (:color blue) "x" "A deino for launching stuff!"
("`" nil "cancel")
("e" execute-extended-command "M-x")) :name "execute order 65")
:use-package-preconfig (smex)
:gsetq (ivy-use-virtual-buffers t))
From the swiper package by Oleh Krehel:
(meq/up counsel
:use-package-postconfig (prescient) (ivy-prescient)
:hook (after-init . (lambda nil (interactive)
(ivy-mode 1)
(counsel-mode 1)
(ivy-prescient-mode 1)
(prescient-persist-mode 1)))
:deino+ (deino-execute nil ("c" counsel-M-x "counsel"))
;; Adapted From: https://www.reddit.com/r/emacs/comments/7o1sjq/exwm_rofidmenu_replacement_for_starting/dt0lvkm?utm_source=share&utm_medium=web2x&context=3
:config (push (concat (getenv "HOME") "/.local/share/applications/") counsel-linux-apps-directories)
:config/defun* (meq/counsel-linux-app-format-function (name comment exec)
"Default Linux application name formatter.
NAME is the name of the application, COMMENT its comment and EXEC
the command to launch it."
(format "% -45s %s"
(propertize name 'face 'font-lock-builtin-face)
(or comment "")))
:gsetq (counsel-linux-app-format-function #'meq/counsel-linux-app-format-function))
Set up the base of this config, including the rainbow-mode package:
(meq/upnsd damascus
:upnsd-postconfig (help-fns+ :load-siluam-file-postconfig ("help+"))
:use-package-postconfig (rainbow-mode :config (rainbow-mode 1))
Define some universal deinos:
:deino (deino-universal/shortcuts (:color blue) "d u s"
"A deino for universal shortcuts!"
("`" nil "cancel")
(";" aiern-ex "aiern-ex")
(":" evil-ex "evil-ex")
("u" uru "uru")
("m" minoru "minoru")
("w" deino-wb/body "window-buffer deino")
;; ("s" meq/shell "shell")
("'" aiern-write "save")
("RET" aiern-save-and-quit "save and quit"))
(deino-universal/modal-modes (:color blue) "d u m"
"A deino for modal modes!"
("a" meq/aiern-execute-with-current-bindings "aiern execute")
("s" meq/sorrow-execute-with-current-bindings "sorrow execute")
("g" meq/god-execute-with-current-bindings "god execute")
("r" meq/ryo-execute-with-current-bindings "ruo execute")
("`" nil "cancel"))
(deino-universal/major-minor-modes (:color blue) "d u M"
"A deino for major and minor modes!"
("`" nil "cancel"))
(deino-universal/everything-else (:color blue) "d u e"
"A deino for everything else!"
("`" nil "cancel")
("u" deino-undo/body "deino-undo")
("RET" meq/end-of-line-and-indented-new-line "indented new line")
("r" deino-restart/body "deino-restart"))
Bind some universal deinos:
:alloy (:keymaps demon-run
(alloy-chord ";'") 'deino-universal/shortcuts/body
(alloy-chord "l;") 'deino-universal/modal-modes/body
(alloy-chord "kl") 'deino-universal/major-minor-modes/body
(alloy-chord "jk") 'deino-universal/everything-else/body
(alloy-chord "hj") 'aiern-exits/body
Bind some keys primarily accessible for me on Android:
"¡" 'ignore "¹" 'ignore "½" 'ignore "⅓" 'ignore "¼" 'ignore "⅛" 'ignore "²" 'ignore "⅜" 'ignore
"¾" 'ignore "³" 'ignore "⁴" 'ignore "⅚" 'ignore "⁵" 'ignore "⅝" 'ignore "⁶" 'ignore "⅞" 'ignore
"⁷" 'ignore "⁸" 'ignore "⁹" 'ignore "∅" 'ignore "ⁿ" 'ignore "⁰" 'ignore "·" 'ignore "—" 'ignore
"∞" 'ignore "≠" 'ignore "≈" 'ignore "ê" 'ignore "é" 'ignore
"è" 'universal-argument "ë" 'ignore "ē" 'ignore
"ū" 'ignore "ü" 'ignore "ú" 'ignore "û" 'ignore "ù" 'ignore "ì" 'ignore "ï" 'ignore "í" 'ignore
"î" 'ignore "ī" 'ignore "ō" 'ignore "œ" 'ignore "ø" 'ignore "õ" 'ignore "ö" 'ignore "ó" 'ignore
"ô" 'ignore "ò" 'ignore "à" 'ignore "á" 'ignore "â" 'ignore "ä" 'ignore "æ" 'ignore "ã" 'ignore
"å" 'ignore "ā" 'ignore "ß" 'ignore "ç" 'ignore "ñ" 'ignore "¿" 'ignore
And bind some keys of general use:
:keymaps '(override aiern-insert-state-map evil-insert-state-map)
(naked "C-backspace") 'meq/delete-white-or-word
(naked "RET") 'newline-and-indent)
This hook and function combo would allow me to save files without query, taken from this answer by Tobias:
:config/defun*
(meq/set-buffer-save-without-query nil
"Set `buffer-save-without-query' to t."
(unless (variable-binding-locus 'buffer-save-without-query)
(setq buffer-save-without-query t)))
:hook (find-file . meq/set-buffer-save-without-query)
Load the latest help package, and set a few self-describing variables:
:gsetq
(indent-tabs-mode nil
inhibit-startup-screen t
confirm-kill-emacs nil
delete-selection-mode 1
echo-keystrokes .1
column-number-mode t
size-indicator-mode t
user-full-name "Jeet Ray"
user-mail-address "<<email>>"
scroll-step 1
scroll-conservatively most-positive-fixnum
vc-follow-symlinks t)
Do not show byte-compiler warnings, from this answer by Malabarba:
(byte-compile-warnings nil)
This would set the initial-major-mode
, from here:
(initial-major-mode 'org-mode)
:init
;; TODO: Use the previous implementation of this to create a version which will use command-line arguments
;; to open specific files, such as this README, protean.aiern.org, meta.aiern.org, bundle/README.org, etc. ,
;; in addition to any files called from the command-line itself.
(let* ((testing (meq/ued "testing.aiern.org"))
(resting (meq/ued "resting.aiern.org")))
;; (setq initial-buffer-choice testing)
;; Adapted From:
;; Answer: https://emacs.stackexchange.com/a/66329
;; User: https://emacs.stackexchange.com/users/26541/hettomei
(eval `(add-hook 'after-init-hook #'(lambda nil (interactive) (unless (buffer-file-name) (find-file ,testing)))))
(eval `(add-hook 'kill-emacs-hook #'(lambda nil (interactive)
;; Adapted From: http://ergoemacs.org/emacs/elisp_file_name_dir_name.html
(when (get-file-buffer ,testing) (delete-file ,testing) (copy-file ,resting ,testing))))))
(let* ((loaddefs (meq/ued-lib "org" "lisp" "org-loaddefs.el"))) (when (get-file-buffer loaddefs) (kill-buffer (get-file-buffer loaddefs))))
(when (get-buffer "*Compile-Log*") (kill-buffer "*Compile-Log*"))
(when (get-buffer "*Shell Command Output*") (kill-buffer "*Shell Command Output*"))
;; This determines the style of line numbers in effect. If set to `nil', line
;; numbers are disabled. For relative line numbers, set this to `relative'.
;; Adapted From: https://www.reddit.com/r/emacs/comments/8fz6x2/relative_number_with_line_folding/dy7lmh7?utm_source=share&utm_medium=web2x&context=3
;; (display-line-numbers-mode t)
(setq display-line-numbers-type 'relative)
;; Adapted From:
;; Answer: https://stackoverflow.com/a/50716229/10827766
;; User: https://stackoverflow.com/users/1482346/muro
(global-display-line-numbers-mode t)
The foloowing few pieces are adapted from Ole’s answer here, with his comments quoted as well:
Makes scratch empty.
(setq initial-scratch-message "")
Removes scratch from buffer after the mode has been set.
(defun meq/remove-scratch-buffer nil (interactive)
(when (get-buffer "*scratch*") (kill-buffer "*scratch*")))
(add-hook 'after-change-major-mode-hook 'meq/remove-scratch-buffer)
Not using this bit:
Removes messages from the buffer.
(setq-default message-log-max nil)
(when (get-buffer "*Messages*") (kill-buffer "*Messages*"))
Removes Completions from buffer after you’ve opened a file.
(add-hook 'minibuffer-exit-hook
#'(lambda nil
(let ((buffer "*Completions*"))
(and (get-buffer buffer)
(kill-buffer buffer)))))
Don’t show Buffer list when opening multiple files at the same time.
(setq inhibit-startup-buffer-menu t)
Show only one active window when opening multiple files at the same time.
(add-hook 'window-setup-hook 'delete-other-windows)
Not using this piece either:
The following avoids being ask to allow the file local setting of `buffer-save-without-query’. IMHO it is not a big risk: The malicious code that must not be saved should never be allowed to enter Emacs in the first place.
(put 'buffer-save-without-query 'safe-local-variable #'booleanp)
And finally, make emacs fullscreen, from Dan’s answer here:
(add-to-list 'default-frame-alist '(fullscreen . fullboth)))
Set up dired and its sidebar, by James:
(meq/up dired-sidebar :demon ((alloy-chord "\\\\") 'meq/backslash-toggle)
For some reason, on terminal interfaces, the arrow keys in dired
tried to change ownership of file;
this was resolved using the following bit, adapted from here:
:upnsd-preconfig (dired+ :gsetq (diredp-bind-problematic-terminal-keys (display-graphic-p)))
Since dired-details
is already implemented in dired
from Emacs version 24.4, we’ll enable it only for prior versions:
(dired-details :if (version< emacs-version "24.4"))
(dired-details+ :if (version< emacs-version "24.4"))
I don’t quite like the dired-sidebar
open all the time, so I close it on opening a file from it;
also, no hidden details hint, courtesy of the Emacs wiki:
:gsetq (dired-sidebar-close-sidebar-on-file-open t)
(dired-details-hidden-string "")
When in the dired
major mode or derived major modes, uru will allow me to quickly create, and optionally open,
Zettelkasten files for my novel and documentation:
:uru (dired-mode t deino-dired-mode (:color blue) "d d"
("`" nil "cancel")
("f" (meq/dired-create-and-open-fell-markdown) "create & edit fell file")
("d" (meq/dired-create-and-open-doc-markdown) "create & edit doc file")
("F" (meq/dired-create-fell-markdown) "create fell file" :color red)
("D" (meq/dired-create-doc-markdown) "create doc file" :color red)))
(use-package god-mode
:config (which-key-enable-god-mode-support)
Here is the setup for the deino
of cosmoem
maps referred to in the cosmoem use-package
definition:
<<8eae8e4e-adf4-45cc-ae3f-ac61384d6b75(map="global-map", mode="god-local-mode", prefix="god", short="g", package="god-mode")>>
This sets up god-mode, evil-god-state by Eric Seidel, and my fork of it aiern-god-state:
:upnsd-postconfig (aiern-god-state) (evil-god-state))
This sets up my fork of doom-modeline by Vincent Zhang upon initialization:
(use-package doom-aiern-modeline
:hook (after-init . doom-aiern-modeline-mode)
:use-package-preconfig (shrink-path)
Most of the following is adapted from here:
:gsetq
;; How tall the mode-line should be. It's only respected in GUI.
;; If the actual char height is larger, it respects the actual height.
(doom-aiern-modeline-height 25)
;; How wide the mode-line bar should be. It's only respected in GUI.
(doom-aiern-modeline-bar-width 3)
;; The limit of the window width.
;; If `window-width' is smaller than the limit, some information won't be displayed.
(doom-aiern-modeline-window-width-limit fill-column)
;; How to detect the project root.
;; The default priority of detection is `ffip' > `projectile' > `project'.
;; nil means to use `default-directory'.
;; The project management packages have some issues on detecting project root.
;; e.g. `projectile' doesn't handle symlink folders well, while `project' is unable
;; to hanle sub-projects.
;; You can specify one if you encounter the issue.
(doom-aiern-modeline-project-detection 'project)
;; Determines the style used by `doom-aiern-modeline-buffer-file-name'.
;;
;; Given ~/Projects/FOSS/emacs/lisp/comint.el
;; auto => emacs/lisp/comint.el (in a project) or comint.el
;; truncate-upto-project => ~/P/F/emacs/lisp/comint.el
;; truncate-from-project => ~/Projects/FOSS/emacs/l/comint.el
;; truncate-with-project => emacs/l/comint.el
;; truncate-except-project => ~/P/F/emacs/l/comint.el
;; truncate-upto-root => ~/P/F/e/lisp/comint.el
;; truncate-all => ~/P/F/e/l/comint.el
;; truncate-nil => ~/Projects/FOSS/emacs/lisp/comint.el
;; relative-from-project => emacs/lisp/comint.el
;; relative-to-project => lisp/comint.el
;; file-name => comint.el
;; buffer-name => comint.el<2> (uniquify buffer name)
;;
;; If you are experiencing the laggy issue, especially while editing remote files
;; with tramp, please try `file-name' style.
;; Please refer to https://github.com/bbatsov/projectile/issues/657.
(doom-aiern-modeline-buffer-file-name-style 'auto)
;; Whether display icons in the mode-line.
;; While using the server mode in GUI, should set the value explicitly.
(doom-aiern-modeline-icon (display-graphic-p))
;; Whether display the icon for `major-mode'. It respects `doom-aiern-modeline-icon'.
(doom-aiern-modeline-major-mode-icon t)
;; Whether display the colorful icon for `major-mode'.
;; It respects `all-the-icons-color-icons'.
(doom-aiern-modeline-major-mode-color-icon t)
;; Whether display the icon for the buffer state. It respects `doom-aiern-modeline-icon'.
(doom-aiern-modeline-buffer-state-icon t)
;; Whether display the modification icon for the buffer.
;; It respects `doom-aiern-modeline-icon' and `doom-aiern-modeline-buffer-state-icon'.
(doom-aiern-modeline-buffer-modification-icon t)
;; Whether to use unicode as a fallback (instead of ASCII) when not using icons.
(doom-aiern-modeline-unicode-fallback nil)
;; Whether display the minor modes in the mode-line.
(doom-aiern-modeline-minor-modes nil)
;; If non-nil, a word count will be added to the selection-info modeline segment.
(doom-aiern-modeline-enable-word-count nil)
;; Major modes in which to display word count continuously.
;; Also applies to any derived modes. Respects `doom-aiern-modeline-enable-word-count'.
;; If it brings the sluggish issue, disable `doom-aiern-modeline-enable-word-count' or
;; remove the modes from `doom-aiern-modeline-continuous-word-count-modes'.
(doom-aiern-modeline-continuous-word-count-modes '(
markdown-mode
gfm-mode
org-mode
outline-mode))
;; Whether display the buffer encoding.
(doom-aiern-modeline-buffer-encoding t)
;; Whether display the indentation information.
(doom-aiern-modeline-indent-info nil)
;; If non-nil, only display one number for checker information if applicable.
(doom-aiern-modeline-checker-simple-format t)
;; The maximum number displayed for notifications.
(doom-aiern-modeline-number-limit 99)
;; The maximum displayed length of the branch name of version control.
(doom-aiern-modeline-vcs-max-length 12)
;; Whether display the workspace name. Non-nil to display in the mode-line.
(doom-aiern-modeline-workspace-name t)
;; Whether display the perspective name. Non-nil to display in the mode-line.
(doom-aiern-modeline-persp-name t)
;; If non nil the default perspective name is displayed in the mode-line.
(doom-aiern-modeline-display-default-persp-name nil)
;; If non nil the perspective name is displayed alongside a folder icon.
(doom-aiern-modeline-persp-icon t)
;; Whether display the `lsp' state. Non-nil to display in the mode-line.
(doom-aiern-modeline-lsp t)
;; Whether display the GitHub notifications. It requires `ghub' package.
(doom-aiern-modeline-github nil)
;; The interval of checking GitHub.
(doom-aiern-modeline-github-interval (* 30 60))
;; Whether display the modal state icon.
;; Including `evil', `overwrite', `god', `ryo' and `xah-fly-keys', etc.
;; From: https://www.reddit.com/r/emacs/comments/gqc9fm/visual_indication_of_the_mode_of_editing_with_evil/frt8trg?utm_source=share&utm_medium=web2x&context=3
(doom-aiern-modeline-modal-icon nil)
;; Whether display the mu4e notifications. It requires `mu4e-alert' package.
(doom-aiern-modeline-mu4e nil)
;; Whether display the gnus notifications.
(doom-aiern-modeline-gnus t)
;; Wheter gnus should automatically be updated and how often (set to 0 or smaller than 0 to disable)
(doom-aiern-modeline-gnus-timer 2)
;; Wheter groups should be excludede when gnus automatically being updated.
(doom-aiern-modeline-gnus-excluded-groups '("dummy.group"))
;; Whether display the IRC notifications. It requires `circe' or `erc' package.
(doom-aiern-modeline-irc t)
;; Function to stylize the irc buffer names.
(doom-aiern-modeline-irc-stylize 'identity)
;; Whether display the environment version.
(doom-aiern-modeline-env-version t)
;; Or for individual languages
(doom-aiern-modeline-env-enable-python t)
(doom-aiern-modeline-env-enable-ruby t)
(doom-aiern-modeline-env-enable-perl t)
(doom-aiern-modeline-env-enable-go t)
(doom-aiern-modeline-env-enable-elixir t)
(doom-aiern-modeline-env-enable-rust t)
;; Change the executables to use for the language version string
(doom-aiern-modeline-env-python-executable "python") ; or `python-shell-interpreter'
(doom-aiern-modeline-env-ruby-executable "ruby")
(doom-aiern-modeline-env-perl-executable "perl")
(doom-aiern-modeline-env-go-executable "go")
(doom-aiern-modeline-env-elixir-executable "iex")
(doom-aiern-modeline-env-rust-executable "rustc")
;; What to dispaly as the version while a new one is being loaded
(doom-aiern-modeline-env-load-string "...")
;; Hooks that run before/after the modeline version string is updated
(doom-aiern-modeline-before-update-env-hook nil)
(doom-aiern-modeline-after-update-env-hook nil))
As mentioned before, both ~evil~ and ~aiern~ require emacs-bind-map, by Justin Burkett:
(meq/up evil :use-package-preconfig (bind-map)
:meta-evil (evil-normal-state-map) (evil-insert-state-map)
More evil, courtesy of this and this:
:upnsd-postconfig (evil-evilified-state)
Disable the evil-escape-key-sequence
, and set the evil-undo-system
to ~undo-fu~
:gsetq (evil-escape-key-sequence nil evil-undo-system 'undo-fu evil-move-beyond-eol t)
This allows me to disable evil-insert-state
:
:leaf (evil :advice
(:override evil-insert-state (lambda (&rest args) (interactive)
(meq/disable-all-modal-modes))))
;; :demon
;; TODO
;; ((alloy-chord "") 'meq/toggle-evil-ex-cosmoem)
:config
;; From: https://www.reddit.com/r/emacs/comments/lp45zd/help_requested_in_configuring_ryomodal/gp3rfx9?utm_source=share&utm_medium=web2x&context=3
;; Kept for documentation porpoises
;; (eval
;; `(ryo-modal-keys
;; ("l l" ,(alloy-simulate-key ":wq <RET>") :first '(evil-normal-state) :name "wq")
;; ("l p" ,(alloy-simulate-key ":q <RET>") :first '(evil-normal-state) :name "q")
;; ("l o" ,(alloy-simulate-key ":w <RET>") :first '(evil-normal-state) :name "w")
;; ("l q" ,(alloy-simulate-key ":q! <RET>") :first '(evil-normal-state) :name "q!")))
;; Use to get command name:
;; Eg: (cdr (assoc "q" evil-ex-commands))
;; Then "C-x C-e" (eval-last-sexp)
;; TODO: How do I create a keymap `evil-ex-keymap' out of the `evil-ex-commands' alist?
;; (cosmoem-def :show-funs #'meq/evil-ex-cosmoem-show
;; :hide-funs #'meq/evil-ex-cosmoem-hide
;; :toggle-funs #'meq/evil-ex-cosmoem-toggle
;; :keymap 'evil-ex-keymap
;; ;; :transient t
;; )
;; (defun meq/evil-ex-cosmoem-toggle nil (interactive))
;; (defun meq/evil-ex-show-top-level nil (interactive)
;; (meq/which-key-show-top-level 'evil-ex-keymap))
;; (defun meq/toggle-evil-ex (ua) (interactive "p")
;; (if (= ua 4)
;; (funcall 'meq/toggle-inner 'evil-mode "evil-ex" (meq/fbatp evil-mode) 'evil-ex-keymap nil t)
;; (funcall 'meq/toggle-inner 'evil-mode "evil-ex" (meq/fbatp evil-mode) 'evil-ex-keymap)))
;; (defun meq/toggle-evil-ex-cosmoem (ua) (interactive "p")
;; (if (= ua 4)
;; (funcall 'meq/toggle-inner 'evil-mode "evil-ex" (meq/fbatp evil-mode) 'evil-ex-keymap t t)
;; (funcall 'meq/toggle-inner 'evil-mode "evil-ex" (meq/fbatp evil-mode) 'evil-ex-keymap t)))
Here is the setup for the deino
of cosmoem
maps referred to in the cosmoem use-package
definition:
<<8eae8e4e-adf4-45cc-ae3f-ac61384d6b75(map="evil-normal-state-map", mode="evil-mode", prefix="evil", short="e", package="evil")>>
)
Zen-mode with olivetti, by Paul W. Rankin:
(meq/up olivetti :gsetq (olivetti-body-width 0.60))
Colorful words with rainbow-identifiers, by Fanael Linithien:
(meq/up rainbow-identifiers
;; Adapted From:
;; Answer: https://stackoverflow.com/a/31253253/10827766
;; User: https://stackoverflow.com/users/2698552/chillaranand
;; :hook ((buffer-list-update window-configuration-change) . (lambda nil (interactive)
;; (rainbow-identifiers-mode 1)))
;; :upnsd-preconfig (xxh)
)
View Large Files with vlfi, by Andrey Kotlarski
(meq/upnsd vlf :gsetq (vlf-application 'always))
(meq/up doom-themes
:deino (deino-themes-light (:color blue) nil "A deino for light themes!" ("`" nil "cancel"))
(deino-themes-dark (:color blue) nil "A deino for dark themes!" ("`" nil "cancel"))
:sorrow ("t" :deino '(deino-themes nil "t" "A deino for themes!"
("s" meq/switch-theme-mode "switch to light / dark")
("l" deino-themes-light/body "light themes")
("d" deino-themes-dark/body "dark themes")
("`" nil "cancel")))
:gsetq
(doom-themes-enable-bold t)
(doom-themes-enable-italic t)
(meq/var/default-theme-override nil)
(meq/var/default-default-theme 'dracula-purple-dark)
;; :upnsd-postconfig
;; (doom-themes-ext-neotree :config (doom-themes-neotree-config))
;; (doom-themes-ext-org :config (doom-themes-org-config))
:config
(unless (meq/which-theme) (cond
((member "--purple" command-line-args)
(delete "--purple" command-line-args)
(meq/load-theme 'dracula-purple-dark))
((member "--orange" command-line-args)
(delete "--orange" command-line-args)
(meq/load-theme 'dracula-orange-dark))
((member "--red" command-line-args)
(delete "--red" command-line-args)
(meq/load-theme 'exo-ui-red-dark))
((member "--flamingo" command-line-args)
(delete "--flamingo" command-line-args)
(meq/load-theme 'herschel-flamingo-pink-dark))
((member "--blue" command-line-args)
(delete "--blue" command-line-args)
(meq/load-theme 'st-giles-blue-dark))
(meq/var/phone (meq/load-theme 'orange-purple-light))
(meq/var/default-theme-override (meq/load-theme meq/var/default-theme-override))
(meq/var/current-theme (meq/load-theme meq/var/current-theme))
((meq/exwm-p) (meq/load-theme meq/var/default-default-theme))
(t (meq/load-theme meq/var/default-default-theme))))
(mapc #'(lambda (theme) (interactive)
(let* ((name (symbol-name (car theme)))
(prefix (symbol-name (cdr theme)))
(light (concat name "-light"))
(dark (concat name "-dark")))
(eval `(defdeino+ deino-themes-light nil
(,prefix (funcall #'meq/load-theme ',(intern light)) ,light)))
(eval `(defdeino+ deino-themes-dark nil
(,prefix (funcall #'meq/load-theme ',(intern dark)) ,dark)))))
'((dracula-purple . p)
(dracula-orange . o)
(exo-ui-red . r)
(herschel-flamingo-pink . f)
(st-giles-blue . b)
(lio-fotia . l)
(orange-purple . C-o)
(flamingo-pink-purple . C-p)
(ghostfreak-green . g))))
(meq/up windmove
:config (winner-mode)
:deino (deino-wb nil nil ("b" deino-buffer/body "buffer") ("w" deino-window/body "window"))
The sorrow
config below is adapted from
here:
:sorrow ("w" :deino '(deino-window (:columns 5) "w"
("`" nil "cancel")
("s" deino-buffer/body "buffer" :color blue)
("B" balance-windows "balance-windows")
("t" toggle-window-spilt "toggle-window-spilt")
("H" shrink-window-horizontally "shrink-window-horizontally")
("K" shrink-window "shrink-window")
("J" enlarge-window "enlarge-window")
("L" enlarge-window-horizontally "enlarge-window-horizontally")
("R" reverse-windows "reverse-windows")
("h" windmove-left "←")
("j" windmove-down "↓")
("k" windmove-up "↑")
("l" windmove-right "→")
("q" deino-move-splitter-left "X←")
("w" deino-move-splitter-down "X↓")
("e" deino-move-splitter-up "X↑")
("r" deino-move-splitter-right "X→")
("F" follow-mode "Follow")
("v" (lambda nil (interactive) (split-window-right) (windmove-right)) "vertical")
("x" (lambda nil (interactive) (split-window-below) (windmove-down)) "horizontal")
("d" delete-window "delete")
("O" delete-other-windows "only this")
("z" (progn (winner-undo) (setq this-command 'winner-undo)) "undo")
("Z" winner-redo "reset")
("o" other-window "other-window"))))
(meq/up ace-window
:deino+ (deino-window (:color red)
("a" (lambda nil (interactive) (ace-window 1) (add-hook 'ace-window-end-once-hook
'deino-window/body)) "ace 1")
("S" (lambda nil (interactive) (ace-window 4) (add-hook 'ace-window-end-once-hook
'deino-window/body)) "swap")
("D" (lambda nil (interactive) (ace-window 16) (add-hook 'ace-window-end-once-hook
'deino-window/body)) "Delete Other")
("E" ace-swap-window "ace-swap-window")
("W" ace-delete-window "ace-delete-window" :exit t)))
(meq/upnsd cosmog :prime ("c" deino-cosmog/body "cosmog"))
(meq/up helm
;; :commands (helm-M-x helm-mini helm-mode)
:deino+ (deino-execute nil
("h" helm-smex-major-mode-commands "helm smex major mode")
("s" helm-smex "helm smex"))
(deino-window nil ("B" helm-mini "helm-mini")
("f" helm-find-files "helm-find-files"))
:upnsd-postconfig (helm-ido-like)
:use-package-postconfig ;; Adapted From: https://github.com/clemera/helm-ido-like-guide
(helm-smex)
(helm-flx)
(helm-swoop))
Adapted From: https://github.com/asok/.emacs.d/blob/master/inits/init-hydra.el#L62
(meq/up magit :deino (deino-magit (:color blue :columns 8) "g"
"It's just like magit!"
("s" magit-status "status")
("c" magit-checkout "checkout")
("b" magit-branch-manager "branch manager")
("m" magit-merge "merge")
("l" magit-log "log")
("c" magit-git-command "command")
("p" magit-process "process")
("`" nil "cancel")))
(meq/up modalka :config
Here is the setup for the deino
of cosmoem
maps referred to in the cosmoem use-package
definition:
<<8eae8e4e-adf4-45cc-ae3f-ac61384d6b75(map="modalka-mode-map", mode="modalka-mode", prefix="modalka", short="m", package="modalka")>>
)
(meq/up objed :config
Here is the setup for the deino
of cosmoem
maps referred to in the cosmoem use-package
definition:
<<8eae8e4e-adf4-45cc-ae3f-ac61384d6b75(map="objed-map", mode="objed-mode", prefix="objed", short="o", package="objed")>>
)
Adapted From: https://sam217pa.github.io/2016/09/23/keybindings-strategies-in-emacs/
(meq/up projectile
:use-package-preconfig (counsel-projectile :config (counsel-projectile-mode 1)) (helm-projectile)
;; Adapted From: https://codeberg.org/dr.ops/medusa/src/branch/main/medusa.org#headline-16
:deino (deino-projectile-other-window (:color teal) "p o"
"projectile-other-window"
("f" projectile-find-file-other-window "file")
("g" projectile-find-file-dwim-other-window "file dwim")
("d" projectile-find-dir-other-window "dir")
("b" projectile-switch-to-buffer-other-window "buffer")
("`" nil "cancel" :color blue))
:sorrow ("p" :deino '(deino-projectile
(:color teal :columns 4) "p p"
("a" counsel-projectile-ag "counsel-projectile-ag")
("g" counsel-projectile-rg "counsel-projectile-rg")
("c" counsel-projectile "counsel-projectile")
("b" counsel-projectile-switch-to-buffer "switch to buffer")
("C" projectile-invalidate-cache "cache clear")
("d" counsel-projectile-find-dir "find-dir")
("f" counsel-projectile-find-file "find-file")
("F" counsel-projectile-find-file-dwim "find-file-dwim")
("C-f" projectile-find-file-in-directory "find-file-in-dir")
("G" ggtags-update-tags "update gtags")
("i" projectile-ibuffer "Ibuffer")
("K" projectile-kill-buffers "kill all buffers")
("o" projectile-multi-occur "multi-occur")
("p" counsel-projectile-switch-project "switch project")
("r" projectile-recentf "recent file")
("x" projectile-remove-known-project "remove known project")
("X" projectile-cleanup-known-projects "cleanup non-existing projects")
("z" projectile-cache-current-file "cache current file")
("h" deino-helm-projectile/body "deino-helm-projectile")
("O" deino-projectile-other-window/body "deino-projectile-other-window")
("`" nil "cancel")))
("P" :deino '(deino-helm-projectile
(:color teal :columns 4) "p h"
("h" helm-projectile "helm-projectile")
("c" helm-projectile-switch-project "switch-project")
("f" helm-projectile-find-file "find-file")
("F" helm-projectile-find-file-dwim "find-file-dwim")
("d" helm-projectile-find-dir "find-dir")
("r" helm-projectile-recentf "recent file")
("b" helm-projectile-switch-to-buffer "switch to buffer")
("a" helm-projectile-ag "helm-projectile-ag")
("g" helm-projectile-rg "helm-projectile-rg")
("C-f" helm-projectile-find-file-in-known-projects "find file in known projects")
("`" nil "cancel"))))
Adapted from here, user5293’s answer here, Pandikunta Anand Reddy’s answer here:
(meq/up pyvenv :hook (after-init . pyvenv-mode)
:config (pyvenv-activate (meq/ued ".local" "venv"))
:gsetq (meq/var/python "python3")
(meq/var/hy "hy")
(pyvenv-post-activate-hooks (list (lambda () (setq python-shell-interpreter (concat pyvenv-virtual-env "bin/python3")
org-babel-hy-command (concat pyvenv-virtual-env "bin/hy")))))
(pyvenv-post-deactivate-hooks (list (lambda () (setq python-shell-interpreter meq/var/python
org-babel-hy-command meq/var/hy)))))
Cool package by Iqbal Ansari!
(meq/up restart-emacs
:deino (deino-restart (:color blue) "r"
("`" nil "cancel")
("l" meq/reload-emacs "reload")
("s" restart-emacs "restart")))
(meq/up ryo-modal
:config ;; From: https://github.com/Kungsgeten/ryo-modal#which-key-integration
(push '((nil . "ryo:.*:") . (nil . "")) which-key-replacement-alist)
Here is the setup for the deino
of cosmoem
maps referred to in the cosmoem use-package
definition:
<<8eae8e4e-adf4-45cc-ae3f-ac61384d6b75(map="ryo-modal-mode-map", mode="ryo-modal-mode", prefix="ryo", short="r", package="ryo-modal")>>
)
(meq/up vterm :use-package-postconfig (multi-vterm)
:if (not (member system-type '(windows-nt ms-dos)))
:gsetq
;; From: https://www.reddit.com/r/emacs/comments/pjtm91/vterm_a_little_bit_slow/hbz40xb?utm_medium=android_app&utm_source=share&context=3
(vterm-timer-delay 0.01)
(vterm-always-compile-module t)
(vterm-shell (meq/ued "vterm-start.sh"))
(vterm-kill-buffer-on-exit t))
(meq/up xah-fly-keys
:commands xah-fly-keys
:config
Here is the setup for the deino
of cosmoem
maps referred to in the cosmoem use-package
definition:
<<8eae8e4e-adf4-45cc-ae3f-ac61384d6b75(map="xah-fly-command-map", mode="xah-fly-keys", prefix="xah", short="x", package="xah-fly-keys")>>
:sorrow ("m" :deino
'(modal-modes (:color blue) "m"
"A modal deino!"
("`" nil "cancel")
("x" meq/toggle-xah "xah-fly-keys")) :name "modal modes"))
(setq show-paren-delay 0)
(add-hook 'after-init-hook #'show-paren-mode)
(meq/up lispy :config
Here is the setup for the deino
of cosmoem
maps referred to in the cosmoem use-package
definition:
<<8eae8e4e-adf4-45cc-ae3f-ac61384d6b75(map="lispy-mode-map", mode="lispy-mode", prefix="lispy", short="l", package="lispy")>>
)
(meq/up sly)
Set up my super major-mode titan:
(meq/upnsd titan-templates :gsetq (meq/var/titan-snippets-dir (meq/ued-lib "titan" "snippets")))
For caddyfiles:
(use-package caddyfile-mode :mode ("\\caddyfile\\'"))
For dockerfiles:
(use-package dockerfile-mode :mode ("\\Dockerfile\\'"))
(use-package hy-mode
:commands (org-babel-execute:hy)
:mode ("\\.hy\\'")
:upnsd-preconfig (ob-hy :commands (org-babel-execute:hy)))
For systemd
:
(use-package systemd-mode :mode ("\\.service\\'"))
For markdown:
(eval `(use-package markdown-mode :mode ,(meq/titan-append-modes "markdown" "\\.md\\'")))
For nix, with org-babel-execute:nix
coming from Zeta’s answer here:
(use-package nix-mode
:commands (org-babel-execute:nix)
:mode ("\\.nix\\'")
:init/defun*
(org-babel-execute:nix (body params)
"Execute a block of Nix code with org-babel."
(message "executing Nix source code block")
(let ((E (cdr (assoc :E params)))
(in-file (unless E (org-babel-temp-file "n" ".nix")))
(show-trace (cdr (assoc :show-trace params)))
(json (cdr (assoc :json params)))
(xml (cdr (assoc :xml params))))
(unless E (with-temp-file in-file (insert body)))
(org-babel-eval
(format "nix-instantiate --read-write-mode --eval %s %s %s %s"
(if show-trace "--show-trace" "")
(if json "--json" "")
(if xml "--xml" "")
(if E (format "-E '%s'" body) (org-babel-process-file-name in-file)))
""))))
(use-package ob-python :commands (org-babel-execute:python))
(use-package ob-shell :commands (org-babel-execute:shell))
For vimrc:
(use-package vimrc-mode
:commands (org-babel-execute:vimrc)
:mode "\\.vim\\(rc\\)?\\'")
For xonsh, again with org-babel-execute:xonsh
coming from Zeta’s answer here:
(use-package xonsh-mode
:commands (org-babel-execute:xonsh)
:mode ("\\.xonshrc\\'" "\\.xsh\\'")
:init/defun*
(org-babel-execute:xonsh (body params)
"Execute a block of Xonsh code with org-babel."
(message "executing Xonsh source code block")
(let ((in-file (org-babel-temp-file "x" ".xsh"))
(opts (or (cdr (assoc :opts params)) nil))
(args (or (cdr (assoc :args params)) nil)))
(with-temp-file in-file
(insert body))
(org-babel-eval
(format "xonsh %s %s %s"
(if (eq opts nil) "" opts)
(if (eq args nil) "" args)
(org-babel-process-file-name in-file))
""))))
For text
, again with org-babel-execute:text
coming from Zeta’s answer here:
(use-package text-mode
:commands (org-babel-execute:text)
:mode ("\\.txt\\'")
:init/defun*
(org-babel-execute:text (body params)
"Return a block of text with org-babel."
(message "returning text source code block")
(let ((in-file (org-babel-temp-file "t" ".txt")))
(with-temp-file in-file (insert body))
(org-babel-eval (format "%s %s"
(if meq/var/windows "type" "cat")
(org-babel-process-file-name in-file)) ""))))
The one and only org-mode, with org-contrib:
- Here’s the git repo
- Here’s the contrib repo
(eval `(use-package org
org-mode
will activate when any files using the ~titan-org~ super major-mode,
or with the extension .org
, are opened:
:mode ,(meq/titan-append-modes "org" '("\\.org\\'" . org-mode))
I used to use this to skip over expanding any sub-headers; now I just use my own:
:hook (org-cycle . (lambda (state) (interactive) (when (eq state 'children) (setq org-cycle-subtree-status 'subtree))))
:use-package-postconfig (org-contrib)
This sets up ox-pandoc by kawabata, for exporting files using pandoc, and my riot package, inspired by tecosaur’s package org-pandoc-import;
it essentially converts any files convertable by pandoc
to an org
file upon opening it, and then converts it back to the original format
on saving the file.
(ox-pandoc :upnsd-postconfig (riot :if (not (meq/item-in-cla "--anti-riot")))
:deino (deino-ob-export-as (:color blue) "o e a"
("`" nil "cancel")
("a" org-pandoc-export-as-asciidoc "asciidoc")
("g" org-pandoc-export-as-gfm "gfm")
("h" org-pandoc-export-as-html5 "html5")
("l" org-pandoc-export-as-latex "latex"))
(deino-ob-export-to (:color blue) "o e t"
("`" nil "cancel")
("a" org-pandoc-export-to-asciidoc "asciidoc")
("d" org-pandoc-export-to-docx "docx")
("o" org-pandoc-export-to-odt "odt")
("g" org-pandoc-export-to-gfm "gfm")
("h" org-pandoc-export-to-html5 "html5")
("l" org-pandoc-export-to-latex "latex"))
(deino-ob-export-and-open (:color blue) "o e o"
("`" nil "cancel")
("a" org-pandoc-export-to-asciidoc-and-open "asciidoc")
("g" org-pandoc-export-to-gfm-and-open "gfm")
("h" org-pandoc-export-to-html5-and-open "html5")
("l" org-pandoc-export-to-latex-and-open "latex"))
(deino-ob-export (:color blue) "o e e"
("`" nil "cancel")
("a" deino-ob-export-as/body "export as")
("t" deino-ob-export-to/body "export to")
("o" deino-ob-export-and-open/body "export and open"))
I have advised the org-pandoc-export
function to allow derived modes of org-mode
as well, to account for my super major-modes, such as ~titan~, ~fell~, ~doc~, etc.
:config/defun* (meq/org-pandoc-export-advice (format a s v b e &optional buf-or-open)
"General interface for Pandoc Export.
If BUF-OR-OPEN is nil, output to file. 0, then open the file.
t means output to buffer."
(unless (derived-mode-p 'org-mode)
(error "You must run this command in org-mode or its derived major modes."))
(unless (executable-find org-pandoc-command)
(error "Pandoc (version 1.12.4 or later) can not be found."))
(setq org-pandoc-format format)
(org-export-to-file 'pandoc (org-export-output-file-name
(concat (make-temp-name ".tmp") ".org") s)
a s v b e (lambda (f) (org-pandoc-run-to-buffer-or-file f format s buf-or-open))))
:leaf (ox-pandoc :advice (:override org-pandoc-export meq/org-pandoc-export-advice)))
Set up yasnippet by João Távora, with the deino
coming from here:
(yasnippet :config (add-to-list 'yas-snippet-dirs (meq/ued "snippets") t)
:deino (deino-yasnippet (:color blue :hint nil) "y"
"
^YASnippets^
--------------------------------------------
Modes: Load/Visit: Actions:
_g_lobal _d_irectory _i_nsert
_m_inor _f_ile _t_ryout
_e_xtra _l_ist _n_ew
_a_ll
"
("d" yas-load-directory)
("e" yas-activate-extra-mode)
("i" yas-insert-snippet)
("f" yas-visit-snippet-file :color blue)
("n" yas-new-snippet)
("t" yas-tryout-snippet)
("l" yas-describe-tables)
("g" yas/global-mode)
("m" yas/minor-mode)
("a" yas-reload-all)))
:config (load (executable-find "org-export-functions.el"))
(setq toggle-debug-on-error t)
;; (setq auto-mode-alist (append auto-mode-alist (meq/titan-append-modes org ("\\.org\\'" . org-mode))))
(defun meq/org-html-export-to-as-html (func &rest args) (let (org-confirm-babel-evaluate) (apply func args)))
(advice-add #'org-html-export-to-html :around #'meq/org-html-export-to-as-html)
(advice-add #'org-html-export-as-html :around #'meq/org-html-export-to-as-html)
Needed for :meta
and :meta-rename
for some reason; why is this necessary?
(mapc #'(lambda (key) (define-key org-mode-map (kbd key) nil))
'("ESC <left>"
"ESC <right>"
"ESC <up>"
"ESC <down>"
"ESC S-<left>"
"ESC S-<right>"
"ESC S-<up>"
"ESC S-<down>"))
:meta (org-mode-map)
:meta-rename (org-mode-map "ESC" "org-metadir")
:minoru (org-src-mode deino-edit-spc (:color blue) "o s"
("`" nil "cancel")
("i" meq/narrow-or-widen-dwim "narrow")
("x" org-edit-special "org edit special")
The following commands are from this file:
("s" org-edit-src-save "save")
("e" org-edit-src-exit "exit")
("a" org-edit-src-abort "abort"))
:uru (org-mode nil deino-org (:color blue) "o o"
"A deino for org-mode!"
("`" nil "cancel")
("t" org-babel-tangle "tangle")
("a" meq/org-babel-tangle-append "tangle append")
("F" org-babel-tangle-file "tangle file")
("n" meq/narrow-or-widen-dwim "narrow")
("s" org-edit-special "org edit special")
("e" deino-ob-export/body "export")
("g" meq/go-to-parent "go to parent")
("l" org-toggle-link-display "toggle link display")
("c" meq/org-custom-id-get-create "create uuid for heading CUSTOM_ID property")
("i" org-id-get-create "create uuid for heading ID property"))
:gsetq
;; I'm using ox-pandoc
;; (org-export-backends '(md gfm latex odt org))
(org-directory "/tmp")
(org-roam-directory org-directory)
(org-descriptive-links nil)
(org-startup-folded t)
;; (org-src-window-setup 'current-window)
;; (org-cycle-emulate-tab 'whitestart)
(org-support-shift-select t)
;; (org-src-tab-acts-natively t)
Upon exiting org-src-mode
I don’t want any indentation added to my code blocks, so I use doltes’s answer here:
(org-edit-src-content-indentation 0)))
Set up documentation super major-mode doc:
(use-package doc-templates
:commands (meq/dired-create-doc-markdown meq/dired-create-and-open-doc-markdown)
:gsetq (meq/var/doc-snippets-dir (meq/ued-lib "doc" "snippets"))
:uru (doc-org-mode nil deino-doc-org (:color blue :inherit (deino-org-usually/heads)) "t d o"
("d" (meq/insert-snippet "org titan template") "template")))
Set up novel’s super major-mode fell:
(use-package fell-templates
:commands (meq/dired-create-fell-markdown meq/dired-create-and-open-fell-markdown)
:gsetq (meq/var/fell-snippets-dir (meq/ued-lib "fell" "snippets"))
:uru (fell-org-mode nil deino-fell-org (:color blue :inherit (deino-org-usually/heads)) "t f o"
("f" (meq/insert-snippet "org titan template") "template")))