Moving to Doom Emacs!

This commit is contained in:
Derek Taylor
2019-12-16 20:21:19 -06:00
parent d9f2f456f1
commit d4b4c33550
683 changed files with 51877 additions and 100 deletions

106
.emacs.d/bin/doom Executable file
View File

@@ -0,0 +1,106 @@
#!/usr/bin/env sh
:; ( echo "$EMACS" | grep -q "term" ) && EMACS=emacs || EMACS=${EMACS:-emacs} # -*-emacs-lisp-*-
:; command -v $EMACS >/dev/null || { >&2 echo "Can't find emacs in your PATH"; exit 1; }
:; VERSION=$($EMACS --version | head -n1)
:; case "$VERSION" in *\ 2[0-5].[0-9]) echo "Detected Emacs $VERSION"; echo "Doom only supports Emacs 26.1 and newer"; echo; exit 2 ;; esac
:; DOOMBASE="$(dirname "$0")/.."
:; [ "$1" = -d ] || [ "$1" = --debug ] && { shift; export DEBUG=1; }
:; [ "$1" = run ] && { cd "$DOOMBASE"; shift; exec $EMACS -q --no-splash -l bin/doom "$@"; exit 0; }
:; exec $EMACS --script "$0" -- "$@"
:; exit 0
(let* ((loaddir (file-name-directory (file-truename load-file-name)))
(emacsdir (getenv "EMACSDIR"))
(user-emacs-directory (or emacsdir (expand-file-name "../" loaddir)))
(load-prefer-newer t))
(push (expand-file-name "core" user-emacs-directory) load-path)
(require 'core)
(require 'core-cli)
(defcli! :main
((help-p ["-h" "--help"] "Same as help command")
(debug-p ["-d" "--debug"] "Turns on doom-debug-mode (and debug-on-error)")
(yes-p ["-y" "--yes"] "Auto-accept all confirmation prompts")
(emacsdir ["--emacsdir" dir] "Use the emacs config at DIR (e.g. ~/.emacs.d)")
(doomdir ["--doomdir" dir] "Use the private module at DIR (e.g. ~/.doom.d)")
(localdir ["--localdir" dir] "Use DIR as your local storage directory")
&optional command &rest args)
"A command line interface for managing Doom Emacs.
Includes package management, diagnostics, unit tests, and byte-compilation.
This tool also makes it trivial to launch Emacs out of a different folder or
with a different private module."
:bare t
(when emacsdir
(setq user-emacs-directory (file-name-as-directory emacsdir))
(print! (info "EMACSDIR=%s") localdir))
(when doomdir
(setenv "DOOMDIR" doomdir)
(print! (info "DOOMDIR=%s") localdir))
(when localdir
(setenv "DOOMLOCALDIR" localdir)
(print! (info "DOOMLOCALDIR=%s") localdir))
(when debug-p
(setenv "DEBUG" "1")
(setq doom-debug-mode t)
(print! (info "Debug mode on")))
(when yes-p
(setenv "YES" "1")
(setq doom-auto-accept t)
(print! (info "Auto-yes on")))
(when help-p
(push command args)
(setq command "help"))
;; Reload core in case any of the directories were changed.
(when (or emacsdir doomdir localdir)
(load! "core/core.el" user-emacs-directory))
(cond ((not noninteractive)
(print! "Doom launched out of %s (test mode)" (path user-emacs-directory))
(load! "init.el" user-emacs-directory)
(doom-run-all-startup-hooks-h))
((null command)
(doom-cli-execute "help"))
((condition-case e
(let ((start-time (current-time)))
(and (doom-cli-execute command args)
(print! (success "Finished! (%.4fs)")
(float-time
(time-subtract (current-time)
start-time)))))
(user-error
(print! (error "%s\n") (error-message-string e))
(print! (yellow "See 'doom help %s' for documentation on this command.") (car args))
(error "")) ; Ensure non-zero exit code
((debug error)
(print! (error "There was an unexpected error:"))
(print-group!
(print! "%s %s" (bold "Type:") (car e))
(print! (bold "Message:"))
(print-group!
(print! "%s" (get (car e) 'error-message)))
(print! (bold "Data:"))
(print-group!
(if (cdr e)
(dolist (item (cdr e))
(print! "%S" item))
(print! "n/a"))))
(unless debug-on-error
(terpri)
(print!
(concat "Run the command again with the -d (or --debug) switch to enable debug\n"
"mode and (hopefully) generate a backtrace from this error:\n"
"\n %s\n\n"
"If you file a bug report, please include it!")
(string-join (append (list (file-name-nondirectory load-file-name) "-d" command)
args)
" "))
(error ""))))))) ; Ensure non-zero exit code
(doom-cli-execute :main (cdr (member "--" argv)))
(setq argv nil))

25
.emacs.d/bin/doom.cmd Normal file
View File

@@ -0,0 +1,25 @@
:: Forward the ./doom script to Emacs
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
PUSHD "%~dp0" >NUL
SET args=
SET command=%1
:LOOP
SHIFT /1
IF NOT [%1]==[] (
SET args=%args% %1
GOTO :LOOP
)
IF [%command%]==[run] (
start runemacs -Q %args% -l ..\init.el -f "doom-run-all-startup-hooks-h"
) ELSE (
emacs --quick --script .\doom -- %*
)
POPD >NUL
ECHO ON

42
.emacs.d/bin/org-capture Executable file
View File

@@ -0,0 +1,42 @@
#!/usr/bin/env sh
# Open an org-capture popup frame from the shell. This opens a temporary emacs
# daemon if emacs isn't already running.
#
# Usage: org-capture [-k KEY] [MESSAGE]
# Examples:
# org-capture -k n "To the mind that is still, the whole universe surrenders."
set -e
cleanup() {
emacsclient --eval '(let (kill-emacs-hook) (kill-emacs))'
}
# If emacs isn't running, we start a temporary daemon, solely for this window.
if ! emacsclient -e nil; then
emacs --daemon
trap cleanup EXIT INT TERM
daemon=1
fi
# org-capture key mapped to argument flags
# keys=$(emacsclient -e "(+org-capture-available-keys)" | cut -d '"' -f2)
while getopts hk opt; do
key="\"$opt\""
break
done
shift $((OPTIND-1))
[ -t 0 ] && str="$*" || str=$(cat)
if [ $daemon ]; then
emacsclient -a "" \
-c -F '((name . "org-capture") (width . 70) (height . 25) (transient . t))' \
-e "(+org-capture/open-frame \"$str\" ${key:-nil})"
else
# Non-daemon servers flicker a lot if frames are created from terminal, so we
# do it internally instead.
emacsclient -a "" \
-e "(+org-capture/open-frame \"$str\" ${key:-nil})"
fi

144
.emacs.d/bin/org-tangle Executable file
View File

@@ -0,0 +1,144 @@
#!/usr/bin/env sh
":"; exec emacs --quick --script "$0" -- "$@" # -*- mode: emacs-lisp; lexical-binding: t; -*-
;;; bin/org-tangle
;; Tangles source blocks from org files. Debug/info messages are directed to
;; stderr and can be ignored.
;;
;; -l/--lang LANG
;; Only include blocks in the specified language (e.g. emacs-lisp).
;; -a/--all
;; Tangle all blocks by default (unless it has :tangle nil set or a
;; :notangle: tag)
;; -t/--tag TAG
;; --and TAG
;; --or TAG
;; Only include blocks in trees that have these tags. Combine multiple --and
;; and --or's, or just use --tag (implicit --and).
;; -p/--print
;; Prints tangled code to stdout instead of to files
;;
;; Usage: org-tangle [[-l|--lang] LANG] some-file.org another.org
;; Examples:
;; org-tangle -l sh modules/some/module/README.org > install_module.sh
;; org-tangle -l sh modules/lang/go/README.org | sh
;; org-tangle --and tagA --and tagB my/literate/config.org
(require 'cl-lib)
(require 'ob-tangle)
(defun usage ()
(with-temp-buffer
(insert (format "%s %s [OPTIONS] [TARGETS...]\n"
"Usage:"
(file-name-nondirectory load-file-name))
"\n"
"A command line interface for tangling org-mode files. TARGETS can be\n"
"files or folders (which are searched for org files recursively).\n"
"\n"
"This is useful for literate configs that rely on command line\n"
"workflows to build it.\n"
"\n"
"Example:\n"
" org-tangle some-file.org\n"
" org-tangle literate/config/\n"
" org-tangle -p -l sh scripts.org > do_something.sh\n"
" org-tangle -p -l python -t tagA -t tagB file.org | python\n"
"\n"
"Options:\n"
" -a --all\t\tTangle all blocks by default\n"
" -l --lang LANG\tOnly tangle blocks written in LANG\n"
" -p --print\t\tPrint tangled output to stdout than to files\n"
" -t --tag TAG\n"
" --and TAG\n"
" --or TAG\n"
" Lets you tangle org blocks by tag. You may have more than one\n"
" of these options.\n")
(princ (buffer-string))))
(defun *org-babel-tangle (orig-fn &rest args)
"Don't write tangled blocks to files, print them to stdout."
(cl-letf (((symbol-function 'write-region)
(lambda (start end filename &optional append visit lockname mustbenew)
(princ (buffer-string)))))
(apply orig-fn args)))
(defun *org-babel-tangle-collect-blocks (&optional language tangle-file)
"Like `org-babel-tangle-collect-blocks', but will ignore blocks that are in
trees with the :notangle: tag."
(let ((counter 0) last-heading-pos blocks)
(org-babel-map-src-blocks (buffer-file-name)
(let ((current-heading-pos
(org-with-wide-buffer
(org-with-limited-levels (outline-previous-heading)))))
(if (eq last-heading-pos current-heading-pos) (cl-incf counter)
(setq counter 1)
(setq last-heading-pos current-heading-pos)))
(unless (org-in-commented-heading-p)
(require 'org)
(let* ((tags (org-get-tags-at))
(info (org-babel-get-src-block-info 'light))
(src-lang (nth 0 info))
(src-tfile (cdr (assq :tangle (nth 2 info)))))
(cond ((member "notangle" tags))
((and (or or-tags and-tags)
(or (not and-tags)
(let ((a (cl-intersection and-tags tags :test #'string=))
(b and-tags))
(not (or (cl-set-difference a b :test #'equal)
(cl-set-difference b a :test #'equal)))))
(or (not or-tags)
(cl-intersection or-tags tags :test #'string=))
t))
((or (not (or all-blocks src-tfile))
(string= src-tfile "no") ; tangle blocks by default
(and tangle-file (not (equal tangle-file src-tfile)))
(and language (not (string= language src-lang)))))
;; Add the spec for this block to blocks under its language.
((let ((by-lang (assoc src-lang blocks))
(block (org-babel-tangle-single-block counter)))
(if by-lang
(setcdr by-lang (cons block (cdr by-lang)))
(push (cons src-lang (list block)) blocks))))))))
;; Ensure blocks are in the correct order.
(mapcar (lambda (b) (cons (car b) (nreverse (cdr b)))) blocks)))
(advice-add #'org-babel-tangle-collect-blocks
:override #'*org-babel-tangle-collect-blocks)
(defvar all-blocks nil)
(defvar and-tags nil)
(defvar or-tags nil)
(let (lang srcs and-tags or-tags)
(pop argv)
(while argv
(let ((arg (pop argv)))
(pcase arg
((or "-h" "--help")
(usage)
(error ""))
((or "-a" "--all")
(setq all-blocks t))
((or "-l" "--lang")
(setq lang (pop argv)))
((or "-p" "--print")
(advice-add #'org-babel-tangle :around #'*org-babel-tangle))
((or "-t" "--tag" "--and")
(push (pop argv) and-tags))
("--or"
(push (pop argv) or-tags))
((guard (string-match-p "^--lang=" arg))
(setq lang (cadr (split-string arg "=" t t))))
((guard (file-directory-p arg))
(setq srcs
(append (directory-files-recursively arg "\\.org$")
srcs)))
((guard (file-exists-p arg))
(push arg srcs))
(_ (error "Unknown option or file: %s" arg)))))
(dolist (file srcs)
(org-babel-tangle-file file nil lang))
(kill-emacs 0))