You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
26 KiB
26 KiB
- Initial setup
- Local vars
- Editing
- Added functionality
- Save/load
- Platform dependent
- Tramp configuration
- Major modes
- Minor modes/misc
- Navigation/auto-completion
- Look and feel
- Clipboard manager
- After-settings-load
Initial setup
(setq after-settings-load-hooks (list t))
Local vars
(advice-add 'risky-local-variable-p :override #'ignore)
Editing
Enable disabled commands
(put 'set-goal-column 'disabled nil) (put 'narrow-to-region 'disabled nil) (put 'upcase-region 'disabled nil) (put 'downcase-region 'disabled nil) (put 'scroll-left 'disabled nil) (put 'erase-buffer 'disabled nil)
IEdit mode
(use-package iedit
:bind ("M-]" . iedit-mode))
Imenu
(use-package imenu
:bind
("C-S-s" . imenu))
Spellcheck
(global-set-key (kbd "C-!") 'ispell-buffer)
String inflection
(use-package string-inflection
:bind ("C-x c" . my-string-inflection-cycle-auto)
:config
(defun my-string-inflection-cycle-auto ()
"switching by major-mode"
(interactive)
(cond
;; for emacs-lisp-mode
((eq major-mode 'emacs-lisp-mode)
(string-inflection-all-cycle))
;; for python
((eq major-mode 'python-mode)
(string-inflection-python-style-cycle))
;; for java
((eq major-mode 'java-mode)
(string-inflection-java-style-cycle))
(t
;; default
(string-inflection-ruby-style-cycle)))))
Undo tree
(use-package undo-tree
:diminish
:config
(global-undo-tree-mode))
Company Mode
(use-package company
:bind
("TAB" . company-indent-or-complete-common))
Added functionality
Kill this buffer
(defun rlbr/kill-this-buffer ()
(interactive)
(kill-buffer (current-buffer)))
Low memeory check
(defun rlbr/high-mem (&optional threshold)
(let ((threshold (or threshold (expt 1024 2)))))
(>= (nth 1 (memory-info))
threshold))
Multiline sexp with symbol
Jump to symbol, go up list, lispy-multiline. Great for diff-friendly custom
(require 'isearch)
(require 'lispy)
(defun rlbr/multiline-sexp-with-symbol (symbol-name)
(save-excursion
(beginning-of-buffer)
(search-forward-regexp (isearch-symbol-regexp symbol-name))
(backward-up-list)
(lispy-alt-multiline)))
Output matches
Run command for each matching exe and see if output-p is true when fed the command output
(defun rlbr/output-matches (output-matches-p exe args)
"locate the executable whose output satisfies output-matches-p when fed args and return the full-path"
(let ((exec-path exec-path)
(output)
(bad)
(command-output)
(current-exe)
(failed))
(while (not (or output failed))
(setq current-exe
(executable-find exe))
(if current-exe
(progn
(setq command-output
(shell-command-to-string (format "%s %s" (rlbr/quote-exe current-exe)
args)))
(if (funcall output-matches-p command-output)
(setq output current-exe)
(progn
(setq bad
(replace-regexp-in-string "/$" "" (file-name-directory current-exe)))
(setq exec-path
(seq-filter (lambda (item)
(not (rlbr/case-insensitive-match item bad)))
exec-path)))))
(setq failed t)))
output))
Prefix arg overload
(defun rlbr/prefix-arg-overload (func alt &optional alt-args)
(let ((advice `(lambda (func &optional arg)
(interactive "P")
(if arg (apply (quote ,alt)
,alt-args)
(apply func nil)))))
(advice-add func :around advice)
advice))
Save buffer-output to file
This handy function is a customized ripoff of custom-save-all
(defun rlbr/save-buffer-func-to-file (visit-file func args)
"Rip off of custom-save-all"
(let* ((filename visit-file)
(recentf-exclude (if recentf-mode (append `(,(concat "\\`" (regexp-quote (recentf-expand-file-name visit-file))
"\\'")
,(concat "\\`" (regexp-quote (file-truename (recentf-expand-file-name visit-file)))
"\\'"))
recentf-exclude)))
(old-buffer (find-buffer-visiting filename))
old-buffer-name)
(with-current-buffer (let ((find-file-visit-truename t))
(or old-buffer (let ((delay-mode-hooks t))
(find-file-noselect filename))))
(when old-buffer (setq old-buffer-name (buffer-file-name))
(set-visited-file-name (file-chase-links filename)))
(unless (eq major-mode 'emacs-lisp-mode)
(delay-mode-hooks (emacs-lisp-mode)))
(let ((inhibit-read-only t)
(print-length nil)
(print-level nil))
(apply func args))
(let ((file-precious-flag t))
(save-buffer))
(if old-buffer (progn (set-visited-file-name old-buffer-name)
(set-buffer-modified-p nil))
(kill-buffer (current-buffer))))))
Save/load
Backup/auto-save
(let ((backup-dir "~/.emacs.d/backup")
(auto-save-dir "~/.emacs.d/autosave"))
(if (not (file-directory-p backup-dir))
(make-directory backup-dir))
(if (not (file-directory-p
auto-save-dir))
(make-directory auto-save-dir)))
On save
(add-hook 'before-save-hook 'delete-trailing-whitespace)
Recent files mode
(use-package recentf
:config
(recentf-mode 1))
Automode priority
(add-to-list 'after-settings-load-hooks
'(progn
(setq rlbr/mode-priority-list
(list
'docker-compose-mode))
(defun rlbr/move-to-top (priority alist)
(let ((ret-alist (copy-sequence alist))
(cons-pair))
(dolist (to-move (reverse priority)
ret-alist)
(if (setq cons-pair (rassq to-move ret-alist))
(progn (delete cons-pair ret-alist)
(setq ret-alist (cons cons-pair ret-alist)))))))
(setq auto-mode-alist (rlbr/move-to-top rlbr/mode-priority-list auto-mode-alist))))
Platform dependent
Windows
(when (string-equal system-type "windows-nt")
(progn (defun rlbr/quote-exe (path)
(w32-short-file-name path))
(defun rlbr/high-mem (&optional threshold) t)
(defun rlbr/start-external-shell ()
(interactive)
(start-process-shell-command (format "cmd(%s)" default-directory)
nil "start default.bat"))
(global-set-key (kbd "C-S-C")
'rlbr/start-external-shell)
(defun rlbr/start-windows-explorer-here ()
(interactive)
(start-process-shell-command "explorer" nil (format "explorer %s" (replace-regexp-in-string "/" (regexp-quote "\\")
(expand-file-name default-directory)))))
(global-set-key (kbd "C-S-E")
'rlbr/start-windows-explorer-here)
(defun rlbr/case-insensitive-match (string1 string2)
(apply 'string-equal (mapcar 'downcase (list string1 string2))))
(let ((find)
(grep)
(ls))
(progn (setq find (rlbr/output-matches (lambda (output)
(string-equal ".\n" output))
"find" "-maxdepth 0"))
(if find (setq find-program (rlbr/quote-exe find)))
(setq grep (rlbr/output-matches (lambda (output)
(string-match "grep (\\w+ grep)" output))
"grep" "-V"))
(if grep (setq grep-program (rlbr/quote-exe grep)))
(setq ls (rlbr/output-matches (lambda (output)
(string-match "ls: .*'\\?/': No such file or directory" output))
"ls" "?/"))
(if ls (setq insert-directory-program (rlbr/quote-exe ls)))))))
Tramp configuration
Tramp append plist to connection properties
(use-package kv
:config
(defun rlbr/add-config-to-tramp (matches-regexp config-plist)
(let ((config-alist (kvplist->alist config-plist)))
(dolist (pair config-alist)
(let ((config (list matches-regexp (car pair)
(cdr pair))))
(add-to-list 'tramp-connection-properties config))))))
Android
(use-package tramp
:config
(let ((android-config (let ((default-directory "/data/data/com.termux/files"))
(list "tmpdir" (expand-file-name "home/temp/")
"remote-shell" (expand-file-name "usr/bin/sh")
"remote-process-environment" (append (list (concat "PREFIX=" default-directory "usr")) tramp-remote-process-environment)
"remote-path" (append (mapcar 'expand-file-name '("home/.local/bin" "usr/bin" "usr/bin/applets")) '("/sbin" "/vendor/bin" "/system/sbin" "/system/bin" "/system/xbin"))))))
(rlbr/add-config-to-tramp (rx "/" (or "scp" "ssh") (zero-or-one "x") ":" "termux" (zero-or-more any) ":") android-config)))
Dired rysnc
(use-package dired
:bind
(:map dired-mode-map
("C-c C-r" . dired-rsync))
:config (use-package dired-rsync))
Major modes
Assembly
(use-package asm-mode
:mode (rx ".sim" eos))
C
(use-package cc-mode :hook (c-mode . (lambda ()
(company-mode)
(format-all-mode)
(format-all-ensure-formatter))))
Docker
Docker
Dockerfile
Docker-compose
(use-package docker-compose-mode
:config
;; auto-mode hack
(let
((docker-compose-mode-regex (rassq 'docker-compose-mode auto-mode-alist)))
(setq auto-mode-alist (cons docker-compose-mode-regex (rassq-delete-all 'docker-compose-mode auto-mode-alist))))
:hook
(docker-compose-mode . company-mode))
Java
Meghanada
(use-package autodisass-java-bytecode
:defer t)
(use-package meghanada
:if (rlbr/high-mem (* 512 1024))
:defer t
:init
(add-hook 'java-mode-hook
(lambda ()
(meghanada-mode t)
(flycheck-mode +1)
(add-hook 'before-save-hook 'meghanada-code-beautify-before-save)))
:config
(setq indent-tabs-mode nil)
(setq meghanada-server-remote-debug t)
(setq meghanada-javac-xlint "-Xlint:all,-processing")
(advice-add 'meghanada-code-beautify :around (lambda (old)
(interactive)
(let ((p (line-number-at-pos)))
(apply old nil)
(goto-line p)
(reposition-window))))
(defhydra hydra-meghanada (:hint nil :exit t)
"
^Edit^ ^Tast or Task^
^^^^^^-------------------------------------------------------
_f_: meghanada-compile-file _m_: meghanada-restart
_c_: meghanada-compile-project _t_: meghanada-run-task
_o_: meghanada-optimize-import _j_: meghanada-run-junit-test-case
_s_: meghanada-switch-test-case _J_: meghanada-run-junit-class
_v_: meghanada-local-variable _R_: meghanada-run-junit-recent
_i_: meghanada-import-all _r_: meghanada-reference
_g_: magit-status _T_: meghanada-typeinfo
_q_: exit
"
("f" meghanada-compile-file)
("m" meghanada-restart)
("c" meghanada-compile-project)
("o" meghanada-optimize-import)
("s" meghanada-switch-test-case)
("v" meghanada-local-variable)
("i" meghanada-import-all)
("g" magit-status)
("t" meghanada-run-task)
("T" meghanada-typeinfo)
("j" meghanada-run-junit-test-case)
("J" meghanada-run-junit-class)
("R" meghanada-run-junit-recent)
("r" meghanada-reference)
("q" exit)
("z" nil "leave"))
:bind
(:map meghanada-mode-map
("C-S-t" . meghanada-switch-testcase)
("M-RET" . meghanada-local-variable)
("M-r" . meghanada-reference)
("M-t" . meghanada-typeinfo)
("C-z" . hydra-meghanada/body))
:commands
(meghanada-mode))
JavaScript
(use-package js2-mode
:mode "\\.js\\'"
:hook ((js2-mode . js2-imenu-extras-mode)
(js2-mode . (lambda () (add-hook 'xref-backend-functions #'xref-js2-xref-backend nil t))))
:config
(use-package js2-refactor
:hook (js2-mode . js2-refactor-mode)
:bind
(:map js2-mode-map
("C-k" . js2r-kill))
:config
(js2r-add-keybindings-with-prefix "C-c C-r"))
(use-package xref-js2
:demand t)
(define-key js-mode-map (kbd "M-.") nil)
(defun rlbr/jump-to-definition ()
"Jump to a definition."
(interactive)
(condition-case-unless-debug nil
(js2-jump-to-definition)
(error
(progn
(ignore-errors
(xref-pop-marker-stack))
(xref-find-definitions (xref-backend-identifier-at-point (xref-find-backend)))))))
(define-key js-mode-map (kbd "M-.") #'rlbr/jump-to-definition))
JSON
(use-package json
:config
(use-package json-mode
:bind (:map json-mode-map
("C-c p p" . json-pretty-print-buffer-ordered)))
(use-package json-reformat
:config
(setq json-encoding-default-indentation (make-string json-reformat:indent-width ? ))))
Lisp
Emacs lisp
(use-package elisp-mode
:hook (emacs-lisp-mode . company-mode))
Magit
(use-package magit
:bind (("C-x g" . magit-status))
:config
(use-package git-commit
:hook (git-commit-setup . git-commit-turn-on-flyspell)))
Org Journal
(use-package org-journal
:bind
("C-c TAB" . org-journal-new-entry))
Python
Platform specific
Set python command
(setq elpy-rpc-python-command (cond ((string-equal system-type "gnu/linux") "python3") ((string-equal system-type "windows-nt") "pythonw.exe")))
put executables in elpy-rpc-venv in path
(defun rlbr/elpy-append-to-path ()
(setenv "PATH" (string-join (list (getenv "PATH")
(let ((default-directory (elpy-rpc-get-or-create-virtualenv))
(path-entry)
(elpy-binpath))
(if (string-equal system-type "windows-nt")
(progn (setq elpy-binpath (expand-file-name "Scripts"))
(setq path-entry (replace-regexp-in-string (regexp-quote "/")
(regexp-quote "\\")
elpy-binpath)))
(setq elpy-binpath (expand-file-name "bin"))
(setq path-entry elpy-binpath))
(nconc exec-path (list elpy-binpath))
elpy-binpath))
path-separator)))
(defun rlbr/fix-for-android ()
(unless (= 0 (call-process elpy-rpc-python-command nil nil nil "-c" "import multiprocessing;multiprocessing.Pool()"))
(setq python-check-command
(string-join `(,python-check-command "--jobs=1") " "))))
Custom feature
(defun rlbr/join-venv-with-number (number-name)
"Join a list with a name and a number"
(let
((number (car number-name))
(name (cdr number-name)))
(if (= number 0)
name
(string-join (list name (number-to-string number))
"~"))))
(defun rlbr/split-venv-with-number (name-number)
"Split a virtualenv name with either a ~ seperating the name and the number, or nothing"
(let ((split-result (split-string name-number (regexp-quote "~")))
(ret))
(if (= 1 (length split-result))
(progn
(setq ret (car split-result))
(push 0 ret))
(progn
(setq ret
(string-join
(butlast split-result)
"~"))
(push
(string-to-number
(car (last split-result)))
ret)))
ret))
(defun rlbr/get-venv-name (&optional library-root)
"Generate venv name based off of the base-name of the library root"
(file-name-base
(directory-file-name
(if library-root
library-root
(elpy-library-root)))))
(defun rlbr/handle-name-conflicts (venv-name)
"Deal with potential name conflicts in venv"
(let ((venv-conflicts)
(venv-partition-name))
(setq venv-partition-name (rlbr/split-venv-with-number venv-name))
(setq venv-conflicts
(seq-filter
(lambda (item)
(string-equal (cdr item)
venv-name))
(mapcar #'rlbr/split-venv-with-number (pyvenv-virtualenv-list))))
(when venv-conflicts
(setcar venv-partition-name (1+ (apply 'max (mapcar #'car venv-conflicts)))))
(rlbr/join-venv-with-number venv-partition-name)))
(require 'vc)
(defun rlbr/setup-python-venv-dirlocals (&optional library-root venv-name)
"Setup .dir-locals file in library root and tell vc system to ignore .dir-locals file"
(let* ((library-root (if library-root
library-root
(elpy-library-root)))
(venv-name (if venv-name venv-name (rlbr/get-venv-name library-root)))
(default-directory library-root)
(dir-locals-path (expand-file-name
".dir-locals.el")))
(rlbr/save-buffer-func-to-file dir-locals-path 'add-dir-local-variable
`(python-mode pyvenv-workon ,venv-name))
(let ((vc-root (vc-find-root dir-locals-path ".git")))
(when vc-root
;; If the directory is under version control
(let ((vc-ignore-file (vc-call-backend 'Git 'find-ignore-file vc-root)))
(if (apply 'string-equal (mapcar 'directory-file-name (mapcar 'file-truename (list vc-root library-root))))
;; If the vc-root is the same as the library root, don't ask any questions
(vc-ignore ".dir-locals.el")
;; Otherwise prompt to ignore
(when (y-or-n-p (format "Ignore .dir-locals.el in repo '%s' ?" vc-root))
(vc-ignore ".dir-locals.el"))))))))
(defun rlbr/get-python-executable ()
(read-file-name "Python interpreter to use: " (file-name-directory (executable-find "python"))
nil nil "python"))
(defun emacs-default-venv ()
(unless (member "emacs-default-venv" (pyvenv-virtualenv-list))
(pyvenv-create "emacs-default-venv" (rlbr/get-python-executable)))
"emacs-default-venv")
(defun rlbr/init-python-venv-in-library-root (&optional library-root)
"Prompt to either create one or use default" (let ((venv-name (rlbr/get-venv-name))
(library-root (if library-root library-root (elpy-library-root))))
(let ((workon-home (pyvenv-workon-home)))
(unless (file-exists-p workon-home)
(make-directory workon-home t)))
(setq venv-name (rlbr/handle-name-conflicts venv-name))
(if (y-or-n-p (format "Create venv '%s'?" venv-name))
(pyvenv-create venv-name (rlbr/get-python-executable))
(progn
(setq venv-name (emacs-default-venv))))
(rlbr/setup-python-venv-dirlocals library-root venv-name)
venv-name))
(require 'dash)
(defun rlbr/init-venv ()
(when (eq major-mode 'python-mode)
(cond ((file-remote-p buffer-file-name)
;; If the file is remote, don't try and do anything fancy
(setq-local pyvenv-workon (emacs-default-venv)))
((let ((buffer-file-name (file-truename buffer-file-name)))
;; Don't change anything if entering a file in a python install's lib (ie for a file located with xref)
(string-match-p (rx bos (or
;; Windows
(and letter ":/" (one-or-more not-newline)
"/Lib")
;; Rest of the sane world
(and (or
;; In the home directory
(and (zero-or-more not-newline)
"/home/" (zero-or-more not-newline)
(or
;; System python user installed package
"/.local"
;; In a virtualenv
(and "/.virtualenvs/" (one-or-more (not (any "/"))))
;; Elpy-rpc venv
(and "/.emacs.d/elpy/rpc-venv")
;; Using Pyenv
(and "/.pyenv/versions/"
(one-or-more (not (any "/"))))))
;; System python
(and (zero-or-more not-newline)
"/usr"
(opt "/local")))
;; Standard */lib/python3.7/ etc
(or
;; Standard python
(and "/lib/python" (one-or-more (any digit ".")))
;; PyPy
(and (or "/lib-python" "/lib_pypy")))))
(zero-or-more not-newline))
buffer-file-name))
nil)
(t
;; Upon failing all conditions, prompt to create virtual environment if it doesn't exist
(cond ((and pyvenv-workon (not (member pyvenv-workon (pyvenv-virtualenv-list))))
;; If there is a virtualenv specified and it doesn't exist, prompt to create it or set to default virtual environment
(if (y-or-n-p (format "Venv '%s' is specified but does not exist. Create it?" pyvenv-workon))
(progn (pyvenv-create pyvenv-workon (rlbr/get-python-executable))
(pyvenv-workon pyvenv-workon))
(rlbr/save-buffer-func-to-file (let ((default-directory (elpy-library-root)))
(expand-file-name ".dir-locals.el"))
'add-dir-local-variable '(python-mode pyvenv-workon (emacs-default-venv)))
(setq-local pyvenv-workon (emacs-default-venv))))
((not pyvenv-workon)
;; If nothing has already set pyvenv-workon, create venv
(setq-local pyvenv-workon (rlbr/init-python-venv-in-library-root))))))
(pyvenv-workon pyvenv-workon)))
Bindings/settings
(use-package python
:hook
((python-mode . pyvenv-mode)
(python-mode . flycheck-mode)
(python-mode . (lambda () (add-hook 'before-save-hook 'elpy-black-fix-code nil 'local))))
:bind
(:map python-mode-map
(("C-<" . flycheck-previous-error)
("C->" . flycheck-next-error)))
:config
(use-package elpy
:hook (hack-local-variables . rlbr/init-venv)
:bind (:map python-mode-map
(("C-=" . elpy-goto-assignment)
("M-." . elpy-goto-definition)))
:config
(when (require 'flycheck nil t)
(setq elpy-modules (delq 'elpy-module-flymake elpy-modules)))
(rlbr/prefix-arg-overload 'elpy-goto-definition 'elpy-goto-definition-other-window)
(rlbr/prefix-arg-overload 'elpy-goto-assignment 'elpy-goto-assignment-other-window)
(rlbr/elpy-append-to-path)
(rlbr/fix-for-android)
(pyvenv-tracking-mode))
(use-package realgud
:bind (:map python-mode-map
(("C-c d b" . realgud:pdb))))
(elpy-enable))
pip-requirements-mode
(use-package pip-requirements-mode
:hook
(pip-requirements-mode . company-mode))
SSH config mode
(use-package ssh-config-mode
:mode "~/.ssh/config\\'")
Tramp
Webmode
(use-package web-mode
:mode
(("\\.phtml\\'" . web-mode)
("\\.tpl\\.php\\'" . web-mode)
("\\.[agj]sp\\'" . web-mode)
("\\.as[cp]x\\'" . web-mode)
("\\.erb\\'" . web-mode)
("\\.mustache\\'" . web-mode)
("\\.djhtml\\'" . web-mode)
("\\.html?\\'" . web-mode)))
YAML
(use-package yaml-mode
:mode "\\.yml\\'")
Minor modes/misc
Better shell
(use-package better-shell
:bind
(("M-V l" . better-shell-shell)
("M-V r" . better-shell-remote-open)
("M-V s" . better-shell-sudo-here)))
Custom custom
(advice-add 'custom-save-faces :after (lambda () (rlbr/multiline-sexp-with-symbol "custom-set-faces"))) (advice-add 'custom-save-variables :after (lambda () (rlbr/multiline-sexp-with-symbol "custom-set-variables")))
Elmacro
(use-package elmacro
:diminish
:demand
:config
(elmacro-mode +1))
Kill the things
Buffer
(global-set-key (kbd "C-x k") 'rlbr/kill-this-buffer)
Emacs
(global-set-key (kbd "C-x C-k C-x C-k") 'save-buffers-kill-emacs)
Lispy
(use-package lispy
:hook ((emacs-lisp-mode) . lispy-mode))
Navigation/auto-completion
Ace window
(use-package ace-window
:bind (:map global-map ("C-\\" . ace-window)))
Avy-mode
(use-package ace-window
:bind (("M-S-j" . avy-goto-symbol-1) ("M-j" . avy-goto-char-timer)))
Disable Ido
(use-package ido
:config
(ido-mode -1))
Disable mouse
(use-package disable-mouse
:config
(global-disable-mouse-mode))
Hippie expand
(use-package hippie-exp
:bind ("M-/" . hippie-expand))
IBuffer mode
(use-package ibbufer-vc
:hook
((ibuffer-mode . ibuffer-vc-set-filter-groups-by-vc-root)))
;; Use human readable Size column instead of original one
(use-package ibuffer :bind (("C-x C-b" . ibuffer))
:bind (:map ibuffer-mode-map
(("C-c t" . ibuffer-tramp-set-filter-groups-by-tramp-connection)
("C-c g" . ibuffer-vc-set-filter-groups-by-vc-root)))
:config (define-ibuffer-column size-h (:name "Size" :inline t)
(cond ((> (buffer-size)
1000000)
(format "%7.1fM" (/ (buffer-size)
1000000.0)))
((> (buffer-size)
100000)
(format "%7.0fk" (/ (buffer-size)
1000.0)))
((> (buffer-size)
1000)
(format "%7.1fk" (/ (buffer-size)
1000.0)))
(t (format "%8d" (buffer-size))))))
Ivy
(use-package ivy
:diminish
:config
(use-package counsel
:diminish)
(use-package swiper
:bind ("C-s" . swiper))
(ivy-mode)
(counsel-mode))
Look and feel
Line numbers
(global-display-line-numbers-mode)
Mode line bell
(use-package mode-line-bell
:config
(mode-line-bell-mode))
Smart mode line
(use-package smart-mode-line
:init
:config
(sml/setup))
Theme
(use-package dracula-theme
:config
(load-theme 'dracula t))
Clipboard manager
Clipmon settings
(use-package clipmon
:if (or (eq system-type 'windows-nt) (member "X11" (split-string system-configuration-features " ")))
:hook ((after-init . clipmon-mode-start)
(after-init . clipmon-persist)))
After-settings-load
(mapcar (lambda (form) (eval form)) after-settings-load-hooks)