Your browser (Internet Explorer 6) is out of date. It has known security flaws and may not display all features of this and other websites. Learn how to update your browser.
Overlapping windows are a bad invention. Frankly, the one UI that works are
virtual desktops with non overlapping windows (e.g. window managers).
Given, the world becomes sane slowly with iOS leading the way: every
application is full screen there.
On Mac OS X, the situation is dire: windows just open wherever they want to. I
wrote a python script a while ago that can be called quickly from Quicksilver
or LaunchBar which took a simple syntax to describe where you want your
window and moved it there. Problem: it was rather slow. It needed to run and
parse a command line tool to get number of screens and resolutions and it had
to ask for the frontmost application via AppleScript.
I got fed up with that yesterday and made it fast. Getting the frontmost
application and the number of screens and their resolution is now done via the
Carbon Framework in a C Extension. You can find the source code on GitHub,
download from there and use pip to install:
You want to call this from LaunchBar or Quicksilver, so install/make a proper
AppleScript (I ship one in contrib). The tool takes the following syntax:
move_window <screen_id><nr of x parts><x span><nr of y parts><y span>
Some examples
move_window 0# Disp 0, full Screen
move_window 02# Disp 0, left half of screen
move_window 030# Disp 0, left third of screen
move_window 031-2 # Disp 0, rightmost two thirds of screen
move_window 12121# Disp 1, bottom right quarter of screen
Second screencast is done and ready! If you have not yet seen the first,
look over here. This was done under the maxim Done is
better than perfect. I had more advanced explanations planed, but the
screencast turned out to be longer than expected. I therefore opted for a
complete overview over the most common features of UltiSnips and will explain
some cooler stuff in this blog post.
So here is the video. You can find some snippets with their explanation below.
Elements inside of default text
Placeholders can contain other UltiSnips elements. This is totally cool and
very useful. For example, the following snippet is defined for the html file
type and ships with UltiSnips:
snippet a
<a href="$1"${2: class="${3:link}"}>
$0
</a>
endsnippet
It allows to either delete the complete tabstop 2 with one keystroke. Or you
can jump to tabstop 3 and replace the CSS class name.
Another example:
snippet date
${2:${1:`date +%d`}.`date +%m`}.`date +%Y`
endsnippet
This snippet will enter the current date in the format that is used in
Germany: dd.mm.yyyy. Jumping forward will allow you to either overwrite the
day or the day and the month. I use this in my todo files to enter due
dates.
Complete Scripts in Shell Interpolation
Shell interpolation is as powerful as the shell itself. Here is a silly
example that is basically a complete Perl script:
snippetrandom`#!/usr/bin/perluse LWP::Simple qw(get);my $page = get "http://www.random.org/integers/?num=1&min=1&max=100&col=1&base=10&format=plain&rnd=new";print $page`endsnippet
This snippet will insert a truly random number between 1 and 100 fetched from
random.org. Useful? Maybe not, but a good example.
Transformations are more powerful than you might think
This transformation shows the transformation option g which means
global replace. It will uppercase every word in the first tabstop while
mirroring its content.
snippet title "Titelize in the Transformation"${1:a text}${1/\w+\s*/\u$0/g}
endsnippet
In the replacement part of this transformation, the u means "uppercase the
next character" and the $0 matches everything found. The complete
transformation basically says: find a word \w+ and any number of whitespace
\s* and replace them through what you found, but uppercase one char. The g
at the end makes sure that not only the first but all words are uppercased.
Conditional replacements
One feature that I didn't mention in the screencast are conditional
replacements. When you capture a group in the search part of a replacement,
you can check if it was matched in the replacement like so: (?<number>:yes text:no text).
yes text will be inserted if the group was matched, otherwise no text will
be inserted. A quick example:
The transformation will match a o at the beginning into group 1 or a t at
the beginning in group 2. The rest of the search string just matches
everything of the first tabstop. The replacement will either be ne when a
o was matched, wo when a t was matched or an empty string. That means
that you can just type a t to quickly get two as the complete content of
the snippet or a o to get one. If you type anything else, you only get the
content of the place holder, i.e. the verbatim of what you typed.
Inword triggers
The snippet option 'i' stands for inword trigger. Let's
say for some coding project, I often want to get variables that end on izer:
maperizer, vectorizer... I want to define a snippet with ri which should
expand to izer. Triggers are always matched to full words though - except
for when you use the i option for your snippet:
snippet ri "rizer" i
rizer
endsnippet
This does what I want: maperi<tab> -> maperizer.
Regular Expression triggers
Regular expression triggers can be used with the r option to a snippet. Note
that you have to add delimiters around your trigger when using regular
expression triggers. I use the following snippet because I can never remember
on which exact trigger I set my $$\textrm{\LaTeX{}}$$ chapter snippet:
This will expand on either cha, chap, chapt, chapte or chapter.
Regular Expression triggers are even more powerful because you can get access
the to match object inside your python interpolation blocks. More on that
in the next episode.
Regular expression triggers also allow to define triggers with special
characters, whitespace or multi word triggers.
snippet " this is a trigger""Multiword & Whitespace" r
Hello World
endsnippet
Conclusion
The features we discussed so far are enough to make crazy snippets and will
suffice for most uses. If you ever feel lost or forget how to use one of the
features, take a look into UltiSnips help document, either via
Next time we will discuss python interpolation which brings even more power to
snippets. With it, some of the features we discussed so far will become easier
to read with and others will only then become possible. With python
interpolation there is basically nothing that a snippet can't do.
As always, leave comments and let me know what you think about the screencast
and the tips. Also let me know what you are interested in and what you would
like to see in future screencasts. I have no more topics for a fourth
screencast, so if you want one, let me know what you want to see in it.