[TxMt] Jump to file command

Allan Odgaard throw-away-1 at macromates.com
Fri Nov 25 03:34:05 UTC 2005


On 24/11/2005, at 18:52, Chris Jenkins wrote:

> Id like to write a command that can locate the currently selected  
> word as a file within the project (assuming the word is the name of  
> a class or some such thing) and open that file. [...] the more I  
> stare at combinations of locate, grep, perl and whatnot the more I  
> can feel my sanity ebb away.

find is for finding files, and it's pretty great :)

It takes as first argument(s), the location(s) to search. We probably  
want to use $TM_PROJECT_DIRECTORY (and fallback to $TM_DIRECTORY).

Then it takes conditions the file (path) should match, here one can  
use grouping, and, or, and not (i.e. boolean logic). In our case, we  
want to find a file by name, and thus use -name with  
$TM_SELECTED_TEXT or $TM_CURRENT_WORD (if there's no selection), - 
name is actually a shell pattern, so we can add * to find files  
starting with the current word.

By default, find will find all matches. To limit it, we need to pipe  
it through head (with argument -n1).

This gives us the match, to actually open it, we use “mate” with the  
result.

So we end up with a command that has Input: None, Output: Show as  
Tool Tip (so we can show a “Not found” error), and Command:

    dir=${TM_PROJECT_DIRECTORY:-$TM_DIRECTORY}
    file=${TM_SELECTED_TEXT:-$TM_CURRENT_WORD}
    res=$(find "$dir" -name ".svn" -prune -or -name "$file*" -print| 
head -n1)
    if [[ -n "$res" ]]
       then mate "$res" &>/dev/null &
       else echo "Couldn't find file: “${file}”"
    fi

I made find skip .svn directories. There's an implicit “-and” between  
the arguments, and -and binds stronger than -or, so the find  
expression really says:

    ( if the name is .svn and “prune” ) or ( name is $file* and  
“print” )

Here “prune” and “print” both evaluate to true, but have side- 
effects, “prune” has the side-effect that it skips the current  
directory, and “print” has the side-effect that it prints the current  
file.  And of course, find does short-circuit the logic/lazy  
evaluation, so if the left side of an or evaluates to true, it won't  
evaluate right side.

As said, find is really great -- it might take a little to get  
comfortable with the way it mixes actions and boolean logic, but it's  
really powerful. There's also an -exec which runs a shell command  
which can also both have side-effects and decide whether evaluation  
of the miscellaneous conditions should continue.

Of course if the file to be found is located in the same folder as  
the current file, the command could simply be:

    mate "$TM_SELECTED_TEXT" &>/dev/null &




More information about the textmate mailing list