Fixing the search #2

Previously I said I had to scan the hrefs for my search-mark spans, but I forgot my assets:

content.scan(/\/assets\/.*?"/).each do |s|
  edited_link = s.gsub('<mark class=\'search\'>', '')
  edited_link.gsub!('</mark>', '')
  content.gsub!(s, edited_link)
end

Sadly, I didn't find a proper way to skip URLs, so I have to scan several times to remove search-mark from them :(

GitUp

I recently stumbled upon GitUp. It's a pretty nice git GUI, with a ton of features, nifty keyboard shortcuts for almost everything, and minimal interface. The only downsides are that it doesn't display the commits next to the working tree, you have to click on them, and that you can't open pull requests on GitHub, like the GitHub Mac app, or SourceTree do. When / if these get implemented, I might just use GitUp as my git GUI.

GitUp screenshot

Terminal improvements for git

Improvement #1: adding the current branch name after the current path. Add this in your .bash_profile file:

parse_git_branch() {
    git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}

export CLICOLOR=1
export LSCOLORS=GxFxCxDxBxegedabagaced
export PS1='\[\e[0;32m\]\u\[\e[0m\]:\[\e[0;33m\]\w\[\e[0m\]\[\e[0;35m\]$(parse_git_branch)\[\e[0m\]$ '

And the outcome is user:path (branch_name) $. The user is green, the path is yellow, the branch_name is purple and everything else is white.

Improvement #2: autocompletion for branch names. Again, add this in your .bash_profile file:

if [ -f ~/.git-completion.bash ]; then
  . ~/.git-completion.bash
fi

I find these pretty useful. Actually, I find them indispensable after a prolonged use. Don't forget to tweak the colors to your own preferences.

Fixing the search

First of all, I changed the <search-mark> tag to <span class='search-mark'>. Secondly, I'm properly adding the search-mark to all occurrences of the searched term, instead of only the first (silly me). Lastly, I search the content again to remove the search-mark from inside hrefs:

start_index = content.downcase.index(w)
end_index = start_index + w.length
original_occurrence = content[start_index..end_index - 1]
content.gsub!(/#{original_occurrence}/i, '<span class=\'search-mark\'>\0</span>')
content.scan(/href=".*?"/).each do |s|
  edited_link = s.gsub('<span class=\'search-mark\'>', '')
  edited_link.gsub!('</span>', '')
  content.gsub!(s, edited_link)
end

Print calling function

Sometimes you need to find out what called a method. StackOverflow helped me find an answer:

public func printCallingFunction() {
  let syms = NSThread.callStackSymbols()

  if !syms.isEmpty {
    var sourceString = syms[2] as? String ?? ""
    var separatorSet = NSCharacterSet(charactersInString: " -[]+?.,")
    var array = sourceString.componentsSeparatedByCharactersInSet(separatorSet).filter() {
      $0 != ""
    }
  }

  // Swift appears to be different than Obj-C
  if (array.count < 6) {
    println("--- \(array[3]))");
  }
  else {
    println("--- \(array[3]) - \(array[4])");
  }
}

There's also this approach, but I don't really like it:

#include <execinfo.h>

void *addr[2];
int nframes = backtrace(addr, sizeof(addr)/sizeof(*addr));
if (nframes > 1) {
  char **syms = backtrace_symbols(addr, nframes);
  NSLog(@"%s: caller: %s", __func__, syms[1]);
  free(syms);
} else {
  NSLog(@"%s: *** Failed to generate backtrace.", __func__);
}