May 16, 2013

SSH Escape Sequences

Today, I learned about a bunch of escape sequences that SSH supports.

Sequence Description
~. terminate connection (and any multiplexed sessions)
~B send a BREAK to the remote system
~C open a command line
~R Request rekey (SSH protocol 2 only)
~^Z suspend ssh
~# list forwarded connections
~& background ssh (when waiting for connections to terminate)
~? this message
~~ send the escape character by typing it twice

For example, you can suspend the SSH process itself to return to your local shell by typing ~^Z (that's ~ + ctrl + z). I've been using SSH for years, but had no idea these existed.

Today, I wondered what the difference between $* and $@ in Bash were. This is a tough one to Google for, so I'm copying the answer I found here:

Variable Result
$* $1 $2 $3 ... ${N}
$@ $1 $2 $3 ... ${N}
"$*" "$1c$2c$3c...c${N}"
"$@" "$1" "$2" "$3" ... "${N}"
March 9, 2013

More OS X Hints

I just came across this list of OS X Lion tricks and tips. A few I didn't know about yet, such as Tip #22, resizing windows with Shift and Option.

I've been using OS X for a few years, I love that I'm still learning new things about it.

February 23, 2013

Xcode 4.6 and ruby-build

I've been having trouble compiling Ruby 1.9.3 since updating to Xcode 4.6. After a little Googling, it turns out that the error is with some invalid CFLAGS set in Ruby's compile scripts.

The flag can be tweaked as follows:

CFLAGS="-Wno-error=shorten-64-to-32" rbenv install 1.9.3-p392

Hopefully future versions of Ruby will address this.

Today, I finally got a new MacBook Pro with Retina Display to replace my aging early-2009 model.

This thing is FAST. I went with the 2.7GHz model (which peaks at 3.7GHz with Turbo Boost), that also includes 16GB of RAM and a 512GB SSD.

Opening programs happens nearly instantly. Restarting the computer takes about 15 seconds. On some projects I work on, running the test suite is almost 2 minutes faster!

Oh, then there's the screen…

February 8, 2013

Running RSpec in Vim

Today, I finally got :make working for RSpec files in Vim.

First, you need vim-rails installed. It includes support for RSpec's error format. As outlined in its FAQ, you need to manually add a snippet of code to your ~/.vimrc to enable :make for specs. I don't need test-unit support, so I adapted the example:

autocmd FileType ruby
  \ if expand("%") =~# '_spec\.rb$' |
  \   compiler rspec | setl makeprg=rspec\ $*|
  \ else |
  \   compiler ruby | setl makeprg=ruby\ -wc\ \"%:p\" |
  \ endif

This didn't work for me at first - I use rbenv and Vim was trying to use the default system Ruby at /usr/bin/ruby. After a bit of Googling, I found the issue was with OS X's /etc/zshenv. Specifically, it uses /usr/libexec/path_helper which changes $PATH. I removed /etc/zshenv and Vim used the correct rbenv provided Ruby.

With this in place, you can run :make to run the entire test suite via rspec; or pass arguments to it. Run the current spec: :make %. Pass extra arguments: :make --fail-fast %.

If there are any failures, you can open the QuickFix window with :copen to view them in a list. Jump to the one you want to edit and press <Enter> and Vim will bring you directly to that line.

Glad I finally got this working. I'll probably use it daily.

NOTE: If you use Bundler, you need to either use binstubs or add bundle exec to the makeprg above.

Vim has a handy feature that allows you to run commands from a file when you open a new session.

For example, suppose you have a file, /tmp/my-vim-commands containing ggIHello World. To execute this, open MacVim with mvim -s /tmp/my-vim-commands. When the session starts, it will run those commands. Then move to the top of the buffer, switch to Insert mode at the beginning of the line, and enter the text “Hello World”.

To read commands in from stdin instead of an actual file, you can use cat and /dev/stdin:

cat <<CMD | mvim -s /dev/stdin
gg
IHello World

Note: This doesn't seem to work with console Vim, it throws an error “Vim: Warning: Input is not from a terminal”.

Yesterday, I decided I wanted to edit a bunch of Jekyll posts. Specifically, I wanted to move the title field in each post's YAML front matter to the bottom. Instead of having to manually edit a few hundred files, I finally remembered to use Vim macros.

In Vim, a macro is a recording of a number of commands. Once you've recorded a macro, you can replay it any number of times. So the idea for this task was to record a macro that could I could replay, that would locate the title line and move it to the bottom of the post's YAML front matter.

To illustrate how this works, let's take a look at this post's YAML front matter:

---
layout: default
title: "Fun With Jekyll Posts and Vim Macros"
date: "Tue Feb 05 19:57:11 -0500 2013"
---

...

To rearrange these lines as desired, you can use these commands in Vim:

gg
/title<cr>
dd
/---<cr>
P
  • gg: Move to line 1
  • /^title:<cr>: Move to the first line starting with “title:”
  • dd: Delete that line to the default register
  • /^---<cr>: Move to the next line starting with “—”
  • P: Paste the contents of the default register above the current line

This gives you the proper sorting, but the process needs to be repeated in each file:

---
layout: default
date: "Tue Feb 05 19:57:11 -0500 2013"
title: "Fun With Jekyll Posts and Vim Macros"
---

...

To use this as a macro, you just need to record it with q. Expanding on the commands above:

qq
gg
/title<cr>
dd
/---<cr>
P
:w
q
  • qq: Start recording a new macro named “q”
  • gg: Move to line 1
  • /^title:<cr>: Move to the first line starting with “title:”
  • dd: Delete that line to the default register
  • /^---<cr>: Move to the next line starting with “—”
  • P: Paste the contents of the default register above the current line
  • :w: Write the file
  • q: End recording

You now have a macro that can be played back with @q. This is much quicker, but you still need to edit each file and manually press @q. To handle this for multiple files you can use :args and :argdo.

:args _posts/*.markdown
:argdo normal @q
  • :args _posts/*.markdown: Set the files to target
  • :argdo normal @q: Run normal @q for each file. This is the same manually running @q in the file.

After you're done, all the files will be updated. Huzzah, macros!

My girlfriend has recently begun learning Java for college. The shittyness of Java aside, I've realized that its lack of a REPL makes it much harder to play around with its features.

A REPL (Read Eval Print Loop), does 4 things:

  1. Read: The program reads your input when you enter a command with your keyboard press enter.
  2. Eval: The program evals, or runs the command it received from you.
  3. Print: The program prints the result of that command to your terminal.
  4. Loop: The program loops back to step 1 so you can run more commands.

Like most Rubyists, I started out hacking on PHP code, and without a REPL. In those days, it was difficult to get PHP running properly on Windows. In order to test code, I typically made changes on a live site and reloaded my browser. Eventually I switched to Linux, and then OS X, and was able to run simple scripts right from the terminal. This was a bit easier, but it was still a pain to do when I just wanted to mess around with a couple functions.

When I switched to Ruby, I discovered IRB, which is Ruby's REPL. When I was first learning the language, I could enter commands directly into IRB and get instant feedback. Years later, I still use IRB every day at work to test code.

Compiled languages, like Java, lack REPLs. To test code in Java, you have to recompile your app and hope it runs as desired. Compiled languages are fine, but it would be much easier to learn how to use them with a REPL.

October 2, 2012

NiGHTS into dreams on PSN

Today, Sega re-released one of my favorite childhood games from Sega Saturn: NiGHTS into DREAMS….

When I was 12 I spent hours playing this game, memorizing the maps, and trying to get the highest scores I could.

The PSN remake retains all of its 1996-charm. In fact, it includes high def and original Sega Saturn graphics. The original graphics look a bit dated on a high def television, but this game is still seriously fun.