Not long ago I shared a Bash function that takes filenames in the form of filename.rb:NNN, where NNN is a line number, opens the file in Emacs, and jumps to that line. This format is commonly used in error messages and the output of test frameworks.

However, there’s another format I run into all the time, the format Github uses in URLs when linking to a specific line number:

1
https://github.com/someorg/somerepo/blob/somebranch/app/controllers/application_controller.rb#L38

Here, the line number is in the form ‘#LNN’, which makes total sense as a URL fragment identifier. I get a lot of these URL in chat when discussing problems and I decided to add support for them to my function.

The old version was:

1
2
3
4
5
6
7
function ec () {
       if [[ $1 =~ (.*):([0-9]+)$ ]]; then
          $EMACSCLIENT -c -n "+${BASH_REMATCH[2]}" "${BASH_REMATCH[1]}"
       else
           $EMACSCLIENT -c -n "$@"
       fi
   }

then new version is:

1
2
3
4
5
6
7
   function ec () {
       if [[ $1 =~ (.*)[:#]L?([0-9]+)$ ]]; then
          $EMACSCLIENT -c -n "+${BASH_REMATCH[2]}" "${BASH_REMATCH[1]}"
       else
           $EMACSCLIENT -c -n "$@"
       fi
   }

The only change is to the regular expression (.*)[:#]L?([0-9]+)$, which says “capture everything up to : or # option followed by “L” and then followed by nothing by numbers to the end of line, which should be captured as well”.

Technically, this regexp would allow the format filename:LNN but that doesn’t keep me up at night.

I typically just copy the text to the right of the branch name in the Github URL, but a clever reader could easily modify the function to take the full URL and just grab the useful bits.

Comments