Last active
December 19, 2015 14:29
-
-
Save jordonbiondo/5970019 to your computer and use it in GitHub Desktop.
Temp-latte-mode
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;--------------------------------------------------------------------------- | |
;; Temp-Lattes: | |
;; abbrev-mode replacement | |
;;--------------------------------------------------------------------------- | |
;;--------------------------------------------------------------------------- | |
;; Recipe Examples | |
;;--------------------------------------------------------------------------- | |
(tl/define-recipe "lm" emacs-lisp-mode | |
(backward-delete-char (length tl/key)) | |
(insert "(lambda ())") | |
(backward-char 2) | |
(indent-according-to-mode)) | |
(tl/define-recipe "df" emacs-lisp-mode | |
(let ((sp (point-at-bol))) | |
(backward-delete-char (length tl/key)) | |
(insert "(defun ()\n\"\"\n)") | |
(indent-region sp (point)) | |
(search-backward "("))) | |
;;--------------------------------------------------------------------------- | |
;; Temp-latte-mode | |
;;--------------------------------------------------------------------------- | |
(defvar tl/keymap (let ((tl-km (make-sparse-keymap))) | |
(define-key tl-km (kbd "M-SPC") 'tl/brew) | |
tl-km) | |
"Keymap for temp-latte-mode.") | |
(define-minor-mode temp-latte-mode | |
"A minor mode for very similar to abbrev-mode, but offers a little more control | |
over expansion. see `tl/define-recipe' for useage information. | |
Default Bindings: | |
\tM-SPC:\t tl/brew" | |
:init-value nil | |
:lighter " latte" | |
:global t | |
:keymap tl/keymap) | |
(defvar tl/recipe-book (make-hash-table :test 'equal) | |
"Temp-latte recipe table. | |
A recipe is a string/lambda pair.") | |
(defvar tl/recipe-modes (make-hash-table :test 'equal) | |
"Temp-latte mode table. | |
A recipe-mode is a string/major-mode pair specifying the major mode in which | |
the recipe will be active.") | |
(defmacro tl/define-recipe (str mode &rest body) | |
"Define a new template recipe that will expand from the key STR when in MODE. | |
MODE is an unquoted name of a major mode in which the recipe will be active, if nil, | |
the recipe will be active in all major modes. | |
BODY may be a function body that will be executed when the key is expanded or a | |
string that will replace the key at brew time. | |
Example: | |
The following creates a recipe for lm in emacs-lisp-mode. when expanded | |
lm becomes (lambda()) and the cursor is moved into the argument parenthesis. | |
In the definition, the variable tl/key will be set to the recipe key, in this case tl/key | |
is \"lm\" | |
(tl/define-recipe \"lm\" emacs-lisp-mode | |
(backward-delete-char (length tl/key)) | |
(insert \"(lambda ())\") | |
(backward-char 2) | |
(indent-according-to-mode))" | |
(declare (indent defun)) | |
(if (not (stringp str)) (signal 'wrong-type-argument str)) | |
(if (and (= (length body) 1) (stringp (first body))) | |
`(progn (puthash ,str (lambda (tl/key) | |
(delete-char ,(- (length str))) | |
(insert ,(first body))) ,(quote tl/recipe-book)) | |
(puthash ,str (quote ,mode) ,(quote tl/recipe-modes))) | |
`(progn (puthash ,str (lambda (tl/key) ,@body) ,(quote tl/recipe-book)) | |
(puthash ,str (quote ,mode) ,(quote tl/recipe-modes))))) | |
(defun tl/dump-recipe (str) | |
"Remove the recipe definition from `tl/recipe-book' with a key of STR." | |
(remhash str tl/recipe-modes) | |
(remhash str tl/recipe-book)) | |
(defun tl/craft-recipe (key) | |
"Attempt to brew a latte with a recipe key of WORD. | |
If there is no such recipe, print an message saying so." | |
(let ((action (gethash key tl/recipe-book)) | |
(action-mode (gethash key tl/recipe-modes))) | |
(if (and action (or (not action-mode) (equal action-mode major-mode))) | |
(apply action (list key)) | |
(tl/no-recipe (current-word))))) | |
(defun tl/brew () | |
"Brew a latte from the recipe key at point. | |
The point needs to be at the end of the key text" | |
(interactive) | |
(if (looking-at "\\>") (tl/craft-recipe (current-word)) | |
(tl/no-key))) | |
(defun tl/no-recipe(key) | |
"Prints a no recipe found error message for KEY." | |
(princ (format "no recipe found for \"%s\"" key))) | |
(defun tl/no-key() | |
"Prints a no recipe key message.." | |
(princ "no recipe key at point, must be at the end of a recipe key")) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment