giant robots smashing into other giant robots

Written by thoughtbot

jferris

How to extract an intention-revealing name using Vim

This method has a magic number:

def wait_time
  @env[QUEUE_WAIT_HEADER].to_i / 1000
end

Let’s extract that to an intention-revealing name. We’ll type:

/1000<Enter>                   # Find the number we want to extract
cwmilliseconds_per_second<Esc> # Replace the number with a variable name
O<Ctrl+A> = <Esc>p             # Assign the replaced number to the variable

The result:

def wait_time
  milliseconds_per_second = 1000
  @env[QUEUE_WAIT_HEADER].to_i / milliseconds_per_second
end

Under the covers:

  • <Ctrl+A> inserts the last text you typed in insert mode, so the variable name is available after replacing the number
  • Replacing or deleting text in Vim will place that text in your default buffer, so the number is available to put at the end

Assuming your cursor is at the value you want to extract, this creates an intention revealing name in 10 keystrokes, plus the keystrokes it takes to type out the name.

Can you beat my Vim golf?

dancroak

Global .gitignore

Set a .gitignore file to apply across all projects on your local machine with:

git config --global core.excludesfile ~/.gitignore

The only ignored pattern I have right now is:

*.swp

That ignores temporary files created by vim.

I used to ignore those files in each project I worked on but then I recognized my presumptuousness: not every teammate on every project is also using vim.

For them, that line is unnecessary.

We might say, “Who cares? It’s only one line.” but I appreciate it when my teammates are similarly disciplined so I ought to apply The Golden Rule.

> “Programming at its best is an act of empathy.” - Kent Beck

What else do you have in your global ~/.gitignore?

Written by .

dancroak

Convert Ruby 1.8 to 1.9 hash syntax

In vim, for an entire file:

:%s/:\([^ ]*\)\(\s*\)=&gt;/\1:/g

In the shell, for an entire project:

