Posted by sjs
on Tuesday, July 03
Update: The only place I’ve seen this mentioned is in a comment on the MacroMates blog.
My Linux box is down due to a hardware failure; a cheap SATA controller to be specific. Perhaps that will be a story for another day. As a result I’ve been working on my MacBook and back in TextMate. Old habits. And I haven’t gotten comfortable in any of the OS X Emacsen yet.
This gave me an opportunity to accidentally discover some shortcuts in TextMate. A result of the Emacs shortcuts that my fingers are already wired to, here are some TextMate keyboard shortcuts that may or may not be documented (I need to RTFM some day).
- As in most Cocoa text areas,
C-f, C-b, C-n, C-p, C-a, C-e, and C-t work as expected (and others I’m sure).
C-k: behaves as a vanilla Emacs, killing till a newline or killing a bare newline. I use the word killing specifically because you can yank it back with…
C-y: yanks back the last thing on the kill ring (paste history). You still have to use C-S-v to yank previous items.
I think TextMate may have helped ease me into Emacs without me even knowing. I had my suspicions that Allan was an Emacs fan and now I’m certain of it. I keep finding things in one that the other has, which makes switching between them easy. Well done Allan.
Posted by sjs
on Saturday, June 23
Update #1: What I first posted will take out your < key by mistake (it’s available via C-q <), it has since been revised to Do The Right Thing.
Update #2: Thanks to an anonymouse[sic] commenter this code is a little cleaner.
Update #3: I should read the Emacs manual sometime, especially since I have it in dead-tree form. Check out skeleton pairs in the Emacs manual.
Despite my current infatuation with Emacs there are many reasons I started using TextMate, especially little time-savers that are very addictive. I’ll talk about one of those features tonight. When you have text selected in TextMate and you hit say the ' (single quote) then TextMate will surround the selected text with single quotes. The same goes for double quotes, parentheses, brackets, and braces. This little trick is one of my favourites so I had to come up with something similar in Emacs. It was easy since a mailing list post has a solution for surrounding the current region with tags, which served as a great starting point.
1
2
3
4
5
6
7
|
(defun surround-region-with-tag (tag-name beg end)
(interactive "sTag name: \nr")
(save-excursion
(goto-char beg)
(insert "<" tag-name ">")
(goto-char (+ end 2 (length tag-name)))
(insert "</" tag-name ">"))) |
With a little modification I now have the following in my ~/.emacs file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
;; help out a TextMate junkie
(defun wrap-region (left right beg end)
"Wrap the region in arbitrary text, LEFT goes to the left and RIGHT goes to the right."
(interactive)
(save-excursion
(goto-char beg)
(insert left)
(goto-char (+ end (length left)))
(insert right)))
(defmacro wrap-region-with-function (left right)
"Returns a function which, when called, will interactively `wrap-region-or-insert' using LEFT and RIGHT."
`(lambda () (interactive)
(wrap-region-or-insert ,left ,right)))
(defun wrap-region-with-tag-or-insert ()
(interactive)
(if (and mark-active transient-mark-mode)
(call-interactively 'wrap-region-with-tag)
(insert "<")))
(defun wrap-region-with-tag (tag beg end)
"Wrap the region in the given HTML/XML tag using `wrap-region'. If any
attributes are specified then they are only included in the opening tag."
(interactive "*sTag (including attributes): \nr")
(let* ((elems (split-string tag " "))
(tag-name (car elems))
(right (concat "</" tag-name ">")))
(if (= 1 (length elems))
(wrap-region (concat "<" tag-name ">") right beg end)
(wrap-region (concat "<" tag ">") right beg end))))
(defun wrap-region-or-insert (left right)
"Wrap the region with `wrap-region' if an active region is marked, otherwise insert LEFT at point."
(interactive)
(if (and mark-active transient-mark-mode)
(wrap-region left right (region-beginning) (region-end))
(insert left)))
(global-set-key "'" (wrap-region-with-function "'" "'"))
(global-set-key "\"" (wrap-region-with-function "\"" "\""))
(global-set-key "`" (wrap-region-with-function "`" "`"))
(global-set-key "(" (wrap-region-with-function "(" ")"))
(global-set-key "[" (wrap-region-with-function "[" "]"))
(global-set-key "{" (wrap-region-with-function "{" "}"))
(global-set-key "<" 'wrap-region-with-tag-or-insert) ;; I opted not to have a wrap-with-angle-brackets |
Download wrap-region.el
That more or less sums up why I like Emacs so much. I wanted that functionality so I implemented it (barely! It was basically done for me), debugged it by immediately evaluating sexps and then trying it out, and then once it worked I reloaded my config and used the wanted feature. That’s just awesome, and shows one strength of open source.
Posted by sjs
on Tuesday, March 07
That’s right, and you should go and get it right away. It’s now the default Rails bundle for TextMate as well.
The reading of schema.rb to generate self.down is really genious. As are footnotes. There’s no going back to gvim now (for Rails anyways).
Now all I need is $500 so I can sell my over-worked PPC Mac mini and be able to get one with an Intel Core Duo in it. It’s not that it’s painfully slow or anything, but compared to the computer I built to be my main workstation it’s pretty weak. I got used to things to being more or less instantaneous.
Posted by sjs
on Friday, March 03
Scott wrote a really cool program that will scan self.up and then consult db/schema.rb to automatically fill in self.down for you. Brilliant!
Posted by sjs
on Tuesday, February 21
This should be working now. I’ve tested it under a new user account here.
This does requires the syncPeople bundle to be installed to work. That’s ok, because you should get the syncPeople on Rails bundle anyways.
When writing database migrations in Ruby on Rails it is common to create a table in the self.up method and then drop it in self.down. The same goes for adding, removing and renaming columns.
I wrote a Ruby program to insert code into both methods with a single snippet. All the TextMate commands and macros that you need are included.
See it in action
I think this looks cool in action. Plus I like to show off what what TextMate can do to people who may not use it, or don’t have a Mac. It’s just over 30 seconds long and weighs in at around 700kb.
Download Demo Video
Features
There are 3 snippets which are activated by the following tab triggers:
- mcdt: Migration Create and Drop Table
- marc: Migration Add and Remove Column
- mnc: Migration Rename Column
Installation
Run Quick Install.app to install these commands to your syncPeople on Rails bundle if it exists, and to the default Rails bundle otherwise. (I highly recommend you get the syncPeople bundle if you haven’t already.)
Download Intelligent Migration Snippets
This is specific to Rails migrations, but there are probably other uses for something like this. You are free to use and distribute this code.
Posted by sjs
on Saturday, February 18
My arsenal of snippets and macros in TextMate is building as I read through the rails canon, Agile Web Development… I’m only 150 pages in so I haven’t had to add much so far because I started with the bundle found on the rails wiki. The main ones so far are for migrations.
Posted by sjs
on Saturday, February 18
Duane came up with a way to jump to the controller method for the view you’re editing, or vice versa in TextMate while coding using Rails. This is a huge time-saver, thanks!