#!/usr/bin/env python
"""
Searches for text of the form

path:line

and creates a TextMate hyperlink using the URL scheme:

txmt://open/?url=file://~/.bash_profile&line=11
"""

import re, sys, os, os.path
from urllib import quote

TM_PROJECT_DIRECTORY = os.getenv("TM_PROJECT_DIRECTORY")
FILE_PATH_CACHE = {}

def find_file(filename):
    if filename in FILE_PATH_CACHE:
        return FILE_PATH_CACHE[filename]
        
    if filename[0] == "/":
        if os.path.exists(filename):
            path = filename
        else:
            path = None
    else:
        for (path, _, files) in os.walk(TM_PROJECT_DIRECTORY):
            if filename in files:
                path = os.path.abspath("%s/%s" % (path, filename))
                break
        else:
            path = None
        
    FILE_PATH_CACHE[filename] = path
    return path

URL_RE_STR = r"\w+:/[\w/.%#?=+:&-]+"
FILENAME_RE_STR = r"([-_/\w.]+):(\d+)"

# Little advertisement (mostly so I know it's running :)
sys.stdout.write("<b>Linking with linkfiles.py by Niko Matsakis</b><br>\n")

while True:
    line = sys.stdin.readline()
    if not line: break
    until = 0
    for mo in re.finditer("(%s)|%s" % (URL_RE_STR, FILENAME_RE_STR), line):
        sys.stdout.write(line[until:mo.start()])
        until = mo.end()

        url = mo.group(1)
        if url and line.startswith("href=", mo.start() - 1 - len("href=")):
            sys.stdout.write(url) # Don't mess with stuff that's already been processed.
        elif url:
            sys.stdout.write("<a href='%s'>%s</a>" % (url, url))
        else:
            filenm, lineno = mo.group(2), mo.group(3)
            path = find_file(filenm)
            if path is None: # No point in a broken hyperlink.
                sys.stdout.write(mo.group())
            else:
                sys.stdout.write('<a href="txmt://open/?url=file://%s&line=%s">%s</a>' % (
                    path, lineno, mo.group()
                ))
    sys.stdout.write(line[until:])
    sys.stdout.flush()
