I feel as if my scenario is fairly simple but that I might be overcomplicating it.

I am searching through files looking for a special condition, that is where the method .all with arguments exists. In the real world that looks like:

ba_mbn_programs = Program.ba_and_managed_bar.all(:conditions => "user_programs.user_id = #{current_user.id} and brand_id = #{brand.id}", :order => :name, :joins => [:user_programs], :select => "distinct programs.*")


I'm able to find those using ag like this:

ag '\.all$$.*$$'


That gives me a big list of file names and line numbers (here's a snippet):

lib/ui_elements.rb
4:      self.active.all(:select => ["name, #{model}.id"], :order => :name).collect{|m| [m.name, m.id]}.insert(0, ["All", nil])


So in no particular order, I need to address these lines in my editor. So what I really want to do is open up the file lib/ui_elements.rb in vim and go right to line 4.

I've learned that using vim +line_num file_name is a way to do that. However just isolating the line number and file name from the ag output has forced me to do something like this:

vim ag '\.where$$.*$$' app | tail -1 | sed -E 's/([^:]*):([0-9]*):.*/\1 \2/' | awk -v q="+" '{print q $2,$1}'


So that just reads the last file from that search and opens the file in vim to that line number. Surely there is a better way then this?

• Why not just use the :grep command from within Vim? Perhaps what you need is a Vim skill (consult Vi and Vim) rather than a code review. – 200_success Jun 8 '16 at 17:04

You could simplify the vim call like this:
vim $(ag '\.where$$.*$$' app | sed -nE '$s/([^:]*):([0-9]*):.*/+\2 \1/p')

That is, no need for the awk to print the matched filename and line number in reverse, you can reverse in the sed, and also prefix the number with + there.
I dropped the tail -1, by using the -n flag of sed to not print output by default, added $ in front of the s/// command to apply for only the last line of input, and the /p flag to print after substitution. Although this has the benefit of eliminating a tail process in the middle, it has the disadvantage that it's a bit harder to understand. So you can put back tail -n 1 (more portable than tail -1) if you prefer. I also changed the obsolete ... to $(...).