Today I Learned

A Hashrocket project

10 posts by jonallured @jonallured

List Your Leader Vim Mappings

Mapping your Vim leader is a great way to customize Vim without clobbering keys that are already mapped. By default your Vim leader is \, but you can change it to another key - many people suggest , since it’s so easy to type but I just use the default.

In any event, if you want to add a leader mapping how can you be sure that it’s not already taken??

Easy, try this:

:map <leader>

Behold - a list of all mappings that involve your leader key.

Move to column in Vim

Jumping to a specific line in Vim is something I do all the time:

# move to line number 10

In the last couple days I’ve wanted to jump to a specific character in a line. I did a quick Google search and found that you use pipe:

# move to character number 10 in your current line

I wondered if there was anything else to know, so I hit the help file:

:he |

Which gives you:

To screen column [count] in the current line. exclusive motion. Ceci n’est pas une pipe.

And I was like, whaaa? A little more Googling and I found this:

And that there is a list of Vim help easter eggs:

It was like a TIL three-for-one!!

The case of meridian in Ruby's strftime

When formatting dates using strftime, you can include AM/PM with %p:

puts"%H:%M:%S %p")
# 20:40:52 PM

I didn’t want PM capitalized, so I did this:

puts"%H:%M:%S %p").downcase
# 20:40:52 pm

But I found that you can also just use %P:

puts"%H:%M:%S %P")
# 20:40:52 pm

Yes that’s right, when you want lowercase AM/PM, use uppercase P. When you want upppercase, use lower. It couldn’t be more straightforward folks.

Rails Runner Shebang Line

I’ve known about the Rails Runner command for a long time - all it does is execute some Ruby in the context of your app. I’ve rarely used it, but had a situation today where I wanted to. I couldn’t quite remember how it worked, so I ran it without any arguments and discovered something new (to me, anyway):

$ rails runner
...blah, blah, blah...
You can also use runner as a shebang line for your executables:
#!/usr/bin/env /Users/jon/project/bin/rails runner

Product.all.each { |p| p.price *= 2 ;! }

Whoa, Rails gives you the runner as a shebang line too!!

Xcode Behaviors For Succeeding and Failing Tests

In the Xcode preferences, there’s a section for Behaviors where you can specify how Xcode should handle certain situations. What I learned about today was that you can have Xcode tell you when your tests pass or fail:

WiFi Menu With More Info

Here I have told Xcode to use the Good News voice to announce when my tests pass. I also picked a voice for passing tests: Bad News seemed appropriate.

Comes in handy when you have switched to another application and you happened to miss the notification in the corner of the screen. Plus, it sounds cool.

h/t Leo Picado

Xcode's Fix All in Scope

Xcode scans your code for compiler errors as you type. These errors show up as a red dot in the gutter that can be clicked to reveal the error message. Xcode may also provide a Fix-It that you can accept.

When your file contains multiple errors and you want to accept all the Fix-Its, do this: Editor > Fix All in Scope. Better yet, the keyboard shortcut: ctrl + opt + cmd + f.

This feature can be a little unpredictable because while Xcode does a great job of identifying compiler errors, it’s not always great at suggesting fixes. But, when you’re confident that you know what the fix is going to be, it can be very handy to let Xcode help you out.

One place I find myself using this feature is when I change my mind about a constant:

let foo = 1
// some code
foo += 1

I thought foo was going to be a constant, but then further down the file I realize my mistake - Xcode will error and I’m usually sure that hitting ctrl + opt + cmd + f will switch the let to var for me.

Private Set on Swift Property

Swift supports public get but private set on properties:

// foo.swift
public class Foo {
  public private(set) var bar: String = "hahaha"

// baz.swift
let foo = Foo() = "muhahaha" // "Cannot assign to property: 'bar' setter is inaccessible"

So, Foo is a public class with a public String property called bar. This property can be read, but cannot be set from the outside.

Choosing Which XCTestCases to Run

Xcode’s Test Navigator (cmd + 5), is an outline of your tests. As you mouse over the elements in this outline, you’ll see a run button off to the right. Using this button you can pick an individual case, file or target to run.

While editing a test file, you can use the buttons in the gutter to run either an individual case or the entire file.

But if you want more control, you can shift or command click on test cases in the Test Navigator to highlight them and then command click to bring up even more options:

Test Navigator Selection Menu

We can choose to run both highlighted cases or even disable them. Nice.

But, what about keyboard shortcuts??

You can run the entire suite with cmd + u, but did you know about these others:

  • ctrl + opt + cmd + u - Run the test file currently open.
  • ctrl + opt + cmd + g - Rerun the test(s) you just ran.

That last shortcut can be really helpful. Once you’ve run a particular test case in isolation, you can use that shortcut to run it over and over as you work.

The Order of Args With Default Values in Swift

Like many languages, the arguments to functions in Swift can have default values. As the documentation notes, it’s a best practice to place these arguments at the end of a function’s parameter list:

func foo(bar: String, baz: String = "omg", bah: String = "haha") {}
foo("<3 <3 <3") // `baz` and `bah` take on the values of "omg" and "haha" respectively

What I learned today is that when calling a function like this, the default arguments can be in any order:

foo("<3 <3 <3", bah: "first!", baz: ":(")


Joe Groff has a proposal on the mailing list to change this behavior.

Credit where credit’s due: I found out about this while reading the excellent Swift Weekly Brief.