The TextMate Super Function (AS3/PHP)

Following my obsession with TextMate snippets and commands, I created a function snippet which extended the basic function and added a few new useful features. This snippet is mapped to Shift + Enter. Just type the name of your function...

myFunction

and hit Shift + Enter after it. The following snippet is inserted:

/**
 *
 *
 * @return
 */
public function myFunction()
{

}

The first tab stop is inside the parentheses so you can add some parameters, hit tab again to focus on the scope (public). We use a simple regular expression here to add "_" or "__" to the method name depending on if you type public|private|protected. The rest of the tabs go through the return statement, docblock and finally end inside the function declaration.

I've got both an AS3 and PHP version. Starting with the PHP version:

cat <<SNIPPET
/**
 * $4
 *
 * @return $3
 */
${2:public} function ${2/(private)|(protected)|(.+)/(?1:__)(?2:_)(?3:)/}${TM_SELECTED_TEXT:-$TM_CURRENT_WORD}($1)
{
	$0
}
SNIPPET

And the AS3 version is basically the same with just a return type defined:

cat <<SNIPPET
/**
 * $4
 *
 * @return ${5:$2}
 */
${3:public} function ${3/(private)|(protected)|(.+)/(?1:__)(?2:_)(?3:)/}${TM_SELECTED_TEXT:-$TM_CURRENT_WORD}($1):${2:void}
{
	$0${2/void$|(.+)/(?1:return null;)/}
}
SNIPPET

I'd also like to eventually add @param docs to the docblock as you type out parameters. Would love some suggestions there.

You can download both the PHP and AS3 Function Commands here. You can also download my TextMate theme Plum Dumb, or—if you're into PureMVC—you can download my PureMVC TextMate templates.

December 29th, 2010 | Permalink

Reducing CSS/Javascript Requests and File Size with Ant and YUI

With continuing reliance on front-end Javascript plugins and CSS, it's important to keep HTTP requests and file sizes smaller to reduce page load times. On this site, we use jQuery, jQuery Address, a custom application Javascript include, and other plugins. We also use a master CSS file as well as a reset file and other CSS additions for things like @media queries and the like. We can reduce all these file requests to one or two requests by combining them all into one file and minifying them.

We can use a compression tool such as YUI Compressor to handle the minifying, but actually doing the work to compile all those files together and run them through the compressor can be a time-consuming task to perform manually. It'd be great if we had a tool to do that for us. Enter Apache Ant.

Ant is a java-based build automation tool. It can be used to perform a variety of tasks and is ideally suited for building files for web applications. If you're on Mac OS X, Ant comes pre-installed (1.7.x on 10.5 and 1.8.x on 10.6). For other systems, check out the easy instructions here. YUI is a simple download and extraction from here.

All we need for a basic Ant task is a build file. Create a "build.xml" file in the root of your application. To start, you just need some basic markup. I added a property that contains the path to the YUI Compressor .jar file.

<?xml version="1.0" encoding="UTF-8"?>

<!-- project name, default target and base directory -->
<project name="typeoneerror" default="init" basedir=".">

    <!-- path to YUI Compressor -->
    <property name="yuic" location="/Users/typeoneerror/bin/yuicompressor-2.4.2/build/yuicompressor-2.4.2.jar"/>

    <!-- path to build resources -->
    <property name="css" location="public/css"/>
    <property name="js" location="public/js"/>
    <property name="ui_css" location="public/ui/css"/>
    <property name="ui_js" location="public/ui/js"/>

    <!-- default target -->
    <target name="init"/>
</project>

This defines our project build with a default target (one of the actions that will run when we build) called "init". Also, we've defined some properties (paths to YUI and to our CSS and Javascript folder) that we'll use later.

Next, create the first target:

<!--concatenate javascript-->
<target name="concat.js" description="Stick all the JS together">
     <concat destfile="build/application.js">
        <!-- first concat all the files in the /ui/js directory -->
        <filelist dir="${ui_js}" files="jquery.min.js,jquery.address.min.js"/>
        <!-- then add our application js file -->
        <filelist dir="${js}" files="application.js"/>
    </concat>
</target>

This target uses the concat process to concatenate a list of javascript files into a destfile (destination file) build/application.js. This combines everything we're using into one file. The next target will use that file and minify it:

<!--minify javascript-->
<target name="minify.js" depends="concat.js" description="Minify JavaScript using YUI Compressor">
    <apply executable="java" parallel="false">
        <!-- look for any javascript files in the build dir -->
        <fileset dir="build" includes="*.js"/>
        <!-- pass arguments to the yui program -->
        <arg line="-jar"/>
        <arg path="${yuic}"/>
        <srcfile/>
        <!-- output minified files to our js dir with .min.js extenstion -->
        <arg line="-o"/>
        <mapper type="glob" from="*.js" to="${js}/*.min.js"/>
        <targetfile/>
    </apply>
</target>

The depends property defines actions that need to be performed before running the target. Add the minify.js target to the depends property of our default action:

<target name="init" depends="minify.js"/>

When we run the build, init will be run and then minify.js. Of course, concat.js will be run before minify.js since minify.js depends on it.

We add another two targets to concat and minify our CSS. Add another target to the list of targets in the init target. Our final build file looks something like this:

<?xml version="1.0" encoding="UTF-8"?>

