The YASnippet package for Emacs has some pretty awesome power for the developer, especially when you utilize the power of Emacs Lisp.
YASnippet was inspired by TextMate, which was inspired by Emacs, in a highly-out-of-equilibrium whirlwind of self-referential creativity.
The screencast above uses a set of snippets I originally took from this WordPress TextMate bundle, created by Shawn Parker and Gordon Brander
The first snippet in the screencast illustrates YASnippet’s mirrors with transformation, in a WordPress plugin template. The snippet calls Emacs Lisp functions as the plugin name is filled in to create the plugin URI, the “namespace” (used here as a prefix for function and variable names), and the primary class name for the plugin.
The second snippet writes a function skeleton, then calls Emacs Lisp at the end to move the generated function outside the current scope into a correct position in the file. This snippet uses YASnippet’s fields with transformations syntax, but to do a sneaky thing: not transform the field, but move a region of generated text!
Following is the code for the snippets shown in the screencast, with no commentary. So pipe up in the comments if you’re curious about how something works!
# -*- mode: snippet -*- # name: WP Plugin # key: plugin # -- /* Plugin Name: ${1:Plugin Name} Plugin URI: http://${2:dynapse.com/plugins/}${1:$(gjg/sanitize text)}/ Description: ${3:Description} Version: ${4:1.0} Author: ${5:Gregory Grubbs} Author URI: http://${6:gregorygrubbs.com/} Namespace: ${1:$(gjg/acronyminize text)}_ */ class ${1:$(gjg/whitespace-to-underscore text)} { /** * constructor for $1 * * The constructor is responsible for registering all hooks used * by this class as as WordPress plugin */ function __construct() { $0 } // constructor } $${1:$(gjg/acronyminize text)} = new ${1:$(gjg/whitespace-to-underscore text)}();
Next, the add_action snippet, which moves a generated function at the end:
# -*- mode: snippet -*- # name: add_action # key: add_action # -- add_action('${1:init}', array($this, 'my_${2:$1}')); ${3:$$(gjg/move-next-sexp-past-current-scope)} function my_$1 () { }
And finally, (some of) the Emacs Lisp functions that the snippets call:
(defun gjg/acronyminize (text &optional do-capitalize) "Make an acronym from the text do-capitalize: t means run text through capitalize function, nil will respect CamelCase " (save-excursion (setq case-fold-search nil) (downcase (replace-regexp-in-string "[^A-Z]" "" (if do-capitalize (capitalize text) text) nil t)))) (defun gjg/move-next-sexp-past-current-scope () "kill sexp following point, move past current scope/sexp/function" (beginning-of-line) (let ((beg (point))) (re-search-forward "^[ \t]*function[ \t]+[^}]+?}" (point-max) nil) (mark-defun) (kill-region (point) (mark))) (forward-line) (yank) (indent-region (mark) (point)))