perl -pi -e 's/:([\w\d_]+)(\s*)=&gt;/\1:/g' **/*.rb

Now, instead of those old-school hashes like this:

get '/', :agent => MOBILE_BROWSERS do

You’ll have new-school hashes like this:

get '/', agent: MOBILE_BROWSERS do

Written by .

lukegriffiths-apprentice

Apprentice.io Three Week Retrospective

Over the past three weeks I’ve begun my apprenticeship at thoughtbot. The apprenticeship lasts until the end of March.  I’m joined by designers Paul Webb and Edwin Morris, and fellow coder apprentice Alex Patriquin. Each of us is assigned to a mentor, who makes sure we absorb as much as possible of the thoughtbot way of doing things and achieve our specific goals. For me, the apprenticeship is a couple of things: it’s a chance to work in coder nirvana (TDD, heavy refactoring, bookshelf full of great literature, 5-minute meetings, pair programming, investment days, open source - the works), and it’s a chance to vastly increase my Rails skills in a bootcamp-style training environment.

My head is swimming with new knowledge. I entered this state the first day, and I’ve been there constantly for the past three weeks. Each evening I ride the T home with my poor neurons about to burst with new activity. At night while I sleep my brain indexes all this new knowledge, and the next day I dive in again. If you’ve ever read Ender’s Game, it’s sort of like Battle School for Geeks.

Let’s get specific. This list is long because I’ve been truly busy. In the past three weeks I have:

  • Mercilessly refactored my code two, three, even four times after writing it. The standards for code quality here are very, very high.
  • Learned to use Github pull requests for code review.
  • Responded to around 150 code review comments, most of which made me stop and rethink coding habits I’ve held unconsciously for years. My style is improving fast.
  • Participated daily in a morning company-wide standup that actually takes less than five minutes, and a team standup that takes another five. That’s only ten minutes of meetings per day!
  • Switched to using higher-level cucumber tests involving steps like “When I sign up as a new user” as opposed to “When I click the link marked ‘foo’”.
  • Achieved and maintained 100% perfect TDD discipline - not writing a single line of feature code until a failing test is present.
  • Completely switched text editors, from Textmate to Vim.
  • Became faster in vim than I ever was in Textmate.
  • Written custom functions for vim.
  • Learned other new tools including Homebrew, ack, ctags, New Relic, KISSmetrics, and kumade.
  • Forked thoughtbot’s dotfiles repo and started customizing it as my personal dev environment. The dotfiles repo contains bashrc, vimrc, git-config, alises, etc - I can now install it to any computer I use to instantly have my customized dev environment in place.
  • Watched an app’s user base jump from 100 to 10,000 in a matter of minutes as an article hit TechCrunch.
  • Gotten a crash-course in startup funding from the other coding apprentice, Alex Patriquin, who boasts, quite accurately, of knowing everybody.
  • Participated in discussions about new features in rails.
  • Made my very first contribution to an open source repo.
  • Been approved to give my first professional presentation - a lightning talk at at Boston.rb meeting.
  • Consumed 3,000 cups of green tea and a foie gras taco.

Did I mention I’ve been busy? That’s just the first three weeks - and I’ve got ten weeks left. I feel excited, involved, and challenged in a completely invigorating way. The team here is universally smart and helpful, and while I’m here I simply can’t help but get better by osmosis at what I do. This is the most fun I’ve had in an office in a long time.

For more information about this program, and to sign up to sponsor a pool of apprentices, visit apprentice.io

More later on,

jdclayton

Vim Macros and You

Ever get the urge to update a ton of files? I know I do. For example, I recently changed multiple hundred coffeescript files from the syntax of

MyGreatClass = Backbone.Model.extend(
  defaults:
    awesome: true
)

to

class @MyGreatClass extends Backbone.Model
  defaults:
    awesome: true

How long did it take me? A couple of minutes. Here’s how.

Ack (or Grep)

I like ack. To find all the files I need to edit, I’d write something like this:

ack '^[^\s].*\=.*\.extend\($' app/assets/javascripts -l

This finds everything that doesn’t start with a space, has an equals sign, and has .extend( at the end of the line.

Opening a list of files in vim

After looking over the results of ack and ensuring that everything that matched is what I want to edit, I’ll open those files in vim.

vim $(ack '^[^\s].*\=.*\.extend\($' app/assets/javascripts -l)

Vim Macros

If you’ve been using vim and haven’t taken advantage of macros (especially if you’re editing a lot of files in a similar fashion), you’re missing out. Open up vim and type :help q to get the nitty-gritty; I’ll summarize here.

To start recording a macro, press (in normal mode) q and then a letter or number. This will record a macro to whatever register you chose (via the letter or number).

Once you’re recording a macro, anything you type will be recorded to that macro so that it can be replayed. What I would type to change these files to the new format would be:

qqgg0iclass @<esc>f=cwextends<esc>2f.DGdd:wnq

Whoa, brain overload. Let’s break it down:

qq             # records the macro to the q buffer
gg             # first line in file
0              # first character in line
iclass @<esc>  # inserts class @ at the cursor and returns to normal mode
f=             # finds the first equal after the cursor
cwextends<esc> # changes the word (=) and moves to insert mode, adds extends, and returns to normal mode
2f.            # finds the second period after the cursor
D              # deletes the remainder of the line
G              # moves to the end of the file
dd             # deletes the line
:wn            # writes the file and moves to the next file in the list
q              # stops recording

This should be fairly straightforward; the only thing I really want to point out is the :wn. The n in that command moves to the next file in the list of files you opened with vim. This is one half of what makes editing all these files really fast.

Replaying a Macro

Now that you have your macro, it’s time to replay it. To replay a macro, press (in normal mode) @q (assuming you stored your macro into the q register). If you were to run that macro, it’ll run it against the current file, write the file, and move to the next. Since vim supports prefixing many commands with a number (for the number of times to repeat the command), running 100@q will run that macro on the first one hundred open files that I’ve opened with vim. Typically, this should be all you need to batch-edit, but if there are more files, just run that command again (or start with a higher number). If there are no more files to edit, vim will let you know.

Ben also mentioned recursive macros (my mind was blown) by adding @q right before the last q (which will run the q macro before stopping recording). Just make sure your q register is empty! This would allow you to run your macro once, without specifying the number of times to run it, because vim will run the macro until it’s out of files. Fancy!

Vim for fun and profit

Want to kick ass at vim? Pick up a copy of Vim for Rails Developers and become blazing-fast! If you want to hang out with fellow vim users to swap awesome tips like this, be sure to head to the Boston Vim Meetup!