<!-- project name, default target and base directory -->
<project name="typeoneerror" default="init" basedir=".">

    <!-- path to YUI Compressor -->
    <property name="yuic" location="/Users/typeoneerror/bin/yuicompressor-2.4.2/build/yuicompressor-2.4.2.jar"/>

    <!-- path to build resources -->
    <property name="css" location="public/css"/>
    <property name="js" location="public/js"/>
    <property name="ui_css" location="public/ui/css"/>
    <property name="ui_js" location="public/ui/js"/>

    <!-- default target -->
    <target name="init" depends="minify.js,minify.css"/>

    <!--concatenate javascript-->
    <target name="concat.js" description="Stick all the JS together">
         <concat destfile="build/application.js">
            <!-- first concat all the files in the /ui/js directory -->
            <filelist dir="${ui_js}" files="jquery.min.js,jquery.address.min.js"/>
            <!-- then add our application js file -->
            <filelist dir="${js}" files="application.js"/>
        </concat>
    </target>

    <!--minify javascript-->
    <target name="minify.js" depends="concat.js" description="Minify JavaScript using YUI Compressor">
        <apply executable="java" parallel="false">
            <!-- look for any javascript files in the build dir -->
            <fileset dir="build" includes="*.js"/>
            <!-- pass arguments to the yui program -->
            <arg line="-jar"/>
            <arg path="${yuic}"/>
            <srcfile/>
            <!-- output minified files to our js dir with .min.js extenstion -->
            <arg line="-o"/>
            <mapper type="glob" from="*.js" to="${js}/*.min.js"/>
            <targetfile/>
        </apply>
    </target>

    <!--concatenate css-->
    <target name="concat.css" description="Stick all the CSS together">
         <concat destfile="build/core.css">
            <filelist dir="${ui_css}" files="reset.min.css"/>
            <filelist dir="${css}" files="screen.css,additions.css"/>
        </concat>
    </target>

    <!--minify concatenated css-->
    <target name="minify.css" depends="concat.css" description="Minify CSS using YUI Compressor">
        <apply executable="java" parallel="false">
            <fileset dir="build" includes="*.css"/>
            <arg line="-jar"/>
            <arg path="${yuic}"/>
            <srcfile/>
            <arg line="-o"/>
            <mapper type="glob" from="*.css" to="${css}/*.min.css"/>
            <targetfile/>
        </apply>
    </target>
</project>

Running an Ant build file is as simple as shelling into the directory via your Terminal or command line interface and entering ant. It automatically looks for a file called "build.xml". You can also grab Simon Gregory's Ant TextMate Bundle if you want to just hit Cmd+R to build in your TextMate project (awesome).

December 20th, 2010 | Permalink

Ignoring Files in TextMate's TODO Plugin

Lately, as I’ve been working on a huge Zend Framework library for rapid website development and content management, as well as the second version of my ASRA framework, I’ve been very into using Soryu’s TextMate TODO plugin. Trouble is, when you have the entire Zend library in your project (or any other huge library), you’re bound to have a ton of todo’s in your list that you don’t really “care” about.

Anyway, I just learned a super easy way to speed up and make things easier to maintain. Simply open the TextMate preferences menu and go to Advanced > Shell Variables. Add a new entry called TM_TODO_IGNORE and give it a value of Zend* (or even just Zend should work). The TM_TODO_IGNORE value just specifies a regular expression for files paths to ignore within your project, so basically this just ignores everything in the Zend library. Yay! Concise to-do list!

August 21st, 2009 | Permalink

@see TextMate Snippet

I've been doing a ton of work with the newest Zend Framework version 1.8.2 this weekend. I've found that typing out all the requires for each class can be a pain, so I made a quick TextMate snippet to make adding @see directives for phpdoc at the same time as the require_once directive. Here it is; simple but useful:

/**
 * @see $1
 */
require_once "${1/_///g}.php";$0

Add this as a "Tab Trigger" for the word "see" then just type "see" and hit tab then type your class name. It will auto fill the comment and the path to the pear-conventionally-named .php file. Got any other useful TextMate snippets? Please do share!

June 6th, 2009 | Permalink

Custom Key Bindings in XCode for TextMate Users

I’ve recently been getting doing some development in XCode and Interface Builder (learning the iPhone SDK). I found XCode a real pleasure to work with (especially its unique form of “Code Sense”), but I did miss some of TextMate’s default text shortcuts, specifically “delete line” and “duplicate line.” There are some Key Binding options in the Preferences but nothing like those.

I asked a question on StackOverflow, a great new wiki/forum/help site for programmers and was pointed to the Cocoa docs and some useful posts where I figured out how to put together these simple key bindings. Results follow.

Create the file ~/Library/KeyBindings/PBKeyBinding.dict if it doesn’t exist and add the following to the file:

{
    "^$K" = (
        "selectLine:",
        "cut:"
    );
    "^$D" = (
        "selectLine:",
        "copy:",
        "moveToEndOfLine:",
        "insertNewline:",
        "paste:"
    );
}

The above snippet creates a key binding for “^$K” (Control-Shift-K – aka TextMate’s “delete line”) and “^$D” (Control-Shift-D – AKA TextMate’s “duplicate line”). You can see there’s loads of different macro’s you can add to this file to make unique key binding snippets. Note that they won’t take effect until you restart XCode.

January 1st, 2009 | Permalink