yeet
This commit is contained in:
60
.config/emacs/modules/lang/emacs-lisp/README.org
Normal file
60
.config/emacs/modules/lang/emacs-lisp/README.org
Normal file
@@ -0,0 +1,60 @@
|
||||
#+TITLE: lang/emacs-lisp
|
||||
#+DATE: January 16, 2017
|
||||
#+SINCE: v1.3
|
||||
#+STARTUP: inlineimages nofold
|
||||
|
||||
* Table of Contents :TOC_3:noexport:
|
||||
- [[#description][Description]]
|
||||
- [[#maintainers][Maintainers]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#hacks][Hacks]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#features][Features]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#troubleshooting][Troubleshooting]]
|
||||
|
||||
* Description
|
||||
This module extends support for Emacs Lisp in Doom Emacs.
|
||||
|
||||
+ Macro expansion
|
||||
+ Go-to-definitions or references functionality
|
||||
|
||||
** Maintainers
|
||||
+ @hlissner (author)
|
||||
|
||||
** Module Flags
|
||||
This module provides no flags.
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/jorgenschaefer/emacs-buttercup][buttercup]]
|
||||
+ [[https://github.com/Wilfred/elisp-def][elisp-def]]
|
||||
+ [[https://github.com/xuchunyang/elisp-demos][elisp-demos]]
|
||||
+ [[https://github.com/flycheck/flycheck-cask][flycheck-cask]] (=:checkers syntax=)
|
||||
+ [[https://github.com/Fanael/highlight-quoted][highlight-quoted]]
|
||||
+ [[https://github.com/joddie/macrostep][macrostep]]
|
||||
+ [[https://github.com/tonini/overseer.el][overseer]]
|
||||
|
||||
** Hacks
|
||||
+ Symbols that are defined in the current session are highlighted with
|
||||
~font-lock-variable-face~.
|
||||
+ Eldoc will display the values of variables next to its documentation.
|
||||
+ ~elisp-demos~ was modified to display API demos for Doom's standard library
|
||||
(in [[file:../../../docs/api.org][docs/api.org]]).
|
||||
+ This module extends imenu support for Doom's API (e.g. ~package!~,
|
||||
~use-package~, ~after!~)
|
||||
+ Flycheck has been configured to tone down the false positives when you are
|
||||
editing your Emacs or Doom config.
|
||||
|
||||
* Prerequisites
|
||||
This module's sole dependency is Emacs. It's very obscure, you wouldn't know
|
||||
about it.
|
||||
|
||||
* TODO Features
|
||||
# An in-depth list of features, how to use them, and their dependencies.
|
||||
|
||||
* TODO Configuration
|
||||
# How to configure this module, including common problems and how to address them.
|
||||
|
||||
* TODO Troubleshooting
|
||||
# Common issues and their solution, or places to look for help.
|
||||
328
.config/emacs/modules/lang/emacs-lisp/autoload.el
Normal file
328
.config/emacs/modules/lang/emacs-lisp/autoload.el
Normal file
@@ -0,0 +1,328 @@
|
||||
;;; lang/emacs-lisp/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;
|
||||
;;; Library
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-eval (beg end)
|
||||
"Evaluate a region and print it to the echo area (if one line long), otherwise
|
||||
to a pop up buffer."
|
||||
(+eval-display-results
|
||||
(string-trim-right
|
||||
(condition-case-unless-debug e
|
||||
(let ((result
|
||||
(let ((buffer-file-name
|
||||
(buffer-file-name (buffer-base-buffer)))
|
||||
(doom--current-module
|
||||
(ignore-errors (doom-module-from-path buffer-file-name)))
|
||||
(debug-on-error t))
|
||||
(eval (read (format "(progn %s)"
|
||||
(buffer-substring-no-properties beg end)))
|
||||
lexical-binding))))
|
||||
(require 'pp)
|
||||
(replace-regexp-in-string "\\\\n" "\n" (pp-to-string result)))
|
||||
(error (error-message-string e))))
|
||||
(current-buffer)))
|
||||
|
||||
|
||||
;;
|
||||
;;; Handlers
|
||||
|
||||
(defun +emacs-lisp--module-at-point ()
|
||||
"Return (CATEGORY MODULE FLAG) at point inside a `doom!' block."
|
||||
(let ((origin (point))
|
||||
(syntax (syntax-ppss)))
|
||||
(when (and (> (ppss-depth syntax) 0) (not (ppss-string-terminator syntax)))
|
||||
(save-excursion
|
||||
(let ((parens (ppss-open-parens syntax))
|
||||
(doom-depth 1))
|
||||
(while (and parens (progn (goto-char (car parens))
|
||||
(not (looking-at "(doom!\\_>"))))
|
||||
(setq parens (cdr parens)
|
||||
doom-depth (1+ doom-depth)))
|
||||
(when parens ;; Are we inside a `doom!' block?
|
||||
(goto-char origin)
|
||||
(let* ((doom-start (car parens))
|
||||
(bare-symbol
|
||||
(if (ppss-comment-depth syntax)
|
||||
(= (save-excursion (beginning-of-thing 'list)) doom-start)
|
||||
(null (cdr parens))))
|
||||
(sexp-start (if bare-symbol
|
||||
(beginning-of-thing 'symbol)
|
||||
(or (cadr parens) (beginning-of-thing 'list))))
|
||||
(match-start nil))
|
||||
(goto-char sexp-start)
|
||||
(while (and (not match-start)
|
||||
(re-search-backward
|
||||
"\\_<:\\(?:\\sw\\|\\s_\\)+\\_>" ;; Find a keyword.
|
||||
doom-start 'noerror))
|
||||
(unless (looking-back "(")
|
||||
(let ((kw-syntax (syntax-ppss)))
|
||||
(when (and (= (ppss-depth kw-syntax) doom-depth)
|
||||
(not (ppss-string-terminator kw-syntax))
|
||||
(not (ppss-comment-depth kw-syntax)))
|
||||
(setq match-start (point))))))
|
||||
(when match-start
|
||||
(let (category module flag)
|
||||
;; `point' is already at `match-start'.
|
||||
(setq category (symbol-at-point))
|
||||
(goto-char origin)
|
||||
(if bare-symbol
|
||||
(setq module (symbol-at-point))
|
||||
(let ((symbol (symbol-at-point))
|
||||
(head (car (list-at-point))))
|
||||
(if (and (symbolp head) (not (keywordp head))
|
||||
(not (eq head symbol)))
|
||||
(setq module head
|
||||
flag symbol)
|
||||
(setq module symbol))))
|
||||
(list category module flag))))))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-lookup-definition (_thing)
|
||||
"Lookup definition of THING."
|
||||
(if-let (module (+emacs-lisp--module-at-point))
|
||||
(doom/help-modules (car module) (cadr module) 'visit-dir)
|
||||
(call-interactively #'elisp-def)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-lookup-documentation (thing)
|
||||
"Lookup THING with `helpful-variable' if it's a variable, `helpful-callable'
|
||||
if it's callable, `apropos' otherwise."
|
||||
(cond ((when-let (module (+emacs-lisp--module-at-point))
|
||||
(doom/help-modules (car module) (cadr module))
|
||||
(when (eq major-mode 'org-mode)
|
||||
(with-demoted-errors "%s"
|
||||
(re-search-forward
|
||||
(if (caddr module)
|
||||
"\\* Module Flags$"
|
||||
"\\* Description$"))
|
||||
(when (caddr module)
|
||||
(re-search-forward (format "=\\%s=" (caddr module))
|
||||
nil t))
|
||||
(when (invisible-p (point))
|
||||
(org-show-hidden-entry))))
|
||||
'deferred))
|
||||
(thing (helpful-symbol (intern thing)))
|
||||
((call-interactively #'helpful-at-point))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-indent-function (indent-point state)
|
||||
"A replacement for `lisp-indent-function'.
|
||||
|
||||
Indents plists more sensibly. Adapted from
|
||||
https://emacs.stackexchange.com/questions/10230/how-to-indent-keywords-aligned"
|
||||
(let ((normal-indent (current-column))
|
||||
(orig-point (point))
|
||||
;; TODO Refactor `target' usage (ew!)
|
||||
target)
|
||||
(goto-char (1+ (elt state 1)))
|
||||
(parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)
|
||||
(cond ((and (elt state 2)
|
||||
(or (not (looking-at-p "\\sw\\|\\s_"))
|
||||
(eq (char-after) ?:)))
|
||||
(unless (> (save-excursion (forward-line 1) (point))
|
||||
calculate-lisp-indent-last-sexp)
|
||||
(goto-char calculate-lisp-indent-last-sexp)
|
||||
(beginning-of-line)
|
||||
(parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t))
|
||||
(backward-prefix-chars)
|
||||
(current-column))
|
||||
((and (save-excursion
|
||||
(goto-char indent-point)
|
||||
(skip-syntax-forward " ")
|
||||
(not (eq (char-after) ?:)))
|
||||
(save-excursion
|
||||
(goto-char orig-point)
|
||||
(and (eq (char-after) ?:)
|
||||
(eq (char-before) ?\()
|
||||
(setq target (current-column)))))
|
||||
(save-excursion
|
||||
(move-to-column target t)
|
||||
target))
|
||||
((let* ((function (buffer-substring (point) (progn (forward-sexp 1) (point))))
|
||||
(method (or (function-get (intern-soft function) 'lisp-indent-function)
|
||||
(get (intern-soft function) 'lisp-indent-hook))))
|
||||
(cond ((or (eq method 'defun)
|
||||
(and (null method)
|
||||
(> (length function) 3)
|
||||
(string-match-p "\\`def" function)))
|
||||
(lisp-indent-defform state indent-point))
|
||||
((integerp method)
|
||||
(lisp-indent-specform method state indent-point normal-indent))
|
||||
(method
|
||||
(funcall method indent-point state))))))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Commands
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp/open-repl ()
|
||||
"Open the Emacs Lisp REPL (`ielm')."
|
||||
(interactive)
|
||||
(pop-to-buffer
|
||||
(or (get-buffer "*ielm*")
|
||||
(progn (ielm)
|
||||
(let ((buf (get-buffer "*ielm*")))
|
||||
(bury-buffer buf)
|
||||
buf)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp/buttercup-run-file ()
|
||||
"Run all buttercup tests in the focused buffer."
|
||||
(interactive)
|
||||
(let ((load-path
|
||||
(append (list (doom-path (dir!) "..")
|
||||
(or (doom-project-root)
|
||||
default-directory))
|
||||
load-path))
|
||||
(buttercup-suites nil))
|
||||
(save-selected-window
|
||||
(eval-buffer)
|
||||
(buttercup-run))
|
||||
(message "File executed successfully")))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp/buttercup-run-project ()
|
||||
"Run all buttercup tests in the project."
|
||||
(interactive)
|
||||
(let* ((default-directory (doom-project-root))
|
||||
(load-path (append (list (doom-path "test")
|
||||
default-directory)
|
||||
load-path))
|
||||
(buttercup-suites nil))
|
||||
(buttercup-run-discover)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp/edebug-instrument-defun-on ()
|
||||
"Toggle on instrumentalisation for the function under `defun'."
|
||||
(interactive)
|
||||
(eval-defun 'edebugit))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp/edebug-instrument-defun-off ()
|
||||
"Toggle off instrumentalisation for the function under `defun'."
|
||||
(interactive)
|
||||
(eval-defun nil))
|
||||
|
||||
|
||||
;;
|
||||
;;; Hooks
|
||||
|
||||
(autoload 'straight-register-file-modification "straight")
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-init-straight-maybe-h ()
|
||||
"Make sure straight sees modifications to installed packages."
|
||||
(when (file-in-directory-p (or buffer-file-name default-directory) doom-local-dir)
|
||||
(add-hook 'after-save-hook #'straight-register-file-modification
|
||||
nil 'local)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-extend-imenu-h ()
|
||||
"Improve imenu support in `emacs-lisp-mode', including recognition for Doom's API."
|
||||
(setq imenu-generic-expression
|
||||
`(("Section" "^[ \t]*;;;;*[ \t]+\\([^\n]+\\)" 1)
|
||||
("Evil commands" "^\\s-*(evil-define-\\(?:command\\|operator\\|motion\\) +\\(\\_<[^ ()\n]+\\_>\\)" 1)
|
||||
("Unit tests" "^\\s-*(\\(?:ert-deftest\\|describe\\) +\"\\([^\")]+\\)\"" 1)
|
||||
("Package" "^\\s-*(\\(?:;;;###package\\|package!\\|use-package!?\\|after!\\) +\\(\\_<[^ ()\n]+\\_>\\)" 1)
|
||||
("Major modes" "^\\s-*(define-derived-mode +\\([^ ()\n]+\\)" 1)
|
||||
("Minor modes" "^\\s-*(define-\\(?:global\\(?:ized\\)?-minor\\|generic\\|minor\\)-mode +\\([^ ()\n]+\\)" 1)
|
||||
("Modelines" "^\\s-*(def-modeline! +\\([^ ()\n]+\\)" 1)
|
||||
("Modeline segments" "^\\s-*(def-modeline-segment! +\\([^ ()\n]+\\)" 1)
|
||||
("Advice" "^\\s-*(\\(?:def\\(?:\\(?:ine-\\)?advice!?\\)\\) +\\([^ )\n]+\\)" 1)
|
||||
("Macros" "^\\s-*(\\(?:cl-\\)?def\\(?:ine-compile-macro\\|macro\\) +\\([^ )\n]+\\)" 1)
|
||||
("Inline functions" "\\s-*(\\(?:cl-\\)?defsubst +\\([^ )\n]+\\)" 1)
|
||||
("Functions" "^\\s-*(\\(?:cl-\\)?def\\(?:un\\|un\\*\\|method\\|generic\\|-memoized!\\) +\\([^ ,)\n]+\\)" 1)
|
||||
("Variables" "^\\s-*(\\(def\\(?:c\\(?:onst\\(?:ant\\)?\\|ustom\\)\\|ine-symbol-macro\\|parameter\\|var\\(?:-local\\)?\\)\\)\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)" 2)
|
||||
("Types" "^\\s-*(\\(cl-def\\(?:struct\\|type\\)\\|def\\(?:class\\|face\\|group\\|ine-\\(?:condition\\|error\\|widget\\)\\|package\\|struct\\|t\\(?:\\(?:hem\\|yp\\)e\\)\\)\\)\\s-+'?\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)" 2))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-reduce-flycheck-errors-in-emacs-config-h ()
|
||||
"Remove `emacs-lisp-checkdoc' checker and reduce `emacs-lisp' checker
|
||||
verbosity when editing a file in `doom-private-dir' or `doom-emacs-dir'."
|
||||
(when (and (bound-and-true-p flycheck-mode)
|
||||
(eq major-mode 'emacs-lisp-mode)
|
||||
(or (not default-directory)
|
||||
(null (buffer-file-name (buffer-base-buffer)))
|
||||
(cl-find-if (doom-partial #'file-in-directory-p default-directory)
|
||||
+emacs-lisp-disable-flycheck-in-dirs)))
|
||||
(add-to-list 'flycheck-disabled-checkers 'emacs-lisp-checkdoc)
|
||||
(set (make-local-variable 'flycheck-emacs-lisp-check-form)
|
||||
(concat "(progn "
|
||||
(prin1-to-string
|
||||
`(progn
|
||||
(setq doom-modules ',doom-modules
|
||||
doom-disabled-packages ',doom-disabled-packages)
|
||||
(ignore-errors (load ,user-init-file t t))
|
||||
(setq byte-compile-warnings
|
||||
'(obsolete cl-functions
|
||||
interactive-only make-local mapcar
|
||||
suspicious constants))
|
||||
(defmacro map! (&rest _))))
|
||||
" "
|
||||
(default-value 'flycheck-emacs-lisp-check-form)
|
||||
")"))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Fontification
|
||||
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-truncate-pin ()
|
||||
"Truncates long SHA1 hashes in `package!' :pin's."
|
||||
(save-excursion
|
||||
(goto-char (match-beginning 0))
|
||||
(and (stringp (plist-get (sexp-at-point) :pin))
|
||||
(search-forward ":pin" nil t)
|
||||
(let ((start (re-search-forward "\"[^\"\n]\\{12\\}" nil t))
|
||||
(finish (and (re-search-forward "\"" (line-end-position) t)
|
||||
(match-beginning 0))))
|
||||
(when (and start finish)
|
||||
(put-text-property start finish 'display "...")))))
|
||||
nil)
|
||||
|
||||
(defvar +emacs-lisp--face nil)
|
||||
;;;###autoload
|
||||
(defun +emacs-lisp-highlight-vars-and-faces (end)
|
||||
"Match defined variables and functions.
|
||||
|
||||
Functions are differentiated into special forms, built-in functions and
|
||||
library/userland functions"
|
||||
(catch 'matcher
|
||||
(while (re-search-forward "\\(?:\\sw\\|\\s_\\)+" end t)
|
||||
(let ((ppss (save-excursion (syntax-ppss))))
|
||||
(cond ((nth 3 ppss) ; strings
|
||||
(search-forward "\"" end t))
|
||||
((nth 4 ppss) ; comments
|
||||
(forward-line +1))
|
||||
((let ((symbol (intern-soft (match-string-no-properties 0))))
|
||||
(and (cond ((null symbol) nil)
|
||||
((eq symbol t) nil)
|
||||
((keywordp symbol) nil)
|
||||
((special-variable-p symbol)
|
||||
(setq +emacs-lisp--face 'font-lock-variable-name-face))
|
||||
((and (fboundp symbol)
|
||||
(eq (char-before (match-beginning 0)) ?\()
|
||||
(not (memq (char-before (1- (match-beginning 0)))
|
||||
(list ?\' ?\`))))
|
||||
(let ((unaliased (indirect-function symbol)))
|
||||
(unless (or (macrop unaliased)
|
||||
(special-form-p unaliased))
|
||||
(let (unadvised)
|
||||
(while (not (eq (setq unadvised (ad-get-orig-definition unaliased))
|
||||
(setq unaliased (indirect-function unadvised)))))
|
||||
unaliased)
|
||||
(setq +emacs-lisp--face
|
||||
(if (subrp unaliased)
|
||||
'font-lock-constant-face
|
||||
'font-lock-function-name-face))))))
|
||||
(throw 'matcher t)))))))
|
||||
nil))
|
||||
|
||||
;; HACK Fontification is already expensive enough. We byte-compile
|
||||
;; `+emacs-lisp-highlight-vars-and-faces' and `+emacs-lisp-truncate-pin' to
|
||||
;; ensure they run as fast as possible:
|
||||
(dolist (fn '(+emacs-lisp-highlight-vars-and-faces +emacs-lisp-truncate-pin))
|
||||
(unless (byte-code-function-p (symbol-function fn))
|
||||
(with-no-warnings (byte-compile fn))))
|
||||
239
.config/emacs/modules/lang/emacs-lisp/config.el
Normal file
239
.config/emacs/modules/lang/emacs-lisp/config.el
Normal file
@@ -0,0 +1,239 @@
|
||||
;;; lang/emacs-lisp/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +emacs-lisp-enable-extra-fontification t
|
||||
"If non-nil, highlight special forms, and defined functions and variables.")
|
||||
|
||||
(defvar +emacs-lisp-outline-regexp "[ \t]*;;;;* [^ \t\n]"
|
||||
"Regexp to use for `outline-regexp' in `emacs-lisp-mode'.
|
||||
This marks a foldable marker for `outline-minor-mode' in elisp buffers.")
|
||||
|
||||
(defvar +emacs-lisp-disable-flycheck-in-dirs
|
||||
(list doom-emacs-dir doom-private-dir)
|
||||
"List of directories to disable `emacs-lisp-checkdoc' in.
|
||||
|
||||
This checker tends to produce a lot of false positives in your .emacs.d and
|
||||
private config, so it is mostly useless there. However, special hacks are
|
||||
employed so that flycheck still does *some* helpful linting.")
|
||||
|
||||
|
||||
;; `elisp-mode' is loaded at startup. In order to lazy load its config we need
|
||||
;; to pretend it isn't loaded
|
||||
(defer-feature! elisp-mode emacs-lisp-mode)
|
||||
|
||||
|
||||
;;
|
||||
;;; Config
|
||||
|
||||
(use-package! elisp-mode
|
||||
:mode ("\\.Cask\\'" . emacs-lisp-mode)
|
||||
:config
|
||||
(set-repl-handler! '(emacs-lisp-mode lisp-interaction-mode) #'+emacs-lisp/open-repl)
|
||||
(set-eval-handler! '(emacs-lisp-mode lisp-interaction-mode) #'+emacs-lisp-eval)
|
||||
(set-lookup-handlers! '(emacs-lisp-mode lisp-interaction-mode helpful-mode)
|
||||
:definition #'+emacs-lisp-lookup-definition
|
||||
:documentation #'+emacs-lisp-lookup-documentation)
|
||||
(set-docsets! '(emacs-lisp-mode lisp-interaction-mode) "Emacs Lisp")
|
||||
(set-ligatures! 'emacs-lisp-mode :lambda "lambda")
|
||||
(set-rotate-patterns! 'emacs-lisp-mode
|
||||
:symbols '(("t" "nil")
|
||||
("let" "let*")
|
||||
("when" "unless")
|
||||
("advice-add" "advice-remove")
|
||||
("defadvice!" "undefadvice!")
|
||||
("add-hook" "remove-hook")
|
||||
("add-hook!" "remove-hook!")
|
||||
("it" "xit")
|
||||
("describe" "xdescribe")))
|
||||
|
||||
(setq-hook! 'emacs-lisp-mode-hook
|
||||
;; Emacs' built-in elisp files use a hybrid tab->space indentation scheme
|
||||
;; with a tab width of 8. Any smaller and the indentation will be
|
||||
;; unreadable. Since Emacs' lisp indenter doesn't respect this variable it's
|
||||
;; safe to ignore this setting otherwise.
|
||||
tab-width 8
|
||||
;; shorter name in modeline
|
||||
mode-name "Elisp"
|
||||
;; Don't treat autoloads or sexp openers as outline headers, we have
|
||||
;; hideshow for that.
|
||||
outline-regexp +emacs-lisp-outline-regexp
|
||||
;; Fixed indenter that intends plists sensibly.
|
||||
lisp-indent-function #'+emacs-lisp-indent-function)
|
||||
|
||||
;; variable-width indentation is superior in elisp. Otherwise, `dtrt-indent'
|
||||
;; and `editorconfig' would force fixed indentation on elisp.
|
||||
(add-to-list 'doom-detect-indentation-excluded-modes 'emacs-lisp-mode)
|
||||
|
||||
(add-hook! 'emacs-lisp-mode-hook
|
||||
;; Allow folding of outlines in comments
|
||||
#'outline-minor-mode
|
||||
;; Make parenthesis depth easier to distinguish at a glance
|
||||
#'rainbow-delimiters-mode
|
||||
;; Make quoted symbols easier to distinguish from free variables
|
||||
#'highlight-quoted-mode
|
||||
;; Extend imenu support to Doom constructs
|
||||
#'+emacs-lisp-extend-imenu-h
|
||||
;; Ensure straight sees modifications to installed packages
|
||||
#'+emacs-lisp-init-straight-maybe-h)
|
||||
|
||||
;; Flycheck's two emacs-lisp checkers produce a *lot* of false positives in
|
||||
;; emacs configs, so we disable `emacs-lisp-checkdoc' and reduce the
|
||||
;; `emacs-lisp' checker's verbosity.
|
||||
(add-hook 'flycheck-mode-hook #'+emacs-lisp-reduce-flycheck-errors-in-emacs-config-h)
|
||||
|
||||
;; Enhance elisp syntax highlighting, by highlighting Doom-specific
|
||||
;; constructs, defined symbols, and truncating :pin's in `package!' calls.
|
||||
(font-lock-add-keywords
|
||||
'emacs-lisp-mode
|
||||
(append `(;; custom Doom cookies
|
||||
("^;;;###\\(autodef\\|if\\|package\\)[ \n]" (1 font-lock-warning-face t)))
|
||||
;; Shorten the :pin of `package!' statements to 10 characters
|
||||
`(("(package!\\_>" (0 (+emacs-lisp-truncate-pin))))
|
||||
;; highlight defined, special variables & functions
|
||||
(when +emacs-lisp-enable-extra-fontification
|
||||
`((+emacs-lisp-highlight-vars-and-faces . +emacs-lisp--face)))))
|
||||
|
||||
;; Recenter window after following definition
|
||||
(advice-add #'elisp-def :after #'doom-recenter-a)
|
||||
|
||||
(defadvice! +emacs-lisp-append-value-to-eldoc-a (fn sym)
|
||||
"Display variable value next to documentation in eldoc."
|
||||
:around #'elisp-get-var-docstring
|
||||
(when-let (ret (funcall fn sym))
|
||||
(if (boundp sym)
|
||||
(concat ret " "
|
||||
(let* ((truncated " [...]")
|
||||
(print-escape-newlines t)
|
||||
(str (symbol-value sym))
|
||||
(str (prin1-to-string str))
|
||||
(limit (- (frame-width) (length ret) (length truncated) 1)))
|
||||
(format (format "%%0.%ds%%s" (max limit 0))
|
||||
(propertize str 'face 'warning)
|
||||
(if (< (length str) limit) "" truncated))))
|
||||
ret)))
|
||||
|
||||
(map! :localleader
|
||||
:map emacs-lisp-mode-map
|
||||
:desc "Expand macro" "m" #'macrostep-expand
|
||||
(:prefix ("d" . "debug")
|
||||
"f" #'+emacs-lisp/edebug-instrument-defun-on
|
||||
"F" #'+emacs-lisp/edebug-instrument-defun-off)
|
||||
(:prefix ("e" . "eval")
|
||||
"b" #'eval-buffer
|
||||
"d" #'eval-defun
|
||||
"e" #'eval-last-sexp
|
||||
"r" #'eval-region
|
||||
"l" #'load-library)
|
||||
(:prefix ("g" . "goto")
|
||||
"f" #'find-function
|
||||
"v" #'find-variable
|
||||
"l" #'find-library)))
|
||||
|
||||
(use-package! ielm
|
||||
:defer t
|
||||
:config
|
||||
(set-lookup-handlers! 'inferior-emacs-lisp-mode
|
||||
:definition #'+emacs-lisp-lookup-definition
|
||||
:documentation #'+emacs-lisp-lookup-documentation)
|
||||
|
||||
;; Adapted from http://www.modernemacs.com/post/comint-highlighting/ to add
|
||||
;; syntax highlighting to ielm REPLs.
|
||||
(setq ielm-font-lock-keywords
|
||||
(append '(("\\(^\\*\\*\\*[^*]+\\*\\*\\*\\)\\(.*$\\)"
|
||||
(1 font-lock-comment-face)
|
||||
(2 font-lock-constant-face)))
|
||||
(when (require 'highlight-numbers nil t)
|
||||
(highlight-numbers--get-regexp-for-mode 'emacs-lisp-mode))
|
||||
(cl-loop for (matcher . match-highlights)
|
||||
in (append lisp-el-font-lock-keywords-2
|
||||
lisp-cl-font-lock-keywords-2)
|
||||
collect
|
||||
`((lambda (limit)
|
||||
(when ,(if (symbolp matcher)
|
||||
`(,matcher limit)
|
||||
`(re-search-forward ,matcher limit t))
|
||||
;; Only highlight matches after the prompt
|
||||
(> (match-beginning 0) (car comint-last-prompt))
|
||||
;; Make sure we're not in a comment or string
|
||||
(let ((state (syntax-ppss)))
|
||||
(not (or (nth 3 state)
|
||||
(nth 4 state))))))
|
||||
,@match-highlights)))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
;;;###package overseer
|
||||
(autoload 'overseer-test "overseer" nil t)
|
||||
;; Properly lazy load overseer by not loading it so early:
|
||||
(remove-hook 'emacs-lisp-mode-hook #'overseer-enable-mode)
|
||||
|
||||
|
||||
(use-package! flycheck-cask
|
||||
:when (featurep! :checkers syntax)
|
||||
:defer t
|
||||
:init
|
||||
(add-hook! 'emacs-lisp-mode-hook
|
||||
(add-hook 'flycheck-mode-hook #'flycheck-cask-setup nil t)))
|
||||
|
||||
|
||||
(use-package! flycheck-package
|
||||
:when (featurep! :checkers syntax)
|
||||
:after flycheck
|
||||
:config (flycheck-package-setup))
|
||||
|
||||
|
||||
(use-package! elisp-demos
|
||||
:defer t
|
||||
:init
|
||||
(advice-add 'describe-function-1 :after #'elisp-demos-advice-describe-function-1)
|
||||
(advice-add 'helpful-update :after #'elisp-demos-advice-helpful-update)
|
||||
:config
|
||||
(defadvice! +emacs-lisp--add-doom-elisp-demos-a (fn symbol)
|
||||
"Add Doom's own demos to help buffers."
|
||||
:around #'elisp-demos--search
|
||||
(or (funcall fn symbol)
|
||||
(when-let (demos-file (doom-module-locate-path :lang 'emacs-lisp "demos.org"))
|
||||
(with-temp-buffer
|
||||
(insert-file-contents demos-file)
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward
|
||||
(format "^\\*\\* %s$" (regexp-quote (symbol-name symbol)))
|
||||
nil t)
|
||||
(let (beg end)
|
||||
(forward-line 1)
|
||||
(setq beg (point))
|
||||
(if (re-search-forward "^\\*" nil t)
|
||||
(setq end (line-beginning-position))
|
||||
(setq end (point-max)))
|
||||
(string-trim (buffer-substring-no-properties beg end)))))))))
|
||||
|
||||
|
||||
(use-package! buttercup
|
||||
:defer t
|
||||
:minor ("/test[/-].+\\.el$" . buttercup-minor-mode)
|
||||
:preface
|
||||
;; buttercup.el doesn't define a keymap for `buttercup-minor-mode', as we have
|
||||
;; to fool its internal `define-minor-mode' call into thinking one exists, so
|
||||
;; it will associate it with the mode.
|
||||
(defvar buttercup-minor-mode-map (make-sparse-keymap))
|
||||
:config
|
||||
(set-popup-rule! "^\\*Buttercup\\*$" :size 0.45 :select nil :ttl 0)
|
||||
(set-yas-minor-mode! 'buttercup-minor-mode)
|
||||
(when (featurep 'evil)
|
||||
(add-hook 'buttercup-minor-mode-hook #'evil-normalize-keymaps))
|
||||
(map! :localleader
|
||||
:map buttercup-minor-mode-map
|
||||
:prefix "t"
|
||||
"t" #'+emacs-lisp/buttercup-run-file
|
||||
"a" #'+emacs-lisp/buttercup-run-project
|
||||
"s" #'buttercup-run-at-point))
|
||||
|
||||
|
||||
;;
|
||||
;;; Project modes
|
||||
|
||||
(def-project-mode! +emacs-lisp-ert-mode
|
||||
:modes '(emacs-lisp-mode)
|
||||
:match "/test[/-].+\\.el$"
|
||||
:add-hooks '(overseer-enable-mode))
|
||||
533
.config/emacs/modules/lang/emacs-lisp/demos.org
Normal file
533
.config/emacs/modules/lang/emacs-lisp/demos.org
Normal file
@@ -0,0 +1,533 @@
|
||||
#+TITLE: API Demos
|
||||
#+PROPERTY: header-args:elisp :results pp
|
||||
|
||||
This file contains demos of Doom's public API; its core library, macros, and
|
||||
autodefs. It is used by the =elisp-demos= package to display examples of their
|
||||
usage from their documentation (e.g. =SPC h f add-hook\!=).
|
||||
|
||||
* Table of Contents :TOC_3:
|
||||
- [[#core-lib][core-lib]]
|
||||
- [[#add-hook][add-hook!]]
|
||||
- [[#add-transient-hook][add-transient-hook!]]
|
||||
- [[#after][after!]]
|
||||
- [[#appendq][appendq!]]
|
||||
- [[#custom-set-faces][custom-set-faces!]]
|
||||
- [[#custom-theme-set-faces][custom-theme-set-faces!]]
|
||||
- [[#defer-feature][defer-feature!]]
|
||||
- [[#defer-until][defer-until!]]
|
||||
- [[#disable-packages][disable-packages!]]
|
||||
- [[#doom][doom!]]
|
||||
- [[#file-exists-p][file-exists-p!]]
|
||||
- [[#cmd][cmd!]]
|
||||
- [[#cmd-1][cmd!!]]
|
||||
- [[#cmds][cmds!]]
|
||||
- [[#kbd][kbd!]]
|
||||
- [[#letenv][letenv!]]
|
||||
- [[#load][load!]]
|
||||
- [[#map][map!]]
|
||||
- [[#package][package!]]
|
||||
- [[#pushnew][pushnew!]]
|
||||
- [[#prependq][prependq!]]
|
||||
- [[#quiet][quiet!]]
|
||||
- [[#remove-hook][remove-hook!]]
|
||||
- [[#setq][setq!]]
|
||||
- [[#setq-hook][setq-hook!]]
|
||||
- [[#unsetq-hook][unsetq-hook!]]
|
||||
- [[#use-package][use-package!]]
|
||||
|
||||
* core-lib
|
||||
** add-hook!
|
||||
#+begin_src emacs-lisp :eval no
|
||||
;; With only one hook and one function, this is identical to `add-hook'. In that
|
||||
;; case, use that instead.
|
||||
(add-hook! 'some-mode-hook #'enable-something)
|
||||
|
||||
;; Adding many-to-many functions to hooks
|
||||
(add-hook! some-mode #'enable-something #'and-another)
|
||||
(add-hook! some-mode #'(enable-something and-another))
|
||||
(add-hook! '(one-mode-hook second-mode-hook) #'enable-something)
|
||||
(add-hook! (one-mode second-mode) #'enable-something)
|
||||
|
||||
;; Appending and local hooks
|
||||
(add-hook! (one-mode second-mode) :append #'enable-something)
|
||||
(add-hook! (one-mode second-mode) :local #'enable-something)
|
||||
|
||||
;; With arbitrary forms
|
||||
(add-hook! (one-mode second-mode) (setq v 5) (setq a 2))
|
||||
(add-hook! (one-mode second-mode) :append :local (setq v 5) (setq a 2))
|
||||
|
||||
;; Inline named hook functions
|
||||
(add-hook! '(one-mode-hook second-mode-hook)
|
||||
(defun do-something ()
|
||||
...)
|
||||
(defun do-another-thing ()
|
||||
...))
|
||||
#+end_src
|
||||
|
||||
** TODO add-transient-hook!
|
||||
** after!
|
||||
#+begin_src emacs-lisp :eval no
|
||||
;;; `after!' will take:
|
||||
|
||||
;; An unquoted package symbol (the name of a package)
|
||||
(after! helm ...)
|
||||
|
||||
;; An unquoted list of package symbols (i.e. BODY is evaluated once both magit
|
||||
;; and git-gutter have loaded)
|
||||
(after! (magit git-gutter) ...)
|
||||
|
||||
;; An unquoted, nested list of compound package lists, using any combination of
|
||||
;; :or/:any and :and/:all
|
||||
(after! (:or package-a package-b ...) ...)
|
||||
(after! (:and package-a package-b ...) ...)
|
||||
(after! (:and package-a (:or package-b package-c) ...) ...)
|
||||
;; (Without :or/:any/:and/:all, :and/:all are implied.)
|
||||
|
||||
;; A common mistake is to pass it the names of major or minor modes, e.g.
|
||||
(after! rustic-mode ...)
|
||||
(after! python-mode ...)
|
||||
;; But the code in them will never run! rustic-mode is in the `rustic' package
|
||||
;; and python-mode is in the `python' package. This is what you want:
|
||||
(after! rustic ...)
|
||||
(after! python ...)
|
||||
#+end_src
|
||||
** appendq!
|
||||
#+begin_src emacs-lisp
|
||||
(let ((x '(a b c)))
|
||||
(appendq! x '(c d e))
|
||||
x)
|
||||
#+end_src
|
||||
|
||||
#+RESULTS:
|
||||
: (a b c c d e)
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(let ((x '(a b c))
|
||||
(y '(c d e))
|
||||
(z '(f g)))
|
||||
(appendq! x y z '(h))
|
||||
x)
|
||||
#+end_src
|
||||
|
||||
#+RESULTS:
|
||||
: (a b c c d e f g h)
|
||||
|
||||
** custom-set-faces!
|
||||
#+begin_src emacs-lisp :eval no
|
||||
(custom-set-faces!
|
||||
'(outline-1 :weight normal)
|
||||
'(outline-2 :weight normal)
|
||||
'(outline-3 :weight normal)
|
||||
'(outline-4 :weight normal)
|
||||
'(outline-5 :weight normal)
|
||||
'(outline-6 :weight normal)
|
||||
'(default :background "red" :weight bold)
|
||||
'(region :background "red" :weight bold))
|
||||
|
||||
(custom-set-faces!
|
||||
'((outline-1 outline-2 outline-3 outline-4 outline-5 outline-6)
|
||||
:weight normal)
|
||||
'((default region)
|
||||
:background "red" :weight bold))
|
||||
|
||||
(let ((red-bg-faces '(default region)))
|
||||
(custom-set-faces!
|
||||
`(,(cl-loop for i from 0 to 6 collect (intern (format "outline-%d" i)))
|
||||
:weight normal)
|
||||
`(,red-bg-faces
|
||||
:background "red" :weight bold)))
|
||||
|
||||
;; You may utilise `doom-themes's theme API to fetch or tweak colors from their
|
||||
;; palettes. No need to wait until the theme or package is loaded. e.g.
|
||||
(custom-set-faces!
|
||||
`(outline-1 :foreground ,(doom-color 'red))
|
||||
`(outline-2 :background ,(doom-color 'blue)))
|
||||
#+end_src
|
||||
|
||||
** custom-theme-set-faces!
|
||||
#+begin_src emacs-lisp :eval no
|
||||
(custom-theme-set-faces! 'doom-one
|
||||
'(outline-1 :weight normal)
|
||||
'(outline-2 :weight normal)
|
||||
'(outline-3 :weight normal)
|
||||
'(outline-4 :weight normal)
|
||||
'(outline-5 :weight normal)
|
||||
'(outline-6 :weight normal)
|
||||
'(default :background "red" :weight bold)
|
||||
'(region :background "red" :weight bold))
|
||||
|
||||
(custom-theme-set-faces! '(doom-one-theme doom-one-light-theme)
|
||||
'((outline-1 outline-2 outline-3 outline-4 outline-5 outline-6)
|
||||
:weight normal)
|
||||
'((default region)
|
||||
:background "red" :weight bold))
|
||||
|
||||
(let ((red-bg-faces '(default region)))
|
||||
(custom-theme-set-faces! '(doom-one-theme doom-one-light-theme)
|
||||
`(,(cl-loop for i from 0 to 6 collect (intern (format "outline-%d" i)))
|
||||
:weight normal)
|
||||
`(,red-bg-faces
|
||||
:background "red" :weight bold)))
|
||||
|
||||
;; You may utilise `doom-themes's theme API to fetch or tweak colors from their
|
||||
;; palettes. No need to wait until the theme or package is loaded. e.g.
|
||||
(custom-theme-set-faces! 'doom-one
|
||||
`(outline-1 :foreground ,(doom-color 'red))
|
||||
`(outline-2 :background ,(doom-color 'blue)))
|
||||
#+end_src
|
||||
|
||||
** TODO defer-feature!
|
||||
** TODO defer-until!
|
||||
** disable-packages!
|
||||
#+begin_src emacs-lisp :eval no
|
||||
;; Disable packages enabled by DOOM
|
||||
(disable-packages! some-package second-package)
|
||||
#+end_src
|
||||
|
||||
** doom!
|
||||
#+begin_src emacs-lisp :eval no
|
||||
(doom! :completion
|
||||
company
|
||||
ivy
|
||||
;;helm
|
||||
|
||||
:tools
|
||||
(:if IS-MAC macos)
|
||||
docker
|
||||
lsp
|
||||
|
||||
:lang
|
||||
(cc +lsp)
|
||||
(:cond ((string= system-name "work-pc")
|
||||
python
|
||||
rust
|
||||
web)
|
||||
((string= system-name "writing-pc")
|
||||
(org +dragndrop)
|
||||
ruby))
|
||||
(:if IS-LINUX
|
||||
(web +lsp)
|
||||
web)
|
||||
|
||||
:config
|
||||
literate
|
||||
(default +bindings +smartparens))
|
||||
#+end_src
|
||||
|
||||
** file-exists-p!
|
||||
#+begin_src emacs-lisp
|
||||
(file-exists-p! "init.el" doom-emacs-dir)
|
||||
#+end_src
|
||||
|
||||
#+RESULTS:
|
||||
: /home/hlissner/.emacs.d/init.el
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(file-exists-p! (and (or "doesnotexist" "init.el")
|
||||
"LICENSE")
|
||||
doom-emacs-dir)
|
||||
#+end_src
|
||||
|
||||
#+RESULTS:
|
||||
: /home/hlissner/.emacs.d/LICENSE
|
||||
|
||||
** cmd!
|
||||
#+begin_src emacs-lisp :eval no
|
||||
(map! "C-j" (cmd! (newline) (indent-according-to-mode)))
|
||||
#+end_src
|
||||
|
||||
** cmd!!
|
||||
When ~newline~ is passed a numerical prefix argument (=C-u 5 M-x newline=), it
|
||||
inserts N newlines. We can use ~cmd!!~ to easily create a keybinds that bakes in
|
||||
the prefix arg into the command call:
|
||||
|
||||
#+begin_src emacs-lisp :eval no
|
||||
(map! "C-j" (cmd!! #'newline 5))
|
||||
#+end_src
|
||||
|
||||
Or to create aliases for functions that behave differently:
|
||||
|
||||
#+begin_src emacs-lisp :eval no
|
||||
(fset 'insert-5-newlines (cmd!! #'newline 5))
|
||||
|
||||
;; The equivalent of C-u M-x org-global-cycle, which resets the org document to
|
||||
;; its startup visibility settings.
|
||||
(fset 'org-reset-global-visibility (cmd!! #'org-global-cycle '(4))
|
||||
#+end_src
|
||||
|
||||
** cmds!
|
||||
#+begin_src emacs-lisp :eval no
|
||||
(map! :i [tab] (cmds! (and (featurep! :editor snippets)
|
||||
(bound-and-true-p yas-minor-mode)
|
||||
(yas-maybe-expand-abbrev-key-filter 'yas-expand))
|
||||
#'yas-expand
|
||||
(featurep! :completion company +tng)
|
||||
#'company-indent-or-complete-common)
|
||||
:m [tab] (cmds! (and (bound-and-true-p yas-minor-mode)
|
||||
(evil-visual-state-p)
|
||||
(or (eq evil-visual-selection 'line)
|
||||
(not (memq (char-after) (list ?\( ?\[ ?\{ ?\} ?\] ?\))))))
|
||||
#'yas-insert-snippet
|
||||
(and (featurep! :editor fold)
|
||||
(save-excursion (end-of-line) (invisible-p (point))))
|
||||
#'+fold/toggle
|
||||
(fboundp 'evil-jump-item)
|
||||
#'evil-jump-item))
|
||||
#+end_src
|
||||
|
||||
** kbd!
|
||||
#+begin_src emacs-lisp :eval no
|
||||
(map! "," (kbd! "SPC")
|
||||
";" (kbd! ":"))
|
||||
#+end_src
|
||||
|
||||
** letenv!
|
||||
#+begin_src emacs-lisp
|
||||
(letenv! (("SHELL" "/bin/sh"))
|
||||
(shell-command-to-string "echo $SHELL"))
|
||||
#+end_src
|
||||
|
||||
#+RESULTS:
|
||||
: "/bin/sh\n"
|
||||
|
||||
** load!
|
||||
#+begin_src emacs-lisp :eval no
|
||||
;;; Lets say we're in ~/.doom.d/config.el
|
||||
(load! "lisp/module") ; loads ~/.doom.d/lisp/module.el
|
||||
(load! "somefile" doom-emacs-dir) ; loads ~/.emacs.d/somefile.el
|
||||
(load! "anotherfile" doom-private-dir) ; loads ~/.doom.d/anotherfile.el
|
||||
|
||||
;; If you don't want a `load!' call to throw an error if the file doesn't exist:
|
||||
(load! "~/.maynotexist" nil t)
|
||||
#+end_src
|
||||
|
||||
** map!
|
||||
#+begin_src emacs-lisp :eval no
|
||||
(map! :map magit-mode-map
|
||||
:m "C-r" 'do-something ; C-r in motion state
|
||||
:nv "q" 'magit-mode-quit-window ; q in normal+visual states
|
||||
"C-x C-r" 'a-global-keybind
|
||||
:g "C-x C-r" 'another-global-keybind ; same as above
|
||||
|
||||
(:when IS-MAC
|
||||
:n "M-s" 'some-fn
|
||||
:i "M-o" (cmd! (message "Hi"))))
|
||||
|
||||
(map! (:when (featurep! :completion company) ; Conditional loading
|
||||
:i "C-@" #'+company/complete
|
||||
(:prefix "C-x" ; Use a prefix key
|
||||
:i "C-l" #'+company/whole-lines)))
|
||||
|
||||
(map! (:when (featurep! :lang latex) ; local conditional
|
||||
(:map LaTeX-mode-map
|
||||
:localleader ; Use local leader
|
||||
:desc "View" "v" #'TeX-view)) ; Add which-key description
|
||||
:leader ; Use leader key from now on
|
||||
:desc "Eval expression" ";" #'eval-expression)
|
||||
#+end_src
|
||||
|
||||
These are side-by-side comparisons, showing how to bind keys with and without
|
||||
~map!~:
|
||||
|
||||
#+begin_src emacs-lisp :eval no
|
||||
;; bind a global key
|
||||
(global-set-key (kbd "C-x y") #'do-something)
|
||||
(map! "C-x y" #'do-something)
|
||||
|
||||
;; bind a key on a keymap
|
||||
(define-key emacs-lisp-mode-map (kbd "C-c p") #'do-something)
|
||||
(map! :map emacs-lisp-mode-map "C-c p" #'do-something)
|
||||
|
||||
;; unbind a key defined elsewhere
|
||||
(define-key lua-mode-map (kbd "SPC m b") nil)
|
||||
(map! :map lua-mode-map "SPC m b" nil)
|
||||
|
||||
;; bind multiple keys
|
||||
(global-set-key (kbd "C-x x") #'do-something)
|
||||
(global-set-key (kbd "C-x y") #'do-something-else)
|
||||
(global-set-key (kbd "C-x z") #'do-another-thing)
|
||||
(map! "C-x x" #'do-something
|
||||
"C-x y" #'do-something-else
|
||||
"C-x z" #'do-another-thing)
|
||||
|
||||
;; bind global keys in normal mode
|
||||
(evil-define-key* 'normal 'global
|
||||
(kbd "C-x x") #'do-something
|
||||
(kbd "C-x y") #'do-something-else
|
||||
(kbd "C-x z") #'do-another-thing)
|
||||
(map! :n "C-x x" #'do-something
|
||||
:n "C-x y" #'do-something-else
|
||||
:n "C-x z" #'do-another-thing)
|
||||
|
||||
;; or on a deferred keymap
|
||||
(evil-define-key 'normal emacs-lisp-mode-map
|
||||
(kbd "C-x x") #'do-something
|
||||
(kbd "C-x y") #'do-something-else
|
||||
(kbd "C-x z") #'do-another-thing)
|
||||
(map! :map emacs-lisp-mode-map
|
||||
:n "C-x x" #'do-something
|
||||
:n "C-x y" #'do-something-else
|
||||
:n "C-x z" #'do-another-thing)
|
||||
|
||||
;; or multiple maps
|
||||
(dolist (map (list emacs-lisp-mode go-mode-map ivy-minibuffer-map))
|
||||
(evil-define-key '(normal insert) map
|
||||
"a" #'a
|
||||
"b" #'b
|
||||
"c" #'c))
|
||||
(map! :map (emacs-lisp-mode go-mode-map ivy-minibuffer-map)
|
||||
:ni "a" #'a
|
||||
:ni "b" #'b
|
||||
:ni "c" #'c)
|
||||
|
||||
;; or in multiple states (order of states doesn't matter)
|
||||
(evil-define-key* '(normal visual) emacs-lisp-mode-map (kbd "C-x x") #'do-something)
|
||||
(evil-define-key* 'insert emacs-lisp-mode-map (kbd "C-x x") #'do-something-else)
|
||||
(evil-define-key* '(visual normal insert emacs) emacs-lisp-mode-map (kbd "C-x z") #'do-another-thing)
|
||||
(map! :map emacs-lisp-mode
|
||||
:nv "C-x x" #'do-something ; normal+visual
|
||||
:i "C-x y" #'do-something-else ; insert
|
||||
:vnie "C-x z" #'do-another-thing) ; visual+normal+insert+emacs
|
||||
|
||||
;; You can nest map! calls:
|
||||
(evil-define-key* '(normal visual) emacs-lisp-mode-map (kbd "C-x x") #'do-something)
|
||||
(evil-define-key* 'normal go-lisp-mode-map (kbd "C-x x") #'do-something-else)
|
||||
(map! (:map emacs-lisp-mode :nv "C-x x" #'do-something)
|
||||
(:map go-lisp-mode :n "C-x x" #'do-something-else))
|
||||
#+end_src
|
||||
|
||||
** package!
|
||||
#+begin_src emacs-lisp :eval no
|
||||
;; To install a package that can be found on ELPA or any of the sources
|
||||
;; specified in `straight-recipe-repositories':
|
||||
(package! evil)
|
||||
(package! js2-mode)
|
||||
(package! rainbow-delimiters)
|
||||
|
||||
;; To disable a package included with Doom (which will no-op all its `after!'
|
||||
;; and `use-package!' blocks):
|
||||
(package! evil :disable t)
|
||||
(package! rainbow-delimiters :disable t)
|
||||
|
||||
;; To install a package from a github repo
|
||||
(package! so-long :recipe (:host github :repo "hlissner/emacs-so-long"))
|
||||
|
||||
;; If a package is particularly big and comes with submodules you don't need,
|
||||
;; you can tell the package manager not to clone the repo recursively:
|
||||
(package! ansible :recipe (:nonrecursive t))
|
||||
|
||||
;; To pin a package to a specific commit:
|
||||
(package! evil :pin "e7bc39de2f9")
|
||||
;; ...or branch:
|
||||
(package! evil :recipe (:branch "stable"))
|
||||
;; To unpin a pinned package:
|
||||
(package! evil :pin nil)
|
||||
|
||||
;; If you share your config between two computers, and don't want bin/doom
|
||||
;; refresh to delete packages used only on one system, use :ignore
|
||||
(package! evil :ignore (not (equal system-name "my-desktop")))
|
||||
#+end_src
|
||||
|
||||
** pushnew!
|
||||
#+begin_src emacs-lisp
|
||||
(let ((list '(a b c)))
|
||||
(pushnew! list 'c 'd 'e)
|
||||
list)
|
||||
#+end_src
|
||||
|
||||
#+RESULTS:
|
||||
: (e d a b c)
|
||||
|
||||
** prependq!
|
||||
#+begin_src emacs-lisp
|
||||
(let ((x '(a b c)))
|
||||
(prependq! x '(c d e))
|
||||
x)
|
||||
#+end_src
|
||||
|
||||
#+RESULTS:
|
||||
: (c d e a b c)
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(let ((x '(a b c))
|
||||
(y '(c d e))
|
||||
(z '(f g)))
|
||||
(prependq! x y z '(h))
|
||||
x)
|
||||
#+end_src
|
||||
|
||||
#+RESULTS:
|
||||
: (c d e f g h a b c)
|
||||
|
||||
** quiet!
|
||||
#+begin_src emacs-lisp :eval no
|
||||
;; Enters recentf-mode without extra output
|
||||
(quiet! (recentf-mode +1))
|
||||
#+end_src
|
||||
** remove-hook!
|
||||
#+begin_src emacs-lisp :eval no
|
||||
;; With only one hook and one function, this is identical to `remove-hook'. In
|
||||
;; that case, use that instead.
|
||||
(remove-hook! 'some-mode-hook #'enable-something)
|
||||
|
||||
;; Removing N functions from M hooks
|
||||
(remove-hook! some-mode #'enable-something #'and-another)
|
||||
(remove-hook! some-mode #'(enable-something and-another))
|
||||
(remove-hook! '(one-mode-hook second-mode-hook) #'enable-something)
|
||||
(remove-hook! (one-mode second-mode) #'enable-something)
|
||||
|
||||
;; Removing buffer-local hooks
|
||||
(remove-hook! (one-mode second-mode) :local #'enable-something)
|
||||
|
||||
;; Removing arbitrary forms (must be exactly the same as the definition)
|
||||
(remove-hook! (one-mode second-mode) (setq v 5) (setq a 2))
|
||||
#+end_src
|
||||
** setq!
|
||||
#+begin_src emacs-lisp
|
||||
;; Each of these have a setter associated with them, which must be triggered in
|
||||
;; order for their new values to have an effect.
|
||||
(setq! evil-want-Y-yank-to-eol nil
|
||||
evil-want-C-u-scroll nil
|
||||
evil-want-C-d-scroll nil)
|
||||
#+end_src
|
||||
** setq-hook!
|
||||
#+begin_src emacs-lisp :eval no
|
||||
;; Set multiple variables after a hook
|
||||
(setq-hook! 'markdown-mode-hook
|
||||
line-spacing 2
|
||||
fill-column 80)
|
||||
|
||||
;; Set variables after multiple hooks
|
||||
(setq-hook! '(eshell-mode-hook term-mode-hook)
|
||||
hscroll-margin 0)
|
||||
#+end_src
|
||||
|
||||
** unsetq-hook!
|
||||
#+begin_src emacs-lisp :eval no
|
||||
(unsetq-hook! 'markdown-mode-hook line-spacing)
|
||||
|
||||
;; Removes the following variable hook
|
||||
(setq-hook! 'markdown-mode-hook line-spacing 2)
|
||||
|
||||
;; Removing N variables from M hooks
|
||||
(unsetq-hook! some-mode enable-something and-another)
|
||||
(unsetq-hook! some-mode (enable-something and-another))
|
||||
(unsetq-hook! '(one-mode-hook second-mode-hook) enable-something)
|
||||
(unsetq-hook! (one-mode second-mode) enable-something)
|
||||
#+end_src
|
||||
|
||||
** use-package!
|
||||
#+begin_src emacs-lisp :eval no
|
||||
;; Use after-call to load package before hook
|
||||
(use-package! projectile
|
||||
:after-call (pre-command-hook after-find-file dired-before-readin-hook))
|
||||
|
||||
;; defer recentf packages one by one
|
||||
(use-package! recentf
|
||||
:defer-incrementally easymenu tree-widget timer
|
||||
:after-call after-find-file)
|
||||
|
||||
;; This is equivalent to :defer-incrementally (abc)
|
||||
(use-package! abc
|
||||
:defer-incrementally t)
|
||||
#+end_src
|
||||
19
.config/emacs/modules/lang/emacs-lisp/packages.el
Normal file
19
.config/emacs/modules/lang/emacs-lisp/packages.el
Normal file
@@ -0,0 +1,19 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/emacs-lisp/packages.el
|
||||
|
||||
(package! elisp-mode :built-in t)
|
||||
|
||||
;; Fontification plugins
|
||||
(package! highlight-quoted :pin "24103478158cd19fbcfb4339a3f1fa1f054f1469")
|
||||
|
||||
;; Tools
|
||||
(package! macrostep :pin "424e3734a1ee526a1bd7b5c3cd1d3ef19d184267")
|
||||
(package! overseer :pin "02d49f582e80e36b4334c9187801c5ecfb027789")
|
||||
(package! elisp-def :pin "dfca043ec0cbead67bd9c526cb009daf771d0fa2")
|
||||
(package! elisp-demos :pin "924b07d28e4f5b82f0e1377bcde800068f0a6d9d")
|
||||
(when (featurep! :checkers syntax)
|
||||
(package! flycheck-package :pin "ecd03f83790611888d693c684d719e033f69cb40")
|
||||
(package! flycheck-cask :pin "4b2ede6362ded4a45678dfbef1876faa42edbd58"))
|
||||
|
||||
;; Libraries
|
||||
(package! buttercup :pin "1de6be465cfe2c3f00183de9351bd838690c9f81")
|
||||
Reference in New Issue
Block a user