mirror of
https://gitlab.com/dwt1/dotfiles.git
synced 2026-04-23 11:30:23 +10:00
Moving to Doom Emacs!
This commit is contained in:
106
.emacs.d/bin/doom
Executable file
106
.emacs.d/bin/doom
Executable 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
25
.emacs.d/bin/doom.cmd
Normal 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
42
.emacs.d/bin/org-capture
Executable 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
144
.emacs.d/bin/org-tangle
Executable 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"
|
||||
"[1mUsage:[0m"
|
||||
(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"
|
||||
"[1mExample:[0m\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"
|
||||
"[1mOptions:[0m\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))
|
||||
Reference in New Issue
Block a user