From acc2433b659b10d92cff78baac1207e469d249d3 Mon Sep 17 00:00:00 2001 From: Aspen Smith Date: Tue, 20 Feb 2024 16:31:30 -0500 Subject: feat(aspen/emacs): Begin a complete emacs config revamp I'm still on doom, but without all the cruft I've accumulated over the last ~6 years it's actually good and fast and nice. Also, the config is literate now! The old emacs is still in .emacs.d, since occasionally I want to reference it, but eventually I'll just get rid of it Change-Id: Icda840d798594f7e6b188dba044494597d5f6043 Reviewed-on: https://cl.tvl.fyi/c/depot/+/10999 Reviewed-by: aspen Tested-by: BuildkiteCI --- users/aspen/emacs/.gitignore | 2 + users/aspen/emacs/config.org | 1375 ++++++++++++++++++++ users/aspen/emacs/init.el | 197 +++ users/aspen/emacs/org-config.el | 141 ++ users/aspen/emacs/packages.el | 12 + users/aspen/emacs/snippets/haskell-mode/annotation | 5 + .../emacs/snippets/haskell-mode/benchmark-module | 26 + users/aspen/emacs/snippets/haskell-mode/header | 5 + .../emacs/snippets/haskell-mode/hedgehog-generator | 8 + .../emacs/snippets/haskell-mode/hedgehog-property | 9 + users/aspen/emacs/snippets/haskell-mode/hlint | 8 + users/aspen/emacs/snippets/haskell-mode/import-i | 4 + users/aspen/emacs/snippets/haskell-mode/inl | 6 + users/aspen/emacs/snippets/haskell-mode/inline | 5 + .../emacs/snippets/haskell-mode/language pragma | 6 + users/aspen/emacs/snippets/haskell-mode/lens.field | 7 + users/aspen/emacs/snippets/haskell-mode/module | 32 + .../emacs/snippets/haskell-mode/shut up, hlint | 6 + users/aspen/emacs/snippets/haskell-mode/test-group | 9 + .../aspen/emacs/snippets/haskell-mode/test-module | 27 + users/aspen/emacs/snippets/haskell-mode/undefined | 6 + users/aspen/emacs/snippets/js2-mode/action-type | 4 + users/aspen/emacs/snippets/js2-mode/before | 7 + users/aspen/emacs/snippets/js2-mode/context | 7 + users/aspen/emacs/snippets/js2-mode/describe | 6 + users/aspen/emacs/snippets/js2-mode/expect | 5 + users/aspen/emacs/snippets/js2-mode/function | 6 + users/aspen/emacs/snippets/js2-mode/header | 6 + users/aspen/emacs/snippets/js2-mode/it | 7 + users/aspen/emacs/snippets/js2-mode/it-pending | 5 + users/aspen/emacs/snippets/js2-mode/module | 12 + users/aspen/emacs/snippets/js2-mode/record | 7 + users/aspen/emacs/snippets/js2-mode/test | 7 + .../aspen/emacs/snippets/nix-mode/fetchFromGitHub | 12 + users/aspen/emacs/snippets/nix-mode/pythonPackage | 16 + users/aspen/emacs/snippets/nix-mode/sha256 | 7 + .../aspen/emacs/snippets/org-mode/SQL source block | 6 + users/aspen/emacs/snippets/org-mode/combat | 13 + users/aspen/emacs/snippets/org-mode/date | 5 + users/aspen/emacs/snippets/org-mode/date-time | 5 + users/aspen/emacs/snippets/org-mode/description | 7 + users/aspen/emacs/snippets/org-mode/nologdone | 5 + .../emacs/snippets/org-mode/python source block | 6 + users/aspen/emacs/snippets/org-mode/reveal | 6 + users/aspen/emacs/snippets/org-mode/transaction | 7 + users/aspen/emacs/snippets/prolog-mode/tests | 11 + users/aspen/emacs/snippets/prolog-mode/use-module | 7 + users/aspen/emacs/snippets/python-mode/add_column | 5 + users/aspen/emacs/snippets/python-mode/decorate | 15 + users/aspen/emacs/snippets/python-mode/dunder | 7 + users/aspen/emacs/snippets/python-mode/name | 7 + .../emacs/snippets/python-mode/op.get_bind.execute | 7 + users/aspen/emacs/snippets/python-mode/pdb | 7 + users/aspen/emacs/snippets/rust-mode/#[macro_use] | 5 + users/aspen/emacs/snippets/rust-mode/async test | 10 + users/aspen/emacs/snippets/rust-mode/benchmark | 10 + users/aspen/emacs/snippets/rust-mode/proptest | 10 + users/aspen/emacs/snippets/rust-mode/test-module | 11 + users/aspen/emacs/snippets/rust-mode/tests | 9 + users/aspen/emacs/snippets/snippet-mode/indent | 5 + .../emacs/snippets/sql-mode/count(*) group by | 5 + users/aspen/emacs/snippets/terraform-mode/variable | 11 + users/aspen/emacs/snippets/text-mode/date | 5 + users/aspen/emacs/snippets/tuareg-mode/expect-test | 9 + users/aspen/emacs/snippets/tuareg-mode/module | 9 + users/aspen/emacs/snippets/tuareg-mode/test-module | 10 + 66 files changed, 2245 insertions(+) create mode 100644 users/aspen/emacs/.gitignore create mode 100644 users/aspen/emacs/config.org create mode 100644 users/aspen/emacs/init.el create mode 100644 users/aspen/emacs/org-config.el create mode 100644 users/aspen/emacs/packages.el create mode 100644 users/aspen/emacs/snippets/haskell-mode/annotation create mode 100644 users/aspen/emacs/snippets/haskell-mode/benchmark-module create mode 100644 users/aspen/emacs/snippets/haskell-mode/header create mode 100644 users/aspen/emacs/snippets/haskell-mode/hedgehog-generator create mode 100644 users/aspen/emacs/snippets/haskell-mode/hedgehog-property create mode 100644 users/aspen/emacs/snippets/haskell-mode/hlint create mode 100644 users/aspen/emacs/snippets/haskell-mode/import-i create mode 100644 users/aspen/emacs/snippets/haskell-mode/inl create mode 100644 users/aspen/emacs/snippets/haskell-mode/inline create mode 100644 users/aspen/emacs/snippets/haskell-mode/language pragma create mode 100644 users/aspen/emacs/snippets/haskell-mode/lens.field create mode 100644 users/aspen/emacs/snippets/haskell-mode/module create mode 100644 users/aspen/emacs/snippets/haskell-mode/shut up, hlint create mode 100644 users/aspen/emacs/snippets/haskell-mode/test-group create mode 100644 users/aspen/emacs/snippets/haskell-mode/test-module create mode 100644 users/aspen/emacs/snippets/haskell-mode/undefined create mode 100644 users/aspen/emacs/snippets/js2-mode/action-type create mode 100644 users/aspen/emacs/snippets/js2-mode/before create mode 100644 users/aspen/emacs/snippets/js2-mode/context create mode 100644 users/aspen/emacs/snippets/js2-mode/describe create mode 100644 users/aspen/emacs/snippets/js2-mode/expect create mode 100644 users/aspen/emacs/snippets/js2-mode/function create mode 100644 users/aspen/emacs/snippets/js2-mode/header create mode 100644 users/aspen/emacs/snippets/js2-mode/it create mode 100644 users/aspen/emacs/snippets/js2-mode/it-pending create mode 100644 users/aspen/emacs/snippets/js2-mode/module create mode 100644 users/aspen/emacs/snippets/js2-mode/record create mode 100644 users/aspen/emacs/snippets/js2-mode/test create mode 100644 users/aspen/emacs/snippets/nix-mode/fetchFromGitHub create mode 100644 users/aspen/emacs/snippets/nix-mode/pythonPackage create mode 100644 users/aspen/emacs/snippets/nix-mode/sha256 create mode 100644 users/aspen/emacs/snippets/org-mode/SQL source block create mode 100644 users/aspen/emacs/snippets/org-mode/combat create mode 100644 users/aspen/emacs/snippets/org-mode/date create mode 100644 users/aspen/emacs/snippets/org-mode/date-time create mode 100644 users/aspen/emacs/snippets/org-mode/description create mode 100644 users/aspen/emacs/snippets/org-mode/nologdone create mode 100644 users/aspen/emacs/snippets/org-mode/python source block create mode 100644 users/aspen/emacs/snippets/org-mode/reveal create mode 100644 users/aspen/emacs/snippets/org-mode/transaction create mode 100644 users/aspen/emacs/snippets/prolog-mode/tests create mode 100644 users/aspen/emacs/snippets/prolog-mode/use-module create mode 100644 users/aspen/emacs/snippets/python-mode/add_column create mode 100644 users/aspen/emacs/snippets/python-mode/decorate create mode 100644 users/aspen/emacs/snippets/python-mode/dunder create mode 100644 users/aspen/emacs/snippets/python-mode/name create mode 100644 users/aspen/emacs/snippets/python-mode/op.get_bind.execute create mode 100644 users/aspen/emacs/snippets/python-mode/pdb create mode 100644 users/aspen/emacs/snippets/rust-mode/#[macro_use] create mode 100644 users/aspen/emacs/snippets/rust-mode/async test create mode 100644 users/aspen/emacs/snippets/rust-mode/benchmark create mode 100644 users/aspen/emacs/snippets/rust-mode/proptest create mode 100644 users/aspen/emacs/snippets/rust-mode/test-module create mode 100644 users/aspen/emacs/snippets/rust-mode/tests create mode 100644 users/aspen/emacs/snippets/snippet-mode/indent create mode 100644 users/aspen/emacs/snippets/sql-mode/count(*) group by create mode 100644 users/aspen/emacs/snippets/terraform-mode/variable create mode 100644 users/aspen/emacs/snippets/text-mode/date create mode 100644 users/aspen/emacs/snippets/tuareg-mode/expect-test create mode 100644 users/aspen/emacs/snippets/tuareg-mode/module create mode 100644 users/aspen/emacs/snippets/tuareg-mode/test-module diff --git a/users/aspen/emacs/.gitignore b/users/aspen/emacs/.gitignore new file mode 100644 index 0000000000..f5236c1235 --- /dev/null +++ b/users/aspen/emacs/.gitignore @@ -0,0 +1,2 @@ +custom.el +config.el diff --git a/users/aspen/emacs/config.org b/users/aspen/emacs/config.org new file mode 100644 index 0000000000..f367e49a65 --- /dev/null +++ b/users/aspen/emacs/config.org @@ -0,0 +1,1375 @@ +# Local variables: +# eval: (paxedit-mode 1) +# eval: (display-line-numbers-mode 1) +# eval: (flyspell-mode -1) +# eval: (org-config-mode 1) +# End: + +#+title: Emacs Config + +* Utils +#+begin_src elisp :tangle yes +(use-package! dash) +#+end_src + +** Elisp extras + +#+begin_src elisp :tangle yes +(defmacro comment (&rest _body) + "Comment out one or more s-expressions" + nil) + +(defun inc (x) "Returns x + 1" (+ 1 x)) +(defun dec (x) "Returns x - 1" (- x 1)) + +(defun average (ns) + "Arithmetic mean of xs" + (if (null ns) nil + (/ (apply #'+ ns) + (length ns)))) + +(defun alist-set (alist-symbol key value) + "Set VALUE of a KEY in ALIST-SYMBOL." + (set alist-symbol (cons (list key value) (assq-delete-all key (eval alist-symbol))))) + +(defun rx-words (&rest words) + (rx-to-string + `(and symbol-start (group (or ,@words)) symbol-end))) +#+end_src + +#+RESULTS: +: rx-words + +#+begin_src elisp :tangle no :results example +(average (list 1 2 3 4)) +#+end_src + +#+RESULTS: +: 2 + +** Text editing utils +*** Reading strings +#+begin_src elisp :tangle yes +(defun get-char (&optional point) + "Get the character at the given `point' (defaulting to the current point), +without properties" + (let ((point (or point (point)))) + (buffer-substring-no-properties point (+ 1 point)))) + +(defun get-line (&optional lineno) + "Read the line number `lineno', or the current line if `lineno' is nil, and +return it as a string stripped of all text properties" + (let ((current-line (line-number-at-pos))) + (if (or (not lineno) + (= current-line lineno)) + (thing-at-point 'line t) + (save-mark-and-excursion + (line-move (- lineno (line-number-at-pos))) + (thing-at-point 'line t))))) + +(defun get-line-point () + "Get the position in the current line of the point" + (- (point) (line-beginning-position))) + +;; Moving in the file + +(defun goto-line-char (pt) + "Moves the point to the given position expressed as an offset from the start +of the line" + (goto-char (+ (line-beginning-position) pt))) + +(defun goto-eol () + "Moves to the end of the current line" + (goto-char (line-end-position))) + +(defun goto-regex-on-line (regex) + "Moves the point to the first occurrence of `regex' on the current line. +Returns nil if the regex did not match, non-nil otherwise" + (when-let ((current-line (get-line)) + (line-char (string-match regex current-line))) + (goto-line-char line-char))) + +(defun goto-regex-on-line-r (regex) + "Moves the point to the *last* occurrence of `regex' on the current line. +Returns nil if the regex did not match, non-nil otherwise" + (when-let ((current-line (get-line)) + (modified-regex (concat ".*\\(" regex "\\)")) + (_ (string-match modified-regex current-line)) + (match-start (match-beginning 1))) + (goto-line-char match-start))) +#+end_src + +#+begin_src elisp :tangle no +(progn + (string-match (rx (and (zero-or-more anything) + (group "foo" "foo"))) + "foofoofoo") + (match-beginning 1)) +#+end_src + +#+RESULTS: +: 3 +*** Changing file contents +#+begin_src elisp :tangle yes +(defmacro saving-excursion (&rest body) + `(λ! () (save-excursion ,@body))) + +(defun delete-line () + "Remove the line at the current point" + (delete-region (line-beginning-position) + (inc (line-end-position)))) + +(defmacro modify-then-indent (&rest body) + "Modify text in the buffer according to body, then re-indent from where the + cursor started to where the cursor ended up, then return the cursor to where + it started." + `(let ((beg (line-beginning-position)) + (orig-line-char (- (point) (line-beginning-position)))) + (atomic-change-group + (save-mark-and-excursion + ,@body + (evil-indent beg (+ (line-end-position) 1)))) + (goto-line-char orig-line-char))) + +(pcase-defmacro s-starts-with (prefix) + `(pred (s-starts-with-p ,prefix))) + +(pcase-defmacro s-contains (needle &optional ignore-case) + `(pred (s-contains-p ,needle + ,@(when ignore-case (list ignore-case))))) +#+end_src + +#+RESULTS: +: s-contains--pcase-macroexpander + +#+begin_src elisp :tangle no +(pcase "foo" + ((s-contains "bar") 1) + ((s-contains "o") 2)) +#+end_src + +#+RESULTS: +: 2 + +** Evil utils +#+begin_src elisp :tangle yes +(defmacro define-move-and-insert + (name &rest body) + `(defun ,name (count &optional vcount skip-empty-lines) + ;; Following interactive form taken from the source for `evil-insert' + (interactive + (list (prefix-numeric-value current-prefix-arg) + (and (evil-visual-state-p) + (memq (evil-visual-type) '(line block)) + (save-excursion + (let ((m (mark))) + ;; go to upper-left corner temporarily so + ;; `count-lines' yields accurate results + (evil-visual-rotate 'upper-left) + (prog1 (count-lines evil-visual-beginning evil-visual-end) + (set-mark m))))) + (evil-visual-state-p))) + (atomic-change-group + ,@body + (evil-insert count vcount skip-empty-lines)))) +#+end_src + +#+RESULTS: +: define-move-and-insert + +* Name and email +#+begin_src emacs-lisp +(setq user-full-name "Aspen Smith" + user-mail-address "root@gws.fyi") +#+end_src + +#+RESULTS: +: root@gws.fyi + +* Visual style +#+begin_src elisp :tangle yes +(let ((font-family (pcase system-type + ('darwin "MesloLGSDZ NF") + ('gnu/linux "Meslo LGSDZ Nerd Font")))) + (setq doom-font (font-spec :family font-family :size 14) + doom-big-font (font-spec :family font-family :size 24) + doom-big-font-increment 5 + doom-variable-pitch-font (font-spec :family font-family) + doom-theme 'doom-solarized-light)) + +(setq display-line-numbers-type t) + +(setq doom-modeline-buffer-file-name-style 'relative-to-project + doom-modeline-modal-icon nil + doom-modeline-github t + doom-modeline-height 12) +#+end_src + +#+RESULTS: +: 12 + +#+begin_src elisp :tangle yes +(setq whitespace-style '(face lines-tail)) +(global-whitespace-mode t) +(add-hook 'org-mode-hook (lambda () (whitespace-mode -1)) t) +#+end_src + +#+RESULTS: +| er/add-org-mode-expansions | +aspen/org-setup | +lookup--init-org-mode-handlers-h | (closure (t) (&rest _) (add-hook 'before-save-hook 'org-encrypt-entries nil t)) | #[0 \300\301\302\303\304$\207 [add-hook change-major-mode-hook org-fold-show-all append local] 5] | #[0 \301\211\207 [imenu-create-index-function org-imenu-get-tree] 2] | doom-disable-show-paren-mode-h | doom-disable-show-trailing-whitespace-h | +org-make-last-point-visible-h | org-appear-mode | org-fancy-priorities-mode | org-superstar-mode | evil-org-mode | toc-org-enable | #[0 \300\301\302\303\304$\207 [add-hook change-major-mode-hook org-babel-show-result-all append local] 5] | org-babel-result-hide-spec | org-babel-hide-all-hashes | flyspell-mode | embrace-org-mode-hook | org-eldoc-load | +literate-enable-recompile-h | (lambda nil (whitespace-mode -1)) | + +** Theme +[[https://davidjohnstone.net/lch-lab-colour-gradient-picker][LAB colour gradient picker]] is a good tool for trying to find "halfway points" between two colours + +*** Variables +#+begin_src elisp :tangle no +(rainbow-mode) +#+end_src + +#+RESULTS: +: t + +#+name: solarized-vars +#+begin_src elisp :tangle yes +(setq +solarized-s-base03 "#002b36" + +solarized-s-base02 "#073642" + ;; emphasized content + +solarized-s-base01 "#586e75" + ;; primary content + +solarized-s-base00 "#657b83" + +solarized-s-base0 "#839496" + ;; comments + +solarized-s-base1 "#93a1a1" + ;; background highlight light + +solarized-s-base2 "#eee8d5" + ;; background light + +solarized-s-base3 "#fdf6e3" + + +solarized-halfway-highlight "#f5efdc" + + ;; Solarized accented colors + +solarized-yellow "#b58900" + +solarized-orange "#cb4b16" + +solarized-red "#dc322f" + +solarized-magenta "#d33682" + +solarized-violet "#6c71c4" + +solarized-blue "#268bd2" + +solarized-cyan "#2aa198" + +solarized-green "#859900" + + ;; Darker and lighter accented colors + ;; Only use these in exceptional circumstances! + +solarized-yellow-d "#7B6000" + +solarized-yellow-l "#DEB542" + +solarized-orange-d "#8B2C02" + +solarized-orange-l "#F2804F" + +solarized-red-d "#990A1B" + +solarized-red-l "#FF6E64" + +solarized-magenta-d "#93115C" + +solarized-magenta-l "#F771AC" + +solarized-violet-d "#3F4D91" + +solarized-violet-l "#9EA0E5" + +solarized-blue-d "#00629D" + +solarized-blue-l "#69B7F0" + +solarized-cyan-d "#00736F" + +solarized-cyan-l "#69CABF" + +solarized-green-d "#546E00" + +solarized-green-l "#B4C342") +#+end_src + +#+RESULTS: solarized-vars +: #B4C342 + +*** Overrides + +#+name: overrides-for-solarized-light +#+begin_src elisp :tangle yes +(custom-set-faces! + `(cursor :background ,+solarized-s-base00) + `(font-lock-doc-face :foreground ,+solarized-s-base1) + `(font-lock-preprocessor-face :foreground ,+solarized-red :bold nil) + `(font-lock-keyword-face :foreground ,+solarized-green :bold nil) + `(font-lock-builtin-face :foreground ,+solarized-s-base01 :bold t) + `(font-lock-function-name-face :foreground ,+solarized-blue) + `(font-lock-constant-face :foreground ,+solarized-blue) + `(font-lock-type-face :italic nil) + `(highlight-numbers-number :bold nil) + `(highlight :background ,+solarized-s-base2) + `(solaire-hl-line-face :background ,+solarized-halfway-highlight) + `(hl-line :background ,+solarized-s-base2) + + `(linum :background ,+solarized-s-base2 :foreground ,+solarized-s-base1) + `(line-number :background ,+solarized-s-base2 :foreground ,+solarized-s-base1) + `(line-number-current-line :background ,+solarized-s-base2 :foreground ,+solarized-s-base1) + `(fringe :background ,+solarized-s-base2) + + `(whitespace-line :foreground ,+solarized-red :underline t) + + `(haskell-operator-face :foreground ,+solarized-green) + `(haskell-keyword-face :foreground ,+solarized-cyan) + + `(magit-branch-local :foreground ,+solarized-blue :bold t) + `(magit-branch-remote :foreground ,+solarized-green :bold t) + `(magit-branch-remote-head :foreground ,+solarized-green :bold t :box t) + `(magit-branch-current :box t :bold t) + `(magit-header-line :background nil :foreground ,+solarized-yellow :bold t :box nil) + `(diff-refine-added :foreground "#dbdb9c" :background "#5b6e35" :bold nil) + `(magit-diff-added-highlight :foreground "#657827" :background "#efeac7" :bold nil) + `(diff-refine-removed :background "#8e433d" :foreground "#ffb9a1" :bold nil) + `(magit-diff-removed-highlight :foreground "#a33c35" :background "#ffdec8" :bold nil) + `(magit-diff-hunk-heading :background "#f8e8c6" :foreground "#876d26" :bold nil) + `(magit-diff-hunk-heading-highlight :background "#f1d49b" :foreground "#766634" :bold nil) + `(magit-section-heading :foreground "#b58900") + `(magit-filename :foreground ,+solarized-s-base00) + `(magit-diff-context-highlight :background ,+solarized-halfway-highlight) + + `(transient-delimiter :foreground ,+solarized-s-base1) + `(transient-inapt-suffix :foreground ,+solarized-s-base1) + `(transient-inactive-value :foreground ,+solarized-s-base1) + `(transient-inactive-argument :foreground ,+solarized-s-base1) + `(transient-key-exit :foreground ,+solarized-green :bold t) + `(transient-key-stay :foreground ,+solarized-blue :bold t) + ) + #+end_src + +#+RESULTS: overrides-for-solarized-light +| doom--customize-themes-h-91 | doom--customize-themes-h-92 | doom--customize-themes-h-93 | doom--customize-themes-h-94 | doom--customize-themes-h-95 | doom--customize-themes-h-96 | doom--customize-themes-h-97 | doom--customize-themes-h-98 | + +* Keybindings and navigation +Get the hell out of here, snipe! +#+begin_src elisp :tangle yes +(remove-hook 'doom-first-input-hook #'evil-snipe-mode) +#+end_src + +** Flycheck +#+begin_src elisp :tangle yes +(evil-set-command-property 'flycheck-next-error :repeat nil) +(evil-set-command-property 'flycheck-prev-error :repeat nil) +(evil-set-command-property 'flycheck-previous-error :repeat nil) + +(map! + (:map flycheck-mode-map + :m "]e" #'flycheck-next-error + :m "[e" #'flycheck-previous-error)) +#+end_src + +#+RESULTS: + +** Smerge +#+begin_src elisp :tangle yes +(evil-set-command-property 'smerge-next :repeat nil) +(evil-set-command-property 'smerge-prev :repeat nil) + +(map! + :n "] n" #'smerge-next + :n "[ n" #'smerge-prev + (:leader + (:desc "smerge" :prefix "g m" + :desc "Keep Current" :n "SPC" #'smerge-keep-current + :desc "Keep All" :n "a" #'smerge-keep-all + :desc "Keep Upper" :n "u" #'smerge-keep-upper + :desc "Keep Lower" :n "l" #'smerge-keep-lower))) +t + #+end_src + +#+RESULTS: +: t + +** Vinegar-style dired +#+begin_src elisp :tangle yes +(defun dired-mode-p () (eq 'dired-mode major-mode)) + +(defun aspen/dired-minus () + (interactive) + (if (dired-mode-p) + (dired-up-directory) + (when buffer-file-name + (-> (buffer-file-name) + (f-dirname) + (dired))))) + +(map! + :n "-" #'aspen/dired-minus + (:map dired-mode-map + "-" #'aspen/dired-minus)) +#+end_src + +#+RESULTS: + +** Lisp mappings +*** Use paxedit +#+begin_src elisp :tangle yes +(use-package! paxedit + :hook ((emacs-lisp-mode . paxedit-mode) + (clojure-mode . paxedit-mode) + (common-lisp-mode . paxedit-mode))) +#+end_src + +#+RESULTS: +| paxedit-mode | + +*** Paxedit functions + +#+begin_src elisp :tangle yes +(define-move-and-insert aspen/insert-at-sexp-end + (when (not (equal (get-char) "(")) + (backward-up-list)) + (forward-sexp) + (backward-char)) + +(define-move-and-insert aspen/insert-at-sexp-start + (backward-up-list) + (forward-char)) + +(define-move-and-insert aspen/insert-at-form-start + (backward-sexp) + (backward-char) + (insert " ")) + +(define-move-and-insert aspen/insert-at-form-end + (forward-sexp) + (insert " ")) + +(defun aspen/paxedit-kill (&optional n) + (interactive "p") + (or (paxedit-comment-kill) + (when (paxedit-symbol-cursor-within?) + (paxedit-symbol-kill)) + (paxedit-implicit-sexp-kill n) + (paxedit-sexp-kill n) + (message paxedit-message-kill))) +#+end_src + +#+RESULTS: +: aspen/paxedit-kill + +*** Paxedit mappings +#+begin_src elisp :tangle yes +(map! + (:after paxedit + (:map paxedit-mode-map + :i ";" #'paxedit-insert-semicolon + :i "(" #'paxedit-open-round + :i "[" #'paxedit-open-bracket + :i "{" #'paxedit-open-curly + :n [remap evil-yank-line] #'paxedit-copy + :n [remap evil-delete-line] #'aspen/paxedit-kill + :n "g o" #'paxedit-sexp-raise + :n [remap evil-join-whitespace] #'paxedit-compress + :n "g S" #'paxedit-format-1 + :n "g k" #'paxedit-backward-up + :n "g j" #'paxedit-backward-end))) + +(require 'general) +(general-evil-setup t) + +(nmap + ">" (general-key-dispatch 'evil-shift-right + "e" 'paxedit-transpose-forward + ")" 'sp-forward-slurp-sexp + "(" 'sp-backward-barf-sexp + "I" 'aspen/insert-at-sexp-end + ;; "a" 'grfn/insert-at-form-end + )) + +(nmap + "<" (general-key-dispatch 'evil-shift-left + "e" 'paxedit-transpose-backward + ")" 'sp-forward-barf-sexp + "(" 'sp-backward-slurp-sexp + "I" 'aspen/insert-at-sexp-start + ;; "a" 'grfn/insert-at-form-start + )) +#+end_src + +#+RESULTS: + +*** Eval functions +#+begin_src elisp :tangle yes +(use-package! predd) + +(predd-defmulti eval-sexp (lambda (form) major-mode)) + +(predd-defmethod eval-sexp 'clojure-mode (form) + (cider-interactive-eval form)) + +(predd-defmethod eval-sexp 'emacs-lisp-mode (form) + (pp-eval-expression form)) + +(predd-defmulti eval-sexp-region (lambda (_beg _end) major-mode)) + +(predd-defmethod eval-sexp-region 'clojure-mode (beg end) + (cider-interactive-eval nil nil (list beg end))) + +(predd-defmethod eval-sexp-region 'emacs-lisp-mode (beg end) + (pp-eval-expression (read (buffer-substring beg end)))) + +(predd-defmulti eval-sexp-region-context (lambda (_beg _end _context) major-mode)) + +(predd-defmethod eval-sexp-region-context 'clojure-mode (beg end context) + (cider--eval-in-context (buffer-substring beg end))) + +(defun pp-eval-context-region (beg end context) + (interactive "r\nxContext: ") + (let* ((inner-expr (read (buffer-substring beg end))) + (full-expr (list 'let* context inner-expr))) + (pp-eval-expression full-expr))) + +(predd-defmethod eval-sexp-region-context 'emacs-lisp-mode (beg end context) + (pp-eval-context-region beg end context)) + +(predd-defmulti preceding-sexp (lambda () major-mode)) + +(predd-defmethod preceding-sexp 'clojure-mode () + (cider-last-sexp)) + +(predd-defmethod preceding-sexp 'emacs-lisp-mode () + (elisp--preceding-sexp)) + +(defun eval-sexp-at-point () + (interactive) + (let ((bounds (bounds-of-thing-at-point 'sexp))) + (eval-sexp-region (car bounds) + (cdr bounds)))) + +(defun eval-last-sexp (_) + (interactive) + (eval-sexp (preceding-sexp))) + +;;; + +(defun cider-insert-current-sexp-in-repl (&optional arg) + "Insert the expression at point in the REPL buffer. +If invoked with a prefix ARG eval the expression after inserting it" + (interactive "P") + (cider-insert-in-repl (cider-sexp-at-point) arg)) + +(evil-define-operator fireplace-send (beg end) + (cider-insert-current-sexp-in-repl nil nil (list beg end))) + +(defun +clojure-pprint-expr (form) + (format "(with-out-str (clojure.pprint/pprint %s))" + form)) + +(defun cider-eval-read-and-print-handler (&optional buffer) + "Make a handler for evaluating and reading then printing result in BUFFER." + (nrepl-make-response-handler + (or buffer (current-buffer)) + (lambda (buffer value) + (let ((value* (read value))) + (with-current-buffer buffer + (insert + (if (derived-mode-p 'cider-clojure-interaction-mode) + (format "\n%s\n" value*) + value*))))) + (lambda (_buffer out) (cider-emit-interactive-eval-output out)) + (lambda (_buffer err) (cider-emit-interactive-eval-err-output err)) + '())) + +(defun cider-eval-and-replace (beg end) + "Evaluate the expression in region and replace it with its result" + (interactive "r") + (let ((form (buffer-substring beg end))) + (cider-nrepl-sync-request:eval form) + (kill-region beg end) + (cider-interactive-eval + (+clojure-pprint-expr form) + (cider-eval-read-and-print-handler)))) + +(defun cider-eval-current-sexp-and-replace () + "Evaluate the expression at point and replace it with its result" + (interactive) + (apply #'cider-eval-and-replace (cider-sexp-at-point 'bounds))) + +;;; +#+end_src + +#+RESULTS: +: fireplace-eval-context +*** Eval bindings +fireplace-esque eval binding + +#+begin_src elisp :tangle yes +(evil-define-operator fireplace-eval (beg end) + (eval-sexp-region beg end)) + +(evil-define-operator fireplace-replace (beg end) + (cider-eval-and-replace beg end)) + +(evil-define-operator fireplace-eval-context (beg end) + (eval-sexp-region-context beg end)) + +(nmap :keymaps 'cider-mode-map + "c" (general-key-dispatch 'evil-change + "p" (general-key-dispatch 'fireplace-eval + "p" 'cider-eval-sexp-at-point + "c" 'cider-eval-last-sexp + "d" 'cider-eval-defun-at-point + "r" 'cider-test-run-test) + "q" (general-key-dispatch 'fireplace-send + "q" 'cider-insert-current-sexp-in-repl + "c" 'cider-insert-last-sexp-in-repl) + "x" (general-key-dispatch 'fireplace-eval-context + "x" 'cider-eval-sexp-at-point-in-context + "c" 'cider-eval-last-sexp-in-context) + "!" (general-key-dispatch 'fireplace-replace + "!" 'cider-eval-current-sexp-and-replace + "c" 'cider-eval-last-sexp-and-replace) + "y" 'cider-copy-last-result)) + +;;; + +(nmap :keymaps 'emacs-lisp-mode-map + "c" (general-key-dispatch 'evil-change + "p" (general-key-dispatch 'fireplace-eval + "p" 'eval-sexp-at-point + "c" 'eval-last-sexp + "d" 'eval-defun + "r" 'cider-test-run-test) + "x" (general-key-dispatch 'fireplace-eval-context + "x" 'cider-eval-sexp-at-point-in-context + "c" 'cider-eval-last-sexp-in-context) + "!" (general-key-dispatch 'fireplace-replace + "!" 'cider-eval-current-sexp-and-replace + "c" 'cider-eval-last-sexp-and-replace) + "y" 'cider-copy-last-result)) + +(nmap :keymaps 'sly-mode-map + "c" (general-key-dispatch 'evil-change + "p" (general-key-dispatch 'sly-eval + ;; "p" 'eval-sexp-at-point + "c" 'sly-eval-last-expression + "d" 'sly-eval-defun + ;; "r" 'cider-test-run-test + ) + ;; "x" (general-key-dispatch 'fireplace-eval-context + ;; "x" 'cider-eval-sexp-at-point-in-context + ;; "c" 'cider-eval-last-sexp-in-context + ;; ) + ;; "!" (general-key-dispatch 'fireplace-replace + ;; "!" 'cider-eval-current-sexp-and-replace + ;; "c" 'cider-eval-last-sexp-and-replace) + ;; "y" 'cider-copy-last-result + )) + +#+end_src + +#+RESULTS: + +** Coerce + +#+begin_src elisp :tangle yes +(use-package! string-inflection + :config + (nmap "c" (general-key-dispatch 'evil-change + "r c" (saving-excursion (string-inflection-lower-camelcase)) + "r C" (saving-excursion (string-inflection-camelcase)) + "r m" (saving-excursion (string-inflection-camelcase)) + "r s" (saving-excursion (string-inflection-underscore)) + "r u" (saving-excursion (string-inflection-upcase)) + "r -" (saving-excursion (string-inflection-kebab-case)) + "r k" (saving-excursion (string-inflection-kebab-case)) + ;; "r ." (saving-excursion (string-inflection-dot-case)) + ;; "r ." (saving-excursion (string-inflection-space-case)) + ;; "r ." (saving-excursion (string-inflection-title-case)) + ))) +#+end_src + +#+RESULTS: +: t + +* Mode-specific config +** org-mode +#+begin_src elisp :tangle yes +(after! org + (load! "org-config")) +#+end_src + +#+RESULTS: +: t +*** Theme overrides + +#+begin_src elisp :tangle yes +(custom-set-faces! + `(org-drawer :foreground ,+solarized-s-base1 :bold t) + `(org-block :foreground ,+solarized-s-base00) + `(org-meta-line :foreground ,+solarized-s-base1 :italic t) + `(org-document-title :foreground ,+solarized-s-base01 :height 1.3) + `(org-done :foreground ,+solarized-green) + `(org-headline-done :foreground ,+solarized-green) + `(org-special-keyword :foreground ,+solarized-s-base1 :bold t) + `(org-date :foreground ,+solarized-blue :underline t) + `(org-table + :foreground ,+solarized-s-base0 ; used to be green, I think I like this better? + :italic t) + `(org-link :foreground ,+solarized-yellow) + `(org-todo :foreground ,+solarized-cyan) + `(org-code :foreground ,+solarized-s-base1) + `(org-block-begin-line :foreground ,+solarized-s-base1 :italic t) + `(org-block-end-line :foreground ,+solarized-s-base1 :italic t) + `(org-document-info-keyword :foreground ,+solarized-s-base1 :italic t) + + `(org-level-1 :foreground ,+solarized-red) + `(org-level-2 :foreground ,+solarized-green) + `(org-level-3 :foreground ,+solarized-blue) + `(org-level-4 :foreground ,+solarized-yellow) + `(org-level-5 :foreground ,+solarized-cyan) + `(org-level-6 :foreground ,+solarized-violet) + `(org-level-7 :foreground ,+solarized-magenta) + `(org-level-8 :foreground ,+solarized-blue)) +#+end_src + +#+RESULTS: +| doom--customize-themes-h-91 | doom--customize-themes-h-92 | doom--customize-themes-h-93 | doom--customize-themes-h-94 | doom--customize-themes-h-95 | doom--customize-themes-h-96 | doom--customize-themes-h-97 | doom--customize-themes-h-98 | doom--customize-themes-h-99 | + +*** Commands +#+begin_src elisp :tangle yes +(defun grfn/insert-new-src-block () + (interactive) + (let* ((current-src-block (org-element-at-point)) + (src-block-head (save-excursion + (goto-char (org-element-property + :begin current-src-block)) + (let ((line (thing-at-point 'line t))) + (if (not (s-starts-with? "#+NAME:" (s-trim line))) + line + (forward-line) + (thing-at-point 'line t))))) + (point-to-insert + (if-let (results-loc (org-babel-where-is-src-block-result)) + (save-excursion + (goto-char results-loc) + (org-element-property + :end + (org-element-at-point))) + (org-element-property :end (org-element-at-point))))) + (goto-char point-to-insert) + (insert "\n") + (insert src-block-head) + (let ((contents (point-marker))) + (insert "\n#+END_SRC\n") + (goto-char contents)))) + +(defun grfn/+org-insert-item (orig direction) + (interactive) + (if (and (org-in-src-block-p) + (equal direction 'below)) + (grfn/insert-new-src-block) + (funcall orig direction))) + +(advice-add #'+org--insert-item :around #'grfn/+org-insert-item) +#+end_src +*** Bindings +#+begin_src elisp :tangle yes +(map! + (:after org + :n "C-c C-x C-o" #'org-clock-out + + (:map org-capture-mode-map + :n "g RET" #'org-capture-finalize + :n "g \\" #'org-captue-refile))) +#+end_src +** magit +#+begin_src elisp :tangle yes +(after! magit + (map! :map magit-mode-map + ;; :n "] ]" #'magit-section-forward + ;; :n "[ [" #'magit-section-backward + ) + + (transient-define-suffix magit-commit-wip () + (interactive) + (magit-commit-create '("-m" "wip"))) + + (transient-append-suffix + #'magit-commit + ["c"] + (list "W" "Commit WIP" #'magit-commit-wip)) + + (transient-define-suffix magit-reset-head-back () + (interactive) + (magit-reset-mixed "HEAD~")) + + (transient-define-suffix magit-reset-head-previous () + (interactive) + (magit-reset-mixed "HEAD@{1}")) + + (transient-append-suffix + #'magit-reset + ["f"] + (list "b" "Reset HEAD~" #'magit-reset-head-back)) + (transient-append-suffix + #'magit-reset + ["f"] + (list "o" "Reset HEAD@{1}" #'magit-reset-head-previous))) +#+end_src + +#+RESULTS: + +** elisp +*** Org config mode +The minor-mode for *this file*! + +#+begin_src elisp :tangle yes +(after! smartparens + (sp-local-pair 'org-config-mode "'" "'" :actions nil) + (sp-local-pair 'org-config-mode "`" "`" :actions nil)) + +(define-minor-mode org-config-mode + "Minor-mode for tangled org .el config" + :group 'org + :lighter "Org-config" + :keymap '() + (sp-update-local-pairs 'org-config-mode)) +#+end_src + +#+RESULTS: +| keymap | + +*** Bindings +#+begin_src elisp :tangle yes +(map! + (:map emacs-lisp-mode-map + :n "g SPC" #'eval-buffer + :n "g RET" (λ! () (ert t)) )) +#+end_src + +#+RESULTS: + +** tuareg +*** Config + +#+begin_src elisp :tangle yes + +(defun aspen/tuareg-setup () + (setq-local sp-max-pair-length (->> '("begin" "sig" "struct") + (--map (length it)) + (-max)) + whitespace-line-column 80)) + +(add-hook 'tuareg-mode-hook #'aspen/tuareg-setup) + +(defun sp-tuareg-post-handler (id action context) + (when (equal action 'insert) + (save-excursion + (insert "x") + (newline) + (indent-according-to-mode)) + (delete-char 1))) + +(after! smartparens-ml + (sp-local-pair 'tuareg-mode "module" "end" :actions nil) + + (dolist (pair-start '("begin" "sig" "struct")) + (sp-local-pair 'tuareg-mode + pair-start "end" + :when '(("SPC" "RET" "")) + :unless '(sp-in-string-p) + :actions '(insert navigate) + :post-handlers '(sp-tuareg-post-handler)))) +nil + #+end_src + +#+RESULTS: + +#+begin_src elisp :tangle yes +(after! dune-mode + (add-hook 'dune-mode-hook 'paxedit-mode)) +#+end_src + +#+RESULTS: + +*** Bindings +#+begin_src elisp :tangle yes +(map! + (:map tuareg-mode-map + :n "g RET" (λ! () (compile "dune build @@runtest")) + :n "g SPC" #'dune-promote + :n "g \\" #'utop + :n "g y" #'merlin-locate-type + "C-c C-f" (λ! () (compile "dune fmt")))) +#+end_src + +#+RESULTS: + +*** Theme overrides +#+begin_src elisp :tangle yes +(custom-set-faces! + `(tuareg-font-lock-governing-face :foreground ,+solarized-s-base01 :bold t) + `(tuareg-font-lock-label-face :foreground ,+solarized-blue) + `(tuareg-font-lock-constructor-face :foreground ,+solarized-yellow) + `(tuareg-font-lock-operator-face :foreground ,+solarized-red) + `(tuareg-font-lock-attribute-face :foreground ,+solarized-red :bold nil) + `(tuareg-font-lock-extension-node-face :background nil :inherit 'font-lock-preprocessor-face) + `(merlin-eldoc-occurrences-face :background ,+solarized-s-base2) + `(merlin-type-face :background ,+solarized-s-base2) + `(utop-prompt :foreground ,+solarized-blue) + `(utop-frozen :foreground ,+solarized-s-base1 :italic t)) +#+end_src + +#+RESULTS: +| doom--customize-themes-h-30 | doom--customize-themes-h-31 | doom--customize-themes-h-32 | doom--customize-themes-h-42 | doom--customize-themes-h-46 | doom--customize-themes-h-47 | doom--customize-themes-h-64 | doom--customize-themes-h-65 | doom--customize-themes-h-66 | doom--customize-themes-h-67 | doom--customize-themes-h-68 | doom--customize-themes-h-69 | + +** clojure + +*** Setup + +#+begin_src elisp :tangle yes +(defun clojure-thing-at-point-setup () + (interactive) + ;; Used by cider-find-dwim to parse the symbol at point + (setq-local + thing-at-point-file-name-chars + (concat thing-at-point-file-name-chars + ">> value + (s-replace "\"" "") + (s-replace "\\n" "\n"))))) + nil nil nil))) + (('clj 'multi) + (funcall-interactively + #'cider-test-run-ns-tests + nil)))) + +(defun cider-copy-last-result () + (interactive) + (cider-interactive-eval + "*1" + (nrepl-make-response-handler + (current-buffer) + (lambda (_ value) + (kill-new value) + (message "Copied last result (%s) to clipboard" + (if (= (length value) 1) "1 char" + (format "%d chars" (length value))))) + nil nil nil))) + +#+end_src + +#+RESULTS: +: cider-copy-last-result + +*** Bindings + + +#+begin_src elisp :tangle yes +(map! + (:after + clojure-mode + (:map clojure-mode-map + :n "] f" 'forward-sexp + :n "[ f" 'backward-sexp)) + + (:after + cider-mode + (:map cider-mode-map + :n "g SPC" 'cider-eval-buffer + :n "g \\" 'cider-switch-to-repl-buffer + :n "K" 'cider-doc + :n "g K" 'cider-apropos + :n "g d" 'cider-find-dwim + :n "C-w ]" 'cider-find-dwim-other-window + ;; :n "g RET" 'cider-test-run-ns-tests + :n "g RET" 'grfn/run-clj-or-cljs-test + :n "g r" #'cljr-rename-symbol + + "C-c C-r r" 'cljr-add-require-to-ns + "C-c C-r i" 'cljr-add-import-to-ns + + (:localleader + ;; :desc "Inspect last result" :n "i" 'cider-inspect-last-result + ;; :desc "Search for documentation" :n "h s" 'cider-apropos-doc + :desc "Add require to ns" :n "n r" 'cljr-add-require-to-ns + :desc "Add import to ns" :n "n i" 'cljr-add-import-to-ns)) + (:map cider-repl-mode-map + :n "g \\" 'cider-switch-to-last-clojure-buffer))) + #+end_src + + #+RESULTS: + +** rust +*** Config +#+begin_src elisp +(defun aspen/rust-setup () + (interactive) + (+evil-embrace-angle-bracket-modes-hook-h) + (setq-local whitespace-line-column 100 + fill-column 100) + (eglot-inlay-hints-mode -1) + (setq lsp-rust-analyzer-cargo-watch-command "clippy" + rustic-format-trigger 'on-save + )) + +(add-hook 'rust-mode-hook #'aspen/rust-setup) +#+end_src + +#+RESULTS: +| doom-modeline-env-setup-rust | aspen/rust-setup | + +*** Bindings + +*** Theme overrides +#+begin_src elisp +(custom-set-faces! + `(rust-unsafe :foreground ,+solarized-red)) +#+end_src + +#+RESULTS: +| doom--customize-themes-h-30 | doom--customize-themes-h-31 | doom--customize-themes-h-32 | doom--customize-themes-h-33 | doom--customize-themes-h-54 | + +* Email +#+begin_src elisp :tangle yes +(after! notmuch + (setq notmuch-saved-searches + '((:name "inbox" :query "tag:inbox tag:important not tag:trash" :key "i") + (:name "flagged" :query "tag:flagged" :key "f") + (:name "sent" :query "tag:sent" :key "s") + (:name "drafts" :query "tag:draft" :key "d") + + (:name "work" :query "tag:inbox and tag:important and path:work/**" + :key "w") + (:name "personal" :query "tag:inbox and tag:important and path:personal/**" + :key "p")) + message-send-mail-function 'message-send-mail-with-sendmail + message-sendmail-f-is-evil 't + message-sendmail-envelope-from 'header + message-sendmail-extra-arguments '("--read-envelope-from"))) +#+end_src + +#+RESULTS: +| --read-envelope-from | + +** Bindings +#+begin_src emacs-lisp :tangle yes +(map! + (:leader + :desc "Email" :n "o m" #'notmuch-jump-search + :desc "Search email" "s M" #'consult-notmuch)) +#+end_src + +#+RESULTS: +: notmuch-jump-search + + +** Theme + +#+begin_src emacs-lisp :tangle yes +(custom-set-faces! + `(notmuch-message-summary-face + :background ,+solarized-halfway-highlight)) +#+end_src + +#+RESULTS: +| doom--customize-themes-h-91 | doom--customize-themes-h-92 | doom--customize-themes-h-93 | doom--customize-themes-h-94 | doom--customize-themes-h-95 | doom--customize-themes-h-96 | doom--customize-themes-h-97 | doom--customize-themes-h-98 | doom--customize-themes-h-99 | doom--customize-themes-h-100 | + +* Misc +** Make underscores word chars +#+begin_src elisp :tangle yes +(modify-syntax-entry ?_ "w") +#+end_src + +#+RESULTS: + +** Matchit +#+begin_src elisp :tangle yes +(use-package! evil-matchit) +#+end_src +** IRC +*** Connecting to IRC + +#+begin_src elisp :tangle yes +(defvar irc-servers + '("hackint" + "libera")) + +(defun irc-connect (server) + (interactive + (list (completing-read "Server: " irc-servers))) + (let ((pw (-> (shell-command-to-string + (format "pass irccloud/%s" server)) + (s-trim) + (s-lines) + (-last-item))) + (gnutls-verify-error nil)) + (erc-tls :server "bnc.irccloud.com" + :port 6697 + :nick "aspen" + :password (concat "bnc@" + (s-trim (shell-command-to-string "hostname")) + ":" + pw)))) + +(defun aspen/switch-to-erc-buffer-or-connect () + (interactive) + (if (functionp 'erc-switch-to-buffer) + (call-interactively #'erc-switch-to-buffer) + (call-interactively #'irc-connect))) +#+end_src + +#+RESULTS: +: aspen/switch-to-erc-buffer-or-connect + +#+begin_src elisp :tangle yes +(map! :leader "o I" #'irc-connect + :leader "o i" #'aspen/switch-to-erc-buffer-or-connect) +#+end_src + +#+RESULTS: +: aspen/switch-to-erc-buffer-or-connect + +*** IRC alerts +#+begin_src elisp :tangle yes +(use-package! alert) + +(defgroup erc-alert nil + "Alert me using alert.el for important ERC messages" + :group 'erc) + +(defcustom erc-noise-regexp + "\\(Logging in:\\|Signing off\\|You're now away\\|Welcome back\\)" + "This regexp matches unwanted noise." + :type 'regexp + :group 'erc) + +(setq tvl-enabled? t) + +(defun disable-tvl-notifications () + (interactive) + (setq tvl-enabled? nil)) + +(defun enable-tvl-notifications () + (interactive) + (setq tvl-enabled? t)) + +(defun erc-alert-important-p (info) + (let ((message (plist-get info :message)) + (erc-message (-> info (plist-get :data) (plist-get :message))) + (erc-channel (-> info (plist-get :data) (plist-get :channel)))) + (and erc-message + (not (or (string-match "^\\** *Users on #" message) + (string-match erc-noise-regexp + message))) + (or (and tvl-enabled? + (string-equal erc-channel "#tvl")) + (string-match "grfn" message))))) + +(comment + last-info + erc-noise-regexp + (setq tvl-enabled? nil) + ) + +(defun my-erc-hook (&optional match-type nick message) + "Shows a notification, when user's nick was mentioned. +If the buffer is currently not visible, makes it sticky." + (setq last-message message) + (if (or (null match-type) (not (eq match-type 'fool))) + (let (alert-log-messages) + (alert (or message (buffer-string)) + :severity (if (string-match "grfn" (or message "")) + 'high 'low) + :title (or nick (buffer-name)) + :data `(:message ,(or message (buffer-string)) + :channel ,(or nick (buffer-name))))))) + +(add-hook 'erc-text-matched-hook 'my-erc-hook) +(add-hook 'erc-insert-modify-hook 'my-erc-hook) + +(defun my-erc-define-alerts (&rest ignore) + ;; Unless the user has recently typed in the ERC buffer, highlight the fringe + (alert-add-rule + :status '(buried visible idle) + :severity '(moderate high urgent) + :mode 'erc-mode + :predicate + #'(lambda (info) + (and (not (eq (current-buffer) (plist-get info :buffer))) + (string-match "grfn:" (plist-get info :message)))) + :persistent + #'(lambda (info) + ;; If the buffer is buried, or the user has been idle for + ;; `alert-reveal-idle-time' seconds, make this alert + ;; persistent. Normally, alerts become persistent after + ;; `alert-persist-idle-time' seconds. + (memq (plist-get info :status) '(buried idle))) + :style 'message + :continue t) + + (alert-add-rule + :status 'buried + :mode 'erc-mode + :predicate #'erc-alert-important-p + :style 'libnotify + :append t) + + (alert-add-rule + :status 'buried + :mode 'erc-mode + :predicate #'erc-alert-important-p + :style 'message + :append t) + + (alert-add-rule + :mode 'erc-mode + :predicate #'erc-alert-important-p + :style 'log + :append t) + + (alert-add-rule :mode 'erc-mode :style 'ignore :append t)) + +(add-hook 'erc-connect-pre-hook 'my-erc-define-alerts) +#+end_src + +#+RESULTS: +| my-erc-define-alerts | + +*** Don't send ~:q~, etc, to the server +#+begin_src elisp :tangle yes +(defun fix-irc-message (msg) + (let ((msg (s-trim msg))) + (if (string-equal msg ":q") "" msg))) +(advice-add #'erc-user-input :filter-return #'fix-irc-message) +#+end_src + +#+RESULTS: + +*** Theme overrides +#+begin_src elisp :tangle yes +(custom-set-faces! + `(erc-button :foreground ,+solarized-blue)) +#+end_src + +#+RESULTS: +| doom--customize-themes-h-30 | doom--customize-themes-h-31 | doom--customize-themes-h-32 | doom--customize-themes-h-43 | doom--customize-themes-h-47 | doom--customize-themes-h-48 | doom--customize-themes-h-49 | doom--customize-themes-h-50 | doom--customize-themes-h-51 | doom--customize-themes-h-52 | doom--customize-themes-h-53 | doom--customize-themes-h-54 | doom--customize-themes-h-56 | doom--customize-themes-h-57 | doom--customize-themes-h-58 | doom--customize-themes-h-59 | doom--customize-themes-h-60 | doom--customize-themes-h-61 | doom--customize-themes-h-62 | doom--customize-themes-h-63 | doom--customize-themes-h-64 | + +*** TODO Nick rainbow colors +Stole this from https://github.com/jtdaugherty/emacs-config/blob/master/common/erc-nick-colors.el. + +IT doesn't work though :( + +#+begin_src elisp :tangle yes +(setq nick-face-list '()) + +;; Define the list of colors to use when coloring IRC nicks. +(setq-default erc-colors-list (list +solarized-yellow + +solarized-orange + +solarized-red + +solarized-magenta + +solarized-violet + +solarized-blue + +solarized-cyan + +solarized-green)) + +(defun build-nick-face-list () + "build-nick-face-list builds a list of new faces using the +foreground colors specified in erc-colors-list. The nick faces +created here will be used to format IRC nicks." + (let ((i -1)) + (setq nick-face-list + (mapcar + (lambda (COLOR) + (setq i (1+ i)) + (list (custom-declare-face + (make-symbol (format "erc-nick-face-%d" i)) + (list (list t (list :foreground COLOR))) + (format "Nick face %d" i)))) + erc-colors-list)))) + +(defun erc-insert-nick-colors () + "This insert-modify hook looks for nicks in new messages and +computes md5(nick) and uses substring(md5_value, 0, 4) mod (length +nick-face-list) to index the face list and produce the same face for a +given nick each time it is seen. We get a lot of collisions this way, +unfortunately, but it's better than some other methods I tried. +Additionally, if you change the order or size of the erc-colors-list, +you'll change the colors used for nicks." + (if (null nick-face-list) (build-nick-face-list)) + (save-excursion + (goto-char (point-min)) + (if (looking-at "<\\([^>]*\\)>") + (let ((nick (match-string 1))) + (put-text-property (match-beginning 1) (match-end 1) + 'face (nth + (mod (string-to-number + (substring (md5 nick) 0 4) 16) + (length nick-face-list)) + nick-face-list)))))) + +;; This adds the ERC message insert hook. +(add-hook 'erc-insert-modify-hook 'erc-insert-nick-colors) +#+end_src + +#+RESULTS: +| erc-insert-nick-colors | erc-controls-highlight | erc-fill | my-erc-hook | erc-button-add-buttons | erc-match-message | erc-add-timestamp | + +* Hacks +Not having this breaks elisp documentation :( +#+begin_src elisp :tangle yes +(defvar elisp-demos-user-files nil) +#+end_src + +#+RESULTS: +: elisp-demos-user-files diff --git a/users/aspen/emacs/init.el b/users/aspen/emacs/init.el new file mode 100644 index 0000000000..2fe2316753 --- /dev/null +++ b/users/aspen/emacs/init.el @@ -0,0 +1,197 @@ +;;; init.el -*- lexical-binding: t; -*- + +;; This file controls what Doom modules are enabled and what order they load +;; in. Remember to run 'doom sync' after modifying it! + +;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's +;; documentation. There you'll find a link to Doom's Module Index where all +;; of our modules are listed, including what flags they support. + +;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or +;; 'C-c c k' for non-vim users) to view its documentation. This works on +;; flags as well (those symbols that start with a plus). +;; +;; Alternatively, press 'gd' (or 'C-c c d') on a module to browse its +;; directory (for easy access to its source code). + +(doom! :input + ;;bidi ; (tfel ot) thgir etirw uoy gnipleh + ;;chinese + ;;japanese + ;;layout ; auie,ctsrnm is the superior home row + + :completion + company ; the ultimate code completion backend + ;;helm ; the *other* search engine for love and life + ;;ido ; the other *other* search engine... + ;;ivy ; a search engine for love and life + vertico ; the search engine of the future + + :ui + ;;deft ; notational velocity for Emacs + doom ; what makes DOOM look the way it does + ;; doom-dashboard ; a nifty splash screen for Emacs + ;;doom-quit ; DOOM quit-message prompts when you quit Emacs + (emoji +unicode) ; 🙂 + hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW + ;;hydra + ;;indent-guides ; highlighted indent columns + ;;ligatures ; ligatures and symbols to make your code pretty again + ;;minimap ; show a map of the code on the side + modeline ; snazzy, Atom-inspired modeline, plus API + ;;nav-flash ; blink cursor line after big motions + ;;neotree ; a project drawer, like NERDTree for vim + ophints ; highlight the region an operation acts on + (popup +defaults) ; tame sudden yet inevitable temporary windows + ;;tabs ; a tab bar for Emacs + ;;treemacs ; a project drawer, like neotree but cooler + ;;unicode ; extended unicode support for various languages + (vc-gutter +pretty) ; vcs diff in the fringe + vi-tilde-fringe ; fringe tildes to mark beyond EOB + ;;window-select ; visually switch windows + workspaces ; tab emulation, persistence & separate workspaces + ;;zen ; distraction-free coding or writing + + :editor + (evil +everywhere); come to the dark side, we have cookies + file-templates ; auto-snippets for empty files + fold ; (nigh) universal code folding + (format +onsave) ; automated prettiness + ;;god ; run Emacs commands without modifier keys + ;;lispy ; vim for lisp, for people who don't like vim + ;;multiple-cursors ; editing in many places at once + ;;objed ; text object editing for the innocent + ;;parinfer ; turn lisp into python, sort of + ;;rotate-text ; cycle region at point between text candidates + snippets ; my elves. They type so I don't have to + word-wrap ; soft wrapping with language-aware indent + + :emacs + dired ; making dired pretty [functional] + electric ; smarter, keyword-based electric-indent + ;;ibuffer ; interactive buffer management + undo ; persistent, smarter undo for your inevitable mistakes + vc ; version-control and Emacs, sitting in a tree + + :term + ;;eshell ; the elisp shell that works everywhere + ;;shell ; simple shell REPL for Emacs + ;;term ; basic terminal emulator for Emacs + vterm ; the best terminal emulation in Emacs + + :checkers + syntax ; tasing you for every semicolon you forget + (spell +flyspell) ; tasing you for misspelling mispelling + ;;grammar ; tasing grammar mistake every you make + + :tools + ;;ansible + ;;biblio ; Writes a PhD for you (citation needed) + ;;debugger ; FIXME stepping through code, to help you add bugs + direnv + docker + ;;editorconfig ; let someone else argue about tabs vs spaces + ;;ein ; tame Jupyter notebooks with emacs + (eval +overlay) ; run code, run (also, repls) + ;;gist ; interacting with github gists + lookup ; navigate your code and its documentation + (lsp +eglot) ; M-x vscode + magit ; a git porcelain for Emacs + ;;make ; run make tasks from Emacs + pass ; password manager for nerds + ;;pdf ; pdf enhancements + ;;prodigy ; FIXME managing external services & code builders + ;;rgb ; creating color strings + ;;taskrunner ; taskrunner for all your projects + terraform ; infrastructure as code + ;;tmux ; an API for interacting with tmux + ;;tree-sitter ; syntax and parsing, sitting in a tree... + ;;upload ; map local to remote projects via ssh/ftp + + :os + (:if IS-MAC macos) ; improve compatibility with macOS + ;;tty ; improve the terminal Emacs experience + + :lang + agda ; types of types of types of types... + ;;beancount ; mind the GAAP + ;;(cc +lsp) ; C > C++ == 1 + clojure ; java with a lisp + common-lisp ; if you've seen one lisp, you've seen them all + ;;coq ; proofs-as-programs + ;;crystal ; ruby at the speed of c + ;;csharp ; unity, .NET, and mono shenanigans + data ; config/data formats + ;;(dart +flutter) ; paint ui and not much else + ;;dhall + ;;elixir ; erlang done right + ;;elm ; care for a cup of TEA? + emacs-lisp ; drown in parentheses + ;;erlang ; an elegant language for a more civilized age + ;;ess ; emacs speaks statistics + ;;factor + ;;faust ; dsp, but you get to keep your soul + ;;fortran ; in FORTRAN, GOD is REAL (unless declared INTEGER) + ;;fsharp ; ML stands for Microsoft's Language + ;;fstar ; (dependent) types and (monadic) effects and Z3 + ;;gdscript ; the language you waited for + ;;(go +lsp) ; the hipster dialect + ;;(graphql +lsp) ; Give queries a REST + (haskell +lsp) ; a language that's lazier than I am + ;;hy ; readability of scheme w/ speed of python + ;;idris ; a language you can depend on + json ; At least it ain't XML + ;;(java +lsp) ; the poster child for carpal tunnel syndrome + ;;javascript ; all(hope(abandon(ye(who(enter(here)))))) + ;;julia ; a better, faster MATLAB + ;;kotlin ; a better, slicker Java(Script) + ;;latex ; writing papers in Emacs has never been so fun + ;;lean ; for folks with too much to prove + ;;ledger ; be audit you can be + ;;lua ; one-based indices? one-based indices + markdown ; writing docs for people to ignore + ;;nim ; python + lisp at the speed of c + nix ; I hereby declare "nix geht mehr!" + ocaml ; an objective camel + (org ; organize your plain life in plain text + +gnuplot + +present + +pretty) + ;;php ; perl's insecure younger brother + ;;plantuml ; diagrams for confusing people more + ;;purescript ; javascript, but functional + python ; beautiful is better than ugly + ;;qt ; the 'cutest' gui framework ever + ;;racket ; a DSL for DSLs + ;;raku ; the artist formerly known as perl6 + ;;rest ; Emacs as a REST client + ;;rst ; ReST in peace + ;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"} + (rust +lsp) ; Fe2O3.unwrap().unwrap().unwrap().unwrap() + ;;scala ; java, but good + ;;(scheme +guile) ; a fully conniving family of lisps + sh ; she sells {ba,z,fi}sh shells on the C xor + ;;sml + ;;solidity ; do you need a blockchain? No. + ;;swift ; who asked for emoji variables? + ;;terra ; Earth and Moon in alignment for performance. + web ; the tubes + yaml ; JSON, but readable + ;;zig ; C, but simpler + + :email + ;;(mu4e +org +gmail) + notmuch + ;;(wanderlust +gmail) + + :app + ;;calendar + ;;emms + ;;everywhere ; *leave* Emacs!? You must be joking + irc ; how neckbeards socialize + ;;(rss +org) ; emacs as an RSS reader + ;;twitter ; twitter client https://twitter.com/vnought + + :config + literate + (default +bindings +smartparens)) diff --git a/users/aspen/emacs/org-config.el b/users/aspen/emacs/org-config.el new file mode 100644 index 0000000000..df93142b0f --- /dev/null +++ b/users/aspen/emacs/org-config.el @@ -0,0 +1,141 @@ +;;; org-config.el -*- lexical-binding: t; -*- + +(defun +aspen/org-setup () + (setq-local truncate-lines -1) + (display-line-numbers-mode -1) + (line-number-mode -1) + (when-let* + ((path (buffer-file-name)) + (fn (file-name-nondirectory path)) + (equal (string-equal fn "config.org"))) + (paxedit-mode 1) + (display-line-numbers-mode 1) + (flyspell-mode -1) + (org-config-mode 1))) + +(add-hook 'org-mode-hook #'+aspen/org-setup 50) + +(defun notes-file (f) + (concat org-directory (if (string-prefix-p "/" f) "" "/") f)) + +(defun aspen/org-project-tag->key (tag) + (s-replace-regexp "^project__" "" tag)) + +(defun aspen/org-project-tag->name (tag) + (s-titleized-words + (s-join " " (s-split "_" (aspen/org-project-tag->key tag))))) + +(defun aspen/org-project-tag->keys (tag) + (s-join "" (cons "p" + (-map (lambda (s) (substring-no-properties s 0 1)) + (s-split "_" (aspen/org-project-tag->key tag)))))) + +(defun aspen/org-projects->agenda-commands (project-tags) + (cl-loop for tag in project-tags + collect `(,(aspen/org-project-tag->keys tag) + ,(aspen/org-project-tag->name tag) + tags-todo + ,tag))) + +(defun aspen/org-projects () + (cl-loop for (tag) in + (org-global-tags-completion-table + (directory-files-recursively "~/notes" "\\.org$")) + when (s-starts-with-p "project__" tag) + collect tag)) + +(comment + (aspen/org-projects->agenda-commands (aspen/org-projects)) + ) + +(setq + org-directory (expand-file-name "~/notes") + +org-dir (expand-file-name "~/notes") + org-default-notes-file (concat org-directory "/inbox.org") + +org-default-todo-file (concat org-directory "/inbox.org") + org-agenda-files (directory-files-recursively + "~/notes" "\\.org$") + org-refile-targets '((org-agenda-files :maxlevel . 3)) + org-outline-path-complete-in-steps nil + org-refile-use-outline-path t + org-file-apps `((auto-mode . emacs) + (,(rx (or (and "." (optional "x") (optional "htm") (optional "l") buffer-end) + (and buffer-start "http" (optional "s") "://"))) + . "firefox %s") + (,(rx ".pdf" buffer-end) . "apvlv %s") + (,(rx "." (or "png" + "jpg" + "jpeg" + "gif" + "tif" + "tiff") + buffer-end) + . "feh %s")) + org-log-done 'time + org-archive-location "~/notes/trash::* From %s" + org-cycle-separator-lines 2 + org-hidden-keywords '(title) + org-tags-column -130 + org-ellipsis "…" + org-imenu-depth 9 + org-capture-templates + `(("t" "Todo" entry + (file +org-default-todo-file) + "* TODO %?\n%i" + :kill-buffer t) + + ("m" "Email" entry + (file +org-default-todo-file) + "* TODO [[%L][%:subject]] :email:\n%i") + + ("n" "Notes" entry + (file +org-default-todo-file) + "* %U %?\n%i" + :prepend t + :kill-buffer t) + + ("c" "Task note" entry + (clock) + "* %U %?\n%i[%l[Context]]\n" + :kill-buffer t + :unnarrowed t) + + ("p" "Projects") + ("px" "Xanthous" entry + (file+headline ,(notes-file "xanthous.org") "Backlog") + "* TODO %?\nContext %a\nIn task: %K") + ("pt" "Tvix" entry + (file+headline ,(notes-file "tvix.org") "Tvix TODO") + "* TODO %?\nContext %a\nIn task: %K") + ("pw" "Windtunnel" entry + (file+headline ,(notes-file "windtunnel.org") "Inbox") + "* TODO %i%?\nContext: %a\nIn task: %K") + ) + + org-capture-templates-contexts + `(("px" ((in-file . "/home/aspen/code/depot/users/aspen/xanthous/.*"))) + ("e" ((in-mode . "notmuch-show-mode")))) + + org-deadline-warning-days 1 + org-agenda-skip-scheduled-if-deadline-is-shown 'todo + org-todo-keywords '((sequence "TODO(t)" "ACTIVE(a)" "|" "DONE(d)" "RUNNING(r)") + (sequence "NEXT(n)" "WAITING(w)" "LATER(l)" "|" "CANCELLED(c)")) + org-agenda-custom-commands + `(("i" "Inbox" tags "inbox") + ("r" "Running jobs" todo "RUNNING") + ("w" "@Work" tags-todo "@work") + ("n" . "Next...") + ("nw" "Next @Work" tags-todo "@work&next") + ("nt" "Next tooling" tags-todo "tooling") + + ("p" . "Project...") + ;; ,@(aspen/org-projects->agenda-commands (aspen/org-projects)) + ) + + org-agenda-dim-blocked-tasks nil + org-enforce-todo-dependencies nil + + org-babel-clojure-backend 'cider) + +(setq whitespace-global-modes '(not org-mode magit-mode vterm-mode)) +(setf (alist-get 'file org-link-frame-setup) 'find-file-other-window) diff --git a/users/aspen/emacs/packages.el b/users/aspen/emacs/packages.el new file mode 100644 index 0000000000..cad4cc9553 --- /dev/null +++ b/users/aspen/emacs/packages.el @@ -0,0 +1,12 @@ +;; -*- no-byte-compile: t; -*- +;;; $DOOMDIR/packages.el + +(package! dash) +(package! paxedit) +(package! predd + :recipe (:host github :repo "skeeto/predd")) +(package! alert) +(package! flycheck-clojure) +(package! evil-matchit) +(package! string-inflection) +(package! protobuf-mode) diff --git a/users/aspen/emacs/snippets/haskell-mode/annotation b/users/aspen/emacs/snippets/haskell-mode/annotation new file mode 100644 index 0000000000..8a2854d759 --- /dev/null +++ b/users/aspen/emacs/snippets/haskell-mode/annotation @@ -0,0 +1,5 @@ +# key: ann +# name: annotation +# expand-env: ((yas-indent-line 'fixed)) +# -- +{-# ANN ${1:module} ("${2:HLint: ignore ${3:Reduce duplication}}" :: String) #-} \ No newline at end of file diff --git a/users/aspen/emacs/snippets/haskell-mode/benchmark-module b/users/aspen/emacs/snippets/haskell-mode/benchmark-module new file mode 100644 index 0000000000..cbb1646e41 --- /dev/null +++ b/users/aspen/emacs/snippets/haskell-mode/benchmark-module @@ -0,0 +1,26 @@ +# key: bench +# name: benchmark-module +# expand-env: ((yas-indent-line (quote fixed))) +# -- +-------------------------------------------------------------------------------- +module ${1:`(if (not buffer-file-name) "Module" + (let ((name (file-name-sans-extension (buffer-file-name))) + (case-fold-search nil)) + (if (cl-search "bench/" name) + (replace-regexp-in-string "/" "." + (replace-regexp-in-string "^\/[^A-Z]*" "" + (car (last (split-string name "src"))))) + (file-name-nondirectory name))))`} ( benchmark, main ) where +-------------------------------------------------------------------------------- +import Bench.Prelude +-------------------------------------------------------------------------------- +import ${1:$(s-chop-suffix "Bench" yas-text)} +-------------------------------------------------------------------------------- + +main :: IO () +main = defaultMain [benchmark] + +-------------------------------------------------------------------------------- + +benchmark :: Benchmark +benchmark = bgroup "${1:$(->> yas-text (s-chop-suffix "Bench") (s-split ".") -last-item)}" [bench "something dumb" $ nf (1 +) (1 :: Int)] diff --git a/users/aspen/emacs/snippets/haskell-mode/header b/users/aspen/emacs/snippets/haskell-mode/header new file mode 100644 index 0000000000..fdd8250d86 --- /dev/null +++ b/users/aspen/emacs/snippets/haskell-mode/header @@ -0,0 +1,5 @@ +# key: hh +# name: header +# expand-env: ((yas-indent-line 'fixed)) +# -- +--------------------------------------------------------------------------------$2 \ No newline at end of file diff --git a/users/aspen/emacs/snippets/haskell-mode/hedgehog-generator b/users/aspen/emacs/snippets/haskell-mode/hedgehog-generator new file mode 100644 index 0000000000..68863f7054 --- /dev/null +++ b/users/aspen/emacs/snippets/haskell-mode/hedgehog-generator @@ -0,0 +1,8 @@ +# key: gen +# name: Hedgehog Generator +# expand-env: ((yas-indent-line (quote fixed))) +# -- +gen${1:Foo} :: Gen $1 +gen$1 = do + $2 + pure $1{..} \ No newline at end of file diff --git a/users/aspen/emacs/snippets/haskell-mode/hedgehog-property b/users/aspen/emacs/snippets/haskell-mode/hedgehog-property new file mode 100644 index 0000000000..bf39a2a3ee --- /dev/null +++ b/users/aspen/emacs/snippets/haskell-mode/hedgehog-property @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# name: Hedgehog Property +# key: hprop +# expand-env: ((yas-indent-line 'fixed)) +# -- +hprop_${1:somethingIsAlwaysTrue} :: Property +hprop_$1 = property $ do + ${2:x} <- forAll ${3:Gen.int $ Range.linear 1 100} + ${4:x === x} \ No newline at end of file diff --git a/users/aspen/emacs/snippets/haskell-mode/hlint b/users/aspen/emacs/snippets/haskell-mode/hlint new file mode 100644 index 0000000000..f25a9b8d40 --- /dev/null +++ b/users/aspen/emacs/snippets/haskell-mode/hlint @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# name: hlint +# uuid: hlint +# expand-env: ((yas-indent-line 'fixed)) +# key: hlint +# condition: t +# -- +{-# ANN module ("Hlint: ignore $1" :: String) #- } \ No newline at end of file diff --git a/users/aspen/emacs/snippets/haskell-mode/import-i b/users/aspen/emacs/snippets/haskell-mode/import-i new file mode 100644 index 0000000000..4a7fca2c2f --- /dev/null +++ b/users/aspen/emacs/snippets/haskell-mode/import-i @@ -0,0 +1,4 @@ +# key: i +# name: import-i +# -- +import ${1:Prelude} \ No newline at end of file diff --git a/users/aspen/emacs/snippets/haskell-mode/inl b/users/aspen/emacs/snippets/haskell-mode/inl new file mode 100644 index 0000000000..6e17b83d71 --- /dev/null +++ b/users/aspen/emacs/snippets/haskell-mode/inl @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: inl +# key: inl +# expand-env: ((yas-indent-line 'fixed)) +# -- +{-# INLINE $1 #-} \ No newline at end of file diff --git a/users/aspen/emacs/snippets/haskell-mode/inline b/users/aspen/emacs/snippets/haskell-mode/inline new file mode 100644 index 0000000000..1beafbe50b --- /dev/null +++ b/users/aspen/emacs/snippets/haskell-mode/inline @@ -0,0 +1,5 @@ +# key: inline +# name: inline +# expand-env: ((yas-indent-line 'fixed)) +# -- +{-# INLINE $1 #-} \ No newline at end of file diff --git a/users/aspen/emacs/snippets/haskell-mode/language pragma b/users/aspen/emacs/snippets/haskell-mode/language pragma new file mode 100644 index 0000000000..6f84720f45 --- /dev/null +++ b/users/aspen/emacs/snippets/haskell-mode/language pragma @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: language pragma +# key: lang +# expand-env: ((yas-indent-line 'fixed)) +# -- +{-# LANGUAGE $1 #-} \ No newline at end of file diff --git a/users/aspen/emacs/snippets/haskell-mode/lens.field b/users/aspen/emacs/snippets/haskell-mode/lens.field new file mode 100644 index 0000000000..b22ea3d2e8 --- /dev/null +++ b/users/aspen/emacs/snippets/haskell-mode/lens.field @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: lens.field +# key: lens +# expand-env: ((yas-indent-line 'fixed)) +# -- +${1:field} :: Lens' ${2:Source} ${3:Target} +$1 = lens _${4:sourceField} $ \\${2:$(-> yas-text s-word-initials s-downcase)} ${4:$(-> yas-text s-word-initials s-downcase)} -> ${2:$(-> yas-text s-word-initials s-downcase)} { _$4 = ${4:$(-> yas-text s-word-initials s-downcase)} } \ No newline at end of file diff --git a/users/aspen/emacs/snippets/haskell-mode/module b/users/aspen/emacs/snippets/haskell-mode/module new file mode 100644 index 0000000000..4554d33f9b --- /dev/null +++ b/users/aspen/emacs/snippets/haskell-mode/module @@ -0,0 +1,32 @@ +# -*- mode: snippet -*- +# key: module +# name: module +# condition: (= (length "module") (current-column)) +# expand-env: ((yas-indent-line 'fixed)) +# contributor: Luke Hoersten +# -- +-------------------------------------------------------------------------------- +-- | +-- Module : $1 +-- Description : $2 +-- Maintainer : Griffin Smith +-- Maturity : ${3:Draft, Usable, Maintained, OR MatureAF} +-- +-- $4 +-------------------------------------------------------------------------------- +module ${1:`(if (not buffer-file-name) "Module" + (let ((name (file-name-sans-extension (buffer-file-name))) + (case-fold-search nil)) + (if (or (cl-search "src/" name) + (cl-search "test/" name)) + (replace-regexp-in-string "/" "." + (replace-regexp-in-string "^\/[^A-Z]*" "" + (car (last (split-string name "src"))))) + (file-name-nondirectory name))))`} + ( + ) where +-------------------------------------------------------------------------------- +import Prelude +-------------------------------------------------------------------------------- + +$0 diff --git a/users/aspen/emacs/snippets/haskell-mode/shut up, hlint b/users/aspen/emacs/snippets/haskell-mode/shut up, hlint new file mode 100644 index 0000000000..fccff1d66f --- /dev/null +++ b/users/aspen/emacs/snippets/haskell-mode/shut up, hlint @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: shut up, hlint +# key: dupl +# expand-env: ((yas-indent-line 'fixed)) +# -- +{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-} \ No newline at end of file diff --git a/users/aspen/emacs/snippets/haskell-mode/test-group b/users/aspen/emacs/snippets/haskell-mode/test-group new file mode 100644 index 0000000000..bf6a66f8a3 --- /dev/null +++ b/users/aspen/emacs/snippets/haskell-mode/test-group @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# name: test-group +# uuid: test-group +# key: testGroup +# condition: t +# -- +testGroup "${1:name}" +[ $0 +] \ No newline at end of file diff --git a/users/aspen/emacs/snippets/haskell-mode/test-module b/users/aspen/emacs/snippets/haskell-mode/test-module new file mode 100644 index 0000000000..036b0ae998 --- /dev/null +++ b/users/aspen/emacs/snippets/haskell-mode/test-module @@ -0,0 +1,27 @@ +# -*- mode: snippet -*- +# name: test-module +# key: test +# expand-env: ((yas-indent-line 'fixed)) +# -- +-------------------------------------------------------------------------------- +module ${1:`(if (not buffer-file-name) "Module" + (let ((name (file-name-sans-extension (buffer-file-name))) + (case-fold-search nil)) + (if (cl-search "test/" name) + (replace-regexp-in-string "/" "." + (replace-regexp-in-string "^\/[^A-Z]*" "" + (car (last (split-string name "src"))))) + (file-name-nondirectory name))))`} (main, test) where +-------------------------------------------------------------------------------- +import Test.Prelude +-------------------------------------------------------------------------------- +import ${1:$(s-chop-suffix "Spec" yas-text)} +-------------------------------------------------------------------------------- + +main :: IO () +main = defaultMain test + +test :: TestTree +test = testGroup "$1" + [ $0 + ] \ No newline at end of file diff --git a/users/aspen/emacs/snippets/haskell-mode/undefined b/users/aspen/emacs/snippets/haskell-mode/undefined new file mode 100644 index 0000000000..7bcd99b571 --- /dev/null +++ b/users/aspen/emacs/snippets/haskell-mode/undefined @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: undefined +# key: u +# expand-env: ((yas-indent-line 'fixed) (yas-wrap-around-region 'nil)) +# -- +undefined$1 \ No newline at end of file diff --git a/users/aspen/emacs/snippets/js2-mode/action-type b/users/aspen/emacs/snippets/js2-mode/action-type new file mode 100644 index 0000000000..ef8d1a3863 --- /dev/null +++ b/users/aspen/emacs/snippets/js2-mode/action-type @@ -0,0 +1,4 @@ +# key: at +# name: action-type +# -- +export const ${1:FOO_BAR$(->> yas-text s-upcase (s-replace-all '(("-" . "_") (" " . "_"))))}: '${3:ns}/${1:$(-> yas-text s-dashed-words)}' = '$3/${1:$(-> yas-text s-dashed-words)}'$5 \ No newline at end of file diff --git a/users/aspen/emacs/snippets/js2-mode/before b/users/aspen/emacs/snippets/js2-mode/before new file mode 100644 index 0000000000..4569b65831 --- /dev/null +++ b/users/aspen/emacs/snippets/js2-mode/before @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: before +# key: bef +# -- +before(function() { + $1 +}) diff --git a/users/aspen/emacs/snippets/js2-mode/context b/users/aspen/emacs/snippets/js2-mode/context new file mode 100644 index 0000000000..d83809f3c3 --- /dev/null +++ b/users/aspen/emacs/snippets/js2-mode/context @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: context +# key: context +# -- +context('$1', function() { + $2 +}) diff --git a/users/aspen/emacs/snippets/js2-mode/describe b/users/aspen/emacs/snippets/js2-mode/describe new file mode 100644 index 0000000000..bd0198181d --- /dev/null +++ b/users/aspen/emacs/snippets/js2-mode/describe @@ -0,0 +1,6 @@ +# key: desc +# name: describe +# -- +describe('$1', () => { + $2 +}) \ No newline at end of file diff --git a/users/aspen/emacs/snippets/js2-mode/expect b/users/aspen/emacs/snippets/js2-mode/expect new file mode 100644 index 0000000000..eba41ef330 --- /dev/null +++ b/users/aspen/emacs/snippets/js2-mode/expect @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: expect +# key: ex +# -- +expect($1).$2 \ No newline at end of file diff --git a/users/aspen/emacs/snippets/js2-mode/function b/users/aspen/emacs/snippets/js2-mode/function new file mode 100644 index 0000000000..b423044b44 --- /dev/null +++ b/users/aspen/emacs/snippets/js2-mode/function @@ -0,0 +1,6 @@ +# key: f +# name: function +# -- +function $1($2) { + $3 +} \ No newline at end of file diff --git a/users/aspen/emacs/snippets/js2-mode/header b/users/aspen/emacs/snippets/js2-mode/header new file mode 100644 index 0000000000..3e303764cb --- /dev/null +++ b/users/aspen/emacs/snippets/js2-mode/header @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: header +# key: hh +# expand-env: ((yas-indent-line 'fixed)) +# -- +//////////////////////////////////////////////////////////////////////////////// diff --git a/users/aspen/emacs/snippets/js2-mode/it b/users/aspen/emacs/snippets/js2-mode/it new file mode 100644 index 0000000000..a451cfc08a --- /dev/null +++ b/users/aspen/emacs/snippets/js2-mode/it @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: it +# key: it +# -- +it('$1', () => { + $2 +}) \ No newline at end of file diff --git a/users/aspen/emacs/snippets/js2-mode/it-pending b/users/aspen/emacs/snippets/js2-mode/it-pending new file mode 100644 index 0000000000..00da312e10 --- /dev/null +++ b/users/aspen/emacs/snippets/js2-mode/it-pending @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: it-pending +# key: xi +# -- +it('$1')$0 \ No newline at end of file diff --git a/users/aspen/emacs/snippets/js2-mode/module b/users/aspen/emacs/snippets/js2-mode/module new file mode 100644 index 0000000000..dc79819d89 --- /dev/null +++ b/users/aspen/emacs/snippets/js2-mode/module @@ -0,0 +1,12 @@ +# key: module +# name: module +# expand-env: ((yas-indent-line (quote fixed))) +# condition: (= (length "module") (current-column)) +# -- +/** + * @fileOverview $1 + * @name ${2:`(file-name-nondirectory (buffer-file-name))`} + * @author Griffin Smith + * @license Proprietary + */ +$3 \ No newline at end of file diff --git a/users/aspen/emacs/snippets/js2-mode/record b/users/aspen/emacs/snippets/js2-mode/record new file mode 100644 index 0000000000..0bb0f02436 --- /dev/null +++ b/users/aspen/emacs/snippets/js2-mode/record @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: record +# key: rec +# -- +export default class $1 extends Record({ + $2 +}) {} \ No newline at end of file diff --git a/users/aspen/emacs/snippets/js2-mode/test b/users/aspen/emacs/snippets/js2-mode/test new file mode 100644 index 0000000000..938d490a74 --- /dev/null +++ b/users/aspen/emacs/snippets/js2-mode/test @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: test +# key: test +# -- +test('$1', () => { + $2 +}) \ No newline at end of file diff --git a/users/aspen/emacs/snippets/nix-mode/fetchFromGitHub b/users/aspen/emacs/snippets/nix-mode/fetchFromGitHub new file mode 100644 index 0000000000..d2447e4b5a --- /dev/null +++ b/users/aspen/emacs/snippets/nix-mode/fetchFromGitHub @@ -0,0 +1,12 @@ +# -*- mode: snippet -*- +# name: fetchFromGitHub +# uuid: fetchFromGitHub +# key: fetchFromGitHub +# condition: t +# -- +fetchFromGitHub { + owner = "$1"; + repo = "$2"; + rev = "$3"; + sha256 = "0000000000000000000000000000000000000000000000000000"; +} \ No newline at end of file diff --git a/users/aspen/emacs/snippets/nix-mode/pythonPackage b/users/aspen/emacs/snippets/nix-mode/pythonPackage new file mode 100644 index 0000000000..0a74c21e18 --- /dev/null +++ b/users/aspen/emacs/snippets/nix-mode/pythonPackage @@ -0,0 +1,16 @@ +# key: pypkg +# name: pythonPackage +# condition: t +# -- +${1:pname} = buildPythonPackage rec { + name = "\${pname}-\${version}"; + pname = "$1"; + version = "${2:1.0.0}"; + src = fetchPypi { + inherit pname version; + sha256 = "0000000000000000000000000000000000000000000000000000"; + }; + propagatedBuildInputs = with pythonSelf; [ + $3 + ]; +}; \ No newline at end of file diff --git a/users/aspen/emacs/snippets/nix-mode/sha256 b/users/aspen/emacs/snippets/nix-mode/sha256 new file mode 100644 index 0000000000..bc640e5ab0 --- /dev/null +++ b/users/aspen/emacs/snippets/nix-mode/sha256 @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: sha256 +# uuid: sha256 +# key: sha256 +# condition: t +# -- +sha256 = "0000000000000000000000000000000000000000000000000000"; \ No newline at end of file diff --git a/users/aspen/emacs/snippets/org-mode/SQL source block b/users/aspen/emacs/snippets/org-mode/SQL source block new file mode 100644 index 0000000000..b5d43fd6bc --- /dev/null +++ b/users/aspen/emacs/snippets/org-mode/SQL source block @@ -0,0 +1,6 @@ +# key: sql +# name: SQL source block +# -- +#+BEGIN_SRC sql ${1::async} +$2 +#+END_SRC diff --git a/users/aspen/emacs/snippets/org-mode/combat b/users/aspen/emacs/snippets/org-mode/combat new file mode 100644 index 0000000000..b4db0f433a --- /dev/null +++ b/users/aspen/emacs/snippets/org-mode/combat @@ -0,0 +1,13 @@ +# -*- mode: snippet -*- +# name: combat +# uuid: combat +# key: combat +# condition: t +# -- +| | initiative | max hp | current hp | status | | +|-------------+------------+--------+------------+--------+------| +| Barty Barty | | | | | <--- | +| Hectoroth | | | | | | +| Xanadu | | | | | | +| Aurora | | | | | | +| EFB | | | | | | \ No newline at end of file diff --git a/users/aspen/emacs/snippets/org-mode/date b/users/aspen/emacs/snippets/org-mode/date new file mode 100644 index 0000000000..297529cdac --- /dev/null +++ b/users/aspen/emacs/snippets/org-mode/date @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# key: date +# name: date.org +# -- +[`(format-time-string "%Y-%m-%d")`]$0 diff --git a/users/aspen/emacs/snippets/org-mode/date-time b/users/aspen/emacs/snippets/org-mode/date-time new file mode 100644 index 0000000000..fde469276c --- /dev/null +++ b/users/aspen/emacs/snippets/org-mode/date-time @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: date-time +# key: dt +# -- +[`(format-time-string "%Y-%m-%d %H:%m:%S")`] \ No newline at end of file diff --git a/users/aspen/emacs/snippets/org-mode/description b/users/aspen/emacs/snippets/org-mode/description new file mode 100644 index 0000000000..a43bc95cc3 --- /dev/null +++ b/users/aspen/emacs/snippets/org-mode/description @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: description +# key: desc +# -- +:DESCRIPTION: +$1 +:END: diff --git a/users/aspen/emacs/snippets/org-mode/nologdone b/users/aspen/emacs/snippets/org-mode/nologdone new file mode 100644 index 0000000000..e5be85d6b3 --- /dev/null +++ b/users/aspen/emacs/snippets/org-mode/nologdone @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: nologdone +# key: nologdone +# -- +#+STARTUP: nologdone$0 \ No newline at end of file diff --git a/users/aspen/emacs/snippets/org-mode/python source block b/users/aspen/emacs/snippets/org-mode/python source block new file mode 100644 index 0000000000..247ae51b0b --- /dev/null +++ b/users/aspen/emacs/snippets/org-mode/python source block @@ -0,0 +1,6 @@ +# key: py +# name: Python source block +# -- +#+BEGIN_SRC python +$0 +#+END_SRC \ No newline at end of file diff --git a/users/aspen/emacs/snippets/org-mode/reveal b/users/aspen/emacs/snippets/org-mode/reveal new file mode 100644 index 0000000000..1bdbdfa5dc --- /dev/null +++ b/users/aspen/emacs/snippets/org-mode/reveal @@ -0,0 +1,6 @@ +# key: reveal +# name: reveal +# condition: t +# -- +#+ATTR_REVEAL: :frag ${1:roll-in} +$0 \ No newline at end of file diff --git a/users/aspen/emacs/snippets/org-mode/transaction b/users/aspen/emacs/snippets/org-mode/transaction new file mode 100644 index 0000000000..37f2dd31ca --- /dev/null +++ b/users/aspen/emacs/snippets/org-mode/transaction @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: transaction +# key: begin +# -- +BEGIN; +$0 +ROLLBACK; \ No newline at end of file diff --git a/users/aspen/emacs/snippets/prolog-mode/tests b/users/aspen/emacs/snippets/prolog-mode/tests new file mode 100644 index 0000000000..a9d92a0d5b --- /dev/null +++ b/users/aspen/emacs/snippets/prolog-mode/tests @@ -0,0 +1,11 @@ +# -*- mode: snippet -*- +# name: tests +# uuid: tests +# key: tests +# condition: t +# -- +:- begin_tests(${1:name}). + +$0 + +:- end_tests($1). \ No newline at end of file diff --git a/users/aspen/emacs/snippets/prolog-mode/use-module b/users/aspen/emacs/snippets/prolog-mode/use-module new file mode 100644 index 0000000000..75fd19b641 --- /dev/null +++ b/users/aspen/emacs/snippets/prolog-mode/use-module @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: use-module +# uuid: use-module +# key: use +# condition: t +# -- +:- use_module(${1:library($2)}${3:, [$4]}). \ No newline at end of file diff --git a/users/aspen/emacs/snippets/python-mode/add_column b/users/aspen/emacs/snippets/python-mode/add_column new file mode 100644 index 0000000000..47e83850d5 --- /dev/null +++ b/users/aspen/emacs/snippets/python-mode/add_column @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: add_column +# key: op.add_column +# -- +op.add_column('${1:table}', sa.Column('${2:name}', sa.${3:String()}))$0 diff --git a/users/aspen/emacs/snippets/python-mode/decorate b/users/aspen/emacs/snippets/python-mode/decorate new file mode 100644 index 0000000000..4f96748572 --- /dev/null +++ b/users/aspen/emacs/snippets/python-mode/decorate @@ -0,0 +1,15 @@ +# -*- mode: snippet -*- +# name: decorate +# uuid: decorate +# key: decorate +# condition: t +# -- +def wrap(inner): + @wraps(inner) + def wrapped(*args, **kwargs): + ret = inner(*args, **kwargs) + return ret + + return wrapped + +return wrap \ No newline at end of file diff --git a/users/aspen/emacs/snippets/python-mode/dunder b/users/aspen/emacs/snippets/python-mode/dunder new file mode 100644 index 0000000000..71d99dddc6 --- /dev/null +++ b/users/aspen/emacs/snippets/python-mode/dunder @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: dunder +# uuid: dunder +# key: du +# condition: t +# -- +__$1__$0 \ No newline at end of file diff --git a/users/aspen/emacs/snippets/python-mode/name b/users/aspen/emacs/snippets/python-mode/name new file mode 100644 index 0000000000..1495cc91d9 --- /dev/null +++ b/users/aspen/emacs/snippets/python-mode/name @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: name +# uuid: name +# key: name +# condition: t +# -- +__name__ \ No newline at end of file diff --git a/users/aspen/emacs/snippets/python-mode/op.get_bind.execute b/users/aspen/emacs/snippets/python-mode/op.get_bind.execute new file mode 100644 index 0000000000..aba801c6ba --- /dev/null +++ b/users/aspen/emacs/snippets/python-mode/op.get_bind.execute @@ -0,0 +1,7 @@ +# key: exec +# name: op.get_bind.execute +# -- +op.get_bind().execute( + """ + `(progn (sqlup-mode) "")`$1 + """) diff --git a/users/aspen/emacs/snippets/python-mode/pdb b/users/aspen/emacs/snippets/python-mode/pdb new file mode 100644 index 0000000000..41c6f87cbf --- /dev/null +++ b/users/aspen/emacs/snippets/python-mode/pdb @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: pdb +# uuid: pdb +# key: pdb +# condition: t +# -- +import pdb; pdb.set_trace() \ No newline at end of file diff --git a/users/aspen/emacs/snippets/rust-mode/#[macro_use] b/users/aspen/emacs/snippets/rust-mode/#[macro_use] new file mode 100644 index 0000000000..fea942a337 --- /dev/null +++ b/users/aspen/emacs/snippets/rust-mode/#[macro_use] @@ -0,0 +1,5 @@ +# key: macro_use +# name: #[macro_use] +# -- +#[macro_use] +${1:extern crate} ${2:something};$0 diff --git a/users/aspen/emacs/snippets/rust-mode/async test b/users/aspen/emacs/snippets/rust-mode/async test new file mode 100644 index 0000000000..2352d7b56b --- /dev/null +++ b/users/aspen/emacs/snippets/rust-mode/async test @@ -0,0 +1,10 @@ +# -*- mode: snippet -*- +# name: async test +# uuid: atest +# key: atest +# condition: t +# -- +#[tokio::test${1:(flavor = "multi_thread")}] +async fn ${2:test_name}() { + `%`$0 +} \ No newline at end of file diff --git a/users/aspen/emacs/snippets/rust-mode/benchmark b/users/aspen/emacs/snippets/rust-mode/benchmark new file mode 100644 index 0000000000..9ec4307538 --- /dev/null +++ b/users/aspen/emacs/snippets/rust-mode/benchmark @@ -0,0 +1,10 @@ +# -*- mode: snippet -*- +# name: benchmark +# uuid: benchmark +# key: bench +# condition: t +# -- +#[bench] +fn ${1:benchmark_name}(b: &mut Bencher) { + `%`b.iter(|| $0); +} \ No newline at end of file diff --git a/users/aspen/emacs/snippets/rust-mode/proptest b/users/aspen/emacs/snippets/rust-mode/proptest new file mode 100644 index 0000000000..be12af4911 --- /dev/null +++ b/users/aspen/emacs/snippets/rust-mode/proptest @@ -0,0 +1,10 @@ +# -*- mode: snippet -*- +# name: proptest +# uuid: proptest +# key: proptest +# condition: t +# -- +#[proptest] +fn ${1:test_name}($2) { + `%`$0 +} \ No newline at end of file diff --git a/users/aspen/emacs/snippets/rust-mode/test-module b/users/aspen/emacs/snippets/rust-mode/test-module new file mode 100644 index 0000000000..bfa2ca2d18 --- /dev/null +++ b/users/aspen/emacs/snippets/rust-mode/test-module @@ -0,0 +1,11 @@ +# -*- mode: snippet -*- +# name: test-module +# uuid: test-module +# key: tmod +# condition: t +# -- +mod $1 { + use super::*; + + $0 +} \ No newline at end of file diff --git a/users/aspen/emacs/snippets/rust-mode/tests b/users/aspen/emacs/snippets/rust-mode/tests new file mode 100644 index 0000000000..0a476ab586 --- /dev/null +++ b/users/aspen/emacs/snippets/rust-mode/tests @@ -0,0 +1,9 @@ +# key: tests +# name: test module +# -- +#[cfg(test)] +mod ${1:tests} { + use super::*; + + $0 +} diff --git a/users/aspen/emacs/snippets/snippet-mode/indent b/users/aspen/emacs/snippets/snippet-mode/indent new file mode 100644 index 0000000000..d38ffceafb --- /dev/null +++ b/users/aspen/emacs/snippets/snippet-mode/indent @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: indent +# key: indent +# -- +# expand-env: ((yas-indent-line 'fixed)) \ No newline at end of file diff --git a/users/aspen/emacs/snippets/sql-mode/count(*) group by b/users/aspen/emacs/snippets/sql-mode/count(*) group by new file mode 100644 index 0000000000..6acc46ff39 --- /dev/null +++ b/users/aspen/emacs/snippets/sql-mode/count(*) group by @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: count(*) group by +# key: countby +# -- +SELECT count(*), ${1:column} FROM ${2:table} GROUP BY $1; diff --git a/users/aspen/emacs/snippets/terraform-mode/variable b/users/aspen/emacs/snippets/terraform-mode/variable new file mode 100644 index 0000000000..14822f1a05 --- /dev/null +++ b/users/aspen/emacs/snippets/terraform-mode/variable @@ -0,0 +1,11 @@ +# -*- mode: snippet -*- +# name: variable +# uuid: variable +# key: var +# condition: t +# -- +variable "${1:name}" { + type = ${2:string} + ${3:default = ${4:default}} +} +$0 \ No newline at end of file diff --git a/users/aspen/emacs/snippets/text-mode/date b/users/aspen/emacs/snippets/text-mode/date new file mode 100644 index 0000000000..7b94311470 --- /dev/null +++ b/users/aspen/emacs/snippets/text-mode/date @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# name: date +# key: date +# -- +`(format-time-string "%Y-%m-%d")`$0 \ No newline at end of file diff --git a/users/aspen/emacs/snippets/tuareg-mode/expect-test b/users/aspen/emacs/snippets/tuareg-mode/expect-test new file mode 100644 index 0000000000..e0b541fce4 --- /dev/null +++ b/users/aspen/emacs/snippets/tuareg-mode/expect-test @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# name: expect-test +# uuid: expect-test +# key: exp +# condition: t +# -- +let%expect_test "${1:name}" = + ${2:}; + [%expect {| $3 |}] \ No newline at end of file diff --git a/users/aspen/emacs/snippets/tuareg-mode/module b/users/aspen/emacs/snippets/tuareg-mode/module new file mode 100644 index 0000000000..9b1701e3a2 --- /dev/null +++ b/users/aspen/emacs/snippets/tuareg-mode/module @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# name: module +# uuid: module +# key: mod +# condition: t +# -- +module ${1:Name} = struct + $0 +end \ No newline at end of file diff --git a/users/aspen/emacs/snippets/tuareg-mode/test-module b/users/aspen/emacs/snippets/tuareg-mode/test-module new file mode 100644 index 0000000000..b16176e5f3 --- /dev/null +++ b/users/aspen/emacs/snippets/tuareg-mode/test-module @@ -0,0 +1,10 @@ +# -*- mode: snippet -*- +# name: test-module +# uuid: test-module +# key: tmod +# condition: t +# -- +let%test_module ${1:_} = + (module struct + $0 + end) \ No newline at end of file -- cgit 1.4.1