These are common staples of searching through text files.
You should stop using them. Now.
You can do much better by writing more consice regular expressions
and using ack or one of its relatives
(ack-grep, or rak).
The primary virtue of these commands is that
they use the Perl regular expression
engine. Most programmers with experience in any of the major scripting languages will find this more comfortable than grep’s use of the GNU regex syntax.
I recently encountered a need to search through many files based on a complex regular expression that required lookahead and lookbehind asserions. I have no idea how that would work in GNU regex land where, honestly, I still have a hard time getting simple capture and alternation. After learning look around syntax, I was glad to know that ack could directly implement it.
Given haystack, a text file:
tin needle
silver needle
lead needle
ocelot
monkey
Find the needles (this is where most grep users get to and never leave):
$ ack needle haystack
tin needle
silver needle
lead needle
Look at that one character shorter than grep and just as easy. Now if you want the silver needle, the unsophisticated, greppy way of doing this
would be:
$ grep needle haystack|grep silver
silver needle
This sucks. Try:
$ ack '(?=silver).*needle' haystack
silver needle
Or, “all things in the haystack that are needles, but not the lead one”
$ ack '^(?!^lead).*needle.*$' haystack
tin needle
silver needle
I know there’s a lot more to the power of the lookaround
assertion, but if I can
re-train myself out of this habit I think it’ll be a big win. Granted, for
smaller searches the “double-grep” method is probably fine, but any time you’re
doing a recursive descent and are looking for true needles in the haystack,
ack’s is the superior approach.
The case that I was working on was where I needed to search all my Rails models
for all named scopes that did not use the lambda form and I wanted five
lines of context around the matches so that I could be understand the behavior.
I heard about this at Golden Gate Ruby Conf this past
year from Ron Evans (@deadprogram). It’s a
low-power, low cost computer that can be used for lightweight media centers or
“learn to program” desktops.
I love the idea of these little machines lurking about hte house doing all
sorts of automated stuff for us behind our back. While it’s clearly underpowered
to do advanced photo editing, most of our requirements for household computing (yet)
are fairly low power with frequent gap time.
The Vim editor has a built-in function for preserving your editor state —
which files you had open, which tabs they were in, etc. — called
“Sessions.” In my experience, few Vim users, even experienced / advanced
users, take advantage of this feature and that is a shame. Sessions allow you
to get you back into the working context of a given problem immediately .
If you’ve avoided a needed reboot for software update or wished you could save
the context of your editing as related to a specific problem, you should take
the time to learn a little bit about sessions.
Curating an Editor State
As developers, we generally start with a single file (“QA says there’s a bug in
this view”) and then realize it has a relationship with another file
(“Hm, but I need this as the data source / dependency / etc.”). Over time we
come to recognize that there are several files whose relationship and
interaction creates a “feature” we want to work on. I call this collection of
files that represents the means to the solution the “curated list.” We groom
our curated list into a user interface that helps us address the problem:
The curated list for this blog post
Finding yourself needing to reboot, where you would wipe away this solution
context like some Tibetan sand
mandala might put you into a panic
routine:
“Which files do I have open? Which directories am I in, which server processes
are running?”
To save your state all you need to do is run :mksession. By default this will
create a file called Session.vim in your working directory. Its contents are
a full list of Vimscript commands that will be issued when you launch Vim with a
reference to that file with vim -S session_file_name at a later date. Reading
this file is also a great way to learn some powerful Vimscript commands.
The commands it requires to re-build your Vim session as it is right now
Standard Vim file-write semantics still apply To overwrite the old session it’s
:mksession! and :mksession session-from-after-lunch.vim It is this latter
usage which allows you to create ‘topic based sessions.’
Topic-Based Vim Sessions
The average Vim session is very small (kilobytes) and they can be made cheaply
(less than a second) therefore, as I work on problems I’ve taken to creating
multiple Vim sessions so that I can address a feature and come back to it
painlessly.
Presently I’m experimenting on creating sessions based on bug-tracker stories.
The session files (ending in .vim) are included in my global .gitignore
file. Given that a certain feature may be revisited at any point, it seems a
good idea to keep each in its own session so that I can pick it back up again
for subsequent bugs / improvements. AND should a refactor add a new file or
drop one, all that’s required is a simple mkession! to write a new session.
Gotchas
By default mksession saves blank, buffers, curdir, folds, help, options,
tabpages, winsize. Depending on how heavily customized your Vim configuration
is, you may find these session commands clashing with your default options. For
a heavily customized Vim installation (like Janus
Vim) this can create some erratic results.
To prevent any clashes, I have modified the default sessionoptions
configuration in my .vimrc to be the following:
” Sessions in Janus are overwrought
set sessionoptions=blank,buffers,curdir,folds,help,tabpages,winsize
Reference
As sessionoptions seems to suggest, there are a wide variety of things that
can be preserved. :help sessionoptions and :help mksession in the on-line
Vim help guide should help you tweak your configuration to perfection.
I can even seen an argument for adding a :mksession! as an autocommand, so
that your session is written on every file-write or buffer-change event. I
don’t (yet) see a need for that, but it’s great to know that Vim has that
capability.
Conclusion
With OSX Lion now preserving open application state, browswers now allowing you
to save tab state, and Vim now allowing you to preserve buffer state, you can
live in less fear of a power outage, an accidental reboot, or a gray screen of
death.
I love usig the mutt mail reader to turn through my
mail. I recently set it up to make use of my MacVim installation by adding the
following configuration to the .muttrc.
set editor="mvim --remote-tab-wait-silent "
This is pretty neat. When I go to reply or compose, I’m thrown into a new tab
in MacVim and I can compose / reply there. After hitting ZZ or :wq!, mutt
properly handled the signal, but didn’t change OSX’s focus back to the
terminal window where Mutt was running. By changing the editor to the
following configuration:
set editor="osascript $HOME/bin/mutt_edit.sh"
I was able to tell Mutt to send my temp file (for the edit) to osascript, a
utility that runs Applscript. In mutt_edit.sh I provided a bit of a wrapper
around the mvim command such that it told OSX to re-activate my terminal
session after the editing activity finished. Here’s the code:
on run argv
tell application "Finder"
do shell script "mvim --remote-tab-wait-silent " & item 1 of argv
end tell
tell application "iTerm (1.0.0.20111020)"
activate
end tell
end run
One of the organizations that I’m most proud of helping out is
Railsbridge. It aims to increase the
diversity within open source software development, particularly women. Twice
now I have worked with wonderful and amazing people in these sessions.
In these activities I have encountered a powerful enemy to successful teaching
that we, as organizers and teachers, should remain vigilant against: negative
confirmation bias.
Negative confirmation bias is when a student walks into a situation expecting
that s/he is not going to succeed and then proceeds to look for data to back up
that negative view. Why students have this negative view is a subject for
another post, but it is my belief that it is at the heart of why there is such
poor diversity in high tech.* At development workshops / boot
camps, students encounter a dangerous confirmant of their negative bias in
one the earliest steps: “Bootstrap the setup using git.”
Facilitators must take an active role in reminding students that the
installation / bootstrap step bears no inherent reflection upon their
ability to enjoy, learn from, and perform well in the class.
As I mentioned elsewhere, my friend Daniel
Miessler said that he would be ready to give up
Textmate for Vim but were it for the level of blogging support. I have,
hopefully, made it easier to do so. In fact, I’m writing this blog post and
using my fork of Vimblog to manage it.
Here’s how this post was made:
:Blog np created a new post
Moved down to the Categs line and then: :Blog cl
/Techno to match the right line. Hit enter.
Vimblog just copied the category name to the yank clipboard for me and then…
p to paste it in
G to the end of the file
o to start typing
Typed Daniel Miessler
v2b\gifl did a Google I’m feeling Lucky to his site and wrapped it in a
markdown link
More editing
:Blog draft (because it’s still alpha-grade code) so I could check it out
in WordPress
Took a screen-shot of vim to put in the post
:Blog um ~/Desk/vimb
Vimblog pasted the url link to the image that makes this work:
I have been wanting to get the Vim Editor working
as a tool for blogging. I’d discussed this a time or two with my friend
Daniel Miessler, and he brought up a
critical thing that was missing for him in migrating away from
Textmate: the ability to do an “I’m feeling
lucky” hotlink onto a word as one is composing.
I had to admit, this was a pretty compelling feature provided by
Textmate’s “Hyperlink Helper” bundle. Its lack definitely hindered
my drive to blog in vim.
To that end, I have created my
first Vim plugin and port this sexy
capability to Vim.
The port is called GIFL which is not some sort of obscure term for
attractive septugenarians, but rather is Google I’mFeeling
Lucky.
With this installed you can do things like:
Imagine you have the following text, with your cursor at ‘*’:
That is, the Markdown code for a URL. That’s pretty handy. This loads
up in the global namespace, so you can use it anywhere and everywhere.
I’ve found it suprpisingly handy in places other than a blogging
context. It’s still very, very, very alpha, but it gets the job done.
By the way, thanks to Pedro MG’s vimblog
project, I was able to write
this post in Vim, with GIFL doing nearly all the linking.
I think that both GIFL and Vimblog need to be polished a bit before
I can say that, together, they make it as easy as it was in Textmate
to be a blogger, but it’s definitely closer. Thanks to Macvim + Janus
as platform, this is close.
As mentioned previously, I gave a talk at Rubyconf XI in New Orleans a few months back. The video is now available. If you want to see me talking about some of the finer details of the Ruby programming language while wearing a shirt from Saturday Morning Breakfast Cereal, here’s your chance.
It may be a bit of a “no duh” observation to point out that joining a consulting firm has a very different work flow versus working in corporate. A few numbers:
Number of days when pairing occurred: 5
Number of hours spent pairing: ~37
Number of stand-ups: 5
Time spent in stand ups (week): ~ 50 minutes
Brown Bag Lunch: 90 minutes
Emails received within project team: 3
Emails received from client: 1
Skills Worked On: HTML5, CSS3, Rails, Backbone.JS
Times astounded by my pair’s refactoring skills: 2
Times astounded by my peer teams’ approaches to managing complexity elegantly: 2