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 &